mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 02:24:10 +08:00
fix(core): install git plugins from branch subdirectories (#50754)
This commit is contained in:
@@ -1075,6 +1075,7 @@
|
||||
"@tanstack/virtual-core@3.17.8": "patches/@tanstack%2Fvirtual-core@3.17.8.patch",
|
||||
"ghostty-web@github:anomalyco/ghostty-web#83c0a07": "patches/ghostty-web@0.3.0.patch",
|
||||
"@modelcontextprotocol/client@2.0.0": "patches/@modelcontextprotocol%2Fclient@2.0.0.patch",
|
||||
"pacote@21.5.1": "patches/pacote@21.5.1.patch",
|
||||
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
|
||||
"@npmcli/agent@4.0.2": "patches/@npmcli%2Fagent@4.0.2.patch",
|
||||
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@
|
||||
"solid-js@1.9.15": "patches/solid-js@1.9.15.patch",
|
||||
"@ai-sdk/mistral@3.0.51": "patches/@ai-sdk%2Fmistral@3.0.51.patch",
|
||||
"gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch",
|
||||
"pacote@21.5.0": "patches/pacote@21.5.0.patch",
|
||||
"pacote@21.5.1": "patches/pacote@21.5.1.patch",
|
||||
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
|
||||
"@pierre/trees@1.0.0-beta.4": "patches/@pierre%2Ftrees@1.0.0-beta.4.patch",
|
||||
"@tanstack/virtual-core@3.17.8": "patches/@tanstack%2Fvirtual-core@3.17.8.patch",
|
||||
|
||||
@@ -248,20 +248,23 @@ describe("Npm.add", () => {
|
||||
expect(entries.added.directory).toContain("node_modules")
|
||||
})
|
||||
|
||||
test("installs a Git package from an npm ::path: subdirectory", async () => {
|
||||
test.each(["commit", "branch"])("installs a Git package from an npm ::path: subdirectory at a %s", async (ref) => {
|
||||
await using tmp = await tmpdir()
|
||||
const fixture = await createGitFixture(tmp.path)
|
||||
const spec = `git+file://${fixture.repository}#${fixture.commit}::path:packages/subdirectory-plugin`
|
||||
const entry = await Effect.gen(function* () {
|
||||
const spec = `git+file://${fixture.repository}#${ref === "commit" ? fixture.commit : "fixture-branch"}::path:packages/subdirectory-plugin`
|
||||
const result = await Effect.gen(function* () {
|
||||
const npm = yield* Npm.Service
|
||||
return yield* npm.add(spec)
|
||||
return { added: yield* npm.add(spec), outdated: yield* npm.check(spec) }
|
||||
}).pipe(Effect.scoped, Effect.provide(npmLayer(path.join(tmp.path, "cache"))), Effect.runPromise)
|
||||
|
||||
expect(entry.directory).toEndWith(path.join("node_modules", "fixture-subdirectory-plugin"))
|
||||
expect(entry.name).toBe("fixture-subdirectory-plugin")
|
||||
expect(result.added.directory).toEndWith(path.join("node_modules", "fixture-subdirectory-plugin"))
|
||||
expect(result.added.name).toBe("fixture-subdirectory-plugin")
|
||||
expect(result.added.version).toBe(fixture.commit)
|
||||
expect(await Bun.file(path.join(result.added.directory, "index.js")).text()).toContain("subdirectory: true")
|
||||
expect(
|
||||
await fs.stat(path.join(path.dirname(entry.directory), "fixture-subdirectory-dependency", "package.json")),
|
||||
await fs.stat(path.join(path.dirname(result.added.directory), "fixture-subdirectory-dependency", "package.json")),
|
||||
).toBeTruthy()
|
||||
expect(result.outdated).toBeFalse()
|
||||
})
|
||||
|
||||
// Several real Git installs and updates exceed Bun's default timeout on Windows.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
diff --git a/lib/git.js b/lib/git.js
|
||||
index 000ee9fc..a2a6cbb7 100644
|
||||
--- a/lib/git.js
|
||||
+++ b/lib/git.js
|
||||
@@ -254,8 +254,11 @@ class GitFetcher extends Fetcher {
|
||||
resolved: this.resolved,
|
||||
integrity: null, // it'll always be different, if we have one
|
||||
}).extract(tmp).then(() => handler(`${tmp}${this.spec.gitSubdir || ''}`), er => {
|
||||
- // fall back to ssh download if tarball fails
|
||||
- if (er.constructor.name.match(/^Http/)) {
|
||||
+ // fall back to clone if the tarball download fails due to an
|
||||
+ // HTTP error or if the response is not a valid tarball (e.g.
|
||||
+ // a hosted provider returning an HTML sign-in page with 200)
|
||||
+ if ((typeof er.statusCode === 'number' && er.statusCode >= 400) ||
|
||||
+ /^TAR_/.test(er.code)) {
|
||||
return this.#clone(handler, false)
|
||||
} else {
|
||||
throw er
|
||||
@@ -0,0 +1,58 @@
|
||||
diff --git a/node_modules/pacote/.bun-tag-eb0e1d32c8fdffa0 b/.bun-tag-eb0e1d32c8fdffa0
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/lib/git.js b/lib/git.js
|
||||
index 8faf125c6e5e572e980cfc8aaf4e6c9a21d740cf..b1ae3c8cdfa9cbdbd7573be7fa74197d158e6bcb 100644
|
||||
--- a/lib/git.js
|
||||
+++ b/lib/git.js
|
||||
@@ -247,15 +247,20 @@ class GitFetcher extends Fetcher {
|
||||
// if we're resolved, and have a tarball url, shell out to RemoteFetcher
|
||||
if (tarballOk) {
|
||||
const nameat = this.spec.name ? `${this.spec.name}@` : ''
|
||||
- return new RemoteFetcher(h.tarball({ noCommittish: false }), {
|
||||
+ // the hosted committish also carries ::path:, which is not a valid
|
||||
+ // archive ref; download the commit and select the subdirectory below
|
||||
+ return new RemoteFetcher(h.tarball({ committish: this.resolvedSha }), {
|
||||
...this.opts,
|
||||
allowGitIgnore: true,
|
||||
pkgid: `git:${nameat}${this.resolved}`,
|
||||
resolved: this.resolved,
|
||||
integrity: null, // it'll always be different, if we have one
|
||||
}).extract(tmp).then(() => handler(`${tmp}${this.spec.gitSubdir || ''}`), er => {
|
||||
- // fall back to ssh download if tarball fails
|
||||
- if (er.constructor.name.match(/^Http/)) {
|
||||
+ // fall back to clone if the tarball download fails due to an
|
||||
+ // HTTP error or if the response is not a valid tarball (e.g.
|
||||
+ // a hosted provider returning an HTML sign-in page with 200)
|
||||
+ if ((typeof er.statusCode === 'number' && er.statusCode >= 400) ||
|
||||
+ /^TAR_/.test(er.code)) {
|
||||
return this.#clone(handler, false)
|
||||
} else {
|
||||
throw er
|
||||
diff --git a/lib/util/add-git-sha.js b/lib/util/add-git-sha.js
|
||||
index 8518bff9e202a61cd4451d184b74015b43f24ad0..f46620d77c8ee336c20c1c93916307ec3be6e183 100644
|
||||
--- a/lib/util/add-git-sha.js
|
||||
+++ b/lib/util/add-git-sha.js
|
||||
@@ -1,17 +1,20 @@
|
||||
// add a sha to a git remote url spec
|
||||
const addGitSha = (spec, sha) => {
|
||||
+ // the sha replaces any committish or semver range, but the subdirectory
|
||||
+ // still selects the package within the resolved commit
|
||||
+ const subdir = spec.gitSubdir ? `::path:${spec.gitSubdir.slice(1)}` : ''
|
||||
if (spec.hosted) {
|
||||
const h = spec.hosted
|
||||
const opt = { noCommittish: true }
|
||||
const base = h.https && h.auth ? h.https(opt) : h.shortcut(opt)
|
||||
|
||||
- return `${base}#${sha}`
|
||||
+ return `${base}#${sha}${subdir}`
|
||||
} else {
|
||||
// don't use new URL for this, because it doesn't handle scp urls
|
||||
// strip the committish with indexOf/slice to avoid a regexp redos
|
||||
const hashIndex = spec.rawSpec.indexOf('#')
|
||||
const base = hashIndex === -1 ? spec.rawSpec : spec.rawSpec.slice(0, hashIndex)
|
||||
- return `${base}#${sha}`
|
||||
+ return `${base}#${sha}${subdir}`
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user