Skip to content

Commit ac1b433

Browse files
committed
cmd/cue/cmd: wire up modmux
This gives the cue command the capability to specify multiple registries. Signed-off-by: Roger Peppe <[email protected]> Change-Id: Iccf78185044ff8a19bce27b42926534ae27c6e8e Reviewed-on: https://review-eu.gerrithub.io/c/cue-lang/cue/+/1170886 TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Daniel Martí <[email protected]>
1 parent 8e24597 commit ac1b433

File tree

5 files changed

+162
-161
lines changed

5 files changed

+162
-161
lines changed

cmd/cue/cmd/registry.go

+9-77
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ package cmd
22

33
import (
44
"fmt"
5-
"net"
65
"os"
7-
"strings"
86

97
"cuelabs.dev/go/oci/ociregistry"
108
"cuelabs.dev/go/oci/ociregistry/ociclient"
11-
"cuelabs.dev/go/oci/ociregistry/ocifilter"
12-
"cuelabs.dev/go/oci/ociregistry/ociref"
139

1410
"cuelang.org/go/internal/cueexperiment"
11+
"cuelang.org/go/internal/mod/modmux"
12+
"cuelang.org/go/internal/mod/modresolve"
1513
)
1614

1715
func getRegistry() (ociregistry.Interface, error) {
@@ -23,79 +21,13 @@ func getRegistry() (ociregistry.Interface, error) {
2321
}
2422
return nil, nil
2523
}
26-
if env == "" {
27-
env = "registry.cuelabs.dev"
28-
}
29-
30-
host, prefix, insecure, err := parseRegistry(env)
31-
if err != nil {
32-
return nil, err
33-
}
34-
r, err := ociclient.New(host, &ociclient.Options{
35-
Insecure: insecure,
36-
})
37-
if err != nil {
38-
return nil, fmt.Errorf("cannot make OCI client: %v", err)
39-
}
40-
if prefix != "" {
41-
r = ocifilter.Sub(r, prefix)
42-
}
43-
return r, nil
44-
}
45-
46-
func parseRegistry(env string) (hostPort, prefix string, insecure bool, err error) {
47-
var suffix string
48-
if i := strings.LastIndex(env, "+"); i > 0 {
49-
suffix = env[i:]
50-
env = env[:i]
51-
}
52-
var r ociref.Reference
53-
if !strings.Contains(env, "/") {
54-
// OCI references don't allow a host name on its own without a repo,
55-
// but we do.
56-
r.Host = env
57-
if !ociref.IsValidHost(r.Host) {
58-
return "", "", false, fmt.Errorf("$CUE_REGISTRY %q is not a valid host name", r.Host)
59-
}
60-
} else {
61-
var err error
62-
r, err = ociref.Parse(env)
63-
if err != nil {
64-
return "", "", false, fmt.Errorf("cannot parse $CUE_REGISTRY: %v", err)
65-
}
66-
if r.Tag != "" || r.Digest != "" {
67-
return "", "", false, fmt.Errorf("$CUE_REGISTRY %q cannot have an associated tag or digest", env)
68-
}
69-
}
70-
if suffix == "" {
71-
if isInsecureHost(r.Host) {
72-
suffix = "+insecure"
73-
} else {
74-
suffix = "+secure"
75-
}
76-
}
77-
switch suffix {
78-
case "+insecure":
79-
insecure = true
80-
case "+secure":
81-
default:
82-
return "", "", false, fmt.Errorf("unknown suffix (%q) to CUE_REGISTRY (need +insecure or +secure)", suffix)
83-
}
84-
return r.Host, r.Repository, insecure, nil
85-
}
86-
87-
func isInsecureHost(hostPort string) bool {
88-
host, _, err := net.SplitHostPort(hostPort)
24+
resolver, err := modresolve.ParseCUERegistry(env, "registry.cuelabs.dev")
8925
if err != nil {
90-
host = hostPort
91-
}
92-
switch host {
93-
case "localhost",
94-
"127.0.0.1",
95-
"::1":
96-
return true
26+
return nil, fmt.Errorf("bad value for $CUE_REGISTRY: %v", err)
9727
}
98-
// TODO other clients have logic for RFC1918 too, amongst other
99-
// things. Maybe we should do that too.
100-
return false
28+
return modmux.New(resolver, func(host string, insecure bool) (ociregistry.Interface, error) {
29+
return ociclient.New(host, &ociclient.Options{
30+
Insecure: insecure,
31+
})
32+
}), nil
10133
}

cmd/cue/cmd/registry_test.go

-77
This file was deleted.

cmd/cue/cmd/script_test.go

+23-6
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,25 @@ func TestScript(t *testing.T) {
108108
"GONOSUMDB=*", // GOPROXY is a private proxy
109109
homeEnvName()+"="+home,
110110
)
111-
registryDir := filepath.Join(e.WorkDir, "_registry")
112-
if info, err := os.Stat(registryDir); err == nil && info.IsDir() {
111+
entries, err := os.ReadDir(e.WorkDir)
112+
if err != nil {
113+
return fmt.Errorf("cannot read workdir: %v", err)
114+
}
115+
hasRegistry := false
116+
for _, entry := range entries {
117+
if !entry.IsDir() {
118+
continue
119+
}
120+
regID, ok := strings.CutPrefix(entry.Name(), "_registry")
121+
if !ok {
122+
continue
123+
}
113124
// There's a _registry directory. Start a fake registry server to serve
114125
// the modules in it.
126+
hasRegistry = true
127+
registryDir := filepath.Join(e.WorkDir, entry.Name())
115128
prefix := ""
116-
if data, err := os.ReadFile(filepath.Join(e.WorkDir, "_registry_prefix")); err == nil {
129+
if data, err := os.ReadFile(filepath.Join(e.WorkDir, "_registry"+regID+"_prefix")); err == nil {
117130
prefix = strings.TrimSpace(string(data))
118131
}
119132
reg, err := registrytest.New(os.DirFS(registryDir), prefix)
@@ -124,14 +137,18 @@ func TestScript(t *testing.T) {
124137
prefix = "/" + prefix
125138
}
126139
e.Vars = append(e.Vars,
127-
"CUE_REGISTRY="+reg.Host()+prefix+"+insecure",
140+
"CUE_REGISTRY"+regID+"="+reg.Host()+prefix+"+insecure",
128141
// This enables some tests to construct their own malformed
129142
// CUE_REGISTRY values that still refer to the test registry.
130-
"DEBUG_REGISTRY_HOST="+reg.Host(),
131-
"CUE_EXPERIMENT=modules",
143+
"DEBUG_REGISTRY"+regID+"_HOST="+reg.Host(),
132144
)
133145
e.Defer(reg.Close)
134146
}
147+
if hasRegistry {
148+
e.Vars = append(e.Vars,
149+
"CUE_EXPERIMENT=modules",
150+
)
151+
}
135152
return nil
136153
},
137154
Condition: cuetest.Condition,

cmd/cue/cmd/testdata/script/registry_invalid_env.txtar

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ env CUE_REGISTRY=malformed!registry@url
44
cmp stderr expect-stderr
55

66
-- expect-stderr --
7-
$CUE_REGISTRY "malformed!registry@url" is not a valid host name
7+
bad value for $CUE_REGISTRY: invalid registry "malformed!registry@url": invalid host name "malformed!registry@url" in registry
88
-- main.cue --
99
package main
1010
import "example.com/e"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
env CUE_REGISTRY=${CUE_REGISTRY1},baz.org=$CUE_REGISTRY2
2+
exec cue eval .
3+
cmp stdout expect-stdout
4+
-- expect-stdout --
5+
main: "main"
6+
"foo.com/bar/hello@v0": "v0.2.3"
7+
"bar.com@v0": "v0.5.0"
8+
"baz.org@v0": "v0.10.1 in registry2"
9+
"example.com@v0": "v0.0.1"
10+
-- cue.mod/module.cue --
11+
module: "main.org"
12+
13+
deps: "example.com@v0": v: "v0.0.1"
14+
15+
-- main.cue --
16+
package main
17+
import "example.com@v0:main"
18+
19+
main
20+
21+
-- _registry1/example.com_v0.0.1/cue.mod/module.cue --
22+
module: "example.com@v0"
23+
deps: {
24+
"foo.com/bar/hello@v0": v: "v0.2.3"
25+
"bar.com@v0": v: "v0.5.0"
26+
}
27+
28+
-- _registry1/example.com_v0.0.1/top.cue --
29+
package main
30+
31+
// Note: import without a major version takes
32+
// the major version from the module.cue file.
33+
import a "foo.com/bar/hello"
34+
a
35+
main: "main"
36+
"example.com@v0": "v0.0.1"
37+
38+
-- _registry1/foo.com_bar_hello_v0.2.3/cue.mod/module.cue --
39+
module: "foo.com/bar/hello@v0"
40+
deps: {
41+
"bar.com@v0": v: "v0.0.2"
42+
"baz.org@v0": v: "v0.10.1"
43+
}
44+
45+
-- _registry1/foo.com_bar_hello_v0.2.3/x.cue --
46+
package hello
47+
import (
48+
a "bar.com/bar@v0"
49+
b "baz.org@v0:baz"
50+
)
51+
"foo.com/bar/hello@v0": "v0.2.3"
52+
a
53+
b
54+
55+
56+
-- _registry1/bar.com_v0.0.2/cue.mod/module.cue --
57+
module: "bar.com@v0"
58+
deps: "baz.org@v0": v: "v0.0.2"
59+
60+
-- _registry1/bar.com_v0.0.2/bar/x.cue --
61+
package bar
62+
import a "baz.org@v0:baz"
63+
"bar.com@v0": "v0.0.2"
64+
a
65+
66+
67+
-- _registry1/bar.com_v0.5.0/cue.mod/module.cue --
68+
module: "bar.com@v0"
69+
deps: "baz.org@v0": v: "v0.5.0"
70+
71+
-- _registry1/bar.com_v0.5.0/bar/x.cue --
72+
package bar
73+
import a "baz.org@v0:baz"
74+
"bar.com@v0": "v0.5.0"
75+
a
76+
77+
78+
-- _registry1/baz.org_v0.0.2/cue.mod/module.cue --
79+
module: "baz.org@v0"
80+
81+
-- _registry1/baz.org_v0.0.2/baz.cue --
82+
package baz
83+
"baz.org@v0": "v0.0.2"
84+
85+
-- _registry1/baz.org_v0.1.2/cue.mod/module.cue --
86+
module: "baz.org@v0"
87+
88+
-- _registry1/baz.org_v0.1.2/baz.cue --
89+
package baz
90+
"baz.org@v0": "v0.1.2"
91+
92+
93+
-- _registry1/baz.org_v0.5.0/cue.mod/module.cue --
94+
module: "baz.org@v0"
95+
96+
-- _registry1/baz.org_v0.5.0/baz.cue --
97+
package baz
98+
"baz.org@v0": "v0.5.0"
99+
100+
-- _registry1/baz.org_v0.10.1/cue.mod/module.cue --
101+
module: "baz.org@v0"
102+
103+
-- _registry1/baz.org_v0.10.1/baz.cue --
104+
package baz
105+
"baz.org@v0": "v0.10.1"
106+
107+
-- _registry2/baz.org_v0.0.2/cue.mod/module.cue --
108+
module: "baz.org@v0"
109+
110+
-- _registry2/baz.org_v0.0.2/baz.cue --
111+
package baz
112+
"baz.org@v0": "v0.0.2"
113+
114+
-- _registry2/baz.org_v0.1.2/cue.mod/module.cue --
115+
module: "baz.org@v0"
116+
117+
-- _registry2/baz.org_v0.5.0/cue.mod/module.cue --
118+
module: "baz.org@v0"
119+
120+
-- _registry2/baz.org_v0.5.0/baz.cue --
121+
package baz
122+
"baz.org@v0": "v0.5.0 in registry2"
123+
124+
-- _registry2/baz.org_v0.10.1/cue.mod/module.cue --
125+
module: "baz.org@v0"
126+
127+
-- _registry2/baz.org_v0.10.1/baz.cue --
128+
package baz
129+
"baz.org@v0": "v0.10.1 in registry2"

0 commit comments

Comments
 (0)