Skip to content

Commit

Permalink
Merge pull request #67 from wwkimball/development
Browse files Browse the repository at this point in the history
Release 2.4.2
  • Loading branch information
wwkimball authored Oct 1, 2020
2 parents 6a58ad3 + cab4ef3 commit b4962fd
Show file tree
Hide file tree
Showing 10 changed files with 434 additions and 95 deletions.
16 changes: 15 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
2.4.2:
Enhancements:
* In the INI file's [rules] section, different merge rules can now be applied
to specific parts -- no matter how deeply nested -- of the same Hash
structure.

Bug Fixes:
* The 3rd-party Python INI file parser had no way of differentiating between
the key and value of a YAML Path entry containing an = sign in its key, like
"/path[.=name]/key = left". This update reconstitutes such lines and
correctly parses an affected YAML Path from the merge rule.

The yaml-merge command now reports version 0.0.3 to reflect these changes.

2.4.1:
Bug Fixes:
* The yaml-merge tool (and underlying Merger class) incorrectly assigned "None"
Anchors to all floating-point numbers. This preventing all merging when both
Anchors to all floating-point numbers. This prevented all merging when both
the LHS and RHS documents contained at least one floating-point number, each.
The yaml-merge command now reports version 0.0.2 to reflect this change.

Expand Down
4 changes: 2 additions & 2 deletions build-release-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
[ -e dist ] && rm -rf dist

# Update pip and install release tools
python -m pip install --upgrade pip
pip install wheel || exit $?
python3 -m pip install --upgrade pip
pip3 install wheel || exit $?

# Require successful tests
if [ ! -x run-tests.sh ]; then
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="yamlpath",
version="2.4.1",
version="2.4.2",
description="Read and change YAML/Compatible data using powerful, intuitive, command-line friendly syntax",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
293 changes: 288 additions & 5 deletions tests/test_merger_merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -1456,10 +1456,11 @@ def test_merge_with_defaults_hash_appends_to_array(
"""
While it is impossible to overwrite an Array with a Hash because that
would be a total loss of data, it is possible to append a Hash to an
Array. This is admittedly an odd case. It is very likely this is the
result of user-error, having provided a silly mergeat argument. But
because the result is a complete preservation of all data from both the
LHS and RHS data sources, it is permitted.
Array (this is different from merging into an Array-of-Hashes, which is
normal and allowed). This is admittedly an odd case. It is very
likely this is the result of user-error, having provided a silly
mergeat argument. But because the result is a complete preservation of
all data from both the LHS and RHS data sources, it is permitted.
A deliberately odd mergeat is provided to force this case.
"""
Expand Down Expand Up @@ -2006,7 +2007,6 @@ def test_merge_rename_anchored_complex_hash_key(
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)


def test_merge_rename_anchored_hash_value(
self, quiet_logger, tmp_path, tmp_path_factory
):
Expand Down Expand Up @@ -2076,3 +2076,286 @@ def test_merge_rename_anchored_hash_value(
(os.path.getsize(output_file) == os.path.getsize(merged_yaml))
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)

def test_merge_hash_with_mergeat_default(
self, quiet_logger, tmp_path, tmp_path_factory
):
lhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
""")
rhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
more_hash:
key: more value
""")
merged_yaml = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
implicit:
structure:
to:
more_hash:
key: more value
""")

output_dir = tmp_path / "test_merge_hash_with_mergeat_default"
output_dir.mkdir()
output_file = output_dir / "output.yaml"

lhs_yaml = get_yaml_editor()
rhs_yaml = get_yaml_editor()
lhs_data = get_yaml_data(lhs_yaml, quiet_logger, lhs_yaml_file)
rhs_data = get_yaml_data(rhs_yaml, quiet_logger, rhs_yaml_file)

args = SimpleNamespace(mergeat="/implicit/structure/to")
mc = MergerConfig(quiet_logger, args)
merger = Merger(quiet_logger, lhs_data, mc)
merger.merge_with(rhs_data)

with open(output_file, 'w') as yaml_dump:
lhs_yaml.dump(merger.data, yaml_dump)

# DEBUG:
with open(output_file, 'r') as output_fnd, open(merged_yaml, 'r') as merged_fnd:
print("Expected:")
print(merged_fnd.read())
print("Got:")
print(output_fnd.read())

assert (
(os.path.getsize(output_file) == os.path.getsize(merged_yaml))
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)

def test_merge_hash_with_mergeat_left(
self, quiet_logger, tmp_path, tmp_path_factory
):
lhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
""")
rhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
more_hash:
key: more value
""")
merged_yaml = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
implicit:
structure:
to:
more_hash:
key: more value
""")

output_dir = tmp_path / "test_merge_hash_with_mergeat_left"
output_dir.mkdir()
output_file = output_dir / "output.yaml"

lhs_yaml = get_yaml_editor()
rhs_yaml = get_yaml_editor()
lhs_data = get_yaml_data(lhs_yaml, quiet_logger, lhs_yaml_file)
rhs_data = get_yaml_data(rhs_yaml, quiet_logger, rhs_yaml_file)

args = SimpleNamespace(hashes="left", mergeat="/implicit/structure/to")
mc = MergerConfig(quiet_logger, args)
merger = Merger(quiet_logger, lhs_data, mc)
merger.merge_with(rhs_data)

with open(output_file, 'w') as yaml_dump:
lhs_yaml.dump(merger.data, yaml_dump)

# DEBUG:
with open(output_file, 'r') as output_fnd, open(merged_yaml, 'r') as merged_fnd:
print("Expected:")
print(merged_fnd.read())
print("Got:")
print(output_fnd.read())

assert (
(os.path.getsize(output_file) == os.path.getsize(merged_yaml))
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)

def test_merge_hash_with_mergeat_right(
self, quiet_logger, tmp_path, tmp_path_factory
):
lhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
""")
rhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
more_hash:
key: more value
""")
merged_yaml = create_temp_yaml_file(tmp_path_factory, """---
hash:
key: value
implicit:
structure:
to:
more_hash:
key: more value
""")

output_dir = tmp_path / "test_merge_hash_with_mergeat_right"
output_dir.mkdir()
output_file = output_dir / "output.yaml"

lhs_yaml = get_yaml_editor()
rhs_yaml = get_yaml_editor()
lhs_data = get_yaml_data(lhs_yaml, quiet_logger, lhs_yaml_file)
rhs_data = get_yaml_data(rhs_yaml, quiet_logger, rhs_yaml_file)

args = SimpleNamespace(hashes="right", mergeat="/implicit/structure/to")
mc = MergerConfig(quiet_logger, args)
merger = Merger(quiet_logger, lhs_data, mc)
merger.merge_with(rhs_data)

with open(output_file, 'w') as yaml_dump:
lhs_yaml.dump(merger.data, yaml_dump)

# DEBUG:
with open(output_file, 'r') as output_fnd, open(merged_yaml, 'r') as merged_fnd:
print("Expected:")
print(merged_fnd.read())
print("Got:")
print(output_fnd.read())

assert (
(os.path.getsize(output_file) == os.path.getsize(merged_yaml))
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)

def test_merge_with_complex_hash_rules(
self, quiet_logger, tmp_path, tmp_path_factory
):
config_file = create_temp_yaml_file(tmp_path_factory, """
[defaults]
hashes = deep
[rules]
/hash/structure/with/several = left
/hash/even = right
/hash/blah = left
/hash/fu = left
/hash/la = right
/hash/ri/fa = left
/force_left = left
/force_right = right
""")
lhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
structure:
with:
several: LHS (several)
keep: LHS (keep)
and:
data: LHS (data)
even: LHS (even)
blah:
tee: LHS (tee)
fu:
ru: LHS (ru)
tu: LHS (tu)
la:
ta: LHS (ta)
da: LHS (da)
ri:
me:
do: LHS (do)
po: LHS (po)
fa:
so: LHS (so)
lhs_exclusive:
key: LHS (key)
force_left: true
force_right: false
""")
rhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
structure:
with:
several: RHS (several)
having: RHS (having)
keep: RHS (keep)
fu:
do: RHS (do)
re: RHS (re)
more: RHS (more)
even: RHS (even)
la:
bi: RHS (bi)
ti: RHS (ti)
blah:
ree: RHS (ree)
ri:
fa:
re: RHS (re)
be: RHS (be)
rhs_exclusive:
another_key: RHS (another_key)
force_left: false
force_right: true
""")
merged_yaml = create_temp_yaml_file(tmp_path_factory, """---
hash:
structure:
with:
several: LHS (several)
having: RHS (having)
keep: RHS (keep)
and:
data: LHS (data)
even: RHS (even)
more: RHS (more)
blah:
tee: LHS (tee)
fu:
ru: LHS (ru)
tu: LHS (tu)
la:
bi: RHS (bi)
ti: RHS (ti)
ri:
me:
do: LHS (do)
po: LHS (po)
fa:
so: LHS (so)
lhs_exclusive:
key: LHS (key)
rhs_exclusive:
another_key: RHS (another_key)
force_left: true
force_right: true
""")

output_dir = tmp_path / "test_merge_with_complex_hash_rules"
output_dir.mkdir()
output_file = output_dir / "output.yaml"

lhs_yaml = get_yaml_editor()
rhs_yaml = get_yaml_editor()
lhs_data = get_yaml_data(lhs_yaml, quiet_logger, lhs_yaml_file)
rhs_data = get_yaml_data(rhs_yaml, quiet_logger, rhs_yaml_file)

args = SimpleNamespace(config=config_file)
mc = MergerConfig(quiet_logger, args)
merger = Merger(quiet_logger, lhs_data, mc)
merger.merge_with(rhs_data)

with open(output_file, 'w') as yaml_dump:
lhs_yaml.dump(merger.data, yaml_dump)

# DEBUG:
# with open(output_file, 'r') as output_fnd, open(merged_yaml, 'r') as merged_fnd:
# print("Expected:")
# print(merged_fnd.read())
# print("Got:")
# print(output_fnd.read())

assert (
(os.path.getsize(output_file) == os.path.getsize(merged_yaml))
and (open(output_file,'r').read() == open(merged_yaml,'r').read())
)
1 change: 1 addition & 0 deletions tests/test_merger_mergerconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ def test_warn_when_rules_matches_zero_nodes(
config_file = create_temp_yaml_file(tmp_path_factory, """
[rules]
/does_not_exist = left
/array_of_hashes[name = "Does Not Compute"] = right
""")
lhs_yaml_file = create_temp_yaml_file(tmp_path_factory, """---
hash:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_yamlpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def test_strip_path_prefix(self, path, prefix, result):
original = YAMLPath(path)
remove = YAMLPath(prefix) if prefix is not None else None
compare = YAMLPath(result)
stripped = YAMLPath.strip_path_prefix(remove, original)
stripped = YAMLPath.strip_path_prefix(original, remove)
assert compare == stripped

def test_parse_double_inversion_error(self):
Expand Down
2 changes: 1 addition & 1 deletion yamlpath/commands/yaml_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from yamlpath.wrappers import ConsolePrinter

# Implied Constants
MY_VERSION = "0.0.2"
MY_VERSION = "0.0.3"

def processcli():
"""Process command-line arguments."""
Expand Down
Loading

0 comments on commit b4962fd

Please sign in to comment.