Skip to content

Commit

Permalink
feat: add new builders for metadata migration check
Browse files Browse the repository at this point in the history
  • Loading branch information
cpourcel authored and fpaul-1A committed Jul 15, 2024
1 parent e2053dc commit 0d64b94
Show file tree
Hide file tree
Showing 48 changed files with 3,450 additions and 60 deletions.
1 change: 1 addition & 0 deletions .github/workflows/it-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ jobs:
npx --yes verdaccio --config $GITHUB_WORKSPACE\\.verdaccio\\conf\\config-without-docker.yaml --listen http://127.0.0.1:4873 &
npx --yes wait-on http://127.0.0.1:4873 -t 180000
fi
yarn verdaccio:login
shell: bash
- name: Test
id: it-tests
Expand Down
2 changes: 1 addition & 1 deletion .verdaccio/conf/.npmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
registry=http://127.0.0.1:4873
registry=http://127.0.0.1:4873/
92 changes: 90 additions & 2 deletions docs/cms-adapters/CMS_ADAPTERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ __Note:__ The duplicate CSS Variable will be specified as warning and overridden

### Rules engine extractor

### Metadata

As for the other metadata retrieved, a bit of configuration is needed in order to extract metadata for facts and operators in rules engine scope.

#### How to install
Expand Down Expand Up @@ -225,3 +223,93 @@ Example:
...
}
```

## How to check for breaking changes on metadata

Version after version, it can be verified whether any breaking changes have been introduced, or if there is any metadata provided to document it.
To achieve this, simply configure the following builder in your `angular.json` file as shown below.

```json5
{
// ...,
"projects": {
// ...,
"<project-name>": {
// ...,
"architect": {
"check-config-migration-metadata": {
"builder": "@o3r/components:check-config-migration-metadata",
"options": {
"migrationDataPath": "./MIGRATION-*.json", // Required
"granularity": "major", // Default value is minor
"allowBreakingChanges": true, // Default value is false
"packageManager": "npm", // If not provided, it will be computed
"metadataPath": "./component.config.metadata.json" // Default value
}
},
"check-style-migration-metadata": {
"builder": "@o3r/styling:check-style-migration-metadata",
"options": {
"migrationDataPath": "./MIGRATION-*.json"
}
},
"check-localization-migration-metadata": {
"builder": "@o3r/localization:check-localization-migration-metadata",
"options": {
"migrationDataPath": "./MIGRATION-*.json"
}
}
}
}
}
}
```

You can validate your migration metadata files with the following JSON schema, by adding:

```json5
{
"$schema": "https://raw.githubusercontent.com/AmadeusITGroup/otter/main/packages/@o3r/extractors/schemas/migration.metadata.schema.json"
}
```

Example of migration file:
```json5
{
"$schema": "https://raw.githubusercontent.com/AmadeusITGroup/otter/main/packages/@o3r/extractors/schemas/migration.metadata.schema.json",
"version": "10.0.0",
"changes": [
{
'contentType': 'CONFIG',
'before': {
'libraryName': '@old/lib',
'configName': 'OldConfig',
'propertyName': 'oldName'
},
'after': {
'libraryName': '@new/lib',
'configName': 'NewConfig',
'propertyName': 'newName'
}
},
{
'contentType': 'LOCALIZATION',
'before': {
'key': 'old-localization.key'
},
'after': {
'key': 'new-localization.key'
}
},
{
'contentType': 'STYLE',
'before': {
'name': 'old-css-var-name'
},
'after': {
'name': 'new-css-var-name'
}
}
]
}
```
5 changes: 3 additions & 2 deletions jest.config.it.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ const getJestProjectConfig = require('./jest.config.ut').getJestProjectConfig;

/**
* @param rootDir {string}
* @param options.tsconfig {string}
* @returns {import('ts-jest/dist/types').JestConfigWithTsJest}
*/
module.exports.getJestConfig = (rootDir) => ({
...getJestProjectConfig(rootDir, false),
module.exports.getJestConfig = (rootDir, options) => ({
...getJestProjectConfig(rootDir, false, options),
rootDir: '..',
setupFilesAfterEnv: null,
testPathIgnorePatterns: [
Expand Down
7 changes: 4 additions & 3 deletions jest.config.ut.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ globalThis.ngJest = {
* Jest configuration that can be set at project level
* @param rootDir {string}
* @param isAngularSetup {boolean}
* @param options.tsconfig {string}
* @returns {import('ts-jest/dist/types').JestConfigWithTsJest}
*/
module.exports.getJestProjectConfig = (rootDir, isAngularSetup) => {
module.exports.getJestProjectConfig = (rootDir, isAngularSetup, options) => {
const relativePath = relative(rootDir, __dirname);
const moduleNameMapper = Object.fromEntries(
Object.entries(pathsToModuleNameMapper(compilerOptions.paths))
Expand All @@ -39,7 +40,7 @@ module.exports.getJestProjectConfig = (rootDir, isAngularSetup) => {
'^.+\\.[mc]?tsx?$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
tsconfig: options?.tsconfig ?? '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.html$'
}
]
Expand All @@ -56,7 +57,7 @@ module.exports.getJestProjectConfig = (rootDir, isAngularSetup) => {
'^.+\\.tsx?$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
tsconfig: options?.tsconfig ?? '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.html$'
}
]
Expand Down
5 changes: 5 additions & 0 deletions packages/@o3r/components/builders.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"implementation": "./builders/component-extractor/",
"schema": "./builders/component-extractor/schema.json",
"description": "Extract the component metadata (configuration and class) from an Otter project"
},
"check-config-migration-metadata": {
"implementation": "./builders/metadata-check/",
"schema": "./builders/metadata-check/schema.json",
"description": "Check for component metadata breaking changes"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { ComponentConfigOutput } from '@o3r/components';
import type { MetadataComparator } from '@o3r/extractors';

/**
* Interface describing a config migration element
*/
export interface MigrationConfigData {
/** Library name */
libraryName: string;
/**
* Configuration name
*/
configName?: string;
/**
* Configuration property name
*/
propertyName?: string;
}

/**
* Returns an array of config metadata from a metadata file.
* To be easily parseable, the properties will be split in separate items of the array.
* @example
* [{ library: '@o3r/demo', properties: [{name : 'property1', type: 'string'}, {name : 'property2', type: 'number'}] }]
* will become :
* [{ library: '@o3r/demo', properties: [{name : 'property1', type: 'string'}] }, { library: '@o3r/demo', properties: [{name : 'property2', type: 'number'}] }]
* @param content Content of a migration metadata files
*/
const getConfigurationArray = (content: ComponentConfigOutput[]): ComponentConfigOutput[] => content.flatMap((config) =>
config.properties.length > 1
? config.properties.map((prop) => ({...config, properties: [prop]}))
: [config]
);

const getConfigurationPropertyName = (config: ComponentConfigOutput) => `${config.library}#${config.name}` + (config.properties.length ? ` ${config.properties[0].name}` : '');

const isMigrationConfigurationDataMatch = (config: ComponentConfigOutput, migrationData: MigrationConfigData) =>
migrationData.libraryName === config.library
&& (!migrationData.configName || migrationData.configName === config.name)
&& (!migrationData.propertyName || config.properties[0]?.name === migrationData.propertyName);

/**
* Comparator used to compare one version of config metadata with another
*/
export const configMetadataComparator: MetadataComparator<ComponentConfigOutput, MigrationConfigData, ComponentConfigOutput[]> = {
getArray: getConfigurationArray,
getIdentifier: getConfigurationPropertyName,
isMigrationDataMatch: isMigrationConfigurationDataMatch
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './config-metadata-comparison.helper';
Loading

0 comments on commit 0d64b94

Please sign in to comment.