Skip to content

Commit c05602b

Browse files
committed
#364 - Remove the about_file_path key/column from input/output
- It will not output the `about_file_path` key/column in the output (which include the generated about_files and the csv/json file). - the `about_resource` is now an essential/required field Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 5d5a1fc commit c05602b

File tree

20 files changed

+140
-125
lines changed

20 files changed

+140
-125
lines changed

src/attributecode/gen.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,21 @@ def check_duplicated_columns(location):
7878
return unique(errors)
7979

8080

81-
def check_duplicated_about_file_path(inventory_dict):
81+
def check_duplicated_about_resource(inventory_dict):
8282
"""
83-
Return a list of errors for duplicated about_file_path in a CSV file at location.
83+
Return a list of errors for duplicated about_resource in a CSV file at location.
8484
"""
85-
afp_list = []
85+
arp_list = []
8686
errors = []
8787
for component in inventory_dict:
8888
# Ignore all the empty path
89-
if component['about_file_path']:
90-
if component['about_file_path'] in afp_list:
91-
msg = ("The input has duplicated values in 'about_file_path' "
92-
"field: " + component['about_file_path'])
89+
if component['about_resource']:
90+
if component['about_resource'] in arp_list:
91+
msg = ("The input has duplicated values in 'about_resource' "
92+
"field: " + component['about_resource'])
9393
errors.append(Error(CRITICAL, msg))
9494
else:
95-
afp_list.append(component['about_file_path'])
95+
arp_list.append(component['about_resource'])
9696
return errors
9797

9898

@@ -122,13 +122,13 @@ def load_inventory(location, base_dir, reference_dir=None):
122122

123123
try:
124124
# FIXME: this should not be done here.
125-
dup_about_paths_err = check_duplicated_about_file_path(inventory)
126-
if dup_about_paths_err:
127-
errors.extend(dup_about_paths_err)
125+
dup_about_resource_err = check_duplicated_about_resource(inventory)
126+
if dup_about_resource_err:
127+
errors.extend(dup_about_resource_err)
128128
return errors, abouts
129129
except Exception as e:
130130
# TODO: why catch ALL Exception
131-
msg = "The essential field 'about_file_path' is not found in the <input>"
131+
msg = "The essential field 'about_resource' is not found in the <input>"
132132
errors.append(Error(CRITICAL, msg))
133133
return errors, abouts
134134

@@ -141,7 +141,7 @@ def load_inventory(location, base_dir, reference_dir=None):
141141
msg = "Required field: %(f)r not found in the <input>" % locals()
142142
errors.append(Error(ERROR, msg))
143143
return errors, abouts
144-
afp = fields.get(model.About.ABOUT_FILE_PATH_ATTR)
144+
afp = fields.get(model.About.ABOUT_RESOURCE_ATTR)
145145

146146
# FIXME: this should not be a failure condition
147147
if not afp or not afp.strip():
@@ -154,24 +154,39 @@ def load_inventory(location, base_dir, reference_dir=None):
154154
about = model.About(about_file_path=afp)
155155
about.location = loc
156156

157+
# Update value for 'about_resource'
158+
# keep only the filename or '.' if it's a directory
159+
if 'about_resource' in fields:
160+
updated_resource_value = u''
161+
resource_path = fields['about_resource']
162+
if resource_path.endswith(u'/'):
163+
updated_resource_value = u'.'
164+
else:
165+
updated_resource_value = basename(resource_path)
166+
fields['about_resource'] = updated_resource_value
167+
157168
ld_errors = about.load_dict(
158169
fields,
159170
base_dir,
160171
running_inventory=False,
161172
reference_dir=reference_dir,
162173
)
174+
"""
163175
# 'about_resource' field will be generated during the process.
164176
# No error need to be raise for the missing 'about_resource'.
165177
for e in ld_errors:
166178
if e.message == 'Field about_resource is required':
167179
ld_errors.remove(e)
180+
"""
168181
for e in ld_errors:
169182
if not e in errors:
170183
errors.extend(ld_errors)
171184
abouts.append(about)
172185

173186
return unique(errors), abouts
174187

188+
def update_about_resource(self):
189+
pass
175190

176191
def generate(location, base_dir, reference_dir=None, fetch_license=False):
177192
"""

src/attributecode/model.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,12 @@ class About(object):
693693

694694
# name of the attribute containing the resolved relative Resources paths
695695
about_resource_path_attr = 'about_resource_path'
696+
697+
# name of the attribute containing the resolved relative Resources paths
698+
ABOUT_RESOURCE_ATTR = 'about_resource'
696699

697700
# Required fields
698-
required_fields = ['name']
701+
required_fields = ['name', ABOUT_RESOURCE_ATTR]
699702

700703
def get_required_fields(self):
701704
return [f for f in self.fields if f.required]
@@ -913,7 +916,6 @@ def process(self, fields, about_file_path, running_inventory=False,
913916
self.base_dir,
914917
self.reference_dir)
915918
errors.extend(validation_errors)
916-
917919
return errors
918920

919921
def load(self, location):
@@ -1130,7 +1132,6 @@ def collect_inventory(location):
11301132
msg = (about_file_path + ": " + message)
11311133
errors.append(Error(severity, msg))
11321134
abouts.append(about)
1133-
11341135
return unique(errors), abouts
11351136

11361137

@@ -1184,16 +1185,24 @@ def about_object_to_list_of_dictionary(abouts):
11841185
ad = about.as_dict()
11851186
# Update the 'about_resource' field with the relative path
11861187
# from the output location
1187-
if 'about_file_path' in ad.keys():
1188-
afp = ad['about_file_path']
1189-
afp_parent = posixpath.dirname(afp)
1190-
afp_parent = '/' + afp_parent if not afp_parent.startswith('/') else afp_parent
1191-
about_resource = ad['about_resource']
1192-
for resource in about_resource:
1193-
updated_about_resource = posixpath.join(afp_parent, resource)
1194-
ad['about_resource'] = OrderedDict([(updated_about_resource, None)])
1195-
del ad['about_file_path']
1196-
serialized.append(ad)
1188+
try:
1189+
if ad['about_resource']:
1190+
if 'about_file_path' in ad.keys():
1191+
afp = ad['about_file_path']
1192+
afp_parent = posixpath.dirname(afp)
1193+
afp_parent = '/' + afp_parent if not afp_parent.startswith('/') else afp_parent
1194+
about_resource = ad['about_resource']
1195+
for resource in about_resource:
1196+
updated_about_resource = posixpath.normpath(posixpath.join(afp_parent, resource))
1197+
if resource == u'.':
1198+
updated_about_resource = updated_about_resource + '/'
1199+
ad['about_resource'] = OrderedDict([(updated_about_resource, None)])
1200+
del ad['about_file_path']
1201+
serialized.append(ad)
1202+
except Exception as e:
1203+
# The missing required field, about_resource, has already been checked
1204+
# and the error has already been logged.
1205+
pass
11971206
return serialized
11981207

11991208

tests/test_cmd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# -*- coding: utf8 -*-
33

44
# ============================================================================
5-
# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved.
5+
# Copyright (c) 2014-2019 nexB Inc. http://www.nexb.com/ - All rights reserved.
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
88
# You may obtain a copy of the License at

tests/test_gen.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# -*- coding: utf8 -*-
33

44
# ============================================================================
5-
# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved.
5+
# Copyright (c) 2014-2019 nexB Inc. http://www.nexb.com/ - All rights reserved.
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
88
# You may obtain a copy of the License at
@@ -45,15 +45,15 @@ def test_check_duplicated_columns_handles_lower_upper_case(self):
4545
result = gen.check_duplicated_columns(test_file)
4646
assert expected == result
4747

48-
def test_check_duplicated_about_file_path(self):
48+
def test_check_duplicated_about_resource(self):
4949
test_dict = [
50-
{'about_file_path': '/test/test.c', 'version': '1.03', 'name': 'test.c'},
51-
{'about_file_path': '/test/abc/', 'version': '1.0', 'name': 'abc'},
52-
{'about_file_path': '/test/test.c', 'version': '1.04', 'name': 'test1.c'}]
50+
{'about_resource': '/test/test.c', 'version': '1.03', 'name': 'test.c'},
51+
{'about_resource': '/test/abc/', 'version': '1.0', 'name': 'abc'},
52+
{'about_resource': '/test/test.c', 'version': '1.04', 'name': 'test1.c'}]
5353
expected = [
5454
Error(CRITICAL,
55-
"The input has duplicated values in 'about_file_path' field: /test/test.c")]
56-
result = gen.check_duplicated_about_file_path(test_dict)
55+
"The input has duplicated values in 'about_resource' field: /test/test.c")]
56+
result = gen.check_duplicated_about_resource(test_dict)
5757
assert expected == result
5858

5959
def test_load_inventory(self):

tests/test_model.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -609,11 +609,10 @@ def test_get_field_names_only_returns_non_empties(self):
609609
b.custom_fields['g'] = model.StringField(
610610
name='g', value='1', present=True)
611611
abouts = [a, b]
612-
# ensure that custom fields and about file path are collected
613-
# and that all fields are in the correct order
612+
# ensure all fields (including custom fields) and
613+
# about_resource are collected in the correct order
614614
expected = [
615-
model.About.ABOUT_FILE_PATH_ATTR,
616-
'about_resource', 'name', 'f', 'g'
615+
model.About.ABOUT_RESOURCE_ATTR, 'name', 'f', 'g'
617616
]
618617
result = model.get_field_names(abouts)
619618
assert expected == result
@@ -630,11 +629,9 @@ def test_get_field_names_does_not_return_duplicates_custom_fields(self):
630629
b.custom_fields['cf'] = model.StringField(name='cf', value='2',
631630
present=True)
632631
abouts = [a, b]
633-
# ensure that custom fields and about file path are collected
634-
# and that all fields are in the correct order
635-
# FIXME: this is not USED
632+
# ensure all fields (including custom fields) and
633+
# about_resource are collected in the correct order
636634
expected = [
637-
'about_file_path',
638635
'about_resource',
639636
'name',
640637
'cf',
@@ -1069,9 +1066,6 @@ def test_collect_inventory_with_no_about_resource_from_directory(self):
10691066
expected_errors = [Error(CRITICAL, 'about/about.ABOUT: Field about_resource is required')]
10701067
assert expected_errors == errors
10711068

1072-
expected = get_test_loc('test_model/inventory/no_about_resource_key/expected.csv')
1073-
check_csv(expected, result)
1074-
10751069
def test_collect_inventory_complex_from_directory(self):
10761070
location = get_test_loc('test_model/inventory/complex')
10771071
result = get_temp_file()
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
"about_file_path","name","version"
2-
"PyJWT-1.6.4-py2.py3-none-any.whl","PyJWT","1.6.4"
3-
"pyldap-2.4.45.tar.gz","pyldap","2.4.45"
4-
"xmlcatmgr-2.2_2.txz","xmlcatmgr","v 2.2_2"
5-
"sdocbook-xml-1.1_2.2.txz","sdocbook-xml","v 1.1_2,2"
6-
"Pygments-2.2.0-py2.py3-none-any.whl","Pygments","2.2.0"
7-
"ruby22-gems-2.6.4.txz","ruby22-gems","v 2.6.4"
8-
"xorg-macros-1.19.0.txz","xorg-macros","v 1.19.0"
9-
"samba42-4.2.14.txz","samba42","v 4.2.14"
10-
"xmlto-0.0.26_2.txz","xmlto","v 0.0.26_2"
11-
"xtrans-1.3.5.txz","xtrans","v 1.3.5"
12-
"w3m-0.5.3_4.txz","w3m","v 0.5.3_4"
13-
"pyaml-17.12.1-py2.py3-none-any.whl","pyaml","17.12.1"
14-
"siproxd-0.8.1.txz","siproxd","v 0.8.1"
15-
"xcb-util-0.4.0_1.1.txz","xcb-util","v 0.4.0_1,1"
16-
"requests-2.17.3-py2.py3-none-any.whl","requests","2.17.3"
17-
"setuptools-36.6.0-py2.py3-none-any.whl","setuptools","36.6.0"
18-
"ruby-2.2.5_1.1.txz","ruby","v 2.2.5_1,1"
19-
"packageurl_python-0.8.1-py2.py3-none-any.whl","packageurl-python","0.8.1"
20-
"certifi-2017.4.17-py2.py3-none-any.whl","certifi","2017.4.17"
21-
"psycopg2-2.7.5.tar.gz","psycopg2","2.7.5"
22-
"xorg-fonts-truetype-7.7_1.txz","xorg-fonts-truetype","v 7.7_1"
23-
"xerces-c3-3.1.4.txz","xerces-c3","v 3.1.4"
1+
about_resource,name,version
2+
PyJWT-1.6.4-py2.py3-none-any.whl,PyJWT,1.6.4
3+
pyldap-2.4.45.tar.gz,pyldap,2.4.45
4+
xmlcatmgr-2.2_2.txz,xmlcatmgr,v 2.2_2
5+
sdocbook-xml-1.1_2.2.txz,sdocbook-xml,"v 1.1_2,2"
6+
Pygments-2.2.0-py2.py3-none-any.whl,Pygments,2.2.0
7+
ruby22-gems-2.6.4.txz,ruby22-gems,v 2.6.4
8+
xorg-macros-1.19.0.txz,xorg-macros,v 1.19.0
9+
samba42-4.2.14.txz,samba42,v 4.2.14
10+
xmlto-0.0.26_2.txz,xmlto,v 0.0.26_2
11+
xtrans-1.3.5.txz,xtrans,v 1.3.5
12+
w3m-0.5.3_4.txz,w3m,v 0.5.3_4
13+
pyaml-17.12.1-py2.py3-none-any.whl,pyaml,17.12.1
14+
siproxd-0.8.1.txz,siproxd,v 0.8.1
15+
xcb-util-0.4.0_1.1.txz,xcb-util,"v 0.4.0_1,1"
16+
requests-2.17.3-py2.py3-none-any.whl,requests,2.17.3
17+
setuptools-36.6.0-py2.py3-none-any.whl,setuptools,36.6.0
18+
ruby-2.2.5_1.1.txz,ruby,"v 2.2.5_1,1"
19+
packageurl_python-0.8.1-py2.py3-none-any.whl,packageurl-python,0.8.1
20+
certifi-2017.4.17-py2.py3-none-any.whl,certifi,2017.4.17
21+
psycopg2-2.7.5.tar.gz,psycopg2,2.7.5
22+
xorg-fonts-truetype-7.7_1.txz,xorg-fonts-truetype,v 7.7_1
23+
xerces-c3-3.1.4.txz,xerces-c3,v 3.1.4

tests/testdata/test_gen/inv.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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_changes,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,custom1
2-
inv/this.ABOUT,.,AboutCode,0.11.0,,"multi
1+
about_resource,name,version,download_url,description,homepage_url,notes,license_name,license_file,license_url,copyright,notice_file,notice_url,redistribute,attribute,track_changes,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,custom1
2+
/inv/,AboutCode,0.11.0,,"multi
33
line",,,,,,,,,,,,,,,,,,,,,,,,,,,"multi
44
line"

tests/testdata/test_gen/inv2.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
about_file_path,name,version
2-
inv/,AboutCode,0.11.0
1+
about_resource,name,version
2+
/inv/,AboutCode,0.11.0

tests/testdata/test_gen/inv3.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
about_file_path,name,version
1+
about_resource,name,version
22
inv/test.tar.gz,AboutCode,0.11.0

tests/testdata/test_gen/inv4.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
about_file_path,about_resource,name,version,description,Confirmed Copyright,Resource,test
2-
inv/this.ABOUT,.,AboutCode,0.11.0,"multi
1+
about_resource,name,version,description,Confirmed Copyright,Resource,test
2+
inv/,AboutCode,0.11.0,"multi
33
line","Copyright (c) nexB, Inc.",this.ABOUT,This is a test

0 commit comments

Comments
 (0)