Skip to content

Commit df3a256

Browse files
rafaelramalho19sindresorhus
authored andcommitted
Add semver range capabilities into migrations (#88)
1 parent 16d51fc commit df3a256

File tree

2 files changed

+95
-3
lines changed

2 files changed

+95
-3
lines changed

index.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,7 @@ class Conf {
197197
let previousMigratedVersion = this._get(MIGRATION_KEY, '0.0.0');
198198

199199
const newerVersions = Object.keys(migrations)
200-
.filter(candidateVersion => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate))
201-
.sort(semver.compare);
200+
.filter(candidateVersion => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate));
202201

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

@@ -220,7 +219,7 @@ class Conf {
220219
}
221220
}
222221

223-
if (!semver.eq(previousMigratedVersion, versionToMigrate)) {
222+
if (this._isVersionInRangeFormat(previousMigratedVersion) || !semver.eq(previousMigratedVersion, versionToMigrate)) {
224223
this._set(MIGRATION_KEY, versionToMigrate);
225224
}
226225
}
@@ -249,7 +248,19 @@ class Conf {
249248
return false;
250249
}
251250

251+
_isVersionInRangeFormat(version) {
252+
return semver.clean(version) === null;
253+
}
254+
252255
_shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate) {
256+
if (this._isVersionInRangeFormat(candidateVersion)) {
257+
if (previousMigratedVersion !== '0.0.0' && semver.satisfies(previousMigratedVersion, candidateVersion)) {
258+
return false;
259+
}
260+
261+
return semver.satisfies(versionToMigrate, candidateVersion);
262+
}
263+
253264
if (semver.lte(candidateVersion, previousMigratedVersion)) {
254265
return false;
255266
}

test.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,87 @@ test('migrations - should run the migration when the version changes', t => {
877877
t.is(conf2.get('foo'), 'cool stuff');
878878
});
879879

880+
test('migrations - should run the migration when the version uses semver comparisons', t => {
881+
const cwd = tempy.directory();
882+
const migrations = {
883+
'>=1.0': store => {
884+
store.set('foo', 'cool stuff');
885+
}
886+
};
887+
888+
const conf = new Conf({cwd, projectVersion: '1.0.2', migrations});
889+
t.is(conf._get('__internal__.migrations.version'), '1.0.2');
890+
t.is(conf.get('foo'), 'cool stuff');
891+
});
892+
893+
test('migrations - should run the migration when the version uses multiple semver comparisons', t => {
894+
const cwd = tempy.directory();
895+
const migrations = {
896+
'>=1.0': store => {
897+
store.set('foo', 'cool stuff');
898+
},
899+
'>2.0.0': store => {
900+
store.set('foo', 'modern cool stuff');
901+
}
902+
};
903+
904+
const conf = new Conf({cwd, projectVersion: '1.0.2', migrations});
905+
t.is(conf._get('__internal__.migrations.version'), '1.0.2');
906+
t.is(conf.get('foo'), 'cool stuff');
907+
908+
const conf2 = new Conf({cwd, projectVersion: '2.0.1', migrations});
909+
t.is(conf2._get('__internal__.migrations.version'), '2.0.1');
910+
t.is(conf2.get('foo'), 'modern cool stuff');
911+
});
912+
913+
test('migrations - should run all valid migrations when the version uses multiple semver comparisons', t => {
914+
const cwd = tempy.directory();
915+
const migrations = {
916+
'>=1.0': store => {
917+
store.set('foo', 'cool stuff');
918+
},
919+
'>2.0.0': store => {
920+
store.set('woof', 'oof');
921+
store.set('medium', 'yes');
922+
},
923+
'<3.0.0': store => {
924+
store.set('woof', 'woof');
925+
store.set('heart', '❤');
926+
}
927+
};
928+
929+
const conf = new Conf({cwd, projectVersion: '2.4.0', migrations});
930+
t.is(conf._get('__internal__.migrations.version'), '2.4.0');
931+
t.is(conf.get('foo'), 'cool stuff');
932+
t.is(conf.get('medium'), 'yes');
933+
t.is(conf.get('woof'), 'woof');
934+
t.is(conf.get('heart'), '❤');
935+
});
936+
937+
test('migrations - should cleanup migrations with non-numeric values', t => {
938+
const cwd = tempy.directory();
939+
const migrations = {
940+
'1.0.1-alpha': store => {
941+
store.set('foo', 'cool stuff');
942+
},
943+
'>2.0.0-beta': store => {
944+
store.set('woof', 'oof');
945+
store.set('medium', 'yes');
946+
},
947+
'<3.0.0': store => {
948+
store.set('woof', 'woof');
949+
store.set('heart', '❤');
950+
}
951+
};
952+
953+
const conf = new Conf({cwd, projectVersion: '2.4.0', migrations});
954+
t.is(conf._get('__internal__.migrations.version'), '2.4.0');
955+
t.is(conf.get('foo'), 'cool stuff');
956+
t.is(conf.get('medium'), 'yes');
957+
t.is(conf.get('woof'), 'woof');
958+
t.is(conf.get('heart'), '❤');
959+
});
960+
880961
test('migrations - should infer the applicationVersion from the package.json when it isn\'t specified', t => {
881962
const cwd = tempy.directory();
882963

0 commit comments

Comments
 (0)