Skip to content

Commit

Permalink
feat: Stub lint command
Browse files Browse the repository at this point in the history
Signed-off-by: Kim Christensen <[email protected]>
  • Loading branch information
kichristensen committed Sep 23, 2024
1 parent b9c73c9 commit fd9057b
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 0 deletions.
17 changes: 17 additions & 0 deletions cmd/skeletor/lint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
"github.com/getporter/skeletor/pkg/skeletor"
"github.com/spf13/cobra"
)

func buildLintCommand(m *skeletor.Mixin) *cobra.Command {
cmd := &cobra.Command{
Use: "lint",
Short: "Execute the lint functionality of this mixin",
RunE: func(cmd *cobra.Command, args []string) error {
return m.PrintLintResults(cmd.Context())
},
}
return cmd
}
1 change: 1 addition & 0 deletions cmd/skeletor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func buildRootCommand(m *skeletor.Mixin, in io.Reader) *cobra.Command {
cmd.AddCommand(buildInvokeCommand(m))
cmd.AddCommand(buildUpgradeCommand(m))
cmd.AddCommand(buildUninstallCommand(m))
cmd.AddCommand(buildLintCommand(m))

return cmd
}
75 changes: 75 additions & 0 deletions pkg/skeletor/lint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package skeletor

import (
"context"
"fmt"

"get.porter.sh/porter/pkg/encoding"
"get.porter.sh/porter/pkg/exec/builder"
"get.porter.sh/porter/pkg/linter"

"gopkg.in/yaml.v2"
)

const mixinName = "skeletor"

const (
// CodeInvalidName is the linter code for when the name of the step is invalid.
CodeInvalidName linter.Code = "skeletor-100"
)

func (m *Mixin) Lint(ctx context.Context) (linter.Results, error) {
var actions Actions
err := builder.LoadAction(ctx, m.RuntimeConfig, "", func(contents []byte) (interface{}, error) {
err := yaml.Unmarshal(contents, &actions)
return &actions, err
})
if err != nil {
return nil, err
}

results := make(linter.Results, 0)

for _, action := range actions {
for stepNumber, step := range action.Steps {
// TODO: Replace with your own linting logic
if step.Name != "invalid" {
continue
}

result := linter.Result{
Level: linter.LevelError,
Code: CodeInvalidName,
Location: linter.Location{
Action: action.Name,
Mixin: mixinName,
StepNumber: stepNumber + 1, // We index from 1 for natural counting, 1st, 2nd, etc.
StepDescription: step.Description,
},
Title: "Invalid name",
Message: "The name cannot be 'invalid'",
URL: "",
}
results = append(results, result)
}
}
return results, nil
}

func (m *Mixin) PrintLintResults(ctx context.Context) error {
results, err := m.Lint(ctx)
if err != nil {
return err
}

b, err := encoding.MarshalJson(results)
if err != nil {
return fmt.Errorf("could not marshal lint results %#v: %w", results, err)
}

// Print the results as json to stdout for Porter to read
resultsJson := string(b)
fmt.Fprintln(m.Config.Out, resultsJson)

return nil
}
55 changes: 55 additions & 0 deletions pkg/skeletor/lint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package skeletor

import (
"bytes"
"context"
"os"
"testing"

"get.porter.sh/porter/pkg/linter"

"github.com/stretchr/testify/require"
)

func TestMixin_Lint(t *testing.T) {
testcases := []struct {
name string // Test case name
file string // Path to the test input yaml
wantResults linter.Results // Indicates the wanted lint result
}{
{"valid file", "testdata/step-input.yaml", nil},
{"invalid name", "testdata/step-input-fail-lint.yaml", linter.Results{
linter.Result{
Level: linter.LevelError,
Location: linter.Location{
Action: "install",
Mixin: "skeletor",
StepNumber: 1,
StepDescription: "Summon Minion",
},
Code: CodeInvalidName,
Title: "Invalid name",
Message: "The name cannot be 'invalid'",
},
}},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
m := NewTestMixin(t)
mixinInputB, err := os.ReadFile(tc.file)
require.NoError(t, err)

m.In = bytes.NewBuffer(mixinInputB)

results, err := m.Lint(ctx)
require.NoError(t, err, "lint failed")

require.Len(t, results, len(tc.wantResults))
for _, wantResult := range tc.wantResults {
require.Contains(t, results, wantResult)
}
})
}
}
11 changes: 11 additions & 0 deletions pkg/skeletor/testdata/step-input-fail-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
install:
- skeletor:
name: "invalid"
description: "Summon Minion"
arguments:
- "man-e-faces"
flags:
species: "human"
outputs:
- name: "VICTORY"
jsonPath: "$Id"

0 comments on commit fd9057b

Please sign in to comment.