Skip to content

Commit 0796c21

Browse files
committed
Add support for about_resource_path #287
* Added 'about_resource_path' ABOUT object * Update code for the validation for the 'about_resource_path' * Update test code (There are still some failing tests) * Commented out the non-use code for now (will be removed later when everything works fine) Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 8fe489c commit 0796c21

File tree

2 files changed

+42
-12
lines changed

2 files changed

+42
-12
lines changed

src/attributecode/model.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ def _validate(self, *args, **kwargs):
362362
relative paths to actual file locations.
363363
"""
364364
errors = super(PathField, self)._validate(*args, ** kwargs)
365+
self.about_file_path = kwargs.get('about_file_path')
366+
self.running_inventory = kwargs.get('running_inventory')
365367
self.base_dir = kwargs.get('base_dir')
366368
self.license_notice_text_location = kwargs.get('license_notice_text_location')
367369

@@ -391,7 +393,20 @@ def _validate(self, *args, **kwargs):
391393
if self.license_notice_text_location:
392394
location = posixpath.join(self.license_notice_text_location, path)
393395
else:
394-
location = posixpath.join(self.base_dir, path)
396+
# The 'about_resource_path' should be a joined path with
397+
# the 'about_file_path' and the 'base_dir
398+
if not self.running_inventory and name == 'about_resource_path':
399+
# Get the parent directory of the 'about_file_path'
400+
afp_parent = posixpath.dirname(self.about_file_path)
401+
402+
# Create a relative 'about_resource_path' by joining the
403+
# parent of the 'about_file_path' with the value of the
404+
# 'about_resource_path'
405+
arp = posixpath.join(afp_parent, path)
406+
normalized_arp = posixpath.normpath(arp).strip(posixpath.sep)
407+
location = posixpath.join(self.base_dir, normalized_arp)
408+
else:
409+
location = posixpath.join(self.base_dir, path)
395410
location = util.to_native(location)
396411
location = os.path.abspath(os.path.normpath(location))
397412
location = util.to_posix(location)
@@ -584,14 +599,14 @@ def __eq__(self, other):
584599
and self.value == other.value)
585600

586601

587-
def validate_fields(fields, base_dir, license_notice_text_location=None):
602+
def validate_fields(fields, about_file_path, running_inventory, base_dir, license_notice_text_location=None):
588603
"""
589604
Validate a sequence of Field objects. Return a list of errors.
590605
Validation may update the Field objects as needed as a side effect.
591606
"""
592607
errors = []
593608
for f in fields:
594-
val_err = f.validate(base_dir=base_dir, license_notice_text_location=license_notice_text_location)
609+
val_err = f.validate(base_dir=base_dir, about_file_path=about_file_path, running_inventory=running_inventory, license_notice_text_location=license_notice_text_location)
595610
errors.extend(val_err)
596611
return errors
597612

@@ -622,6 +637,7 @@ def create_fields(self):
622637
self.fields = OrderedDict([
623638
('about_resource', AboutResourceField(required=True)),
624639
('name', SingleLineField(required=True)),
640+
('about_resource_path', PathField()),
625641

626642
('version', SingleLineField()),
627643
('download_url', UrlField()),
@@ -871,7 +887,7 @@ def hydrate(self, fields):
871887
errors.append(Error(INFO, msg % locals()))
872888
return errors
873889

874-
def process(self, fields, base_dir=None, license_notice_text_location=None):
890+
def process(self, fields, about_file_path, running_inventory=False, base_dir=None, license_notice_text_location=None):
875891
"""
876892
Hydrate and validate a sequence of field name/value tuples from an
877893
ABOUT file. Return a list of errors.
@@ -889,7 +905,7 @@ def process(self, fields, base_dir=None, license_notice_text_location=None):
889905

890906
# we validate all fields, not only these hydrated
891907
all_fields = self.all_fields()
892-
validation_errors = validate_fields(all_fields, self.base_dir, self.license_notice_text_location)
908+
validation_errors = validate_fields(all_fields, about_file_path, running_inventory, self.base_dir, self.license_notice_text_location)
893909
errors.extend(validation_errors)
894910

895911
# do not forget to resolve about resource paths
@@ -908,7 +924,17 @@ def load(self, location):
908924
try:
909925
loc = add_unc(loc)
910926
input_text = codecs.open(loc, encoding='utf-8').read()
911-
errs = self.load_dict(saneyaml.load(input_text), base_dir)
927+
"""
928+
The running_inventory defines if the current process is 'inventory' or not.
929+
This is used for the validation of the about_resource_path.
930+
In the 'inventory' command, the code will use the parent of the about_file_path
931+
location and join with the 'about_resource_path' for the validation.
932+
On the other hand, in the 'gen' command, the code will use the
933+
generated location (aka base_dir) along with the parent of the about_file_path
934+
and then join with the 'about_resource_path'
935+
"""
936+
running_inventory = True
937+
errs = self.load_dict(saneyaml.load(input_text), base_dir, running_inventory)
912938
errors.extend(errs)
913939
except Exception, e:
914940
msg = 'Cannot load invalid ABOUT file: %(location)r: %(e)r\n' + str(e)
@@ -938,17 +964,18 @@ def load_lines(self, lines, base_dir):
938964
self.errors = errors
939965
return errors
940966

941-
def load_dict(self, fields_dict, base_dir, license_notice_text_location=None, with_empty=True):
967+
def load_dict(self, fields_dict, base_dir, running_inventory=False, license_notice_text_location=None, with_empty=True):
942968
"""
943969
Load the ABOUT file from a fields name/value mapping.
944970
If with_empty, create fields with no value for empty fields.
945971
Return a list of
946972
errors.
947973
"""
948974
fields = fields_dict.items()
975+
about_file_path = self.about_file_path
949976
if not with_empty:
950977
fields = [(n, v) for n, v in fields_dict.items() if v]
951-
errors = self.process(fields, base_dir, license_notice_text_location)
978+
errors = self.process(fields, about_file_path, running_inventory, base_dir, license_notice_text_location)
952979
self.errors = errors
953980
return errors
954981

@@ -1154,7 +1181,7 @@ def field_names(abouts, with_paths=True, with_absent=True, with_empty=True):
11541181
fields = []
11551182
if with_paths:
11561183
fields.append(About.about_file_path_attr)
1157-
fields.append(About.about_resource_path_attr)
1184+
#fields.append(About.about_resource_path_attr)
11581185

11591186
standard_fields = About().fields.keys()
11601187
if with_absent:
@@ -1206,10 +1233,10 @@ def about_object_to_list_of_dictionary(abouts, with_absent=False, with_empty=Tru
12061233
afp = ad['about_file_path']
12071234
afp = '/' + afp if not afp.startswith('/') else afp
12081235
ad['about_file_path'] = afp
1209-
if 'about_resource_path' in ad.keys():
1236+
"""if 'about_resource_path' in ad.keys():
12101237
arp = ad['about_resource_path']
12111238
arp = '/' + arp if not arp.startswith('/') else arp
1212-
ad['about_resource_path'] = arp
1239+
ad['about_resource_path'] = arp"""
12131240
# Make the 'about_resource_path' endswith '/' if the 'about_resource'
12141241
# reference the current directory
12151242
if 'about_resource' in ad.keys() and ad['about_resource'] == '.':

tests/test_model.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ def test_About_dumps_does_not_transform_strings_in_lists(self):
578578
a = model.About(test_file, about_file_path='complete2/about.ABOUT')
579579
expected = u'''about_resource: .
580580
name: AboutCode
581+
about_resource_path:
581582
version: 0.11.0
582583
download_url:
583584
description: AboutCode is a tool to process ABOUT files. An ABOUT file is a file.
@@ -648,9 +649,10 @@ def test_field_names(self):
648649
# and that all fields are in the correct order
649650
expected = [
650651
model.About.about_file_path_attr,
651-
model.About.about_resource_path_attr,
652+
#model.About.about_resource_path_attr,
652653
'about_resource',
653654
'name',
655+
'about_resource_path',
654656
'version',
655657
'download_url',
656658
'description',
@@ -857,6 +859,7 @@ def test_About_as_dict_with_present(self):
857859
Error(WARNING, u'Field author is present but empty')]
858860
assert expected_errors == a.errors
859861
expected = {'about_resource': u'.',
862+
'about_resource_path': u'',
860863
'author': u'',
861864
'attribute': u'',
862865
'changelog_file': u'',

0 commit comments

Comments
 (0)