-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cascading] from release/10.3 to main (#1826)
<!-- {"currentBranch":"release/10.3","targetBranch":"main","bypassReviewers":false,"isConflicting":false} --> ## Cascading from release/10.3 to main --- <small>This Pull Request has been generated with ❤️ by the [Otter](https://github.com/AmadeusITGroup/otter) cascading tool.</small>
- Loading branch information
Showing
12 changed files
with
220 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
packages/@ama-sdk/schematics/schematics/helpers/is-typescript-project.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Tree } from '@angular-devkit/schematics'; | ||
|
||
/** | ||
* Determine if the targeted SDK is typescript based | ||
* @param tree Schematic Tree | ||
* @param pathInTree Path to the SDK in the tree | ||
*/ | ||
export const isTypescriptSdk = (tree: Tree, pathInTree = '/') => { | ||
return tree.getDir(pathInTree) | ||
.subfiles | ||
.some((filePath) => /tsconfig[^/\\]*\.json$/.test(filePath)); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { Rule } from '@angular-devkit/schematics'; | ||
import { MigrateSchematicsSchemaOptions } from './schema'; | ||
import { getMigrationRuleRunner, getWorkspaceConfig, type MigrationRulesMap } from '@o3r/schematics'; | ||
import { resolve } from 'node:path'; | ||
import { gt, minVersion } from 'semver'; | ||
import { isTypescriptSdk } from '../helpers/is-typescript-project'; | ||
|
||
const tsMigrationMap: MigrationRulesMap = { | ||
|
||
}; | ||
/** | ||
* Facilitate the migration of a version to another by the run of migration rules | ||
* @param options | ||
*/ | ||
function migrateFn(options: MigrateSchematicsSchemaOptions): Rule { | ||
|
||
const currentVersion = JSON.parse(require(resolve(__dirname, '..', '..', 'package.json'))).version; | ||
const to: string = options.to || currentVersion; | ||
const minimumVersion = minVersion(to); | ||
|
||
return (tree, context) => { | ||
if (minimumVersion && gt(minimumVersion, currentVersion)) { | ||
context.logger.warn(`The specified range "${to}" has a minimum supported version higher than the current version of @ama-sdk/schematics (${currentVersion}).` + | ||
' The migration may not have any effect.'); | ||
} | ||
const workingDirectory = options?.projectName && getWorkspaceConfig(tree)?.projects[options.projectName]?.root || '/'; | ||
const runMigrateSchematic = isTypescriptSdk(tree, workingDirectory) ? getMigrationRuleRunner(tsMigrationMap, { logger: context.logger }) : undefined; | ||
return runMigrateSchematic?.({from: options.from, to}); | ||
}; | ||
} | ||
|
||
/** | ||
* Facilitate the migration of a version to another by the run of migration rules | ||
* @param options | ||
*/ | ||
export const migrate = (options: MigrateSchematicsSchemaOptions) => async () => { | ||
const { createSchematicWithMetricsIfInstalled } = await import('@o3r/schematics'); | ||
return createSchematicWithMetricsIfInstalled(migrateFn)(options); | ||
}; |
28 changes: 28 additions & 0 deletions
28
packages/@ama-sdk/schematics/schematics/migrate/schema.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "MigrateSchematicsSchema", | ||
"title": "Execute migration scripts between 2 versions", | ||
"description": "Schematics to migrate from a specific version to another one", | ||
"properties": { | ||
"from": { | ||
"type": "string", | ||
"description": "Starting version from which the migration scripts are executed", | ||
"x-prompt": "What was the original version before migration?" | ||
}, | ||
"to": { | ||
"type": "string", | ||
"description": "Version of the package to migrate to (will use the current version if not specified)" | ||
}, | ||
"projectName": { | ||
"type": "string", | ||
"description": "Project name (in case it is applied to a module from an Angular Project)", | ||
"$default": { | ||
"$source": "projectName" | ||
} | ||
} | ||
}, | ||
"additionalProperties": true, | ||
"required": [ | ||
"from" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** Schematic Option */ | ||
export interface MigrateSchematicsSchemaOptions { | ||
/** Starting version from which the migration scripts are executed */ | ||
from: string; | ||
/** Version of the package to migrate to (will use the current version if not specified) */ | ||
to?: string; | ||
/** Project name */ | ||
projectName?: string | undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
packages/@o3r/schematics/src/utility/migration/migration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { callRule, Tree } from '@angular-devkit/schematics'; | ||
import { getMigrationRuleRunner } from './migration'; | ||
import { firstValueFrom } from 'rxjs'; | ||
|
||
describe('getMigrationRuleRunner', () => { | ||
|
||
it('should execute rule when in the range', async () => { | ||
const spy = jest.fn(); | ||
const runnner = getMigrationRuleRunner({ | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
'10.0.*': spy | ||
}); | ||
|
||
const rules = runnner({ from: '9.0.0', to: '10.1.0' }); | ||
|
||
await firstValueFrom(callRule(rules, Tree.empty(), {} as any)); | ||
|
||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not execute rule when not in the range', async () => { | ||
const spy = jest.fn(); | ||
const spy2 = jest.fn(); | ||
const runnner = getMigrationRuleRunner({ | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
'8.*': spy2, | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
'10.0.*': spy | ||
}); | ||
|
||
const rules = runnner({ from: '8.0.0', to: '9.1.0' }); | ||
await firstValueFrom(callRule(rules, Tree.empty(), {} as any)); | ||
|
||
expect(spy).not.toHaveBeenCalled(); | ||
expect(spy2).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should execute rule when in the range without limit', async () => { | ||
const spy = jest.fn(); | ||
const runnner = getMigrationRuleRunner({ | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
'10.0.*': spy | ||
}); | ||
|
||
const rules = runnner({ from: '9.0.0' }); | ||
await firstValueFrom(callRule(rules, Tree.empty(), {} as any)); | ||
|
||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
}); |
60 changes: 60 additions & 0 deletions
60
packages/@o3r/schematics/src/utility/migration/migration.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import type { LoggerApi } from '@angular-devkit/core/src/logger'; | ||
import { chain, type Rule } from '@angular-devkit/schematics'; | ||
import { intersects, Range, validRange } from 'semver'; | ||
|
||
/** Create the migration */ | ||
interface MigrateRuleRunnerOptions { | ||
/** The original version from which to execute the rules */ | ||
from: string; | ||
|
||
/** | ||
* The last version for which to execute the rule. | ||
* If not specified, all the versions from the "from" parameter will be considered. | ||
*/ | ||
to?: string; | ||
} | ||
|
||
/** Mapping of rules to apply to its specific range */ | ||
export interface MigrationRulesMap { | ||
/** Rules to apply to a specific semver range */ | ||
[range: string]: Rule | Rule[]; | ||
} | ||
|
||
/** | ||
* Option for migration rule runner factory | ||
*/ | ||
interface MigrationRuleRunnerOptions { | ||
/** Logger */ | ||
logger?: LoggerApi; | ||
} | ||
|
||
/** | ||
* Generate the Migration Rule Schematic runner to execute rules according to the range | ||
* @param rulesMapping Mapping of rules to execute based on its semver range | ||
* @param options Additional options | ||
*/ | ||
export function getMigrationRuleRunner(rulesMapping: MigrationRulesMap, options?: MigrationRuleRunnerOptions) { | ||
const rangeMapping = Object.entries(rulesMapping) | ||
.reduce((acc, [range, rule]) => { | ||
const checkedRange = validRange(range); | ||
if (!checkedRange) { | ||
options?.logger?.warn(`The range "${range}" is invalid and will be ignored in the Migration rule`); | ||
} else { | ||
acc.push([checkedRange, Array.isArray(rule) ? rule : [rule]]); | ||
} | ||
return acc; | ||
}, [] as [string, Rule[]][]); | ||
|
||
/** | ||
* Migration rule runner | ||
* @param config Provide information regarding the range to match | ||
*/ | ||
return (config: MigrateRuleRunnerOptions): Rule => { | ||
const fromToRange = new Range(config.to ? `>${config.from} <=${config.to}` : `>${config.from}`); | ||
return chain( | ||
rangeMapping | ||
.filter(([range]) => intersects(range, fromToRange)) | ||
.map(([_, rules]) => chain(rules)) | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters