aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/install/install.zig116
-rw-r--r--src/install/lockfile.zig22
2 files changed, 87 insertions, 51 deletions
diff --git a/src/install/install.zig b/src/install/install.zig
index 17848a044..3a165d234 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -4261,7 +4261,8 @@ pub const PackageManager = struct {
) !void {
const G = JSAst.G;
- var remaining: usize = updates.len;
+ var remaining = updates.len;
+ var replacing: usize = 0;
// There are three possible scenarios here
// 1. There is no "dependencies" (or equivalent list) or it is empty
@@ -4275,8 +4276,12 @@ pub const PackageManager = struct {
if (query.expr.data == .e_object) {
if (query.expr.asProperty(update.name)) |value| {
if (value.expr.data == .e_string) {
- updates[i].e_string = value.expr.data.e_string;
- remaining -= 1;
+ if (update.resolved_name.isEmpty()) {
+ updates[i].e_string = value.expr.data.e_string;
+ remaining -= 1;
+ } else {
+ replacing += 1;
+ }
}
break :outer;
}
@@ -4295,7 +4300,7 @@ pub const PackageManager = struct {
}
}
- var new_dependencies = try allocator.alloc(G.Property, dependencies.len + remaining);
+ var new_dependencies = try allocator.alloc(G.Property, dependencies.len + remaining - replacing);
std.mem.copy(G.Property, new_dependencies, dependencies);
std.mem.set(G.Property, new_dependencies[dependencies.len..], G.Property{});
@@ -4305,11 +4310,32 @@ pub const PackageManager = struct {
var k: usize = 0;
while (k < new_dependencies.len) : (k += 1) {
+ if (new_dependencies[k].key) |key| {
+ if (key.data.e_string.eql(string, update.name)) {
+ if (update.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
+ if (new_dependencies.len > 1) {
+ new_dependencies[k] = new_dependencies[new_dependencies.len - 1];
+ new_dependencies = new_dependencies[0 .. new_dependencies.len - 1];
+ } else {
+ new_dependencies = &[_]G.Property{};
+ }
+ continue;
+ }
+ new_dependencies[k].key = null;
+ }
+ }
+
if (new_dependencies[k].key == null) {
new_dependencies[k].key = JSAst.Expr.init(
JSAst.E.String,
JSAst.E.String{
- .data = update.name,
+ .data = if (update.resolved_name.isEmpty())
+ update.name
+ else
+ try allocator.dupe(u8, update.resolved_name.slice(update.version_buf)),
},
logger.Loc.Empty,
);
@@ -4325,18 +4351,6 @@ pub const PackageManager = struct {
updates[j].e_string = new_dependencies[k].value.?.data.e_string;
continue :outer;
}
-
- // This actually is a duplicate
- // like "react" appearing in both "dependencies" and "optionalDependencies"
- // For this case, we'll just swap remove it
- if (new_dependencies[k].key.?.data.e_string.eql(string, update.name)) {
- if (new_dependencies.len > 1) {
- new_dependencies[k] = new_dependencies[new_dependencies.len - 1];
- new_dependencies = new_dependencies[0 .. new_dependencies.len - 1];
- } else {
- new_dependencies = &[_]G.Property{};
- }
- }
}
}
@@ -4400,13 +4414,19 @@ pub const PackageManager = struct {
}
for (updates) |*update| {
- var str = update.e_string.?;
-
- if (update.version.tag == .uninitialized) {
- str.data = latest;
- } else {
- str.data = update.version.literal.slice(update.version_buf);
- }
+ update.e_string.?.data = switch (update.resolution.tag) {
+ .npm => if (update.version.tag == .npm and update.version.value.npm.version.input.len == 0)
+ std.fmt.allocPrint(allocator, "^{}", .{
+ update.resolution.value.npm.version.fmt(update.version_buf),
+ }) catch unreachable
+ else
+ null,
+ .uninitialized => switch (update.version.tag) {
+ .uninitialized => latest,
+ else => null,
+ },
+ else => null,
+ } orelse update.version.literal.slice(update.version_buf);
}
}
};
@@ -5241,9 +5261,10 @@ pub const PackageManager = struct {
pub const UpdateRequest = struct {
name: string = "",
name_hash: PackageNameHash = 0,
- resolved_version_buf: string = "",
- version: Dependency.Version = Dependency.Version{},
+ version: Dependency.Version = .{},
version_buf: []const u8 = "",
+ resolution: Resolution = .{},
+ resolved_name: String = .{},
missing_version: bool = false,
failed: bool = false,
// This must be cloned to handle when the AST store resets
@@ -5262,7 +5283,8 @@ pub const PackageManager = struct {
// add
// remove
outer: for (positionals) |positional| {
- var value = std.mem.trim(u8, positional, " \n\r\t");
+ var input = std.mem.trim(u8, positional, " \n\r\t");
+ var value = input;
switch (op) {
.link, .unlink => if (!strings.hasPrefixComptime(value, "link:")) {
value = std.fmt.allocPrint(allocator, "link:{s}", .{value}) catch unreachable;
@@ -5297,23 +5319,31 @@ pub const PackageManager = struct {
});
Global.exit(1);
};
+ if (switch (version.tag) {
+ .dist_tag => version.value.dist_tag.name.eql(placeholder, value, value),
+ .npm => version.value.npm.name.eql(placeholder, value, value),
+ else => false,
+ }) {
+ value = std.fmt.allocPrint(allocator, "npm:{s}", .{value}) catch unreachable;
+ version = Dependency.parseWithOptionalTag(
+ allocator,
+ placeholder,
+ value,
+ null,
+ &SlicedString.init(value, value),
+ log,
+ ) orelse {
+ Output.prettyErrorln("<r><red>error<r><d>:<r> unrecognised dependency format: {s}", .{
+ positional,
+ });
+ Global.exit(1);
+ };
+ }
switch (version.tag) {
- .dist_tag => if (version.value.dist_tag.name.eql(placeholder, value, value)) {
- value = std.fmt.allocPrint(allocator, "npm:{s}", .{value}) catch unreachable;
- version = Dependency.parseWithOptionalTag(
- allocator,
- placeholder,
- value,
- null,
- &SlicedString.init(value, value),
- log,
- ) orelse {
- Output.prettyErrorln("<r><red>error<r><d>:<r> unrecognised dependency format: {s}", .{
- positional,
- });
- Global.exit(1);
- };
- },
+ .dist_tag, .npm => version.literal = if (strings.lastIndexOfChar(value, '@')) |at|
+ String.init(value, value[at + 1 ..])
+ else
+ String.from(""),
else => {},
}
diff --git a/src/install/lockfile.zig b/src/install/lockfile.zig
index df2436ae8..b948557bf 100644
--- a/src/install/lockfile.zig
+++ b/src/install/lockfile.zig
@@ -689,19 +689,25 @@ pub fn clean(old: *Lockfile, updates: []PackageManager.UpdateRequest) !*Lockfile
// Don't allow invalid memory to happen
if (updates.len > 0) {
- const dep_list = new.packages.items(.dependencies)[0];
- const res_list = new.packages.items(.resolutions)[0];
+ const slice = new.packages.slice();
+ const names = slice.items(.name);
+ const resolutions = slice.items(.resolution);
+ const dep_list = slice.items(.dependencies)[0];
+ const res_list = slice.items(.resolutions)[0];
const root_deps: []const Dependency = dep_list.get(new.buffers.dependencies.items);
- const new_resolutions: []const PackageID = res_list.get(new.buffers.resolutions.items);
+ const resolved_ids: []const PackageID = res_list.get(new.buffers.resolutions.items);
for (updates) |update, update_i| {
- if (update.version.tag == .uninitialized) {
+ if (update.resolution.tag == .uninitialized) {
+ const name_hash = String.Builder.stringHash(update.name);
for (root_deps) |dep, i| {
- if (dep.name_hash == String.Builder.stringHash(update.name)) {
- if (new_resolutions[i] > new.packages.len) continue;
+ if (dep.name_hash == name_hash) {
+ const package_id = resolved_ids[i];
+ if (package_id > new.packages.len) continue;
updates[update_i].version_buf = new.buffers.string_bytes.items;
updates[update_i].version = dep.version;
- updates[update_i].resolved_version_buf = new.buffers.string_bytes.items;
+ updates[update_i].resolution = resolutions[package_id];
+ updates[update_i].resolved_name = names[package_id];
updates[update_i].missing_version = true;
}
}
@@ -2367,7 +2373,7 @@ pub const Package = extern struct {
continue;
};
- if (to_deps[to_i].eql(from_dep, from_lockfile.buffers.string_bytes.items, to_lockfile.buffers.string_bytes.items)) {
+ if (to_deps[to_i].eql(from_dep, to_lockfile.buffers.string_bytes.items, from_lockfile.buffers.string_bytes.items)) {
mapping[to_i] = @truncate(PackageID, i);
continue;
}