Skip to content

Commit 864b231

Browse files
author
Simon Stone
authored
feat(*): add keep and set prerelease option to version command (#493)
Signed-off-by: Simon Stone <[email protected]>
1 parent 853837a commit 864b231

File tree

3 files changed

+52
-19
lines changed

3 files changed

+52
-19
lines changed

packages/concerto-cli/index.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,38 @@ require('yargs')
226226
})
227227
.command('version <release>', 'modify the version of one or more model files', yargs => {
228228
yargs.demandOption(['model'], 'Please provide Concerto model(s)');
229+
yargs.positional('release', {
230+
describe: 'the new version, or a release to use when incrementing the existing version',
231+
type: 'string',
232+
choices: [
233+
'keep',
234+
'major',
235+
'minor',
236+
'patch',
237+
'premajor',
238+
'preminor',
239+
'prepatch',
240+
'prerelease'
241+
]
242+
});
229243
yargs.option('model', {
230244
alias: 'models',
231245
describe: 'array of concerto model files',
232246
type: 'string',
233247
array: true
234248
});
249+
yargs.option('prerelease', {
250+
describe: 'set the specified pre-release version',
251+
type: 'string'
252+
});
235253
}, argv => {
236254
const modelFiles = argv.model.flatMap(model => {
237255
if (glob.hasMagic(model)) {
238256
return glob.sync(model);
239257
}
240258
return model;
241259
});
242-
return Commands.version(argv.release, modelFiles)
260+
return Commands.version(argv.release, modelFiles, argv.prerelease)
243261
.then((result) => {
244262
if (result) {
245263
Logger.info(result);

packages/concerto-cli/lib/commands.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,13 @@ class Commands {
281281
*
282282
* @param {string} release the release, major/minor/patch, or a semantic version
283283
* @param {string[]} modelFiles the list of model file paths
284+
* @param {string} [prerelease] the pre-release version to set
284285
*/
285-
static async version(release, modelFiles) {
286+
static async version(release, modelFiles, prerelease) {
286287
const updatedModelFiles = [];
287288
for (const modelFile of modelFiles) {
288289
const resolvedModelFile = path.resolve(modelFile);
289-
const updatedModelFile = await Commands.versionModelFile(release, resolvedModelFile);
290+
const updatedModelFile = await Commands.versionModelFile(release, resolvedModelFile, prerelease);
290291
updatedModelFiles.push(updatedModelFile);
291292
}
292293
Commands.updateImportsForUpdatedModelFiles(updatedModelFiles);
@@ -324,16 +325,17 @@ class Commands {
324325
*
325326
* @param {string} release the release, major/minor/patch, or a semantic version
326327
* @param {string} modelFile the model file path
328+
* @param {string} [prerelease] the pre-release version to set
327329
* @private
328330
*/
329-
static async versionModelFile(release, modelFile) {
331+
static async versionModelFile(release, modelFile, prerelease) {
330332
const data = fs.readFileSync(modelFile, 'utf-8');
331333
const isMetaModel = Commands.isJSON(data);
332334
if (isMetaModel) {
333-
return Commands.versionMetaModelFile(release, modelFile, data);
335+
return Commands.versionMetaModelFile(release, modelFile, data, prerelease);
334336

335337
} else {
336-
return Commands.versionCtoModelFile(release, modelFile, data);
338+
return Commands.versionCtoModelFile(release, modelFile, data, prerelease);
337339
}
338340
}
339341

@@ -419,13 +421,14 @@ class Commands {
419421
* @param {string} release the release, major/minor/patch, or a semantic version
420422
* @param {string} modelFile the model file path
421423
* @param {string} data the model file data
424+
* @param {string} [prerelease] the pre-release version to set
422425
* @private
423426
*/
424-
static async versionMetaModelFile(release, modelFile, data) {
427+
static async versionMetaModelFile(release, modelFile, data, prerelease) {
425428
const metamodel = JSON.parse(data);
426429
const currentNamespace = metamodel.namespace;
427430
const [namespace, currentVersion] = currentNamespace.split('@');
428-
const newVersion = Commands.calculateNewVersion(release, currentVersion);
431+
const newVersion = Commands.calculateNewVersion(release, currentVersion, prerelease);
429432
const newNamespace = [namespace, newVersion].join('@');
430433
metamodel.namespace = newNamespace;
431434
const newData = JSON.stringify(metamodel, null, 2);
@@ -447,13 +450,14 @@ class Commands {
447450
* @param {string} release the release, major/minor/patch, or a semantic version
448451
* @param {string} modelFile the model file path
449452
* @param {string} data the model file data
453+
* @param {string} [prerelease] the pre-release version to set
450454
* @private
451455
*/
452-
static async versionCtoModelFile(release, modelFile, data) {
456+
static async versionCtoModelFile(release, modelFile, data, prerelease) {
453457
const metamodel = Parser.parse(data);
454458
const currentNamespace = metamodel.namespace;
455459
const [namespace, currentVersion] = currentNamespace.split('@');
456-
const newVersion = Commands.calculateNewVersion(release, currentVersion);
460+
const newVersion = Commands.calculateNewVersion(release, currentVersion, prerelease);
457461
const newNamespace = [namespace, newVersion].join('@');
458462
const newData = data.replace(/(namespace\s+)(\S+)/, (match, keyword) => {
459463
return `${keyword}${newNamespace}`;
@@ -475,20 +479,30 @@ class Commands {
475479
*
476480
* @param {string} release the release, major/minor/patch, or a semantic version
477481
* @param {string} currentVersion the current version
482+
* @param {string} [prerelease] the pre-release version to set
478483
* @returns {string} the new version
479484
* @private
480485
*/
481-
static calculateNewVersion(release, currentVersion) {
486+
static calculateNewVersion(release, currentVersion, prerelease) {
482487
if (semver.valid(release)) {
483488
return release;
484489
} else if (!semver.valid(currentVersion)) {
485490
throw new Error(`invalid current version "${currentVersion}"`);
486491
}
487-
const newVersion = semver.inc(currentVersion, release);
488-
if (!newVersion) {
489-
throw new Error(`invalid release "${release}"`);
492+
const result = semver.parse(currentVersion);
493+
if (release !== 'keep') {
494+
try {
495+
result.inc(release);
496+
} catch (error) {
497+
throw new Error(`invalid release "${release}"`);
498+
}
499+
}
500+
if (prerelease) {
501+
result.prerelease = prerelease.split('.');
502+
return result.format();
503+
} else {
504+
return result.toString();
490505
}
491-
return newVersion;
492506
}
493507

494508
/**

packages/concerto-cli/test/cli.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,20 +297,21 @@ describe('concerto-cli', () => {
297297
{ name: 'minor', release: 'minor', expectedNamespace: '[email protected]' },
298298
{ name: 'major', release: 'major', expectedNamespace: '[email protected]' },
299299
{ name: 'explicit', release: '4.5.6', expectedNamespace: '[email protected]' },
300-
{ name: 'prerelease', release: '5.6.7-pr.3472381', expectedNamespace: '[email protected]' }
300+
{ name: 'prerelease', release: '5.6.7-pr.3472381', expectedNamespace: '[email protected]' },
301+
{ name: 'keep-and-set-prerelease', release: 'keep', prerelease: 'pr.1234567', expectedNamespace: '[email protected]' }
301302
];
302303

303-
tests.forEach(({ name, release, expectedNamespace }) => {
304+
tests.forEach(({ name, release, prerelease, expectedNamespace }) => {
304305

305306
it(`should patch bump a cto file [${name}]`, async () => {
306-
await Commands.version(release, [ctoPath]);
307+
await Commands.version(release, [ctoPath], prerelease);
307308
const cto = fs.readFileSync(ctoPath, 'utf-8');
308309
const metamodel = Parser.parse(cto);
309310
metamodel.namespace.should.equal(expectedNamespace);
310311
});
311312

312313
it(`should patch bump a metamodel file [${name}]`, async () => {
313-
await Commands.version(release, [metamodelPath]);
314+
await Commands.version(release, [metamodelPath], prerelease);
314315
const metamodel = JSON.parse(fs.readFileSync(metamodelPath, 'utf-8'));
315316
metamodel.namespace.should.equal(expectedNamespace);
316317
});

0 commit comments

Comments
 (0)