Skip to content

Commit 0df0d32

Browse files
committed
Working in Progress for #22
1 parent cc5572c commit 0df0d32

File tree

3 files changed

+110
-21
lines changed

3 files changed

+110
-21
lines changed

src/attributecode/cmd.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from attributecode.attrib import generate_and_save as generate_attribution_doc
4141
from attributecode.gen import generate as generate_about_files
4242
from attributecode.model import collect_inventory
43+
from attributecode.model import copy_redist_src
4344
from attributecode.model import write_output
4445
from attributecode.util import extract_zip
4546
from attributecode.util import filter_errors
@@ -360,6 +361,61 @@ def attrib(location, output, template, vartext, quiet, verbose):
360361
sys.exit(errors_count)
361362

362363

364+
######################################################################
365+
# collect_redist_src subcommand
366+
######################################################################
367+
368+
@about.command(cls=AboutCommand,
369+
short_help='Collect redistributable sources.')
370+
371+
@click.argument('location',
372+
required=True,
373+
metavar='LOCATION',
374+
type=click.Path(
375+
exists=True, file_okay=True, dir_okay=True, readable=True, resolve_path=True))
376+
377+
@click.argument('output',
378+
required=True,
379+
metavar='OUTPUT',
380+
type=click.Path(exists=True, file_okay=False, writable=True, resolve_path=True))
381+
382+
@click.option('-q', '--quiet',
383+
is_flag=True,
384+
help='Do not print error or warning messages.')
385+
386+
@click.option('--verbose',
387+
is_flag=True,
388+
help='Show all error and warning messages.')
389+
390+
@click.help_option('-h', '--help')
391+
392+
def collect_redist_src(location, output, quiet, verbose):
393+
"""
394+
Collect sources that have 'redistribute' flagged to the output location.
395+
396+
LOCATION: Path to a file or directory containing .ABOUT files.
397+
398+
OUTPUT: Path to a directory where sources will be copied to.
399+
"""
400+
if not quiet:
401+
print_version()
402+
click.echo('Collecting inventory from ABOUT files...')
403+
404+
if location.lower().endswith('.zip'):
405+
# accept zipped ABOUT files as input
406+
location = extract_zip(location)
407+
408+
errors, abouts = collect_inventory(location)
409+
copy_errors = copy_redist_src(abouts, location, output)
410+
411+
errors.extend(copy_errors)
412+
errors_count = report_errors(errors, quiet, verbose, log_file_loc=output + '-error.log')
413+
if not quiet:
414+
msg = 'Inventory collected in {output}.'.format(**locals())
415+
click.echo(msg)
416+
sys.exit(errors_count)
417+
418+
363419
######################################################################
364420
# check subcommand
365421
######################################################################

src/attributecode/model.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
from attributecode.util import add_unc
6464
from attributecode.util import boolean_fields
6565
from attributecode.util import copy_license_notice_files
66+
from attributecode.util import copy_file
6667
from attributecode.util import csv
6768
from attributecode.util import file_fields
6869
from attributecode.util import filter_errors
@@ -867,7 +868,7 @@ def hydrate(self, fields):
867868
# this is a special attribute, skip entirely
868869
continue
869870

870-
# A field that has been alredy processed ... and has a value
871+
# A field that has been already processed ... and has a value
871872
previous_value = seen_fields.get(name)
872873
if previous_value:
873874
if value != previous_value:
@@ -1268,6 +1269,25 @@ def get_field_names(abouts):
12681269
return fields
12691270

12701271

1272+
def copy_redist_src(abouts, location, output):
1273+
"""
1274+
Given a list of About objects, copy the referenced source (file or directory)
1275+
to the output location if the 'redistribute' field is set to True.
1276+
"""
1277+
errors = []
1278+
for about in abouts:
1279+
if about.redistribute.value:
1280+
for e in about.errors:
1281+
if 'Field about_resource' in e.message and 'not found' in e.message:
1282+
msg = e.message + u' and cannot be copied.'
1283+
errors.append(Error(CRITICAL, msg))
1284+
continue
1285+
for k in about.about_resource.value:
1286+
from_path = about.about_resource.value.get(k)
1287+
copy_file(from_path, output)
1288+
return errors
1289+
1290+
12711291
def about_object_to_list_of_dictionary(abouts):
12721292
"""
12731293
Convert About objects to a list of dictionaries

src/attributecode/util.py

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -466,26 +466,39 @@ def copy_license_notice_files(fields, base_dir, reference_dir, afp):
466466
from_lic_path = posixpath.join(to_posix(reference_dir), copy_file_name)
467467
about_file_dir = os.path.dirname(to_posix(afp)).lstrip('/')
468468
to_lic_path = posixpath.join(to_posix(base_dir), about_file_dir)
469-
470-
if on_windows:
471-
from_lic_path = add_unc(from_lic_path)
472-
to_lic_path = add_unc(to_lic_path)
473-
474-
# Strip the white spaces
475-
from_lic_path = from_lic_path.strip()
476-
to_lic_path = to_lic_path.strip()
477-
478-
# Errors will be captured when doing the validation
479-
if not posixpath.exists(from_lic_path):
480-
continue
481-
482-
if not posixpath.exists(to_lic_path):
483-
os.makedirs(to_lic_path)
484-
try:
485-
shutil.copy2(from_lic_path, to_lic_path)
486-
except Exception as e:
487-
print(repr(e))
488-
print('Cannot copy file at %(from_lic_path)r.' % locals())
469+
470+
copy_file(from_lic_path, to_lic_path)
471+
472+
473+
def copy_file(from_path, to_path):
474+
# Return if the from_path is empty or None.
475+
if not from_path:
476+
return
477+
478+
if on_windows:
479+
from_path = add_unc(from_path)
480+
to_path = add_unc(to_path)
481+
482+
# Strip the white spaces
483+
from_path = from_path.strip()
484+
to_path = to_path.strip()
485+
486+
# Errors will be captured when doing the validation
487+
if not posixpath.exists(from_path):
488+
return
489+
490+
if not posixpath.exists(to_path):
491+
os.makedirs(to_path)
492+
try:
493+
if os.path.isdir(from_path):
494+
print("#############################")
495+
from distutils.dir_util import copy_tree
496+
copy_tree(from_path, to_path)
497+
else:
498+
shutil.copy2(from_path, to_path)
499+
except Exception as e:
500+
print(repr(e))
501+
print('Cannot copy file at %(from_path)r.' % locals())
489502

490503

491504
# FIXME: we should use a license object instead

0 commit comments

Comments
 (0)