diff --git a/src/deltacode/__init__.py b/src/deltacode/__init__.py index 6b7c1a55..018a8ef9 100644 --- a/src/deltacode/__init__.py +++ b/src/deltacode/__init__.py @@ -27,6 +27,7 @@ from collections import OrderedDict +from deltacode.models import File from deltacode.models import Scan from deltacode import utils @@ -42,7 +43,15 @@ class DeltaCode(object): def __init__(self, new_path, old_path): self.new = Scan(new_path) self.old = Scan(old_path) - self.deltas = self.determine_delta() + self.deltas = OrderedDict([ + ('added', []), + ('removed', []), + ('modified', []), + ('unmodified', []) + ]) + + if self.new.path != '' and self.old.path != '': + self.determine_delta() def align_scan(self): """ @@ -65,16 +74,6 @@ def determine_delta(self): the objects under the keys 'added', 'modified', 'removed' or 'unmodified'. Return None if no File objects can be loaded from either scan. """ - if self.new.files is None or self.old.files is None: - return None - - deltas = OrderedDict([ - ('added', []), - ('removed', []), - ('modified', []), - ('unmodified', []) - ]) - # align scan and create our index self.align_scan() new_index = self.new.index_files() @@ -95,7 +94,7 @@ def determine_delta(self): try: delta_old_files = old_index[path] except KeyError: - deltas['added'].append(Delta(new_file, None, 'added')) + self.deltas['added'].append(Delta(new_file, None, 'added')) continue # at this point, we have a delta_old_file. @@ -104,11 +103,11 @@ def determine_delta(self): for f in delta_old_files: # TODO: make sure sha1 is NOT empty if new_file.sha1 == f.sha1: - deltas['unmodified'].append(Delta(new_file, f, 'unmodified')) + self.deltas['unmodified'].append(Delta(new_file, f, 'unmodified')) continue else: delta = Delta(new_file, f, 'modified') - deltas['modified'].append(delta) + self.deltas['modified'].append(delta) # now time to find the added. for path, old_files in old_index.items(): @@ -122,15 +121,13 @@ def determine_delta(self): # This file already classified as 'modified' or 'unmodified' so do nothing new_index[path] except KeyError: - deltas['removed'].append(Delta(None, old_file, 'removed')) + self.deltas['removed'].append(Delta(None, old_file, 'removed')) continue # make sure everything is accounted for assert new_files_to_visit == 0 assert old_files_to_visit == 0 - return deltas - def get_stats(self): """ Given a list of Delta objects, return a 'counts' dictionary keyed by @@ -152,9 +149,6 @@ def to_dict(self): objects grouping the objects under the keys 'added', 'removed', 'modified' or 'unmodified'. """ - if self.deltas is None: - return - return OrderedDict([ ('added', [d.to_dict() for d in self.deltas.get('added')]), ('removed', [d.to_dict() for d in self.deltas.get('removed')]), @@ -170,10 +164,9 @@ class Delta(object): 'added', 'modified', 'removed' or 'unmodified'. """ def __init__(self, new_file=None, old_file=None, delta_type=None): - # TODO: add check to ensure both are File objects - self.new_file = new_file - self.old_file = old_file - self.category = delta_type + self.new_file = new_file if new_file else File() + self.old_file = old_file if old_file else File() + self.category = delta_type if delta_type else '' # Change the Delta object's 'category' attribute to # 'license change' if a substantial license change has been detected. @@ -187,9 +180,6 @@ def _license_diff(self, cutoff_score=50): 'license change' if those details differ and the cutoff score test is satisfied. """ - if not self.new_file or not self.old_file: - return - new_licenses = self.new_file.licenses or [] new_keys = set(l.key for l in new_licenses if l.score >= cutoff_score) @@ -204,9 +194,6 @@ def to_dict(self): Check the 'category' attribute of the Delta object and return an OrderedDict comprising the 'category' and 'path' of the object. """ - if self.new_file is None and self.old_file is None: - return - if self.category == 'added': return OrderedDict([ ('category', 'added'), diff --git a/src/deltacode/cli.py b/src/deltacode/cli.py index 629fd038..8e4e708f 100644 --- a/src/deltacode/cli.py +++ b/src/deltacode/cli.py @@ -78,7 +78,7 @@ def cli(new, old, csv_file, json_file): option is selected, print the JSON results to the console. """ # do the delta - delta = DeltaCode(new, old) + delta = DeltaCode(new, old).determine_delta() # output to csv if csv_file: diff --git a/src/deltacode/models.py b/src/deltacode/models.py index d8bf91f9..be1fc99e 100644 --- a/src/deltacode/models.py +++ b/src/deltacode/models.py @@ -38,10 +38,19 @@ class Scan(object): selected key. """ def __init__(self, path=''): - self.path = '' if path is None else path - self.files_count = self.get_files_count(self.path) - self.files = self.load_files(self.path) - self.options = self.get_options(self.path) + if path is None: + path = '' + + if not self.is_valid_scan(path): + self.path = '' + self.files_count = 0 + self.files = [] + self.options = {} + else: + self.path = path + self.files_count = self.get_files_count(path) + self.files = self.load_files(path) + self.options = self.get_options(path) def get_options(self, path): """ @@ -145,18 +154,15 @@ class File(object): File object created from an ABCD formatted 'file' dictionary. """ def __init__(self, dictionary={}): - self.path = dictionary.get('path') - self.type = dictionary.get('type') - self.name = dictionary.get('name') - self.size = dictionary.get('size') - self.sha1 = dictionary.get('sha1') + self.path = dictionary.get('path', '') + self.type = dictionary.get('type', '') + self.name = dictionary.get('name', '') + self.size = dictionary.get('size', '') + self.sha1 = dictionary.get('sha1', '') self.original_path = '' - self.licenses = self.get_licenses(dictionary) + self.licenses = self.get_licenses(dictionary) if dictionary.get('licenses') else [] def get_licenses(self, dictionary): - if dictionary.get('licenses') == None: - return None - if dictionary.get('licenses') == []: return [] else: @@ -173,7 +179,7 @@ def to_dict(self): ]) # TODO: disable this for now due to high memory usage - #if self.licenses: + # if self.licenses: # d['licenses'] = [l.to_dict() for l in self.licenses] return d diff --git a/tests/test_deltacode.py b/tests/test_deltacode.py index 7cb0508c..038d4da2 100644 --- a/tests/test_deltacode.py +++ b/tests/test_deltacode.py @@ -345,7 +345,7 @@ def test_DeltaCode_to_dict_empty(self): result = delta.to_dict() - assert result == None + assert result == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])]) def test_DeltaCode_invalid_paths(self): test_path_1 = '/some/invalid/path/1.json' @@ -353,41 +353,40 @@ def test_DeltaCode_invalid_paths(self): result = DeltaCode(test_path_1, test_path_2) - assert result.new.path == '/some/invalid/path/1.json' - assert result.new.files_count == None - assert result.new.files == None + assert result.new.path == '' + assert result.new.files_count == 0 + assert result.new.files == [] - assert result.old.path == '/some/invalid/path/2.json' - assert result.new.files_count == None - assert result.old.files == None + assert result.old.path == '' + assert result.old.files_count == 0 + assert result.old.files == [] - assert result.deltas == None + assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])]) def test_DeltaCode_empty_paths(self): result = DeltaCode('', '') assert result.new.path == '' - assert result.new.files_count == None - assert result.new.files == None + assert result.new.files_count == 0 + assert result.new.files == [] assert result.old.path == '' - assert result.new.files_count == None - assert result.old.files == None + assert result.old.files_count == 0 + assert result.old.files == [] - assert result.deltas == None + assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])]) def test_DeltaCode_None_paths(self): result = DeltaCode(None, None) assert result.new.path == '' - assert result.new.files_count == None - assert result.new.files == None + assert result.new.files_count == 0 + assert result.new.files == [] assert result.old.path == '' - assert result.new.files_count == None - assert result.old.files == None - - assert result.deltas == None + assert result.old.files_count == 0 + assert result.old.files == [] + assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])]) def test_Delta_license_diff_new_no_license_info(self): new_file = models.File({'path': 'new/path.txt'}) @@ -493,9 +492,9 @@ def test_Delta_license_diff_one_None(self): def test_Delta_license_diff_None_files(self): delta = deltacode.Delta(None, None, None) - assert delta.new_file == None - assert delta.old_file == None - assert delta.category == None + assert type(delta.new_file) == type(models.File()) + assert type(delta.old_file) == type(models.File()) + assert delta.category == '' def test_DeltaCode_license_modified_low_score(self): new_scan = self.get_test_loc('deltacode/scan_modified_new_license_added_low_score.json') @@ -678,7 +677,7 @@ def test_Delta_to_dict_unmodified(self): def test_Delta_to_dict_empty(self): delta = deltacode.Delta() - assert delta.to_dict() == None + assert delta.to_dict() == OrderedDict([('category', 'unmodified'), ('path', '')]) def test_Delta_create_object_removed(self): new = None @@ -686,7 +685,7 @@ def test_Delta_create_object_removed(self): delta = deltacode.Delta(new, old, 'removed') - assert delta.new_file == None + assert type(delta.new_file) == type(models.File()) assert delta.old_file.path == 'path/removed.txt' assert delta.category == 'removed' @@ -697,7 +696,7 @@ def test_Delta_create_object_added(self): delta = deltacode.Delta(new, old, 'added') assert delta.new_file.path == 'path/added.txt' - assert delta.old_file == None + assert type(delta.old_file) == type(models.File()) assert delta.category == 'added' def test_Delta_create_object_modified(self): @@ -727,6 +726,6 @@ def test_Delta_create_object_unmodified(self): def test_Delta_create_object_empty(self): delta = deltacode.Delta() - assert delta.new_file == None - assert delta.old_file == None - assert delta.category == None + assert type(delta.new_file) == type(models.File()) + assert type(delta.old_file) == type(models.File()) + assert delta.category == '' diff --git a/tests/test_models.py b/tests/test_models.py index 483ed12f..c6a895c4 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -344,26 +344,26 @@ def test_Scan_invalid_path(self): result = models.Scan(test_path) - assert result.path == '/some/invalid/path.json' - assert result.files_count == None - assert result.files == None - assert result.options == None + assert result.path == '' + assert result.files_count == 0 + assert result.files == [] + assert result.options == {} def test_Scan_empty_path(self): result = models.Scan('') assert result.path == '' - assert result.files_count == None - assert result.files == None - assert result.options == None + assert result.files_count == 0 + assert result.files == [] + assert result.options == {} def test_Scan_None_path(self): result = models.Scan(None) assert result.path == '' - assert result.files_count == None - assert result.files == None - assert result.options == None + assert result.files_count == 0 + assert result.files == [] + assert result.options == {} def test_License_to_dict_simple(self): data = { @@ -549,11 +549,11 @@ def test_File_to_dict_empty(self): empty_file = models.File() expected = { - 'path': None, - 'type': None, - 'name': None, - 'size': None, - 'sha1': None, + 'path': '', + 'type': '', + 'name': '', + 'size': '', + 'sha1': '', 'original_path': '' } @@ -621,6 +621,29 @@ def test_File_create_object_license_none(self): assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1 assert [] == result.licenses + def test_File_create_object_license_missing(self): + data = { + 'path': 'a/b/file1.txt', + 'type': 'file', + 'name': 'file1.txt', + 'size': 20, + 'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b', + } + + result = models.File(data) + + assert [] == result.licenses + + def test_File_empty(self): + empty_file = models.File() + + assert empty_file.path == '' + assert empty_file.type == '' + assert empty_file.name == '' + assert empty_file.size == '' + assert empty_file.sha1 == '' + assert empty_file.licenses == [] + def test_File_create_object(self): data = { 'path': 'a/b/file1.txt',