unjs / giget

✨ Download templates and git repositories with pleasure!
MIT License
425 stars 37 forks source link

parseGitURI is not working for tags containing `@` characters #152

Closed matthewvolk closed 4 months ago

matthewvolk commented 4 months ago

Environment

Reproduction

In your terminal, run:

npx giget@latest --verbose github:bigcommerce/catalyst/apps/core#@bigcommerce/catalyst-core@0.1.0

Expected Result: Giget should successfully clone bigcommerce-catalyst to bigcommerce-catalyst at commit SHA 5955b5aeb0894ddb6748e4b60745899f1720f6ec (the commit SHA associated with tag @bigcommerce/catalyst-core@0.1.0).

Actual Result: Giget clones main instead of the desired tag. You'll notice the logs confirm this:

npx giget@latest --verbose github:bigcommerce/catalyst/apps/core#@bigcommerce/catalyst-core@0.1.0
[giget] Downloaded https://api.github.com/repos/bigcommerce/catalyst/tarball/main to /Users/matt.volk/.cache/giget/github/bigcommerce-catalyst/main.tar.gz in 537ms

Describe the bug

parseGitURI's inputRegex is as follows: https://github.com/unjs/giget/blob/2398346f387627bb7aaf0773bd2467be525331b6/src/_utils.ts#L49

We have a repository (bigcommerce/catalyst) containing tags with @ characters (example: https://github.com/bigcommerce/catalyst/tree/@bigcommerce/catalyst-core@0.1.0)

Since the @ character is not included in the <ref> character set [\w./-], the tag above won't be matched by this pattern, and will fallback to main.

Even if we try to URI encode the tag name (so that it turns into %40bigcommerce%2Fcatalyst-core%400.1.0), the character % is also not included in the <ref> character set, so it still falls back to main.

Additional context

The following change seems to fix the issue, though I'm not sure if there was an intentional reason to omit @ from the inputRegex string:

diff --git a/src/_utils.ts b/src/_utils.ts
index 6e6d8c4..f6d56db 100644
--- a/src/_utils.ts
+++ b/src/_utils.ts
@@ -46,7 +46,7 @@ export async function download(
 }

 const inputRegex =
-  /^(?<repo>[\w.-]+\/[\w.-]+)(?<subdir>[^#]+)?(?<ref>#[\w./-]+)?/;
+  /^(?<repo>[\w.-]+\/[\w.-]+)(?<subdir>[^#]+)?(?<ref>#[\w./@-]+)?/;

 export function parseGitURI(input: string): GitInfo {
   const m = input.match(inputRegex)?.groups || {};

Logs

[giget] Downloaded https://api.github.com/repos/bigcommerce/catalyst/tarball/main to /Users/matt.volk/.cache/giget/github/bigcommerce-catalyst/main.tar.gz in 537ms
[giget] Extracted to /Users/matt.volk/code/bigcommerce-catalyst in 105ms
✨ Successfully cloned bigcommerce-catalyst to bigcommerce-catalyst