Skip to content

Commit d3a18fb

Browse files
nicktrnKritik-Jmatt-aitken
authored
v3: cli and misc fixes for windows (#1027)
* fix: otlp-importer script * update pluginPath * Refactor script to ensure compatibility with both Windows and Unix platforms * Revert command changes * Fix: Init command was failing on Windows because of bad template paths * Removed resolveInternalFilePath * Path fixes for the dev command * Fix for the import paths being wrong on Windows because the contain backslashes * The metaOutputKey should have forward slashes in it * Print the banner immediately, otherwise with bad internet you get a blank console for a long time * Try normalizing the trigger.config import path * Allow tsx and jsx files * Improved task file names and paths * Removed closing bracket for the upgrade message * Log out the metafile outputs for debugging * Log out the entryPointContents before esbuild * Log the metafile out * ballmerize the cli * replace npm-watch with plain old nodemon * fix text inputs on windows * changeset --------- Co-authored-by: Kritik Jiyaviya <kritikjiyaviya07@gmail.com> Co-authored-by: Matt Aitken <matt@mattaitken.com>
1 parent b82a07a commit d3a18fb

23 files changed

+194
-127
lines changed

.changeset/silly-suits-switch.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@trigger.dev/otlp-importer": patch
3+
"trigger.dev": patch
4+
---
5+
6+
Fix package builds and CLI commands on Windows

.changeset/tidy-balloons-suffer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Init command was failing on Windows because of bad template paths

packages/cli-v3/package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
"@types/semver": "^7.3.13",
4646
"@types/ws": "^8.5.3",
4747
"cpy-cli": "^5.0.0",
48+
"nodemon": "^3.0.1",
4849
"npm-run-all": "^4.1.5",
49-
"npm-watch": "^0.11.0",
5050
"open": "^10.0.3",
5151
"p-retry": "^6.1.0",
5252
"rimraf": "^3.0.2",
@@ -56,9 +56,6 @@
5656
"vitest": "^0.34.4",
5757
"xdg-app-paths": "^8.3.0"
5858
},
59-
"watch": {
60-
"build:prod-containerfile": "src/Containerfile.prod"
61-
},
6259
"scripts": {
6360
"typecheck": "tsc -p tsconfig.check.json",
6461
"build": "npm run clean && run-p build:**",
@@ -68,7 +65,7 @@
6865
"dev": "npm run clean && run-p dev:**",
6966
"dev:main": "tsup --watch",
7067
"dev:workers": "tsup --config tsup.workers.config.ts --watch",
71-
"dev:prod-containerfile": "npm-watch",
68+
"dev:test": "nodemon -w src/Containerfile.prod -x npm run build:prod-containerfile",
7269
"clean": "rimraf dist",
7370
"start": "node dist/index.js",
7471
"test": "vitest"

packages/cli-v3/src/commands/deploy.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { intro, log, outro, spinner } from "@clack/prompts";
1+
import { intro, log, outro } from "@clack/prompts";
22
import { depot } from "@depot/cli";
33
import { context, trace } from "@opentelemetry/api";
44
import {
@@ -12,11 +12,10 @@ import chalk from "chalk";
1212
import { Command, Option as CommandOption } from "commander";
1313
import { Metafile, build } from "esbuild";
1414
import { execa } from "execa";
15-
import { resolve as importResolve } from "import-meta-resolve";
1615
import { createHash } from "node:crypto";
1716
import { readFileSync } from "node:fs";
1817
import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
19-
import { dirname, join, relative } from "node:path";
18+
import { dirname, join, relative, posix } from "node:path";
2019
import { setTimeout } from "node:timers/promises";
2120
import terminalLink from "terminal-link";
2221
import invariant from "tiny-invariant";
@@ -56,6 +55,8 @@ import {
5655
} from "../utilities/deployErrors";
5756
import { safeJsonParse } from "../utilities/safeJsonParse";
5857
import { JavascriptProject } from "../utilities/javascriptProject";
58+
import { cliRootPath } from "../utilities/resolveInternalFilePath";
59+
import { escapeImportPath, spinner } from "../utilities/windows";
5960

6061
const DeployCommandOptions = CommonCommandOptions.extend({
6162
skipTypecheck: z.boolean().default(false),
@@ -939,27 +940,27 @@ async function compileProject(
939940

940941
const taskFiles = await gatherTaskFiles(config);
941942
const workerFacade = readFileSync(
942-
new URL(importResolve("./workers/prod/worker-facade.js", import.meta.url)).href.replace(
943-
"file://",
944-
""
945-
),
943+
join(cliRootPath(), "workers", "prod", "worker-facade.js"),
946944
"utf-8"
947945
);
948946

949-
const workerSetupPath = new URL(
950-
importResolve("./workers/prod/worker-setup.js", import.meta.url)
951-
).href.replace("file://", "");
947+
const workerSetupPath = join(cliRootPath(), "workers", "dev", "worker-setup.js");
952948

953949
let workerContents = workerFacade
954950
.replace("__TASKS__", createTaskFileImports(taskFiles))
955-
.replace("__WORKER_SETUP__", `import { tracingSDK } from "${workerSetupPath}";`);
951+
.replace(
952+
"__WORKER_SETUP__",
953+
`import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
954+
);
956955

957956
if (configPath) {
958957
logger.debug("Importing project config from", { configPath });
959958

960959
workerContents = workerContents.replace(
961960
"__IMPORTED_PROJECT_CONFIG__",
962-
`import * as importedConfigExports from "${configPath}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
961+
`import * as importedConfigExports from "${escapeImportPath(
962+
configPath
963+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
963964
);
964965
} else {
965966
workerContents = workerContents.replace(
@@ -1015,10 +1016,7 @@ async function compileProject(
10151016
}
10161017

10171018
const entryPointContents = readFileSync(
1018-
new URL(importResolve("./workers/prod/entry-point.js", import.meta.url)).href.replace(
1019-
"file://",
1020-
""
1021-
),
1019+
join(cliRootPath(), "workers", "prod", "entry-point.js"),
10221020
"utf-8"
10231021
);
10241022

@@ -1076,12 +1074,13 @@ async function compileProject(
10761074
logger.debug(`Writing compiled files to ${tempDir}`);
10771075

10781076
// Get the metaOutput for the result build
1079-
const metaOutput = result.metafile!.outputs[join("out", "stdin.js")];
1077+
const metaOutput = result.metafile!.outputs[posix.join("out", "stdin.js")];
10801078

10811079
invariant(metaOutput, "Meta output for the result build is missing");
10821080

10831081
// Get the metaOutput for the entryPoint build
1084-
const entryPointMetaOutput = entryPointResult.metafile!.outputs[join("out", "stdin.js")];
1082+
const entryPointMetaOutput =
1083+
entryPointResult.metafile!.outputs[posix.join("out", "stdin.js")];
10851084

10861085
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
10871086

@@ -1156,9 +1155,7 @@ async function compileProject(
11561155
}
11571156

11581157
// Write the Containerfile to /tmp/dir/Containerfile
1159-
const containerFilePath = new URL(
1160-
importResolve("./Containerfile.prod", import.meta.url)
1161-
).href.replace("file://", "");
1158+
const containerFilePath = join(cliRootPath(), "Containerfile.prod");
11621159
// Copy the Containerfile to /tmp/dir/Containerfile
11631160
await copyFile(containerFilePath, join(tempDir, "Containerfile"));
11641161

packages/cli-v3/src/commands/dev.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ import {
1111
import { watch } from "chokidar";
1212
import { Command } from "commander";
1313
import { BuildContext, Metafile, context } from "esbuild";
14-
import { resolve as importResolve } from "import-meta-resolve";
1514
import { render, useInput } from "ink";
1615
import { createHash } from "node:crypto";
1716
import fs, { readFileSync } from "node:fs";
1817
import { ClientRequestArgs } from "node:http";
19-
import { basename, dirname, join } from "node:path";
18+
import { basename, dirname, join, normalize } from "node:path";
2019
import pDebounce from "p-debounce";
2120
import { WebSocket } from "partysocket";
2221
import React, { Suspense, useEffect } from "react";
@@ -52,6 +51,8 @@ import {
5251
parseNpmInstallError,
5352
} from "../utilities/deployErrors";
5453
import { findUp, pathExists } from "find-up";
54+
import { cliRootPath } from "../utilities/resolveInternalFilePath";
55+
import { escapeImportPath } from "../utilities/windows";
5556

5657
let apiClient: CliApiClient | undefined;
5758

@@ -338,28 +339,27 @@ function useDev({
338339

339340
const taskFiles = await gatherTaskFiles(config);
340341

341-
const workerFacade = readFileSync(
342-
new URL(importResolve("./workers/dev/worker-facade.js", import.meta.url)).href.replace(
343-
"file://",
344-
""
345-
),
346-
"utf-8"
347-
);
342+
const workerFacadePath = join(cliRootPath(), "workers", "dev", "worker-facade.js");
343+
const workerFacade = readFileSync(workerFacadePath, "utf-8");
348344

349-
const workerSetupPath = new URL(
350-
importResolve("./workers/dev/worker-setup.js", import.meta.url)
351-
).href.replace("file://", "");
345+
const workerSetupPath = join(cliRootPath(), "workers", "dev", "worker-setup.js");
352346

353347
let entryPointContents = workerFacade
354348
.replace("__TASKS__", createTaskFileImports(taskFiles))
355-
.replace("__WORKER_SETUP__", `import { tracingSDK, sender } from "${workerSetupPath}";`);
349+
.replace(
350+
"__WORKER_SETUP__",
351+
`import { tracingSDK, sender } from "${escapeImportPath(workerSetupPath)}";`
352+
);
356353

357354
if (configPath) {
355+
configPath = normalize(configPath);
358356
logger.debug("Importing project config from", { configPath });
359357

360358
entryPointContents = entryPointContents.replace(
361359
"__IMPORTED_PROJECT_CONFIG__",
362-
`import * as importedConfigExports from "${configPath}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
360+
`import * as importedConfigExports from "${escapeImportPath(
361+
configPath
362+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
363363
);
364364
} else {
365365
entryPointContents = entryPointContents.replace(
@@ -414,7 +414,11 @@ function useDev({
414414
logger.log(chalkGrey("○ Building background worker…"));
415415
}
416416

417-
const metaOutputKey = join("out", `stdin.js`);
417+
const metaOutputKey = join("out", `stdin.js`).replace(/\\/g, "/");
418+
419+
logger.debug("Metafile", {
420+
metafileOutputs: JSON.stringify(result.metafile?.outputs),
421+
});
418422

419423
const metaOutput = result.metafile!.outputs[metaOutputKey];
420424

packages/cli-v3/src/commands/init.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
1+
import { intro, isCancel, log, outro, select, text } from "@clack/prompts";
22
import { context, trace } from "@opentelemetry/api";
33
import {
44
GetProjectResponseBody,
@@ -30,8 +30,9 @@ import { createFile, pathExists, readFile } from "../utilities/fileSystem";
3030
import { getUserPackageManager } from "../utilities/getUserPackageManager";
3131
import { printStandloneInitialBanner } from "../utilities/initialBanner.js";
3232
import { logger } from "../utilities/logger";
33-
import { resolveInternalFilePath } from "../utilities/resolveInternalFilePath";
33+
import { cliRootPath } from "../utilities/resolveInternalFilePath";
3434
import { login } from "./login";
35+
import { spinner } from "../utilities/windows";
3536

3637
const InitCommandOptions = CommonCommandOptions.extend({
3738
projectRef: z.string().optional(),
@@ -185,7 +186,7 @@ async function _initCommand(dir: string, options: InitCommandOptions) {
185186
async function createTriggerDir(dir: string, options: InitCommandOptions) {
186187
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
187188
try {
188-
const defaultValue = `${dir}/src/trigger`;
189+
const defaultValue = join(dir, "src", "trigger");
189190

190191
const location = await text({
191192
message: "Where would you like to create the Trigger.dev directory?",
@@ -199,6 +200,8 @@ async function createTriggerDir(dir: string, options: InitCommandOptions) {
199200

200201
const triggerDir = resolve(process.cwd(), location);
201202

203+
logger.debug({ triggerDir });
204+
202205
span.setAttributes({
203206
"cli.triggerDir": triggerDir,
204207
});
@@ -239,11 +242,11 @@ async function createTriggerDir(dir: string, options: InitCommandOptions) {
239242
return { location, isCustomValue: location !== defaultValue };
240243
}
241244

242-
const exampleFile = resolveInternalFilePath(`./templates/examples/${example}.ts.template`);
245+
const templatePath = join(cliRootPath(), "templates", "examples", `${example}.ts.template`);
243246
const outputPath = join(triggerDir, "example.ts");
244247

245248
await createFileFromTemplate({
246-
templatePath: exampleFile,
249+
templatePath,
247250
outputPath,
248251
replacements: {},
249252
});
@@ -440,7 +443,7 @@ async function writeConfigFile(
440443
spnnr.start("Creating config file");
441444

442445
const projectDir = resolve(process.cwd(), dir);
443-
const templatePath = resolveInternalFilePath("./templates/trigger.config.ts.template");
446+
const templatePath = join(cliRootPath(), "templates", "trigger.config.ts.template");
444447
const outputPath = join(projectDir, "trigger.config.ts");
445448

446449
span.setAttributes({

packages/cli-v3/src/commands/login.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { intro, log, outro, select, spinner } from "@clack/prompts";
1+
import { intro, log, outro, select } from "@clack/prompts";
22
import { recordSpanException } from "@trigger.dev/core/v3";
33
import { Command } from "commander";
44
import open from "open";
@@ -20,6 +20,7 @@ import { printInitialBanner } from "../utilities/initialBanner.js";
2020
import { LoginResult } from "../utilities/session.js";
2121
import { whoAmI } from "./whoami.js";
2222
import { logger } from "../utilities/logger.js";
23+
import { spinner } from "../utilities/windows.js";
2324

2425
export const LoginCommandOptions = CommonCommandOptions.extend({
2526
apiUrl: z.string(),

packages/cli-v3/src/commands/update.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { confirm, spinner } from "@clack/prompts";
1+
import { confirm } from "@clack/prompts";
22
import { RunOptions, run } from "npm-check-updates";
33
import path from "path";
44
import { z } from "zod";
55
import { chalkError, chalkSuccess } from "../utilities/cliOutput.js";
66
import { readJSONFileSync, writeJSONFile } from "../utilities/fileSystem.js";
77
import { installDependencies } from "../utilities/installDependencies.js";
8+
import { spinner } from "../utilities/windows.js";
89

910
export const UpdateCommandOptionsSchema = z.object({
1011
to: z.string().optional(),

packages/cli-v3/src/commands/whoami.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { intro, note, spinner } from "@clack/prompts";
1+
import { intro, note } from "@clack/prompts";
22
import { chalkLink } from "../utilities/cliOutput.js";
33
import { logger } from "../utilities/logger.js";
44
import { isLoggedIn } from "../utilities/session.js";
@@ -12,6 +12,7 @@ import {
1212
} from "../cli/common.js";
1313
import { z } from "zod";
1414
import { CliApiClient } from "../apiClient.js";
15+
import { spinner } from "../utilities/windows.js";
1516

1617
type WhoAmIResult =
1718
| {

packages/cli-v3/src/utilities/build.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { readFileSync } from "node:fs";
44
import { extname, isAbsolute } from "node:path";
55
import tsConfigPaths from "tsconfig-paths";
66
import { logger } from "./logger";
7+
import { escapeImportPath } from "./windows";
78

89
export function bundleTriggerDevCore(buildIdentifier: string, tsconfigPath?: string): Plugin {
910
return {
@@ -56,7 +57,9 @@ export function workerSetupImportConfigPlugin(configPath?: string): Plugin {
5657

5758
workerSetupContents = workerSetupContents.replace(
5859
"__SETUP_IMPORTED_PROJECT_CONFIG__",
59-
`import * as setupImportedConfigExports from "${configPath}"; const setupImportedConfig = setupImportedConfigExports.config;`
60+
`import * as setupImportedConfigExports from "${escapeImportPath(
61+
configPath
62+
)}"; const setupImportedConfig = setupImportedConfigExports.config;`
6063
);
6164

6265
logger.debug("Loading worker setup", {

packages/cli-v3/src/utilities/initialBanner.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { spinner } from "@clack/prompts";
21
import chalk from "chalk";
32
import type { Result } from "update-check";
43
import checkForUpdate from "update-check";
54
import pkg from "../../package.json";
65
import { chalkGrey, chalkRun, chalkTask, chalkWorker, green, logo } from "./cliOutput.js";
76
import { getVersion } from "./getVersion.js";
87
import { logger } from "./logger.js";
8+
import { spinner } from "./windows";
99

1010
export async function printInitialBanner(performUpdateCheck = true) {
1111
const packageVersion = getVersion();
@@ -40,18 +40,18 @@ After installation, run Trigger.dev with \`npx trigger.dev\`.`
4040
export async function printStandloneInitialBanner(performUpdateCheck = true) {
4141
const packageVersion = getVersion();
4242

43-
let text = `\n${logo()} ${chalkGrey("(v3 Developer Preview)")}`;
43+
logger.log(`\n${logo()} ${chalkGrey("(v3 Developer Preview)")}`);
4444

4545
if (performUpdateCheck) {
4646
const maybeNewVersion = await updateCheck();
4747

4848
// Log a slightly more noticeable message if this is a major bump
4949
if (maybeNewVersion !== undefined) {
50-
text = `${text} (update available ${chalk.green(maybeNewVersion)})`;
50+
logger.log(`Update available ${chalk.green(maybeNewVersion)}`);
5151
}
5252
}
5353

54-
logger.log(text + "\n" + chalkGrey("-".repeat(54)));
54+
logger.log(`${chalkGrey("-".repeat(54))}`);
5555
}
5656

5757
export function printDevBanner() {

packages/cli-v3/src/utilities/installDependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { spinner } from "@clack/prompts";
21
import chalk from "chalk";
32
import { execa } from "execa";
43
import { getUserPackageManager, type PackageManager } from "./getUserPackageManager.js";
54
import { logger } from "./logger.js";
5+
import { spinner } from "./windows.js";
66

77
export async function installDependencies(projectDir: string) {
88
logger.info("Installing dependencies...");
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { resolve as importResolve } from "import-meta-resolve";
1+
import path from "path";
2+
import { fileURLToPath } from "url";
23

3-
export function resolveInternalFilePath(filePath: string): string {
4-
return new URL(importResolve(filePath, import.meta.url)).href.replace("file://", "");
4+
export function cliRootPath() {
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = path.dirname(__filename);
7+
return __dirname;
58
}

0 commit comments

Comments
 (0)