Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renovate ignoriere lombok #76

Merged
merged 15 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/.vitepress/components/adr/status.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<div style="margin-top: 4px">
<span
><svg height="24px" viewBox="0 0 24 24">
<path :d="svgPath" :fill="svgFillColor"></path></svg
></span>
<span class="statusText">{{ statusI18nText }}</span>
</div>
</template>

<script setup>
import { useStatus, Status } from "../../composables/status";
import { useData } from "vitepress";
import { computed } from "vue";

const props = defineProps({
status: {
type: Status,
required: true,
},
});

const { lang } = useData();
const statusComposable = useStatus();

const statusI18nText = computed(() =>
statusComposable.statusToI18NTextOrEmpty(lang.value, props.status),
);

const svgPath = computed(() =>
statusComposable.statusToIconPathOrEmpty(props.status),
);

const svgFillColor = computed(() =>
statusComposable.statusToColorOrEmpty(props.status),
);
</script>

<style scoped>
div {
display: flex;
}

.statusText {
margin-left: 4px;
}
</style>
14 changes: 14 additions & 0 deletions docs/.vitepress/components/adr/status/overview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<div v-for="status in Status" :key="status">
<adr-status :status="status"></adr-status>
</div>
</template>

<script setup>
import {Status, useStatus} from "../../../composables/status";
import {useData} from "vitepress";

const statusComposable = useStatus();
const {lang} = useData();

</script>
70 changes: 70 additions & 0 deletions docs/.vitepress/composables/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
mdiAlertOutline,
mdiProgressQuestion,
mdiThumbDownOutline,
mdiThumbUpOutline,
} from "@mdi/js";

export enum Status {
ACCEPTED = "accepted",
REJECTED = "rejected",
PROPOSED = "proposed",
DEPRECATED = "deprecated",
}

const empty = "";

const mapStatusToColorMap = new Map<Status, String>([
[Status.ACCEPTED, "green"],
[Status.REJECTED, "red"],
[Status.PROPOSED, "gray"],
[Status.DEPRECATED, "orange"],
]);

const mapStatusToI18NText = new Map<String, Map<Status, String>>([
[
"en-US",
new Map<Status, String>([
[Status.ACCEPTED, "accepted"],
[Status.REJECTED, "rejected"],
[Status.PROPOSED, "proposed"],
[Status.DEPRECATED, "deprecated"],
]),
],
[
"de-DE",
new Map<Status, String>([
[Status.ACCEPTED, "angenommen"],
[Status.REJECTED, "abgelehnt"],
[Status.PROPOSED, "vorgeschlagen"],
[Status.DEPRECATED, "veraltet"],
]),
],
]);

const mapStatusToIconPath = new Map<Status, String>([
[Status.ACCEPTED, mdiThumbUpOutline],
[Status.REJECTED, mdiThumbDownOutline],
[Status.PROPOSED, mdiProgressQuestion],
[Status.DEPRECATED, mdiAlertOutline],
]);

export const useStatus = function () {
function statusToIconPathOrEmpty(status: Status): String {
return mapStatusToIconPath.get(status) ?? empty;
}

function statusToColorOrEmpty(status: Status): String {
return mapStatusToColorMap.get(status) ?? empty;
}

function statusToI18NTextOrEmpty(lang: String, status: Status): String {
return mapStatusToI18NText.get(lang)?.get(status) ?? empty;
}

return {
statusToIconPathOrEmpty,
statusToColorOrEmpty,
statusToI18NTextOrEmpty,
};
};
6 changes: 5 additions & 1 deletion docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const PATH_TECHNIK = '/technik/';
export default withMermaid({
title: "Wahllokalsystem",
description: "Datenerfassung am Wahltag",
lang: "de-DE",
base: '/Wahllokalsystem/',
srcDir: 'src', //markdown files are located in that directory
themeConfig: {
Expand All @@ -23,7 +24,10 @@ export default withMermaid({
{
text: 'Getting Started', link: `${PATH_TECHNIK}get_started/`
},
{ text: 'Entwicklungsumgebung', link: `${PATH_TECHNIK}development/`}
{ text: 'Entwicklungsumgebung', link: `${PATH_TECHNIK}development/` },
{ text: 'Adr', link: `${PATH_TECHNIK}adr/`, collapsed: true, items: [
{ text: 'Renovate - ignoriere lombok', link: `${PATH_TECHNIK}adr/adr001-renovate-ignore-lombok` }
] }
]
},

Expand Down
15 changes: 15 additions & 0 deletions docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// .vitepress/theme/index.ts
import type {Theme} from "vitepress";
import DefaultTheme from "vitepress/theme";

import status from "../components/adr/status.vue";
import statusOverview from "../components/adr/status/overview.vue";

export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// register your custom global components
app.component("adrStatus", status);
app.component("statusOverview", statusOverview);
},
} satisfies Theme;
15 changes: 14 additions & 1 deletion docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
"docs:build": "vitepress build",
"docs:preview": "vitepress preview"
},
"dependencies": {
"@mdi/js": "^7.2.96"
},
"devDependencies": {
"vitepress": "^1.0.0-rc.45",
"mermaid": "^10.9.0",
"vitepress-plugin-mermaid": "^2.0.16"
"vitepress-plugin-mermaid": "^2.0.16",
"@mdi/font": "^7.3.67"
}
}
117 changes: 117 additions & 0 deletions docs/src/technik/adr/adr001-renovate-ignore-lombok.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Kein Update von org.projectlombok:lombok durch renovate

## Status

<adr-status status='accepted'></adr-status>

## Kontext

Wir verwenden [Renovate](https://docs.renovatebot.com) um unsere Dependencies auf den aktuellen Stand zu halten. Renovate
erzeugt automatisch Pull-Requests mit Vorschlägen zu Anpassungen. Wir reviewen diese Vorschläge und nehmen diese entsprechend an.
Das Dashboard mit einer Übersicht was alles verwaltet wird ist in einem [Issue](https://github.com/it-at-m/Wahllokalsystem/issues/1).

In unseren Services verwenden wir `lombok`. Die Dependency dafür kommt von Spring als managed dependency:

```xml
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```

```xml
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
```

Zur korrekten Funktionsweise muss auch ein Annotation-Processor [eingerichtet](https://projectlombok.org/setup/maven) werden.

Die Version des Annotation-Processors muss in unserem maven projekt definiert werden:

```xml
<properties>
<org.projectlombok.lombok.version>1.18.30</org.projectlombok.lombok.version>
</properties>
```

```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${org.projectlombok.mapstructbinding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
```

Die Versionen der Dependency und vom Processor sollten gleich sein. Die Wahrscheinlichkeit für Probleme wird mit dem Unterschied der Version (Major, Minor, Patch) zusammenhängen.
Da die Versionen aber an unterschiedlicher Stelle gepflegt werden kann dies aktuell nicht
technisch sichergestellt werden. Daher wurde ein Kommentar in der `pom.xml` in den `properties` eingefügt:
```xml
<properties>
<!-- Version muss mit der in den spring-boot-dependencies bereitgestellten Lombok-Version übereinstimmen -->
<org.projectlombok.lombok.version>1.18.30</org.projectlombok.lombok.version>
</properties>
```

Renovate kann diesen Kommentar natürlich nicht beachten und erstellt bei entsprechenden möglichen Updates Pull-Requests.
Diese werden wir aktuell schließen. Da das Wahllokalsystem aus knapp ca. 15 Services am Ende bestehen wird, würden so regelmäßig
zahlreiche PRs entstehen, die wir schließen müssten.

Updates von `lombok` machen wir bei Updates von `spring` mit.

## Entscheidung

Wir lassen `renovate` `org.projectlombok:lombok` ignorieren. Updates von `lombok` erfolgen wie gehabt manuell.

### betrachtete Alternative

Es wäre möglich die Pflege der Version im `annotationProcessorPaths` weg zu bekommen. Dazu müsste man an Stelle von
`annotationProcessorPaths` [`annotationProcessors` pflegen](https://projectlombok.org/contributing/lombok-execution-path) und dort die expliziten Klassen referenzieren. Kommt Mapstruct,
hinzu muss `org.mapstruct:mapstruct-processor` als Dependency vorhanden sein.

Aus meiner Sicht spricht gegen dieses Vorgehen, dass die Processors manuell gepflegt werden müssen, was Aufgrund der Kleinteiligkeit
mühsamer sein dürfte als mit `annotationProcessorPaths` zu arbeiten. Bei Hebungen der
Version müssten wir prüfen, ob sich etwas an der Architektur geändert hat, z.B. ob es jetzt eine weitere Klasse gibt, die man
verwenden müsste. Klassen die gelöscht werden sorgen für Fehler und somit für schnelles Feedback.

Beide Konfigurationsmöglichkeiten können nicht zur selben Zeit verwendet werden.

## Konsequenzen

### positiv

Weniger Pull-Requests die gehandhabt werden müssen.

### negativ

Steigerung der Komplexität durch eine zusätzliche Konfiguration für eine Dependency. Ein Verweis in der Konfiguration auf diesen ADR ist nicht möglich.

`lombok` wird in keinem Projekt mehr durch `renovate` gepflegt. Das halte ich für vertrebar da wir `lombok` immer im Kontext von `spring` verwenden.
9 changes: 9 additions & 0 deletions docs/src/technik/adr/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Architecture Decision Records (ADRs)

Architecture decision records dokumentieren funktionale und nicht-funktionale Entscheidungen.
Wir benutzen dafür folgendes Template:
[ADR template of Michael Nygard](https://github.com/joelparkerhenderson/architecture-decision-record/tree/main/locales/en/templates/decision-record-template-by-michael-nygard).

Entscheidungen können sich im Laufe der Zeit ändern. Daher befindet sich jede der Entscheidungen in einem der folgenden Zustände:

<status-overview></status-overview>
3 changes: 3 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
],
"addLabels": [
"renovate"
],
"ignoreDeps": [
"org.projectlombok:lombok"
]
}
Loading