Skip to content

Commit cd39e56

Browse files
committed
Option for --validate-about-resource #300
* Add the `--validate-about-resource` options for both `gen`, `inventory` and `attrib` * The code will still do the validation, but it will not show the error if `--validate-about-resource` option is not used. * Update USAGE doc Signed-off-by: Chin Yeung Li <[email protected]>
1 parent f231fa2 commit cd39e56

File tree

6 files changed

+125
-51
lines changed

6 files changed

+125
-51
lines changed

USAGE.rst

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ attrib
4040

4141
::
4242

43-
--inventory PATH Path to an inventory file
44-
--mapping Use for mapping between the input keys and the ABOUT field
45-
names - mapping.config
46-
--template PATH Path to a custom attribution template
47-
-q, --quiet Do not print any error/warning.
48-
--help Show this message and exit.
43+
--inventory PATH Path to an inventory file.
44+
--mapping Use for mapping between the input keys and the ABOUT field.
45+
names - mapping.config
46+
--show-all Show all the errors and warning
47+
--template PATH Path to a custom attribution template.
48+
--validate-about-resource Validate the existence of the about resource.
49+
-q, --quiet Do not print any error/warning.
50+
--help Show this message and exit.
4951

5052
Purpose
5153
-------
@@ -81,12 +83,21 @@ Options
8183

8284
See mapping.config for details
8385

86+
--show-all
87+
88+
This option ask the tool to show all kind of errors found.
89+
The default behavior will only show 'CRITICAL', 'ERROR', and 'WARNING'
90+
8491
--template
8592

8693
This option allows users to use their own template for attribution generation.
8794
For instance, if user has a custom template located at:
8895
/home/custom_template/template.html
8996

97+
--validate-about-resource
98+
99+
The option ask the tool to validate the existence of the referencing file.
100+
90101
$ about attrib --template /home/custom_template/template.html LOCATION OUTPUT
91102

92103

@@ -166,6 +177,8 @@ gen
166177
the generated location
167178
--mapping Use for mapping between the input keys and
168179
the ABOUT field names - mapping.config
180+
--show-all Show all the errors and warning
181+
--validate-about-resource Validate the existence of the about resource.
169182
-q, --quiet Do not print any error/warning.
170183
--help Show this message and exit.
171184

@@ -206,6 +219,14 @@ Options
206219

207220
See mapping.config for details
208221

222+
--show-all
223+
224+
This option ask the tool to show all kind of errors found.
225+
The default behavior will only show 'CRITICAL', 'ERROR', and 'WARNING'
226+
227+
--validate-about-resource
228+
229+
The option ask the tool to validate the existence of the referencing file.
209230

210231
inventory
211232
=========
@@ -223,9 +244,11 @@ inventory
223244

224245
::
225246

226-
-f, --format [json|csv] Set OUTPUT file format. [default: csv]
227-
-q, --quiet Do not print any error/warning.
228-
--help Show this message and exit.
247+
-f, --format [json|csv] Set OUTPUT file format. [default: csv]
248+
--show-all Show all the errors and warning
249+
--validate-about-resource Validate the existence of the about resource.
250+
-q, --quiet Do not print any error/warning.
251+
--help Show this message and exit.
229252

230253
Purpose
231254
-------
@@ -240,4 +263,13 @@ Options
240263
241264
Set OUTPUT file format. [default: csv]
242265

266+
--show-all
267+
268+
This option ask the tool to show all kind of errors found.
269+
The default behavior will only show 'CRITICAL', 'ERROR', and 'WARNING'
270+
271+
--validate-about-resource
272+
273+
The option ask the tool to validate the existence of the referencing file.
274+
243275
$ about inventory -f json [OPTIONS] LOCATION OUTPUT

src/attributecode/cmd.py

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from attributecode import model
3636
from attributecode import severities
3737
from attributecode.util import extract_zip
38+
from attributecode.util import ignore_about_resource_path_error
3839
from attributecode.util import to_posix
3940

4041

@@ -119,12 +120,16 @@ def cli():
119120
'for any level.'
120121
)
121122

123+
@click.option('--validate-about-resource', is_flag=True, default=False,
124+
help='Validate the existence of the about resource.'
125+
)
126+
122127
@click.option('-q', '--quiet', is_flag=True,
123128
help='Do not print error or warning messages.')
124129

125130
@click.help_option('-h', '--help')
126131

127-
def inventory(location, output, quiet, format, show_all):
132+
def inventory(location, output, quiet, format, show_all, validate_about_resource):
128133
"""
129134
Collect a JSON or CSV inventory of components from .ABOUT files.
130135
@@ -152,7 +157,15 @@ def inventory(location, output, quiet, format, show_all):
152157
write_errors = model.write_output(abouts, output, format)
153158
for err in write_errors:
154159
errors.append(err)
155-
log_errors(errors, quiet, show_all, os.path.dirname(output))
160+
161+
finalized_errors = []
162+
163+
if not validate_about_resource:
164+
finalized_errors = ignore_about_resource_path_error(errors)
165+
else:
166+
finalized_errors = errors
167+
168+
log_errors(finalized_errors, quiet, show_all, os.path.dirname(output))
156169
sys.exit(0)
157170

158171

@@ -183,10 +196,10 @@ def inventory(location, output, quiet, format, show_all):
183196
# TODO: this option help and long name is obscure and would need to be refactored
184197
@click.option('--license-notice-text-location', nargs=1,
185198
type=click.Path(exists=True, dir_okay=True, readable=True, resolve_path=True),
186-
help="Copy the 'license_file' from the directory to the generated location")
199+
help="Copy the 'license_file' from the directory to the generated location.")
187200

188201
@click.option('--mapping', is_flag=True,
189-
help='Use file mapping.config with mapping between input keys and ABOUT field names')
202+
help='Use file mapping.config with mapping between input keys and ABOUT field names.')
190203

191204
@click.option('--show-all', is_flag=True, default=False,
192205
help='Show all errors and warnings. '
@@ -223,20 +236,25 @@ def gen(location, output, mapping, license_notice_text_location, fetch_license,
223236
click.echo('Generating .ABOUT files...')
224237

225238
errors, abouts = gen_generate(
226-
location=location, base_dir=output, validate_about_resource=validate_about_resource,
227-
license_notice_text_location=license_notice_text_location,
239+
location=location, base_dir=output, license_notice_text_location=license_notice_text_location,
228240
fetch_license=fetch_license, use_mapping=mapping)
229241

230242
about_count = len(abouts)
231243
error_count = 0
244+
finalized_errors = []
245+
246+
if not validate_about_resource:
247+
finalized_errors = ignore_about_resource_path_error(errors)
248+
else:
249+
finalized_errors = errors
232250

233-
for e in errors:
251+
for e in finalized_errors:
234252
# Only count as warning/error if CRITICAL, ERROR and WARNING
235253
if e.severity > 20:
236254
error_count = error_count + 1
237255
click.echo(
238256
'Generated %(about_count)d .ABOUT files with %(error_count)d errors or warnings' % locals())
239-
log_errors(errors, quiet, show_all, output)
257+
log_errors(finalized_errors, quiet, show_all, output)
240258
sys.exit(0)
241259

242260

@@ -256,12 +274,12 @@ def gen(location, output, mapping, license_notice_text_location, fetch_license,
256274
@click.option('--inventory', required=False,
257275
type=click.Path(exists=True, file_okay=True, resolve_path=True),
258276
help='Path to an optional JSON or CSV inventory file listing the '
259-
'subset of .ABOUT files path to consider when generating attribution '
277+
'subset of .ABOUT files path to consider when generating attribution.'
260278
)
261279

262280
@click.option('--mapping', is_flag=True,
263281
help='Use the file "mapping.config" with mappings between the CSV '
264-
'inventory columns names and .ABOUT field names')
282+
'inventory columns names and .ABOUT field names.')
265283

266284
@click.option('--show-all', is_flag=True, default=False,
267285
help='Show all errors and warnings. '
@@ -274,12 +292,17 @@ def gen(location, output, mapping, license_notice_text_location, fetch_license,
274292
@click.option('--template', type=click.Path(exists=True), nargs=1,
275293
help='Path to an optional custom attribution template used for generation.')
276294

295+
@click.option('--validate-about-resource', is_flag=True, default=False,
296+
help='Validate the existence of the about resource.'
297+
)
298+
277299
@click.option('-q', '--quiet', is_flag=True,
278300
help='Do not print error or warning messages.')
279301

280302
@click.help_option('-h', '--help')
281303

282-
def attrib(location, output, template, mapping, inventory, quiet, show_all):
304+
def attrib(location, output, template, mapping, inventory, quiet, show_all,
305+
validate_about_resource):
283306
"""
284307
Generate an attribution document at OUTPUT using .ABOUT files at LOCATION.
285308
@@ -303,7 +326,14 @@ def attrib(location, output, template, mapping, inventory, quiet, show_all):
303326
for no_match_error in no_match_errors:
304327
inv_errors.append(no_match_error)
305328

306-
log_errors(inv_errors, quiet, show_all, os.path.dirname(output))
329+
finalized_errors = []
330+
331+
if not validate_about_resource:
332+
finalized_errors = ignore_about_resource_path_error(inv_errors)
333+
else:
334+
finalized_errors = inv_errors
335+
336+
log_errors(finalized_errors, quiet, show_all, os.path.dirname(output))
307337
click.echo('Finished.')
308338
sys.exit(0)
309339

src/attributecode/gen.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,9 @@ def load_inventory(location, base_dir, license_notice_text_location=None,
178178
return errors, abouts
179179

180180

181-
def generate(location, base_dir, validate_about_resource=False,
182-
license_notice_text_location=None, fetch_license=False, policy=None,
183-
conf_location=None, with_empty=False, with_absent=False,
184-
use_mapping=False):
181+
def generate(location, base_dir, license_notice_text_location=None,
182+
fetch_license=False, policy=None, conf_location=None,
183+
with_empty=False, with_absent=False, use_mapping=False):
185184
"""
186185
Load ABOUT data from a CSV inventory at `location`. Write ABOUT files to
187186
base_dir using policy flags and configuration file at conf_location.
@@ -256,22 +255,21 @@ def generate(location, base_dir, validate_about_resource=False,
256255
for about_resource_value in about.about_resource.value:
257256
about.about_resource_path.value[about_resource_value] = None
258257
about.about_resource_path.present = True
259-
if validate_about_resource:
260-
# Check for the existence of the about_resource
261-
# If the input already have the about_resource_path field, it will
262-
# be validated when creating the about object
263-
loc = util.to_posix(dump_loc)
264-
about_file_loc = loc
265-
for about_resource_value in about.about_resource_path.value:
266-
path = join(dirname(util.to_posix(about_file_loc)),
267-
about_resource_value)
268-
if not exists(path):
269-
path = util.to_posix(path.strip(UNC_PREFIX_POSIX))
270-
path = normpath(path)
271-
msg = (u'The reference file: '
272-
u'%(path)s '
273-
u'does not exist' % locals())
274-
not_exist_errors.append(msg)
258+
# Check for the existence of the about_resource
259+
# If the input already have the about_resource_path field, it will
260+
# be validated when creating the about object
261+
loc = util.to_posix(dump_loc)
262+
about_file_loc = loc
263+
for about_resource_value in about.about_resource_path.value:
264+
path = join(dirname(util.to_posix(about_file_loc)),
265+
about_resource_value)
266+
if not exists(path):
267+
path = util.to_posix(path.strip(UNC_PREFIX_POSIX))
268+
path = normpath(path)
269+
msg = (u'Field about_resource_path: '
270+
u'%(path)s '
271+
u'does not exist' % locals())
272+
not_exist_errors.append(msg)
275273
if gen_license:
276274
about.license_file.value = OrderedDict()
277275
# Write generated LICENSE file

src/attributecode/util.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,14 @@ def copy_license_notice_files(fields, base_dir, license_notice_text_location, af
471471
if not posixpath.exists(to_lic_path):
472472
os.makedirs(to_lic_path)
473473
shutil.copy2(from_lic_path, to_lic_path)
474+
475+
476+
def ignore_about_resource_path_error(errors):
477+
ignore_resource_path_check_message = u'Field about_resource_path:'
478+
updated_errors = []
479+
for err in errors:
480+
if ignore_resource_path_check_message in err.message:
481+
continue
482+
else:
483+
updated_errors.append(err)
484+
return updated_errors

tests/test_gen.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,40 +113,37 @@ def test_generation_with_no_about_resource(self):
113113
errors, abouts = gen.generate(location, base_dir)
114114
expected = [u'.']
115115
assert abouts[0].about_resource.value == expected
116-
assert len(errors) == 0
116+
assert len(errors) == 1
117117

118118
def test_generation_with_no_about_resource_reference(self):
119119
location = get_test_loc('gen/inv3.csv')
120120
base_dir = get_temp_dir()
121-
validate_about_resource = True
122121

123-
errors, abouts = gen.generate(location, base_dir, validate_about_resource)
122+
errors, abouts = gen.generate(location, base_dir)
124123
expected = [u'test.tar.gz']
125124

126125
assert abouts[0].about_resource.value == expected
127126
assert len(errors) == 1
128-
msg = u'The reference file'
127+
msg = u'Field about_resource_path'
129128
assert msg in errors[0].message
130129

131130
def test_generation_with_no_about_resource_reference_no_resource_validation(self):
132131
location = get_test_loc('gen/inv3.csv')
133132
base_dir = get_temp_dir()
134-
validate_about_resource = False
135133

136-
errors, abouts = gen.generate(location, base_dir, validate_about_resource)
134+
errors, abouts = gen.generate(location, base_dir)
137135
expected = [u'test.tar.gz']
138136

139137
assert abouts[0].about_resource.value == expected
140-
assert len(errors) == 0
138+
assert len(errors) == 1
141139

142140
def test_generate(self):
143141
location = get_test_loc('gen/inv.csv')
144142
base_dir = get_temp_dir()
145-
validate_about_resource = True
146143

147-
errors, abouts = gen.generate(location, base_dir, validate_about_resource)
144+
errors, abouts = gen.generate(location, base_dir)
148145
msg1 = u'Field custom1 is not a supported field and is ignored.'
149-
msg2 = u'The reference file'
146+
msg2 = u'Field about_resource_path'
150147

151148
assert msg1 in errors[0].message
152149
assert msg2 in errors[1].message

tests/test_util.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from testing_utils import on_windows
3030

3131
from attributecode import CRITICAL
32+
from attributecode import ERROR
3233
from attributecode import Error
3334
from attributecode import util
3435

@@ -338,3 +339,8 @@ def test_apply_mapping(self):
338339
])]
339340
assert util.apply_mapping(input) == expected
340341

342+
def test_ignore_about_resource_path_error(self):
343+
input_err = [Error(ERROR, 'Field about_resource_path: test.tar.gz does not exist'),
344+
Error(ERROR, 'Field about_resource_path: test.tar.gz does not exist')]
345+
expected_err = []
346+
assert util.ignore_about_resource_path_error(input_err) == expected_err

0 commit comments

Comments
 (0)