Skip to content

Commit

Permalink
feat(nx-micronaut): add nx-micronaut plugin
Browse files Browse the repository at this point in the history
This new plugin adds first-class support for [Micronaut framework](https://micronaut.io/).
This will allow you (for example) to create cloud-native JVM-based applications in your Nx workspace.
  • Loading branch information
tinesoft committed Jul 3, 2022
1 parent 7a13720 commit 08d6099
Show file tree
Hide file tree
Showing 77 changed files with 2,469 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nrwl/nx/javascript"],
"rules": {}
},
{
"files": "*.json",
"parser": "jsonc-eslint-parser",
"rules": {}
}
]
}
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/BUG_REPORT.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ body:
- "@nxrocks/nx-spring-boot"
- "@nxrocks/nx-flutter"
- "@nxrocks/nx-quarkus"
- "@nxrocks/nx-micronaut"
validations:
required: true
- type: input
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/run-e2e-tests-nx-micronaut.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Run e2e Tests for nx-micronaut

on:
push:
branches: [ develop ]
paths: [ "nx.json", "package.json", "workspace.json", "packages/common/**", "packages/nx-micronaut/**" ]
pull_request:
branches: [ develop ]
paths: [ "nx.json", "package.json", "workspace.json", "packages/common/**", "packages/nx-micronaut/**" ]

jobs:
run_e2e:
name: Run e2e Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [16.x]
steps:
- name: Checkout Repo
uses: actions/checkout@v2

- name: Use Java
uses: actions/setup-java@v1
with:
java-version: 11

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- name: Cache Yarn
uses: actions/cache@v3
env:
cache-name: yarn
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ matrix.os }}-node-${{ matrix.node-version }}-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ matrix.os }}-node-${{ matrix.node-version }}-${{ env.cache-name }}-
- name: Install packages
run: yarn install --frozen-lockfile

- name: Run e2e tests
env:
NX_E2E_CI_CACHE_KEY: e2e-gha-${{ matrix.os }}-${{ matrix.node-version }}
NX_E2E_SKIP_BUILD_CLEANUP: ${{ 'true' }}
NX_E2E_SKIP_DAEMON_CLEANUP: ${{ 'true' }}
run: |
yarn ts-node -P ./tools/tsconfig.tools.json ./tools/patch-nx-project.ts
yarn run e2e nx-micronaut-e2e
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"eslint.validate": ["json"]
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Status | Name | Description
✅ | [nx-spring-boot](packages/nx-spring-boot) | [Nx](https://nx.dev) plugin to generate, run, package, build (and more) [Spring Boot](https://spring.io/projects/spring-boot) projects inside your Nx workspace
✅ | [nx-flutter](packages/nx-flutter) | [Nx](https://nx.dev) plugin adding first class support for [Flutter](https://flutter.dev) in your Nx workspace
✅ | [nx-quarkus](packages/nx-quarkus) | [Nx](https://nx.dev) plugin to generate, run, package, build (and more) [Quarkus](https://quarkus.io) projects inside your Nx workspace
✅ | [nx-micronaut](packages/nx-micronaut) | [Nx](https://nx.dev) plugin to generate, run, package, build (and more) [Micronaut](https://micronaut.io) projects inside your Nx workspace


## License
Expand Down
15 changes: 15 additions & 0 deletions e2e/nx-micronaut-e2e/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable */
export default {
displayName: 'nx-micronaut-e2e',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
transform: {
'^.+\\.[tj]s$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/e2e/nx-micronaut-e2e',
};
16 changes: 16 additions & 0 deletions e2e/nx-micronaut-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "e2e/nx-micronaut-e2e/src",
"targets": {
"e2e": {
"executor": "@nrwl/nx-plugin:e2e",
"options": {
"target": "nx-micronaut:build",
"jestConfig": "e2e/nx-micronaut-e2e/jest.config.ts"
}
}
},
"tags": [],
"implicitDependencies": ["nx-micronaut"]
}
179 changes: 179 additions & 0 deletions e2e/nx-micronaut-e2e/tests/nx-micronaut.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import {
checkFilesExist,
readFile,
readJson,
runNxCommandAsync,
tmpProjPath,
uniq,
} from '@nrwl/nx-plugin/testing';
import { ensureNxProjectWithDeps } from '@nxrocks/common/testing';

import { lstatSync } from 'fs';

describe('nx-micronaut e2e', () => {
const isWin = process.platform === "win32";

// Setting up individual workspaces per
// test can cause e2e runs to take a long time.
// For this reason, we recommend each suite only
// consumes 1 workspace. The tests should each operate
// on a unique project in the workspace, such that they
// are not dependant on one another.
beforeAll(() => {
ensureNxProjectWithDeps('@nxrocks/nx-micronaut', 'dist/packages/nx-micronaut',
[{ depPkgName: '@nxrocks/common', depDistPath: 'dist/packages/common' }]);
});

afterAll(() => {
// `nx reset` kills the daemon, and performs
// some work which can help clean up e2e leftovers
runNxCommandAsync('reset');
});

it('should create nx-micronaut with default options', async() => {
const prjName = uniq('nx-micronaut');
await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName}`
);

const resultClean= await runNxCommandAsync(`clean ${prjName}`);
expect(resultClean.stdout).toContain(`Executing command: ${isWin ? 'mvnw.bat' : './mvnw'} clean`)

expect(() =>
checkFilesExist(`apps/${prjName}/mvnw`,`apps/${prjName}/pom.xml`, `apps/${prjName}/README.md`)
).not.toThrow();

// make sure the build wrapper file is executable (*nix only)
if(!isWin) {
const execPermission = '755';
expect(
lstatSync(
tmpProjPath(`apps/${prjName}/mvnw`)
).mode & octal(execPermission)
).toEqual(octal(execPermission));
}

}, 200000);

it('should create nx-micronaut with given options', async() => {
const prjName = uniq('nx-micronaut');
const buildSystem = 'MAVEN';
const basePackage = 'com.tinesoft';
const features="graphql";

await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName} --projectType default --buildSystem=${buildSystem} --basePackage=${basePackage} --features=${features}`
);

const resultClean= await runNxCommandAsync(`clean ${prjName}`);
expect(resultClean.stdout).toContain(`Executing command: ${isWin ? 'mvnw.bat' : './mvnw'} clean`)

expect(() =>
checkFilesExist(
`apps/${prjName}/mvnw`,
`apps/${prjName}/pom.xml`,
`apps/${prjName}/README.md`,
`apps/${prjName}/src/main/java/com/tinesoft/${prjName.split('-')[0]}/Application.java`)
).not.toThrow();

const pomXml = readFile(`apps/${prjName}/pom.xml`);
expect(pomXml).toContain(`<groupId>${basePackage}.${prjName.split('-')[0]}</groupId>`);
expect(pomXml).toContain(`<artifactId>${prjName.split('-')[1]}</artifactId>`);

// make sure the build wrapper file is executable (*nix only)
if(!isWin) {
const execPermission = '755';
expect(
lstatSync(
tmpProjPath(`apps/${prjName}/mvnw`)
).mode & octal(execPermission)
).toEqual(octal(execPermission));
}

}, 200000);

describe('--buildSystem=GRADLE', () => {
it('should create a gradle micronaut project', async() => {
const prjName = uniq('nx-micronaut');

await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName} --projectType default --buildSystem GRADLE`
);

const resultClean= await runNxCommandAsync(`clean ${prjName}`);
expect(resultClean.stdout).toContain(`Executing command: ${isWin ? 'gradlew.bat' : './gradlew'} clean`)

expect(() =>
checkFilesExist(`apps/${prjName}/gradlew`,`apps/${prjName}/build.gradle`, `apps/${prjName}/README.md`)
).not.toThrow();

// make sure the build wrapper file is executable (*nix only)
if(!isWin) {
const execPermission = '755';
expect(
lstatSync(
tmpProjPath(`apps/${prjName}/gradlew`)
).mode & octal(execPermission)
).toEqual(octal(execPermission));
}

}, 200000);
});

describe('--buildSystem=GRADLE_KOTLIN', () => {
it('should create a gradle micronaut project with kotlin', async() => {
const prjName = uniq('nx-micronaut');

await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName} --projectType default --buildSystem GRADLE_KOTLIN`
);

const resultClean= await runNxCommandAsync(`clean ${prjName}`);
expect(resultClean.stdout).toContain(`Executing command: ${isWin ? 'gradlew.bat' : './gradlew'} clean`)

expect(() =>
checkFilesExist(`apps/${prjName}/gradlew`,`apps/${prjName}/build.gradle.kts`, `apps/${prjName}/README.md`)
).not.toThrow();

// make sure the build wrapper file is executable (*nix only)
if(!isWin) {
const execPermission = '755';
expect(
lstatSync(
tmpProjPath(`apps/${prjName}/gradlew`)
).mode & octal(execPermission)
).toEqual(octal(execPermission));
}

}, 200000);
});


describe('--directory', () => {
it('should create src in the specified directory', async () => {
const prjName = uniq('nx-micronaut');
await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName} --directory subdir`
);
expect(() =>
checkFilesExist(`apps/subdir/${prjName}/mvnw`,`apps/subdir/${prjName}/pom.xml`, `apps/subdir/${prjName}/README.md`)
).not.toThrow();
}, 120000);
});

describe('--tags', () => {
it('should add tags to the project', async () => {
const prjName = uniq('nx-micronaut');
await runNxCommandAsync(
`generate @nxrocks/nx-micronaut:new ${prjName} --tags e2etag,e2ePackage`
);
const project = readJson(`apps/${prjName}/project.json`);
expect(project.tags).toEqual(['e2etag', 'e2ePackage']);
}, 120000);
});

function octal(value: string | number): number {
if (typeof value === 'string') return parseInt(value, 8);
return value;
}
});
10 changes: 10 additions & 0 deletions e2e/nx-micronaut-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}
9 changes: 9 additions & 0 deletions e2e/nx-micronaut-e2e/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
}
Binary file added images/micronaut.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/nx-micronaut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/nx-micronaut.pxz
Binary file not shown.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"private": true,
"dependencies": {
"@swc/helpers": "~0.3.3",
"inquirer": "^8.2.0",
"js-yaml": "^4.1.0",
"node-fetch": "^2.6.1",
Expand All @@ -56,6 +57,7 @@
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@swc-node/register": "^1.4.2",
"@swc/cli": "~0.1.55",
"@swc/core": "^1.2.173",
"@types/fs-extra": "^9.0.13",
"@types/inquirer": "^8.1.3",
Expand All @@ -72,6 +74,7 @@
"fs-extra": "^10.0.0",
"husky": "^6.0.0",
"jest": "27.5.1",
"jsonc-eslint-parser": "^2.1.0",
"nx": "14.3.6",
"prettier": "2.6.2",
"semantic-release": "^19.0.2",
Expand All @@ -88,4 +91,3 @@
"url": "https://github.com/tinesoft/nxrocks.git"
}
}

2 changes: 1 addition & 1 deletion packages/nx-flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

Here is a list of some of the coolest features of the plugin:

- ✅ Generation of Flutter applications/packages/modules/plugins based on **Flutter CLI** API
- ✅ Generation of Flutter applications/packages/modules/plugins based on **Flutter cli** API
- ✅ Building, packaging, testing, etc your Flutter projects
- ✅ Integration with Nx's **dependency graph** (through `nx dep-graph` or `nx affected:dep-graph`): this allows you to **visualize** the dependencies of any Flutter projects inside your workspace, just like Nx natively does it for JS/TS-based projects!

Expand Down
25 changes: 25 additions & 0 deletions packages/nx-micronaut/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*", ".releaserc.js"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["./package.json", "./generators.json", "./executors.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nrwl/nx/nx-plugin-checks": "error"
}
}
]
}
7 changes: 7 additions & 0 deletions packages/nx-micronaut/.releaserc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { createScopedReleaseConfig } = require('../../tools/release');

module.exports = createScopedReleaseConfig({
projectScope: 'nx-micronaut',
projectRoot: 'packages/nx-micronaut',
buildOutput: 'dist/packages/nx-micronaut',
});
Loading

0 comments on commit 08d6099

Please sign in to comment.