diff --git a/README.md b/README.md index 596b6989..4221a4db 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ individual files as well as packaged in [CSAR files](https://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.3/TOSCA-Simple-Profile-YAML-v1.3.html#_Toc302251718). Puccini also comes with a simple CSAR creation tool that can be used independently of the -other tools, [`puccini-csar`](puccini-csar/). +other tools, [`puccini-csar`](executables/puccini-csar/). ### Design Principles diff --git a/executables/puccini-clout/default.pgo b/executables/puccini-clout/default.pgo index 85fc7b56..bcc884f2 100644 Binary files a/executables/puccini-clout/default.pgo and b/executables/puccini-clout/default.pgo differ diff --git a/executables/puccini-csar/default.pgo b/executables/puccini-csar/default.pgo index 6df92314..c4f65ff0 100644 Binary files a/executables/puccini-csar/default.pgo and b/executables/puccini-csar/default.pgo differ diff --git a/executables/puccini-tosca/README.md b/executables/puccini-tosca/README.md index 4ae82dfe..92b1a4da 100644 --- a/executables/puccini-tosca/README.md +++ b/executables/puccini-tosca/README.md @@ -40,6 +40,20 @@ The list of supported quirks is maintained [here](../tosca/parsing/QUIRKS.md). See the [tutorial](../TUTORIAL.md) for more detail. +`validate` +---------- + +Equivalent to `compile` but without Clout output. Will print "valid" to stderr if valid, otherwise +will print the problems. Use `--quiet` to suppress all output. + +Note that both `validate` and `compile` set the exit code: 0 for valid, 1 if there are problems, which +is useful in scripts: + + if puccini-tosca validate service.yaml --quiet; then + deploy servicel + fi + + `parse` ------- diff --git a/executables/puccini-tosca/commands/compile.go b/executables/puccini-tosca/commands/compile.go index 322d419b..6c4d4583 100644 --- a/executables/puccini-tosca/commands/compile.go +++ b/executables/puccini-tosca/commands/compile.go @@ -12,11 +12,12 @@ import ( ) var ( - output string - resolve bool - coerce bool - exec string - arguments map[string]string + enableOutput bool + output string + resolve bool + coerce bool + exec string + arguments map[string]string ) func init() { @@ -47,6 +48,7 @@ var compileCommand = &cobra.Command{ url = args[0] } + enableOutput = true dumpPhases = nil Compile(contextpkg.TODO(), url) }, @@ -87,7 +89,7 @@ func Compile(context contextpkg.Context, url string) { if exec != "" { err = Exec(context, exec, arguments, clout, urlContext) util.FailOnError(err) - } else if !terminal.Quiet || (output != "") { + } else if enableOutput && (!terminal.Quiet || (output != "")) { err = Transcriber().Write(clout) util.FailOnError(err) } diff --git a/executables/puccini-tosca/commands/validate.go b/executables/puccini-tosca/commands/validate.go new file mode 100644 index 00000000..e18e17cf --- /dev/null +++ b/executables/puccini-tosca/commands/validate.go @@ -0,0 +1,41 @@ +package commands + +import ( + contextpkg "context" + + "github.com/spf13/cobra" + "github.com/tliron/kutil/terminal" +) + +func init() { + rootCommand.AddCommand(validateCommand) + validateCommand.Flags().StringSliceVarP(&importPaths, "path", "b", nil, "specify an import path or base URL") + validateCommand.Flags().StringVarP(&template, "template", "t", "", "select service template in CSAR (leave empty for root, or use \"all\", path, or integer index)") + validateCommand.Flags().StringToStringVarP(&inputs, "input", "i", nil, "specify input (format is name=value)") + validateCommand.Flags().StringVarP(&inputsUrl, "inputs", "n", "", "load inputs from a PATH or URL to YAML content") + validateCommand.Flags().StringVarP(&problemsFormat, "problems-format", "m", "", "problems format (\"yaml\", \"json\", \"xjson\", \"xml\", \"cbor\", \"messagepack\", or \"go\")") + validateCommand.Flags().StringSliceVarP(&quirks, "quirk", "x", nil, "parser quirk") + validateCommand.Flags().StringToStringVarP(&urlMappings, "map-url", "u", nil, "map a URL (format is from=to)") + + validateCommand.Flags().BoolVarP(&resolve, "resolve", "r", true, "resolves the topology (attempts to satisfy all requirements with capabilities)") + validateCommand.Flags().BoolVarP(&coerce, "coerce", "c", false, "coerces all values (calls functions and applies constraints)") +} + +var validateCommand = &cobra.Command{ + Use: "validate [[TOSCA PATH or URL]]", + Short: "Validate TOSCA", + Long: `Validates TOSCA service templates. Equivalent to "compile" without the Clout output.`, + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + var url string + if len(args) == 1 { + url = args[0] + } + + dumpPhases = nil + Compile(contextpkg.TODO(), url) + if !terminal.Quiet { + terminal.Eprintln("valid") + } + }, +} diff --git a/executables/puccini-tosca/default.pgo b/executables/puccini-tosca/default.pgo index 48571789..58156c5c 100644 Binary files a/executables/puccini-tosca/default.pgo and b/executables/puccini-tosca/default.pgo differ diff --git a/go.mod b/go.mod index 432423dc..bf1410da 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/tliron/puccini go 1.23 require ( - github.com/dop251/goja v0.0.0-20240806095544-3491d4a58fbe + github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 github.com/fxamacker/cbor/v2 v2.7.0 github.com/klauspost/compress v1.17.9 github.com/klauspost/pgzip v1.2.6 @@ -25,13 +25,13 @@ require ( github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beevik/etree v1.3.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect - github.com/docker/cli v24.0.0+incompatible // indirect + github.com/docker/cli v24.0.9+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.0+incompatible // indirect + github.com/docker/docker v25.0.6+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/color v1.16.0 // indirect diff --git a/go.sum b/go.sum index 7c6ceda6..20007cde 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -15,8 +17,9 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ github.com/beevik/etree v1.3.0 h1:hQTc+pylzIKDb23yYprodCWWTt+ojFfUZyzU09a/hmU= github.com/beevik/etree v1.3.0/go.mod h1:aiPf89g/1k3AShMVAzriilpcE4R/Vuor90y83zVZWFc= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -29,16 +32,16 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM= -github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+LkwYQisD50= +github.com/docker/cli v24.0.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.0+incompatible h1:z4bf8HvONXX9Tde5lGBMQ7yCJgNahmJumdrStZAbeY4= -github.com/docker/docker v24.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/dop251/goja v0.0.0-20240806095544-3491d4a58fbe h1:jwFJkgsdelB87ohlXaAGSd05Cb5ALDFa9iW9IGRHcRM= -github.com/dop251/goja v0.0.0-20240806095544-3491d4a58fbe/go.mod h1:DF+w/nLMIkvRpyhd/0K+Okbh3fVZBtXLwRtS/ccAa5w= +github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 h1:YIxvsQAoCLGScK2c9ag+4sFCgiQFpMzywJG6dQZFu9k= +github.com/dop251/goja v0.0.0-20240828124009-016eb7256539/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= diff --git a/library/default.pgo b/library/default.pgo index 48571789..58156c5c 100644 Binary files a/library/default.pgo and b/library/default.pgo differ diff --git a/scripts/generate-pgo b/scripts/generate-pgo index 3e30052a..4e8a3394 100755 --- a/scripts/generate-pgo +++ b/scripts/generate-pgo @@ -6,10 +6,10 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") EXECUTABLES=$ROOT/executables -rm --force "$EXECUTABLES/puccini-tosca/default.pgo" -rm --force "$EXECUTABLES/puccini-clout/default.pgo" -rm --force "$EXECUTABLES/puccini-csar/default.pgo" -rm --force "$ROOT/library/default.pgo" +rm --force "$EXECUTABLES/puccini-tosca"/*.pgo +rm --force "$EXECUTABLES/puccini-clout"/*.pgo +rm --force "$EXECUTABLES/puccini-csar"/*.pgo +rm --force "$ROOT/library"/*.pgo "$HERE/build" diff --git a/tosca/parsing/QUIRKS.md b/tosca/parsing/QUIRKS.md index c87bfab6..9a576a76 100644 --- a/tosca/parsing/QUIRKS.md +++ b/tosca/parsing/QUIRKS.md @@ -2,7 +2,7 @@ Puccini TOSCA Quirks ==================== These are activated via the `--quirk/-x` switch for -[**puccini-tosca**](../../puccini-tosca/): +[**puccini-tosca**](../../executables/puccini-tosca/): * **imports.implicit.disable**: In TOSCA 1.0-1.3 the Simple Profile is implicitly imported by default. This quirk will disable implicit imports. @@ -36,10 +36,10 @@ These are activated via the `--quirk/-x` switch for * **namespace.normative.shortcuts.disable**: In TOSCA 1.0-1.3 all the normative types have long names, such as "tosca.nodes.Compute", prefixed names ("tosca:Compute"), and also short names - ("Compute"). Those short names are annoying because it means you can't use those names for your - own types. This quirk disables the short names (the prefixed names remain). + ("Compute"). Those short names might be annoying because it means you can't use those names for + your own types. This quirk disables the short names (the prefixed names remain). -* **substitution_mappings.requirements.list**: According to the examples in the TOSCA 1.0-1.3 specs, +* **substitution_mappings.requirements.list**: According to the examples in the TOSCA 1.0-2.0 specs, the `requirements` key under `substitution_mappings` is syntactically a map. However, this syntax is inconsistent because it doesn't match the syntax in node templates, which is a sequenced list. (In node types, too, it is a sequenced list, although grammatically it works like a map.) This diff --git a/tosca/parsing/quirks.go b/tosca/parsing/quirks.go index 1103cdfb..369a509f 100755 --- a/tosca/parsing/quirks.go +++ b/tosca/parsing/quirks.go @@ -50,8 +50,8 @@ const ( // In TOSCA 1.0-1.3 all the normative types have long // names, such as "tosca.nodes.Compute", prefixed names ("tosca:Compute"), and also short names - // ("Compute"). Those short names are annoying because it means you can't use those names for your - // own types. This quirk disables the short names (the prefixed names remain). + // ("Compute"). Those short names might be annoying because it means you can't use those names for + // your own types. This quirk disables the short names (the prefixed names remain). QuirkNamespaceNormativeShortcutsDisable Quirk = "namespace.normative.shortcuts.disable" // According to the examples in the TOSCA 1.0-1.3 specs,