add support for nested keys

This commit is contained in:
Jason Ertel
2023-11-20 16:18:30 -05:00
parent f31e288005
commit 6356a0bf95
2 changed files with 43 additions and 5 deletions

View File

@@ -16,12 +16,12 @@ lockFile = "/tmp/so-yaml.lock"
def showUsage(args): def showUsage(args):
print('Usage: {} <COMMAND> <YAML_FILE> [ARGS...]'.format(sys.argv[0])) print('Usage: {} <COMMAND> <YAML_FILE> [ARGS...]'.format(sys.argv[0]))
print(' General commands:') print(' General commands:')
print(' remove - Removes a yaml top-level key, if it exists. Requires KEY arg.') print(' remove - Removes a yaml key, if it exists. Requires KEY arg.')
print(' help - Prints this usage information.') print(' help - Prints this usage information.')
print('') print('')
print(' Where:') print(' Where:')
print(' YAML_FILE - Path to the file that will be modified. Ex: /opt/so/conf/service/conf.yaml') print(' YAML_FILE - Path to the file that will be modified. Ex: /opt/so/conf/service/conf.yaml')
print(' KEY - Top level key only, does not support dot-notations for nested keys at this time. Ex: level1') print(' KEY - YAML key, does not support \' or " characters at this time. Ex: level1.level2')
sys.exit(1) sys.exit(1)
@@ -36,6 +36,13 @@ def writeYaml(filename, content):
return yaml.dump(content, file) return yaml.dump(content, file)
def removeKey(content, key):
pieces = key.split(".", 1)
if len(pieces) > 1:
removeKey(content[pieces[0]], pieces[1])
else:
content.pop(key, None)
def remove(args): def remove(args):
if len(args) != 2: if len(args) != 2:
print('Missing filename or key arg', file=sys.stderr) print('Missing filename or key arg', file=sys.stderr)
@@ -43,11 +50,12 @@ def remove(args):
return return
filename = args[0] filename = args[0]
key = args[1]
content = loadYaml(filename) content = loadYaml(filename)
removeKey(content, key)
content.pop(args[1], None)
writeYaml(filename, content) writeYaml(filename, content)
return 0 return 0

View File

@@ -57,6 +57,36 @@ class TestRemove(unittest.TestCase):
expected = "key2: false\n" expected = "key2: false\n"
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
def test_remove_nested(self):
filename = "/tmp/so-yaml_test-remove.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: abc }, key2: false}")
file.close()
soyaml.remove([filename, "key1.child2"])
file = open(filename, "r")
actual = file.read()
file.close()
expected = "key1:\n child1: 123\nkey2: false\n"
self.assertEqual(actual, expected)
def test_remove_nested_deep(self):
filename = "/tmp/so-yaml_test-remove.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: { deep1: 45, deep2: ab } }, key2: false}")
file.close()
soyaml.remove([filename, "key1.child2.deep1"])
file = open(filename, "r")
actual = file.read()
file.close()
expected = "key1:\n child1: 123\n child2:\n deep2: ab\nkey2: false\n"
self.assertEqual(actual, expected)
def test_remove_missing_args(self): def test_remove_missing_args(self):
with patch('sys.exit', new=MagicMock()) as sysmock: with patch('sys.exit', new=MagicMock()) as sysmock:
with patch('sys.stderr', new=StringIO()) as mock_stdout: with patch('sys.stderr', new=StringIO()) as mock_stdout: