diff --git a/.github/workflows/plugin-e2e.yml b/.github/workflows/plugin-e2e.yml index 14d6408aa..c0912e7cf 100644 --- a/.github/workflows/plugin-e2e.yml +++ b/.github/workflows/plugin-e2e.yml @@ -28,7 +28,7 @@ on: - nx-maven quarkus bom e2e - nx-maven spring-boot bom e2e - nx-maven spring-boot-parent-pom e2e - - should create a micronaut java application + - should create a sb java application os: type: choice description: Os diff --git a/DEV.md b/DEV.md new file mode 100644 index 000000000..afdb1f466 --- /dev/null +++ b/DEV.md @@ -0,0 +1,3 @@ +nx local-registry + +nx run-many --targets publish --ver 0.0.0-e2e --tag e2e diff --git a/package-lock.json b/package-lock.json index aa03b5ada..91d802f12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,6 +58,7 @@ "nx": "17.2.8", "prettier": "^3.1.1", "prettier-plugin-java": "^2.5.0", + "smol-toml": "^1.1.3", "tcp-port-used": "^1.0.2", "tmp": "^0.2.1", "tree-kill": "1.2.2", @@ -13689,6 +13690,16 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/smol-toml": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.1.3.tgz", + "integrity": "sha512-qTyy6Owjho1ISBmxj4HdrFWB2kMQ5RczU6J04OqslSfdSH656OIHuomHS4ZDvhwm37nig/uXyiTMJxlC9zIVfw==", + "dev": true, + "engines": { + "node": ">= 18", + "pnpm": ">= 8" + } + }, "node_modules/sonic-boom": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", diff --git a/package.json b/package.json index 0c2983f66..03465fddb 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "nx": "17.2.8", "prettier": "^3.1.1", "prettier-plugin-java": "^2.5.0", + "smol-toml": "^1.1.3", "tcp-port-used": "^1.0.2", "tmp": "^0.2.1", "tree-kill": "1.2.2", diff --git a/packages/nx-gradle/package.json b/packages/nx-gradle/package.json index 4709580ec..4dd2842f4 100644 --- a/packages/nx-gradle/package.json +++ b/packages/nx-gradle/package.json @@ -34,6 +34,7 @@ "@jnxplus/common": "0.18.5", "nx": ">=17.0.0", "tslib": "^2.6.2", - "@nx/devkit": ">=17.0.0" + "@nx/devkit": ">=17.0.0", + "smol-toml": "^1.1.3" } } diff --git a/packages/nx-gradle/src/generators/application/generator.ts b/packages/nx-gradle/src/generators/application/generator.ts index 6fcbfe418..98c37ca7b 100644 --- a/packages/nx-gradle/src/generators/application/generator.ts +++ b/packages/nx-gradle/src/generators/application/generator.ts @@ -31,6 +31,7 @@ import { getVersionManagement, } from '../../utils'; import { NxGradleAppGeneratorSchema } from './schema'; +import { addMissingCode } from '../../utils/libs-versions-toml'; export default async function ( tree: Tree, @@ -324,6 +325,14 @@ async function applicationGenerator( ) { const normalizedOptions = normalizeOptions(tree, options); + await addMissingCode( + tree, + normalizedOptions.versionManagement, + normalizedOptions.gradleRootDirectory, + options.framework, + options.language, + ); + const projectConfiguration: ProjectConfiguration = { root: normalizedOptions.projectRoot, projectType: 'application', diff --git a/packages/nx-gradle/src/generators/init/files/gradle/catalog/kmp/libs.versions.toml b/packages/nx-gradle/src/generators/init/files/gradle/catalog/kmp/libs.versions.toml deleted file mode 100644 index 30ad3ab96..000000000 --- a/packages/nx-gradle/src/generators/init/files/gradle/catalog/kmp/libs.versions.toml +++ /dev/null @@ -1,5 +0,0 @@ -[versions] - -[libraries] - -[plugins] diff --git a/packages/nx-gradle/src/generators/init/files/gradle/catalog/micronaut/libs.versions.toml b/packages/nx-gradle/src/generators/init/files/gradle/catalog/micronaut/libs.versions.toml deleted file mode 100644 index 6393c450e..000000000 --- a/packages/nx-gradle/src/generators/init/files/gradle/catalog/micronaut/libs.versions.toml +++ /dev/null @@ -1,16 +0,0 @@ -[versions] -java = "<%= javaVersion %>" -kotlin = "<%= kotlinVersion %>" -micronaut = "<%= micronautVersion %>" - -[libraries] - -[plugins] -micronaut-aot = { id = "io.micronaut.aot", version = "4.2.1" } -micronaut-application = { id = "io.micronaut.application", version = "4.2.1" } -micronaut-library = { id = "io.micronaut.library", version = "4.2.1" } -google-devtools-ksp = { id = "com.google.devtools.ksp", version = "<%= kspVersion %>" } -github-johnrengelman-shadow = { id = "com.github.johnrengelman.shadow", version = "<%= shadowVersion %>" } -github-khalilou88-jnxplus = { id = "io.github.khalilou88.jnxplus", version = "<%= jnxplusGradlePluginVersion %>" } -jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -jetbrains-kotlin-plugin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" } diff --git a/packages/nx-gradle/src/generators/init/files/gradle/catalog/none/libs.versions.toml b/packages/nx-gradle/src/generators/init/files/gradle/catalog/none/libs.versions.toml deleted file mode 100644 index ba4ca1d4b..000000000 --- a/packages/nx-gradle/src/generators/init/files/gradle/catalog/none/libs.versions.toml +++ /dev/null @@ -1,9 +0,0 @@ -[versions] -java = "<%= javaVersion %>" -kotlin = "<%= kotlinVersion %>" - -[libraries] - -[plugins] -github-khalilou88-jnxplus = { id = "io.github.khalilou88.jnxplus", version = "<%= jnxplusGradlePluginVersion %>" } -jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/packages/nx-gradle/src/generators/init/files/gradle/catalog/quarkus/libs.versions.toml b/packages/nx-gradle/src/generators/init/files/gradle/catalog/quarkus/libs.versions.toml deleted file mode 100644 index b2399b54a..000000000 --- a/packages/nx-gradle/src/generators/init/files/gradle/catalog/quarkus/libs.versions.toml +++ /dev/null @@ -1,13 +0,0 @@ -[versions] -java = "<%= javaVersion %>" -kotlin = "<%= kotlinVersion %>" -quarkus = "<%= quarkusVersion %>" - -[libraries] -quarkus-platform-quarkus-bom = { module = "io.quarkus.platform:quarkus-bom", version.ref = "quarkus" } - -[plugins] -quarkus = { id = "io.quarkus", version.ref = "quarkus" } -github-khalilou88-jnxplus = { id = "io.github.khalilou88.jnxplus", version = "<%= jnxplusGradlePluginVersion %>" } -jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -jetbrains-kotlin-plugin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" } diff --git a/packages/nx-gradle/src/generators/init/files/gradle/catalog/spring-boot/libs.versions.toml b/packages/nx-gradle/src/generators/init/files/gradle/catalog/spring-boot/libs.versions.toml deleted file mode 100644 index 5795e9c72..000000000 --- a/packages/nx-gradle/src/generators/init/files/gradle/catalog/spring-boot/libs.versions.toml +++ /dev/null @@ -1,13 +0,0 @@ -[versions] -java = "<%= javaVersion %>" -kotlin = "<%= kotlinVersion %>" -spring-boot = "<%= springBootVersion %>" - -[libraries] - -[plugins] -springframework-boot = { id = "org.springframework.boot", version.ref = "spring-boot" } -spring-dependency-management = { id = "io.spring.dependency-management", version = "<%= springDependencyManagementVersion %>" } -github-khalilou88-jnxplus = { id = "io.github.khalilou88.jnxplus", version = "<%= jnxplusGradlePluginVersion %>" } -jetbrains-kotlin-plugin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } -jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/packages/nx-gradle/src/generators/init/files/gradle/config/none/build.gradle__kotlinExtension__ b/packages/nx-gradle/src/generators/init/files/gradle/config/none/build.gradle__kotlinExtension__ index ee22d4498..a0933355c 100644 --- a/packages/nx-gradle/src/generators/init/files/gradle/config/none/build.gradle__kotlinExtension__ +++ b/packages/nx-gradle/src/generators/init/files/gradle/config/none/build.gradle__kotlinExtension__ @@ -14,13 +14,11 @@ plugins { alias libs.plugins.github.khalilou88.jnxplus // this is necessary to avoid the plugins to be loaded multiple times // in each subproject's classloader - alias libs.plugins.jetbrains.kotlin.jvm apply false <% } -%> <% if(dsl === 'kotlin') { -%> alias(libs.plugins.github.khalilou88.jnxplus) // this is necessary to avoid the plugins to be loaded multiple times // in each subproject's classloader - alias(libs.plugins.jetbrains.kotlin.jvm) apply false <% } -%> } <% } -%> diff --git a/packages/nx-gradle/src/generators/init/generator.ts b/packages/nx-gradle/src/generators/init/generator.ts index d3f49f696..09d48e9a1 100644 --- a/packages/nx-gradle/src/generators/init/generator.ts +++ b/packages/nx-gradle/src/generators/init/generator.ts @@ -23,6 +23,7 @@ import { writeJson, } from '@nx/devkit'; import * as path from 'path'; +import { addLibsVersionsToml } from '../../utils/libs-versions-toml'; import { NxGradleInitGeneratorSchema } from './schema'; interface NormalizedSchema extends NxGradleInitGeneratorSchema { @@ -86,11 +87,12 @@ function addFiles(tree: Tree, options: NormalizedSchema) { ); if (options.versionManagement === 'version-catalog') { - generateFiles( + addLibsVersionsToml( tree, - path.join(__dirname, 'files', 'gradle', 'catalog', options.preset), - joinPathFragments(options.gradleRootDirectory, 'gradle'), - templateOptions, + options.gradleRootDirectory, + options.javaVersion, + options.preset, + 'java', ); } } diff --git a/packages/nx-gradle/src/generators/library/generator.ts b/packages/nx-gradle/src/generators/library/generator.ts index 1534db695..999edb537 100644 --- a/packages/nx-gradle/src/generators/library/generator.ts +++ b/packages/nx-gradle/src/generators/library/generator.ts @@ -29,6 +29,7 @@ import { getVersionManagement, } from '../../utils'; import { NxGradleLibGeneratorSchema } from './schema'; +import { addMissingCode } from '../../utils/libs-versions-toml'; export default async function ( tree: Tree, @@ -276,6 +277,14 @@ async function libraryGenerator( ) { const normalizedOptions = normalizeOptions(tree, options); + await addMissingCode( + tree, + normalizedOptions.versionManagement, + normalizedOptions.gradleRootDirectory, + options.framework, + options.language, + ); + const projectConfiguration: ProjectConfiguration = { root: normalizedOptions.projectRoot, projectType: 'library', diff --git a/packages/nx-gradle/src/utils/libs-versions-toml.ts b/packages/nx-gradle/src/utils/libs-versions-toml.ts new file mode 100644 index 000000000..4a175172e --- /dev/null +++ b/packages/nx-gradle/src/utils/libs-versions-toml.ts @@ -0,0 +1,274 @@ +import { + PresetType, + VersionManagementType, + jnxplusGradlePluginVersion, + kotlinVersion, + kspVersion, + micronautVersion, + quarkusVersion, + shadowVersion, + springBootVersion, + springDependencyManagementVersion, +} from '@jnxplus/common'; +import { Tree, joinPathFragments } from '@nx/devkit'; + +const regex1 = /\[versions]/; +const regex2 = /\[libraries]/; +const regex3 = /\[plugins]/; + +const regex = '/plugins\\s*{/'; + +export async function addMissingCode( + tree: Tree, + versionManagement: VersionManagementType, + gradleRootDirectory: string, + framework: PresetType | undefined, + language: string, +) { + if (versionManagement !== 'version-catalog') { + return; + } + + const { parse } = await (Function("return import('smol-toml')")() as Promise< + typeof import('smol-toml') + >); + + const libsVersionsTomlPath = joinPathFragments( + gradleRootDirectory, + 'gradle', + 'libs.versions.toml', + ); + + const libsVersionsTomlContent = + tree.read(libsVersionsTomlPath, 'utf-8') || ''; + const catalog = parse(libsVersionsTomlContent); + + const elements: ElementsType = getElements( + '17', + framework, + language, + catalog, + ); + + const newLibsVersionsTomlContent = libsVersionsTomlContent + .replace(regex1, `[versions]\n${elements.versions.join('\n')}`) + .replace(regex2, `[libraries]\n${elements.libraries.join('\n')}`) + .replace(regex3, `[plugins]\n${elements.plugins.join('\n')}`); + + tree.write(libsVersionsTomlPath, newLibsVersionsTomlContent); + + if (elements.plugins.length > 0) { + const buildGradlePath = joinPathFragments( + gradleRootDirectory, + 'build.gradle', + ); + const buildGradleKtsPath = joinPathFragments( + gradleRootDirectory, + 'build.gradle.kts', + ); + + const a = elements.plugins.map((p) => p.split('=')[0].trim()); + + if (tree.exists(buildGradlePath)) { + const buildGradleContent = tree.read(buildGradlePath, 'utf-8') || ''; + + const b = a.map((aa) => `alias ${aa} apply false`); + + const newBuildGradleContent = buildGradleContent.replace( + regex, + `plugins {\n${b.join('\n')}`, + ); + tree.write(buildGradlePath, newBuildGradleContent); + } + + if (tree.exists(buildGradleKtsPath)) { + const buildGradleKtsContent = + tree.read(buildGradleKtsPath, 'utf-8') || ''; + + const bb = a.map((aa) => `alias(${aa}) apply false`); + + const newBuildGradleKtsContent = buildGradleKtsContent.replace( + regex, + `plugins {\n${bb.join('\n')}`, + ); + tree.write(buildGradleKtsPath, newBuildGradleKtsContent); + } + } +} + +export function addLibsVersionsToml( + tree: Tree, + gradleRootDirectory: string, + javaVersion: string | number, + preset: PresetType, + language: string, +) { + const libsVersionsTomlPath = joinPathFragments( + gradleRootDirectory, + 'gradle', + 'libs.versions.toml', + ); + + const libsVersionsTomlContent = getLibsVersionsTomlContent( + javaVersion, + preset, + language, + ); + + if (!tree.exists(libsVersionsTomlPath)) { + tree.write(libsVersionsTomlPath, libsVersionsTomlContent); + } +} + +type ElementsType = { + versions: string[]; + libraries: string[]; + plugins: string[]; +}; + +function getLibsVersionsTomlContent( + javaVersion: string | number, + preset: PresetType | undefined, + language: string, +) { + const elements: ElementsType = getElements(javaVersion, preset, language); + + return `[versions]\n${elements.versions.join( + '\n', + )}\n\n[libraries]\n${elements.libraries.join( + '\n', + )}\n\n[plugins]\n${elements.plugins.join('\n')}`; +} + +function getElements( + javaVersion: string | number, + preset: PresetType | undefined, + language: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + catalog?: any, +) { + const elements: ElementsType = { versions: [], libraries: [], plugins: [] }; + + if (!catalog?.versions['java']) { + elements.versions.push(`java = "${javaVersion}"`); + } + + if (!catalog?.plugins['github-khalilou88-jnxplus']) { + elements.plugins.push( + `github-khalilou88-jnxplus = { id = "io.github.khalilou88.jnxplus", version = "${jnxplusGradlePluginVersion}" }`, + ); + } + + if (language === 'kotlin') { + if (!catalog?.versions['kotlin']) { + elements.versions.push(`kotlin = "${kotlinVersion}"`); + } + + if (!catalog?.plugins['jetbrains-kotlin-jvm']) { + elements.plugins.push( + 'jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }', + ); + } + } + + if (preset === 'spring-boot') { + if (!catalog?.versions['spring-boot']) { + elements.versions.push(`spring-boot = "${springBootVersion}"`); + } + + if (!catalog?.plugins['springframework-boot']) { + elements.plugins.push( + 'springframework-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }', + ); + } + + if (!catalog?.plugins['spring-dependency-management']) { + elements.plugins.push( + `spring-dependency-management = { id = "io.spring.dependency-management", version = "${springDependencyManagementVersion}" }`, + ); + } + + if ( + language === 'kotlin' && + !catalog?.plugins['jetbrains-kotlin-plugin-spring'] + ) { + elements.plugins.push( + 'jetbrains-kotlin-plugin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }', + ); + } + } + + if (preset === 'quarkus') { + if (!catalog?.versions['quarkus']) { + elements.versions.push(`quarkus = "${quarkusVersion}"`); + } + + if (!catalog?.libraries['quarkus-platform-quarkus-bom']) { + elements.libraries.push( + 'quarkus-platform-quarkus-bom = { module = "io.quarkus.platform:quarkus-bom", version.ref = "quarkus" }', + ); + } + + if ( + language === 'kotlin' && + !catalog?.plugins['jetbrains-kotlin-plugin-allopen'] + ) { + elements.plugins.push( + 'jetbrains-kotlin-plugin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" }', + ); + } + + if (!catalog?.plugins['quarkus']) { + elements.plugins.push( + 'quarkus = { id = "io.quarkus", version.ref = "quarkus" }', + ); + } + } + + if (preset === 'micronaut') { + if (!catalog?.versions['micronaut']) { + elements.versions.push(`micronaut = "${micronautVersion}"`); + } + + if ( + language === 'kotlin' && + !catalog?.plugins['jetbrains-kotlin-plugin-allopen'] + ) { + elements.plugins.push( + 'jetbrains-kotlin-plugin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" }', + ); + } + + if (!catalog?.plugins['micronaut-aot']) { + elements.plugins.push( + 'micronaut-aot = { id = "io.micronaut.aot", version = "4.2.1" }', + ); + } + + if (!catalog?.plugins['micronaut-application']) { + elements.plugins.push( + 'micronaut-application = { id = "io.micronaut.application", version = "4.2.1" }', + ); + } + + if (!catalog?.plugins['micronaut-library']) { + elements.plugins.push( + 'micronaut-library = { id = "io.micronaut.library", version = "4.2.1" }', + ); + } + + if (!catalog?.plugins['google-devtools-ksp']) { + elements.plugins.push( + `google-devtools-ksp = { id = "com.google.devtools.ksp", version = "${kspVersion}" }`, + ); + } + + if (!catalog?.plugins['github-johnrengelman-shadow']) { + elements.plugins.push( + `github-johnrengelman-shadow = { id = "com.github.johnrengelman.shadow", version = "${shadowVersion}" }`, + ); + } + } + + return elements; +} diff --git a/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus-kt.spec.ts b/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus-kt.spec.ts index 1c45d1f37..96891b0e6 100644 --- a/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus-kt.spec.ts +++ b/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus-kt.spec.ts @@ -43,7 +43,7 @@ describe('nx-gradle quarkus kotlin dsl e2e', () => { }); await runNxCommandAsync( - `generate @jnxplus/nx-gradle:init --dsl kotlin --rootProjectName ${rootProjectName} --preset quarkus --versionManagement version-catalog`, + `generate @jnxplus/nx-gradle:init --dsl kotlin --rootProjectName ${rootProjectName} --preset none --versionManagement version-catalog`, ); addJVMMemory(); diff --git a/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus.spec.ts b/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus.spec.ts index 56e3036c1..e2ac71e62 100644 --- a/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus.spec.ts +++ b/testing-projects/jnxplus-e2e/tests/nx-gradle/quarkus.spec.ts @@ -43,7 +43,7 @@ describe('nx-gradle quarkus e2e', () => { }); await runNxCommandAsync( - `generate @jnxplus/nx-gradle:init --rootProjectName ${rootProjectName} --preset quarkus --versionManagement version-catalog`, + `generate @jnxplus/nx-gradle:init --rootProjectName ${rootProjectName} --preset none --versionManagement version-catalog`, ); addJVMMemory(); diff --git a/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot-kt.spec.ts b/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot-kt.spec.ts index f6b8e539e..d4c1695fe 100644 --- a/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot-kt.spec.ts +++ b/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot-kt.spec.ts @@ -42,7 +42,7 @@ describe('nx-gradle spring-boot kotlin dsl e2e', () => { }); await runNxCommandAsync( - `generate @jnxplus/nx-gradle:init --dsl kotlin --rootProjectName ${rootProjectName} --preset spring-boot --versionManagement version-catalog`, + `generate @jnxplus/nx-gradle:init --dsl kotlin --rootProjectName ${rootProjectName} --preset none --versionManagement version-catalog`, ); }, 120000); @@ -79,7 +79,7 @@ describe('nx-gradle spring-boot kotlin dsl e2e', () => { ).not.toThrow(); }, 120000); - it('should create a java application', async () => { + it('should create a sb java application', async () => { const appName = uniq('g-sb-app-'); await runNxCommandAsync( diff --git a/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot.spec.ts b/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot.spec.ts index 080d6cdc3..d181edb08 100644 --- a/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot.spec.ts +++ b/testing-projects/jnxplus-e2e/tests/nx-gradle/spring-boot.spec.ts @@ -42,7 +42,7 @@ describe('nx-gradle spring-boot e2e', () => { }); await runNxCommandAsync( - `generate @jnxplus/nx-gradle:init --rootProjectName ${rootProjectName} --preset spring-boot --versionManagement version-catalog`, + `generate @jnxplus/nx-gradle:init --rootProjectName ${rootProjectName} --preset none --versionManagement version-catalog`, ); }, 120000);