Skip to content

Commit 9464206

Browse files
author
Antoine Pelisse
committed
FixTabsOrDie doesn't work well with YAML structs
Especially when the struct is in a list because: ```yaml - a: 1 b: 2 ``` panics because of mixed spaces and tabs. A working alternative is to indent with tabs, but I don't think it's very pleasant: ```yaml - a: 1 b: 2 ``` Update the code so that prefixed tabs from the first line are removed from all consecutive lines, and keep it that simple.
1 parent 787950f commit 9464206

File tree

2 files changed

+24
-43
lines changed

2 files changed

+24
-43
lines changed

internal/fixture/state.go

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,52 +35,37 @@ type State struct {
3535
Updater *merge.Updater
3636
}
3737

38-
// FixTabsOrDie counts the number of tab characters preceding the first line in
39-
// the given yaml object. It removes that many tabs from every line. It then
40-
// converts remaining tabs to spaces (two spaces per tab). It panics (it's a
41-
// test funtion) if it finds mixed tabs and spaces in front of a line, or if
42-
// some line has fewer tabs than the first line.
38+
// FixTabsOrDie counts the number of tab characters preceding the first
39+
// line in the given yaml object. It removes that many tabs from every
40+
// line. It panics (it's a test funtion) if some line has fewer tabs
41+
// than the first line.
4342
//
4443
// The purpose of this is to make it easier to read tests.
4544
func FixTabsOrDie(in typed.YAMLObject) typed.YAMLObject {
46-
consumeTabs := func(line []byte) (tabCount int, spacesFound bool) {
47-
for _, c := range line {
48-
if c == ' ' {
49-
spacesFound = true
50-
}
51-
if c != '\t' {
52-
break
53-
}
54-
tabCount++
55-
}
56-
return tabCount, spacesFound
57-
}
58-
5945
lines := bytes.Split([]byte(in), []byte{'\n'})
6046
if len(lines[0]) == 0 && len(lines) > 1 {
6147
lines = lines[1:]
6248
}
63-
prefix, _ := consumeTabs(lines[0])
64-
var anySpacesFound bool
65-
var anyTabsFound bool
66-
49+
// Create prefix made of tabs that we want to remove.
50+
var prefix []byte
51+
for _, c := range lines[0] {
52+
if c != '\t' {
53+
break
54+
}
55+
prefix = append(prefix, byte('\t'))
56+
}
57+
// Remove prefix from all tabs, fail otherwise.
6758
for i := range lines {
6859
line := lines[i]
69-
indent, spacesFound := consumeTabs(line)
70-
if i == len(lines)-1 && len(line) <= prefix && indent == len(line) {
71-
// It's OK for the last line to be blank (trailing \n)
60+
// It's OK for the last line to be blank (trailing \n)
61+
if i == len(lines)-1 && len(line) <= len(prefix) && bytes.TrimSpace(line) == nil {
7262
lines[i] = []byte{}
7363
break
7464
}
75-
anySpacesFound = anySpacesFound || spacesFound
76-
anyTabsFound = anyTabsFound || indent > 0
77-
if indent < prefix {
78-
panic(fmt.Sprintf("line %v doesn't have %v tabs as a prefix:\n%s", i, prefix, in))
65+
if !bytes.HasPrefix(line, prefix) {
66+
panic(fmt.Errorf("line %d doesn't start with expected number (%d) of tabs: %v", i, len(prefix), line))
7967
}
80-
lines[i] = append(bytes.Repeat([]byte{' ', ' '}, indent-prefix), line[indent:]...)
81-
}
82-
if anyTabsFound && anySpacesFound {
83-
panic("mixed tabs and spaces found:\n" + string(in))
68+
lines[i] = line[len(prefix):]
8469
}
8570
return typed.YAMLObject(bytes.Join(lines, []byte{'\n'}))
8671
}

internal/fixture/state_test.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package fixture
1818

1919
import (
20-
"bytes"
2120
"fmt"
2221
"testing"
2322

@@ -33,16 +32,16 @@ func TestFixTabs(t *testing.T) {
3332
out: "a\n b\n",
3433
}, {
3534
in: "\t\ta\n\t\t\tb\n",
36-
out: "a\n b\n",
35+
out: "a\n\tb\n",
3736
}, {
38-
in: "\n\t\ta\n\t\t\tb\n",
39-
out: "a\n b\n",
37+
in: "\n\t\ta\n\t\tb\n",
38+
out: "a\nb\n",
4039
}, {
4140
in: "\n\t\ta\n\t\t\tb\n\t",
42-
out: "a\n b\n",
41+
out: "a\n\tb\n",
4342
}, {
44-
in: "\t\ta\n\t\t b\n",
45-
shouldPanic: true,
43+
in: "\t\ta\n\t\t b\n",
44+
out: "a\n b\n",
4645
}, {
4746
in: "\t\ta\n\tb\n",
4847
shouldPanic: true,
@@ -62,9 +61,6 @@ func TestFixTabs(t *testing.T) {
6261
if e, a := tt.out, got; e != a {
6362
t.Errorf("mismatch\n got %v\nwanted %v", []byte(a), []byte(e))
6463
}
65-
if bytes.Contains([]byte(got), []byte{'\t'}) {
66-
t.Error("contained a tab")
67-
}
6864
})
6965
}
7066
}

0 commit comments

Comments
 (0)