From d45a3544fcf18e82aedbeac0eb3440e6935dc20f Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Tue, 28 Jan 2025 17:21:26 +0100 Subject: [PATCH 1/3] Add Spotless Gradle plugin configuration --- build.gradle | 9 +++++++ project.gradle | 27 ++++++++++++++++++++ tools/spotless/openremote-license-header.txt | 18 +++++++++++++ ui/app/custom-react/build.gradle | 6 ++--- ui/app/custom/build.gradle | 6 ++--- 5 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 tools/spotless/openremote-license-header.txt diff --git a/build.gradle b/build.gradle index 0caedf150..6014cdcd0 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,15 @@ scmVersion { } } +buildscript { + repositories { + maven { url = 'https://plugins.gradle.org/m2' } + } + dependencies { + classpath 'com.diffplug.spotless:spotless-plugin-gradle:8.5.1' + } +} + allprojects { // Apply common project setup apply from: "${project.rootDir}/project.gradle" diff --git a/project.gradle b/project.gradle index 0f9c07d78..97de1ad0a 100644 --- a/project.gradle +++ b/project.gradle @@ -387,4 +387,31 @@ plugins.withType(JavaPlugin).whenPluginAdded { } } +plugins.apply('com.diffplug.spotless') + +spotless { + java { + target '**/*.java' + + googleJavaFormat() + licenseHeaderFile rootProject.file('tools/spotless/openremote-license-header.txt') + importOrder('java', 'javax', 'com', 'org') + removeUnusedImports() + formatAnnotations() + trimTrailingWhitespace() + endWithNewline() + } + + typescript { + target 'src/**/*.ts' + targetExclude( + 'src/model.ts', + 'src/restclient.ts' + ) + + eslint().configFile(rootProject.file('ui/.eslintrc.json')).tsconfigFile(rootProject.file('ui/tsconfig.json')) + licenseHeaderFile rootProject.file('tools/spotless/openremote-license-header.txt'), '(import|const|declare|export|var) ' + } +} + // POM generator diff --git a/tools/spotless/openremote-license-header.txt b/tools/spotless/openremote-license-header.txt new file mode 100644 index 000000000..2a336e1ba --- /dev/null +++ b/tools/spotless/openremote-license-header.txt @@ -0,0 +1,18 @@ +/* + * Copyright $YEAR, OpenRemote Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ diff --git a/ui/app/custom-react/build.gradle b/ui/app/custom-react/build.gradle index 797533f42..c61fa77b1 100644 --- a/ui/app/custom-react/build.gradle +++ b/ui/app/custom-react/build.gradle @@ -1,12 +1,10 @@ buildDir = "dist" -tasks.register('clean') { - dependsOn npmClean -} - tasks.register('installDist', Copy) { dependsOn npmBuild mustRunAfter(resolveTask(":manager:installDist")) from project.buildDir into "${project(':deployment').buildDir}/image/manager/app/${projectDir.name}" } + +clean.dependsOn(npmClean) diff --git a/ui/app/custom/build.gradle b/ui/app/custom/build.gradle index 797533f42..c61fa77b1 100644 --- a/ui/app/custom/build.gradle +++ b/ui/app/custom/build.gradle @@ -1,12 +1,10 @@ buildDir = "dist" -tasks.register('clean') { - dependsOn npmClean -} - tasks.register('installDist', Copy) { dependsOn npmBuild mustRunAfter(resolveTask(":manager:installDist")) from project.buildDir into "${project(':deployment').buildDir}/image/manager/app/${projectDir.name}" } + +clean.dependsOn(npmClean) From fbfdf7c868a9652a23c09cee1771f3d881ba3635 Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Fri, 22 May 2026 18:25:48 +0200 Subject: [PATCH 2/3] Add eslint dependencies --- ui/app/custom-react/package.json | 8 ++++++++ ui/app/custom/package.json | 8 ++++++++ ui/component/model/package.json | 10 +++++++++- ui/component/rest/package.json | 6 ++++++ yarn.lock | 34 ++++++++++++++++++++++++++++++-- 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/ui/app/custom-react/package.json b/ui/app/custom-react/package.json index 87cc4f6d5..91702fb50 100644 --- a/ui/app/custom-react/package.json +++ b/ui/app/custom-react/package.json @@ -22,7 +22,15 @@ "@rspack/core": "~1.7.1", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "cross-env": "^10.1.0", + "eslint": "^8.6.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0", "react-refresh": "^0.18.0", "ts-node": "^10.9.2", "typescript": "^5.9.3" diff --git a/ui/app/custom/package.json b/ui/app/custom/package.json index eead7e96e..1c94e8cf5 100644 --- a/ui/app/custom/package.json +++ b/ui/app/custom/package.json @@ -28,8 +28,16 @@ "@openremote/util": "~1.22.1", "@rspack/cli": "*", "@rspack/core": "*", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "cross-env": "*", "css-loader": "*", + "eslint": "^8.6.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0", "shx": "*", "ts-loader": "*", "typescript": "^5.9.3" diff --git a/ui/component/model/package.json b/ui/component/model/package.json index 8d73398d5..63bcc81fd 100644 --- a/ui/component/model/package.json +++ b/ui/component/model/package.json @@ -22,7 +22,15 @@ "author": "OpenRemote", "license": "AGPL-3.0-or-later", "devDependencies": { - "@openremote/util": "~1.22.1" + "@openremote/util": "~1.22.1", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.6.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0" }, "publishConfig": { "access": "restricted" diff --git a/ui/component/rest/package.json b/ui/component/rest/package.json index d14784407..604e2b3ab 100644 --- a/ui/component/rest/package.json +++ b/ui/component/rest/package.json @@ -28,6 +28,12 @@ "devDependencies": { "@openremote/util": "~1.22.1", "@rspack/core": "*", + "eslint": "^8.6.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0", "typescript": "^5.9.3" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index 8ae71cbdd..a23ec3ba4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1306,7 +1306,15 @@ __metadata: "@rspack/core": "npm:~1.7.1" "@types/react": "npm:^19.2.2" "@types/react-dom": "npm:^19.2.2" + "@typescript-eslint/eslint-plugin": "npm:^5.62.0" + "@typescript-eslint/parser": "npm:^5.62.0" cross-env: "npm:^10.1.0" + eslint: "npm:^8.6.0" + eslint-config-prettier: "npm:^8.3.0" + eslint-config-standard: "npm:^16.0.3" + eslint-plugin-import: "npm:^2.25.4" + eslint-plugin-node: "npm:^11.1.0" + eslint-plugin-promise: "npm:^6.0.0" react: "npm:^19.2.0" react-dom: "npm:^19.2.0" react-refresh: "npm:^0.18.0" @@ -1324,8 +1332,16 @@ __metadata: "@openremote/util": "npm:~1.22.1" "@rspack/cli": "npm:*" "@rspack/core": "npm:*" + "@typescript-eslint/eslint-plugin": "npm:^5.62.0" + "@typescript-eslint/parser": "npm:^5.62.0" cross-env: "npm:*" css-loader: "npm:*" + eslint: "npm:^8.6.0" + eslint-config-prettier: "npm:^8.3.0" + eslint-config-standard: "npm:^16.0.3" + eslint-plugin-import: "npm:^2.25.4" + eslint-plugin-node: "npm:^11.1.0" + eslint-plugin-promise: "npm:^6.0.0" lit: "npm:^3.3.1" model: "workspace:*" rest: "workspace:*" @@ -2583,7 +2599,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.9.0": +"@typescript-eslint/eslint-plugin@npm:^5.62.0, @typescript-eslint/eslint-plugin@npm:^5.9.0": version: 5.62.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" dependencies: @@ -2607,7 +2623,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.9.0": +"@typescript-eslint/parser@npm:^5.62.0, @typescript-eslint/parser@npm:^5.9.0": version: 5.62.0 resolution: "@typescript-eslint/parser@npm:5.62.0" dependencies: @@ -7269,6 +7285,14 @@ __metadata: resolution: "model@workspace:ui/component/model" dependencies: "@openremote/util": "npm:~1.22.1" + "@typescript-eslint/eslint-plugin": "npm:^5.62.0" + "@typescript-eslint/parser": "npm:^5.62.0" + eslint: "npm:^8.6.0" + eslint-config-prettier: "npm:^8.3.0" + eslint-config-standard: "npm:^16.0.3" + eslint-plugin-import: "npm:^2.25.4" + eslint-plugin-node: "npm:^11.1.0" + eslint-plugin-promise: "npm:^6.0.0" languageName: unknown linkType: soft @@ -8356,6 +8380,12 @@ __metadata: "@openremote/rest": "npm:~1.22.1" "@openremote/util": "npm:~1.22.1" "@rspack/core": "npm:*" + eslint: "npm:^8.6.0" + eslint-config-prettier: "npm:^8.3.0" + eslint-config-standard: "npm:^16.0.3" + eslint-plugin-import: "npm:^2.25.4" + eslint-plugin-node: "npm:^11.1.0" + eslint-plugin-promise: "npm:^6.0.0" model: "workspace:*" typescript: "npm:^5.9.3" languageName: unknown From fb9792507bf28333d1d86be87e9aec0bf1578736 Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Fri, 22 May 2026 18:26:14 +0200 Subject: [PATCH 3/3] Apply Spotless --- .../openremote/agent/custom/CustomAgent.java | 81 +++++++++--------- .../custom/CustomAgentModelProvider.java | 16 ++-- .../agent/custom/CustomProtocol.java | 85 +++++++++---------- .../manager/custom/CustomService.java | 25 ++---- .../openremote/model/custom/CustomAsset.java | 70 ++++++++------- .../custom/CustomAssetModelProvider.java | 15 ++-- .../openremote/model/custom/CustomData.java | 26 +++--- .../model/custom/CustomEndpointResource.java | 14 +-- .../setup/custom/CustomKeycloakSetup.java | 59 +++++++------ .../setup/custom/CustomManagerSetup.java | 25 +++--- .../setup/custom/CustomSetupTasks.java | 31 +++---- ui/app/custom-react/src/react-env.d.ts | 21 ++++- ui/app/custom/src/index.ts | 21 ++++- ui/app/custom/src/pages/page-custom.ts | 20 ++++- ui/component/model/src/index.ts | 18 ++++ ui/component/model/src/util.ts | 18 ++++ ui/component/rest/src/index.ts | 18 ++++ 17 files changed, 327 insertions(+), 236 deletions(-) diff --git a/agent/src/main/java/org/openremote/agent/custom/CustomAgent.java b/agent/src/main/java/org/openremote/agent/custom/CustomAgent.java index 2a152dec8..4610d6490 100644 --- a/agent/src/main/java/org/openremote/agent/custom/CustomAgent.java +++ b/agent/src/main/java/org/openremote/agent/custom/CustomAgent.java @@ -1,9 +1,6 @@ /* * Copyright 2017, OpenRemote Inc. * - * See the CONTRIBUTORS.txt file in the distribution for a - * full listing of individual contributors. - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the @@ -15,10 +12,14 @@ * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * along with this program. If not, see . + * + * SPDX-License-Identifier: AGPL-3.0-or-later */ package org.openremote.agent.custom; +import java.util.Optional; + import org.openremote.model.asset.Asset; import org.openremote.model.asset.agent.Agent; import org.openremote.model.asset.agent.AgentDescriptor; @@ -27,57 +28,57 @@ import org.openremote.model.value.ValueDescriptor; import jakarta.persistence.Entity; -import java.util.Optional; /** - * This is an example of a custom {@link Agent} type; this must be registered via an - * {@link org.openremote.model.AssetModelProvider} and must conform to the same requirements as custom {@link Asset}s and - * in addition the following requirements: + * This is an example of a custom {@link Agent} type; this must be registered via an {@link + * org.openremote.model.AssetModelProvider} and must conform to the same requirements as custom + * {@link Asset}s and in addition the following requirements: * *
    - *
  • Optionally add a custom {@link org.openremote.model.asset.agent.AgentLink} (the {@link Class#getSimpleName} must - * be unique compared to all other registered {@link org.openremote.model.asset.agent.AgentLink}s) - *
  • Must define a {@link org.openremote.model.asset.agent.Protocol} implementation that corresponds to this {@link Agent} - *
  • Must have a public static final {@link org.openremote.model.asset.agent.AgentDescriptor} rather than an - * {@link org.openremote.model.asset.AssetDescriptor} + *
  • Optionally add a custom {@link org.openremote.model.asset.agent.AgentLink} (the {@link + * Class#getSimpleName} must be unique compared to all other registered {@link + * org.openremote.model.asset.agent.AgentLink}s) + *
  • Must define a {@link org.openremote.model.asset.agent.Protocol} implementation that + * corresponds to this {@link Agent} + *
  • Must have a public static final {@link org.openremote.model.asset.agent.AgentDescriptor} + * rather than an {@link org.openremote.model.asset.AssetDescriptor} *
*/ @Entity public class CustomAgent extends Agent { - public enum Option { - ONE, - TWO, - THREE - }; + public enum Option { + ONE, + TWO, + THREE + }; - public static final ValueDescriptor