Skip to content

Commit

Permalink
Allow specifying tasks. (#3002)
Browse files Browse the repository at this point in the history
`turbo-ignore` by default specifies `build` as the task it will run. This makes it possible to specify an alternative task name as the entry point.

This enables `npx turbo-ignore --task="workspace#build"`, for example.
  • Loading branch information
nathanhammond committed Dec 18, 2022
1 parent 97baee4 commit d3c4c6f
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 6 deletions.
43 changes: 42 additions & 1 deletion packages/turbo-ignore/__tests__/args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe("parseArgs()", () => {
const result = parseArgs({ argv: [] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
});

it("outputs help text (--help)", async () => {
Expand Down Expand Up @@ -40,29 +41,69 @@ describe("parseArgs()", () => {
const result = parseArgs({ argv: ["this-workspace"] });
expect(result.workspace).toBe("this-workspace");
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("correctly finds fallback", async () => {
const result = parseArgs({ argv: ["--fallback=HEAD^"] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe("HEAD^");
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("correctly finds task", async () => {
const result = parseArgs({ argv: ["--task=some-workspace#build"] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe("some-workspace#build");
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("uses default fallback if incorrectly specified", async () => {
const result = parseArgs({ argv: ["--fallback"] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("uses default fallback if empty string", async () => {
const result = parseArgs({ argv: ["--fallback="] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("uses default task if incorrectly specified", async () => {
const result = parseArgs({ argv: ["--task"] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("uses default task if empty string", async () => {
const result = parseArgs({ argv: ["--task="] });
expect(result.workspace).toBe(undefined);
expect(result.fallback).toBe(undefined);
expect(result.task).toBe(undefined);
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});

it("correctly finds fallback and workspace", async () => {
const result = parseArgs({
argv: ["this-workspace", "--fallback=HEAD~10"],
argv: [
"this-workspace",
"--fallback=HEAD~10",
"--task=some-workspace#build",
],
});
expect(result.workspace).toBe("this-workspace");
expect(result.fallback).toBe("HEAD~10");
expect(result.task).toBe("some-workspace#build");
expect(mockExit.exit).toHaveBeenCalledTimes(0);
});
});
25 changes: 25 additions & 0 deletions packages/turbo-ignore/__tests__/getTask.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { getTask } from "../src/getTask";
import { spyConsole, validateLogs } from "./test-utils";

describe("getWorkspace()", () => {
const mockConsole = spyConsole();
it("getTask defaults to build", async () => {
expect(getTask({})).toEqual("build");
validateLogs(
['using "build" as the task as it was unspecified'],
mockConsole.log
);
});

it("getTask returns a quoted task if user-supplied", async () => {
expect(
getTask({
task: "workspace#task",
})
).toEqual(`"workspace#task"`);
validateLogs(
['using "workspace#task" as the task from the arguments'],
mockConsole.log
);
});
});
12 changes: 10 additions & 2 deletions packages/turbo-ignore/__tests__/ignore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ describe("turboIgnore()", () => {
},
});
expect(mockConsole.log).toHaveBeenNthCalledWith(
3,
4,
"≫ ",
'no previous deployments found for "test-app" on branch "my-branch".'
);
Expand Down Expand Up @@ -268,6 +268,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
`found previous deployment ("last-deployed-sha") for \"test-app\" on branch \"my-branch\"`,
"analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`",
"this project and its dependencies are not affected",
Expand Down Expand Up @@ -298,15 +299,17 @@ describe("turboIgnore()", () => {
});
turboIgnore({
args: {
task: "workspace#build",
directory: "__fixtures__/app",
},
});
validateLogs(
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "workspace#build" as the task from the arguments',
'found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"',
"analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`",
'analyzing results of `npx turbo run "workspace#build" --filter=test-app...[last-deployed-sha] --dry=json`',
'this commit affects "test-app"',
() => expect.stringContaining("✅ proceeding with deployment"),
],
Expand Down Expand Up @@ -342,6 +345,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
'found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"',
"analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`",
'this commit affects "test-app" and 1 dependency (ui)',
Expand Down Expand Up @@ -379,6 +383,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
'found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"',
"analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`",
'this commit affects "test-app" and 2 dependencies (ui, tsconfig)',
Expand Down Expand Up @@ -473,6 +478,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
"found commit message: [vercel skip]",
() => expect.stringContaining("⬜️ ignoring the change"),
],
Expand All @@ -496,6 +502,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
"found commit message: [vercel deploy]",
() => expect.stringContaining("✅ proceeding with deployment"),
],
Expand Down Expand Up @@ -534,6 +541,7 @@ describe("turboIgnore()", () => {
[
"Using Turborepo to determine if this project is affected by the commit...\n",
'inferred "test-app" as workspace from "package.json"',
'using "build" as the task as it was unspecified',
"conflicting commit messages found: [vercel deploy] and [vercel skip]",
`found previous deployment ("last-deployed-sha") for \"test-app\" on branch \"my-branch\"`,
"analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`",
Expand Down
12 changes: 10 additions & 2 deletions packages/turbo-ignore/src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,17 @@ export default function parseArgs({
args.workspace = argv[0];
}

// set task (if provided)
const taskArgSentinel = "--task=";
const taskArg = argv.find((arg) => arg.startsWith(taskArgSentinel));
if (taskArg && taskArg.length > taskArgSentinel.length) {
args.task = taskArg.split("=")[1];
}

// set fallback (if provided)
const fallbackArg = argv.find((arg) => arg.startsWith("--fallback="));
if (fallbackArg) {
const fallbackSentinel = "--fallback=";
const fallbackArg = argv.find((arg) => arg.startsWith(fallbackSentinel));
if (fallbackArg && fallbackArg.length > fallbackSentinel.length) {
args.fallback = fallbackArg.split("=")[1];
}

Expand Down
13 changes: 13 additions & 0 deletions packages/turbo-ignore/src/getTask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { info } from "./logger";
import { TurboIgnoreArgs } from "./types";

export function getTask(args: TurboIgnoreArgs): string | null {
if (args.task) {
info(`using "${args.task}" as the task from the arguments`);
return `"${args.task}"`;
}

info('using "build" as the task as it was unspecified');

return "build";
}
6 changes: 5 additions & 1 deletion packages/turbo-ignore/src/ignore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { exec } from "child_process";
import path from "path";
import { getTurboRoot } from "turbo-utils";
import { getComparison } from "./getComparison";
import { getTask } from "./getTask";
import { getWorkspace } from "./getWorkspace";
import { info, warn, error } from "./logger";
import { shouldWarn } from "./errors";
Expand Down Expand Up @@ -50,6 +51,9 @@ export default function turboIgnore({ args }: { args: TurboIgnoreArgs }) {
return continueBuild();
}

// Identify which task to execute from the command-line args
let task = getTask(args);

// check the commit message
const parsedCommit = checkCommit({ workspace });
if (parsedCommit.result === "skip") {
Expand All @@ -72,7 +76,7 @@ export default function turboIgnore({ args }: { args: TurboIgnoreArgs }) {
}

// Build, and execute the command
const command = `npx turbo run build --filter=${workspace}...[${comparison.ref}] --dry=json`;
const command = `npx turbo run ${task} --filter=${workspace}...[${comparison.ref}] --dry=json`;
info(`analyzing results of \`${command}\``);
exec(
command,
Expand Down
2 changes: 2 additions & 0 deletions packages/turbo-ignore/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export interface TurboIgnoreArgs {
directory?: string;
// the workspace to check for changes
workspace?: string;
// the task to run, if not build
task?: string;
// A ref/head to compare against if no previously deployed SHA is available
fallback?: string;
}

0 comments on commit d3c4c6f

Please sign in to comment.