Skip to content

Commit

Permalink
Add semver range capabilities into migrations (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelramalho19 authored and sindresorhus committed Nov 1, 2019
1 parent 16d51fc commit df3a256
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 3 deletions.
17 changes: 14 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ class Conf {
let previousMigratedVersion = this._get(MIGRATION_KEY, '0.0.0');

const newerVersions = Object.keys(migrations)
.filter(candidateVersion => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate))
.sort(semver.compare);
.filter(candidateVersion => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate));

let storeBackup = {...this.store};

Expand All @@ -220,7 +219,7 @@ class Conf {
}
}

if (!semver.eq(previousMigratedVersion, versionToMigrate)) {
if (this._isVersionInRangeFormat(previousMigratedVersion) || !semver.eq(previousMigratedVersion, versionToMigrate)) {
this._set(MIGRATION_KEY, versionToMigrate);
}
}
Expand Down Expand Up @@ -249,7 +248,19 @@ class Conf {
return false;
}

_isVersionInRangeFormat(version) {
return semver.clean(version) === null;
}

_shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate) {
if (this._isVersionInRangeFormat(candidateVersion)) {
if (previousMigratedVersion !== '0.0.0' && semver.satisfies(previousMigratedVersion, candidateVersion)) {
return false;
}

return semver.satisfies(versionToMigrate, candidateVersion);
}

if (semver.lte(candidateVersion, previousMigratedVersion)) {
return false;
}
Expand Down
81 changes: 81 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,87 @@ test('migrations - should run the migration when the version changes', t => {
t.is(conf2.get('foo'), 'cool stuff');
});

test('migrations - should run the migration when the version uses semver comparisons', t => {
const cwd = tempy.directory();
const migrations = {
'>=1.0': store => {
store.set('foo', 'cool stuff');
}
};

const conf = new Conf({cwd, projectVersion: '1.0.2', migrations});
t.is(conf._get('__internal__.migrations.version'), '1.0.2');
t.is(conf.get('foo'), 'cool stuff');
});

test('migrations - should run the migration when the version uses multiple semver comparisons', t => {
const cwd = tempy.directory();
const migrations = {
'>=1.0': store => {
store.set('foo', 'cool stuff');
},
'>2.0.0': store => {
store.set('foo', 'modern cool stuff');
}
};

const conf = new Conf({cwd, projectVersion: '1.0.2', migrations});
t.is(conf._get('__internal__.migrations.version'), '1.0.2');
t.is(conf.get('foo'), 'cool stuff');

const conf2 = new Conf({cwd, projectVersion: '2.0.1', migrations});
t.is(conf2._get('__internal__.migrations.version'), '2.0.1');
t.is(conf2.get('foo'), 'modern cool stuff');
});

test('migrations - should run all valid migrations when the version uses multiple semver comparisons', t => {
const cwd = tempy.directory();
const migrations = {
'>=1.0': store => {
store.set('foo', 'cool stuff');
},
'>2.0.0': store => {
store.set('woof', 'oof');
store.set('medium', 'yes');
},
'<3.0.0': store => {
store.set('woof', 'woof');
store.set('heart', '❤');
}
};

const conf = new Conf({cwd, projectVersion: '2.4.0', migrations});
t.is(conf._get('__internal__.migrations.version'), '2.4.0');
t.is(conf.get('foo'), 'cool stuff');
t.is(conf.get('medium'), 'yes');
t.is(conf.get('woof'), 'woof');
t.is(conf.get('heart'), '❤');
});

test('migrations - should cleanup migrations with non-numeric values', t => {
const cwd = tempy.directory();
const migrations = {
'1.0.1-alpha': store => {
store.set('foo', 'cool stuff');
},
'>2.0.0-beta': store => {
store.set('woof', 'oof');
store.set('medium', 'yes');
},
'<3.0.0': store => {
store.set('woof', 'woof');
store.set('heart', '❤');
}
};

const conf = new Conf({cwd, projectVersion: '2.4.0', migrations});
t.is(conf._get('__internal__.migrations.version'), '2.4.0');
t.is(conf.get('foo'), 'cool stuff');
t.is(conf.get('medium'), 'yes');
t.is(conf.get('woof'), 'woof');
t.is(conf.get('heart'), '❤');
});

test('migrations - should infer the applicationVersion from the package.json when it isn\'t specified', t => {
const cwd = tempy.directory();

Expand Down

0 comments on commit df3a256

Please sign in to comment.