Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Json schema command #74

Merged
merged 11 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.DEFAULT_GOAL:=help
-include .makerc

# --- Config -----------------------------------------------------------------

export PATH := bin:$(PATH)

# --- Targets -----------------------------------------------------------------

# This allows us to accept extra arguments
Expand All @@ -18,6 +22,11 @@

## === Tasks ===

.PHONY: brew
## Install project binaries
brew:
@ownbrew install

.PHONY: doc
## Run tests
doc:
Expand Down
2 changes: 1 addition & 1 deletion _examples/helloworld/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2.0'
version: '2.1'

squadron:
storefinder:
Expand Down
59 changes: 59 additions & 0 deletions _examples/kustomize/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.DEFAULT_GOAL:=help

export PROJECT_ROOT=$(PWD)

## === Tasks ===

.PHONY: list
## Show config
list:
@go run ../../cmd/main.go list

.PHONY: config
## Show config
config:
@go run ../../cmd/main.go config

.PHONY: build
## Show config
build:
@go run ../../cmd/main.go build

.PHONY: template
## Show config
template:
@go run ../../cmd/main.go template

## === Utils ===

## Show help text
help:
@awk '{ \
if ($$0 ~ /^.PHONY: [a-zA-Z\-\_0-9]+$$/) { \
helpCommand = substr($$0, index($$0, ":") + 2); \
if (helpMessage) { \
printf "\033[36m%-23s\033[0m %s\n", \
helpCommand, helpMessage; \
helpMessage = ""; \
} \
} else if ($$0 ~ /^[a-zA-Z\-\_0-9.]+:/) { \
helpCommand = substr($$0, 0, index($$0, ":")); \
if (helpMessage) { \
printf "\033[36m%-23s\033[0m %s\n", \
helpCommand, helpMessage"\n"; \
helpMessage = ""; \
} \
} else if ($$0 ~ /^##/) { \
if (helpMessage) { \
helpMessage = helpMessage"\n "substr($$0, 3); \
} else { \
helpMessage = substr($$0, 3); \
} \
} else { \
if (helpMessage) { \
print "\n "helpMessage"\n" \
} \
helpMessage = ""; \
} \
}' \
$(MAKEFILE_LIST)
3 changes: 3 additions & 0 deletions _examples/kustomize/app/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/foomo/squadron/exmpale/kustomize

go 1.21
21 changes: 21 additions & 0 deletions _examples/kustomize/app/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import (
"flag"
"log"
"net/http"
)

func main() {
flagAddress := flag.String("address", ":80", "address to listen to ")
flagGreeting := flag.String("greeting", "HELLO", "sets the greeting message")
flag.Parse()

greeting := []byte(*flagGreeting)

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(greeting)
})

log.Fatal(http.ListenAndServe(*flagAddress, handler))
}
3 changes: 3 additions & 0 deletions _examples/kustomize/kustomize/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resources:
- .chart.yaml # will be auto generated
- serviceaccount.yaml
4 changes: 4 additions & 0 deletions _examples/kustomize/kustomize/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kustomize-demo
20 changes: 20 additions & 0 deletions _examples/kustomize/squadron.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '2.1'

squadron:
storefinder:
backend:
chart: <% env "PROJECT_ROOT" %>/../common/charts/backend
kustomize: <% env "PROJECT_ROOT" %>/kustomize
builds:
default:
tag: latest
context: <% env "PROJECT_ROOT" %>/app
dockerfile: <% env "PROJECT_ROOT" %>/../common/docker/backend.Dockerfile
image: kustomize/app
values:
image:
tag: <% .Squadron.storefinder.backend.builds.default.tag | quote %>
repository: <% .Squadron.storefinder.backend.builds.default.image %>
service:
ports:
- 80
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.0'
version: '2.1'

squadron:
checkout:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.0'
version: '2.1'

squadron:
checkout:
Expand Down
2 changes: 1 addition & 1 deletion _examples/monorepo/squadrons/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2.0'
version: '2.1'

global:
docker:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.0'
version: '2.1'

squadron:
storefinder:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.0'
version: '2.1'

squadron:
storefinder:
Expand Down
2 changes: 1 addition & 1 deletion cmd/actions/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&flagVerbose, "verbose", "v", false, "show more output")
rootCmd.PersistentFlags().StringSliceVarP(&flagFiles, "file", "f", []string{"squadron.yaml"}, "specify alternative squadron files")

rootCmd.AddCommand(upCmd, diffCmd, downCmd, buildCmd, pushCmd, listCmd, rollbackCmd, statusCmd, configCmd, versionCmd, completionCmd, templateCmd, postRendererCmd)
rootCmd.AddCommand(upCmd, diffCmd, downCmd, buildCmd, pushCmd, listCmd, rollbackCmd, statusCmd, configCmd, versionCmd, completionCmd, templateCmd, postRendererCmd, schemaCmd)

pterm.Info = *pterm.Info.WithPrefix(pterm.Prefix{Text: "⎈", Style: pterm.Info.Prefix.Style})
pterm.Debug = *pterm.Debug.WithPrefix(pterm.Prefix{Text: "⚒︎", Style: pterm.Debug.Prefix.Style})
Expand Down
58 changes: 58 additions & 0 deletions cmd/actions/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package actions

import (
"fmt"
"os"

"github.com/foomo/squadron"
"github.com/foomo/squadron/internal/util"
"github.com/pkg/errors"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
)

var (
flagOutput string
flagBaseSchema string
)

func init() {
schemaCmd.Flags().StringVar(&flagOutput, "output", "", "Output file")
schemaCmd.Flags().StringVar(&flagBaseSchema, "base-schema", "https://raw.githubusercontent.com/foomo/squadron/refs/heads/main/squadron.schema.json", "Base schema to use")
schemaCmd.Flags().StringSliceVar(&flagTags, "tags", nil, "list of tags to include or exclude (can specify multiple or separate values with commas: tag1,tag2,-tag3)")
}

var schemaCmd = &cobra.Command{
Use: "schema [SQUADRON]",
Short: "generate squadron json schema",
Example: " squadron schema",
Args: cobra.MinimumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
sq := squadron.New(cwd, "", flagFiles)

if err := sq.MergeConfigFiles(cmd.Context()); err != nil {
return errors.Wrap(err, "failed to merge config files")
}

squadronName, unitNames := parseSquadronAndUnitNames(args)
if err := sq.FilterConfig(cmd.Context(), squadronName, unitNames, flagTags); err != nil {
return errors.Wrap(err, "failed to filter config")
}

js, err := sq.RenderSchema(cmd.Context(), flagBaseSchema)
if err != nil {
return errors.Wrap(err, "failed to render schema")
}

if flagOutput != "" {
pterm.Info.Printfln("Writing JSON schema to %s", flagOutput)
if err := os.WriteFile(flagOutput, []byte(js), 0600); err != nil {
return errors.Wrap(err, "failed to write schema")
}
} else {
fmt.Print(util.Highlight(js))
}

return nil
},
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/foomo/squadron

go 1.23.1
go 1.23.2

replace github.com/miracl/conflate v1.2.1 => github.com/runz0rd/conflate v1.2.2-0.20210920145208-fa48576ef06d

Expand All @@ -12,6 +12,7 @@ require (
github.com/foomo/go v0.0.3
github.com/invopop/jsonschema v0.12.0
github.com/miracl/conflate v1.2.1
github.com/p12se/merger-json-schemas v0.0.0-20230809180605-04bf9b969093
github.com/pkg/errors v0.9.1
github.com/pterm/pterm v0.12.79
github.com/sirupsen/logrus v1.9.3
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand All @@ -128,6 +129,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/p12se/merger-json-schemas v0.0.0-20230809180605-04bf9b969093 h1:QE4z8zBUOzzrGIqnBQXV0DPK3shFxwr9+KW3gBRXYk8=
github.com/p12se/merger-json-schemas v0.0.0-20230809180605-04bf9b969093/go.mod h1:VTS5z9nhfJOEcPwIJQbLp/qzO+XABmfCdINUtjmjHJw=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down
4 changes: 3 additions & 1 deletion internal/config/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

type Build struct {
// Build context
Context string `json:"context,omitempty" yaml:"context,omitempty"`
// AddHost add a custom host-to-IP mapping (format: "host:ip")
AddHost []string `json:"add_host,omitempty" yaml:"add_host,omitempty"`
Expand Down Expand Up @@ -58,7 +59,8 @@ type Build struct {
// SSH agent socket or keys to expose to the build (format: "default|<id>[=<socket>|<key>[,<key>]]")
SSH string `json:"ssh,omitempty" yaml:"ssh,omitempty"`
// Tag name and optionally a tag (format: "name:tag")
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
// Image name
Image string `json:"image,omitempty" yaml:"image,omitempty"`
// Target set the target build stage to build
Target string `json:"target,omitempty" yaml:"target,omitempty"`
Expand Down
25 changes: 22 additions & 3 deletions internal/config/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@ import (
"fmt"
"os"
"path"
"path/filepath"

"github.com/foomo/squadron/internal/template"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)

type Chart struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Chart name
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Chart repository
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
Alias string `json:"alias,omitempty" yaml:"alias,omitempty"`
// Values schema json
Schema string `json:"schema,omitempty" yaml:"schema,omitempty"`
// Chart version
Version string `json:"version,omitempty" yaml:"version,omitempty"`
// Chart alias
Alias string `json:"alias,omitempty" yaml:"alias,omitempty"`
}

func (d *Chart) UnmarshalYAML(value *yaml.Node) error {
Expand All @@ -39,6 +46,18 @@ func (d *Chart) UnmarshalYAML(value *yaml.Node) error {
d.Name = localChart.Name
d.Repository = fmt.Sprintf("file://%v", vString)
d.Version = localChart.Version
wd, err := os.Getwd()
if err != nil {
return errors.Wrap(err, "failed to get working directory")
}
schemaPath := string(vBytes)
if value, err := filepath.Rel(wd, string(vBytes)); err == nil {
schemaPath = value
}

if _, err := os.Stat(path.Join(schemaPath, "values.schema.json")); err == nil {
d.Schema = path.Join(schemaPath, "values.schema.json")
}
return nil
default:
return fmt.Errorf("unsupported node tag type for %T: %q", d, value.Tag)
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

type Config struct {
// Version of the schema
Version string `json:"version,omitempty" yaml:"version,omitempty" jsonschema:"required"`
Version string `json:"version,omitempty" yaml:"version,omitempty" jsonschema:"pattern=^[0-9]\\.[0-9]$,required"`
// Global values to be injected into all squadron values
Vars map[string]any `json:"vars,omitempty" yaml:"vars,omitempty"`
// Global values to be injected into all squadron values
Expand Down
34 changes: 0 additions & 34 deletions internal/config/config_test.go

This file was deleted.

Loading