From 093b5b57bfa85b1136134f00b7216aa516cfd801 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Tue, 22 Aug 2023 00:06:38 -0300 Subject: [PATCH 01/17] add documentation files --- ARCHITECTURE.md | 64 +++++++++++++++ CONTRIBUTING.md | 213 +----------------------------------------------- DEVELOPMENT.md | 192 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+), 209 deletions(-) create mode 100644 ARCHITECTURE.md create mode 100644 DEVELOPMENT.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 00000000000..b0cdbea43b6 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,64 @@ +# JHipster architecture + +## Yeoman basis + +Internally JHipster uses [yeoman](https://yeoman.io) as core. + +## File structure + +- `.blueprint` - development blueprint, used to generate and manage samples +- `.devcontainer` - vscode's devcontainer definitions +- `.github` - github configuration +- `.vscode` - vscode's configuration +- `bin` - jit executable and helper +- `cli` - (exported) cli implementation +- `generators/*` - (exported) generators + - `generator.m[tj]s` - generator implementation + - `index.m[tj]s` - generator exports. Must re-export generator as default export. + - `internal` - non-exported supporting libs + - `resources` - supporting resources + - `jdl` - generator's jdl specifications + - `support` - (exported) exported supporting libs + - `templates` - templates folder +- `jdl` - (exported) jdl parser implementation +- `rfcs` - (RFCs)[CONTRIBUTING.md#rfcs] +- `test` - package tests +- `test-integration` - CI related stuff. Samples, scripts. + +## Lifecycle + +- [Cli entrypoint](https://github.com/jhipster/generator-jhipster/blob/main/cli/jhipster.cjs) +- [Basic environment validation](https://github.com/jhipster/generator-jhipster/blob/main/cli/cli.mjs) +- [Cli arguments parsing and Environment bootstrap](https://github.com/jhipster/generator-jhipster/blob/main/cli/program.mjs) + - Lookup for Generators and Blueprints + - Build cli options and arguments definition + - Parse options and arguments +- Run Generator (start the Environment) passing options and arguments +- Run every task from the highest precedence priority until there is no more pending task + +https://github.com/jhipster/generator-jhipster/blob/main/generators/base/priorities.mjs +https://github.com/jhipster/generator-jhipster/blob/main/generators/base-application/priorities.mjs + +## Blueprints + +https://www.jhipster.tech/modules/extending-and-customizing/ +https://www.jhipster.tech/modules/creating-a-module/ +https://www.jhipster.tech/modules/creating-a-blueprint/ + +### Blueprint lifecycle + +## Generator Hierarchy + +### GeneratorBaseCore + +Adds custom apis to `yeoman-generator` and customizes the behavior. + +### GeneratorBase + +Adds Blueprint composing apis. + +### GeneratorApplication + +Adds Entities related apis. + +## JDL diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c607b77a4a3..6e2d244bc00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,6 @@ Are you ready to contribute to JHipster? We'd love to have you on board, and we - [Feature Requests](#feature) - [RFCs](#rfcs) - [Submission Guidelines](#submit) -- [Generator development setup](#setup) - [Coding Rules](#rules) - [Git Commit Guidelines](#commit) @@ -95,7 +94,7 @@ Before you submit your pull request consider the following guidelines: - Search [GitHub](https://github.com/jhipster/generator-jhipster/pulls?utf8=%E2%9C%93&q=is%3Apr) for an open or closed Pull Request that relates to your submission. -- If you want to modify the JHipster generator, read our [Generator development setup](#setup) +- If you want to modify the JHipster generator, read our [Development](DEVELOPMENT.md) - Make your changes in a new git branch ```shell @@ -207,221 +206,17 @@ from the main (upstream) repository: git pull --ff upstream main ``` -## Generator development setup - -JHipster is a [Yeoman Generator](http://yeoman.io/), so you must follow the [Yeoman authoring documentation](http://yeoman.io/authoring/) in order to be able to run and test your changes. - -Here are the most important steps. - -### Fork the generator-jhipster project - -Go to the [generator-jhipster project](https://github.com/jhipster/generator-jhipster) and click on the "fork" button. You can then clone your own fork of the project, and start working on it. - -[Please read the GitHub forking documentation for more information](https://help.github.com/articles/fork-a-repo) - -### Set `jhipster` command to use the cloned project - -Since v8 `generator-jhipster` is written in typescript. -To run it you need to compile to javascript or use a just-in-time compilation. - -#### Runnning jit executable - -The executable is located at `bin/jhipster.cjs`. -You can alias it to `jhipster` command: - -```shell -alias jhipster="GLOBAL_PATH/generator-jhipster/bin/jhipster.cjs" -``` - -#### Globally linked compiled package - -In your cloned `generator-jhipster` project, run `npm ci` and then run `npm link`. - -`npm ci` will do a clean installation of all the project dependencies and compile sources. -`npm run build` can be used to compile sources after each change. - -`npm link` will make a symbolic link from the global `node_modules` version to point to this folder, so when we run `jhipster`, you will now use the development version of JHipster. - -### Test generating applications - -For testing, you will want to generate an application, and there is a specific issue here: for each application, JHipster installs a local version of itself. This is made to enable several applications to each use a specific JHipster version (application A uses JHipster 3.1.0, and application B uses JHipster 3.2.0). - -To overcome this you need to run `npm link generator-jhipster` on the generated project folder as well, so that the local version has a symbolic link to the development version of JHipster. -Also add the option `--skip-jhipster-dependencies` to generate the application ignoring the JHipster dependencies (otherwise a released version will be installed each time npm install/ci is called). You can later on re-add the dependency with the command `jhipster --no-skip-jhipster-dependencies`. - -To put it in a nutshell, you need to: - -1. run `npm link` on the `generator-jhipster` project (link globally) or configure jit executable -2. run `jhipster --skip-jhipster-dependencies` on the generated application folder - -You can execute `jhipster --install-path` to check where jhipster is being executed from. - -You can test your setup by making a small change in your cloned generator, and running again on an existing JHipster project: - -For projects with jhipster third party library (i.e. react-jhipster, etc.) you need to run `npm link` on the library project as well, then npm link the original framework (i.e. react) from the generated project to the library project `cd react-jhipster && npm link /node_modules/react`. - -```shell -jhipster -``` - -Depending on which parts of the generator you have changed, do not forget to run jhipster command with the proper arguments e.g. when updating the entity template run: - -```shell -jhipster --with-entities -``` - -You should see your changes reflected in the generated project. - -Note: The generated project might not build properly in case the generator is using a -snapshot version of [jhipster/jhipster-bom](https://github.com/jhipster/jhipster-bom). This issue is mentioned in; https://github.com/jhipster/generator-jhipster/issues/9571. In -this case clone the jhipster/jhipster-bom project and build it using: - -```shell script -./mvnw clean install -Dgpg.skip=true -``` - -or on Windows: - -``` -.\mvnw.cmd clean install -D"gpg.skip=true" -``` - -### Use a text editor - -As modifying the JHipster generator includes modifying Java and JavaScript templates, most IDE will not work correctly. We recommend you use a text editor like [VSCode](https://code.visualstudio.com/) or [IntelliJ IDEA](https://www.jetbrains.com/idea/) to code your changes. The ESLint and EditorConfig extensions are recommended to help with respecting code conventions. - -### Use a debugger - -It is possible to debug JHipster's code using a Node.js debugger. To achieve this setup your debugger to launch `cli/jhipster.js`. - -#### Debugging with VSCode - -To start debugging JHipster with **VSCode**, open the generator code in your workspace and simply press F5 (or click the green arrow in the **Debug** menu reachable with Ctrl/Cmd+Shift+D). This will start the generator in debug mode and generate files in the [test-integration/samples/app-sample-dev](test-integration/samples/app-sample-dev) folder. - -It is also possible to debug sub generators by selecting one of the other debug options (for example `jhipster entity`). Those debug configurations are specified in the `.vscode/launch.json` file. - -## Generator tests and snapshots. - -Run every test with lint/prettier -`npm test` - -Run every test without lint/prettier -`npx esmocha` - -Update every test snapshot -`npm run update-snapshots` - -Run specific tests -`npx esmocha ` - -Run specific tests in series (improved error reporting) -`npx esmocha --no-parallel` - -Update specific test snapshot -`npm run update-snapshot -- ` or `npx esmocha --no-parallel --update-snapshot` - -Fixing lint and prettier errors -`npm run lint-fix` - -## Generating and testing samples - -Sample generating is provided by `generator-jhipster` local blueprint which we will refer as `dev blueprint`. -The dev blueprint is enabled by running jhipster in JIT mode (executing `./bin/jhipster.cjs` file relative to this file). - -### Generating samples using dev blueprint - -`jhipster generate-sample ng-default` will generate the `ng-default` sample at current folder. - -#### Daily builds samples - -Daily builds samples are prefixed with `daily-`. - -#### Samples folder - -A common samples folder will be used if `--global` option is used like `jhipster generate-sample ng-default --global`. -At first execution a prompt will ask for the samples folder, the choosen value will be reused at next executions. -At samples folder, a `jhipster-samples.code-workspace` is generated. It provides a single vscode workspace for `generator-jhipster` and samples generated at the samples folder. It's very used for quick looks. - -### Testing samples - -CI tests uses the following commands: - -``` -npm ci:backend:test -npm ci:frontend:test -npm run ci:e2e:package # Builds the application -npm run ci:e2e:prepare # Starts the application using docker -npm run ci:e2e:run # Runs e2e tests -``` - -## DX using vscode - -`generator-jhipster` add a series of vscode configurations for a better developer experience. - -### Development Containers - -Container is built using java, node and npm recommended by `generator-jhipster`. -Once up, you should have the stack maintainers recommends. - -### Execution shortcuts - -Shortcuts are provided to easily generate integration tests samples. - -- go to `Execute and Debug`. -- select the sample's github workflow. -- run the shortcut. -- select the sample. -- sample is generated at `../jhipster-samples/` folder relative the `generator-jhipster` folder. - -Some daily builds samples are available too. - -### Generators tests - -At test tab you can run and debug individual test. - -## Running integration tests locally - -You can run the builds locally by following below commands - -Go into the `test-integration` folder with `cd test-integration` from the generator source code root folder - -Run `./generate-sample.sh [folder] [sample_name:optional] [type of entity]` - -This will create a folder with configuration and entities. Then, you can generate manually a JHipster project and test it. - -Command name can be as below - - `list`: List all sample names - `generate`: Generate the sample - ## Coding Rules To ensure consistency throughout the source code, keep these rules in mind as you are working: - All features or bug fixes **must be tested** by one or more tests. -- All files must follow the [.editorconfig file](http://editorconfig.org/) located at the root of the JHipster generator project. Please note that generated projects use the same `.editorconfig` file, so that both the generator and the generated projects share the same configuration. -- Java files **must be** formatted using IntelliJ IDEA default code style. -- Generators JavaScript files **must follow** the eslint configuration defined at the project root, which is based on [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript). -- Any client side feature/change should be done for both Angular and react clients -- Web apps JavaScript files **must follow** [Google's JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html). -- Angular Typescript files **must follow** the [Official Angular style guide](https://angular.io/styleguide). -- React/Redux Typescript files **may follow** the [React/Redux Typescript guide](https://github.com/piotrwitek/react-redux-typescript-guide). +- Most `generator-jhipster` files **must follow** the eslint and prettier configuration defined at the project root, which is based on [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript). +- Generated project files **must follow** the eslint and prettier configuration defined at the generated project root, which is based on each technology rules. +- EJS files uses a 2 spaces identation for templates logic and follows the generated file rules for the templating parts. Please ensure to run `npm run lint` and `npm test` on the project root before submitting a pull request. You can also run `npm run lint-fix` to fix some of the lint issues automatically. -## Template Guidelines - -The template engine used by yeoman is [EJS](http://ejs.co/), its syntax is fairly simple. -For simple code (few lines), logic can be embedded in the main file but if logic becomes more complex it's better to externalise the JS fragment to a sub template included by the first one and located in same folder. - -Sub templates should be named with the `ejs` extension because it's the default one, it enables editors to apply correct syntax highlighting and it enables us to use a very concise syntax: - - <%- include('../common/field_validators', {field, reactive}); -%> - -This statement means that [_PersistClass_.java.jhi.jakarta_validation.ejs](generators/server/templates/entity/src/main/java/package/domain/_PersistClass_.java.jhi.jakarta_validation.ejs) template includes [field_validators.ejs](generators/server/templates/entity/src/main/java/package/common/field_validators.ejs) sub template. - -Sub templates can be unit tested. - ## Git Commit Guidelines We have rules over how our git commit messages must be formatted. Please ensure to [squash](https://help.github.com/articles/about-git-rebase/#commands-available-while-rebasing) unnecessary commits so that your commit history is clean. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 00000000000..61516b8f451 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,192 @@ +# JHipster development + +- [Generator development setup](#setup) + +## Generator development setup + +JHipster is a [Yeoman Generator](http://yeoman.io/), so you must follow the [Yeoman authoring documentation](http://yeoman.io/authoring/) in order to be able to run and test your changes. + +Here are the most important steps. + +### Fork the generator-jhipster project + +Go to the [generator-jhipster project](https://github.com/jhipster/generator-jhipster) and click on the "fork" button. You can then clone your own fork of the project, and start working on it. + +[Please read the GitHub forking documentation for more information](https://help.github.com/articles/fork-a-repo) + +### Set `jhipster` command to use the cloned project + +Since v8 `generator-jhipster` is written in typescript. +To run it you need to compile to javascript or use a just-in-time compilation. + +#### Runnning jit executable + +The executable is located at `bin/jhipster.cjs`. +You can alias it to `jhipster` command: + +```shell +alias jhipster="GLOBAL_PATH/generator-jhipster/bin/jhipster.cjs" +``` + +#### Globally linked compiled package + +In your cloned `generator-jhipster` project, run `npm ci` and then run `npm link`. + +`npm ci` will do a clean installation of all the project dependencies and compile sources. +`npm run build` can be used to compile sources after each change. + +`npm link` will make a symbolic link from the global `node_modules` version to point to this folder, so when we run `jhipster`, you will now use the development version of JHipster. + +### Test generating applications + +For testing, you will want to generate an application, and there is a specific issue here: for each application, JHipster installs a local version of itself. This is made to enable several applications to each use a specific JHipster version (application A uses JHipster 3.1.0, and application B uses JHipster 3.2.0). + +To overcome this you need to run `npm link generator-jhipster` on the generated project folder as well, so that the local version has a symbolic link to the development version of JHipster. +Also add the option `--skip-jhipster-dependencies` to generate the application ignoring the JHipster dependencies (otherwise a released version will be installed each time npm install/ci is called). You can later on re-add the dependency with the command `jhipster --no-skip-jhipster-dependencies`. + +To put it in a nutshell, you need to: + +1. run `npm link` on the `generator-jhipster` project (link globally) or configure jit executable +2. run `jhipster --skip-jhipster-dependencies` on the generated application folder + +You can execute `jhipster --install-path` to check where jhipster is being executed from. + +You can test your setup by making a small change in your cloned generator, and running again on an existing JHipster project: + +For projects with jhipster third party library (i.e. react-jhipster, etc.) you need to run `npm link` on the library project as well, then npm link the original framework (i.e. react) from the generated project to the library project `cd react-jhipster && npm link /node_modules/react`. + +```shell +jhipster +``` + +Depending on which parts of the generator you have changed, do not forget to run jhipster command with the proper arguments e.g. when updating the entity template run: + +```shell +jhipster --with-entities +``` + +You should see your changes reflected in the generated project. + +Note: The generated project might not build properly in case the generator is using a +snapshot version of [jhipster/jhipster-bom](https://github.com/jhipster/jhipster-bom). This issue is mentioned in; https://github.com/jhipster/generator-jhipster/issues/9571. In +this case clone the jhipster/jhipster-bom project and build it using: + +```shell script +./mvnw clean install -Dgpg.skip=true +``` + +or on Windows: + +``` +.\mvnw.cmd clean install -D"gpg.skip=true" +``` + +### Use a text editor + +As modifying the JHipster generator includes modifying Java and JavaScript templates, most IDE will not work correctly. We recommend you use a text editor like [VSCode](https://code.visualstudio.com/) or [IntelliJ IDEA](https://www.jetbrains.com/idea/) to code your changes. The ESLint and EditorConfig extensions are recommended to help with respecting code conventions. + +### Use a debugger + +It is possible to debug JHipster's code using a Node.js debugger. To achieve this setup your debugger to launch `cli/jhipster.js`. + +#### Debugging with VSCode + +To start debugging JHipster with **VSCode**, open the generator code in your workspace and simply press F5 (or click the green arrow in the **Debug** menu reachable with Ctrl/Cmd+Shift+D). This will start the generator in debug mode and generate files in the [test-integration/samples/app-sample-dev](test-integration/samples/app-sample-dev) folder. + +It is also possible to debug sub generators by selecting one of the other debug options (for example `jhipster entity`). Those debug configurations are specified in the `.vscode/launch.json` file. + +## Generator implementation + +### important config objects + +## Generator tests and snapshots + +Run every test with lint/prettier +`npm test` + +Run every test without lint/prettier +`npx esmocha` + +Update every test snapshot +`npm run update-snapshots` + +Run specific tests +`npx esmocha ` + +Run specific tests in series (improved error reporting) +`npx esmocha --no-parallel` + +Update specific test snapshot +`npm run update-snapshot -- ` or `npx esmocha --no-parallel --update-snapshot` + +Fixing lint and prettier errors +`npm run lint-fix` + +## Generating and testing samples + +Sample generating is provided by `generator-jhipster` local blueprint which we will refer as `dev blueprint`. +The dev blueprint is enabled by running jhipster in JIT mode (executing `./bin/jhipster.cjs` file relative to this file). + +### Generating samples using dev blueprint + +`jhipster generate-sample ng-default` will generate the `ng-default` sample at current folder. + +#### Daily builds samples + +Daily builds samples are prefixed with `daily-`. + +#### Samples folder + +A common samples folder will be used if `--global` option is used like `jhipster generate-sample ng-default --global`. +At first execution a prompt will ask for the samples folder, the choosen value will be reused at next executions. +At samples folder, a `jhipster-samples.code-workspace` is generated. It provides a single vscode workspace for `generator-jhipster` and samples generated at the samples folder. It's very used for quick looks. + +### Testing samples + +CI tests uses the following commands: + +``` +npm ci:backend:test +npm ci:frontend:test +npm run ci:e2e:package # Builds the application +npm run ci:e2e:prepare # Starts the application using docker +npm run ci:e2e:run # Runs e2e tests +``` + +## DX using vscode + +`generator-jhipster` add a series of vscode configurations for a better developer experience. + +### Development Containers + +Container is built using java, node and npm recommended by `generator-jhipster`. +Once up, you should have the stack maintainers recommends. + +### Execution shortcuts + +Shortcuts are provided to easily generate integration tests samples. + +- go to `Execute and Debug`. +- select the sample's github workflow. +- run the shortcut. +- select the sample. +- sample is generated at `../jhipster-samples/` folder relative the `generator-jhipster` folder. + +Some daily builds samples are available too. + +### Generators tests + +At test tab you can run and debug individual test. + +## Template Guidelines + +The template engine used by yeoman is [EJS](http://ejs.co/), its syntax is fairly simple. +For simple code (few lines), logic can be embedded in the main file but if logic becomes more complex it's better to externalise the JS fragment to a sub template included by the first one and located in same folder. + +Sub templates should be named with the `ejs` extension because it's the default one, it enables editors to apply correct syntax highlighting and it enables us to use a very concise syntax: + + <%- include('../common/field_validators', {field, reactive}); -%> + +This statement means that [_PersistClass_.java.jhi.jakarta_validation.ejs](generators/server/templates/entity/src/main/java/package/domain/_PersistClass_.java.jhi.jakarta_validation.ejs) template includes [field_validators.ejs](generators/server/templates/entity/src/main/java/package/common/field_validators.ejs) sub template. + +Sub templates can be unit tested. From 2460f036446c6912a3cd5bef992c0708e93b9375 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Fri, 25 Aug 2023 09:04:01 -0300 Subject: [PATCH 02/17] cleanup CONTRIBUTING --- CONTRIBUTING.md | 110 +----------------------------------------------- 1 file changed, 2 insertions(+), 108 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e2d244bc00..fcb2cdc2e2d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,124 +95,18 @@ Before you submit your pull request consider the following guidelines: - Search [GitHub](https://github.com/jhipster/generator-jhipster/pulls?utf8=%E2%9C%93&q=is%3Apr) for an open or closed Pull Request that relates to your submission. - If you want to modify the JHipster generator, read our [Development](DEVELOPMENT.md) -- Make your changes in a new git branch - - ```shell - git checkout -b my-fix-branch main - ``` - -- Create your patch, **including appropriate test cases**. - Follow our [Coding Rules](#rules). -- Generate a new JHipster project, and ensure that all tests pass - - ```shell - mvnw verify -Pprod - ``` - -- Test that the new project runs correctly: - - ```shell - mvnw spring-boot:run - ``` - -- You can generate our Continuous Integration (with GitHub Actions and Azure Pipelines) by following [this](#running-integration-tests-locally) - -- Commit your changes using a descriptive commit message that follows our - [commit message conventions](#commit-message-format). - - ```shell - git commit -a - ``` - - Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files. - -- Push your branch to GitHub: - - ```shell - git push origin my-fix-branch - ``` - - In GitHub, send a pull request to `jhipster/generator-jhipster:main`. -- If we suggest changes then - - - Make the required updates. - - Re-run the JHipster tests on your sample generated project to ensure tests are still passing. - - Rebase your branch and force push to your GitHub repository (this will update your Pull Request): - - ```shell - git rebase main -i - git push -f - ``` +- **Every CI tests must pass**. That's it! Thank you for your contribution! -#### Resolving merge conflicts ("This branch has conflicts that must be resolved") - -Sometimes your PR will have merge conflicts with the upstream repository's main branch. There are several ways to solve this but if not done correctly this can end up as a true nightmare. So here is one method that works quite well. - -- First, fetch the latest information from the main - - ```shell - git fetch upstream - ``` - -- Rebase your branch against the upstream/main - - ```shell - git rebase upstream/main - ``` - -- Git will stop rebasing at the first merge conflict and indicate which file is in conflict. Edit the file, resolve the conflict then - - ```shell - git add - git rebase --continue - ``` - -- The rebase will continue up to the next conflict. Repeat the previous step until all files are merged and the rebase ends successfully. -- Re-run the JHipster tests on your sample generated project to ensure tests are still passing. -- Force push to your GitHub repository (this will update your Pull Request) - - ```shell - git push -f - ``` - -#### After your pull request is merged - -After your pull request is merged, you can safely delete your branch and pull the changes -from the main (upstream) repository: - -- Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows: - - ```shell - git push origin --delete my-fix-branch - ``` - -- Check out the main branch: - - ```shell - git checkout main -f - ``` - -- Delete the local branch: - - ```shell - git branch -D my-fix-branch - ``` - -- Update your main with the latest upstream version: - - ```shell - git pull --ff upstream main - ``` - ## Coding Rules To ensure consistency throughout the source code, keep these rules in mind as you are working: - All features or bug fixes **must be tested** by one or more tests. -- Most `generator-jhipster` files **must follow** the eslint and prettier configuration defined at the project root, which is based on [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript). -- Generated project files **must follow** the eslint and prettier configuration defined at the generated project root, which is based on each technology rules. +- Most files formatting are checked by prettier and eslint. - EJS files uses a 2 spaces identation for templates logic and follows the generated file rules for the templating parts. Please ensure to run `npm run lint` and `npm test` on the project root before submitting a pull request. You can also run `npm run lint-fix` to fix some of the lint issues automatically. From c016e64a0ae4a7b85dbf03fbd79b407cb35a5427 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Fri, 15 Sep 2023 16:18:40 -0300 Subject: [PATCH 03/17] add some generator and blueprint information --- ARCHITECTURE.md | 316 +++++++++++++++++++++++++++++++++++++++++++++--- BLUEPRINTS.md | 64 ++++++++++ 2 files changed, 360 insertions(+), 20 deletions(-) create mode 100644 BLUEPRINTS.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index b0cdbea43b6..5156808962c 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -6,24 +6,25 @@ Internally JHipster uses [yeoman](https://yeoman.io) as core. ## File structure -- `.blueprint` - development blueprint, used to generate and manage samples -- `.devcontainer` - vscode's devcontainer definitions -- `.github` - github configuration -- `.vscode` - vscode's configuration -- `bin` - jit executable and helper -- `cli` - (exported) cli implementation -- `generators/*` - (exported) generators - - `generator.m[tj]s` - generator implementation - - `index.m[tj]s` - generator exports. Must re-export generator as default export. - - `internal` - non-exported supporting libs - - `resources` - supporting resources - - `jdl` - generator's jdl specifications - - `support` - (exported) exported supporting libs - - `templates` - templates folder -- `jdl` - (exported) jdl parser implementation -- `rfcs` - (RFCs)[CONTRIBUTING.md#rfcs] -- `test` - package tests -- `test-integration` - CI related stuff. Samples, scripts. +- `.blueprint` - development blueprint, used to generate and manage samples +- `.devcontainer` - vscode's devcontainer definitions +- `.github` - github configuration +- `.vscode` - vscode's configuration +- `bin` - jit executable and helper +- `cli` - (exported) cli implementation +- `generators/*` - (exported) generators + - `command.m[tj]s` - cli options, cli arguments definitions + - `generator.m[tj]s` - generator implementation + - `index.m[tj]s` - generator exports. Must re-export generator as default export and the command + - `internal` - non-exported supporting libs + - `resources` - supporting resources + - `jdl` - generator's jdl specifications + - `support` - (exported) exported supporting libs + - `templates` - templates folder +- `jdl` - (exported) jdl parser implementation +- `rfcs` - (RFCs)[CONTRIBUTING.md#rfcs] +- `test` - package tests +- `test-integration` - CI related stuff. Samples, scripts. ## Lifecycle @@ -36,8 +37,283 @@ Internally JHipster uses [yeoman](https://yeoman.io) as core. - Run Generator (start the Environment) passing options and arguments - Run every task from the highest precedence priority until there is no more pending task -https://github.com/jhipster/generator-jhipster/blob/main/generators/base/priorities.mjs -https://github.com/jhipster/generator-jhipster/blob/main/generators/base-application/priorities.mjs +### Priorities + +#### Initializing (yeoman) + +Initial generator information. + +- say generator specific hello +- initial environment checks +- argument and options loading + +``` + get [Generator.INITIALIZING]() { + return this.asInitializingTaskGroup() { + sayHelloTask() { + this.log.info('Welcome to your generator'); + }, + envChecks() { + checkNode(); + checkDocker(); + }, + async loadOptions() { + this.parseJHipsterArguments(command.arguments); + this.parseJHipsterOptions(command.options); + }, + } + } +``` + +#### Prompting (yeoman) + +Prompt for configuration. + +TODO + +#### Configuring (yeoman) + +Check and fix configurations. + +``` + get [Generator.CONFIGURING]() { + return this.asConfiguringTaskGroup() { + checkConfig() { + if (this.jhipsterConfigWithDefaults.reactive && this.jhipsterConfigWithDefaults.cacheProvider !== 'no') { + this.log.warn("Reactive applications doesn't support cache. Disabling"); + this.jhipsterConfig.cacheProvider = 'no'; + } + }, + } + } +``` + +#### Composing (base) + +Compose with other generators. + +``` + get [Generator.COMPOSING]() { + return this.asComposingTaskGroup() { + composing() { + if (this.jhipsterConfigWithDefaults.clientFramework === 'angular') { + this.composeWithJHipster('angular'); + } + }, + } + } +``` + +#### Loading (base) + +Load configuration. + +``` + get [Generator.LOADING]() { + return this.asLoadingTaskGroup() { + loading({ application }) { + application.myCustomConfig = this.jhipsterConfig.myCustomConfig; + application.myBlueprintCustomConfig = this.blueprintConfig.myBlueprintCustomConfig; + }, + } + } +``` + +#### Preparing (base) + +Generate properties to improve understanding. + +``` + get [Generator.PREPARING]() { + return this.asPreparingTaskGroup() { + preparing({ application }) { + application.myCustomConfigFoo = this.jhipsterConfig.myCustomConfig === 'foo'; + application.myCustomConfigBar = this.jhipsterConfig.myCustomConfig === 'bar'; + application.myCustomConfigNo = !this.jhipsterConfig.myCustomConfig || this.jhipsterConfig.myCustomConfig === 'no'; + }, + } + } +``` + +#### Configuring each entity (base-application) + +Configure and check entity's configuration. + +``` + get [Generator.CONFIGURING_EACH_ENTITY]() { + return this.asConfiguringEachEntityTaskGroup() { + configuring({ application, entityConfig }) { + if (application.searchEngineNo && entityConfig.searchEngine && entityConfig.searchEngine !== 'no') { + this.log.warn("Search engine cannot be enabled at entity because it's disabled at application"); + entityConfig.searchEngine = 'no'; + } + }, + } + } +``` + +#### Loading entities (base-application) + +Usually empty the entire entity configuration is loaded by default. + +#### Preparing each entity (base-application) + +Generate properties to improve understanding at entity level. + +``` + get [Generator.PREPARING_EACH_ENTITY]() { + return this.asPreparingEachEntityTaskGroup() { + preparing({ application, entity }) { + entity.dtoMapstruct = entity.dto === 'mapstruct'; + }, + } + } +``` + +#### Preparing each entity field (base-application) + +Generate properties to improve understanding at field level. + +``` + get [Generator.PREPARING_EACH_ENTITY_FIELD]() { + return this.asPreparingEachEntityFieldTaskGroup() { + preparing({ application, entity, field }) { + field.technologyFieldTypeIntegerMap = field.fieldType === 'Integer'; + }, + } + } +``` + +#### Preparing each entity relationship (base-application) + +Generate properties to improve understanding at relationship level. + +``` + get [Generator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { + return this.asPreparingEachEntityRelationshipTaskGroup() { + preparing({ application, entity, relationship }) { + relationship.technologyRelationshipDbName = relationship.relationshipTypeOneToOne ? 'foo' : 'bar'; + }, + }; + } +``` + +#### Default (yeoman) + +Generate properties to improve understanding that depends on others properties. + +``` + get [Generator.DEFAULT]() { + return this.asDefaultTaskGroup() { + preparing({ application, entities }) { + application.hasEntityFieldInteger = entities.some(entity => entity.fields.some(field => field.fieldTypeInteger)); + }, + }; + } +``` + +#### Writing (yeoman) + +Write files to in memory file system. + +There are a lot of apis to write files, copy files, delete files. +`writeFiles` is the most used at official generators. + +``` + get [Generator.WRITING]() { + return this.asWritingTaskGroup({ + writingTask({ application }) { + this.writeFiles({ + blocks: [ + { + condition: ctx => ctx.shouldWrite, + templates: ['template.file'], + } + ], + context: application, + }); + }, + }); + } +``` + +#### Writing entities (base-application) + +Write entity files to in memory file system. + +Entities writing is a separed priority to keep workflow sane when using options like `--skip-application` and `--single-entity`. + +``` + get [Generator.WRITING_ENTITIES]() { + return this.asWritingTaskGroup({ + writingTask({ application, entities }) { + for (const entity of entities) { + this.writeFiles({ + blocks: [ + { + condition: ctx => ctx.shouldWrite, + templates: ['entity.template.file'], + } + ], + context: { ...application, ...entity }, + }); + } + }, + }); + } +``` + +#### Post writing (base) + +Injects code in the generated source + +##### Injecting code with provided apis (needles) + +JHipster adds apis to some code injection. + +``` + get [Generator.POST_WRITING]() { + return this.asPostWritingTaskGroup({ + postWritingTask({ source }) { + source.someProvidedInjectionApi({ code: 'some code' }); + } + }); + } +``` + +##### Custom code injection + +Every file can be edited manually. + +``` + get [Generator.POST_WRITING]() { + return this.asPostWritingTaskGroup({ + postWritingTask({ source }) { + this.editFile('path/to/some/file', content => content.replaceAll('some content', 'another content')); + } + }); + } +``` + +#### Install (yeoman) + +Usually empty. +Install task is queued by detecting `package.json` changes. + +#### End (yeoman) + +Print generator result and info. + +``` + get [Generator.END]() { + return this.asEndTaskGroup() { + preparing({ application }) { + this.log.success('Tech application generated successfully'); + this.log.log(`Start the application running 'npm run start:app'`); + }, + }; + } +``` ## Blueprints diff --git a/BLUEPRINTS.md b/BLUEPRINTS.md new file mode 100644 index 00000000000..2a99e97f01b --- /dev/null +++ b/BLUEPRINTS.md @@ -0,0 +1,64 @@ +# JHipster Blueprints + +Blueprints allows to add new features or change current features. + +## Creating a Blueprint + +``` +jhipster generate-blueprint +``` + +When creating blueprints it's cleaner to have the blueprint forwarding to a custom generator. +Example [jOOQ Blueprint](https://github.com/jhipster/generator-jhipster-jooq/blob/ce48a06a2b031013383db01cc787bbe94aa2c683/generators/server/generator.mjs) + +## Maintaining a Blueprint + +### Upgrading to a new JHipster version + +#### Install a new `generator-jhipster` version + +Main branch will be used as example. +Go to the blueprint folder and run: + +``` +npm install jhipster/generator-jhipster#main +``` + +If conflict happens you can try to recreate `node_modules` and `package-lock.json`. + +``` +rm -rf node_modules +rm package-lock.json +``` + +#### Syncing the generated blueprint + +Each JHipster version brings updated dependencies. +You should regenerate the blueprint to update dependencies. + +``` +npx jhipster generate-blueprint +``` + +When updating from a minor jhipster version, you probably will want to ignore (press i) to every generator and test conflict. +Ignore (i option instead of s) will store the file at `.yo-resolve` so that following `generate-blueprint` executions will ignore those files by default. + +From time to time generate-blueprint may generate different code. +So regenerate every file ignoring `.yo-resolve` executing `jhipster generate-blueprint --skip-yo-resolve` and check the differences. + +### Blueprint dependencies + +`generator-jhipster` have every dependency using an exact version. +If the blueprint uses exact versions too, duplicated dependencies with different versions will be added to `node_modules`. +For this reason try to _avoid exact version at blueprint dependencies_ and disable auto updates since dependencies will be updated every time the blueprint is regenerated using `generate-blueprint`. + +### Upgrading from v7 to v8 + +- `entity-*` generators were dropped and the replacements are entity's specific priorities at the technology specific generator (server, angular, spring-data-relational, ...). + Motivation can be found at https://github.com/jhipster/generator-jhipster/blob/main/rfcs/4-jhipster-rfc-entity-as-core.md. +- priorities names are static constants at the generator class. + `get initializing() {}` -> `get [Generator.INITIALIZING]() {}` + Motivation can be found at https://github.com/jhipster/generator-jhipster/blob/main/rfcs/3-jhipster-rfc-unambiguous-priorities.md. +- many property migration can be warned by enabling `jhipster7Migration` feature at the constructor. +- needles are not implemented in the generator base anymore. + They are injected at source object provided at some priorities and used like https://github.com/jhipster/generator-jhipster/blob/6373c9c76e57d01c4c1451a276f0d78bfbdd2c42/generators/spring-cache/generator.mts#L97-L101 From ad7f60785d467eb696479e705f64bc16fa00a966 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sat, 21 Oct 2023 17:10:16 -0300 Subject: [PATCH 04/17] Update BLUEPRINTS.md --- BLUEPRINTS.md | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/BLUEPRINTS.md b/BLUEPRINTS.md index 2a99e97f01b..cb303d3107d 100644 --- a/BLUEPRINTS.md +++ b/BLUEPRINTS.md @@ -8,39 +8,23 @@ Blueprints allows to add new features or change current features. jhipster generate-blueprint ``` -When creating blueprints it's cleaner to have the blueprint forwarding to a custom generator. -Example [jOOQ Blueprint](https://github.com/jhipster/generator-jhipster-jooq/blob/ce48a06a2b031013383db01cc787bbe94aa2c683/generators/server/generator.mjs) +When creating blueprints it's cleaner to have the blueprint forwarding to a custom generator and keep main generators like client/common/server with customizations. +Example [jOOQ Blueprint](https://github.com/jhipster/generator-jhipster-jooq/blob/ce48a06a2b031013383db01cc787bbe94aa2c683/generators/server/generator.mjs#L21) ## Maintaining a Blueprint ### Upgrading to a new JHipster version -#### Install a new `generator-jhipster` version - -Main branch will be used as example. -Go to the blueprint folder and run: - -``` -npm install jhipster/generator-jhipster#main -``` - -If conflict happens you can try to recreate `node_modules` and `package-lock.json`. - -``` -rm -rf node_modules -rm package-lock.json -``` - -#### Syncing the generated blueprint +#### Upgrading and syncing the generated blueprint Each JHipster version brings updated dependencies. You should regenerate the blueprint to update dependencies. ``` -npx jhipster generate-blueprint +npx --package generator-jhipster@x.x.x jhipster generate-blueprint ``` -When updating from a minor jhipster version, you probably will want to ignore (press i) to every generator and test conflict. +When updating from a minor jhipster version, you probably will want to ignore (press s) to every generator and test conflict. Ignore (i option instead of s) will store the file at `.yo-resolve` so that following `generate-blueprint` executions will ignore those files by default. From time to time generate-blueprint may generate different code. From 174db09b2be6562e70b65f0d2a92e022f8d8ee57 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sat, 21 Oct 2023 22:02:53 -0300 Subject: [PATCH 05/17] Update BLUEPRINTS.md --- BLUEPRINTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLUEPRINTS.md b/BLUEPRINTS.md index cb303d3107d..37edc36d333 100644 --- a/BLUEPRINTS.md +++ b/BLUEPRINTS.md @@ -21,7 +21,7 @@ Each JHipster version brings updated dependencies. You should regenerate the blueprint to update dependencies. ``` -npx --package generator-jhipster@x.x.x jhipster generate-blueprint +npx --package generator-jhipster@latest jhipster generate-blueprint ``` When updating from a minor jhipster version, you probably will want to ignore (press s) to every generator and test conflict. From 18a73b07bc76bbd8ab7eac481bc26129aeaeb51e Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sun, 22 Oct 2023 13:52:34 -0300 Subject: [PATCH 06/17] Create Readme with customizations. --- generators/spring-data-relational/README.md | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 generators/spring-data-relational/README.md diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md new file mode 100644 index 00000000000..cfd4363e6d0 --- /dev/null +++ b/generators/spring-data-relational/README.md @@ -0,0 +1,53 @@ +# SQL/spring-data-relational sub-generador + +// TODO move first customizing and sub titles to app README. +## Customizing + +JHipster implementation allows you to override almost every aspect of the generation process. + +### Entities + +Every annotation is loaded as entities properties and will be used at generation process. + +```jdl +@CustomsProp1(customValue) +entity Bar {} +``` + +`.jhipster/Bar.json`: +```json +{ + "name": "Bar", + "options": { + "customsProp1": "customValue" + } +} +``` + +#### Notable customizations + +##### Label + +``` +@EntityClassHumanized("Departamento") +@EntityClassPluralHumanized("Departamentos") +entity Department {} +``` + +## Customizing + +Customizing basics can be found at [Customizing](../app/README.md#customizing) + +### Notable relationships customizations + +#### Eager loading relationships + +JHipster UI uses only the id and `otherEntityFieldName` properties, by default only fields used by the UI will be fetched. + +```jdl +relationship OneToMany { + @RelationshipEagerLoad Bar to @RelationshipEagerLoad Foo +} +``` + +Related issues: (#23917)[https://github.com/jhipster/generator-jhipster/issues/23917] From 73e1dc43e3079c47c5b0588974110ca30d9abb56 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sun, 22 Oct 2023 13:56:57 -0300 Subject: [PATCH 07/17] Update README.md --- generators/spring-data-relational/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md index cfd4363e6d0..12fce92523b 100644 --- a/generators/spring-data-relational/README.md +++ b/generators/spring-data-relational/README.md @@ -34,6 +34,24 @@ entity Bar {} entity Department {} ``` +### Fields + +TODO add jdl and json examples + +#### Notable customizations + +##### Label + +TODO add humanized name example + +### Relationships + +#### Notable customizations + +##### Label + +TODO add humanized name example + ## Customizing Customizing basics can be found at [Customizing](../app/README.md#customizing) From 74e3903c710f07776e034b863f3eb9f213b0db6c Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sun, 22 Oct 2023 14:12:32 -0300 Subject: [PATCH 08/17] Update README.md --- generators/spring-data-relational/README.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md index 12fce92523b..37fafe206db 100644 --- a/generators/spring-data-relational/README.md +++ b/generators/spring-data-relational/README.md @@ -5,6 +5,8 @@ JHipster implementation allows you to override almost every aspect of the generation process. +[SQL/spring-data-relational customizations](https://github.com/jhipster/generator-jhipster/blob/skip_ci-architecture/generators/spring-data-relational/README.md#sqlspring-data-relational-sub-generador) + ### Entities Every annotation is loaded as entities properties and will be used at generation process. @@ -52,13 +54,10 @@ TODO add humanized name example TODO add humanized name example -## Customizing +##### Eager loading relationships -Customizing basics can be found at [Customizing](../app/README.md#customizing) - -### Notable relationships customizations - -#### Eager loading relationships +Currently appliable to SQL/spring-data-relational with partial support at MongoDb/spring-data-mongodb. +Neo4j eager loads every relationship by default. JHipster UI uses only the id and `otherEntityFieldName` properties, by default only fields used by the UI will be fetched. @@ -69,3 +68,13 @@ relationship OneToMany { ``` Related issues: (#23917)[https://github.com/jhipster/generator-jhipster/issues/23917] + +## Customizing + +Customizing basics can be found at [Customizing](../app/README.md#customizing) + +### Notable relationships customizations + +#### Cascading + +TODO add @Cascade example From d8d4c42a8378635c3e397508f93690e48bb936c6 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sun, 22 Oct 2023 14:34:08 -0300 Subject: [PATCH 09/17] Update README.md --- generators/spring-data-relational/README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md index 37fafe206db..a5896382e21 100644 --- a/generators/spring-data-relational/README.md +++ b/generators/spring-data-relational/README.md @@ -7,6 +7,22 @@ JHipster implementation allows you to override almost every aspect of the genera [SQL/spring-data-relational customizations](https://github.com/jhipster/generator-jhipster/blob/skip_ci-architecture/generators/spring-data-relational/README.md#sqlspring-data-relational-sub-generador) +### Application + +JDL doesn't support annotations, customizations must be done through local blueprint. + +`.blueprint/app/generator.mjs` (to create a local blueprint follow https://www.jhipster.tech/modules/creating-a-blueprint/#local-blueprints): + +```js +get [Generator.PREPARING]() { + return { + customize({ application }) { + application.baseNameHumanized = 'Custom application title'; + }, + }; +} +``` + ### Entities Every annotation is loaded as entities properties and will be used at generation process. @@ -56,7 +72,7 @@ TODO add humanized name example ##### Eager loading relationships -Currently appliable to SQL/spring-data-relational with partial support at MongoDb/spring-data-mongodb. +Appliable to SQL/spring-data-relational with partial support at MongoDb/spring-data-mongodb. Neo4j eager loads every relationship by default. JHipster UI uses only the id and `otherEntityFieldName` properties, by default only fields used by the UI will be fetched. From 35c314976cebd9e4a674e9a22aa962d64b843f27 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Sun, 22 Oct 2023 16:27:02 -0300 Subject: [PATCH 10/17] Add EntityI18nVariant customization. --- generators/spring-data-relational/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md index a5896382e21..c0c7be58704 100644 --- a/generators/spring-data-relational/README.md +++ b/generators/spring-data-relational/README.md @@ -52,6 +52,19 @@ entity Bar {} entity Department {} ``` +##### Translation variant + +Translation variant allows different translations for the entity whenever appliable. + +```jdl +@EntityI18nVariant('female') +@EntityClassHumanized("Empresa") +@EntityClassPluralHumanized("Empresas") +entity Company {} +``` + +`female` variant is supported by `pt-br` locale. + ### Fields TODO add jdl and json examples From 6ed278a56010c2773b5f6443965bc2f9685d6ae2 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Mon, 23 Oct 2023 20:34:02 -0300 Subject: [PATCH 11/17] add app README --- generators/app/README.md | 101 +++++++++++++++++++ generators/liquibase/README.md | 19 ++++ generators/spring-data-relational/README.md | 104 +------------------- 3 files changed, 121 insertions(+), 103 deletions(-) create mode 100644 generators/app/README.md create mode 100644 generators/liquibase/README.md diff --git a/generators/app/README.md b/generators/app/README.md new file mode 100644 index 00000000000..b353caca00e --- /dev/null +++ b/generators/app/README.md @@ -0,0 +1,101 @@ +# app sub-generador + +`jhipster` command entrypoint, it composes with `common`, `languages`, `server`, and `client`. + +## Customizing + +JHipster implementation allows you to override almost every aspect of the generation process. + +[SQL/spring-data-relational customizations](https://github.com/jhipster/generator-jhipster/blob/skip_ci-architecture/generators/spring-data-relational/README.md#sqlspring-data-relational-sub-generador) + +### Application + +JDL doesn't support annotations, customizations must be done through local blueprint. + +`.blueprint/app/generator.mjs` (to create a local blueprint follow https://www.jhipster.tech/modules/creating-a-blueprint/#local-blueprints): + +```js +get [Generator.PREPARING]() { + return { + customize({ application }) { + application.baseNameHumanized = 'Custom application title'; + }, + }; +} +``` + +### Entities + +Every annotation is loaded as entities properties and will be used at generation process. + +```jdl +@CustomsProp1(customValue) +entity Bar {} +``` + +`.jhipster/Bar.json`: + +```json +{ + "name": "Bar", + "options": { + "customsProp1": "customValue" + } +} +``` + +#### Notable customizations + +##### Label + +``` +@EntityClassHumanized("Departamento") +@EntityClassPluralHumanized("Departamentos") +entity Department {} +``` + +##### Translation variant + +Translation variant allows different translations for the entity whenever appliable. + +```jdl +@EntityI18nVariant('female') +@EntityClassHumanized("Empresa") +@EntityClassPluralHumanized("Empresas") +entity Company {} +``` + +`female` variant is supported by `pt-br` locale. + +### Fields + +TODO add jdl and json examples + +#### Notable customizations + +##### Label + +TODO add humanized name example + +### Relationships + +#### Notable customizations + +##### Label + +TODO add humanized name example + +##### Eager loading relationships + +Appliable to SQL/spring-data-relational with partial support at MongoDb/spring-data-mongodb. +Neo4j eager loads every relationship by default. + +JHipster UI uses only the id and `otherEntityFieldName` properties, by default only fields used by the UI will be fetched. + +```jdl +relationship OneToMany { + @RelationshipEagerLoad Bar to @RelationshipEagerLoad Foo +} +``` + +Related issues: (#23917)[https://github.com/jhipster/generator-jhipster/issues/23917] diff --git a/generators/liquibase/README.md b/generators/liquibase/README.md new file mode 100644 index 00000000000..7ab50f9e856 --- /dev/null +++ b/generators/liquibase/README.md @@ -0,0 +1,19 @@ +# SQL/spring-data-relational sub-generador + +Adds support to liquibase to SQL databases and Neo4j. + +## Customizing + +Customizing basics can be found at [Customizing](../app/README.md#customizing) + +### Notable relationships customizations + +#### OnUpdate/OnDelete + +```jdl +relationship ManyToOne { + A to @OnDelete("SET NULL") @OnUpdate("CASCADE") B +} +``` + +Allowed values: `NO ACTION | RESTRICT | CASCADE | SET NULL | SET DEFAULT` diff --git a/generators/spring-data-relational/README.md b/generators/spring-data-relational/README.md index c0c7be58704..a04bc8ccc8c 100644 --- a/generators/spring-data-relational/README.md +++ b/generators/spring-data-relational/README.md @@ -1,109 +1,7 @@ # SQL/spring-data-relational sub-generador -// TODO move first customizing and sub titles to app README. -## Customizing - -JHipster implementation allows you to override almost every aspect of the generation process. - -[SQL/spring-data-relational customizations](https://github.com/jhipster/generator-jhipster/blob/skip_ci-architecture/generators/spring-data-relational/README.md#sqlspring-data-relational-sub-generador) - -### Application - -JDL doesn't support annotations, customizations must be done through local blueprint. - -`.blueprint/app/generator.mjs` (to create a local blueprint follow https://www.jhipster.tech/modules/creating-a-blueprint/#local-blueprints): - -```js -get [Generator.PREPARING]() { - return { - customize({ application }) { - application.baseNameHumanized = 'Custom application title'; - }, - }; -} -``` - -### Entities - -Every annotation is loaded as entities properties and will be used at generation process. - -```jdl -@CustomsProp1(customValue) -entity Bar {} -``` - -`.jhipster/Bar.json`: -```json -{ - "name": "Bar", - "options": { - "customsProp1": "customValue" - } -} -``` - -#### Notable customizations - -##### Label - -``` -@EntityClassHumanized("Departamento") -@EntityClassPluralHumanized("Departamentos") -entity Department {} -``` - -##### Translation variant - -Translation variant allows different translations for the entity whenever appliable. - -```jdl -@EntityI18nVariant('female') -@EntityClassHumanized("Empresa") -@EntityClassPluralHumanized("Empresas") -entity Company {} -``` - -`female` variant is supported by `pt-br` locale. - -### Fields - -TODO add jdl and json examples - -#### Notable customizations - -##### Label - -TODO add humanized name example - -### Relationships - -#### Notable customizations - -##### Label - -TODO add humanized name example - -##### Eager loading relationships - -Appliable to SQL/spring-data-relational with partial support at MongoDb/spring-data-mongodb. -Neo4j eager loads every relationship by default. - -JHipster UI uses only the id and `otherEntityFieldName` properties, by default only fields used by the UI will be fetched. - -```jdl -relationship OneToMany { - @RelationshipEagerLoad Bar to @RelationshipEagerLoad Foo -} -``` - -Related issues: (#23917)[https://github.com/jhipster/generator-jhipster/issues/23917] +Adds support to spring-data-relational and provides sql related utilities. ## Customizing Customizing basics can be found at [Customizing](../app/README.md#customizing) - -### Notable relationships customizations - -#### Cascading - -TODO add @Cascade example From 0ffc5c12ebb09ad11a6cfe1bb49a428fcf0369e6 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Thu, 26 Oct 2023 12:05:36 -0300 Subject: [PATCH 12/17] Apply suggestions from code review Co-authored-by: Matt Raible --- ARCHITECTURE.md | 42 ++++++++++++++++++++-------------------- BLUEPRINTS.md | 2 +- CONTRIBUTING.md | 4 ++-- DEVELOPMENT.md | 16 +++++++-------- generators/app/README.md | 2 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 5156808962c..1c16b0231c2 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,7 +2,7 @@ ## Yeoman basis -Internally JHipster uses [yeoman](https://yeoman.io) as core. +Internally, JHipster uses [Yeoman](https://yeoman.io) as the core. JHipster is the [most popular generator of all time](https://yeoman.io/generators/). ## File structure @@ -28,11 +28,11 @@ Internally JHipster uses [yeoman](https://yeoman.io) as core. ## Lifecycle -- [Cli entrypoint](https://github.com/jhipster/generator-jhipster/blob/main/cli/jhipster.cjs) +- [CLI entry point](https://github.com/jhipster/generator-jhipster/blob/main/cli/jhipster.cjs) - [Basic environment validation](https://github.com/jhipster/generator-jhipster/blob/main/cli/cli.mjs) - [Cli arguments parsing and Environment bootstrap](https://github.com/jhipster/generator-jhipster/blob/main/cli/program.mjs) - - Lookup for Generators and Blueprints - - Build cli options and arguments definition + - Lookup for generators and blueprints + - Build CLI options and arguments definition - Parse options and arguments - Run Generator (start the Environment) passing options and arguments - Run every task from the highest precedence priority until there is no more pending task @@ -73,7 +73,7 @@ TODO #### Configuring (yeoman) -Check and fix configurations. +Check and fix configurations: ``` get [Generator.CONFIGURING]() { @@ -90,7 +90,7 @@ Check and fix configurations. #### Composing (base) -Compose with other generators. +Compose with other generators: ``` get [Generator.COMPOSING]() { @@ -106,7 +106,7 @@ Compose with other generators. #### Loading (base) -Load configuration. +Load configuration: ``` get [Generator.LOADING]() { @@ -121,7 +121,7 @@ Load configuration. #### Preparing (base) -Generate properties to improve understanding. +Generate properties to improve understanding: ``` get [Generator.PREPARING]() { @@ -137,7 +137,7 @@ Generate properties to improve understanding. #### Configuring each entity (base-application) -Configure and check entity's configuration. +Configure and check entity's configuration: ``` get [Generator.CONFIGURING_EACH_ENTITY]() { @@ -158,7 +158,7 @@ Usually empty the entire entity configuration is loaded by default. #### Preparing each entity (base-application) -Generate properties to improve understanding at entity level. +Generate properties to improve understanding at the entity level: ``` get [Generator.PREPARING_EACH_ENTITY]() { @@ -172,7 +172,7 @@ Generate properties to improve understanding at entity level. #### Preparing each entity field (base-application) -Generate properties to improve understanding at field level. +Generate properties to improve understanding at the field level: ``` get [Generator.PREPARING_EACH_ENTITY_FIELD]() { @@ -186,7 +186,7 @@ Generate properties to improve understanding at field level. #### Preparing each entity relationship (base-application) -Generate properties to improve understanding at relationship level. +Generate properties to improve understanding at the relationship level: ``` get [Generator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { @@ -200,7 +200,7 @@ Generate properties to improve understanding at relationship level. #### Default (yeoman) -Generate properties to improve understanding that depends on others properties. +Generate properties to improve understanding that depends on others' properties: ``` get [Generator.DEFAULT]() { @@ -214,10 +214,10 @@ Generate properties to improve understanding that depends on others properties. #### Writing (yeoman) -Write files to in memory file system. +Write files to the in-memory file system. -There are a lot of apis to write files, copy files, delete files. -`writeFiles` is the most used at official generators. +There are a lot of APIs to write files, copy files, and delete files. +The `writeFiles()` method is the most used in official generators. ``` get [Generator.WRITING]() { @@ -239,9 +239,9 @@ There are a lot of apis to write files, copy files, delete files. #### Writing entities (base-application) -Write entity files to in memory file system. +Write entity files to the in-memory file system. -Entities writing is a separed priority to keep workflow sane when using options like `--skip-application` and `--single-entity`. +Writing entities is a separate priority to keep the workflow sane when using options like `--skip-application` and `--single-entity`. ``` get [Generator.WRITING_ENTITIES]() { @@ -265,11 +265,11 @@ Entities writing is a separed priority to keep workflow sane when using options #### Post writing (base) -Injects code in the generated source +Injects code in the generated source. ##### Injecting code with provided apis (needles) -JHipster adds apis to some code injection. +JHipster adds APIs to some code injection: ``` get [Generator.POST_WRITING]() { @@ -302,7 +302,7 @@ Install task is queued by detecting `package.json` changes. #### End (yeoman) -Print generator result and info. +Print generator result and info: ``` get [Generator.END]() { diff --git a/BLUEPRINTS.md b/BLUEPRINTS.md index 37edc36d333..5a48ffcec18 100644 --- a/BLUEPRINTS.md +++ b/BLUEPRINTS.md @@ -24,7 +24,7 @@ You should regenerate the blueprint to update dependencies. npx --package generator-jhipster@latest jhipster generate-blueprint ``` -When updating from a minor jhipster version, you probably will want to ignore (press s) to every generator and test conflict. +When updating from a minor JHipster version, you probably will want to ignore (press s) to every generator and test conflict. Ignore (i option instead of s) will store the file at `.yo-resolve` so that following `generate-blueprint` executions will ignore those files by default. From time to time generate-blueprint may generate different code. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fcb2cdc2e2d..67ae76eac92 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ Before you submit your pull request consider the following guidelines: - Search [GitHub](https://github.com/jhipster/generator-jhipster/pulls?utf8=%E2%9C%93&q=is%3Apr) for an open or closed Pull Request that relates to your submission. -- If you want to modify the JHipster generator, read our [Development](DEVELOPMENT.md) +- If you want to modify the JHipster generator, read our [Development Guide](DEVELOPMENT.md) - Follow our [Coding Rules](#rules). - In GitHub, send a pull request to `jhipster/generator-jhipster:main`. - **Every CI tests must pass**. @@ -107,7 +107,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo - All features or bug fixes **must be tested** by one or more tests. - Most files formatting are checked by prettier and eslint. -- EJS files uses a 2 spaces identation for templates logic and follows the generated file rules for the templating parts. +- EJS files use a two-space indentation for template logic and follow the generated file rules for the templating parts. Please ensure to run `npm run lint` and `npm test` on the project root before submitting a pull request. You can also run `npm run lint-fix` to fix some of the lint issues automatically. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 61516b8f451..dbf67e54032 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -16,8 +16,8 @@ Go to the [generator-jhipster project](https://github.com/jhipster/generator-jhi ### Set `jhipster` command to use the cloned project -Since v8 `generator-jhipster` is written in typescript. -To run it you need to compile to javascript or use a just-in-time compilation. +Since v8 `generator-jhipster` is written in TypeScript. +To run it you need to compile to JavaScript or use a just-in-time compilation. #### Runnning jit executable @@ -46,20 +46,20 @@ Also add the option `--skip-jhipster-dependencies` to generate the application i To put it in a nutshell, you need to: -1. run `npm link` on the `generator-jhipster` project (link globally) or configure jit executable -2. run `jhipster --skip-jhipster-dependencies` on the generated application folder +1. Run `npm link` on the `generator-jhipster` project (link globally) or configure jit executable +2. Run `jhipster --skip-jhipster-dependencies` on the generated application folder -You can execute `jhipster --install-path` to check where jhipster is being executed from. +You can execute `jhipster --install-path` to check where JHipster is being executed from. You can test your setup by making a small change in your cloned generator, and running again on an existing JHipster project: -For projects with jhipster third party library (i.e. react-jhipster, etc.) you need to run `npm link` on the library project as well, then npm link the original framework (i.e. react) from the generated project to the library project `cd react-jhipster && npm link /node_modules/react`. +For projects with JHipster third-party libraries (i.e. react-jhipster, etc.), you need to run `npm link` on the library project as well, then `npm link` the original framework (i.e. react) from the generated project to the library project `cd react-jhipster && npm link /node_modules/react`. ```shell jhipster ``` -Depending on which parts of the generator you have changed, do not forget to run jhipster command with the proper arguments e.g. when updating the entity template run: +Depending on which parts of the generator you have changed, do not forget to run the `jhipster` command with the proper arguments e.g. when updating the entity template run: ```shell jhipster --with-entities @@ -159,7 +159,7 @@ npm run ci:e2e:run # Runs e2e tests ### Development Containers -Container is built using java, node and npm recommended by `generator-jhipster`. +A container is built using Java, Node, and npm as recommended by `generator-jhipster`. Once up, you should have the stack maintainers recommends. ### Execution shortcuts diff --git a/generators/app/README.md b/generators/app/README.md index b353caca00e..baba0b600ed 100644 --- a/generators/app/README.md +++ b/generators/app/README.md @@ -56,7 +56,7 @@ entity Department {} ##### Translation variant -Translation variant allows different translations for the entity whenever appliable. +Translation variant allows different translations for the entity whenever applicable. ```jdl @EntityI18nVariant('female') From 1db7c418906f5724ecec7a56695093b228062953 Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Tue, 31 Oct 2023 19:46:35 -0600 Subject: [PATCH 13/17] Prettier --- ARCHITECTURE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 1c16b0231c2..3785410d3d9 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,7 +2,7 @@ ## Yeoman basis -Internally, JHipster uses [Yeoman](https://yeoman.io) as the core. JHipster is the [most popular generator of all time](https://yeoman.io/generators/). +Internally, JHipster uses [Yeoman](https://yeoman.io) as the core. JHipster is the [most popular generator of all time](https://yeoman.io/generators/). ## File structure From c55cd040e3e2bfaf70b99429cba1c2e538513b81 Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Tue, 31 Oct 2023 20:08:21 -0600 Subject: [PATCH 14/17] Improve code blocks --- ARCHITECTURE.md | 306 ++++++++++++++++++++++++------------------------ 1 file changed, 153 insertions(+), 153 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 3785410d3d9..6ce748de1c6 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -47,22 +47,22 @@ Initial generator information. - initial environment checks - argument and options loading -``` - get [Generator.INITIALIZING]() { - return this.asInitializingTaskGroup() { - sayHelloTask() { - this.log.info('Welcome to your generator'); - }, - envChecks() { - checkNode(); - checkDocker(); - }, - async loadOptions() { - this.parseJHipsterArguments(command.arguments); - this.parseJHipsterOptions(command.options); - }, - } +```ts +get [Generator.INITIALIZING]() { + return this.asInitializingTaskGroup() { + sayHelloTask() { + this.log.info('Welcome to your generator'); + }, + envChecks() { + checkNode(); + checkDocker(); + }, + async loadOptions() { + this.parseJHipsterArguments(command.arguments); + this.parseJHipsterOptions(command.options); + }, } +} ``` #### Prompting (yeoman) @@ -75,81 +75,81 @@ TODO Check and fix configurations: -``` - get [Generator.CONFIGURING]() { - return this.asConfiguringTaskGroup() { - checkConfig() { - if (this.jhipsterConfigWithDefaults.reactive && this.jhipsterConfigWithDefaults.cacheProvider !== 'no') { - this.log.warn("Reactive applications doesn't support cache. Disabling"); - this.jhipsterConfig.cacheProvider = 'no'; - } - }, - } +```ts +get [Generator.CONFIGURING]() { + return this.asConfiguringTaskGroup() { + checkConfig() { + if (this.jhipsterConfigWithDefaults.reactive && this.jhipsterConfigWithDefaults.cacheProvider !== 'no') { + this.log.warn("Reactive applications doesn't support cache. Disabling"); + this.jhipsterConfig.cacheProvider = 'no'; + } + }, } +} ``` #### Composing (base) Compose with other generators: -``` - get [Generator.COMPOSING]() { - return this.asComposingTaskGroup() { - composing() { - if (this.jhipsterConfigWithDefaults.clientFramework === 'angular') { - this.composeWithJHipster('angular'); - } - }, - } +```ts +get [Generator.COMPOSING]() { + return this.asComposingTaskGroup() { + composing() { + if (this.jhipsterConfigWithDefaults.clientFramework === 'angular') { + this.composeWithJHipster('angular'); + } + }, } +} ``` #### Loading (base) Load configuration: -``` - get [Generator.LOADING]() { - return this.asLoadingTaskGroup() { - loading({ application }) { - application.myCustomConfig = this.jhipsterConfig.myCustomConfig; - application.myBlueprintCustomConfig = this.blueprintConfig.myBlueprintCustomConfig; - }, - } +```ts +get [Generator.LOADING]() { + return this.asLoadingTaskGroup() { + loading({ application }) { + application.myCustomConfig = this.jhipsterConfig.myCustomConfig; + application.myBlueprintCustomConfig = this.blueprintConfig.myBlueprintCustomConfig; + }, } +} ``` #### Preparing (base) Generate properties to improve understanding: -``` - get [Generator.PREPARING]() { - return this.asPreparingTaskGroup() { - preparing({ application }) { - application.myCustomConfigFoo = this.jhipsterConfig.myCustomConfig === 'foo'; - application.myCustomConfigBar = this.jhipsterConfig.myCustomConfig === 'bar'; - application.myCustomConfigNo = !this.jhipsterConfig.myCustomConfig || this.jhipsterConfig.myCustomConfig === 'no'; - }, - } +```ts +get [Generator.PREPARING]() { + return this.asPreparingTaskGroup() { + preparing({ application }) { + application.myCustomConfigFoo = this.jhipsterConfig.myCustomConfig === 'foo'; + application.myCustomConfigBar = this.jhipsterConfig.myCustomConfig === 'bar'; + application.myCustomConfigNo = !this.jhipsterConfig.myCustomConfig || this.jhipsterConfig.myCustomConfig === 'no'; + }, } +} ``` #### Configuring each entity (base-application) Configure and check entity's configuration: -``` - get [Generator.CONFIGURING_EACH_ENTITY]() { - return this.asConfiguringEachEntityTaskGroup() { - configuring({ application, entityConfig }) { - if (application.searchEngineNo && entityConfig.searchEngine && entityConfig.searchEngine !== 'no') { - this.log.warn("Search engine cannot be enabled at entity because it's disabled at application"); - entityConfig.searchEngine = 'no'; - } - }, - } +```ts +get [Generator.CONFIGURING_EACH_ENTITY]() { + return this.asConfiguringEachEntityTaskGroup() { + configuring({ application, entityConfig }) { + if (application.searchEngineNo && entityConfig.searchEngine && entityConfig.searchEngine !== 'no') { + this.log.warn("Search engine cannot be enabled at entity because it's disabled at application"); + entityConfig.searchEngine = 'no'; + } + }, } +} ``` #### Loading entities (base-application) @@ -160,56 +160,56 @@ Usually empty the entire entity configuration is loaded by default. Generate properties to improve understanding at the entity level: -``` - get [Generator.PREPARING_EACH_ENTITY]() { - return this.asPreparingEachEntityTaskGroup() { - preparing({ application, entity }) { - entity.dtoMapstruct = entity.dto === 'mapstruct'; - }, - } +```ts +get [Generator.PREPARING_EACH_ENTITY]() { + return this.asPreparingEachEntityTaskGroup() { + preparing({ application, entity }) { + entity.dtoMapstruct = entity.dto === 'mapstruct'; + }, } +} ``` #### Preparing each entity field (base-application) Generate properties to improve understanding at the field level: -``` - get [Generator.PREPARING_EACH_ENTITY_FIELD]() { - return this.asPreparingEachEntityFieldTaskGroup() { - preparing({ application, entity, field }) { - field.technologyFieldTypeIntegerMap = field.fieldType === 'Integer'; - }, - } +```ts +get [Generator.PREPARING_EACH_ENTITY_FIELD]() { + return this.asPreparingEachEntityFieldTaskGroup() { + preparing({ application, entity, field }) { + field.technologyFieldTypeIntegerMap = field.fieldType === 'Integer'; + }, } +} ``` #### Preparing each entity relationship (base-application) Generate properties to improve understanding at the relationship level: -``` - get [Generator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { - return this.asPreparingEachEntityRelationshipTaskGroup() { - preparing({ application, entity, relationship }) { - relationship.technologyRelationshipDbName = relationship.relationshipTypeOneToOne ? 'foo' : 'bar'; - }, - }; - } +```ts +get [Generator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { + return this.asPreparingEachEntityRelationshipTaskGroup() { + preparing({ application, entity, relationship }) { + relationship.technologyRelationshipDbName = relationship.relationshipTypeOneToOne ? 'foo' : 'bar'; + }, + }; +} ``` #### Default (yeoman) Generate properties to improve understanding that depends on others' properties: -``` - get [Generator.DEFAULT]() { - return this.asDefaultTaskGroup() { - preparing({ application, entities }) { - application.hasEntityFieldInteger = entities.some(entity => entity.fields.some(field => field.fieldTypeInteger)); - }, - }; - } +```ts +get [Generator.DEFAULT]() { + return this.asDefaultTaskGroup() { + preparing({ application, entities }) { + application.hasEntityFieldInteger = entities.some(entity => entity.fields.some(field => field.fieldTypeInteger)); + }, + }; +} ``` #### Writing (yeoman) @@ -219,22 +219,22 @@ Write files to the in-memory file system. There are a lot of APIs to write files, copy files, and delete files. The `writeFiles()` method is the most used in official generators. -``` - get [Generator.WRITING]() { - return this.asWritingTaskGroup({ - writingTask({ application }) { - this.writeFiles({ - blocks: [ - { - condition: ctx => ctx.shouldWrite, - templates: ['template.file'], - } - ], - context: application, - }); - }, - }); - } +```ts +get [Generator.WRITING]() { + return this.asWritingTaskGroup({ + writingTask({ application }) { + this.writeFiles({ + blocks: [ + { + condition: ctx => ctx.shouldWrite, + templates: ['template.file'], + } + ], + context: application, + }); + }, + }); +} ``` #### Writing entities (base-application) @@ -243,24 +243,24 @@ Write entity files to the in-memory file system. Writing entities is a separate priority to keep the workflow sane when using options like `--skip-application` and `--single-entity`. -``` - get [Generator.WRITING_ENTITIES]() { - return this.asWritingTaskGroup({ - writingTask({ application, entities }) { - for (const entity of entities) { - this.writeFiles({ - blocks: [ - { - condition: ctx => ctx.shouldWrite, - templates: ['entity.template.file'], - } - ], - context: { ...application, ...entity }, - }); - } - }, - }); - } +```ts +get [Generator.WRITING_ENTITIES]() { + return this.asWritingTaskGroup({ + writingTask({ application, entities }) { + for (const entity of entities) { + this.writeFiles({ + blocks: [ + { + condition: ctx => ctx.shouldWrite, + templates: ['entity.template.file'], + } + ], + context: { ...application, ...entity }, + }); + } + }, + }); +} ``` #### Post writing (base) @@ -269,30 +269,30 @@ Injects code in the generated source. ##### Injecting code with provided apis (needles) -JHipster adds APIs to some code injection: +JHipster adds APIs for code injection: -``` - get [Generator.POST_WRITING]() { - return this.asPostWritingTaskGroup({ - postWritingTask({ source }) { - source.someProvidedInjectionApi({ code: 'some code' }); - } - }); - } +```ts +get [Generator.POST_WRITING]() { + return this.asPostWritingTaskGroup({ + postWritingTask({ source }) { + source.someProvidedInjectionApi({ code: 'some code' }); + } + }); +} ``` ##### Custom code injection Every file can be edited manually. -``` - get [Generator.POST_WRITING]() { - return this.asPostWritingTaskGroup({ - postWritingTask({ source }) { - this.editFile('path/to/some/file', content => content.replaceAll('some content', 'another content')); - } - }); - } +```ts +get [Generator.POST_WRITING]() { + return this.asPostWritingTaskGroup({ + postWritingTask({ source }) { + this.editFile('path/to/some/file', content => content.replaceAll('some content', 'another content')); + } + }); +} ``` #### Install (yeoman) @@ -304,15 +304,15 @@ Install task is queued by detecting `package.json` changes. Print generator result and info: -``` - get [Generator.END]() { - return this.asEndTaskGroup() { - preparing({ application }) { - this.log.success('Tech application generated successfully'); - this.log.log(`Start the application running 'npm run start:app'`); - }, - }; - } +```ts +get [Generator.END]() { + return this.asEndTaskGroup() { + preparing({ application }) { + this.log.success('Tech application generated successfully'); + this.log.log(`Start the application running 'npm run start:app'`); + }, + }; +} ``` ## Blueprints @@ -327,11 +327,11 @@ https://www.jhipster.tech/modules/creating-a-blueprint/ ### GeneratorBaseCore -Adds custom apis to `yeoman-generator` and customizes the behavior. +Adds custom APIS to `yeoman-generator` and customizes the behavior. ### GeneratorBase -Adds Blueprint composing apis. +Adds Blueprint composing APIS. ### GeneratorApplication From eadeffaea438bf225695adcd536307a26eb7dc23 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Mon, 13 Nov 2023 17:16:45 -0300 Subject: [PATCH 15/17] add documentations --- ARCHITECTURE.md | 24 +++++++++++++++--------- generators/app/README.md | 15 +++++++++++---- generators/app/USAGE | 3 +++ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 6ce748de1c6..49cebb93a4a 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -69,7 +69,15 @@ get [Generator.INITIALIZING]() { Prompt for configuration. -TODO +```ts +get [Generator.PROMPTING]() { + return this.asPromptingTaskGroup() { + async prompting() { + await this.prompt(this.prepareQuestions(command.configs)); + }, + } +} +``` #### Configuring (yeoman) @@ -95,9 +103,9 @@ Compose with other generators: ```ts get [Generator.COMPOSING]() { return this.asComposingTaskGroup() { - composing() { + async composing() { if (this.jhipsterConfigWithDefaults.clientFramework === 'angular') { - this.composeWithJHipster('angular'); + await this.composeWithJHipster('angular'); } }, } @@ -222,8 +230,8 @@ The `writeFiles()` method is the most used in official generators. ```ts get [Generator.WRITING]() { return this.asWritingTaskGroup({ - writingTask({ application }) { - this.writeFiles({ + async writingTask({ application }) { + await this.writeFiles({ blocks: [ { condition: ctx => ctx.shouldWrite, @@ -246,9 +254,9 @@ Writing entities is a separate priority to keep the workflow sane when using opt ```ts get [Generator.WRITING_ENTITIES]() { return this.asWritingTaskGroup({ - writingTask({ application, entities }) { + async writingTask({ application, entities }) { for (const entity of entities) { - this.writeFiles({ + await this.writeFiles({ blocks: [ { condition: ctx => ctx.shouldWrite, @@ -336,5 +344,3 @@ Adds Blueprint composing APIS. ### GeneratorApplication Adds Entities related apis. - -## JDL diff --git a/generators/app/README.md b/generators/app/README.md index baba0b600ed..64aa32ab1e2 100644 --- a/generators/app/README.md +++ b/generators/app/README.md @@ -69,13 +69,16 @@ entity Company {} ### Fields -TODO add jdl and json examples - #### Notable customizations ##### Label -TODO add humanized name example +```jdl +entity Company { + @FieldNameHumanized('Company Name') + company_name +} +``` ### Relationships @@ -83,7 +86,11 @@ TODO add humanized name example ##### Label -TODO add humanized name example +```jdl +relationship ManyToOnly { + @RelationshipNameHumanized('Company user') Company{user} to User +} +``` ##### Eager loading relationships diff --git a/generators/app/USAGE b/generators/app/USAGE index 79267f9a915..2e3847ca81b 100644 --- a/generators/app/USAGE +++ b/generators/app/USAGE @@ -5,3 +5,6 @@ Example: jhipster This will compose jhipster:client, jhipster:server and jhipster:languages to scaffold a full application + +More information: + https://github.com/jhipster/generator-jhipster/tree/main/generators/app From cf1dc75b231ef0d694a9b3d72b3af06421531012 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Tue, 21 Nov 2023 11:18:30 -0300 Subject: [PATCH 16/17] add blueprint readme --- ARCHITECTURE.md | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 49cebb93a4a..5054fa4cac8 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -325,12 +325,53 @@ get [Generator.END]() { ## Blueprints -https://www.jhipster.tech/modules/extending-and-customizing/ -https://www.jhipster.tech/modules/creating-a-module/ -https://www.jhipster.tech/modules/creating-a-blueprint/ +Blueprint support allows to customize the generation process. + +A Blueprint package can include any number of sub-generators, each can be a replacement blueprint, a side-by-side blueprint, or a stand alone blueprint. + +- Normal blueprints will completely replace the blueprinted sub-generator with a replacement. +- Side by side blueprint doesn't change the generation process, it customizes it. +- Stand alone blueprint doesn't hook into a sub-generator. + +Examples: + +- [Micronaut](https://github.com/jhipster/generator-jhipster-micronaut) has a [server](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/server) replacement blueprint, a [angular](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/angular), [client](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/client), [cypress](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/cypress), [docker](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/docker) and [react](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/react) side by side blueprints, and a [micronaut-cache](https://github.com/jhipster/generator-jhipster-micronaut/tree/0818dd9d90f4a550e008133adc7fad6b17089caa/generators/micronaut-cache) stand alone blueprint + +More information can be found at: + +[Extending and customizing](https://www.jhipster.tech/modules/extending-and-customizing/) +[Creating a stand alone Blueprint](https://www.jhipster.tech/modules/creating-a-module/) +[Creating a blueprint](https://www.jhipster.tech/modules/creating-a-blueprint/) ### Blueprint lifecycle +#### Replacement blueprint + +| Priority | Blueprinted sub-gen | Blueprint sub-gen | +| ------------ | ------------------------------------- | ------------------------------ | +| beforeQueue | composes with blueprints/dependencies | composes with dependencies | +| initializing | X | replacement initializing tasks | +| prompting | X | replacement prompting tasks | +| ... | X | ... | + +#### Side by side blueprint + +| Priority | Blueprinted sub-gen | Blueprint sub-gen | Another blueprint sub-gen | +| ------------ | ------------------------------------- | ----------------------------- | ----------------------------- | +| beforeQueue | composes with blueprints/dependencies | composes with dependencies | composes with dependencies | +| initializing | initializing tasks | additional initializing tasks | additional initializing tasks | +| prompting | prompting tasks | additional prompting tasks | additional prompting tasks | +| ... | ... | ... | ... | + +#### Stand alone blueprint + +| Priority | Blueprint sub-gen | +| ------------ | -------------------------- | +| beforeQueue | composes with dependencies | +| initializing | initializing tasks | +| prompting | prompting tasks | +| ... | ... | + ## Generator Hierarchy ### GeneratorBaseCore From 88a2877fc73e48ad10c2190a7d6fa379043c8cc4 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Tue, 21 Nov 2023 18:14:04 -0300 Subject: [PATCH 17/17] change options -> annotations --- generators/app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/app/README.md b/generators/app/README.md index 64aa32ab1e2..ec988e69d4f 100644 --- a/generators/app/README.md +++ b/generators/app/README.md @@ -38,7 +38,7 @@ entity Bar {} ```json { "name": "Bar", - "options": { + "annotations": { "customsProp1": "customValue" } }