Add recipe_diff function and helpers.
This takes a pair of Recipe objects and returns a list of diff dicts that include what was changed between the two recipes.
This commit is contained in:
parent
a76e95dcb5
commit
052a8ba991
@ -718,3 +718,83 @@ def is_parent_diff(repo, filename, tree, parent):
|
|||||||
diff_opts.set_pathspec([filename])
|
diff_opts.set_pathspec([filename])
|
||||||
diff = Git.Diff.new_tree_to_tree(repo, parent.get_tree(), tree, diff_opts)
|
diff = Git.Diff.new_tree_to_tree(repo, parent.get_tree(), tree, diff_opts)
|
||||||
return diff.get_num_deltas() > 0
|
return diff.get_num_deltas() > 0
|
||||||
|
|
||||||
|
def find_name(name, lst):
|
||||||
|
"""Find the dict matching the name in a list and return it.
|
||||||
|
|
||||||
|
:param name: Name to search for
|
||||||
|
:type name: str
|
||||||
|
:param lst: List of dict's with "name" field
|
||||||
|
:returns: First dict with matching name, or None
|
||||||
|
:rtype: dict or None
|
||||||
|
"""
|
||||||
|
for e in lst:
|
||||||
|
if e["name"] == name:
|
||||||
|
return e
|
||||||
|
return None
|
||||||
|
|
||||||
|
def diff_items(title, old_items, new_items):
|
||||||
|
"""Return the differences between two lists of dicts.
|
||||||
|
|
||||||
|
:param title: Title of the entry
|
||||||
|
:type title: str
|
||||||
|
:param old_items: List of item dicts with "name" field
|
||||||
|
:type old_items: list(dict)
|
||||||
|
:param new_items: List of item dicts with "name" field
|
||||||
|
:type new_items: list(dict)
|
||||||
|
:returns: List of diff dicts with old/new entries
|
||||||
|
:rtype: list(dict)
|
||||||
|
"""
|
||||||
|
diffs = []
|
||||||
|
old_names = set(m["name"] for m in old_items)
|
||||||
|
new_names = set(m["name"] for m in new_items)
|
||||||
|
|
||||||
|
added_items = new_names.difference(old_names)
|
||||||
|
added_items = sorted(added_items, key=lambda n: n.lower())
|
||||||
|
|
||||||
|
removed_items = old_names.difference(new_names)
|
||||||
|
removed_items = sorted(removed_items, key=lambda n: n.lower())
|
||||||
|
|
||||||
|
same_items = old_names.intersection(new_names)
|
||||||
|
same_items = sorted(same_items, key=lambda n: n.lower())
|
||||||
|
|
||||||
|
for name in added_items:
|
||||||
|
diffs.append({"old":None,
|
||||||
|
"new":{title:find_name(name, new_items)}})
|
||||||
|
|
||||||
|
for name in removed_items:
|
||||||
|
diffs.append({"old":{title:find_name(name, old_items)},
|
||||||
|
"new":None})
|
||||||
|
|
||||||
|
for name in same_items:
|
||||||
|
old_item = find_name(name, old_items)
|
||||||
|
new_item = find_name(name, new_items)
|
||||||
|
if old_item != new_item:
|
||||||
|
diffs.append({"old":{title:old_item},
|
||||||
|
"new":{title:new_item}})
|
||||||
|
|
||||||
|
return diffs
|
||||||
|
|
||||||
|
|
||||||
|
def recipe_diff(old_recipe, new_recipe):
|
||||||
|
"""Diff two versions of a recipe
|
||||||
|
|
||||||
|
:param old_recipe: The old version of the recipe
|
||||||
|
:type old_recipe: Recipe
|
||||||
|
:param new_recipe: The new version of the recipe
|
||||||
|
:type new_recipe: Recipe
|
||||||
|
:returns: A list of diff dict entries with old/new
|
||||||
|
:rtype: list(dict)
|
||||||
|
"""
|
||||||
|
|
||||||
|
diffs = []
|
||||||
|
# These cannot be added or removed, just different
|
||||||
|
for element in ["name", "description", "version"]:
|
||||||
|
if old_recipe[element] != new_recipe[element]:
|
||||||
|
diffs.append({"old":{element.title():old_recipe[element]},
|
||||||
|
"new":{element.title():new_recipe[element]}})
|
||||||
|
|
||||||
|
diffs.extend(diff_items("Module", old_recipe["modules"], new_recipe["modules"]))
|
||||||
|
diffs.extend(diff_items("Package", old_recipe["packages"], new_recipe["packages"]))
|
||||||
|
|
||||||
|
return diffs
|
||||||
|
@ -39,6 +39,25 @@ class BasicRecipeTest(unittest.TestCase):
|
|||||||
result_dict = eval(f_dict.read())
|
result_dict = eval(f_dict.read())
|
||||||
self.input_toml.append((f_toml.read(), result_dict))
|
self.input_toml.append((f_toml.read(), result_dict))
|
||||||
|
|
||||||
|
self.old_modules = [recipes.RecipeModule("toml", "2.1"),
|
||||||
|
recipes.RecipeModule("bash", "4.*"),
|
||||||
|
recipes.RecipeModule("httpd", "3.7.*")]
|
||||||
|
self.old_packages = [recipes.RecipePackage("python", "2.7.*"),
|
||||||
|
recipes.RecipePackage("parted", "3.2")]
|
||||||
|
self.new_modules = [recipes.RecipeModule("toml", "2.1"),
|
||||||
|
recipes.RecipeModule("httpd", "3.8.*"),
|
||||||
|
recipes.RecipeModule("openssh", "2.8.1")]
|
||||||
|
self.new_packages = [recipes.RecipePackage("python", "2.7.*"),
|
||||||
|
recipes.RecipePackage("parted", "3.2"),
|
||||||
|
recipes.RecipePackage("git", "2.13.*")]
|
||||||
|
self.modules_result = [{"new": {"Modules": {"version": "2.8.1", "name": "openssh"}},
|
||||||
|
"old": None},
|
||||||
|
{"new": None,
|
||||||
|
"old": {"Modules": {"name": "bash", "version": "4.*"}}},
|
||||||
|
{"new": {"Modules": {"version": "3.8.*", "name": "httpd"}},
|
||||||
|
"old": {"Modules": {"version": "3.7.*", "name": "httpd"}}}]
|
||||||
|
self.packages_result = [{"new": {"Packages": {"name": "git", "version": "2.13.*"}}, "old": None}]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(self):
|
def tearDownClass(self):
|
||||||
pass
|
pass
|
||||||
@ -97,6 +116,30 @@ class BasicRecipeTest(unittest.TestCase):
|
|||||||
new_version = recipe.bump_version("0.0.1")
|
new_version = recipe.bump_version("0.0.1")
|
||||||
self.assertEqual(new_version, "0.1.1")
|
self.assertEqual(new_version, "0.1.1")
|
||||||
|
|
||||||
|
def find_name_test(self):
|
||||||
|
"""Test the find_name function"""
|
||||||
|
test_list = [{"name":"dog"}, {"name":"cat"}, {"name":"squirrel"}]
|
||||||
|
|
||||||
|
self.assertEqual(recipes.find_name("dog", test_list), {"name":"dog"})
|
||||||
|
self.assertEqual(recipes.find_name("cat", test_list), {"name":"cat"})
|
||||||
|
self.assertEqual(recipes.find_name("squirrel", test_list), {"name":"squirrel"})
|
||||||
|
|
||||||
|
def diff_items_test(self):
|
||||||
|
"""Test the diff_items function"""
|
||||||
|
self.assertEqual(recipes.diff_items("Modules", self.old_modules, self.new_modules), self.modules_result)
|
||||||
|
self.assertEqual(recipes.diff_items("Packages", self.old_packages, self.new_packages), self.packages_result)
|
||||||
|
|
||||||
|
def recipe_diff_test(self):
|
||||||
|
"""Test the recipe_diff function"""
|
||||||
|
old_recipe = recipes.Recipe("test-recipe", "A recipe used for testing", "0.1.1", self.old_modules, self.old_packages)
|
||||||
|
new_recipe = recipes.Recipe("test-recipe", "A recipe used for testing", "0.3.1", self.new_modules, self.new_packages)
|
||||||
|
result = [{'new': {'Version': '0.3.1'}, 'old': {'Version': '0.1.1'}},
|
||||||
|
{'new': {'Module': {'name': 'openssh', 'version': '2.8.1'}}, 'old': None},
|
||||||
|
{'new': None, 'old': {'Module': {'name': 'bash', 'version': '4.*'}}},
|
||||||
|
{'new': {'Module': {'name': 'httpd', 'version': '3.8.*'}},
|
||||||
|
'old': {'Module': {'name': 'httpd', 'version': '3.7.*'}}},
|
||||||
|
{'new': {'Package': {'name': 'git', 'version': '2.13.*'}}, 'old': None}]
|
||||||
|
self.assertEqual(recipes.recipe_diff(old_recipe, new_recipe), result)
|
||||||
|
|
||||||
class GitRecipesTest(unittest.TestCase):
|
class GitRecipesTest(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
Loading…
Reference in New Issue
Block a user