Skip to content

Commit 5c7bd00

Browse files
committed
Merge branch '403_invalid_info_for_false_boolean_field' into develop
2 parents daa925f + 89d2788 commit 5c7bd00

File tree

6 files changed

+78
-9
lines changed

6 files changed

+78
-9
lines changed

src/attributecode/model.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@
6161
from attributecode import saneyaml
6262
from attributecode import util
6363
from attributecode.util import add_unc
64+
from attributecode.util import boolean_fields
6465
from attributecode.util import copy_license_notice_files
6566
from attributecode.util import csv
6667
from attributecode.util import filter_errors
6768
from attributecode.util import is_valid_name
6869
from attributecode.util import on_windows
70+
from attributecode.util import wrap_boolean_value
6971
from attributecode.util import UNC_PREFIX
7072
from attributecode.util import ungroup_licenses
7173
from attributecode.util import unique
@@ -119,7 +121,7 @@ def validate(self, *args, **kwargs):
119121
# present fields should have content ...
120122
# The boolean value can be True, False and None
121123
# The value True or False is the content of boolean fields
122-
if not self.has_content:
124+
if not name in boolean_fields and not self.has_content:
123125
# ... especially if required
124126
if self.required:
125127
msg = u'Field %(name)s is required and empty'
@@ -585,8 +587,7 @@ def _validate(self, *args, **kwargs):
585587
self.value = None
586588
elif flag is None:
587589
name = self.name
588-
msg = (u'Field %(name)s: field is empty. '
589-
u'Defaulting flag to no.' % locals())
590+
msg = (u'Field %(name)s: field is present but empty. ' % locals())
590591
errors.append(Error(INFO, msg))
591592
self.value = None
592593
else:
@@ -896,7 +897,6 @@ def process(self, fields, about_file_path, running_inventory=False,
896897
afp = self.about_file_path
897898

898899
errors = self.hydrate(fields)
899-
900900
# We want to copy the license_files before the validation
901901
if reference_dir:
902902
copy_license_notice_files(
@@ -926,6 +926,10 @@ def load(self, location):
926926
loc = add_unc(loc)
927927
with io.open(loc, encoding='utf-8') as txt:
928928
input_text = txt.read()
929+
# The 'Yes' and 'No' will be converted to 'True' and 'False' in the yaml.load()
930+
# Therefore, we need to wrap the original value in quote to prevent
931+
# the conversion
932+
input = wrap_boolean_value(input_text)
929933
# FIXME: this should be done in the commands, not here
930934
"""
931935
The running_inventory defines if the current process is 'inventory' or not.
@@ -937,7 +941,7 @@ def load(self, location):
937941
and then join with the 'about_resource'
938942
"""
939943
running_inventory = True
940-
data = saneyaml.load(input_text, allow_duplicate_keys=False)
944+
data = saneyaml.load(input, allow_duplicate_keys=False)
941945
errs = self.load_dict(data, base_dir, running_inventory)
942946
errors.extend(errs)
943947
except Exception as e:
@@ -979,6 +983,7 @@ def load_dict(self, fields_dict, base_dir, running_inventory=False, reference_di
979983
# 'Field licenses is a custom field.'
980984
licenses_field = (key, value)
981985
fields.remove(licenses_field)
986+
982987
errors = self.process(
983988
fields=fields,
984989
about_file_path=self.about_file_path,
@@ -1009,9 +1014,9 @@ def dumps(self):
10091014
license_file = []
10101015
license_url = []
10111016
file_fields = ['about_resource', 'notice_file', 'changelog_file', 'author_file']
1012-
bool_fields = ['redistribute', 'attribute', 'track_changes', 'modified']
1017+
bool_fields = ['redistribute', 'attribute', 'track_changes', 'modified', 'internal_use_only']
10131018
for field in self.all_fields():
1014-
if not field.value:
1019+
if not field.value and not field.name in bool_fields:
10151020
continue
10161021

10171022
if field.name == 'license_key' and field.value:
@@ -1028,8 +1033,10 @@ def dumps(self):
10281033
# value of 'about_resource'
10291034
elif field.name in file_fields and field.value:
10301035
data[field.name] = list(field.value.keys())[0]
1036+
elif field.name in bool_fields and not field.value == None:
1037+
data[field.name] = field.value
10311038
else:
1032-
if field.value or (field.name in bool_fields and not field.value == None):
1039+
if field.value:
10331040
data[field.name] = field.value
10341041

10351042
# Group the same license information in a list
@@ -1127,7 +1134,6 @@ def collect_inventory(location):
11271134
msg = (about_file_path + ": " + message)
11281135
errors.append(Error(severity, msg))
11291136
abouts.append(about)
1130-
11311137
return unique(errors), abouts
11321138

11331139

src/attributecode/util.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151

5252
on_windows = 'win32' in sys.platform
5353

54+
# boolean field name
55+
boolean_fields = ['redistribute', 'attribute', 'track_change', 'modified', 'internal_use_only']
5456

5557
def to_posix(path):
5658
"""
@@ -123,6 +125,20 @@ def check_file_names(paths):
123125
seen[path] = orig_path
124126
return errors
125127

128+
def wrap_boolean_value(context):
129+
updated_context = ''
130+
for line in context.splitlines():
131+
"""
132+
wrap the boolean value in quote
133+
"""
134+
key = line.partition(':')[0]
135+
value = line.partition(':')[2].strip()
136+
value = '"' + value + '"'
137+
if key in boolean_fields and not value == "":
138+
updated_context += key + ': ' + value + '\n'
139+
else:
140+
updated_context += line + '\n'
141+
return updated_context
126142

127143
# TODO: rename to normalize_path
128144
def get_absolute(location):

tests/test_gen.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,18 @@ def test_generate_not_overwrite_original_license_file(self):
199199
'licenses:\n'
200200
' - file: this.LICENSE\n')
201201
assert expected == result
202+
203+
def test_boolean_value_not_lost(self):
204+
location = get_test_loc('test_gen/inv6.csv')
205+
base_dir = get_temp_dir()
206+
207+
_errors, abouts = gen.generate(location, base_dir)
208+
209+
in_mem_result = [a.dumps() for a in abouts][0]
210+
expected = (u'about_resource: .\n'
211+
u'name: AboutCode\n'
212+
u'version: 0.11.0\n'
213+
u'redistribute: yes\n'
214+
u'attribute: yes\n'
215+
u'modified: no\n')
216+
assert expected == in_mem_result

tests/test_model.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,27 @@ def test_About_invalid_boolean_value(self):
578578
expected_msg = "Field modified: Invalid flag value: 'blah'"
579579
assert expected_msg in a.errors[0].message
580580

581+
def test_About_boolean_value(self):
582+
test_file = get_test_loc('test_model/parse/boolean_data.about')
583+
a = model.About(test_file)
584+
expected_msg = "Field track_changes is present but empty."
585+
assert expected_msg in a.errors[0].message
586+
# Context of the test file
587+
"""
588+
about_resource: .
589+
name: boolean_data
590+
attribute: False
591+
modified: true
592+
internal_use_only: no
593+
redistribute: yes
594+
track_changes:
595+
"""
596+
assert a.attribute.value is False
597+
assert a.modified.value is True
598+
assert a.internal_use_only.value is False
599+
assert a.redistribute.value is True
600+
assert a.track_changes.value is None
601+
581602
def test_About_contains_about_file_path(self):
582603
test_file = get_test_loc('test_model/serialize/about.ABOUT')
583604
# TODO: I am not sure this override of the about_file_path makes sense
@@ -681,6 +702,8 @@ def test_About_dumps_does_all_non_empty_present_fields(self):
681702
Error(INFO, 'Field custom2 is a custom field.'),
682703
Error(INFO, 'Field custom2 is present but empty.')
683704
]
705+
print("########################################")
706+
print(a.errors)
684707
assert sorted(expected_error) == sorted(a.errors)
685708

686709
expected = '''about_resource: .

tests/testdata/test_gen/inv6.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
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
2+
inv/this.ABOUT,.,AboutCode,0.11.0,,,,,,,,,,,Yes,Y,,N,,,,,,,,,,,,,,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
about_resource: .
2+
name: boolean_data
3+
attribute: False
4+
modified: true
5+
internal_use_only: no
6+
redistribute: yes
7+
track_changes:

0 commit comments

Comments
 (0)