Skip to content

Commit

Permalink
fix: share project data when nesting commands (#3709)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesHenry committed Jun 5, 2023
1 parent fd57e02 commit 53e71e4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 13 deletions.
9 changes: 8 additions & 1 deletion libs/commands/publish/src/index.ts
Expand Up @@ -262,7 +262,14 @@ class PublishCommand extends Command {
} else if (this.options.canary) {
result = await this.detectCanaryVersions();
} else {
result = await versionCommand(this.argv);
/**
* Due to lerna publish's legacy of being backwards compatible with running versioning and publishing
* in a single step, we need to be able to pass down the existing project data to the nested version command.
*/
result = await versionCommand(this.argv, {
projectFileMap: this.projectFileMap,
projectGraph: this.projectGraph,
});
}

if (!result) {
Expand Down
29 changes: 21 additions & 8 deletions libs/commands/version/src/index.ts
@@ -1,23 +1,24 @@
import {
Command,
CommandConfigOptions,
Package,
PreInitializedProjectData,
ProjectGraphProjectNodeWithPackage,
ValidationError,
applyBuildMetadata,
checkWorkingTree,
collectProjects,
collectProjectUpdates,
Command,
CommandConfigOptions,
collectProjects,
createRunner,
getPackage,
getPackagesForOption,
output,
Package,
prereleaseIdFromVersion,
ProjectGraphProjectNodeWithPackage,
promptConfirmation,
recommendVersion,
runProjectsTopologically,
throwIfUncommitted,
updateChangelog,
ValidationError,
} from "@lerna/core";
import chalk from "chalk";
import dedent from "dedent";
Expand Down Expand Up @@ -46,8 +47,11 @@ import { updateLockfileVersion } from "./lib/update-lockfile-version";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const childProcess = require("@lerna/child-process");

module.exports = function factory(argv: NodeJS.Process["argv"]) {
return new VersionCommand(argv);
module.exports = function factory(
argv: NodeJS.Process["argv"],
preInitializedProjectData?: PreInitializedProjectData
) {
return new VersionCommand(argv, preInitializedProjectData);
};

interface VersionCommandConfigOptions extends CommandConfigOptions {
Expand Down Expand Up @@ -128,6 +132,15 @@ class VersionCommand extends Command {
);
}

/**
* Due to lerna publish's legacy of being backwards compatible with running versioning and publishing
* in a single step, we need to be able to receive any project data which might already exist from the
* publish command (in the case that it invokes the version command from within its implementation details).
*/
constructor(argv: NodeJS.Process["argv"], preInitializedProjectData?: PreInitializedProjectData) {
super(argv, { skipValidations: false, preInitializedProjectData });
}

configureProperties() {
super.configureProperties();

Expand Down
2 changes: 1 addition & 1 deletion libs/core/src/index.ts
Expand Up @@ -8,7 +8,7 @@ export {
ProjectCollectorOptions,
ProjectUpdateCollectorOptions,
} from "./lib/collect-updates";
export { Command } from "./lib/command";
export { Command, PreInitializedProjectData } from "./lib/command";
export { isGitInitialized } from "./lib/command/is-git-initialized";
export { applyBuildMetadata, recommendVersion, updateChangelog } from "./lib/conventional-commits";
export { describeRef, describeRefSync } from "./lib/describe-ref";
Expand Down
30 changes: 28 additions & 2 deletions libs/core/src/lib/command/index.ts
Expand Up @@ -18,6 +18,11 @@ import { warnIfHanging } from "./warn-if-hanging";

const DEFAULT_CONCURRENCY = os.cpus().length;

export interface PreInitializedProjectData {
projectFileMap: ProjectFileMap;
projectGraph: ProjectGraphWithPackages;
}

export class Command<T extends CommandConfigOptions = CommandConfigOptions> {
name: string;
composed: boolean;
Expand All @@ -44,7 +49,16 @@ export class Command<T extends CommandConfigOptions = CommandConfigOptions> {
this._project = project;
}

constructor(_argv: any, { skipValidations } = { skipValidations: false }) {
constructor(
_argv: any,
{
skipValidations,
preInitializedProjectData,
}: {
skipValidations: boolean;
preInitializedProjectData?: PreInitializedProjectData;
} = { skipValidations: false }
) {
log.pause();
log.heading = "lerna";

Expand Down Expand Up @@ -84,7 +98,19 @@ export class Command<T extends CommandConfigOptions = CommandConfigOptions> {
if (!skipValidations) {
chain = chain.then(() => this.runValidations());
}
chain = chain.then(() => this.detectProjects());
chain = chain.then(() => {
/**
* Due to lerna publish's legacy of being backwards compatible with running versioning and publishing
* in a single step, we need to be able to receive any project data which might already exist from the
* publish command (in the case that it invokes the version command from within its implementation details).
*/
if (preInitializedProjectData) {
this.projectFileMap = preInitializedProjectData.projectFileMap;
this.projectGraph = preInitializedProjectData.projectGraph;
return;
}
return this.detectProjects();
});
chain = chain.then(() => this.runPreparations());
chain = chain.then(() => this.runCommand());

Expand Down
Expand Up @@ -21,7 +21,7 @@ describe("createGitHubClient", () => {
it("errors if no GH_TOKEN env var", () => {
expect(() => {
createGitHubClient();
}).toThrow("A GH_TOKEN environment variable is required.");
}).toThrow(`A GH_TOKEN environment variable is required when "createRelease" is set to "github"`);
});

it("doesnt error if GH_TOKEN env var is set", () => {
Expand Down

0 comments on commit 53e71e4

Please sign in to comment.