Skip to content

Commit

Permalink
refactor(migrations): extend abstract migration (#12963)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
pret-a-porter and viceice committed Dec 11, 2021
1 parent c7dbbd8 commit a4249f9
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 105 deletions.
2 changes: 1 addition & 1 deletion lib/config/migration.ts
Expand Up @@ -33,7 +33,7 @@ export function migrateConfig(
optionTypes[option.name] = option.type;
});
}
const newConfig = MigrationsService.run(config);
const newConfig = MigrationsService.run(config).migratedConfig;
const migratedConfig = clone(newConfig) as MigratedRenovateConfig;
const depTypes = [
'dependencies',
Expand Down
45 changes: 35 additions & 10 deletions lib/config/migrations/base/abstract-migration.ts
@@ -1,24 +1,49 @@
import is from '@sindresorhus/is';
import type { RenovateConfig } from '../../types';
import type { Migration } from '../types';

export abstract class AbstractMigration implements Migration {
readonly propertyName: string;
abstract readonly propertyName: string;

protected readonly originalConfig: RenovateConfig;
private readonly originalConfig: RenovateConfig;

protected readonly migratedConfig: RenovateConfig;
private readonly migratedConfig: RenovateConfig;

constructor(
propertyName: string,
originalConfig: RenovateConfig,
migratedConfig: RenovateConfig
) {
this.propertyName = propertyName;
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
this.originalConfig = originalConfig;
this.migratedConfig = migratedConfig;
}

abstract run(): void;
abstract run(value: unknown): void;

protected get<Key extends keyof RenovateConfig>(
key: Key
): RenovateConfig[Key] {
return this.migratedConfig[key] ?? this.originalConfig[key];
}

protected setSafely<Key extends keyof RenovateConfig>(
key: Key,
value: RenovateConfig[Key]
): void {
if (
is.nullOrUndefined(this.originalConfig[key]) &&
is.nullOrUndefined(this.migratedConfig[key])
) {
this.migratedConfig[key] = value;
}
}

protected setHard<Key extends keyof RenovateConfig>(
key: Key,
value: RenovateConfig[Key]
): void {
this.migratedConfig[key] = value;
}

protected rewrite(value: unknown): void {
this.setHard(this.propertyName, value);
}

protected delete(property: string): void {
delete this.migratedConfig[property];
Expand Down
12 changes: 12 additions & 0 deletions lib/config/migrations/base/remove-property-migration.ts
@@ -1,6 +1,18 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from './abstract-migration';

export class RemovePropertyMigration extends AbstractMigration {
readonly propertyName: string;

constructor(
propertyName: string,
originalConfig: RenovateConfig,
migratedConfig: RenovateConfig
) {
super(originalConfig, migratedConfig);
this.propertyName = propertyName;
}

override run(): void {
this.delete(this.propertyName);
}
Expand Down
12 changes: 7 additions & 5 deletions lib/config/migrations/base/rename-property-migration.ts
Expand Up @@ -2,22 +2,24 @@ import type { RenovateConfig } from '../../types';
import { AbstractMigration } from './abstract-migration';

export class RenamePropertyMigration extends AbstractMigration {
protected readonly newPropertyName: string;
readonly propertyName: string;

private readonly newPropertyName: string;

constructor(
deprecatedPropertyName: string,
newPropertyName: string,
originalConfig: RenovateConfig,
migratedConfig: RenovateConfig
) {
super(deprecatedPropertyName, originalConfig, migratedConfig);
super(originalConfig, migratedConfig);
this.propertyName = deprecatedPropertyName;
this.newPropertyName = newPropertyName;
}

override run(): void {
override run(value): void {
this.delete(this.propertyName);

this.migratedConfig[this.newPropertyName] =
this.originalConfig[this.propertyName];
this.setSafely(this.newPropertyName, value);
}
}
7 changes: 5 additions & 2 deletions lib/config/migrations/custom/binary-source-migration.spec.ts
Expand Up @@ -2,10 +2,13 @@ import { MigrationsService } from '../migrations-service';

describe('config/migrations/custom/binary-source-migration', () => {
it('should migrate "auto" to "global"', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
binarySource: 'auto',
});

expect(migratedConfig.binarySource).toBe('global');
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
binarySource: 'global',
});
});
});
11 changes: 4 additions & 7 deletions lib/config/migrations/custom/binary-source-migration.ts
@@ -1,14 +1,11 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from '../base/abstract-migration';

export class BinarySourceMigration extends AbstractMigration {
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
super('binarySource', originalConfig, migratedConfig);
}
readonly propertyName = 'binarySource';

override run(): void {
if (this.originalConfig.binarySource === 'auto') {
this.migratedConfig.binarySource = 'global';
override run(value): void {
if (value === 'auto') {
this.rewrite('global');
}
}
}
22 changes: 13 additions & 9 deletions lib/config/migrations/custom/go-mod-tidy-migration.spec.ts
Expand Up @@ -2,30 +2,34 @@ import { MigrationsService } from '../migrations-service';

describe('config/migrations/custom/go-mod-tidy-migration', () => {
it('should add postUpdateOptions option when true', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
gomodTidy: true,
postUpdateOptions: ['test'],
});

expect(migratedConfig).not.toHaveProperty('gomodTidy');
expect(migratedConfig.postUpdateOptions).toEqual(['test', 'gomodTidy']);
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
postUpdateOptions: ['test', 'gomodTidy'],
});
});

it('should handle case when postUpdateOptions is not defined ', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
gomodTidy: true,
});

expect(migratedConfig).not.toHaveProperty('gomodTidy');
expect(migratedConfig.postUpdateOptions).toEqual(['gomodTidy']);
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
postUpdateOptions: ['gomodTidy'],
});
});

it('should only remove when false', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
gomodTidy: false,
});

expect(migratedConfig).not.toHaveProperty('gomodTidy');
expect(migratedConfig).not.toHaveProperty('postUpdateOptions');
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({});
});
});
17 changes: 8 additions & 9 deletions lib/config/migrations/custom/go-mod-tidy-migration.ts
@@ -1,19 +1,18 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from '../base/abstract-migration';

export class GoModTidyMigration extends AbstractMigration {
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
super('gomodTidy', originalConfig, migratedConfig);
}
readonly propertyName = 'gomodTidy';

override run(): void {
const { gomodTidy, postUpdateOptions } = this.originalConfig;
override run(value): void {
const postUpdateOptions = this.get('postUpdateOptions');

this.delete(this.propertyName);

if (gomodTidy) {
this.migratedConfig.postUpdateOptions ??= postUpdateOptions ?? [];
this.migratedConfig.postUpdateOptions.push('gomodTidy');
if (value) {
const newPostUpdateOptions = Array.isArray(postUpdateOptions)
? postUpdateOptions.concat(['gomodTidy'])
: ['gomodTidy'];
this.setHard('postUpdateOptions', newPostUpdateOptions);
}
}
}
Expand Up @@ -2,10 +2,11 @@ import { MigrationsService } from '../migrations-service';

describe('config/migrations/custom/ignore-node-modules-migration', () => {
it('should migrate to ignorePaths', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
ignoreNodeModules: true,
});

expect(migratedConfig.ignorePaths).toEqual(['node_modules/']);
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({ ignorePaths: ['node_modules/'] });
});
});
11 changes: 3 additions & 8 deletions lib/config/migrations/custom/ignore-node-modules-migration.ts
@@ -1,16 +1,11 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from '../base/abstract-migration';

export class IgnoreNodeModulesMigration extends AbstractMigration {
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
super('ignoreNodeModules', originalConfig, migratedConfig);
}
readonly propertyName = 'ignoreNodeModules';

override run(): void {
override run(value): void {
this.delete(this.propertyName);

this.migratedConfig.ignorePaths = this.originalConfig.ignoreNodeModules
? ['node_modules/']
: [];
this.setSafely('ignorePaths', value ? ['node_modules/'] : []);
}
}
Expand Up @@ -2,11 +2,13 @@ import { MigrationsService } from '../migrations-service';

describe('config/migrations/custom/required-status-checks-migration', () => {
it('should migrate requiredStatusChecks=null to ignoreTests=true', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
requiredStatusChecks: null,
});

expect(migratedConfig).not.toHaveProperty('requiredStatusChecks');
expect(migratedConfig.ignoreTests).toBeTrue();
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
ignoreTests: true,
});
});
});
11 changes: 4 additions & 7 deletions lib/config/migrations/custom/required-status-checks-migration.ts
@@ -1,16 +1,13 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from '../base/abstract-migration';

export class RequiredStatusChecksMigration extends AbstractMigration {
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
super('requiredStatusChecks', originalConfig, migratedConfig);
}
readonly propertyName = 'requiredStatusChecks';

override run(): void {
override run(value): void {
this.delete(this.propertyName);

if (this.originalConfig.requiredStatusChecks === null) {
this.migratedConfig.ignoreTests = true;
if (value === null) {
this.setSafely('ignoreTests', true);
}
}
}
22 changes: 14 additions & 8 deletions lib/config/migrations/custom/trust-level-migration.spec.ts
Expand Up @@ -2,25 +2,31 @@ import { MigrationsService } from '../migrations-service';

describe('config/migrations/custom/trust-level-migration', () => {
it('should handle hight level', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
trustLevel: 'high',
});

expect(migratedConfig.allowCustomCrateRegistries).toBeTrue();
expect(migratedConfig.allowScripts).toBeTrue();
expect(migratedConfig.exposeAllEnv).toBeTrue();
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
allowCustomCrateRegistries: true,
allowScripts: true,
exposeAllEnv: true,
});
});

it('should not rewrite provided properties', () => {
const migratedConfig = MigrationsService.run({
const { isMigrated, migratedConfig } = MigrationsService.run({
allowCustomCrateRegistries: false,
allowScripts: false,
exposeAllEnv: false,
trustLevel: 'high',
});

expect(migratedConfig.allowCustomCrateRegistries).toBeFalse();
expect(migratedConfig.allowScripts).toBeFalse();
expect(migratedConfig.exposeAllEnv).toBeFalse();
expect(isMigrated).toBeTrue();
expect(migratedConfig).toEqual({
allowCustomCrateRegistries: false,
allowScripts: false,
exposeAllEnv: false,
});
});
});
18 changes: 6 additions & 12 deletions lib/config/migrations/custom/trust-level-migration.ts
@@ -1,21 +1,15 @@
import type { RenovateConfig } from '../../types';
import { AbstractMigration } from '../base/abstract-migration';

export class TrustLevelMigration extends AbstractMigration {
constructor(originalConfig: RenovateConfig, migratedConfig: RenovateConfig) {
super('trustLevel', originalConfig, migratedConfig);
}
readonly propertyName = 'trustLevel';

override run(): void {
override run(value): void {
this.delete(this.propertyName);

if (this.originalConfig.trustLevel === 'high') {
this.migratedConfig.allowCustomCrateRegistries =
this.originalConfig.allowCustomCrateRegistries ?? true;
this.migratedConfig.allowScripts =
this.originalConfig.allowScripts ?? true;
this.migratedConfig.exposeAllEnv =
this.originalConfig.exposeAllEnv ?? true;
if (value === 'high') {
this.setSafely('allowCustomCrateRegistries', true);
this.setSafely('allowScripts', true);
this.setSafely('exposeAllEnv', true);
}
}
}

0 comments on commit a4249f9

Please sign in to comment.