this repo has no description
0
fork

Configure Feed

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

cmd/cue: implement --language-version flag for cue mod edit and init

This allows the language version to be chosen at `cue mod init` time
and also to be changed later.

Fixes #3247.
Fixes #2920.

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: Iaa7324d164242ecc8ff6ce793e16dfaf88a532b4
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1196822
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.io>

+166 -44
+33 -32
cmd/cue/cmd/flags.go
··· 20 20 21 21 // Common flags 22 22 const ( 23 - flagAll flagName = "all" 24 - flagAllErrors flagName = "all-errors" 25 - flagCheck flagName = "check" 26 - flagDiff flagName = "diff" 27 - flagDryRun flagName = "dry-run" 28 - flagEscape flagName = "escape" 29 - flagExpression flagName = "expression" 30 - flagExt flagName = "ext" 31 - flagFiles flagName = "files" 32 - flagForce flagName = "force" 33 - flagGlob flagName = "name" 34 - flagIgnore flagName = "ignore" 35 - flagInject flagName = "inject" 36 - flagInjectVars flagName = "inject-vars" 37 - flagInlineImports flagName = "inline-imports" 38 - flagJSON flagName = "json" 39 - flagList flagName = "list" 40 - flagMerge flagName = "merge" 41 - flagOut flagName = "out" 42 - flagOutFile flagName = "outfile" 43 - flagPackage flagName = "package" 44 - flagPath flagName = "path" 45 - flagProtoEnum flagName = "proto_enum" 46 - flagProtoPath flagName = "proto_path" 47 - flagRecursive flagName = "recursive" 48 - flagSchema flagName = "schema" 49 - flagSimplify flagName = "simplify" 50 - flagSource flagName = "source" 51 - flagStrict flagName = "strict" 52 - flagTrace flagName = "trace" 53 - flagVerbose flagName = "verbose" 54 - flagWithContext flagName = "with-context" 23 + flagAll flagName = "all" 24 + flagAllErrors flagName = "all-errors" 25 + flagCheck flagName = "check" 26 + flagDiff flagName = "diff" 27 + flagDryRun flagName = "dry-run" 28 + flagEscape flagName = "escape" 29 + flagExpression flagName = "expression" 30 + flagExt flagName = "ext" 31 + flagFiles flagName = "files" 32 + flagForce flagName = "force" 33 + flagGlob flagName = "name" 34 + flagIgnore flagName = "ignore" 35 + flagInject flagName = "inject" 36 + flagInjectVars flagName = "inject-vars" 37 + flagInlineImports flagName = "inline-imports" 38 + flagJSON flagName = "json" 39 + flagLanguageVersion flagName = "language-version" 40 + flagList flagName = "list" 41 + flagMerge flagName = "merge" 42 + flagOut flagName = "out" 43 + flagOutFile flagName = "outfile" 44 + flagPackage flagName = "package" 45 + flagPath flagName = "path" 46 + flagProtoEnum flagName = "proto_enum" 47 + flagProtoPath flagName = "proto_path" 48 + flagRecursive flagName = "recursive" 49 + flagSchema flagName = "schema" 50 + flagSimplify flagName = "simplify" 51 + flagSource flagName = "source" 52 + flagStrict flagName = "strict" 53 + flagTrace flagName = "trace" 54 + flagVerbose flagName = "verbose" 55 + flagWithContext flagName = "with-context" 55 56 56 57 // Hidden flags. 57 58 flagCpuProfile flagName = "cpuprofile"
+40 -2
cmd/cue/cmd/modedit.go
··· 21 21 "path/filepath" 22 22 "strconv" 23 23 24 + "cuelang.org/go/internal/cueversion" 25 + "cuelang.org/go/internal/mod/semver" 24 26 "cuelang.org/go/mod/modfile" 25 27 "cuelang.org/go/mod/module" 26 28 "github.com/spf13/cobra" ··· 54 56 RunE: mkRunE(c, editCmd.run), 55 57 Args: cobra.ExactArgs(0), 56 58 } 57 - addFlagVar(cmd, flagFunc(editCmd.flagSource), "source", "set the source field") 59 + addFlagVar(cmd, flagFunc(editCmd.flagSource), string(flagSource), "set the source field") 58 60 addFlagVar(cmd, boolFlagFunc(editCmd.flagDropSource), "drop-source", "remove the source field") 61 + addFlagVar(cmd, flagFunc(editCmd.flagLanguageVersion), string(flagLanguageVersion), "set language.version ('current' means current language version)") 59 62 addFlagVar(cmd, flagFunc(editCmd.flagModule), "module", "set the module path") 60 63 addFlagVar(cmd, flagFunc(editCmd.flagRequire), "require", "add a required module@version") 61 64 addFlagVar(cmd, flagFunc(editCmd.flagDropRequire), "drop-require", "remove a requirement") ··· 88 91 } 89 92 newData, err := mf.Format() 90 93 if err != nil { 91 - return fmt.Errorf("internal error: invalid module.cue file generated: %v", err) 94 + return fmt.Errorf("invalid resulting module.cue file after edits: %v", err) 92 95 } 93 96 if bytes.Equal(newData, data) { 94 97 return nil ··· 126 129 return nil 127 130 }) 128 131 return nil 132 + } 133 + 134 + func (c *modEditCmd) flagLanguageVersion(arg string) error { 135 + editFunc, err := addLanguageVersion(arg) 136 + if err != nil { 137 + return err 138 + } 139 + c.addEdit(editFunc) 140 + return nil 141 + } 142 + 143 + func addLanguageVersion(v string) (func(*modfile.File) error, error) { 144 + if v == "current" { 145 + v = cueversion.LanguageVersion() 146 + } else { 147 + if semver.Canonical(v) != v { 148 + return nil, fmt.Errorf("language version %q is not canonical (must include major, minor and patch versions)", v) 149 + } 150 + 151 + if min := modfile.EarliestClosedSchemaVersion(); semver.Compare(v, min) < 0 { 152 + // TODO(rogpeppe) We might want to relax this to allow people to 153 + // declare an earlier language version (see https://cuelang.org/issue/3145). 154 + return nil, fmt.Errorf("language version %q is too early for module.cue schema (earliest allowed is %s)", v, min) 155 + } 156 + if max := cueversion.LanguageVersion(); semver.Compare(v, max) > 0 { 157 + return nil, fmt.Errorf("language version %q may not be after current language version %s", v, max) 158 + } 159 + } 160 + return func(f *modfile.File) error { 161 + if f.Language == nil { 162 + f.Language = &modfile.Language{} 163 + } 164 + f.Language.Version = v 165 + return nil 166 + }, nil 129 167 } 130 168 131 169 func (c *modEditCmd) flagModule(arg string) error {
+7 -3
cmd/cue/cmd/modinit.go
··· 22 22 23 23 "github.com/spf13/cobra" 24 24 25 - "cuelang.org/go/internal/cueversion" 26 25 "cuelang.org/go/mod/modfile" 27 26 "cuelang.org/go/mod/module" 28 27 ) ··· 45 44 46 45 cmd.Flags().BoolP(string(flagForce), "f", false, "force moving old-style cue.mod file") 47 46 cmd.Flags().String(string(flagSource), "", "set the source field") 47 + cmd.Flags().String(string(flagLanguageVersion), "current", "set the language version ('current' means current language version)") 48 48 return cmd 49 49 } 50 50 ··· 84 84 return err 85 85 } 86 86 } 87 - mf.Language = &modfile.Language{ 88 - Version: cueversion.LanguageVersion(), 87 + editFunc, err := addLanguageVersion(flagLanguageVersion.String(cmd)) 88 + if err != nil { 89 + return err 90 + } 91 + if err := editFunc(mf); err != nil { 92 + return err 89 93 } 90 94 91 95 err = os.Mkdir(mod, 0755)
+37
cmd/cue/cmd/testdata/script/modedit_initial.txtar
··· 19 19 exec cue mod edit --module othermain.org@v1 20 20 cmp cue.mod/module.cue want-module-5 21 21 22 + # Set specific version. 23 + exec cue mod edit --language-version v0.9.2 24 + cmp cue.mod/module.cue want-module-6 25 + 26 + # Set latest version. 27 + exec cue mod edit --language-version current 28 + cmpenv cue.mod/module.cue want-module-7 29 + 30 + # Set version earlier than earliest module schema version. 31 + ! exec cue mod edit --language-version v0.4.3 32 + cmp stderr want-stderr-8 33 + 34 + # Set version too new. 35 + ! exec cue mod edit --language-version v2.3.4 36 + cmpenv stderr want-stderr-9 37 + 38 + # Check that it's an error to set the version earlier than 39 + # allowed by some of the fields already present. 40 + exec cue mod edit --source self 41 + ! exec cue mod edit --language-version v0.8.0 42 + cmp stderr want-stderr-10 22 43 23 44 -- cue.mod/module.cue -- 24 45 module: "main.org@v0" ··· 66 87 language: { 67 88 version: "v0.9.0-alpha.0" 68 89 } 90 + -- want-module-6 -- 91 + module: "othermain.org@v1" 92 + language: { 93 + version: "v0.9.2" 94 + } 95 + -- want-module-7 -- 96 + module: "othermain.org@v1" 97 + language: { 98 + version: "$CUE_LANGUAGE_VERSION" 99 + } 100 + -- want-stderr-8 -- 101 + invalid argument "v0.4.3" for "--language-version" flag: language version "v0.4.3" is too early for module.cue schema (earliest allowed is v0.8.0-alpha.0) 102 + -- want-stderr-9 -- 103 + invalid argument "v2.3.4" for "--language-version" flag: language version "v2.3.4" may not be after current language version $CUE_LANGUAGE_VERSION 104 + -- want-stderr-10 -- 105 + invalid resulting module.cue file after edits: cannot parse result: invalid module.cue file: source field is not allowed at this language version; need at least v0.9.0-alpha.0
+43
cmd/cue/cmd/testdata/script/modinit_with_explicit_version.txtar
··· 1 + # Check we can initialize the module with an explicit version. 2 + 3 + # Set current version. 4 + exec cue mod init --language-version current foo.example 5 + cmpenv cue.mod/module.cue want-module-1 6 + rm cue.mod 7 + 8 + # Set specific version. 9 + exec cue mod init --language-version v0.9.2 foo.example 10 + cmp cue.mod/module.cue want-module-2 11 + rm cue.mod 12 + 13 + # Set version earlier than earliest module schema version. 14 + ! exec cue mod init --language-version v0.4.3 foo.example 15 + cmp stderr want-stderr-3 16 + rm cue.mod 17 + 18 + # Set version too new. 19 + ! exec cue mod init --language-version v2.3.4 foo.example 20 + cmp stderr want-stderr-4 21 + rm cue.mod 22 + 23 + # Set version that's incompatible with the source field. 24 + ! exec cue mod init --language-version v0.8.0 --source self foo.example 25 + cmp stderr want-stderr-5 26 + rm cue.mod 27 + 28 + -- want-module-1 -- 29 + module: "foo.example" 30 + language: { 31 + version: "$CUE_LANGUAGE_VERSION" 32 + } 33 + -- want-module-2 -- 34 + module: "foo.example" 35 + language: { 36 + version: "v0.9.2" 37 + } 38 + -- want-stderr-3 -- 39 + language version "v0.4.3" is too early for module.cue schema (earliest allowed is v0.8.0-alpha.0) 40 + -- want-stderr-4 -- 41 + language version "v2.3.4" may not be after current language version v0.10.0 42 + -- want-stderr-5 -- 43 + cannot parse result: invalid module.cue file: source field is not allowed at this language version; need at least v0.9.0-alpha.0
+2 -3
cmd/cue/cmd/testdata/script/modinit_without_version.txtar
··· 1 1 # Check that cue mod init is independent of the module version; 2 2 # even though CUE's current module version will often be a v0 pseudo-version 3 3 # or a pre-release, we will always use the current language version in init. 4 - env-fill want-module 5 4 exec cue mod init foo.example 6 - cmp cue.mod/module.cue want-module 5 + cmpenv cue.mod/module.cue want-module 7 6 8 7 # cue mod tidy should be a no-op after cue mod init 9 8 exec cue mod tidy 10 - cmp cue.mod/module.cue want-module 9 + cmpenv cue.mod/module.cue want-module 11 10 12 11 -- want-module -- 13 12 module: "foo.example"
+2 -2
mod/modfile/modfile.go
··· 156 156 // before formatting the output. 157 157 f1, err := ParseNonStrict(data, "-") 158 158 if err != nil { 159 - return nil, fmt.Errorf("cannot round-trip module file: %v", strings.TrimSuffix(errors.Details(err, nil), "\n")) 159 + return nil, fmt.Errorf("cannot parse result: %v", strings.TrimSuffix(errors.Details(err, nil), "\n")) 160 160 } 161 161 if f.Language != nil && f1.actualSchemaVersion == "v0.0.0" { 162 162 // It's not a legacy module file (because the language field is present) ··· 363 363 } 364 364 f, err = ParseNonStrict(data, "fixed-"+filename) 365 365 if err != nil { 366 - return nil, fmt.Errorf("cannot round-trip fixed module file %q: %v", data, err) 366 + return nil, fmt.Errorf("cannot parse resulting module file %q: %v", data, err) 367 367 } 368 368 return f, nil 369 369 }
+2 -2
mod/modfile/modfile_test.go
··· 500 500 Version: "v0.4.3", 501 501 }, 502 502 }, 503 - wantError: `cannot round-trip module file: cannot find schema suitable for reading module file with language version "v0.4.3"`, 503 + wantError: `cannot parse result: cannot find schema suitable for reading module file with language version "v0.4.3"`, 504 504 }, { 505 505 name: "WithInvalidModuleVersion", 506 506 file: &File{ ··· 509 509 Version: "badversion--", 510 510 }, 511 511 }, 512 - wantError: `cannot round-trip module file: language version "badversion--" in module.cue is not valid semantic version`, 512 + wantError: `cannot parse result: language version "badversion--" in module.cue is not valid semantic version`, 513 513 }, { 514 514 name: "WithNonNilEmptyDeps", 515 515 file: &File{