diff --git a/src/cli.zig b/src/cli.zig index aa64f315ae..3224c3af42 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -578,6 +578,7 @@ pub const Command = struct { break :brk .InstallCommand; }, + RootCommandMatcher.case("ci") => .InstallCommand, RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand, RootCommandMatcher.case("test") => .TestCommand, diff --git a/src/install/PackageManager/CommandLineArguments.zig b/src/install/PackageManager/CommandLineArguments.zig index 4878547610..156fb80c6b 100644 --- a/src/install/PackageManager/CommandLineArguments.zig +++ b/src/install/PackageManager/CommandLineArguments.zig @@ -712,9 +712,10 @@ pub fn parse(allocator: std.mem.Allocator, comptime subcommand: Subcommand) !Com } var cli = CommandLineArguments{}; + cli.positionals = args.positionals(); cli.yarn = args.flag("--yarn"); cli.production = args.flag("--production"); - cli.frozen_lockfile = args.flag("--frozen-lockfile"); + cli.frozen_lockfile = args.flag("--frozen-lockfile") or (cli.positionals.len > 0 and strings.eqlComptime(cli.positionals[0], "ci")); cli.no_progress = args.flag("--no-progress"); cli.dry_run = args.flag("--dry-run"); cli.global = args.flag("--global"); @@ -920,8 +921,6 @@ pub fn parse(allocator: std.mem.Allocator, comptime subcommand: Subcommand) !Com cli.registry = registry; } - cli.positionals = args.positionals(); - if (subcommand == .patch and cli.positionals.len < 2) { Output.errGeneric("Missing pkg to patch\n", .{}); Global.crash(); diff --git a/test/cli/install/bun-install.test.ts b/test/cli/install/bun-install.test.ts index 7d096e88d4..516e71db0b 100644 --- a/test/cli/install/bun-install.test.ts +++ b/test/cli/install/bun-install.test.ts @@ -6198,6 +6198,65 @@ it("should handle --frozen-lockfile", async () => { expect(await exited).toBe(1); }); +it("should handle bun ci alias (to --frozen-lockfile)", async () => { + let urls: string[] = []; + setHandler(dummyRegistry(urls, { "0.0.3": { as: "0.0.3" }, "0.0.5": { as: "0.0.5" } })); + + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ name: "foo", version: "0.0.1", dependencies: { baz: "0.0.3" } }), + ); + + // save the lockfile once + expect( + await spawn({ + cmd: [bunExe(), "install"], + cwd: package_dir, + stdout: "ignore", + stdin: "ignore", + stderr: "ignore", + env, + }).exited, + ).toBe(0); + + // change version of baz in package.json + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "foo", + version: "0.0.1", + dependencies: { baz: "0.0.5" }, + }), + ); + + const { stderr: stderr1, exited: exited1 } = spawn({ + cmd: [bunExe(), "ci"], + cwd: package_dir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env, + }); + + const err1 = await new Response(stderr1).text(); + expect(err1).toContain("error: lockfile had changes, but lockfile is frozen"); + expect(await exited1).toBe(1); + + // test that it works even if ci isn't first "arg" + const { stderr: stderr2, exited: exited2 } = spawn({ + cmd: [bunExe(), "--save", "ci"], + cwd: package_dir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env, + }); + + const err2 = await new Response(stderr2).text(); + expect(err2).toContain("error: lockfile had changes, but lockfile is frozen"); + expect(await exited2).toBe(1); +}); + it("should handle frozenLockfile in config file", async () => { let urls: string[] = []; setHandler(dummyRegistry(urls, { "0.0.3": { as: "0.0.3" }, "0.0.5": { as: "0.0.5" } }));