Skip to content
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
6 changes: 4 additions & 2 deletions cmd/bundle.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package cmd implements the mass CLI commands.
package cmd

import (
Expand All @@ -6,6 +7,7 @@ import (
"context"
"embed"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -316,7 +318,7 @@ func bundleDir(cmd *cobra.Command, args []string) (string, error) {
hasPositional := len(args) > 0
flagSet := cmd.Flags().Changed("bundle-directory")
if hasPositional && flagSet {
return "", fmt.Errorf("cannot specify both a positional path and --bundle-directory; use one")
return "", errors.New("cannot specify both a positional path and --bundle-directory; use one")
}
if hasPositional {
return args[0], nil
Expand Down Expand Up @@ -561,7 +563,7 @@ func runBundleGet(cmd *cobra.Command, args []string) error {

bundleID := args[0]
if !strings.Contains(bundleID, "@") {
bundleID = bundleID + "@latest"
bundleID += "@latest"
}

outputFormat, err := cmd.Flags().GetString("output")
Expand Down
1 change: 1 addition & 0 deletions cmd/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ func runEnvironmentCreate(cmd *cobra.Command, args []string) error {
return nil
}

//nolint:dupl // parallel CRUD shape with other entity update commands
func runEnvironmentUpdate(cmd *cobra.Command, args []string) error {
ctx := context.Background()

Expand Down
3 changes: 2 additions & 1 deletion cmd/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
var instanceTemplates embed.FS

// NewCmdInstance returns a cobra command for managing instances of IaC deployed in environments.
func NewCmdInstance() *cobra.Command { //nolint:funlen // cobra command builders are necessarily long
func NewCmdInstance() *cobra.Command {
instanceCmd := &cobra.Command{
Use: "instance",
Aliases: []string{"inst", "package", "instance"},
Expand Down Expand Up @@ -183,6 +183,7 @@ func renderInstance(instance *api.Instance) error {
return nil
}

//nolint:gocognit // sequential flag parsing and dispatch, not branching logic
func runInstanceDeploy(cmd *cobra.Command, args []string) error {
ctx := context.Background()

Expand Down
1 change: 1 addition & 0 deletions cmd/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ func runProjectCreate(cmd *cobra.Command, args []string) error {
return nil
}

//nolint:dupl // parallel CRUD shape with other entity update commands
func runProjectUpdate(cmd *cobra.Command, args []string) error {
ctx := context.Background()

Expand Down
15 changes: 8 additions & 7 deletions cmd/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"embed"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
Expand Down Expand Up @@ -167,31 +168,31 @@ func runRepositoryList(input *repositoryListInput) error {

func buildOciReposFilter(input *repositoryListInput) (*api.OciReposFilter, error) {
filter := &api.OciReposFilter{}
any := false
hasFilter := false

if input.kind != "" {
mediaType, resolveErr := resolveArtifactType(input.kind)
if resolveErr != nil {
return nil, resolveErr
}
filter.ArtifactType = mediaType
any = true
hasFilter = true
}
if input.search != "" {
filter.Search = input.search
any = true
hasFilter = true
}
switch {
case input.name != "" && input.prefix != "":
return nil, fmt.Errorf("--name and --prefix are mutually exclusive")
return nil, errors.New("--name and --prefix are mutually exclusive")
case input.name != "":
filter.Name = &api.OciRepoNameFilter{Eq: input.name}
any = true
hasFilter = true
case input.prefix != "":
filter.Name = &api.OciRepoNameFilter{StartsWith: input.prefix}
any = true
hasFilter = true
}
if !any {
if !hasFilter {
return nil, nil //nolint:nilnil // explicit nil filter is the no-filter signal to the API
}
return filter, nil
Expand Down
22 changes: 11 additions & 11 deletions internal/api/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import (

// Bundle represents a Massdriver bundle (IaC module) and its metadata.
type Bundle struct {
ID string `json:"id" mapstructure:"id"`
Name string `json:"name" mapstructure:"name"`
Version string `json:"version" mapstructure:"version"`
Description string `json:"description,omitempty" mapstructure:"description"`
Icon string `json:"icon,omitempty" mapstructure:"icon"`
SourceURL string `json:"sourceUrl,omitempty" mapstructure:"sourceUrl"`
Repo string `json:"repo,omitempty" mapstructure:"repo"`
CreatedAt time.Time `json:"createdAt,omitzero" mapstructure:"createdAt"`
UpdatedAt time.Time `json:"updatedAt,omitzero" mapstructure:"updatedAt"`
Dependencies []BundleSlot `json:"dependencies,omitempty" mapstructure:"dependencies"`
Resources []BundleSlot `json:"resources,omitempty" mapstructure:"resources"`
ID string `json:"id" mapstructure:"id"`
Name string `json:"name" mapstructure:"name"`
Version string `json:"version" mapstructure:"version"`
Description string `json:"description,omitempty" mapstructure:"description"`
Icon string `json:"icon,omitempty" mapstructure:"icon"`
SourceURL string `json:"sourceUrl,omitempty" mapstructure:"sourceUrl"`
Repo string `json:"repo,omitempty" mapstructure:"repo"`
CreatedAt time.Time `json:"createdAt,omitzero" mapstructure:"createdAt"`
UpdatedAt time.Time `json:"updatedAt,omitzero" mapstructure:"updatedAt"`
Dependencies []BundleSlot `json:"dependencies,omitempty" mapstructure:"dependencies"`
Resources []BundleSlot `json:"resources,omitempty" mapstructure:"resources"`
}

// BundleSlot describes one of a bundle's input dependencies or output
Expand Down
6 changes: 3 additions & 3 deletions internal/api/oci_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ func GetOciRepo(ctx context.Context, mdClient *client.Client, id string) (*OciRe
UpdatedAt: r.UpdatedAt,
}
for _, rc := range r.ReleaseChannels.Items {
repo.ReleaseChannels = append(repo.ReleaseChannels, OciReleaseChannel{Name: rc.Name, Tag: rc.Tag})
repo.ReleaseChannels = append(repo.ReleaseChannels, OciReleaseChannel(rc))
}
for _, tag := range r.Tags.Items {
repo.Tags = append(repo.Tags, OciRepoTag{Tag: tag.Tag, CreatedAt: tag.CreatedAt})
repo.Tags = append(repo.Tags, OciRepoTag(tag))
}

return &repo, nil
Expand All @@ -81,7 +81,7 @@ func ListOciRepos(ctx context.Context, mdClient *client.Client, filter *OciRepos
UpdatedAt: r.UpdatedAt,
}
for _, rc := range r.ReleaseChannels.Items {
repo.ReleaseChannels = append(repo.ReleaseChannels, OciReleaseChannel{Name: rc.Name, Tag: rc.Tag})
repo.ReleaseChannels = append(repo.ReleaseChannels, OciReleaseChannel(rc))
}
repos = append(repos, repo)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/scalars/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func isEmpty(v any) bool {
}
rv = rv.Elem()
}
switch rv.Kind() {
switch rv.Kind() { //nolint:exhaustive // only nil-able container kinds need the IsNil check
case reflect.Map, reflect.Slice:
return rv.IsNil()
}
Expand Down
43 changes: 28 additions & 15 deletions internal/commands/instance/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,15 @@ func TestRunDeployReusesLastConfig(t *testing.T) {
t.Errorf("got %s, wanted COMPLETED", dep.Status)
}

input, ok := createDeploymentVars["input"].(map[string]any)
if !ok {
t.Fatalf("expected input map, got %T", createDeploymentVars["input"])
}
input := mustInputMap(t, createDeploymentVars)
if input["message"] != "redeploy" {
t.Errorf("expected message 'redeploy', got %v", input["message"])
}
if input["action"] != "PROVISION" {
t.Errorf("expected action 'PROVISION', got %v", input["action"])
}

gotParams := map[string]any{}
gqlmock.MustUnmarshalJSON([]byte(input["params"].(string)), &gotParams)
gotParams := unmarshalParams(t, input)
wantParams := map[string]any{"size": "small"}
if !reflect.DeepEqual(gotParams, wantParams) {
t.Errorf("got params %v, wanted %v", gotParams, wantParams)
Expand Down Expand Up @@ -131,9 +127,8 @@ func TestRunDeployWithParamsReplacesConfig(t *testing.T) {
t.Fatal(err)
}

input := createDeploymentVars["input"].(map[string]any)
gotParams := map[string]any{}
gqlmock.MustUnmarshalJSON([]byte(input["params"].(string)), &gotParams)
input := mustInputMap(t, createDeploymentVars)
gotParams := unmarshalParams(t, input)
wantParams := map[string]any{"size": "6GB"}
if !reflect.DeepEqual(gotParams, wantParams) {
t.Errorf("got params %v, wanted %v", gotParams, wantParams)
Expand Down Expand Up @@ -186,9 +181,8 @@ func TestRunDeployWithPatchQueriesUpdatesLastConfig(t *testing.T) {
t.Fatal(err)
}

input := createDeploymentVars["input"].(map[string]any)
gotParams := map[string]any{}
gqlmock.MustUnmarshalJSON([]byte(input["params"].(string)), &gotParams)
input := mustInputMap(t, createDeploymentVars)
gotParams := unmarshalParams(t, input)
wantParams := map[string]any{"cidr": "10.0.0.0/20", "name": "keep"}
if !reflect.DeepEqual(gotParams, wantParams) {
t.Errorf("got params %v, wanted %v", gotParams, wantParams)
Expand Down Expand Up @@ -239,13 +233,12 @@ func TestRunDeployWithDecommissionAction(t *testing.T) {
t.Fatal(err)
}

input := createDeploymentVars["input"].(map[string]any)
input := mustInputMap(t, createDeploymentVars)
if input["action"] != "DECOMMISSION" {
t.Errorf("expected action 'DECOMMISSION', got %v", input["action"])
}

gotParams := map[string]any{}
gqlmock.MustUnmarshalJSON([]byte(input["params"].(string)), &gotParams)
gotParams := unmarshalParams(t, input)
wantParams := map[string]any{"size": "small"}
if !reflect.DeepEqual(gotParams, wantParams) {
t.Errorf("got params %v, wanted %v", gotParams, wantParams)
Expand Down Expand Up @@ -287,3 +280,23 @@ func TestRunDeployFailsWhenDeploymentFails(t *testing.T) {
t.Fatal("expected error, got nil")
}
}

func mustInputMap(t *testing.T, vars map[string]any) map[string]any {
t.Helper()
input, ok := vars["input"].(map[string]any)
if !ok {
t.Fatalf("expected input map, got %T", vars["input"])
}
return input
}

func unmarshalParams(t *testing.T, input map[string]any) map[string]any {
t.Helper()
raw, ok := input["params"].(string)
if !ok {
t.Fatalf("expected params string, got %T", input["params"])
}
out := map[string]any{}
gqlmock.MustUnmarshalJSON([]byte(raw), &out)
return out
}
2 changes: 1 addition & 1 deletion internal/resourcetype/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Delete(ctx context.Context, mdClient *client.Client, name string, force boo
}
}

deletedRT, deleteErr := api.DeleteResourceType(ctx, mdClient, name)
deletedRT, deleteErr := api.DeleteResourceType(ctx, mdClient, name) //nolint:staticcheck // pending migration to OCI-native flow
if deleteErr != nil {
return fmt.Errorf("error deleting resource type: %w", deleteErr)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/resourcetype/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Publish(ctx context.Context, mdClient *client.Client, path string) (*api.Re
Schema: rt,
}

return api.PublishResourceType(ctx, mdClient, input)
return api.PublishResourceType(ctx, mdClient, input) //nolint:staticcheck // pending migration to OCI-native flow
}

func validateResourceType(rt map[string]any, schemaURL string) error {
Expand Down
Loading