diff options
Diffstat (limited to 'src/install/repository.zig')
-rw-r--r-- | src/install/repository.zig | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/install/repository.zig b/src/install/repository.zig index 109e24ce9..d53fca8d5 100644 --- a/src/install/repository.zig +++ b/src/install/repository.zig @@ -1,11 +1,16 @@ const PackageManager = @import("./install.zig").PackageManager; +const Lockfile = @import("./lockfile.zig"); const Semver = @import("./semver.zig"); const ExternalString = Semver.ExternalString; const String = Semver.String; +const SlicedString = Semver.SlicedString; const std = @import("std"); const GitSHA = String; +const bun = @import("../bun.zig"); const string = @import("../string_types.zig").string; +const strings = @import("../bun.zig").strings; const Environment = @import("../env.zig"); +const Group = Semver.Query.Group; pub const Repository = extern struct { owner: String = String{}, @@ -46,6 +51,161 @@ pub const Repository = extern struct { return try formatter.format(layout, opts, writer); } + pub fn getGitHubURL(this: Repository, lockfile: *Lockfile, buf: *[bun.MAX_PATH_BYTES]u8) []u8 { + const github = "https://github.com/"; + const owner = lockfile.str(this.owner); + const repo = lockfile.str(this.repo); + const committish = lockfile.str(this.committish); + + var i: usize = 0; + std.mem.copy(u8, buf[i..], github); + i += github.len; + + std.mem.copy(u8, buf[i..], owner); + i += owner.len; + buf[i] = '/'; + i += 1; + std.mem.copy(u8, buf[i..], repo); + i += repo.len; + if (committish.len > 0) { + buf[i] = '#'; + i += 1; + std.mem.copy(u8, buf[i..], committish); + i += committish.len; + } + + return buf[0..i]; + } + + pub fn getURL(this: Repository, lockfile: *Lockfile, buf: *[bun.MAX_PATH_BYTES]u8) []u8 { + const owner = lockfile.str(this.owner); + const repo = lockfile.str(this.repo); + const committish = lockfile.str(this.committish); + + var i: usize = 0; + std.mem.copy(u8, buf[i..], owner); + i += owner.len; + buf[i] = '/'; + i += 1; + std.mem.copy(u8, buf[i..], repo); + i += repo.len; + if (committish.len > 0) { + buf[i] = '#'; + i += 1; + std.mem.copy(u8, buf[i..], committish); + i += committish.len; + } + + return buf[0..i]; + } + + pub fn getCacheDirectoryForGitHub(this: Repository, manager: *PackageManager, buf: *[bun.MAX_PATH_BYTES]u8) ![]u8 { + var url_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const url = this.getGitHubURL(manager.lockfile, &url_buf); + + const url_hash = std.hash.Wyhash.hash(0, url); + const hex_fmt = bun.fmt.hexIntLower(url_hash); + + const repo = manager.lockfile.str(this.repo); + + return try std.fmt.bufPrint(buf, "{s}-{any}", .{ repo[0..@min(16, repo.len)], hex_fmt }); + } + + pub fn getCacheDirectory(this: Repository, manager: *PackageManager, buf: *[bun.MAX_PATH_BYTES]u8) ![]u8 { + var url_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const url = this.getURL(manager.lockfile, &url_buf); + + const url_hash = std.hash.Wyhash.hash(0, url); + const hex_fmt = bun.fmt.hexIntLower(url_hash); + + const repo = manager.lockfile.str(this.repo); + + return try std.fmt.bufPrint(buf, "{s}-{any}", .{ repo[0..@min(16, repo.len)], hex_fmt }); + } + + pub fn getCachePathForGitHub(this: Repository, manager: *PackageManager, buf: *[bun.MAX_PATH_BYTES]u8) ![]u8 { + var url_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const url = this.getGitHubURL(manager.lockfile, &url_buf); + + var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const path = try std.os.getFdPath(manager.getGitCacheDirectory().dir.fd, &path_buf); + + const url_hash = std.hash.Wyhash.hash(0, url); + const hex_fmt = bun.fmt.hexIntLower(url_hash); + + const repo = manager.lockfile.str(this.repo); + + return try std.fmt.bufPrint(buf, "{s}/{s}-{any}", .{ path, repo[0..@min(16, repo.len)], hex_fmt }); + } + + pub fn getCachePath(this: Repository, manager: *PackageManager, buf: *[bun.MAX_PATH_BYTES]u8) ![]u8 { + var url_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const url = this.getURL(manager.lockfile, &url_buf); + + var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const path = try std.os.getFdPath(manager.getGitCacheDirectory().dir.fd, &path_buf); + + const url_hash = std.hash.Wyhash.hash(0, url); + const hex_fmt = bun.fmt.hexIntLower(url_hash); + + const repo = manager.lockfile.str(this.repo); + + return try std.fmt.bufPrint(buf, "{s}/{s}-{any}", .{ path, repo[0..@min(16, repo.len)], hex_fmt }); + } + + pub fn parse(input: *const SlicedString) !Repository { + var repo = Repository{}; + const slice = input.slice; + + // ignore "git+" + const i: usize = if (strings.indexOfChar(slice, '+')) |j| j + 1 else 0; + if (strings.indexOfChar(slice[i..], ':')) |_j| { + var j = i + _j + 1; + if (!strings.hasPrefixComptime(slice[j..], "//")) return error.InvalidGitURL; + j += 2; + if (strings.indexOfAny(slice[j..], ":/")) |k| { + j += k + 1; + if (strings.indexOfChar(slice[j..], '/')) |l| { + j += l; + repo.owner = String.init(input.buf, slice[i..j]); + } else return error.InvalidGitURL; + } else return error.InvalidGitURL; + + if (strings.indexOfChar(slice[j..], '#')) |_k| { + var k = _k + j; + if (strings.endsWithComptime(slice[j + 1 .. k], ".git")) { + repo.repo = String.init(input.buf, slice[j + 1 .. k - ".git".len]); + } else { + repo.repo = String.init(input.buf, slice[j + 1 .. k]); + } + repo.committish = String.init(input.buf, slice[k + 1 ..]); + } else { + const end = if (strings.endsWithComptime(slice[j + 1 ..], ".git")) slice.len - ".git".len else slice.len; + repo.repo = String.init(input.buf, slice[j + 1 .. end]); + } + } else return error.InvalidGitURL; + + return repo; + } + + pub fn parseGitHub(input: *const SlicedString) !Repository { + var repo = Repository{}; + // ignore "github:" + const i: usize = if (strings.indexOfChar(input.slice, ':')) |j| j + 1 else 0; + if (strings.indexOfChar(input.slice, '/')) |j| { + repo.owner = String.init(input.buf, input.slice[i..j]); + if (strings.indexOfChar(input.slice[j + 1 ..], '#')) |k| { + repo.repo = String.init(input.buf, input.slice[j + 1 .. k]); + repo.committish = String.init(input.buf, input.slice[k + 1 ..]); + } else { + repo.repo = String.init(input.buf, input.slice[j + 1 ..]); + } + } else { + return error.InvalidGitURL; + } + return repo; + } + pub const Formatter = struct { label: []const u8 = "", buf: []const u8, |