Skip to content
Closed
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
24 changes: 17 additions & 7 deletions src/attributecode/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@
from attributecode import saneyaml
from attributecode import util
from attributecode.util import add_unc
from attributecode.util import boolean_fields
from attributecode.util import copy_license_notice_files
from attributecode.util import check_duplicate_keys_about_file
from attributecode.util import on_windows
from attributecode.util import wrap_boolean_value
from attributecode.util import UNC_PREFIX
from attributecode.util import UNC_PREFIX_POSIX

Expand Down Expand Up @@ -114,7 +116,8 @@ def validate(self, *args, **kwargs):
pass"""
else:
# present fields should have content ...
if not self.has_content:
# Note that 'False' can be a value for boolean field
if not name in boolean_fields and not self.has_content:
# ... especially if required
if self.required:
msg = u'Field %(name)s is required and empty'
Expand Down Expand Up @@ -563,9 +566,8 @@ def _validate(self, *args, **kwargs):
self.value = None
elif flag is None:
name = self.name
msg = (u'Field %(name)s: field is empty. '
u'Defaulting flag to no.' % locals())
errors.append(Error(INFO, msg))
msg = (u'Field %(name)s: field is present but empty. ' % locals())
errors.append(Error(WARNING, msg))
self.value = None
else:
self.value = self.flags.get(flag)
Expand Down Expand Up @@ -790,6 +792,7 @@ def all_fields(self, with_absent=True, with_empty=True):
If with_empty, include empty fields.
"""
all_fields = []

for field in list(self.fields.values()) + list(self.custom_fields.values()):
if field.required:
all_fields.append(field)
Expand All @@ -800,8 +803,11 @@ def all_fields(self, with_absent=True, with_empty=True):
elif field.present:
if with_empty:
all_fields.append(field)
elif field.present and field.value:
all_fields.append(field)
elif field.present:
if field.value:
all_fields.append(field)
elif field.name in boolean_fields and not field.value == None:
all_fields.append(field)

else:
if field.present:
Expand Down Expand Up @@ -985,6 +991,10 @@ def load(self, location, use_mapping=False, mapping_file=None):
with codecs.open(loc, encoding='utf-8') as txt:
input_text = txt.read()
dup_keys = check_duplicate_keys_about_file(input_text)
# The 'Yes' and 'No' will be converted to 'True' and 'False' in the yaml.load()
# Therefore, we need to wrap the original value in quote to prevent
# the conversion
input = wrap_boolean_value(input_text)
if dup_keys:
msg = ('Duplicated key name(s): %(dup_keys)s' % locals())
errors.append(Error(ERROR, msg % locals()))
Expand All @@ -999,7 +1009,7 @@ def load(self, location, use_mapping=False, mapping_file=None):
and then join with the 'about_resource_path'
"""
running_inventory = True
errs = self.load_dict(saneyaml.load(input_text), base_dir, running_inventory, use_mapping, mapping_file)
errs = self.load_dict(saneyaml.load(input), base_dir, running_inventory, use_mapping, mapping_file)
errors.extend(errs)
except Exception as e:
msg = 'Cannot load invalid ABOUT file: %(location)r: %(e)r\n' + str(e)
Expand Down
18 changes: 17 additions & 1 deletion src/attributecode/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@
from attributecode import CRITICAL, INFO
from attributecode import Error


on_windows = 'win32' in sys.platform

# boolean field name
boolean_fields = ['redistribute', 'attribute', 'track_change', 'modified']


def to_posix(path):
"""
Expand Down Expand Up @@ -123,6 +125,20 @@ def check_file_names(paths):
seen[path] = orig_path
return errors

def wrap_boolean_value(context):
updated_context = ''
for line in context.splitlines():
"""
wrap the boolean value in quote
"""
key = line.partition(':')[0]
value = line.partition(':')[2].strip()
if key in boolean_fields and value:
value = '"' + value + '"'
updated_context += key + ': ' + value + '\n'
else:
updated_context += line + '\n'
return updated_context

def check_duplicate_keys_about_file(context):
keys = []
Expand Down
17 changes: 17 additions & 0 deletions tests/test_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,20 @@ def test_deduplicate(self):
expected = ['a', 'b', 'd', 'c']
results = gen.deduplicate(items)
assert expected == results

def test_boolean_value_not_lost(self):
location = get_test_loc('gen/inv6.csv')
base_dir = get_temp_dir()

errors, abouts = gen.generate(location, base_dir)

in_mem_result = [a.dumps(with_absent=False, with_empty=False)
for a in abouts][0]
expected = (u'about_resource: .\n'
u'name: AboutCode\n'
u'about_resource_path: .\n'
u'version: 0.11.0\n'
u'redistribute: yes\n'
u'attribute: yes\n'
u'modified: no\n')
assert expected == in_mem_result
2 changes: 1 addition & 1 deletion tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def test_About_dumps_does_not_transform_strings_in_lists(self):
notice_file: NOTICE
notice_url:
redistribute:
attribute:
attribute: yes
track_change:
modified:
changelog_file:
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/gen/inv6.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
about_file_path,about_resource,name,version,download_url,description,homepage_url,notes,license_name,license_file,license_url,copyright,notice_file,notice_url,redistribute,attribute,track_change,modified,changelog_file,owner,owner_url,contact,author,vcs_tool,vcs_repository,vcs_path,vcs_tag,vcs_branch,vcs_revision,checksum_md5,checksum_sha1,spec_version
inv/this.ABOUT,.,AboutCode,0.11.0,,,,,,,,,,,Yes,Y,,N,,,,,,,,,,,,,,