...
1// Copyright 2023 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// This schema constrains a module.cue file. This form constrains module.cue files
16// outside of the main module. For the module.cue file in a main module, the schema
17// is less restrictive, because wherever #Semver is used, a less specific version may be
18// used instead, which will be rewritten to the canonical form by the cue command tooling.
19// To check against that form,
20
21// Note: we're using 1&2 rather than _|_ because
22// use of _|_ causes the source location of the errors
23// to be lost. See https://github.com/cue-lang/cue/issues/2319.
24let unimplemented = 1&2
25
26
27// #File represents the overarching module file schema.
28#File: {
29 // Reserve fields that are unimplemented for now.
30 {
31 deprecated?: unimplemented
32 retract?: unimplemented
33 publish?: unimplemented
34 #Dep: {
35 exclude?: unimplemented
36 replace?: unimplemented
37 replaceAll?: unimplemented
38 }
39 }
40 // module indicates the module's path.
41 module?: #Module | ""
42
43 // version indicates the language version used by the code
44 // in this module - the minimum version of CUE required
45 // to evaluate the code in this module. When a later version of CUE
46 // is evaluating code in this module, this will be used to
47 // choose version-specific behavior. If an earlier version of CUE
48 // is used, an error will be given.
49 language?: version?: #Semver
50
51 // description describes the purpose of this module.
52 description?: string
53
54 // When present, deprecated indicates that the module
55 // is deprecated and includes information about that deprecation, ideally
56 // mentioning an alternative that can be used instead.
57 // TODO implement this.
58 deprecated?: string
59
60 // deps holds dependency information for modules, keyed by module path.
61 deps?: [#Module]: #Dep
62
63 #Dep: {
64 // TODO use the below when mustexist is implemented.
65 // replace and replaceAll are mutually exclusive.
66 //mustexist(<=1, replace, replaceAll)
67 // There must be at least one field specified for a given module.
68 //mustexist(>=1, v, exclude, replace, replaceAll)
69
70 // v indicates the minimum required version of the module.
71 // This can be null if the version is unknown and the module
72 // entry is only present to be replaced.
73 v!: #Semver | null
74
75 // default indicates this module is used as a default in case
76 // more than one major version is specified for the same module
77 // path. Imports must specify the exact major version for a
78 // module path if there is more than one major version for that
79 // path and default is not set for exactly one of them.
80 // TODO implement this.
81 default?: bool
82
83 // exclude excludes a set of versions of the module
84 // TODO implement this.
85 exclude?: [#Semver]: true
86
87 // replace specifies replacements for specific versions of
88 // the module. This field is exclusive with replaceAll.
89 // TODO implement this.
90 replace?: [#Semver]: #Replacement
91
92 // replaceAll specifies a replacement for all versions of the module.
93 // This field is exclusive with replace.
94 // TODO implement this.
95 replaceAll?: #Replacement
96 }
97
98 // retract specifies a set of previously published versions to retract.
99 // TODO implement this.
100 retract?: [... #RetractedVersion]
101
102 // The publish section can be used to restrict the scope of a module to prevent
103 // accidental publishing.
104 // TODO complete the definition of this and implement it.
105 publish?: _
106
107 // #RetractedVersion specifies either a single version
108 // to retract, or an inclusive range of versions to retract.
109 #RetractedVersion: #Semver | {
110 from!: #Semver
111 // TODO constrain to to be after from?
112 to!: #Semver
113 }
114
115 // #Replacement specifies a replacement for a module. It can either
116 // be a reference to a local directory or an alternative module with associated
117 // version.
118 #Replacement: string | {
119 m!: #Module
120 v!: #Semver
121 }
122
123 // #Module constrains a module path.
124 // The major version indicator is optional, but should always be present
125 // in a normalized module.cue file.
126 #Module: string
127
128 // #Semver constrains a semantic version.
129 #Semver: =~"."
130}
131
132// _#Strict can be unified with the top level schema to enforce the strict version
133// of the schema required by the registry.
134#Strict: #File & {
135 // This regular expression is taken from https://semver.org/spec/v2.0.0.html
136 #Semver: =~#"^v(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"#
137
138 // WIP: (([\-_~a-zA-Z0-9][.\-_~a-zA-Z0-9]*[\-_~a-zA-Z0-9])|([\-_~a-zA-Z0-9]))(/([\-_~a-zA-Z0-9][.\-_~a-zA-Z0-9]*[\-_~a-zA-Z0-9])|([\-_~a-zA-Z0-9]))*
139 #Module: =~#"^[^@]+(@v(0|[1-9]\d*))$"#
140
141 // We don't yet implement local file replacement (specified as a string)
142 // so require a struct, thus allowing only replacement by some other module.
143 #Replacement: {...}
144
145 // The module declaration is required.
146 module!: #Module
147
148 // No null versions, because no replacements yet.
149 #Dep: v!: #Semver
150
151 // TODO require the CUE version?
152 // language!: version!: _
153}
View as plain text