diff --git a/package-lock.json b/package-lock.json index fc8afc3c0..02349b0b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "@conventional-commits/parser": "^0.4.1", "@google-automations/git-file-utils": "^1.2.5", "@iarna/toml": "^3.0.0", - "@lerna-lite/core": "1.17.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", @@ -3657,20 +3656,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -7970,8 +7955,7 @@ } }, "@lerna-lite/core": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@lerna-lite/core/-/core-1.17.0.tgz", + "version": "https://registry.npmjs.org/@lerna-lite/core/-/core-1.17.0.tgz", "integrity": "sha512-lxiEHXOzDF8RYFWjc8IqIr6G4w0JUB174SJD/h2DI/eXN9wjv8tEZjzhOkTTSs45Aoe1qY7BbaeApEulpoYmcA==", "requires": { "@npmcli/run-script": "^6.0.0", @@ -10354,13 +10338,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", diff --git a/package.json b/package.json index 10e86ade5..92de356df 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "@conventional-commits/parser": "^0.4.1", "@google-automations/git-file-utils": "^1.2.5", "@iarna/toml": "^3.0.0", - "@lerna-lite/core": "1.17.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", diff --git a/src/plugins/node-workspace.ts b/src/plugins/node-workspace.ts index 1e12698b0..5eab29efc 100644 --- a/src/plugins/node-workspace.ts +++ b/src/plugins/node-workspace.ts @@ -12,20 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {PackageGraph} from '@lerna-lite/core'; -import { - Package as LernaPackage, - RawManifest as PackageJson, -} from '@lerna-lite/core'; import {GitHub} from '../github'; import {CandidateReleasePullRequest, RepositoryConfig} from '../manifest'; import {Version, VersionsMap} from '../version'; -import {RawContent} from '../updaters/raw-content'; import {PullRequestTitle} from '../util/pull-request-title'; import {PullRequestBody} from '../util/pull-request-body'; import {ReleasePullRequest} from '../release-pull-request'; import {BranchName} from '../util/branch-name'; -import {jsonStringify} from '../util/json-stringify'; import {Changelog} from '../updaters/changelog'; import { WorkspacePlugin, @@ -36,23 +29,28 @@ import { addPath, } from './workspace'; import {PatchVersionUpdate} from '../versioning-strategy'; +import {CompositeUpdater} from '../updaters/composite'; +import {PackageJson, newVersionWithRange} from '../updaters/node/package-json'; +import {Logger} from '../util/logger'; -class Package extends LernaPackage { - constructor( - public readonly rawContent: string, - location: string, - pkg?: PackageJson - ) { - super(pkg ?? JSON.parse(rawContent), location); - } +interface ParsedPackageJson { + name: string; + version: string; + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; + optionalDependencies?: Record; +} - clone() { - return new Package( - this.rawContent, - this.location, - this.toJSON() as PackageJson - ); - } +interface Package { + path: string; + name: string; + version: string; + dependencies: Record; + devDependencies: Record; + peerDependencies: Record; + optionalDependencies: Record; + jsonContent: string; } interface NodeWorkspaceOptions extends WorkspacePluginOptions { @@ -68,7 +66,6 @@ interface NodeWorkspaceOptions extends WorkspacePluginOptions { */ export class NodeWorkspace extends WorkspacePlugin { private alwaysLinkLocal: boolean; - private packageGraph?: PackageGraph; constructor( github: GitHub, targetBranch: string, @@ -105,22 +102,28 @@ export class NodeWorkspace extends WorkspacePlugin { const packageUpdate = candidate.pullRequest.updates.find( update => update.path === packagePath ); - if (packageUpdate?.cachedFileContents) { - const pkg = new Package( - packageUpdate.cachedFileContents.parsedContent, - candidate.path - ); - packagesByPath.set(candidate.path, pkg); - candidatesByPackage[pkg.name] = candidate; - } else { - const contents = await this.github.getFileContentsOnBranch( + const contents = + packageUpdate?.cachedFileContents ?? + (await this.github.getFileContentsOnBranch( packagePath, this.targetBranch - ); - const pkg = new Package(contents.parsedContent, candidate.path); - packagesByPath.set(candidate.path, pkg); - candidatesByPackage[pkg.name] = candidate; - } + )); + const packageJson: ParsedPackageJson = JSON.parse( + contents.parsedContent + ); + const pkg: Package = { + name: packageJson.name, + path, + version: packageJson.version, + dependencies: packageJson.dependencies || {}, + devDependencies: packageJson.devDependencies || {}, + peerDependencies: packageJson.peerDependencies || {}, + optionalDependencies: packageJson.optionalDependencies || {}, + jsonContent: contents.parsedContent, + }; + packagesByPath.set(candidate.path, pkg); + candidatesByPackage[pkg.name] = candidate; + // } } else { const packagePath = addPath(path, 'package.json'); this.logger.debug( @@ -130,16 +133,23 @@ export class NodeWorkspace extends WorkspacePlugin { packagePath, this.targetBranch ); - packagesByPath.set(path, new Package(contents.parsedContent, path)); + const packageJson: ParsedPackageJson = JSON.parse( + contents.parsedContent + ); + const pkg: Package = { + name: packageJson.name, + path, + version: packageJson.version, + dependencies: packageJson.dependencies || {}, + devDependencies: packageJson.devDependencies || {}, + peerDependencies: packageJson.peerDependencies || {}, + optionalDependencies: packageJson.optionalDependencies || {}, + jsonContent: contents.parsedContent, + }; + packagesByPath.set(path, pkg); } } const allPackages = Array.from(packagesByPath.values()); - this.packageGraph = new PackageGraph( - allPackages, - 'allDependencies', - this.alwaysLinkLocal - ); - return { allPackages, candidatesByPackage, @@ -156,46 +166,31 @@ export class NodeWorkspace extends WorkspacePlugin { pkg: Package, updatedVersions: VersionsMap ): CandidateReleasePullRequest { - const graphPackage = this.packageGraph?.get(pkg.name); - if (!graphPackage) { - throw new Error(`Could not find graph package for ${pkg.name}`); - } - const updatedPackage = pkg.clone(); // Update version of the package - const newVersion = updatedVersions.get(updatedPackage.name); - if (newVersion) { - this.logger.info(`Updating ${updatedPackage.name} to ${newVersion}`); - updatedPackage.version = newVersion.toString(); - } - // Update dependency versions - for (const [depName, resolved] of graphPackage.localDependencies) { - const depVersion = updatedVersions.get(depName); - if (depVersion && resolved.type !== 'directory') { - const currentVersion = this.combineDeps(pkg)?.[depName]; - const prefix = currentVersion - ? this.detectRangePrefix(currentVersion) - : ''; - updatedPackage.updateLocalDependency( - resolved, - depVersion.toString(), - prefix - ); - this.logger.info( - `${pkg.name}.${depName} updated to ${prefix}${depVersion.toString()}` - ); - } + const newVersion = updatedVersions.get(pkg.name); + if (!newVersion) { + throw new Error(`Didn't find updated version for ${pkg.name}`); } + const updatedPackage = { + ...pkg, + version: newVersion.toString(), + }; + + const updater = new PackageJson({ + version: newVersion, + versionsMap: updatedVersions, + }); const dependencyNotes = getChangelogDepsNotes( pkg, updatedPackage, - updatedVersions + updatedVersions, + this.logger ); + existingCandidate.pullRequest.updates = existingCandidate.pullRequest.updates.map(update => { if (update.path === addPath(existingCandidate.path, 'package.json')) { - update.updater = new RawContent( - jsonStringify(updatedPackage.toJSON(), updatedPackage.rawContent) - ); + update.updater = new CompositeUpdater(update.updater, updater); } else if (update.updater instanceof Changelog) { if (dependencyNotes) { update.updater.changelogEntry = @@ -236,47 +231,28 @@ export class NodeWorkspace extends WorkspacePlugin { pkg: Package, updatedVersions: VersionsMap ): CandidateReleasePullRequest { - const graphPackage = this.packageGraph?.get(pkg.name); - if (!graphPackage) { - throw new Error(`Could not find graph package for ${pkg.name}`); - } - const updatedPackage = pkg.clone(); // Update version of the package - const newVersion = updatedVersions.get(updatedPackage.name); - if (newVersion) { - this.logger.info(`Updating ${updatedPackage.name} to ${newVersion}`); - updatedPackage.version = newVersion.toString(); - } - for (const [depName, resolved] of graphPackage.localDependencies) { - const depVersion = updatedVersions.get(depName); - if (depVersion && resolved.type !== 'directory') { - const currentVersion = this.combineDeps(pkg)?.[depName]; - const prefix = currentVersion - ? this.detectRangePrefix(currentVersion) - : ''; - updatedPackage.updateLocalDependency( - resolved, - depVersion.toString(), - prefix - ); - this.logger.info( - `${pkg.name}.${depName} updated to ${prefix}${depVersion.toString()}` - ); - } + const newVersion = updatedVersions.get(pkg.name); + if (!newVersion) { + throw new Error(`Didn't find updated version for ${pkg.name}`); } + const updatedPackage = { + ...pkg, + version: newVersion.toString(), + }; + const dependencyNotes = getChangelogDepsNotes( pkg, updatedPackage, - updatedVersions + updatedVersions, + this.logger ); - const packageJson = updatedPackage.toJSON() as PackageJson; - const version = Version.parse(packageJson.version); const pullRequest: ReleasePullRequest = { title: PullRequestTitle.ofTargetBranch(this.targetBranch), body: new PullRequestBody([ { component: updatedPackage.name, - version, + version: newVersion, notes: appendDependenciesSectionToChangelog( '', dependencyNotes, @@ -286,17 +262,18 @@ export class NodeWorkspace extends WorkspacePlugin { ]), updates: [ { - path: addPath(updatedPackage.location, 'package.json'), + path: addPath(updatedPackage.path, 'package.json'), createIfMissing: false, - updater: new RawContent( - jsonStringify(packageJson, updatedPackage.rawContent) - ), + updater: new PackageJson({ + version: newVersion, + versionsMap: updatedVersions, + }), }, { - path: addPath(updatedPackage.location, 'CHANGELOG.md'), + path: addPath(updatedPackage.path, 'CHANGELOG.md'), createIfMissing: false, updater: new Changelog({ - version, + version: newVersion, changelogEntry: appendDependenciesSectionToChangelog( '', dependencyNotes, @@ -307,11 +284,11 @@ export class NodeWorkspace extends WorkspacePlugin { ], labels: [], headRefName: BranchName.ofTargetBranch(this.targetBranch).toString(), - version, + version: newVersion, draft: false, }; return { - path: updatedPackage.location, + path: updatedPackage.path, pullRequest, config: { releaseType: 'node', @@ -357,15 +334,7 @@ export class NodeWorkspace extends WorkspacePlugin { } protected pathFromPackage(pkg: Package): string { - return pkg.location; - } - - private detectRangePrefix(version: string): string { - return ( - Object.values(SUPPORTED_RANGE_PREFIXES).find(supportedRangePrefix => - version.startsWith(supportedRangePrefix) - ) || '' - ); + return pkg.path; } private combineDeps(packageJson: Package): Record { @@ -377,19 +346,11 @@ export class NodeWorkspace extends WorkspacePlugin { } } -enum SUPPORTED_RANGE_PREFIXES { - CARET = '^', - TILDE = '~', - GREATER_THAN = '>', - LESS_THAN = '<', - EQUAL_OR_GREATER_THAN = '>=', - EQUAL_OR_LESS_THAN = '<=', -} - function getChangelogDepsNotes( original: Package, updated: Package, - updateVersions: VersionsMap + updateVersions: VersionsMap, + logger: Logger ): string { let depUpdateNotes = ''; type DT = @@ -411,21 +372,20 @@ function getChangelogDepsNotes( continue; } for (const [depName, currentDepVer] of Object.entries(pkgDepTypes)) { + const newVersion = updateVersions.get(depName); + if (!newVersion) { + logger.debug(`${depName} was not bumped, ignoring`); + continue; + } const origDepVer = original[depType]?.[depName]; - if (currentDepVer !== origDepVer) { + const newVersionString = newVersionWithRange(origDepVer, newVersion); + if (currentDepVer.startsWith('workspace:')) { + depUpdates.push(`\n * ${depName} bumped to ${newVersionString}`); + } else if (newVersionString !== origDepVer) { depUpdates.push( - `\n * ${depName} bumped from ${origDepVer} to ${currentDepVer}` + `\n * ${depName} bumped from ${origDepVer} to ${newVersionString}` ); //handle case when "workspace:" version is used - } else if ( - currentDepVer.startsWith('workspace:') && - updateVersions.get(depName) !== undefined - ) { - depUpdates.push( - `\n * ${depName} bumped to ${updateVersions - .get(depName) - ?.toString()}` - ); } } if (depUpdates.length > 0) { diff --git a/src/plugins/workspace.ts b/src/plugins/workspace.ts index 8f5b2b9c5..b703b4770 100644 --- a/src/plugins/workspace.ts +++ b/src/plugins/workspace.ts @@ -130,7 +130,7 @@ export abstract class WorkspacePlugin extends ManifestPlugin { if (existingCandidate) { // if already has an pull request, update the changelog and update this.logger.info( - `Updating exising candidate pull request for ${this.packageNameFromPackage( + `Updating existing candidate pull request for ${this.packageNameFromPackage( pkg )}, path: ${existingCandidate.path}` );