diff options
author | 2023-09-27 18:22:50 -0800 | |
---|---|---|
committer | 2023-09-27 19:22:50 -0700 | |
commit | 1d6d639352d58e65f6bbeff0188c01efbfa59bf8 (patch) | |
tree | e7ead427bc25b58f0fcd3d8592c1bb14f86d4cfe | |
parent | 7cd1dc2817158f9a27605ec5bac33575b9ef12f3 (diff) | |
download | bun-1d6d639352d58e65f6bbeff0188c01efbfa59bf8.tar.gz bun-1d6d639352d58e65f6bbeff0188c01efbfa59bf8.tar.zst bun-1d6d639352d58e65f6bbeff0188c01efbfa59bf8.zip |
fix(bun install): Handle vercel and github tarball path dependencies (#6122)
* fix(bun install): Handle vercel and github tarball path dependencies
* test(bun install): test tarball path with when
* Simplify github tarball detection
---------
Co-authored-by: bun <noreply@oven.sh>
-rw-r--r-- | src/install/dependency.zig | 25 | ||||
-rw-r--r-- | test/cli/install/bun-install.test.ts | 56 |
2 files changed, 80 insertions, 1 deletions
diff --git a/src/install/dependency.zig b/src/install/dependency.zig index 9c7bcf479..01c1ecd86 100644 --- a/src/install/dependency.zig +++ b/src/install/dependency.zig @@ -221,6 +221,26 @@ pub inline fn isGitHubRepoPath(dependency: string) bool { return hash_index != dependency.len - 1 and first_slash_index > 0 and first_slash_index != dependency.len - 1; } +// Github allows for the following format of URL: +// https://github.com/<org>/<repo>/tarball/<ref> +// This is a legacy (but still supported) method of retrieving a tarball of an +// entire source tree at some git reference. (ref = branch, tag, etc. Note: branch +// can have arbitrary number of slashes) +pub inline fn isGitHubTarballPath(dependency: string) bool { + var parts = strings.split(dependency, "/"); + + var n_parts: usize = 0; + + while (parts.next()) |part| { + n_parts += 1; + if (n_parts == 3) { + return strings.eql(part, "tarball"); + } + } + + return false; +} + // This won't work for query string params, but I'll let someone file an issue // before I add that. pub inline fn isTarball(dependency: string) bool { @@ -494,8 +514,11 @@ pub const Version = struct { else => {}, } if (strings.hasPrefixComptime(url, "github.com/")) { - if (isGitHubRepoPath(url["github.com/".len..])) return .github; + const path = url["github.com/".len..]; + if (isGitHubTarballPath(path)) return .tarball; + if (isGitHubRepoPath(path)) return .github; } + return .tarball; } } }, diff --git a/test/cli/install/bun-install.test.ts b/test/cli/install/bun-install.test.ts index 3c70f8a8c..063f9ad04 100644 --- a/test/cli/install/bun-install.test.ts +++ b/test/cli/install/bun-install.test.ts @@ -2850,6 +2850,62 @@ it("should handle GitHub URL in dependencies (git+https://github.com/user/repo.g await access(join(package_dir, "bun.lockb")); }); +it("should handle GitHub tarball URL in dependencies (https://github.com/user/repo/tarball/ref)", async () => { + const urls: string[] = []; + setHandler(dummyRegistry(urls)); + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "Foo", + version: "0.0.1", + dependencies: { + when: "https://github.com/cujojs/when/tarball/1.0.2", + }, + }), + ); + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "install"], + cwd: package_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err).toContain("Saved lockfile"); + expect(stdout).toBeDefined(); + let out = await new Response(stdout).text(); + out = out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, ""); + out = out.replace(/(github:[^#]+)#[a-f0-9]+/, "$1"); + expect(out.split(/\r?\n/)).toEqual([ + " + when@https://github.com/cujojs/when/tarball/1.0.2", + "", + " 1 packages installed", + ]); + expect(await exited).toBe(0); + expect(urls.sort()).toBeEmpty(); + expect(requested).toBe(0); + expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "when"]); + expect(await readdirSorted(join(package_dir, "node_modules", "when"))).toEqual([ + ".gitignore", + ".gitmodules", + "LICENSE.txt", + "README.md", + "apply.js", + "cancelable.js", + "delay.js", + "package.json", + "test", + "timed.js", + "timeout.js", + "when.js", + ]); + const package_json = await file(join(package_dir, "node_modules", "when", "package.json")).json(); + expect(package_json.name).toBe("when"); + await access(join(package_dir, "bun.lockb")); +}); + it("should handle GitHub URL with existing lockfile", async () => { const urls: string[] = []; setHandler(dummyRegistry(urls)); |