aboutsummaryrefslogtreecommitdiff
path: root/src/install/install.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/install/install.zig')
-rw-r--r--src/install/install.zig133
1 files changed, 89 insertions, 44 deletions
diff --git a/src/install/install.zig b/src/install/install.zig
index dad1c4f99..d56c4c3c5 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -4934,14 +4934,13 @@ pub const PackageManager = struct {
return initMaybeInstall(ctx, package_json_file_, params, false);
}
- pub fn initMaybeInstall(
+ fn initMaybeInstall(
ctx: Command.Context,
package_json_file_: ?std.fs.File,
comptime params: []const ParamType,
comptime is_install: bool,
) !*PackageManager {
- var _ctx = ctx;
- var cli = try CommandLineArguments.parse(ctx.allocator, params, &_ctx);
+ const cli = try CommandLineArguments.parse(ctx.allocator, params);
if (comptime is_install) {
if (cli.positionals.len > 1) {
@@ -4949,13 +4948,15 @@ pub const PackageManager = struct {
}
}
- return try initWithCLI(_ctx, package_json_file_, cli);
+ var _ctx = ctx;
+ return initWithCLI(&_ctx, package_json_file_, cli, is_install);
}
- pub fn initWithCLI(
- ctx: Command.Context,
+ fn initWithCLI(
+ ctx: *Command.Context,
package_json_file_: ?std.fs.File,
cli: CommandLineArguments,
+ comptime is_install: bool,
) !*PackageManager {
// assume that spawning a thread will take a lil so we do that asap
try HTTP.HTTPThread.init();
@@ -4970,7 +4971,7 @@ pub const PackageManager = struct {
}
var fs = try Fs.FileSystem.init(null);
- var original_cwd = std.mem.trimRight(u8, fs.top_level_dir, "/");
+ var original_cwd = strings.withoutTrailingSlash(fs.top_level_dir);
bun.copy(u8, &cwd_buf, original_cwd);
@@ -4978,41 +4979,93 @@ pub const PackageManager = struct {
//
// We will walk up from the cwd, calling chdir on each directory until we find a package.json
// If we fail to find one, we will report an error saying no packages to install
- var package_json_file: std.fs.File = undefined;
-
- if (package_json_file_) |file| {
- package_json_file = file;
- } else {
-
- // can't use orelse due to a stage1 bug
- package_json_file = std.fs.cwd().openFileZ("package.json", .{ .mode = .read_write }) catch brk: {
- var this_cwd = original_cwd;
- outer: while (std.fs.path.dirname(this_cwd)) |parent| {
- cwd_buf[parent.len] = 0;
- var chdir = cwd_buf[0..parent.len :0];
-
- std.os.chdirZ(chdir) catch |err| {
- Output.prettyErrorln("Error {s} while chdir - {s}", .{ @errorName(err), bun.span(chdir) });
+ const package_json_file = package_json_file_ orelse brk: {
+ var this_cwd = original_cwd;
+ const child_json = child: {
+ while (true) {
+ var dir = std.fs.openDirAbsolute(this_cwd, .{}) catch |err| {
+ Output.prettyErrorln("Error {s} accessing {s}", .{ @errorName(err), this_cwd });
Output.flush();
return err;
};
+ defer dir.close();
+ break :child dir.openFileZ("package.json", .{ .mode = .read_write }) catch {
+ if (std.fs.path.dirname(this_cwd)) |parent| {
+ this_cwd = parent;
+ continue;
+ } else {
+ break;
+ }
+ };
+ }
+ return error.MissingPackageJSON;
+ };
- break :brk std.fs.cwd().openFileZ("package.json", .{ .mode = .read_write }) catch {
+ const child_cwd = this_cwd;
+ // Check if this is a workspace; if so, use root package
+ if (comptime is_install) {
+ var found = false;
+ while (std.fs.path.dirname(this_cwd)) |parent| {
+ var dir = std.fs.openDirAbsolute(parent, .{}) catch break;
+ defer dir.close();
+ const json_file = dir.openFileZ("package.json", .{ .mode = .read_write }) catch {
this_cwd = parent;
- continue :outer;
+ continue;
};
+ defer if (!found) json_file.close();
+ const json_stat = try json_file.stat();
+ const json_buf = try ctx.allocator.alloc(u8, json_stat.size + 64);
+ defer ctx.allocator.free(json_buf);
+ const json_len = try json_file.preadAll(json_buf, 0);
+ var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ const json_path = try bun.getFdPath(json_file.handle, &path_buf);
+ const json_source = logger.Source.initPathString(
+ json_path,
+ json_buf[0..json_len],
+ );
+ initializeStore();
+ const json = try json_parser.ParseJSONUTF8(&json_source, ctx.log, ctx.allocator);
+ if (json.asProperty("workspaces")) |prop| {
+ var workspace_names = bun.StringMap.init(ctx.allocator, true);
+ defer workspace_names.deinit();
+ const json_array = switch (prop.expr.data) {
+ .e_array => |arr| arr,
+ .e_object => |obj| if (obj.get("packages")) |packages| switch (packages.data) {
+ .e_array => |arr| arr,
+ else => break,
+ } else break,
+ else => break,
+ };
+ _ = Package.processWorkspaceNamesArray(
+ &workspace_names,
+ ctx.allocator,
+ ctx.log,
+ json_array,
+ &json_source,
+ prop.loc,
+ null,
+ ) catch break;
+ for (workspace_names.keys()) |path| {
+ if (strings.eql(child_cwd, path)) {
+ found = true;
+ child_json.close();
+ fs.top_level_dir = parent;
+ break :brk json_file;
+ }
+ }
+ break;
+ }
+ this_cwd = parent;
}
+ }
- bun.copy(u8, &cwd_buf, original_cwd);
- cwd_buf[original_cwd.len] = 0;
- var real_cwd: [:0]u8 = cwd_buf[0..original_cwd.len :0];
- std.os.chdirZ(real_cwd) catch {};
-
- return error.MissingPackageJSON;
- };
- }
+ fs.top_level_dir = child_cwd;
+ break :brk child_json;
+ };
- fs.top_level_dir = try std.os.getcwd(&cwd_buf);
+ try std.os.chdir(fs.top_level_dir);
+ try BunArguments.loadConfig(ctx.allocator, cli.config, ctx, .InstallCommand);
+ bun.copy(u8, &cwd_buf, fs.top_level_dir);
cwd_buf[fs.top_level_dir.len] = '/';
cwd_buf[fs.top_level_dir.len + 1] = 0;
fs.top_level_dir = cwd_buf[0 .. fs.top_level_dir.len + 1];
@@ -5640,11 +5693,7 @@ pub const PackageManager = struct {
}
};
- pub fn parse(
- allocator: std.mem.Allocator,
- comptime params: []const ParamType,
- ctx: *Command.Context,
- ) !CommandLineArguments {
+ pub fn parse(allocator: std.mem.Allocator, comptime params: []const ParamType) !CommandLineArguments {
var diag = clap.Diagnostic{};
var args = clap.parse(clap.Help, params, .{
@@ -5693,8 +5742,6 @@ pub const PackageManager = struct {
cli.config = opt;
}
- try BunArguments.loadConfig(allocator, cli.config, ctx, .InstallCommand);
-
cli.link_native_bins = args.options("--link-native-bins");
if (comptime params.len == add_params.len) {
@@ -6296,10 +6343,8 @@ pub const PackageManager = struct {
var cwd_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
var package_json_cwd_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- pub inline fn install(
- ctx: Command.Context,
- ) !void {
- var manager = PackageManager.initMaybeInstall(ctx, null, &install_params, true) catch |err| {
+ pub inline fn install(ctx: Command.Context) !void {
+ var manager = initMaybeInstall(ctx, null, &install_params, true) catch |err| {
if (err == error.SwitchToBunAdd) {
return add(ctx);
}