Skip to content

Commit 59a0d3c

Browse files
rogpeppemvdan
authored andcommitted
cmd/cue: new "mod resolve" command
This command prints information about how a module path resolves to a registry in a standard format (OCI references). Fixes #2829 Signed-off-by: Roger Peppe <[email protected]> Change-Id: Ib470870e96f6b8a3224e1b1e181af7ec0717100b Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1194106 Unity-Result: CUE porcuepine <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Daniel Martí <[email protected]>
1 parent bc3e24c commit 59a0d3c

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

cmd/cue/cmd/mod.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ See also:
4848
cmd.AddCommand(newModGetCmd(c))
4949
cmd.AddCommand(newModInitCmd(c))
5050
cmd.AddCommand(newModRegistryCmd(c))
51+
cmd.AddCommand(newModResolveCmd(c))
5152
cmd.AddCommand(newModTidyCmd(c))
5253
cmd.AddCommand(newModUploadCmd(c))
5354
return cmd

cmd/cue/cmd/modresolve.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2024 The CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"fmt"
19+
"strings"
20+
21+
"cuelabs.dev/go/oci/ociregistry/ociref"
22+
"github.com/spf13/cobra"
23+
24+
"cuelang.org/go/mod/module"
25+
)
26+
27+
func newModResolveCmd(c *Command) *cobra.Command {
28+
cmd := &cobra.Command{
29+
Use: "resolve <modulepath>[@<version>] ...",
30+
Short: "Show how a module path resolves to a registry",
31+
Long: `WARNING: THIS COMMAND IS EXPERIMENTAL.
32+
33+
This command prints information about how a given
34+
module path will resolve to an actual registry in the
35+
form of an OCI reference.
36+
37+
If the module version (which must be a canonical semver version)
38+
is omitted, it omits the tag from the reference.
39+
40+
It only consults local information - it works lexically
41+
with respect to the registry configuration (see "cue help registryconfig")
42+
and does not make any network calls to check whether
43+
the module exists.
44+
45+
Note: you must enable the modules experiment with:
46+
export CUE_EXPERIMENT=modules
47+
for this command to work.
48+
`,
49+
RunE: mkRunE(c, runModResolve),
50+
}
51+
return cmd
52+
}
53+
54+
func runModResolve(cmd *Command, args []string) error {
55+
resolver, err := getRegistryResolver()
56+
if err != nil {
57+
return err
58+
}
59+
if resolver == nil {
60+
return fmt.Errorf("modules experiment not enabled (enable with CUE_EXPERIMENT=modules)")
61+
}
62+
63+
for _, arg := range args {
64+
mpath, vers, ok := strings.Cut(arg, "@")
65+
if ok {
66+
if _, err := module.ParseVersion(arg); err != nil {
67+
return fmt.Errorf("invalid module path: %v", err)
68+
}
69+
} else {
70+
mpath = args[0]
71+
if err := module.CheckPathWithoutVersion(arg); err != nil {
72+
return fmt.Errorf("invalid module path: %v", err)
73+
}
74+
}
75+
loc, ok := resolver.ResolveToLocation(mpath, vers)
76+
if !ok {
77+
// TODO should we print this and carry on anyway?
78+
// And perhaps return a silent error when we do that?
79+
return fmt.Errorf("no registry found for module %q", arg)
80+
}
81+
82+
ref := ociref.Reference{
83+
Host: loc.Host,
84+
Repository: loc.Repository,
85+
}
86+
// TODO when vers is empty, loc.Tag does actually contain the
87+
// tag prefix (if any) so we could potentially provide more info,
88+
// but it might be misleading so leave it out for now.
89+
// Also, there's no way in the standard OCI reference syntax to
90+
// indicate that a connection is insecure, so leave out that
91+
// info too. We could use our own syntax (+insecure) but
92+
// that arguably makes the output less useful as it won't be
93+
// acceptable to standard tooling.
94+
if vers != "" {
95+
ref.Tag = loc.Tag
96+
}
97+
fmt.Println(ref)
98+
}
99+
return nil
100+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
env CUE_EXPERIMENT=modules
2+
env CUE_REGISTRY=foo.com/bar=myregistry.example/foo,other.org=none
3+
4+
exec cue mod resolve somethingelse.bar.com/[email protected]
5+
cmp stdout want-resolve0
6+
7+
exec cue mod resolve somethingelse.bar.com/abc
8+
cmp stdout want-resolve1
9+
10+
exec cue mod resolve foo.com/bar/[email protected]
11+
cmp stdout want-resolve2
12+
13+
! exec cue mod resolve other.org/a/b
14+
cmp stderr want-resolve3
15+
16+
env CUE_REGISTRY=file:registry-config.cue
17+
18+
exec cue mod resolve a.com/b
19+
cmp stdout want-resolve4
20+
21+
exec cue mod resolve a.com/foo/bar/[email protected]
22+
cmp stdout want-resolve5
23+
24+
exec cue mod resolve a.com/foo/bar/[email protected]
25+
cmp stdout want-resolve5
26+
27+
exec cue mod resolve stripped.org/bar/baz/[email protected]
28+
cmp stdout want-resolve6
29+
30+
-- registry-config.cue --
31+
moduleRegistries: {
32+
"a.com": {
33+
registry: "r1.example/a/b+insecure"
34+
}
35+
"a.com/foo/bar": {
36+
registry: "r2.example/xxx"
37+
pathEncoding: "hashAsRepo"
38+
prefixForTags: "cue-"
39+
}
40+
"stripped.org/bar": {
41+
registry: "r3.example/repo"
42+
stripPrefix: true
43+
}
44+
"badmodules.org": {
45+
registry: "none"
46+
}
47+
}
48+
-- want-resolve0 --
49+
registry.cue.works/somethingelse.bar.com/abc:v1.2.3
50+
-- want-resolve1 --
51+
registry.cue.works/somethingelse.bar.com/abc
52+
-- want-resolve2 --
53+
myregistry.example/foo/foo.com/bar/baz:v0.1.2
54+
-- want-resolve3 --
55+
no registry found for module "other.org/a/b"
56+
-- want-resolve4 --
57+
r1.example/a/b/a.com/b
58+
-- want-resolve5 --
59+
r2.example/xxx/0764601cd4e1d9d84efc2f4ddc23191e599fa9826f46b16b84269b6fe3679184:cue-v1.2.3
60+
-- want-resolve6 --
61+
r3.example/repo/baz/p:v0.1.2

0 commit comments

Comments
 (0)