aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/install/repository.zig9
-rw-r--r--src/install/resolution.zig26
-rw-r--r--src/install/semver.zig68
3 files changed, 101 insertions, 2 deletions
diff --git a/src/install/repository.zig b/src/install/repository.zig
index 23caabf73..f93402ea4 100644
--- a/src/install/repository.zig
+++ b/src/install/repository.zig
@@ -11,6 +11,15 @@ pub const Repository = extern struct {
repo: String = String{},
committish: GitSHA = GitSHA{},
+ pub fn order(lhs: *const Repository, rhs: *const Repository, lhs_buf: []const u8, rhs_buf: []const u8) std.math.Order {
+ const owner_order = lhs.owner.order(&rhs.owner, lhs_buf, rhs_buf);
+ if (owner_order != .eq) return owner_order;
+ const repo_order = lhs.repo.order(&rhs.repo, lhs_buf, rhs_buf);
+ if (repo_order != .eq) return repo_order;
+
+ return lhs.committish.order(&rhs.committish, lhs_buf, rhs_buf);
+ }
+
pub fn count(this: Repository, buf: []const u8, comptime StringBuilder: type, builder: StringBuilder) void {
builder.count(this.owner.slice(buf));
builder.count(this.repo.slice(buf));
diff --git a/src/install/resolution.zig b/src/install/resolution.zig
index 468f513df..ea75486a7 100644
--- a/src/install/resolution.zig
+++ b/src/install/resolution.zig
@@ -12,6 +12,32 @@ pub const Resolution = extern struct {
tag: Tag = Tag.uninitialized,
value: Value = Value{ .uninitialized = .{} },
+ pub fn order(
+ lhs: *const Resolution,
+ rhs: *const Resolution,
+ lhs_buf: []const u8,
+ rhs_buf: []const u8,
+ ) std.math.Order {
+ if (lhs.tag != rhs.tag) {
+ return std.math.order(@enumToInt(lhs.tag), @enumToInt(rhs.tag));
+ }
+
+ return switch (lhs.tag) {
+ .npm => lhs.value.npm.order(rhs.value.npm, lhs_buf, rhs_buf),
+ .local_tarball => lhs.value.local_tarball.order(&rhs.value.local_tarball, lhs_buf, rhs_buf),
+ .git_ssh => lhs.value.git_ssh.order(&rhs.value.git_ssh, lhs_buf, rhs_buf),
+ .git_http => lhs.value.git_http.order(&rhs.value.git_http, lhs_buf, rhs_buf),
+ .folder => lhs.value.folder.order(&rhs.value.folder, lhs_buf, rhs_buf),
+ .remote_tarball => lhs.value.remote_tarball.order(&rhs.value.remote_tarball, lhs_buf, rhs_buf),
+ .workspace => lhs.value.workspace.order(&rhs.value.workspace, lhs_buf, rhs_buf),
+ .symlink => lhs.value.symlink.order(&rhs.value.symlink, lhs_buf, rhs_buf),
+ .single_file_module => lhs.value.single_file_module.order(&rhs.value.single_file_module, lhs_buf, rhs_buf),
+ .github => lhs.value.github.order(&rhs.value.github, lhs_buf, rhs_buf),
+ .gitlab => lhs.value.gitlab.order(&rhs.value.gitlab, lhs_buf, rhs_buf),
+ else => .eq,
+ };
+ }
+
pub fn count(this: *const Resolution, buf: []const u8, comptime Builder: type, builder: Builder) void {
switch (this.tag) {
.npm => this.value.npm.count(buf, Builder, builder),
diff --git a/src/install/semver.zig b/src/install/semver.zig
index a640ee42a..1eb015a62 100644
--- a/src/install/semver.zig
+++ b/src/install/semver.zig
@@ -15,6 +15,32 @@ pub const String = extern struct {
big,
};
+ pub inline fn fmt(self: *const String, buf: []const u8) Formatter {
+ return Formatter{
+ .buf = buf,
+ .str = self,
+ };
+ }
+
+ pub const Formatter = struct {
+ str: *const String,
+ buf: string,
+
+ pub fn format(formatter: Formatter, comptime layout: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
+ const str = formatter.str;
+ try writer.writeAll(str.slice(formatter.buf));
+ }
+ };
+
+ pub inline fn order(
+ lhs: *const String,
+ rhs: *const String,
+ lhs_buf: []const u8,
+ rhs_buf: []const u8,
+ ) std.math.Order {
+ return std.math.order(lhs.slice(lhs_buf), rhs.slice(rhs_buf));
+ }
+
pub inline fn canInline(buf: []const u8) bool {
return switch (buf.len) {
0...max_inline_len - 1 => true,
@@ -318,6 +344,16 @@ pub const ExternalString = extern struct {
value: String = String{},
hash: u64 = 0,
+ pub inline fn fmt(this: *const ExternalString, buf: []const u8) String.Formatter {
+ return this.value.fmt(buf);
+ }
+
+ pub fn order(lhs: *const ExternalString, rhs: *const ExternalString, lhs_buf: []const u8, rhs_buf: []const u8) std.math.Order {
+ if (lhs.hash == rhs.hash and lhs.hash > 0) return .eq;
+
+ return lhs.value.order(&rhs.value, lhs_buf, rhs_buf);
+ }
+
/// ExternalString but without the hash
pub inline fn from(in: string) ExternalString {
return ExternalString{
@@ -496,7 +532,10 @@ pub const Version = extern struct {
}
};
- pub fn order(lhs: Version, rhs: Version) std.math.Order {
+ pub fn orderWithoutTag(
+ lhs: Version,
+ rhs: Version,
+ ) std.math.Order {
if (lhs.major < rhs.major) return .lt;
if (lhs.major > rhs.major) return .gt;
if (lhs.minor < rhs.minor) return .lt;
@@ -504,13 +543,38 @@ pub const Version = extern struct {
if (lhs.patch < rhs.patch) return .lt;
if (lhs.patch > rhs.patch) return .gt;
+ if (lhs.tag.hasPre() != rhs.tag.hasPre())
+ return if (lhs.tag.hasPre()) .lt else .gt;
+
+ if (lhs.tag.hasBuild() != rhs.tag.hasBuild())
+ return if (lhs.tag.hasBuild()) .gt else .lt;
+
return .eq;
}
+ pub fn order(
+ lhs: Version,
+ rhs: Version,
+ lhs_buf: []const u8,
+ rhs_buf: []const u8,
+ ) std.math.Order {
+ const order_without_tag = orderWithoutTag(lhs, rhs);
+ if (order_without_tag != .eq) return order_without_tag;
+
+ return lhs.tag.order(rhs.tag, lhs_buf, rhs_buf);
+ }
+
pub const Tag = extern struct {
pre: ExternalString = ExternalString{},
build: ExternalString = ExternalString{},
+ pub fn order(lhs: Tag, rhs: Tag, lhs_buf: []const u8, rhs_buf: []const u8) std.math.Order {
+ const pre_order = lhs.pre.order(&rhs.pre, lhs_buf, rhs_buf);
+ if (pre_order != .eq) return pre_order;
+
+ return lhs.build.order(&rhs.build, lhs_buf, rhs_buf);
+ }
+
pub fn cloneInto(this: Tag, slice: []const u8, buf: *[]u8) Tag {
var pre: String = this.pre.value;
var build: String = this.build.value;
@@ -992,7 +1056,7 @@ pub const Range = struct {
}
pub fn satisfies(this: Comparator, version: Version) bool {
- const order = version.order(this.version);
+ const order = version.orderWithoutTag(this.version);
return switch (order) {
.eq => switch (this.op) {