Skip to content

Commit 0d5080d

Browse files
committed
Fixed #485 - Implement gen_license command
Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 9637fa0 commit 0d5080d

File tree

8 files changed

+190
-0
lines changed

8 files changed

+190
-0
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Support Excel file format for `inventory`, `gen` and `attrib`
1717
* Add 'spdx_license_key' support
1818
* Add option to save error log in `check` command
19+
* New `gen_license` option
1920

2021
2021-04-02
2122
Release 6.0.0

docs/source/general.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ AboutCode Toolkit is a tool for your software development team to document your
1717

1818
- **gen**: Create ABOUT file(s) from a Software Inventory file (.csv, .json or .xlsx format) which is typically created from a software audit, and insert these AboutCode Toolkit files into your codebase. You can regenerate the AboutCode Toolkit files from a new Software Inventory file whenever you make changes.
1919

20+
- **gen_license**: Fetch licenses in the license_expression field and save to the output location.
21+
2022
- **inventory**: Generate a Software Inventory list (.csv, .json or .xlsx format) from your codebase based on ABOUT file(s). Note that this Software Inventory will only include components that have AboutCode Toolkit data. In another word, if you do not create AboutCode Toolkit files for your own original software components, these components will not show up in the generated inventory.
2123

2224
- **transform**: A command to transform an input CSV/JSON/Excel by applying renaming and/or filtering and then output to a new CSV/JSON/Excel file.

docs/source/reference.rst

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,19 @@ Details
185185

186186
.. code-block:: none
187187
188+
---djc
189+
190+
Validate license_expression from a DejaCode License.
191+
192+
This option requires 2 parameters:
193+
api_url - URL to the DJE License Library.
194+
api_key - Hash key to authenticate yourself in the API.
195+
196+
In addition, the input needs to have the 'license_expression' field.
197+
(Please contact nexB to get the api_* value for this feature)
198+
199+
$ about check --djc 'api_url' 'api_key' /home/project/about_files/
200+
188201
--log
189202
190203
This option save the error log to the defined location
@@ -379,6 +392,60 @@ Details
379392
This option tells the tool to show all errors found.
380393
The default behavior will only show 'CRITICAL', 'ERROR', and 'WARNING'
381394
395+
gen_license
396+
===========
397+
398+
Syntax
399+
------
400+
401+
.. code-block:: none
402+
403+
about gen_license [OPTIONS] LOCATION OUTPUT
404+
405+
LOCATION: Path to a JSON/CSV/Excel/.ABOUT file(s)
406+
OUTPUT: Path to a directory where license files are saved.
407+
408+
Options
409+
-------
410+
411+
.. code-block:: none
412+
413+
--djc api_url api_key Fetch licenses data from DejaCode License
414+
Library and create <license>.LICENSE to the
415+
OUTPUT location.
416+
417+
--verbose Show all the errors and warning.
418+
-h, --help Show this message and exit.
419+
420+
Purpose
421+
-------
422+
423+
Fetch licenses in the license_expression field and save to the output location.
424+
425+
Details
426+
^^^^^^^
427+
428+
.. code-block:: none
429+
430+
--djc
431+
432+
Fetch licenses text from a DejaCode API, and create <license>.LICENSE to the
433+
OUTPUT Location using the data fetched from the DejaCode License Library.
434+
435+
This option requires 2 parameters:
436+
api_url - URL to the DJE License Library.
437+
api_key - Hash key to authenticate yourself in the API.
438+
439+
In addition, the input needs to have the 'license_expression' field.
440+
(Please contact nexB to get the api_* value for this feature)
441+
442+
$ about gen_license --djc 'api_url' 'api_key' LOCATION OUTPUT
443+
444+
--verbose
445+
446+
This option tells the tool to show all errors found.
447+
The default behavior will only show 'CRITICAL', 'ERROR', and 'WARNING'
448+
382449
inventory
383450
=========
384451

src/attributecode/cmd.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from attributecode.util import filter_errors
4949
from attributecode.util import get_temp_dir
5050
from attributecode.util import get_file_text
51+
from attributecode.util import write_licenses
5152

5253
__copyright__ = """
5354
Copyright (c) nexB Inc and others. All rights reserved.
@@ -276,6 +277,85 @@ def gen(location, output, android, fetch_license, fetch_license_djc, reference,
276277
click.echo(msg)
277278
sys.exit(errors_count)
278279

280+
281+
######################################################################
282+
# gen_license subcommand
283+
######################################################################
284+
285+
@about.command(cls=AboutCommand,
286+
short_help='Fetch and save all the licenses in the license_expression field to a directory.')
287+
288+
@click.argument('location',
289+
required=True,
290+
metavar='LOCATION',
291+
type=click.Path(
292+
exists=True, file_okay=True, dir_okay=True, readable=True, resolve_path=True))
293+
294+
@click.argument('output',
295+
required=True,
296+
metavar='OUTPUT',
297+
type=click.Path(exists=True, file_okay=False, writable=True, resolve_path=True))
298+
299+
@click.option('--djc',
300+
nargs=2,
301+
type=str,
302+
metavar='api_url api_key',
303+
help='Fetch licenses from a DejaCode License Library.')
304+
305+
@click.option('--verbose',
306+
is_flag=True,
307+
help='Show all error and warning messages.')
308+
309+
@click.help_option('-h', '--help')
310+
def gen_license(location, output, djc, verbose):
311+
"""
312+
Fetch licenses in the license_expression field and save to the output location.
313+
314+
LOCATION: Path to a JSON/CSV/Excel/.ABOUT file(s)
315+
316+
OUTPUT: Path to a directory where license files are saved.
317+
"""
318+
print_version()
319+
320+
if location.endswith('.csv') or location.endswith('.json') or location.endswith('.xlsx'):
321+
_errors, abouts = load_inventory(
322+
location=location
323+
)
324+
else:
325+
_errors, abouts = collect_inventory(location)
326+
327+
328+
log_file_loc = os.path.join(output, 'error.log')
329+
api_url = ''
330+
api_key = ''
331+
errors = []
332+
if djc:
333+
# Strip the ' and " for api_url, and api_key from input
334+
api_url = djc[0].strip("'").strip('"')
335+
api_key = djc[1].strip("'").strip('"')
336+
337+
click.echo('Fetching licenses...')
338+
license_dict, lic_errors = pre_process_and_fetch_license_dict(abouts, api_url, api_key)
339+
if lic_errors:
340+
errors.extend(lic_errors)
341+
342+
# A dictionary with license file name as the key and context as the value
343+
lic_dict_output = {}
344+
for key in license_dict:
345+
if not key in lic_dict_output:
346+
lic_filename = license_dict[key][1]
347+
lic_context = license_dict[key][2]
348+
lic_dict_output[lic_filename] = lic_context
349+
350+
write_errors = write_licenses(lic_dict_output, output)
351+
if write_errors:
352+
errors.extend(write_errors)
353+
354+
errors = unique(errors)
355+
severe_errors_count = report_errors(errors, quiet=False, verbose=verbose, log_file_loc=log_file_loc)
356+
sys.exit(severe_errors_count)
357+
358+
279359
######################################################################
280360
# attrib subcommand
281361
######################################################################
@@ -741,6 +821,7 @@ def report_errors(errors, quiet, verbose, log_file_loc=None):
741821
log_msgs, _ = get_error_messages(errors, quiet=False, verbose=True)
742822
with io.open(log_file_loc, 'w', encoding='utf-8', errors='replace') as lf:
743823
lf.write('\n'.join(log_msgs))
824+
click.echo("Error log: " + log_file_loc)
744825
return severe_errors_count
745826

746827

src/attributecode/util.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,25 @@ def load_excel(location):
707707
results.append(row_dict)
708708
return errors, results
709709

710+
def write_licenses(lic_dict, location):
711+
import io
712+
713+
loc = to_posix(location)
714+
errors = []
715+
716+
if not posixpath.exists(loc):
717+
os.makedirs(add_unc(loc))
718+
try:
719+
for lic in lic_dict:
720+
output_location = posixpath.join(loc, lic)
721+
with io.open(output_location, 'w', encoding='utf-8', errors='replace') as out:
722+
out.write(lic_dict[lic])
723+
except Exception as e:
724+
msg = str(e)
725+
errors.append(Error(CRITICAL, msg))
726+
return errors
727+
728+
710729
"""
711730
Return True if a string s name is safe to use as an attribute name.
712731
"""

tests/test_cmd.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,11 @@ def test_about_gen_help_text():
367367
'test_cmd/help/about_gen_help.txt', regen=False)
368368

369369

370+
def test_about_gen_license_help_text():
371+
check_about_stdout(
372+
['gen-license', '--help'],
373+
'test_cmd/help/about_gen_license_help.txt', regen=False)
374+
370375
def test_about_check_help_text():
371376
check_about_stdout(
372377
['check', '--help'],
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Usage: about gen-license [OPTIONS] LOCATION OUTPUT
2+
3+
Fetch licenses in the license_expression field and save to the output
4+
location.
5+
6+
LOCATION: Path to a JSON/CSV/Excel/.ABOUT file(s)
7+
8+
OUTPUT: Path to a directory where license files are saved.
9+
10+
Options:
11+
--djc api_url api_key Fetch licenses from a DejaCode License Library.
12+
--verbose Show all error and warning messages.
13+
-h, --help Show this message and exit.

tests/testdata/test_cmd/help/about_help.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Commands:
1919
report errors and warnings.
2020
collect-redist-src Collect redistributable sources.
2121
gen Generate .ABOUT files from an inventory as CSV/JSON/Excel.
22+
gen-license Fetch and save all the licenses in the license_expression
23+
field to a directory.
2224
inventory Collect the inventory of .ABOUT files to a CSV/JSON/Excel
2325
file.
2426
transform Transform a CSV/JSON/Excel by applying renamings, filters

0 commit comments

Comments
 (0)