this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/e2e: first version of the end-to-end module tests

GITHUB_TOKEN is required with the documented permissions for GITHUB_ORG.
The test should otherwise work without any other manual steps.

A cleanup go-build-ignored program is also included
which removes repositories left behind by GITHUB_KEEP=true or failures,
which also follows the GITHUB_TOKEN and GITHUB_ORG env vars.

We use a separate Go module since these tests use google/go-github,
and we don't want the root module to gain extra module dependencies.
The test module requires the root module via a replace directive;
we avoid using a Go workspace because it's unnecessary for two modules,
and because the test module should always use the git repo's CUE module.

We place the module in internal/e2e, and not somewhere under cmd/cue,
since in the near term we might also want to end-to-end test cue/load.
The module doesn't need to be inside an internal directory,
since the test/... module path alone already makes it non-importable,
but it's a helpful signal to developers that it's not a public library.

Note that this commit doesn't hook up the tests in CI yet.
A future commit will do that, adding a token secret and an Actions step.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: Id65235a058acb78b544265e508c9462856b06b1e
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1171435
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>

+448
+92
internal/e2e/cleanup.go
··· 1 + // Copyright 2023 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 + //go:build ignore 16 + 17 + package main 18 + 19 + import ( 20 + "context" 21 + "fmt" 22 + "log" 23 + "os" 24 + "time" 25 + 26 + "github.com/google/go-github/v56/github" 27 + ) 28 + 29 + var ( 30 + githubOrg = envOr("GITHUB_ORG", "cue-labs-modules-testing") 31 + githubToken = envMust("GITHUB_TOKEN") 32 + ) 33 + 34 + func main() { 35 + client := github.NewClient(nil).WithAuthToken(githubToken) 36 + ctx := context.TODO() 37 + 38 + // Starting from the oldest, delete any repositories until a cutoff point. 39 + // For now, during active development, we delete all repos regardless of creation time. 40 + moreRepos: 41 + for { 42 + repos, resp, err := client.Repositories.ListByOrg(ctx, githubOrg, &github.RepositoryListByOrgOptions{ 43 + Sort: "created", 44 + Direction: "asc", 45 + ListOptions: github.ListOptions{ 46 + Page: 1, 47 + PerPage: 100, 48 + }, 49 + }) 50 + if err != nil { 51 + panic(err) 52 + } 53 + cutoff := time.Now() 54 + anyDeleted := false 55 + // cutoff := time.Now().Sub(24 * time.Hour) 56 + for _, repo := range repos { 57 + if repo.CreatedAt.After(cutoff) { 58 + break moreRepos // We're past the cutoff point; no more repos to delete. 59 + } 60 + repoName := repo.GetName() 61 + switch repoName { 62 + case "manual-testing": 63 + // We want to keep these repos around. 64 + continue 65 + } 66 + log.Printf("deleting %s/%s", githubOrg, repoName) 67 + if _, err := client.Repositories.Delete(ctx, githubOrg, repoName); err != nil { 68 + panic(err) 69 + } 70 + anyDeleted = true 71 + } 72 + // If we didn't find any more repos to delete, or we're at the last page, stop. 73 + // Note that we always get the first page since we delete repositories from its start. 74 + if !anyDeleted || resp.NextPage == 0 { 75 + break 76 + } 77 + } 78 + } 79 + 80 + func envOr(name, fallback string) string { 81 + if s := os.Getenv(name); s != "" { 82 + return s 83 + } 84 + return fallback 85 + } 86 + 87 + func envMust(name string) string { 88 + if s := os.Getenv(name); s != "" { 89 + return s 90 + } 91 + panic(fmt.Sprintf("%s must be set", name)) 92 + }
+35
internal/e2e/go.mod
··· 1 + module test/e2e 2 + 3 + go 1.20 4 + 5 + require ( 6 + cuelang.org/go v0.0.0-00010101000000-000000000000 7 + github.com/google/go-github/v56 v56.0.0 8 + github.com/rogpeppe/go-internal v1.11.1-0.20230926105539-32ae33786ecc 9 + github.com/rogpeppe/retry v0.1.0 10 + ) 11 + 12 + require ( 13 + cuelabs.dev/go/oci/ociregistry v0.0.0-20231004130125-2c3ad8a6ecd3 // indirect 14 + github.com/cockroachdb/apd/v3 v3.2.1 // indirect 15 + github.com/emicklei/proto v1.10.0 // indirect 16 + github.com/google/go-querystring v1.1.0 // indirect 17 + github.com/google/uuid v1.2.0 // indirect 18 + github.com/inconshreveable/mousetrap v1.1.0 // indirect 19 + github.com/mitchellh/go-wordwrap v1.0.1 // indirect 20 + github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect 21 + github.com/opencontainers/go-digest v1.0.0 // indirect 22 + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect 23 + github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 // indirect 24 + github.com/spf13/cobra v1.7.0 // indirect 25 + github.com/spf13/pflag v1.0.5 // indirect 26 + github.com/tetratelabs/wazero v1.0.2 // indirect 27 + golang.org/x/mod v0.12.0 // indirect 28 + golang.org/x/net v0.15.0 // indirect 29 + golang.org/x/sys v0.12.0 // indirect 30 + golang.org/x/text v0.13.0 // indirect 31 + golang.org/x/tools v0.13.0 // indirect 32 + gopkg.in/yaml.v3 v3.0.1 // indirect 33 + ) 34 + 35 + replace cuelang.org/go => ../../
+61
internal/e2e/go.sum
··· 1 + cuelabs.dev/go/oci/ociregistry v0.0.0-20231004130125-2c3ad8a6ecd3 h1:jJJsm3hgxosEoI5wXrwt8mv21j23vInE3owbSYKhR2c= 2 + cuelabs.dev/go/oci/ociregistry v0.0.0-20231004130125-2c3ad8a6ecd3/go.mod h1:oqwWmDcccWVB2yC2eCHFNrQR44/AVB7gHOwtBsWMo0g= 3 + github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= 4 + github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= 5 + github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 6 + github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw= 7 + github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= 8 + github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= 9 + github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= 10 + github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 11 + github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 12 + github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= 13 + github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= 14 + github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 15 + github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 16 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= 17 + github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= 18 + github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 + github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 20 + github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 21 + github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 22 + github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 23 + github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= 24 + github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= 25 + github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= 26 + github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 27 + github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto= 28 + github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY= 29 + github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 30 + github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 31 + github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= 32 + github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= 33 + github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4= 34 + github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= 35 + github.com/rogpeppe/go-internal v1.11.1-0.20230926105539-32ae33786ecc h1:mutztH6OmvFf2MGH0cqacv/FCFLkJn/rz3i7E/VWfm0= 36 + github.com/rogpeppe/go-internal v1.11.1-0.20230926105539-32ae33786ecc/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 37 + github.com/rogpeppe/retry v0.1.0 h1:6km4oqeZcFrnhx+PCPg/YxV3fnTdROBNVlSl8Pe/ztU= 38 + github.com/rogpeppe/retry v0.1.0/go.mod h1:/PtRtl9qXn+Pv5S4wN+Y5nusihQeI1PJ9U7KDcKzuvI= 39 + github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 40 + github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= 41 + github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 42 + github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 43 + github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 44 + github.com/tetratelabs/wazero v1.0.2 h1:lpwL5zczFHk2mxKur98035Gig+Z3vd9JURk6lUdZxXY= 45 + github.com/tetratelabs/wazero v1.0.2/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= 46 + golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= 47 + golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 48 + golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= 49 + golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 50 + golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= 51 + golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= 52 + golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 53 + golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= 54 + golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 55 + golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= 56 + golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 57 + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 58 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 59 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 60 + gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 61 + gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+188
internal/e2e/script_test.go
··· 1 + // Copyright 2023 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 e2e_test 16 + 17 + import ( 18 + "context" 19 + "fmt" 20 + "net/http" 21 + "os" 22 + "os/exec" 23 + "path/filepath" 24 + "testing" 25 + "time" 26 + 27 + "github.com/google/go-github/v56/github" 28 + "github.com/rogpeppe/go-internal/testscript" 29 + "github.com/rogpeppe/retry" 30 + ) 31 + 32 + func TestMain(m *testing.M) { 33 + cachedGobin := os.Getenv("CUE_CACHED_GOBIN") 34 + if cachedGobin == "" { 35 + // Install the cmd/cue version into a cached GOBIN so we can reuse it. 36 + // TODO: use "go tool cue" once we can rely on Go 1.22's tool dependency tracking in go.mod. 37 + // See: https://go.dev/issue/48429 38 + cacheDir, err := os.UserCacheDir() 39 + if err != nil { 40 + panic(err) 41 + } 42 + cachedGobin = filepath.Join(cacheDir, "cue-e2e-gobin") 43 + cmd := exec.Command("go", "install", "cuelang.org/go/cmd/cue") 44 + cmd.Env = append(cmd.Environ(), "GOBIN="+cachedGobin) 45 + out, err := cmd.CombinedOutput() 46 + if err != nil { 47 + panic(fmt.Errorf("%v: %s", err, out)) 48 + } 49 + os.Setenv("CUE_CACHED_GOBIN", cachedGobin) 50 + } 51 + 52 + os.Exit(testscript.RunMain(m, map[string]func() int{ 53 + "cue": func() int { 54 + // Note that we could avoid this wrapper entirely by setting PATH, 55 + // since TestMain sets up a single cue binary in a GOBIN directory, 56 + // but that may change at any point, or we might just switch to "go tool cue". 57 + cmd := exec.Command(filepath.Join(cachedGobin, "cue"), os.Args[1:]...) 58 + cmd.Stdin = os.Stdin 59 + cmd.Stdout = os.Stdout 60 + cmd.Stderr = os.Stderr 61 + if err := cmd.Run(); err != nil { 62 + if err, ok := err.(*exec.ExitError); ok { 63 + return err.ExitCode() 64 + } 65 + fmt.Fprintln(os.Stderr, err) 66 + return 1 67 + } 68 + return 0 69 + }, 70 + })) 71 + } 72 + 73 + var ( 74 + // githubOrg is a GitHub organization where the "CUE Module Publisher" 75 + // GitHub App has been installed on all repositories. 76 + // This is necessary since we will create a new repository per test, 77 + // and there's no way to easily install the app on each repo via the API. 78 + githubOrg = envOr("GITHUB_ORG", "cue-labs-modules-testing") 79 + // githubToken should have read and write access to repository 80 + // administration and contents within githubOrg, 81 + // to be able to create repositories under the org and git push to them. 82 + githubToken = envMust("GITHUB_TOKEN") 83 + // githubKeep leaves the newly created repo around when set to true. 84 + githubKeep = envOr("GITHUB_KEEP", "false") 85 + ) 86 + 87 + func TestScript(t *testing.T) { 88 + p := testscript.Params{ 89 + Dir: filepath.Join("testdata", "script"), 90 + RequireExplicitExec: true, 91 + Setup: func(env *testscript.Env) error { 92 + env.Setenv("CUE_EXPERIMENT", "modules") 93 + env.Setenv("CUE_REGISTRY", "registry.cue.works") 94 + env.Setenv("CUE_CACHED_GOBIN", os.Getenv("CUE_CACHED_GOBIN")) 95 + env.Setenv("GITHUB_TOKEN", githubToken) // needed for "git push" 96 + return nil 97 + }, 98 + Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ 99 + // create-github-repo creates a unique repository under githubOrg 100 + // and sets $MODULE to its resulting module path. 101 + "create-github-repo": func(ts *testscript.TestScript, neg bool, args []string) { 102 + if neg || len(args) > 0 { 103 + ts.Fatalf("usage: create-github-repo") 104 + } 105 + // TODO: name the repo after ts.Name once the API lands 106 + // TODO: add a short random suffix to prevent time collisions 107 + repoName := time.Now().UTC().Format("2006-01-02.15-04-05") 108 + client := github.NewClient(nil).WithAuthToken(githubToken) 109 + ctx := context.TODO() 110 + 111 + repo := &github.Repository{ 112 + Name: github.String(repoName), 113 + } 114 + _, _, err := client.Repositories.Create(ctx, githubOrg, repo) 115 + ts.Check(err) 116 + 117 + // Unless GITHUB_KEEP=true is set, delete the repo when we finish. 118 + // 119 + // TODO: It might be useful to leave the repo around when the test fails. 120 + // We would need testscript.TestScript to expose T.Failed for this. 121 + ts.Defer(func() { 122 + if githubKeep == "true" { 123 + return 124 + } 125 + _, err := client.Repositories.Delete(ctx, githubOrg, repoName) 126 + ts.Check(err) 127 + }) 128 + 129 + ts.Setenv("MODULE", fmt.Sprintf("github.com/%s/%s", githubOrg, repoName)) 130 + }, 131 + // env-fill rewrites its argument files to replace any environment variable 132 + // references with their values, using the same algorithm as cmpenv. 133 + "env-fill": func(ts *testscript.TestScript, neg bool, args []string) { 134 + if neg || len(args) == 0 { 135 + ts.Fatalf("usage: env-fill args...") 136 + } 137 + for _, arg := range args { 138 + path := ts.MkAbs(arg) 139 + data := ts.ReadFile(path) 140 + data = tsExpand(ts, data) 141 + ts.Check(os.WriteFile(path, []byte(data), 0o666)) 142 + } 143 + }, 144 + // cue-mod-wait waits for a CUE module to exist in a registry for up to 20s. 145 + // Since this is easily done via an HTTP HEAD request, an OCI client isn't necessary. 146 + "cue-mod-wait": func(ts *testscript.TestScript, neg bool, args []string) { 147 + if neg || len(args) > 0 { 148 + ts.Fatalf("usage: cue-mod-wait") 149 + } 150 + manifest := tsExpand(ts, "https://${CUE_REGISTRY}/v2/${MODULE}/manifests/${VERSION}") 151 + retries := retry.Strategy{ 152 + Delay: 10 * time.Millisecond, 153 + MaxDelay: time.Second, 154 + MaxDuration: 20 * time.Second, 155 + } 156 + for it := retries.Start(); it.Next(nil); { 157 + resp, err := http.Head(manifest) 158 + ts.Check(err) 159 + if resp.StatusCode == http.StatusOK { 160 + return 161 + } 162 + } 163 + ts.Fatalf("timed out waiting for module") 164 + }, 165 + }, 166 + } 167 + testscript.Run(t, p) 168 + } 169 + 170 + func envOr(name, fallback string) string { 171 + if s := os.Getenv(name); s != "" { 172 + return s 173 + } 174 + return fallback 175 + } 176 + 177 + func envMust(name string) string { 178 + if s := os.Getenv(name); s != "" { 179 + return s 180 + } 181 + panic(fmt.Sprintf("%s must be set", name)) 182 + } 183 + 184 + func tsExpand(ts *testscript.TestScript, s string) string { 185 + return os.Expand(s, func(key string) string { 186 + return ts.Getenv(key) 187 + }) 188 + }
+50
internal/e2e/testdata/script/basic.txtar
··· 1 + create-github-repo 2 + env VERSION=v0.0.1 3 + env MODVER=${MODULE}@v0 4 + 5 + cd publish 6 + 7 + # TODO: replace by "cue mod init" once it's available. 8 + # cue mod init ${MODVER} 9 + env-fill cue.mod/module.cue 10 + 11 + exec git init --initial-branch main 12 + exec git config user.name 'modules_e2e' 13 + exec git config user.email 'modules_e2e@bot' 14 + exec git remote add origin https://${GITHUB_TOKEN}@${MODULE} 15 + 16 + exec git add foo.cue cue.mod 17 + exec git commit -m 'first commit' 18 + exec git tag cue-${VERSION} 19 + 20 + exec git push origin main cue-${VERSION} 21 + # TODO: could we replace this with a retry loop of e.g. "cue mod download"? 22 + cue-mod-wait 23 + 24 + cd ../depend 25 + 26 + env-fill cue.mod/module.cue out_foo.cue 27 + exec cue export 28 + cmp stdout export.golden 29 + 30 + -- publish/cue.mod/module.cue -- 31 + module: "${MODVER}" 32 + -- publish/foo.cue -- 33 + package publish 34 + 35 + foo: "foo value" 36 + 37 + -- depend/cue.mod/module.cue -- 38 + module: "depend.localhost" 39 + 40 + deps: "${MODVER}": v: "${VERSION}" 41 + -- depend/out_foo.cue -- 42 + package depend 43 + 44 + import mt "${MODVER}:publish" 45 + 46 + out: mt.foo 47 + -- depend/export.golden -- 48 + { 49 + "out": "foo value" 50 + }
+22
internal/e2e/tools.go
··· 1 + // Copyright 2023 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 + //go:build tools 16 + // +build tools 17 + 18 + package tools 19 + 20 + import ( 21 + _ "cuelang.org/go/cmd/cue" 22 + )