Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 17 additions & 30 deletions src/deltacode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from collections import OrderedDict

from deltacode.models import File
from deltacode.models import Scan
from deltacode import utils

Expand All @@ -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):
"""
Expand All @@ -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()
Expand All @@ -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.
Expand All @@ -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():
Expand All @@ -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
Expand All @@ -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')]),
Expand All @@ -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.
Expand All @@ -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)

Expand All @@ -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'),
Expand Down
2 changes: 1 addition & 1 deletion src/deltacode/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
34 changes: 20 additions & 14 deletions src/deltacode/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
55 changes: 27 additions & 28 deletions tests/test_deltacode.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,49 +345,48 @@ 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'
test_path_2 = '/some/invalid/path/2.json'

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'})
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -678,15 +677,15 @@ 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
old = models.File({'path': 'path/removed.txt'})

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'

Expand All @@ -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):
Expand Down Expand Up @@ -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 == ''
53 changes: 38 additions & 15 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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': ''
}

Expand Down Expand Up @@ -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',
Expand Down