Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"nx": "15.4.1",
"parse-version-string": "^1.0.1",
"prettier": "2.7.1",
"semver": "^7.5.4",
"ts-jest": "28.0.8",
"ts-node": "10.9.1",
"tslib": "^2.0.0",
Expand Down
5 changes: 5 additions & 0 deletions packages/plugin-tools/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
"factory": "./src/generators/config",
"schema": "./src/generators/config/schema.json",
"description": "Configure workspace scope."
},
"bump-packages": {
"factory": "./src/generators/bump-packages/generator",
"schema": "./src/generators/bump-packages/schema.json",
"description": "bump-packages generator"
}
}
}
1 change: 1 addition & 0 deletions packages/plugin-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"lint-staged": "^13.0.0",
"nativescript-theme-core": "~1.0.4",
"sass": "^1.35.0",
"semver": "^7.5.4",
"parse-version-string": "^1.0.1",
"prettier": "^2.7.0",
"pretty-data": "^0.40.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Tree, addProjectConfiguration } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import generator from './generator';

describe('bump-packages generator', () => {
let appTree: Tree;

beforeEach(() => {
appTree = createTreeWithEmptyWorkspace();
appTree.write('apps/app/package.json', JSON.stringify({ version: '1.0.0' }));
appTree.write('packages/lib/package.json', JSON.stringify({ version: '1.0.0' }));
appTree.write('packages/lib2/package.json', JSON.stringify({ version: '2.0.0' }));
addProjectConfiguration(appTree, 'app', {
root: 'apps/app',
projectType: 'application',
tags: ['tag1', 'tag2'],
});
addProjectConfiguration(appTree, 'lib', {
root: 'packages/lib',
projectType: 'library',
tags: ['tag2'],
});
addProjectConfiguration(appTree, 'lib2', {
root: 'packages/lib2',
projectType: 'library',
tags: ['tag1'],
});
});

it('should bump all by patch', async () => {
await generator(appTree, {
targetVersion: 'patch',
});
expect(JSON.parse(appTree.read('apps/app/package.json').toString()).version).toBe('1.0.1');
expect(JSON.parse(appTree.read('packages/lib/package.json').toString()).version).toBe('1.0.1');
expect(JSON.parse(appTree.read('packages/lib2/package.json').toString()).version).toBe('2.0.1');
});

it('should filter by type', async () => {
await generator(appTree, {
targetVersion: 'patch',
projectType: 'library',
});
expect(JSON.parse(appTree.read('apps/app/package.json').toString()).version).toBe('1.0.0');
expect(JSON.parse(appTree.read('packages/lib/package.json').toString()).version).toBe('1.0.1');
expect(JSON.parse(appTree.read('packages/lib2/package.json').toString()).version).toBe('2.0.1');
});
it('should filter by tag', async () => {
await generator(appTree, {
targetVersion: 'patch',
tags: 'tag2',
});
expect(JSON.parse(appTree.read('apps/app/package.json').toString()).version).toBe('1.0.1');
expect(JSON.parse(appTree.read('packages/lib/package.json').toString()).version).toBe('1.0.1');
expect(JSON.parse(appTree.read('packages/lib2/package.json').toString()).version).toBe('2.0.0');
});

it('should fail to set non-semver', async () => {
const gen = await generator(appTree, {
targetVersion: 'not-semver',
}).catch(() => 'failed');
expect(gen).toBe('failed');
});
it('should fail to set version lower than the existing version', async () => {
const gen = await generator(appTree, {
targetVersion: '1.0.1',
}).catch(() => 'failed');
expect(gen).toBe('failed');
});
});
72 changes: 72 additions & 0 deletions packages/plugin-tools/src/generators/bump-packages/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { ProjectConfiguration, Tree, formatFiles, getProjects, logger } from '@nrwl/devkit';
import * as semver from 'semver';
import { BumpPackagesGeneratorSchema } from './schema';

interface NormalizedSchema extends BumpPackagesGeneratorSchema {
projects: ProjectConfiguration[];
versionBump: semver.ReleaseType | false;
fixedVersion: string;
}

function isVersionBump(version: string): version is semver.ReleaseType {
return ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].includes(version);
}

function normalizeOptions(tree: Tree, options: BumpPackagesGeneratorSchema): NormalizedSchema {
const filters = {
projectType: options.projectType ?? '',
tags: options.tags?.split(',').map((s) => s.trim()),
};
console.log(filters);
const projects = options.projectName
? [getProjects(tree).get(options.projectName)]
: Array.from(getProjects(tree).values()).filter((v) => {
if (filters.projectType) {
if (v.projectType !== filters.projectType) {
return false;
}
}
if (filters.tags) {
if (!v.tags.some((t) => filters.tags.includes(t))) {
return false;
}
}
return true;
});

const versionBump = isVersionBump(options.targetVersion) ? options.targetVersion : false;
if (!versionBump) {
if (!semver.parse(options.targetVersion)) {
throw new Error(`Invalid version ${options.targetVersion}`);
}
}

return {
...options,
projects,
versionBump,
fixedVersion: versionBump ? '' : options.targetVersion,
};
}

export default async function (tree: Tree, options: BumpPackagesGeneratorSchema) {
const normalizedOptions = normalizeOptions(tree, options);
normalizedOptions.projects.forEach((project) => {
const packageJson = tree.read(`${project.root}/package.json`);
if (!packageJson) {
throw new Error(`Could not find package.json for project ${project.name}`);
}
const parsedPackageJson = JSON.parse(packageJson.toString());
const oldVersion = parsedPackageJson.version;
const newVersion = normalizedOptions.versionBump ? semver.inc(parsedPackageJson.version, normalizedOptions.versionBump) : normalizedOptions.fixedVersion;
if (!newVersion) {
throw new Error(`Could not bump version for project ${project.name}`);
}
if (semver.gte(oldVersion, newVersion)) {
throw new Error(`New version (${newVersion}) is not greater than old version (${oldVersion}) for project ${project.name}, Skipping project`);
}
parsedPackageJson.version = newVersion;
tree.write(`${project.root}/package.json`, JSON.stringify(parsedPackageJson, null, 2));
});
await formatFiles(tree);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface BumpPackagesGeneratorSchema {
targetVersion: string;
projectName?: string;
tags?: string;
projectType?: string;
}
44 changes: 44 additions & 0 deletions packages/plugin-tools/src/generators/bump-packages/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "BumpPackages",
"title": "",
"type": "object",
"properties": {
"targetVersion": {
"x-prompt": "What's the new version (patch, minor, major) or explicit version number?.",
"type": "string",
"description": "Desired version to bump (patch, minor, major), or explicit version number (must comply with semver)",
"default": "patch",
"$default": {
"$source": "argv",
"index": 0
},
"anyOf": [
{
"enum": ["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"]
},
{
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
}
],
"x-priority": "important"
},
"projectName": {
"description": "Project to bump. If unspecified all projects are bumped",
"type": "string",
"x-dropdown": "projects"
},
"tags": {
"type": "string",
"description": "Filter projects by tags (comma separated)",
"alias": "t"
},
"projectType": {
"type": "string",
"enum": ["application", "library"],
"default": "library"
}
},
"required": ["targetVersion"]
}
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5902,6 +5902,13 @@ semver@^6.0.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==

semver@^7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"

send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
Expand Down