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

move entity to base-application #20957

Merged
merged 3 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions generators/base-application/generator-ts.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import _ from 'lodash';
import type Storage from 'yeoman-generator/lib/util/storage.js';

import BaseGenerator from '../base/index.mjs';
import { JHIPSTER_CONFIG_DIR } from '../generator-constants.mjs';
import { getEntitiesFromDir } from './support/index.mjs';

const { upperFirst } = _;

// Temporary Generator with Typescript implementations
export default class BaseApplicationTsGenerator extends BaseGenerator {
/**
* Get all the generator configuration from the .yo-rc.json file
* @param entityName - Name of the entity to load.
* @param create - Create storage if doesn't exists.
*/
getEntityConfig(entityName: string, create = false): Storage | undefined {
const entityPath = this.destinationPath(JHIPSTER_CONFIG_DIR, `${upperFirst(entityName)}.json`);
if (!create && !this.fs.exists(entityPath)) return undefined;
return this.createStorage(entityPath, { sorted: true } as any);
}

/**
* get sorted list of entitiy names according to changelog date (i.e. the order in which they were added)
*/
getExistingEntityNames(): string[] {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be in a support file isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

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

IMO no.
Every core api should be implemented inline in the generator (except some utilities).
And we should avoid utilities to use any complex parameter like the generator and the log.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why am I stating that: these APIs will certainly be used by many generators, so we'll avoid passing complex parameters (generator) reusing them by moving this method to a dedicated support package.

I agree generatorshould not be passed as an attribute. LogAdapter looks to be a must (quite systematic) as there's no slf4j-like static injection fwk

return this.getExistingEntities().map(entity => entity.name);
}

/**
* get sorted list of entities according to changelog date (i.e. the order in which they were added)
*/
getExistingEntities(): { name: string; definition: Record<string, any> }[] {
function isBefore(e1, e2) {
return e1.definition.changelogDate - e2.definition.changelogDate;
}

const configDir = this.destinationPath(JHIPSTER_CONFIG_DIR);

const entities: { name: string; definition: Record<string, any> }[] = [];
for (const entityName of [...new Set(((this.jhipsterConfig.entities as string[]) || []).concat(getEntitiesFromDir(configDir)))]) {
const definition = this.getEntityConfig(entityName)?.getAll();
if (definition) {
entities.push({ name: entityName, definition });
}
}
entities.sort(isBefore);
this.jhipsterConfig.entities = entities.map(({ name }) => name);
return entities;
}
}
8 changes: 4 additions & 4 deletions generators/base-application/generator.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
import _ from 'lodash';

import BaseGenerator from '../base/index.mjs';
import BaseApplicationTsGenerator from './generator-ts.mjs';
import { CUSTOM_PRIORITIES, PRIORITY_NAMES, QUEUES } from './priorities.mjs';
import { JHIPSTER_CONFIG_DIR } from '../generator-constants.mjs';

Expand Down Expand Up @@ -52,16 +52,16 @@ const {
POST_WRITING_ENTITIES_QUEUE,
} = QUEUES;

const asPriority = BaseGenerator.asPriority;
const asPriority = BaseApplicationTsGenerator.asPriority;

/**
* This is the base class for a generator that generates entities.
*
* @class
* @template ApplicationType
* @extends {BaseGenerator}
* @extends {BaseApplicationTsGenerator}
*/
export default class BaseApplicationGenerator extends BaseGenerator {
export default class BaseApplicationGenerator extends BaseApplicationTsGenerator {
static CONFIGURING_EACH_ENTITY = asPriority(CONFIGURING_EACH_ENTITY);

static LOADING_ENTITIES = asPriority(LOADING_ENTITIES);
Expand Down
39 changes: 39 additions & 0 deletions generators/base-application/support/entities.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2023 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { existsSync, mkdirSync, opendirSync } from 'fs';
import { extname, basename } from 'path';

// eslint-disable-next-line import/prefer-default-export
export function getEntitiesFromDir(configDir: string): string[] {
if (!existsSync(configDir)) {
mkdirSync(configDir);
}
const dir = opendirSync(configDir);
const entityNames: string[] = [];
let dirent = dir.readSync();
while (dirent !== null) {
const extension = extname(dirent.name);
if (dirent.isFile() && extension === '.json') {
entityNames.push(basename(dirent.name, extension));
}
dirent = dir.readSync();
}
dir.closeSync();
return entityNames;
}
3 changes: 2 additions & 1 deletion generators/base-application/support/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
* limitations under the License.
*/

export * from './field-utils.mjs';
export * from './enum.mjs';
export * from './entities.mjs';
export * from './field-utils.mjs';
25 changes: 0 additions & 25 deletions generators/base/generator-base.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ import {
} from '../../jdl/jhipster/index.mjs';
import { databaseData, getJdbcUrl, getR2dbcUrl, prepareSqlApplicationProperties } from '../sql/support/index.mjs';
import {
JHIPSTER_CONFIG_DIR,
SERVER_MAIN_SRC_DIR,
SERVER_TEST_SRC_DIR,
SERVER_MAIN_RES_DIR,
Expand Down Expand Up @@ -688,30 +687,6 @@ export default class JHipsterBaseGenerator extends PrivateBase {
return _.camelCase(microserviceName) + (microserviceName.endsWith('App') ? '' : 'App');
}

/**
* get sorted list of entitiy names according to changelog date (i.e. the order in which they were added)
*/
getExistingEntityNames() {
return this.getExistingEntities().map(entity => entity.name);
}

/**
* @private
* Read entity json from config folder.
* @param {string} entityName - Entity name
* @return {object} entity definition
*/
readEntityJson(entityName) {
const file = path.join(path.dirname(this.config.path), JHIPSTER_CONFIG_DIR, `${entityName}.json`);
try {
return this.fs.readJSON(file);
} catch (error) {
this.logger.warn(`Unable to parse ${file}, is the entity file malformed or invalid?`);
this.logger.debug('Error:', error);
return undefined;
}
}

/**
* @private
* get a table name in JHipster preferred style.
Expand Down
47 changes: 1 addition & 46 deletions generators/base/generator.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { existsSync, mkdirSync, opendirSync } from 'fs';
import { basename, extname, join as joinPath, dirname } from 'path';
import { basename, join as joinPath, dirname } from 'path';
import { createHash } from 'crypto';
import { fileURLToPath } from 'url';
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
Expand All @@ -44,7 +43,6 @@ import type {
CheckResult,
} from './api.mjs';
import type { BaseTaskGroup } from './tasks.mjs';
import { JHIPSTER_CONFIG_DIR } from '../generator-constants.mjs';
import { packageJson } from '../../lib/index.mjs';
import { type BaseApplication } from '../base-application/types.mjs';
import { GENERATOR_BOOTSTRAP } from '../generator-list.mjs';
Expand Down Expand Up @@ -529,49 +527,6 @@ export default class BaseGenerator extends JHipsterBaseBlueprintGenerator {
});
}

/**
* Get all the generator configuration from the .yo-rc.json file
* @param entityName - Name of the entity to load.
* @param {boolean} create - Create storage if doesn't exists.
*/
getEntityConfig(entityName: string, create = false): Storage | undefined {
const entityPath = this.destinationPath(JHIPSTER_CONFIG_DIR, `${_.upperFirst(entityName)}.json`);
if (!create && !this.fs.exists(entityPath)) return undefined;
return this.createStorage(entityPath, { sorted: true } as any);
}

/**
* get sorted list of entities according to changelog date (i.e. the order in which they were added)
*/
getExistingEntities() {
function isBefore(e1, e2) {
return e1.definition.changelogDate - e2.definition.changelogDate;
}

const configDir = this.destinationPath(JHIPSTER_CONFIG_DIR);
if (!existsSync(configDir)) {
mkdirSync(configDir);
}
const dir = opendirSync(configDir);
const entityNames: string[] = [];
let dirent = dir.readSync();
while (dirent !== null) {
const extension = extname(dirent.name);
if (dirent.isFile() && extension === '.json') {
entityNames.push(basename(dirent.name, extension));
}
dirent = dir.readSync();
}
dir.closeSync();

const entities = [...new Set(((this.jhipsterConfig.entities as string[]) || []).concat(entityNames))]
.map(entityName => ({ name: entityName, definition: this.getEntityConfig(entityName)?.getAll() }))
.filter(entity => entity && entity.definition)
.sort(isBefore);
this.jhipsterConfig.entities = entities.map(({ name }) => name);
return entities;
}

private createSharedData(jhipsterOldVersion: string | null): SharedData<BaseApplication> {
const destinationPath = this.destinationPath();
const dirname = basename(destinationPath);
Expand Down
2 changes: 1 addition & 1 deletion generators/bootstrap-application-base/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const { STRING: TYPE_STRING } = CommonDBTypes;

// eslint-disable-next-line import/prefer-default-export
export function createUserEntity(customUserData = {}, application) {
const userEntityDefinition = this.readEntityJson('User');
const userEntityDefinition = this.getEntityConfig('User')?.getAll();
if (userEntityDefinition) {
if (userEntityDefinition.relationships && userEntityDefinition.relationships.length > 0) {
this.logger.warn('Relationships on the User entity side will be disregarded');
Expand Down
6 changes: 3 additions & 3 deletions generators/entities/generator.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import BaseGenerator from '../base/index.mjs';
import BaseApplicationGenerator from '../base-application/index.mjs';
import { JHIPSTER_CONFIG_DIR } from '../generator-constants.mjs';
import { GENERATOR_ENTITIES, GENERATOR_APP } from '../generator-list.mjs';
import { getDefaultAppName } from '../project-name/support/index.mjs';

export default class EntitiesGenerator extends BaseGenerator {
export default class EntitiesGenerator extends BaseApplicationGenerator {
constructor(args, options, features) {
super(args, options, { unique: 'namespace', ...features });

Expand Down Expand Up @@ -124,7 +124,7 @@ export default class EntitiesGenerator extends BaseGenerator {
};
}

get [BaseGenerator.COMPOSING]() {
get [BaseApplicationGenerator.COMPOSING]() {
return this.delegateTasksToBlueprint(() => this.composing);
}
}
14 changes: 7 additions & 7 deletions generators/entity/generator.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import fs from 'fs';
import _ from 'lodash';
import path from 'path';

import BaseGenerator from '../base/index.mjs';
import BaseApplicationGenerator from '../base-application/index.mjs';
import prompts from './prompts.mjs';
import { JHIPSTER_CONFIG_DIR, ANGULAR_DIR } from '../generator-constants.mjs';
import { applicationTypes, clientFrameworkTypes, getConfigWithDefaults, reservedKeywords } from '../../jdl/jhipster/index.mjs';
Expand All @@ -34,7 +34,7 @@ const { GATEWAY, MICROSERVICE } = applicationTypes;
const { NO: CLIENT_FRAMEWORK_NO, ANGULAR } = clientFrameworkTypes;
const { isReservedClassName } = reservedKeywords;

export default class EntityGenerator extends BaseGenerator {
export default class EntityGenerator extends BaseApplicationGenerator {
constructor(args, options, features) {
super(args, options, { unique: 'argument', ...features });

Expand Down Expand Up @@ -263,7 +263,7 @@ export default class EntityGenerator extends BaseGenerator {
};
}

get [BaseGenerator.INITIALIZING]() {
get [BaseApplicationGenerator.INITIALIZING]() {
return this.delegateTasksToBlueprint(() => this.initializing);
}

Expand All @@ -284,7 +284,7 @@ export default class EntityGenerator extends BaseGenerator {
};
}

get [BaseGenerator.PROMPTING]() {
get [BaseApplicationGenerator.PROMPTING]() {
return this.delegateTasksToBlueprint(() => this.prompting);
}

Expand All @@ -305,7 +305,7 @@ export default class EntityGenerator extends BaseGenerator {
};
}

get [BaseGenerator.COMPOSING]() {
get [BaseApplicationGenerator.COMPOSING]() {
return this.delegateTasksToBlueprint(() => this.composing);
}

Expand All @@ -328,7 +328,7 @@ export default class EntityGenerator extends BaseGenerator {
};
}

get [BaseGenerator.WRITING]() {
get [BaseApplicationGenerator.WRITING]() {
return this.delegateTasksToBlueprint(() => this.writing);
}

Expand All @@ -341,7 +341,7 @@ export default class EntityGenerator extends BaseGenerator {
};
}

get [BaseGenerator.END]() {
get [BaseApplicationGenerator.END]() {
return this.delegateTasksToBlueprint(() => this.end);
}

Expand Down
28 changes: 18 additions & 10 deletions generators/info/generator.mts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
import chalk from 'chalk';
import type { ExecaReturnValue } from 'execa';

import BaseGenerator from '../base/index.mjs';
import BaseApplicationGenerator from '../base-application/index.mjs';
import JSONToJDLEntityConverter from '../../jdl/converters/json-to-jdl-entity-converter.js';
import JSONToJDLOptionConverter from '../../jdl/converters/json-to-jdl-option-converter.js';
import type { JHipsterGeneratorFeatures, JHipsterGeneratorOptions } from '../base/api.mjs';
import { type BaseApplication } from '../base-application/types.mjs';

export default class InfoGenerator extends BaseGenerator {
export default class InfoGenerator extends BaseApplicationGenerator<BaseApplication> {
constructor(args: string | string[], options: JHipsterGeneratorOptions, features: JHipsterGeneratorFeatures) {
super(args, options, { unique: 'namespace', ...features });

Expand All @@ -43,7 +44,7 @@ export default class InfoGenerator extends BaseGenerator {
this.env.options.skipInstall = true;
}

get [BaseGenerator.INITIALIZING]() {
get [BaseApplicationGenerator.INITIALIZING]() {
return this.asInitializingTaskGroup({
sayHello() {
this.logger.info(chalk.white('Welcome to the JHipster Information Sub-Generator\n'));
Expand All @@ -65,13 +66,6 @@ export default class InfoGenerator extends BaseGenerator {
console.log(`\n<details>\n<summary>.yo-rc.json file</summary>\n<pre>\n${result}\n</pre>\n</details>\n`);
},

displayEntities() {
console.log('\n##### **JDL for the Entity configuration(s) `entityName.json` files generated in the `.jhipster` directory**\n');
const jdl = this.generateJDLFromEntities();
console.log('<details>\n<summary>JDL entity definitions</summary>\n');
console.log(`<pre>\n${jdl?.toString()}\n</pre>\n</details>\n`);
},

async checkJava() {
console.log('\n##### **Environment and Tools**\n');
await this.checkCommand('java', ['-version'], ({ stderr }) => console.log(stderr));
Expand All @@ -95,6 +89,20 @@ export default class InfoGenerator extends BaseGenerator {
async checkDocker() {
await this.checkCommand('docker', ['-v']);
},

checkApplication() {
if (this.jhipsterConfig.baseName === undefined) {
this.logger.warn("Current location doesn't contain a valid JHipster application");
this.cancelCancellableTasks();
}
},

displayEntities() {
console.log('\n##### **JDL for the Entity configuration(s) `entityName.json` files generated in the `.jhipster` directory**\n');
const jdl = this.generateJDLFromEntities();
console.log('<details>\n<summary>JDL entity definitions</summary>\n');
console.log(`<pre>\n${jdl?.toString()}\n</pre>\n</details>\n`);
},
});
}

Expand Down
Loading