Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

a bit of type checking #27097

Closed
wants to merge 4 commits into from
Closed

a bit of type checking #27097

wants to merge 4 commits into from

Conversation

Tcharl
Copy link
Contributor

@Tcharl Tcharl commented Aug 27, 2024

Move yo-rc definition to a typescript object.

Further PR will try to narrow the amount of fields filled at each step of generator phases and move the types to their respective generators. Not perfect yet and waiting for advices

contribute to #26114


Please make sure the below checklist is followed for Pull Requests.

When you are still working on the PR, consider converting it to Draft (below reviewers) and adding skip-ci label, you can still see CI build result at your branch.

@mshima
Copy link
Member

mshima commented Aug 28, 2024

I don't think we should make jhipsterConfig typed.

  • blueprints will need to convert to any before using.

@Tcharl
Copy link
Contributor Author

Tcharl commented Aug 28, 2024

This is why I kept the & Record<string, any> at the end of the AbstractJSONGeneratorJhipsterContent.
I'm convinced that knowing all the available and filled options at every step of every generator will improve readability, velocity, stability and keep (once everything done) cli and jdl options aligned.

Please change your mind: it's definitely hard to introduce (or fix) the current codebase for not near full time contributors, and setting type checking would definitely help in that regard (at least).

Finally, i'm also pretty sure that moving these types and default values to their respective generators (i.e. moving JSONGeneratorJhipsterClientContent to generators/client) will help us finding smart modularity tricks (valuable for blueprints)

@mshima
Copy link
Member

mshima commented Aug 28, 2024

jhipsterConfig and jhipsterConfigWithDefaults are never manually used anymore.

Command has evolved as somewhat source of truth.
https://github.com/mshima/generator-jhipster/blob/f0a8e84e2fbd24ab2f7e9cbe2bcac581004aa671/generators/git/command.ts#L37-L39

A storage scoped config:

  • allows cli option/argument with choices
  • allows prompts
  • allows post processing
  • is loaded from cli/prompt to the jhipsterConfig
  • is loaded from jhipsterConfigWithDefaults to the application object.

Probably will allow jdl definitions in the future.

@Tcharl
Copy link
Contributor Author

Tcharl commented Aug 28, 2024

Thanks for the tips, seems to be a very nice approach

Still, jhipsterConfig* are used in the codebase (via the 'loaded from the cli to jhipster config') so from an implementor point of view using types should help the contributors to understand features more easily (and get IDE code completion), particularly which field is available at which lifecycle step (which confuses even me).
I plan to merge the jdl/JSONGeneratorJhipsterXContent with their <generator>/types.d counterparts in the next commits and use the same types for application: i.e. removing jdl/JSONGeneratorJhipsterAuthenticationContent in favor of base-application/types.d/AuthenticationType to avoid code dupe and enforce consistency.

Doing it step by step just to avoid breaking change and hardcore peer review. Pretty sure the code refactor will lead to breeze and awesome ease to scale again (again ;-)).

Anyway, this PR doesn't harm much and help overall (blueprints should not even need as any), and also contributes to a future simplification of the codebase...

@Tcharl
Copy link
Contributor Author

Tcharl commented Aug 30, 2024

Is it correct? simplifies a bit the default value code

@mshima
Copy link
Member

mshima commented Aug 31, 2024

I think we should generate Types from command instead of reworking types see #27133.

@Tcharl
Copy link
Contributor Author

Tcharl commented Aug 31, 2024

I got it already: command act as the single source of truth.
Still, at on point in time during the generation execution lifecycle:

  1. Commands will be merged with defaults when no answer: here, the objective of this PR in the long term will be to get rid of the 'jhipsterconfigWithDefault' in favor of default values introduced in the respective <generator>/command.ts.
  2. Commands results will be injected in an object representing all the answers of a user for generator prompts: configure part of the command: the goal of this PR is to materialize the resulting typescript object (let's call it GeneratorXConfig) and all its attributes (an object per generator), instead of using jhipsterConfig which is the aggregate of the GeneratorConfigs of all the generators and which should only exist temporary.
  3. These objects will then be enriched with derived properties EnrichedGeneratorXConfig.
  4. These EnrichedGeneratorConfigs are then classified: platforms ones, application ones and entities-related: each generator Config will be classified in one of these three category (PlatformConfig, ApplicationConfig, EntityConfig). -> I'm not sure this step should happen, but I guess that sometimes you'll need an aggregate to produce a full template, your opinion?
  5. Finally, these EnrichedConfigs will be used in preprocess, process and postprocess: here, the developer will definitely be happy to get autocomplete and know at which phase he can have access to which attribute of this config in his template, which is why I started the PR.

I know it's far from being finished yet and that it is quite an adventure to get rid of the current pains related:

  1. Knowing configuration attributes available at each lifecycle phase
  2. Modular generator architecture not centralized on 'big aggregate' objects which would help blueprints
  3. JDL vs Cli gaps and synchronization.

But we have to start from something and this is a small step to start from.

PS: Ah, and BTW, I have a bit of time due to my current situation to contribute in the mid term to this kind of rework. I just don't want to push big stuff with hundreds of conflicts and make it step by step with this objective in mind until it happens

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test needs a minimum reproduction, if we provide a complete sample it may break with unrelated changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test needs a minimum reproduction, if we provide a complete sample it may break with unrelated changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These properties are available in app/command.
We should extract from there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, at one point it has to be materialized to an object

@@ -10,12 +10,17 @@ type ClientFrameworkType = ['no', 'angular', 'react', 'vue', 'svelte'];

type ClientFrameworkApplication = OptionWithDerivedProperties<'clientFramework', ClientFrameworkType>;

export type PersistedClientApplication = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Persisted types are the ExportStoragePropertiesFromCommand types.

@@ -10,12 +10,17 @@ type ClientFrameworkType = ['no', 'angular', 'react', 'vue', 'svelte'];

type ClientFrameworkApplication = OptionWithDerivedProperties<'clientFramework', ClientFrameworkType>;

export type PersistedClientApplication = {
withAdminUi: boolean;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s already available in the bellow type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default types should be dropped from converters and replaced with generics.
We should not try to export or integrate them.

@@ -68,6 +68,7 @@ import { getGradleLibsVersionsProperties } from '../gradle/support/dependabot-gr
import { dockerPlaceholderGenerator } from '../docker/utils.js';
import { getConfigWithDefaults } from '../../jdl/index.js';
import { extractArgumentsFromConfigs } from '../base/internal/command.js';
import { JSONGeneratorJhipsterContent } from '../../jdl/converters/types.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not mix jdl with generator types.
To add a type to jhipsterConfig a new type should be created join storage types from every generator.

@Tcharl
Copy link
Contributor Author

Tcharl commented Aug 31, 2024

Gonna retry with a smaller scope

@Tcharl Tcharl closed this Aug 31, 2024
@Tcharl Tcharl mentioned this pull request Aug 31, 2024
6 tasks
@mraible mraible added this to the 8.7.1 milestone Sep 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants