From a8f432cd644cb59d2a53463ff6d89ac2b4abbd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 2 Nov 2021 15:00:15 +0100 Subject: [PATCH] feat: allow --no-update-package-json when providing closes #596 --- src/main.ts | 16 +++++++-- src/package.ts | 66 ++++++++++++++++++++++++------------ src/publish.ts | 3 +- src/test/package.test.ts | 72 ++++++++++++++++++++++++++++++++-------- 4 files changed, 119 insertions(+), 38 deletions(-) diff --git a/src/main.ts b/src/main.ts index f72c71fd..d2f29465 100644 --- a/src/main.ts +++ b/src/main.ts @@ -81,7 +81,11 @@ module.exports = function (argv: string[]): void { .option('-o, --out ', 'Output .vsix extension file to location (defaults to -.vsix)') .option('-t, --target ', 'Target architecture') .option('-m, --message ', 'Commit message used when calling `npm version`.') - .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`.') + .option( + '--no-git-tag-version', + 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.' + ) + .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.') .option( '--githubBranch ', 'The GitHub branch used to infer relative links in README.md. Can be overriden by --baseContentUrl and --baseImagesUrl.' @@ -106,6 +110,7 @@ module.exports = function (argv: string[]): void { target, message, gitTagVersion, + updatePackageJson, githubBranch, gitlabBranch, baseContentUrl, @@ -124,6 +129,7 @@ module.exports = function (argv: string[]): void { target, commitMessage: message, gitTagVersion, + updatePackageJson, githubBranch, gitlabBranch, baseContentUrl, @@ -147,7 +153,11 @@ module.exports = function (argv: string[]): void { ) .option('-t, --target ', 'Target architectures') .option('-m, --message ', 'Commit message used when calling `npm version`.') - .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`.') + .option( + '--no-git-tag-version', + 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.' + ) + .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.') .option('-i, --packagePath ', 'Publish the provided VSIX packages.') .option( '--githubBranch ', @@ -172,6 +182,7 @@ module.exports = function (argv: string[]): void { target, message, gitTagVersion, + updatePackageJson, packagePath, githubBranch, gitlabBranch, @@ -190,6 +201,7 @@ module.exports = function (argv: string[]): void { targets: target, commitMessage: message, gitTagVersion, + updatePackageJson, packagePath, githubBranch, gitlabBranch, diff --git a/src/package.ts b/src/package.ts index 8a3b20f2..df352c84 100644 --- a/src/package.ts +++ b/src/package.ts @@ -87,6 +87,7 @@ export interface IPackageOptions { readonly target?: string; readonly commitMessage?: string; readonly gitTagVersion?: boolean; + readonly updatePackageJson?: boolean; readonly cwd?: string; readonly githubBranch?: string; readonly gitlabBranch?: string; @@ -271,23 +272,31 @@ function isHostTrusted(url: url.UrlWithStringQuery): boolean { return TrustedSVGSources.indexOf(url.host.toLowerCase()) > -1 || isGitHubBadge(url.href); } -export async function versionBump( - cwd: string = process.cwd(), - version?: string, - commitMessage?: string, - gitTagVersion: boolean = true -): Promise { - if (!version) { - return Promise.resolve(null); +export interface IVersionBumpOptions { + readonly cwd?: string; + readonly version?: string; + readonly commitMessage?: string; + readonly gitTagVersion?: boolean; + readonly updatePackageJson?: boolean; +} + +export async function versionBump(options: IVersionBumpOptions): Promise { + if (!options.version) { + return; + } + + if (!(options.updatePackageJson ?? true)) { + return; } + const cwd = options.cwd ?? process.cwd(); const manifest = await readManifest(cwd); - if (manifest.version === version) { + if (manifest.version === options.version) { return null; } - switch (version) { + switch (options.version) { case 'major': case 'minor': case 'patch': @@ -297,20 +306,20 @@ export async function versionBump( case 'prepatch': case 'prerelease': case 'from-git': - return Promise.reject(`Not supported: ${version}`); + return Promise.reject(`Not supported: ${options.version}`); default: - if (!semver.valid(version)) { - return Promise.reject(`Invalid version ${version}`); + if (!semver.valid(options.version)) { + return Promise.reject(`Invalid version ${options.version}`); } } - let command = `npm version ${version}`; + let command = `npm version ${options.version}`; - if (commitMessage) { - command = `${command} -m "${commitMessage}"`; + if (options.commitMessage) { + command = `${command} -m "${options.commitMessage}"`; } - if (!gitTagVersion) { + if (!(options.gitTagVersion ?? true)) { command = `${command} --no-git-tag-version`; } @@ -343,7 +352,7 @@ const Targets = new Set([ ]); export class ManifestProcessor extends BaseProcessor { - constructor(manifest: Manifest, options: IPackageOptions = {}) { + constructor(manifest: Manifest, private readonly options: IPackageOptions = {}) { super(manifest); const flags = ['Public']; @@ -395,7 +404,7 @@ export class ManifestProcessor extends BaseProcessor { ...this.vsix, id: manifest.name, displayName: manifest.displayName || manifest.name, - version: manifest.version, + version: options.version && !(options.updatePackageJson ?? true) ? options.version : manifest.version, publisher: manifest.publisher, target, engine: manifest.engines['vscode'], @@ -439,6 +448,13 @@ export class ManifestProcessor extends BaseProcessor { return Promise.resolve(file); } + if (this.options.version && !(this.options.updatePackageJson ?? true)) { + const contents = await read(file); + const packageJson = JSON.parse(contents); + packageJson.version = this.options.version; + file = { ...file, contents: JSON.stringify(packageJson, undefined, 2) }; + } + // Ensure that package.json is writable as VS Code needs to // store metadata in the extracted file. return { ...file, mode: 0o100644 }; @@ -1400,11 +1416,17 @@ function writeVsix(files: IFile[], packagePath: string): Promise { } function getDefaultPackageName(manifest: Manifest, options: IPackageOptions): string { + let version = manifest.version; + + if (options.version && !(options.updatePackageJson ?? true)) { + version = options.version; + } + if (options.target) { - return `${manifest.name}-${options.target}-${manifest.version}.vsix`; + return `${manifest.name}-${options.target}-${version}.vsix`; } - return `${manifest.name}-${manifest.version}.vsix`; + return `${manifest.name}-${version}.vsix`; } async function prepublish(cwd: string, manifest: Manifest, useYarn?: boolean): Promise { @@ -1467,7 +1489,7 @@ export async function pack(options: IPackageOptions = {}): Promise { - await versionBump(options.cwd, options.version, options.commitMessage, options.gitTagVersion); + await versionBump(options); const { packagePath, files } = await pack(options); const stats = await stat(packagePath); diff --git a/src/publish.ts b/src/publish.ts index 8fadbd5c..f5c71f4f 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -16,6 +16,7 @@ export interface IPublishOptions { readonly targets?: string[]; readonly commitMessage?: string; readonly gitTagVersion?: boolean; + readonly updatePackageJson?: boolean; readonly cwd?: string; readonly githubBranch?: string; readonly gitlabBranch?: string; @@ -50,7 +51,7 @@ export async function publish(options: IPublishOptions = {}): Promise { await _publish(packagePath, vsix.manifest, { ...options, target }); } } else { - await versionBump(options.cwd, options.version, options.commitMessage, options.gitTagVersion); + await versionBump(options); if (options.targets) { for (const target of options.targets) { diff --git a/src/test/package.test.ts b/src/test/package.test.ts index fc67073f..8511a1f8 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -1774,6 +1774,46 @@ describe('ManifestProcessor', () => { const outPackageJson = await processor.onFile(packageJson); assert.ok(outPackageJson.mode & 0o200); }); + + it('should bump package.json version in-memory when using --no-update-package-json', async () => { + const root = fixture('uuid'); + + let manifest = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')); + assert.deepStrictEqual(manifest.version, '1.0.0'); + + const processor = new ManifestProcessor(manifest, { version: '1.1.1', updatePackageJson: false }); + const packageJson = { + path: 'extension/package.json', + localPath: path.join(root, 'package.json'), + }; + + manifest = JSON.parse(await read(await processor.onFile(packageJson))); + assert.deepStrictEqual(manifest.version, '1.1.1'); + assert.deepStrictEqual(processor.vsix.version, '1.1.1'); + + manifest = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')); + assert.deepStrictEqual(manifest.version, '1.0.0'); + }); + + it('should not bump package.json version in-memory when not using --no-update-package-json', async () => { + const root = fixture('uuid'); + + let manifest = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')); + assert.deepStrictEqual(manifest.version, '1.0.0'); + + const processor = new ManifestProcessor(manifest, { version: '1.1.1' }); + const packageJson = { + path: 'extension/package.json', + localPath: path.join(root, 'package.json'), + }; + + manifest = JSON.parse(await read(await processor.onFile(packageJson))); + assert.deepStrictEqual(manifest.version, '1.0.0'); + assert.deepStrictEqual(processor.vsix.version, '1.0.0'); + + manifest = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')); + assert.deepStrictEqual(manifest.version, '1.0.0'); + }); }); describe('MarkdownProcessor', () => { @@ -2547,7 +2587,7 @@ describe('version', () => { }); it('should bump patch version', async () => { - await versionBump(cwd, 'patch'); + await versionBump({ cwd, version: 'patch' }); const newManifest = await readManifest(cwd); @@ -2555,7 +2595,7 @@ describe('version', () => { }); it('should bump minor version', async () => { - await versionBump(cwd, 'minor'); + await versionBump({ cwd, version: 'minor' }); const newManifest = await readManifest(cwd); @@ -2563,7 +2603,7 @@ describe('version', () => { }); it('should bump major version', async () => { - await versionBump(cwd, 'major'); + await versionBump({ cwd, version: 'major' }); const newManifest = await readManifest(cwd); @@ -2571,7 +2611,7 @@ describe('version', () => { }); it('should set custom version', async () => { - await versionBump(cwd, '1.1.1'); + await versionBump({ cwd, version: '1.1.1' }); const newManifest = await readManifest(cwd); @@ -2579,16 +2619,16 @@ describe('version', () => { }); it('should fail with invalid version', async () => { - await assert.rejects(versionBump(cwd, 'a1.a.2')); - await assert.rejects(versionBump(cwd, 'prepatch')); - await assert.rejects(versionBump(cwd, 'preminor')); - await assert.rejects(versionBump(cwd, 'premajor')); - await assert.rejects(versionBump(cwd, 'prerelease')); - await assert.rejects(versionBump(cwd, 'from-git')); + await assert.rejects(versionBump({ cwd, version: 'a1.a.2' })); + await assert.rejects(versionBump({ cwd, version: 'prepatch' })); + await assert.rejects(versionBump({ cwd, version: 'preminor' })); + await assert.rejects(versionBump({ cwd, version: 'premajor' })); + await assert.rejects(versionBump({ cwd, version: 'prerelease' })); + await assert.rejects(versionBump({ cwd, version: 'from-git' })); }); it('should create git tag and commit', async () => { - await versionBump(cwd, '1.1.1'); + await versionBump({ cwd, version: '1.1.1' }); assert.strictEqual(git(['rev-parse', 'v1.1.1']).status, 0); assert.strictEqual(git(['rev-parse', 'HEAD']).status, 0); @@ -2596,15 +2636,21 @@ describe('version', () => { it('should use custom commit message', async () => { const commitMessage = 'test commit message'; - await versionBump(cwd, '1.1.1', commitMessage); + await versionBump({ cwd, version: '1.1.1', commitMessage }); assert.deepStrictEqual(git(['show', '-s', '--format=%B', 'HEAD']).stdout, `${commitMessage}\n\n`); }); it('should not create git tag and commit', async () => { - await versionBump(cwd, '1.1.1', undefined, false); + await versionBump({ cwd, version: '1.1.1', gitTagVersion: false }); assert.notDeepStrictEqual(git(['rev-parse', 'v1.1.1']).status, 0); assert.notDeepStrictEqual(git(['rev-parse', 'HEAD']).status, 0); }); + + it('should not write to package.json with --no-update-package-json', async () => { + await versionBump({ cwd, version: '1.1.1', updatePackageJson: false }); + const newManifest = await readManifest(cwd); + assert.strictEqual(newManifest.version, '1.0.0'); + }); });