Skip to content

Commit 0105c3f

Browse files
committed
internal/filetypes: support richer versions in IsPackage
To support package paths like `foo.com/[email protected]` and `@latest`, we'll need to recognize those paths as packages, so change filetypes.IsPackage to do so. For #3618. Signed-off-by: Roger Peppe <[email protected]> Change-Id: If48f8821ca48680d146b9ffd778a529d19af4483 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1211883 Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Daniel Martí <[email protected]> TryBot-Result: CUEcueckoo <[email protected]>
1 parent b0b6049 commit 0105c3f

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

internal/filetypes/util.go

+21-10
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,31 @@ func IsPackage(s string) bool {
3030
return false
3131
}
3232

33-
// This goes off the assumption that file names may not have a `:` in their
34-
// name in cue.
35-
// A filename must have an extension or be preceded by a qualifier argument.
36-
// So strings of the form foo/bar:baz, where bar is a valid identifier and
37-
// absolute package
38-
if p := strings.LastIndexByte(s, ':'); p > 0 {
39-
if !ast.IsValidIdent(s[p+1:]) {
33+
ip := ast.ParseImportPath(s)
34+
if ip.ExplicitQualifier {
35+
if !ast.IsValidIdent(ip.Qualifier) || strings.Contains(ip.Path, ":") || ip.Path == "-" {
36+
// TODO potentially widen the scope of "file-like"
37+
// paths here to include more invalid package paths?
4038
return false
4139
}
42-
// For a non-pkg, the part before : may only be lowercase and '+'.
43-
// In addition, a package necessarily must have a slash of some form.
44-
return strings.ContainsAny(s[:p], `/.\`)
40+
// If it's got an explicit qualifier, the path has a colon in
41+
// which isn't generally allowed in CUE file names.
42+
return true
43+
}
44+
if ip.Version != "" {
45+
if strings.Contains(ip.Version, "/") {
46+
// We'll definitely not allow slashes in the version string
47+
// so treat it as a file name.
48+
return false
49+
}
50+
// Looks like an explicit version suffix.
51+
// Deliberately leave the syntax fairly open so that
52+
// we get reasonable error messages when invalid version
53+
// queries are specified.
54+
return true
4555
}
4656

57+
// No version and no qualifier.
4758
// Assuming we terminate search for packages once a scoped qualifier is
4859
// found, we know that any file without an extension (except maybe '-')
4960
// is invalid. We can therefore assume it is a package.

internal/filetypes/util_test.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@ func TestIsPackage(t *testing.T) {
2626
{"../.../foo", true},
2727
{".../foo", true},
2828
{"./:foo", true},
29+
{"[email protected]", true},
30+
{"foo.bar/[email protected]", true},
31+
{"foo.bar/[email protected]:foo", true},
2932
{"foo.bar/foo", true},
3033
{"./.foo", true},
3134
{"./.foo.json", false},
32-
35+
{`C:\Users\somefile.cue`, false},
36+
{`/foo.cue`, false},
37+
{`C:somefile.cue`, false},
38+
{`foo.cue:1234`, false},
39+
{`foo.cue:12:13`, false},
3340
// Not supported yet, but could be and isn't anything else valid.
3441
{":foo", true},
3542

@@ -43,7 +50,7 @@ func TestIsPackage(t *testing.T) {
4350
t.Run(tc.in, func(t *testing.T) {
4451
got := IsPackage(tc.in)
4552
if got != tc.out {
46-
t.Errorf("got %v; want %v", got, tc.out)
53+
t.Errorf("%q; got %v; want %v", tc.in, got, tc.out)
4754
}
4855
})
4956
}

0 commit comments

Comments
 (0)