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.zig172
1 files changed, 88 insertions, 84 deletions
diff --git a/src/install/install.zig b/src/install/install.zig
index 5e1b54aa6..38f2ae11f 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -1641,6 +1641,7 @@ pub const PackageManager = struct {
root_download_node: std.Progress.Node = undefined,
to_remove: []const UpdateRequest = &[_]UpdateRequest{},
+ to_update: bool = false,
root_package_json_file: std.fs.File,
root_dependency_list: Lockfile.DependencySlice = .{},
@@ -3821,9 +3822,9 @@ pub const PackageManager = struct {
},
}
}
- for (manager.package_json_updates) |*update| {
- if (strings.eql(update.name, name.slice())) {
- update.failed = true;
+ for (manager.package_json_updates) |*request| {
+ if (strings.eql(request.name, name.slice())) {
+ request.failed = true;
manager.options.do.save_lockfile = false;
manager.options.do.save_yarn_lock = false;
manager.options.do.install_packages = false;
@@ -4880,21 +4881,21 @@ pub const PackageManager = struct {
// 3. There is a "dependencies" (or equivalent list), and the package name exists in multiple lists
ast_modifier: {
// Try to use the existing spot in the dependencies list if possible
- for (updates) |*update| {
+ for (updates) |*request| {
inline for ([_]string{ "dependencies", "devDependencies", "optionalDependencies" }) |list| {
if (current_package_json.asProperty(list)) |query| {
if (query.expr.data == .e_object) {
if (query.expr.asProperty(
- if (update.is_aliased)
- update.name
+ if (request.is_aliased)
+ request.name
else
- update.version.literal.slice(update.version_buf),
+ request.version.literal.slice(request.version_buf),
)) |value| {
if (value.expr.data == .e_string) {
- if (!update.resolved_name.isEmpty() and strings.eql(list, dependency_list)) {
+ if (!request.resolved_name.isEmpty() and strings.eql(list, dependency_list)) {
replacing += 1;
} else {
- update.e_string = value.expr.data.e_string;
+ request.e_string = value.expr.data.e_string;
remaining -= 1;
}
}
@@ -4919,16 +4920,16 @@ pub const PackageManager = struct {
bun.copy(G.Property, new_dependencies, dependencies);
@memset(new_dependencies[dependencies.len..], G.Property{});
- outer: for (updates) |*update| {
- if (update.e_string != null) continue;
- defer if (comptime Environment.allow_assert) std.debug.assert(update.e_string != null);
+ outer: for (updates) |*request| {
+ if (request.e_string != null) continue;
+ defer if (comptime Environment.allow_assert) std.debug.assert(request.e_string != null);
var k: usize = 0;
while (k < new_dependencies.len) : (k += 1) {
if (new_dependencies[k].key) |key| {
- if (!update.is_aliased and !update.resolved_name.isEmpty() and key.data.e_string.eql(
+ if (!request.is_aliased and !request.resolved_name.isEmpty() and key.data.e_string.eql(
string,
- update.resolved_name.slice(update.version_buf),
+ request.resolved_name.slice(request.version_buf),
)) {
// This actually is a duplicate which we did not
// pick up before dependency resolution.
@@ -4943,12 +4944,12 @@ pub const PackageManager = struct {
}
if (key.data.e_string.eql(
string,
- if (update.is_aliased)
- update.name
+ if (request.is_aliased)
+ request.name
else
- update.version.literal.slice(update.version_buf),
+ request.version.literal.slice(request.version_buf),
)) {
- if (update.resolved_name.isEmpty()) {
+ if (request.resolved_name.isEmpty()) {
// This actually is a duplicate like "react"
// appearing in both "dependencies" and "optionalDependencies".
// For this case, we'll just swap remove it
@@ -4968,12 +4969,12 @@ pub const PackageManager = struct {
new_dependencies[k].key = try JSAst.Expr.init(
JSAst.E.String,
JSAst.E.String{
- .data = try allocator.dupe(u8, if (update.is_aliased)
- update.name
- else if (update.resolved_name.isEmpty())
- update.version.literal.slice(update.version_buf)
+ .data = try allocator.dupe(u8, if (request.is_aliased)
+ request.name
+ else if (request.resolved_name.isEmpty())
+ request.version.literal.slice(request.version_buf)
else
- update.resolved_name.slice(update.version_buf)),
+ request.resolved_name.slice(request.version_buf)),
},
logger.Loc.Empty,
).clone(allocator);
@@ -4986,8 +4987,8 @@ pub const PackageManager = struct {
},
logger.Loc.Empty,
).clone(allocator);
- update.e_string = new_dependencies[k].value.?.data.e_string;
- if (update.is_aliased) continue :outer;
+ request.e_string = new_dependencies[k].value.?.data.e_string;
+ if (request.is_aliased) continue :outer;
}
}
}
@@ -5051,26 +5052,26 @@ pub const PackageManager = struct {
}
}
- for (updates) |*update| {
- if (update.e_string) |e_string| {
- e_string.data = switch (update.resolution.tag) {
- .npm => if (update.version.tag == .dist_tag and update.version.literal.isEmpty())
+ for (updates) |*request| {
+ if (request.e_string) |e_string| {
+ e_string.data = switch (request.resolution.tag) {
+ .npm => if (request.version.tag == .dist_tag and request.version.literal.isEmpty())
switch (exact_versions) {
false => std.fmt.allocPrint(allocator, "^{}", .{
- update.resolution.value.npm.version.fmt(update.version_buf),
+ request.resolution.value.npm.version.fmt(request.version_buf),
}) catch unreachable,
true => std.fmt.allocPrint(allocator, "{}", .{
- update.resolution.value.npm.version.fmt(update.version_buf),
+ request.resolution.value.npm.version.fmt(request.version_buf),
}) catch unreachable,
}
else
null,
- .uninitialized => switch (update.version.tag) {
+ .uninitialized => switch (request.version.tag) {
.uninitialized => try allocator.dupe(u8, latest),
else => null,
},
else => null,
- } orelse try allocator.dupe(u8, update.version.literal.slice(update.version_buf));
+ } orelse try allocator.dupe(u8, request.version.literal.slice(request.version_buf));
}
}
}
@@ -5079,6 +5080,7 @@ pub const PackageManager = struct {
// Corresponds to possible commands from the CLI.
pub const Subcommand = enum {
install,
+ update,
pm,
add,
remove,
@@ -5086,17 +5088,7 @@ pub const PackageManager = struct {
unlink,
};
- pub fn init(
- ctx: Command.Context,
- comptime subcommand: Subcommand,
- ) !*PackageManager {
- return initMaybeInstall(ctx, subcommand);
- }
-
- fn initMaybeInstall(
- ctx: Command.Context,
- comptime subcommand: Subcommand,
- ) !*PackageManager {
+ pub fn init(ctx: Command.Context, comptime subcommand: Subcommand) !*PackageManager {
const cli = try CommandLineArguments.parse(ctx.allocator, subcommand);
if (comptime subcommand == .install) {
@@ -5443,21 +5435,19 @@ pub const PackageManager = struct {
try package_json_file.pwriteAll("{\"dependencies\": {}}", 0);
}
- pub inline fn add(
- ctx: Command.Context,
- ) !void {
+ pub inline fn update(ctx: Command.Context) !void {
+ try updatePackageJSONAndInstall(ctx, .update, .update);
+ }
+
+ pub inline fn add(ctx: Command.Context) !void {
try updatePackageJSONAndInstall(ctx, .add, .add);
}
- pub inline fn remove(
- ctx: Command.Context,
- ) !void {
+ pub inline fn remove(ctx: Command.Context) !void {
try updatePackageJSONAndInstall(ctx, .remove, .remove);
}
- pub inline fn link(
- ctx: Command.Context,
- ) !void {
+ pub inline fn link(ctx: Command.Context) !void {
var manager = PackageManager.init(ctx, .link) catch |err| brk: {
if (err == error.MissingPackageJSON) {
try attemptToCreatePackageJSON();
@@ -5602,14 +5592,12 @@ pub const PackageManager = struct {
} else {
// bun link lodash
switch (manager.options.log_level) {
- inline else => |log_level| try updatePackageJSONAndInstallWithManager(ctx, manager, .link, log_level),
+ inline else => |log_level| try manager.updatePackageJSONAndInstallWithManager(ctx, .link, log_level),
}
}
}
- pub inline fn unlink(
- ctx: Command.Context,
- ) !void {
+ pub inline fn unlink(ctx: Command.Context) !void {
var manager = PackageManager.init(ctx, .unlink) catch |err| brk: {
if (err == error.MissingPackageJSON) {
try attemptToCreatePackageJSON();
@@ -5770,6 +5758,10 @@ pub const PackageManager = struct {
clap.parseParam("<POS> ... ") catch unreachable,
};
+ const update_params = install_params_ ++ [_]ParamType{
+ clap.parseParam("<POS> ... \"name\" of packages to update") catch unreachable,
+ };
+
const pm_params = install_params_ ++ [_]ParamType{
clap.parseParam("<POS> ... ") catch unreachable,
};
@@ -5848,6 +5840,7 @@ pub const PackageManager = struct {
pub fn parse(allocator: std.mem.Allocator, comptime subcommand: Subcommand) !CommandLineArguments {
comptime var params: []const ParamType = &switch (subcommand) {
.install => install_params,
+ .update => update_params,
.pm => pm_params,
.add => add_params,
.remove => remove_params,
@@ -6087,15 +6080,22 @@ pub const PackageManager = struct {
comptime op: Lockfile.Package.Diff.Op,
comptime subcommand: Subcommand,
) !void {
- var manager = PackageManager.init(ctx, subcommand) catch |err| brk: {
+ var manager = init(ctx, subcommand) catch |err| brk: {
if (err == error.MissingPackageJSON) {
- if (op == .remove) {
- Output.prettyErrorln("<r>No package.json, so nothing to remove\n", .{});
- Global.crash();
+ switch (op) {
+ .update => {
+ Output.prettyErrorln("<r>No package.json, so nothing to update\n", .{});
+ Global.crash();
+ },
+ .remove => {
+ Output.prettyErrorln("<r>No package.json, so nothing to remove\n", .{});
+ Global.crash();
+ },
+ else => {
+ try attemptToCreatePackageJSON();
+ break :brk try PackageManager.init(ctx, subcommand);
+ },
}
-
- try attemptToCreatePackageJSON();
- break :brk try PackageManager.init(ctx, subcommand);
}
return err;
@@ -6107,13 +6107,13 @@ pub const PackageManager = struct {
}
switch (manager.options.log_level) {
- inline else => |log_level| try updatePackageJSONAndInstallWithManager(ctx, manager, op, log_level),
+ inline else => |log_level| try manager.updatePackageJSONAndInstallWithManager(ctx, op, log_level),
}
}
fn updatePackageJSONAndInstallWithManager(
- ctx: Command.Context,
manager: *PackageManager,
+ ctx: Command.Context,
comptime op: Lockfile.Package.Diff.Op,
comptime log_level: Options.LogLevel,
) !void {
@@ -6125,7 +6125,7 @@ pub const PackageManager = struct {
const off = @as(u64, @intCast(std.time.milliTimestamp()));
switch (op) {
- .update, .add => {
+ .add => {
const filler = @import("../cli.zig").HelpCommand.packages_to_add_filler;
examples_to_print[0] = filler[@as(usize, @intCast((off) % filler.len))];
@@ -6210,9 +6210,8 @@ pub const PackageManager = struct {
}
var updates = UpdateRequest.parse(ctx.allocator, ctx.log, manager.options.positionals[1..], &update_requests, op);
- try updatePackageJSONAndInstallWithManagerWithUpdates(
+ try manager.updatePackageJSONAndInstallWithManagerWithUpdates(
ctx,
- manager,
updates,
false,
op,
@@ -6221,8 +6220,8 @@ pub const PackageManager = struct {
}
fn updatePackageJSONAndInstallWithManagerWithUpdates(
- ctx: Command.Context,
manager: *PackageManager,
+ ctx: Command.Context,
updates: []UpdateRequest,
auto_free: bool,
comptime op: Lockfile.Package.Diff.Op,
@@ -6304,7 +6303,7 @@ pub const PackageManager = struct {
.remove => {
// if we're removing, they don't have to specify where it is installed in the dependencies list
// they can even put it multiple times and we will just remove all of them
- for (updates) |update| {
+ for (updates) |request| {
inline for ([_]string{ "dependencies", "devDependencies", "optionalDependencies", "peerDependencies" }) |list| {
if (current_package_json.asProperty(list)) |query| {
if (query.expr.data == .e_object) {
@@ -6313,7 +6312,7 @@ pub const PackageManager = struct {
var new_len = dependencies.len;
while (i < dependencies.len) : (i += 1) {
if (dependencies[i].key.?.data == .e_string) {
- if (dependencies[i].key.?.data.e_string.eql(string, update.name)) {
+ if (dependencies[i].key.?.data.e_string.eql(string, request.name)) {
if (new_len > 1) {
dependencies[i] = dependencies[new_len - 1];
new_len -= 1;
@@ -6354,7 +6353,7 @@ pub const PackageManager = struct {
}
manager.to_remove = updates;
},
- .link, .add, .update => {
+ .link, .add => {
try PackageJSONEditor.edit(
ctx.allocator,
updates,
@@ -6364,6 +6363,10 @@ pub const PackageManager = struct {
);
manager.package_json_updates = updates;
},
+ .update => {
+ manager.package_json_updates = updates;
+ manager.to_update = true;
+ },
else => {},
}
@@ -6397,8 +6400,8 @@ pub const PackageManager = struct {
try manager.installWithManager(ctx, new_package_json_source, log_level);
if (op == .update or op == .add or op == .link) {
- for (manager.package_json_updates) |update| {
- if (update.failed) {
+ for (manager.package_json_updates) |request| {
+ if (request.failed) {
Global.exit(1);
return;
}
@@ -6454,14 +6457,14 @@ pub const PackageManager = struct {
bun.copy(u8, &node_modules_buf, "node_modules" ++ std.fs.path.sep_str);
var offset_buf = node_modules_buf["node_modules/".len..];
const name_hashes = manager.lockfile.packages.items(.name_hash);
- for (updates) |update| {
+ for (updates) |request| {
// If the package no longer exists in the updated lockfile, delete the directory
// This is not thorough.
// It does not handle nested dependencies
// This is a quick & dirty cleanup intended for when deleting top-level dependencies
- if (std.mem.indexOfScalar(PackageNameHash, name_hashes, String.Builder.stringHash(update.name)) == null) {
- bun.copy(u8, offset_buf, update.name);
- cwd.deleteTree(node_modules_buf[0 .. "node_modules/".len + update.name.len]) catch {};
+ if (std.mem.indexOfScalar(PackageNameHash, name_hashes, String.Builder.stringHash(request.name)) == null) {
+ bun.copy(u8, offset_buf, request.name);
+ cwd.deleteTree(node_modules_buf[0 .. "node_modules/".len + request.name.len]) catch {};
}
}
@@ -6500,7 +6503,7 @@ pub const PackageManager = struct {
var package_json_cwd: string = "";
pub inline fn install(ctx: Command.Context) !void {
- var manager = initMaybeInstall(ctx, .install) catch |err| {
+ var manager = init(ctx, .install) catch |err| {
if (err == error.SwitchToBunAdd) {
return add(ctx);
}
@@ -7493,6 +7496,7 @@ pub const PackageManager = struct {
&lockfile,
&root,
&maybe_root,
+ if (manager.to_update) manager.package_json_updates else null,
mapping,
);
@@ -7666,9 +7670,9 @@ pub const PackageManager = struct {
}
if (manager.lockfile.packages.len > 0) {
- for (manager.package_json_updates) |update| {
+ for (manager.package_json_updates) |request| {
// prevent redundant errors
- if (update.failed) {
+ if (request.failed) {
return error.InstallFailed;
}
}
@@ -7845,8 +7849,8 @@ pub const PackageManager = struct {
}
} else if (manager.summary.remove > 0) {
if (manager.to_remove.len > 0) {
- for (manager.to_remove) |update| {
- Output.prettyln(" <r><red>-<r> {s}", .{update.name});
+ for (manager.to_remove) |request| {
+ Output.prettyln(" <r><red>-<r> {s}", .{request.name});
}
}