Repository: getsops/sops (language: python)

Issue:
using flag `--set` on new root level key, creates a new file with just the added key
### Version
sops 3.1.1

### Bug behaviour
When using `sops --set '["some-key"]["nested-key"] "some-value" secrets.yml'` where `some-key` does not exist at the root level of `secrets.yml` and the file is rewritten with only the keys in the command.

### Expected behaviour
The new key is added to the top level, with the nested key(s) and the existing keys in the file.

### Discussion
It seems this is the intended behaviour based on https://github.com/mozilla/sops/issues/336. The difference is that `nested-key` causes the bug.


Discussion / hints:
This is most certainly not intended, and what you describe as the expected behavior is what should happen. Marked as a bug, thanks for the report!

Fix patch:
diff --git a/sops.go b/sops.go
index 1d39d881d..71b08f23e 100644
--- a/sops.go
+++ b/sops.go
@@ -148,10 +148,11 @@ func set(branch interface{}, path []interface{}, value interface{}) interface{}
 			}
 		}
 		// Not found, need to add the next path entry to the branch
-		if len(path) == 1 {
-			return append(branch, TreeItem{Key: path[0], Value: value})
+		value := valueFromPathAndLeaf(path, value)
+		if newBranch, ok := value.(TreeBranch); ok && len(newBranch) > 0 {
+			return append(branch, newBranch[0])
 		}
-		return valueFromPathAndLeaf(path, value)
+		return branch
 	case []interface{}:
 		position := path[0].(int)
 		if len(path) == 1 {


Test patch:
diff --git a/sops_test.go b/sops_test.go
index 1386bbcc6..549de80bf 100644
--- a/sops_test.go
+++ b/sops_test.go
@@ -577,6 +577,36 @@ func TestSetNewKey(t *testing.T) {
 	assert.Equal(t, "hello", set[0].Value.(TreeBranch)[0].Value.(TreeBranch)[1].Value)
 }
 
+func TestSetNewBranch(t *testing.T) {
+	branch := TreeBranch{
+		TreeItem{
+			Key:   "key",
+			Value: "value",
+		},
+	}
+	set := branch.Set([]interface{}{"foo", "bar", "baz"}, "hello")
+	assert.Equal(t, TreeBranch{
+		TreeItem{
+			Key:   "key",
+			Value: "value",
+		},
+		TreeItem{
+			Key: "foo",
+			Value: TreeBranch{
+				TreeItem{
+					Key: "bar",
+					Value: TreeBranch{
+						TreeItem{
+							Key:   "baz",
+							Value: "hello",
+						},
+					},
+				},
+			},
+		},
+	}, set)
+}
+
 func TestSetArrayDeepNew(t *testing.T) {
 	branch := TreeBranch{
 		TreeItem{