Skip to content
Draft
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
11 changes: 11 additions & 0 deletions sops.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ type Comment struct {
Value string
}

// EmptyLines represents empty lines in the sops tree
type EmptyLines struct {
Count int // Must be positive
}

// TreeItem is an item inside sops's tree
type TreeItem struct {
Key interface{}
Expand Down Expand Up @@ -316,6 +321,9 @@ func (branch TreeBranch) walkSlice(in []interface{}, path []string, commentsStac
// Because append returns a new slice, the original stack is not changed.
commentsStack = append(commentsStack, []string{})
for i, v := range in {
if _, ok := v.(EmptyLines); ok {
continue
}
c, vIsComment := v.(Comment)
if vIsComment {
// If v is a comment, we add it to the slice of active comments.
Expand All @@ -339,6 +347,9 @@ func (branch TreeBranch) walkBranch(in TreeBranch, path []string, commentsStack
// Because append returns a new slice, the original stack is not changed.
commentsStack = append(commentsStack, []string{})
for i, item := range in {
if _, ok := item.Key.(EmptyLines); ok {
continue
}
if c, ok := item.Key.(Comment); ok {
// If key is a comment, we add it to the slice of active comments.
// This allows us to also encrypt comments themselves by enabling encryption in a prior comment.
Expand Down
15 changes: 14 additions & 1 deletion stores/dotenv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) {
}
case sops.Comment:
resultBranch = append(resultBranch, item)
case sops.EmptyLines:
resultBranch = append(resultBranch, item)
default:
panic(fmt.Sprintf("Unexpected type: %T (value %#v)", key, key))
}
Expand Down Expand Up @@ -76,10 +78,19 @@ func (store *Store) LoadPlainFile(in []byte) (sops.TreeBranches, error) {
var branches sops.TreeBranches
var branch sops.TreeBranch

emptyLines := 0
for _, line := range bytes.Split(in, []byte("\n")) {
if len(line) == 0 {
emptyLines += 1
continue
}
if emptyLines > 0 {
branch = append(branch, sops.TreeItem{
Key: sops.EmptyLines{Count: emptyLines},
Value: nil,
})
emptyLines = 0
}
if line[0] == '#' {
branch = append(branch, sops.TreeItem{
Key: sops.Comment{Value: string(line[1:])},
Expand Down Expand Up @@ -138,7 +149,9 @@ func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) {
return nil, fmt.Errorf("cannot use complex value in dotenv file: %s", item.Value)
}
var line string
if comment, ok := item.Key.(sops.Comment); ok {
if emptyLines, ok := item.Key.(sops.EmptyLines); ok {
line = strings.Repeat("\n", emptyLines.Count)
} else if comment, ok := item.Key.(sops.Comment); ok {
line = fmt.Sprintf("#%s\n", comment.Value)
} else {
value := strings.Replace(item.Value.(string), "\n", "\\n", -1)
Expand Down
3 changes: 3 additions & 0 deletions stores/ini/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ func (store Store) encodeTree(branches sops.TreeBranches) ([]byte, error) {
iniFile.DeleteSection(ini.DefaultSection)
for _, branch := range branches {
for _, item := range branch {
if _, ok := item.Key.(sops.EmptyLines); ok {
continue
}
if _, ok := item.Key.(sops.Comment); ok {
continue
}
Expand Down
6 changes: 6 additions & 0 deletions stores/json/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ func (store Store) encodeArray(array []interface{}) ([]byte, error) {
out := "["
empty := true
for _, item := range array {
if _, ok := item.(sops.EmptyLines); ok {
continue
}
if _, ok := item.(sops.Comment); ok {
continue
}
Expand All @@ -209,6 +212,9 @@ func (store Store) encodeTree(tree sops.TreeBranch) ([]byte, error) {
out := "{"
empty := true
for _, item := range tree {
if _, ok := item.Key.(sops.EmptyLines); ok {
continue
}
if _, ok := item.Key.(sops.Comment); ok {
continue
}
Expand Down
54 changes: 48 additions & 6 deletions stores/yaml/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,63 @@ func NewStore(c *config.YAMLStoreConfig) *Store {

func (store Store) appendCommentToList(comment string, list []interface{}) []interface{} {
if comment != "" {
emptyLines := 0
for _, commentLine := range strings.Split(comment, "\n") {
if commentLine != "" {
if emptyLines > 0 {
list = append(list, sops.EmptyLines{
Count: emptyLines,
})
emptyLines = 0
}
list = append(list, sops.Comment{
Value: commentLine[1:],
})
} else {
emptyLines += 1
}
}
if emptyLines > 0 {
list = append(list, sops.EmptyLines{
Count: emptyLines,
})
}
}
return list
}

func (store Store) appendCommentToMap(comment string, branch sops.TreeBranch) sops.TreeBranch {
if comment != "" {
emptyLines := 0
for _, commentLine := range strings.Split(comment, "\n") {
if commentLine != "" {
if emptyLines > 0 {
branch = append(branch, sops.TreeItem{
Key: sops.EmptyLines{
Count: emptyLines,
},
Value: nil,
})
emptyLines = 0
}
branch = append(branch, sops.TreeItem{
Key: sops.Comment{
Value: commentLine[1:],
},
Value: nil,
})
} else {
emptyLines += 1
}
}
if emptyLines > 0 {
branch = append(branch, sops.TreeItem{
Key: sops.EmptyLines{
Count: emptyLines,
},
Value: nil,
})
}
}
return branch
}
Expand Down Expand Up @@ -158,7 +192,7 @@ func (store Store) yamlDocumentNodeToTreeBranch(in yaml.Node) (sops.TreeBranch,

func (store *Store) addCommentsHead(node *yaml.Node, comments []string) []string {
if len(comments) > 0 {
comment := "#" + strings.Join(comments, "\n#")
comment := strings.Join(comments, "\n")
if len(node.HeadComment) > 0 {
node.HeadComment = comment + "\n" + node.HeadComment
} else {
Expand All @@ -170,7 +204,7 @@ func (store *Store) addCommentsHead(node *yaml.Node, comments []string) []string

func (store *Store) addCommentsFoot(node *yaml.Node, comments []string) []string {
if len(comments) > 0 {
comment := "#" + strings.Join(comments, "\n#")
comment := strings.Join(comments, "\n")
if len(node.FootComment) > 0 {
node.FootComment += "\n" + comment
} else {
Expand Down Expand Up @@ -203,8 +237,12 @@ func (store *Store) appendSequence(in []interface{}, sequence *yaml.Node) {
var comments []string
var beginning bool = true
for _, item := range in {
if comment, ok := item.(sops.Comment); ok {
comments = append(comments, comment.Value)
if emptyLines, ok := item.(sops.EmptyLines); ok {
for _ = range emptyLines.Count {
comments = append(comments, "")
}
} else if comment, ok := item.(sops.Comment); ok {
comments = append(comments, "#" + comment.Value)
} else {
if beginning {
comments = store.addCommentsHead(sequence, comments)
Expand All @@ -228,8 +266,12 @@ func (store *Store) appendTreeBranch(branch sops.TreeBranch, mapping *yaml.Node)
var comments []string
var beginning bool = true
for _, item := range branch {
if comment, ok := item.Key.(sops.Comment); ok {
comments = append(comments, comment.Value)
if emptyLines, ok := item.Key.(sops.EmptyLines); ok {
for _ = range emptyLines.Count {
comments = append(comments, "")
}
} else if comment, ok := item.Key.(sops.Comment); ok {
comments = append(comments, "#" + comment.Value)
} else {
if beginning {
comments = store.addCommentsHead(mapping, comments)
Expand Down
Loading