Skip to content

Commit

Permalink
fix: indentation (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcreey committed Apr 17, 2024
1 parent 6edcbba commit 4f6b697
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 54 deletions.
2 changes: 1 addition & 1 deletion command/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (c *CheckCommand) Run(ctx context.Context, originalArgs []string) error {

fsys := os.DirFS(".")

files, err := loadYAMLFiles(fsys, args)
files, err := loadYAMLFiles(fsys, args, false)
if err != nil {
return err
}
Expand Down
50 changes: 46 additions & 4 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (r loadResults) nodes() []*yaml.Node {
return n
}

func loadYAMLFiles(fsys fs.FS, paths []string) (loadResults, error) {
func loadYAMLFiles(fsys fs.FS, paths []string, format bool) (loadResults, error) {
r := make(loadResults, 0, len(paths))

for _, pth := range paths {
Expand All @@ -137,17 +137,59 @@ func loadYAMLFiles(fsys fs.FS, paths []string) (loadResults, error) {
if err := yaml.Unmarshal(contents, &node); err != nil {
return nil, fmt.Errorf("failed to parse yaml for %s: %w", pth, err)
}

r = append(r, &loadResult{
lr := &loadResult{
path: pth,
node: &node,
contents: contents,
})
}

if format {
if err := FixIndentation(lr); err != nil {
return nil, fmt.Errorf("failed to format indentation: %w", err)
}
}

r = append(r, lr)
}

return r, nil
}

// FixIndentation corrects the indentation for the given loadResult and edits it in-place.
func FixIndentation(f *loadResult) error {
updated, err := marshalYAML(f.node)
if err != nil {
return fmt.Errorf("failed to marshal yaml for %s: %w", f.path, err)
}
lines := strings.Split(string(f.contents), "\n")
afterLines := strings.Split(string(updated), "\n")

editedLines := []string{}
afterIndex := 0
// Loop through both lists line by line using a two-pointer technique.
for _, l := range lines {
token := strings.TrimSpace(l)
if token == "" {
editedLines = append(editedLines, l)
continue
}
currentAfterLine := afterLines[afterIndex]
indexInAfterLine := strings.Index(currentAfterLine, token)
for indexInAfterLine == -1 {
afterIndex++
currentAfterLine = afterLines[afterIndex]
indexInAfterLine = strings.Index(currentAfterLine, token)
}

lineWithCorrectIndent := currentAfterLine[:indexInAfterLine] + token
editedLines = append(editedLines, lineWithCorrectIndent)
afterIndex++
}

f.contents = []byte(strings.Join(editedLines, "\n"))
return nil
}

func removeNewLineChanges(beforeContent, afterContent string) string {
lines := strings.Split(beforeContent, "\n")
edits := myers.ComputeEdits(span.URIFromPath("before.txt"), beforeContent, afterContent)
Expand Down
155 changes: 110 additions & 45 deletions command/command_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package command

import (
"bytes"
"os"
"reflect"
"testing"

"github.com/braydonk/yaml"
"github.com/google/go-cmp/cmp"
)

Expand Down Expand Up @@ -331,56 +329,123 @@ func Test_loadYAMLFiles(t *testing.T) {
cases := []struct {
name string
yamlFilenames []string
format bool
want string
}{
{
name: "yamlA_multiple_empty_lines",
yamlFilenames: []string{"testdata/github.yml"},
format: false,
want: `jobs:
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
`,
},
{
name: "handles-leading-dot-slash",
yamlFilenames: []string{"./testdata/github.yml"},
format: false,
want: `jobs:
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
`,
},
{
name: "yaml_steps_indent_change",
yamlFilenames: []string{"testdata/github.yml"},
format: true,
want: `jobs:
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
`,
},
{
name: "yaml_all_indent_change",
yamlFilenames: []string{"testdata/github-crazy-indent.yml"},
format: true,
want: `jobs:
my_job:
runs-on: 'ubuntu-latest'
container:
image: 'ubuntu:20.04'
services:
nginx:
image: 'nginx:1.21'
steps:
- uses: 'actions/checkout@v3'
- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'
- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
final_job:
uses: './local/path/to/action'
`,
},
}
Expand All @@ -391,16 +456,16 @@ func Test_loadYAMLFiles(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

files, err := loadYAMLFiles(os.DirFS(".."), tc.yamlFilenames)
files, err := loadYAMLFiles(os.DirFS(".."), tc.yamlFilenames, tc.format)
if err != nil {
t.Fatalf("loadYAMLFiles() returned error: %s", err)
}

var buf bytes.Buffer
if err := yaml.NewEncoder(&buf).Encode(files.nodes()[0]); err != nil {
t.Errorf("failed to marshal yaml to string: %s", err)
b, err := marshalYAML(files[0].node)
if err != nil {
t.Fatalf("marshalYAML() returned error: %s", err)
}
got := buf.String()
got := string(b)

if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("returned diff (-want, +got):\n%s", diff)
Expand Down
2 changes: 1 addition & 1 deletion command/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (c *PinCommand) Run(ctx context.Context, originalArgs []string) error {

fsys := os.DirFS(".")

files, err := loadYAMLFiles(fsys, args)
files, err := loadYAMLFiles(fsys, args, true)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion command/unpin.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (c *UnpinCommand) Run(ctx context.Context, originalArgs []string) error {

fsys := os.DirFS(".")

files, err := loadYAMLFiles(fsys, args)
files, err := loadYAMLFiles(fsys, args, true)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion command/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *UpdateCommand) Run(ctx context.Context, originalArgs []string) error {

fsys := os.DirFS(".")

files, err := loadYAMLFiles(fsys, args)
files, err := loadYAMLFiles(fsys, args, true)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion command/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (c *UpgradeCommand) Run(ctx context.Context, originalArgs []string) error {

fsys := os.DirFS(".")

files, err := loadYAMLFiles(fsys, args)
files, err := loadYAMLFiles(fsys, args, true)
if err != nil {
return err
}
Expand Down
30 changes: 30 additions & 0 deletions testdata/github-crazy-indent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
jobs:
my_job:
runs-on: 'ubuntu-latest'

container:
image: 'ubuntu:20.04'

services:
nginx:
image: 'nginx:1.21'

steps:
- uses: 'actions/checkout@v3'

- uses: 'docker://ubuntu:20.04'
with:
uses: '/path/to/user.png'
image: '/path/to/image.jpg'

- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'

final_job:
uses: './local/path/to/action'
3 changes: 3 additions & 0 deletions testdata/github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:

- runs: |-
echo "Hello 😀"
if [ "true" == "false" ];
echo "NOPE"
fi
other_job:
uses: 'my-org/my-repo/.github/workflows/my-workflow.yml@v0'
Expand Down

0 comments on commit 4f6b697

Please sign in to comment.