diff --git a/.github/workflows/branch.yaml b/.github/workflows/branch.yaml index 9695e359..77df57c5 100644 --- a/.github/workflows/branch.yaml +++ b/.github/workflows/branch.yaml @@ -11,7 +11,7 @@ permissions: jobs: build: name: Build simple-container in branch - runs-on: self-hosted + runs-on: blacksmith-8vcpu-ubuntu-2204 outputs: cicd-bot-telegram-token: ${{ steps.prepare-secrets.outputs.cicd-bot-telegram-token }} cicd-bot-telegram-chat-id: ${{ steps.prepare-secrets.outputs.cicd-bot-telegram-chat-id }} @@ -42,7 +42,7 @@ jobs: finalize: name: Finalize build in branch - runs-on: self-hosted + runs-on: blacksmith-2vcpu-ubuntu-2204 if: ${{ always() }} permissions: contents: write diff --git a/go.mod b/go.mod index 3ab1d05f..c9f746c8 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,8 @@ require ( github.com/spf13/afero v1.12.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 - github.com/vektra/mockery/v2 v2.52.2 + github.com/tkrajina/typescriptify-golang-structs v0.2.0 + github.com/vektra/mockery/v2 v2.52.3 go.uber.org/atomic v1.11.0 golang.org/x/crypto v0.33.0 golang.org/x/oauth2 v0.25.0 diff --git a/go.sum b/go.sum index fe705ee4..55dfc045 100644 --- a/go.sum +++ b/go.sum @@ -1572,6 +1572,9 @@ github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyP github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= github.com/timonwong/loggercheck v0.10.1 h1:uVZYClxQFpw55eh+PIoqM7uAOHMrhVcDoWDery9R8Lg= github.com/timonwong/loggercheck v0.10.1/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8= +github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= +github.com/tkrajina/typescriptify-golang-structs v0.2.0 h1:ZedWk82egydDspGTryAatbX0/1NZDQbdiZLoCbOk4f8= +github.com/tkrajina/typescriptify-golang-structs v0.2.0/go.mod h1:sjU00nti/PMEOZb07KljFlR+lJ+RotsC0GBQMv9EKls= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck/v2 v2.10.0 h1:SzRCryzy4IrAH7bVGG4cK40tNUhmVmMDuJujy4XwYDg= @@ -1602,8 +1605,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= -github.com/vektra/mockery/v2 v2.52.2 h1:8QfPKUIrq8P3Cs7G79Iu4Byd5wdhGCE0quIS27x7rQo= -github.com/vektra/mockery/v2 v2.52.2/go.mod h1:zGDY/f6bip0Yh13GQ5j7xa43fuEoYBa4ICHEaihisHw= +github.com/vektra/mockery/v2 v2.52.3 h1:lInrh+OuJu3dY/UPFvdFmJ/lsscEnUFrTmagcRJKoWU= +github.com/vektra/mockery/v2 v2.52.3/go.mod h1:zGDY/f6bip0Yh13GQ5j7xa43fuEoYBa4ICHEaihisHw= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= diff --git a/pkg/api/config.go b/pkg/api/config.go index f8761ef8..25c7d966 100644 --- a/pkg/api/config.go +++ b/pkg/api/config.go @@ -8,6 +8,8 @@ import ( "gopkg.in/yaml.v3" "github.com/pkg/errors" + + "github.com/simple-container-com/api/pkg/api/config" ) const ( @@ -38,7 +40,7 @@ type InitParams struct { GenerateKeyPair bool `json:"generateKeyPair" yaml:"generateKeyPair"` } -func ReadConfigFile(workDir, profile string) (*ConfigFile, error) { +func ReadConfigFile(reader config.Reader, workDir, profile string) (*ConfigFile, error) { configFromEnv := os.Getenv(ScConfigEnvVariable) if configFromEnv != "" { if res, err := UnmarshalDescriptor[ConfigFile]([]byte(configFromEnv)); err != nil { @@ -47,7 +49,7 @@ func ReadConfigFile(workDir, profile string) (*ConfigFile, error) { return res, nil } } - res, err := ReadDescriptor(ConfigFilePath(workDir, profile), &ConfigFile{}) + res, err := ReadDescriptor(reader, ConfigFilePath(workDir, profile), &ConfigFile{}) if err != nil { return nil, errors.Wrapf(err, "profile does not exist: %q", profile) } diff --git a/pkg/api/config/reader.go b/pkg/api/config/reader.go new file mode 100644 index 00000000..1ac293ea --- /dev/null +++ b/pkg/api/config/reader.go @@ -0,0 +1,34 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +type Reader interface { + ReadFile(path string) ([]byte, error) +} + +type fileSystemReader struct{} + +func (r *fileSystemReader) ReadFile(path string) ([]byte, error) { + return os.ReadFile(path) +} + +var FSReader = &fileSystemReader{} + +type InlineConfigReader struct { + WorkDir string + Configs map[string]string +} + +func (r *InlineConfigReader) ReadFile(path string) ([]byte, error) { + path = strings.TrimPrefix(path, fmt.Sprintf("%s%c", r.WorkDir, filepath.Separator)) + if val, ok := r.Configs[path]; ok { + return []byte(val), nil + } else { + return nil, os.ErrNotExist + } +} diff --git a/pkg/api/read.go b/pkg/api/read.go index 71a7ab6f..3988e52b 100644 --- a/pkg/api/read.go +++ b/pkg/api/read.go @@ -1,11 +1,11 @@ package api import ( - "os" - "gopkg.in/yaml.v3" "github.com/pkg/errors" + + "github.com/simple-container-com/api/pkg/api/config" ) const ( @@ -14,8 +14,8 @@ const ( ClientDescriptorFileName = "client.yaml" ) -func ReadDescriptor[T any](filePath string, descriptor *T) (*T, error) { - fileBytes, err := os.ReadFile(filePath) +func ReadDescriptor[T any](reader config.Reader, filePath string, descriptor *T) (*T, error) { + fileBytes, err := reader.ReadFile(filePath) if err != nil { return nil, errors.Wrapf(err, "failed to read %s", filePath) } @@ -40,8 +40,8 @@ func UnmarshalDescriptor[T any](bytes []byte) (*T, error) { return &descriptor, nil } -func ReadServerDescriptor(path string) (*ServerDescriptor, error) { - descriptor, err := ReadDescriptor(path, &ServerDescriptor{}) +func ReadServerDescriptor(reader config.Reader, path string) (*ServerDescriptor, error) { + descriptor, err := ReadDescriptor(reader, path, &ServerDescriptor{}) if err != nil { return descriptor, errors.Wrapf(err, "failed to read server descriptor from %q", path) } @@ -53,8 +53,8 @@ func ReadServerDescriptor(path string) (*ServerDescriptor, error) { return res, nil } -func ReadSecretsDescriptor(path string) (*SecretsDescriptor, error) { - descriptor, err := ReadDescriptor(path, &SecretsDescriptor{}) +func ReadSecretsDescriptor(reader config.Reader, path string) (*SecretsDescriptor, error) { + descriptor, err := ReadDescriptor(reader, path, &SecretsDescriptor{}) if err != nil { return nil, err } @@ -66,8 +66,8 @@ func ReadSecretsDescriptor(path string) (*SecretsDescriptor, error) { return res, nil } -func ReadClientDescriptor(path string) (*ClientDescriptor, error) { - descriptor, err := ReadDescriptor(path, &ClientDescriptor{}) +func ReadClientDescriptor(reader config.Reader, path string) (*ClientDescriptor, error) { + descriptor, err := ReadDescriptor(reader, path, &ClientDescriptor{}) if err != nil { return descriptor, errors.Wrapf(err, "failed to unmarshal %s", path) } diff --git a/pkg/api/secrets/cryptor.go b/pkg/api/secrets/cryptor.go index 0f8ddd1b..aad006af 100644 --- a/pkg/api/secrets/cryptor.go +++ b/pkg/api/secrets/cryptor.go @@ -5,6 +5,7 @@ import ( "github.com/samber/lo" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/git" "github.com/simple-container-com/welder/pkg/util" ) @@ -37,9 +38,10 @@ type Cryptor interface { } type cryptor struct { - workDir string - projectName string - profile string + configReader config.Reader + workDir string + projectName string + profile string options []Option diff --git a/pkg/api/secrets/cryptor_test.go b/pkg/api/secrets/cryptor_test.go index 29f519f6..bd691120 100644 --- a/pkg/api/secrets/cryptor_test.go +++ b/pkg/api/secrets/cryptor_test.go @@ -9,12 +9,24 @@ import ( . "github.com/onsi/gomega" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/git" "github.com/simple-container-com/api/pkg/api/secrets/ciphers" "github.com/simple-container-com/api/pkg/api/tests/testutil" "github.com/simple-container-com/welder/pkg/util/test" ) +func withInlineConfigReader(reader *config.InlineConfigReader) Option { + return Option{ + beforeInit: true, + f: func(c *cryptor) error { + reader.WorkDir = c.workDir + opt := WithConfigReader(reader) + return opt.f(c) + }, + } +} + func withGitDir(gitDir string) Option { return Option{ beforeInit: true, @@ -37,6 +49,9 @@ type mocks struct { func TestNewCryptor(t *testing.T) { RegisterTestingT(t) + cfgKeyInline, err := os.ReadFile("testdata/repo/.sc/cfg.local-key-inline.yaml") + Expect(err).To(BeNil()) + cases := []struct { name string testExampleDir string @@ -86,6 +101,28 @@ func TestNewCryptor(t *testing.T) { prepareMocks: acceptAllChanges, actions: happyPathScenario, }, + { + name: "happy path with custom config reader", + testExampleDir: "testdata/repo", + opts: []Option{ + withGitDir("gitdir"), + withInlineConfigReader(&config.InlineConfigReader{ + Configs: map[string]string{ + "stacks/common/secrets.yaml": "blabla", + ".sc/cfg.default.yaml": string(cfgKeyInline), + }, + }), + WithProfile("default"), + WithKeysFromCurrentProfile(), + }, + prepareMocks: acceptAllChanges, + actions: func(t *testing.T, c Cryptor, m *mocks, wd string) { + Expect(c.AddFile("stacks/common/secrets.yaml")).To(BeNil()) + Expect(c.EncryptChanged(true, false)).To(BeNil()) + err := c.DecryptAll(false) + Expect(err).To(BeNil()) + }, + }, { name: "happy path with invalid passphrase from console", testExampleDir: "testdata/repo", @@ -140,7 +177,7 @@ func TestNewCryptor(t *testing.T) { prepareMocks: acceptAllChanges, actions: func(t *testing.T, c Cryptor, m *mocks, wd string) { happyPathScenario(t, c, m, wd) - cfg, err := api.ReadConfigFile(wd, "test-profile") + cfg, err := api.ReadConfigFile(config.FSReader, wd, "test-profile") Expect(err).To(BeNil()) Expect(cfg.PrivateKey).To(ContainSubstring(c.PrivateKey())) Expect(cfg.PublicKey).To(ContainSubstring(c.PublicKey())) diff --git a/pkg/api/secrets/management.go b/pkg/api/secrets/management.go index b50dcd68..c23d3d7e 100644 --- a/pkg/api/secrets/management.go +++ b/pkg/api/secrets/management.go @@ -16,6 +16,7 @@ import ( "github.com/samber/lo" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/logger/color" "github.com/simple-container-com/api/pkg/api/secrets/ciphers" "github.com/simple-container-com/welder/pkg/util" @@ -459,6 +460,9 @@ func (c *cryptor) decryptSecretDataToFile(encryptedData []string, relFilePath st } func (c *cryptor) initData() error { + if c.configReader == nil { + c.configReader = config.FSReader + } if c.secrets.Secrets == nil { c.secrets.Secrets = make(map[string]EncryptedSecrets, 0) } diff --git a/pkg/api/secrets/opts.go b/pkg/api/secrets/opts.go index 9dba5265..e429f2a8 100644 --- a/pkg/api/secrets/opts.go +++ b/pkg/api/secrets/opts.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/git" "github.com/simple-container-com/welder/pkg/util" ) @@ -111,6 +112,16 @@ func WithGeneratedKeys(projectName, profile string) Option { } } +func WithConfigReader(reader config.Reader) Option { + return Option{ + beforeInit: true, + f: func(c *cryptor) error { + c.configReader = reader + return nil + }, + } +} + func WithKeysFromScConfig(profile string) Option { return Option{ f: func(c *cryptor) error { @@ -121,7 +132,11 @@ func WithKeysFromScConfig(profile string) Option { return errors.Errorf("profile is not configured") } c.profile = profile - cfg, err := api.ReadConfigFile(c.workDir, c.profile) + cfgReader := c.configReader + if c.configReader == nil { + cfgReader = config.FSReader + } + cfg, err := api.ReadConfigFile(cfgReader, c.workDir, c.profile) if err != nil { return err } diff --git a/pkg/api/tests/refapp_test.go b/pkg/api/tests/refapp_test.go index 10e3eaeb..7b9b965c 100644 --- a/pkg/api/tests/refapp_test.go +++ b/pkg/api/tests/refapp_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" ) func TestReadServerDescriptor(t *testing.T) { @@ -45,7 +46,7 @@ func TestReadServerDescriptor(t *testing.T) { } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) { - got, err := api.ReadServerDescriptor(tt.path) + got, err := api.ReadServerDescriptor(config.FSReader, tt.path) Expect(err).To(BeNil()) actual := got.ValuesOnly() @@ -77,7 +78,7 @@ func TestReadSecretsDescriptor(t *testing.T) { } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) { - got, err := api.ReadSecretsDescriptor(tt.path) + got, err := api.ReadSecretsDescriptor(config.FSReader, tt.path) Expect(err).To(BeNil()) assert.EqualValuesf(t, tt.want, got, "%v failed", tt.path) @@ -109,7 +110,7 @@ func TestReadClientDescriptor(t *testing.T) { } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) { - got, err := api.ReadClientDescriptor(tt.path) + got, err := api.ReadClientDescriptor(config.FSReader, tt.path) Expect(err).To(BeNil()) assert.EqualValuesf(t, tt.want.Copy(), got.Copy(), "%v failed", tt.path) diff --git a/pkg/clouds/pulumi/login.go b/pkg/clouds/pulumi/login.go index 9008eabc..e6d8714a 100644 --- a/pkg/clouds/pulumi/login.go +++ b/pkg/clouds/pulumi/login.go @@ -44,10 +44,6 @@ func (p *pulumi) login(ctx context.Context, cfg *api.ConfigFile, stack api.Stack organization = provisionerCfg.Organization } - if err != nil { - return errors.Wrapf(err, "failed to init pulumi provisioner context") - } - var pulumiHome string if os.Getenv(workspace.PulumiHomeEnvVar) == "" { if pulumiHome, err = path_util.ReplaceTildeWithHome("~/.pulumi"); err != nil { diff --git a/pkg/clouds/pulumi/testutil/secrets_test_util.go b/pkg/clouds/pulumi/testutil/secrets_test_util.go index fcba0c5d..0a36614d 100644 --- a/pkg/clouds/pulumi/testutil/secrets_test_util.go +++ b/pkg/clouds/pulumi/testutil/secrets_test_util.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/secrets" awsApi "github.com/simple-container-com/api/pkg/clouds/aws" "github.com/simple-container-com/api/pkg/clouds/cloudflare" @@ -43,7 +44,7 @@ func ReadIntegrationTestConfig() (*api.ConfigFile, secrets.Cryptor) { Expect(c.ReadSecretFiles()).To(BeNil()) - cfg, err := api.ReadConfigFile(c.Workdir(), "test") + cfg, err := api.ReadConfigFile(config.FSReader, c.Workdir(), "test") Expect(err).To(BeNil()) return cfg, c diff --git a/pkg/provisioner/common.go b/pkg/provisioner/common.go index d892fe0b..33d5664c 100644 --- a/pkg/provisioner/common.go +++ b/pkg/provisioner/common.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/git" "github.com/simple-container-com/api/pkg/api/logger" "github.com/simple-container-com/api/pkg/api/secrets" @@ -62,6 +63,7 @@ type provisioner struct { phResolver placeholders.Placeholders log logger.Logger overrideProvisioner api.Provisioner + configReader config.Reader } func New(opts ...Option) (Provisioner, error) { @@ -94,6 +96,9 @@ func New(opts ...Option) (Provisioner, error) { res.rootDir = path.Base(wd) } } + if res.configReader == nil { + res.configReader = config.FSReader + } return res, nil } @@ -102,7 +107,7 @@ func (p *provisioner) Stacks() api.StacksMap { } func (p *provisioner) GetStack(ctx context.Context, params api.StackParams, opts api.ReadOpts) (*api.Stack, error) { - cfg, err := api.ReadConfigFile(p.rootDir, p.profile) + cfg, err := api.ReadConfigFile(p.configReader, p.rootDir, p.profile) if err != nil { return nil, errors.Wrapf(err, "failed to read config file for profile %q", p.profile) } diff --git a/pkg/provisioner/deploy.go b/pkg/provisioner/deploy.go index 6347b39a..f348ad59 100644 --- a/pkg/provisioner/deploy.go +++ b/pkg/provisioner/deploy.go @@ -43,7 +43,7 @@ func (p *provisioner) prepareForChildStack(ctx context.Context, params *api.Stac } func (p *provisioner) initProvisioner(ctx context.Context, params api.StackParams) (*api.ConfigFile, *api.Stack, api.Provisioner, error) { - cfg, err := api.ReadConfigFile(p.rootDir, p.profile) + cfg, err := api.ReadConfigFile(p.configReader, p.rootDir, p.profile) if err != nil { return nil, nil, nil, errors.Wrapf(err, "failed to read config file for profile %q", p.profile) } diff --git a/pkg/provisioner/opts.go b/pkg/provisioner/opts.go index 7a4993e9..64fb173f 100644 --- a/pkg/provisioner/opts.go +++ b/pkg/provisioner/opts.go @@ -4,6 +4,7 @@ import ( "context" "github.com/simple-container-com/api/pkg/api" + "github.com/simple-container-com/api/pkg/api/config" "github.com/simple-container-com/api/pkg/api/git" "github.com/simple-container-com/api/pkg/api/logger" "github.com/simple-container-com/api/pkg/api/secrets" @@ -19,6 +20,13 @@ func WithProfile(profile string) Option { } } +func WithConfigReader(reader config.Reader) Option { + return func(p *provisioner) error { + p.configReader = reader + return nil + } +} + func WithPlaceholders(ph placeholders.Placeholders) Option { return func(p *provisioner) error { p.phResolver = ph diff --git a/pkg/provisioner/provision.go b/pkg/provisioner/provision.go index be8cde1f..2c3cc624 100644 --- a/pkg/provisioner/provision.go +++ b/pkg/provisioner/provision.go @@ -33,7 +33,7 @@ func (p *provisioner) Provision(ctx context.Context, params api.ProvisionParams) } func (p *provisioner) prepareForParentStack(ctx context.Context, params api.ProvisionParams) (*api.ConfigFile, error) { - cfg, err := api.ReadConfigFile(p.rootDir, p.profile) + cfg, err := api.ReadConfigFile(p.configReader, p.rootDir, p.profile) if err != nil { return nil, errors.Wrapf(err, "failed to read config file for profile %q", p.profile) } @@ -155,7 +155,7 @@ func (p *provisioner) resolvePlaceholders() error { func (p *provisioner) readServerDescriptor(rootDir string, stackName string) (*api.ServerDescriptor, error) { descFilePath := path.Join(rootDir, stackName, api.ServerDescriptorFileName) - if desc, err := api.ReadServerDescriptor(descFilePath); err != nil { + if desc, err := api.ReadServerDescriptor(p.configReader, descFilePath); err != nil { return nil, errors.Wrapf(err, "failed to read server descriptor from %q", descFilePath) } else { return desc, nil @@ -171,7 +171,7 @@ func (p *provisioner) readSecretsDescriptor(rootDir string, stackName string) (* } func (p *provisioner) readSecretsDescriptorFromFile(descFilePath string) (*api.SecretsDescriptor, error) { - if desc, err := api.ReadSecretsDescriptor(descFilePath); err != nil { + if desc, err := api.ReadSecretsDescriptor(p.configReader, descFilePath); err != nil { return nil, errors.Wrapf(err, "failed to read secrets descriptor from %q", descFilePath) } else { return desc, nil @@ -187,7 +187,7 @@ func (p *provisioner) readClientDescriptor(rootDir string, stackName string) (*a } func (p *provisioner) readClientDescriptorFromFile(path string) (*api.ClientDescriptor, error) { - if desc, err := api.ReadClientDescriptor(path); err != nil { + if desc, err := api.ReadClientDescriptor(p.configReader, path); err != nil { return nil, errors.Wrapf(err, "failed to read client descriptor from %q", path) } else { return desc, nil diff --git a/tools.go b/tools.go index 01fb1694..d85e667d 100644 --- a/tools.go +++ b/tools.go @@ -4,6 +4,8 @@ //go:generate go build -o ./bin/gofumpt mvdan.cc/gofumpt //go:generate go build -o ./bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint //go:generate go build -o ./bin/dlv github.com/go-delve/delve/cmd/dlv +//go:generate go build -o ./bin/tscriptify github.com/tkrajina/typescriptify-golang-structs/tscriptify +//go:generate ./bin/tscriptify -package=github.com/simple-container-com/api/pkg/api -target=models/typescript/models.ts // this file references indirect dependencies that are used during the build @@ -13,6 +15,7 @@ import ( _ "github.com/atombender/go-jsonschema/pkg/generator" _ "github.com/go-delve/delve/cmd/dlv" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" + _ "github.com/tkrajina/typescriptify-golang-structs/tscriptify" _ "github.com/vektra/mockery/v2" _ "mvdan.cc/gofumpt" )