Skip to content

Commit 455fdfb

Browse files
committed
Merge branch 'release-v1.0.0' into develop
2 parents 60703aa + 3a3d414 commit 455fdfb

File tree

9 files changed

+548
-345
lines changed

9 files changed

+548
-345
lines changed

SPEC

Lines changed: 220 additions & 0 deletions
Large diffs are not rendered by default.

about_code_tool/about.py

Lines changed: 159 additions & 216 deletions
Large diffs are not rendered by default.

about_code_tool/genabout.py

Lines changed: 65 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
from collections import namedtuple
3838
from os import makedirs
39-
from os.path import exists, dirname, join, abspath, isdir, normpath, basename
39+
from os.path import exists, dirname, join, abspath, isdir, normpath, basename, expanduser
4040

4141
import about
4242

@@ -237,7 +237,7 @@ def verify_files_existence(self, input_list, project_dir, file_in_project):
237237
# Get all the dictionary keys
238238
column_keys = input_list[0].keys()
239239

240-
# Get all the keys that ends with _file except for the 'about_file
240+
# Get all the keys that ends with _file except for the 'about_file'
241241
file_keys = []
242242
for key in column_keys:
243243
if key.endswith('_file') and key != 'about_file':
@@ -289,6 +289,19 @@ def request_license_data(self, url, username, api_key, license_key):
289289
'format': 'json'
290290
}
291291

292+
# Check is the provided api_url valid or not.
293+
try:
294+
request = urllib2.Request(url)
295+
response = urllib2.urlopen(request)
296+
response_content = response.read()
297+
except urllib2.HTTPError as http_e:
298+
if http_e.code == 404:
299+
error_msg = ("URL not reachable. Invalid '--api_url'."
300+
" LICENSE generation is skipped.")
301+
print("\n" + error_msg + "\n")
302+
self.extract_dje_license_error = True
303+
self.errors.append(Error('--api_url', url, error_msg))
304+
292305
url = url.rstrip('/')
293306
encoded_payload = urllib.urlencode(payload)
294307
full_url = '%(url)s/%(license_key)s/?%(encoded_payload)s' % locals()
@@ -382,31 +395,16 @@ def get_dje_license_list(self, gen_location, input_list, gen_license, dje_licens
382395
license_file_list = []
383396
file_location = line['about_file']
384397
about_parent_dir = dirname(file_location)
385-
if '\n' in line['license_text_file']:
386-
file_value = line['license_text_file'].split('\n')
387-
else:
388-
file_value = [line['license_text_file']]
389-
for license_text_file in file_value:
390-
license_file_list.append(normpath(gen_location.rpartition('/')[0] + join(about_parent_dir, license_text_file)))
391-
for license_file in license_file_list:
392-
if not _exists(license_file):
393-
self.errors.append(Error('license_text_file', license_file, "The 'license_text_file' does not exist."))
398+
license_text_file = line['license_text_file']
399+
license_file = normpath(gen_location.rpartition('/')[0] + join(about_parent_dir, license_text_file))
400+
if not _exists(license_file):
401+
self.errors.append(Error('license_text_file', license_file, "The 'license_text_file' does not exist."))
394402
else:
395403
if gen_license:
396404
if line['dje_license']:
397405
license_output_list.append(self.gen_license_list(line))
398-
license_names = []
399-
if '\n' in line['dje_license_name']:
400-
license_names = line['dje_license_name'].split('\n ')
401-
else:
402-
license_names = [line['dje_license_name']]
403-
for lic_name in license_names:
404-
try:
405-
if line['license_text_file']:
406-
line['license_text_file'] += '\n '
407-
line['license_text_file'] += dje_license_dict[lic_name][0] + '.LICENSE'
408-
except:
409-
line['license_text_file'] = dje_license_dict[lic_name][0] + '.LICENSE'
406+
lic_name = line['dje_license_name']
407+
line['license_text_file'] = dje_license_dict[lic_name][0] + '.LICENSE'
410408
else:
411409
self.warnings.append(Warn('dje_license', '',
412410
"Missing 'dje_license' for " + line['about_file']))
@@ -417,18 +415,9 @@ def get_dje_license_list(self, gen_location, input_list, gen_license, dje_licens
417415
if gen_license:
418416
if line['dje_license']:
419417
license_output_list.append(self.gen_license_list(line))
420-
license_names = []
421-
if '\n' in line['dje_license_name']:
422-
license_names = line['dje_license_name'].split('\n ')
423-
else:
424-
license_names = [line['dje_license_name']]
425-
426-
for lic_name in license_names:
427-
if 'license_text_file' in line:
428-
line['license_text_file'] += '\n '
429-
license_name = dje_license_dict[lic_name][0]
430-
license_text_file = license_name + '.LICENSE'
431-
line['license_text_file'] = license_text_file
418+
lic_name = line['dje_license_name']
419+
if lic_name:
420+
line['license_text_file'] = dje_license_dict[lic_name][0] + '.LICENSE'
432421
else:
433422
self.warnings.append(Warn('dje_license', '',
434423
"Missing 'dje_license' for " + line['about_file']))
@@ -440,32 +429,25 @@ def pre_process_and_dje_license_dict(self, input_list, api_url, api_username, ap
440429
for line in input_list:
441430
try:
442431
if line['dje_license']:
443-
license_list = []
444432
if '\n' in line['dje_license']:
445-
license_list = line['dje_license'].split('\n')
433+
line['dje_license_name'] = ""
434+
self.errors.append(Error('dje_license',
435+
line['dje_license'],
436+
"No multiple licenses or newline character are accepted."))
437+
continue
438+
lic = line['dje_license']
439+
if not lic in license_dict:
440+
detail_list = []
441+
detail = self.get_license_details_from_api(api_url, api_username, api_key, lic)
442+
license_dict[lic] = detail[0]
443+
line['dje_license_name'] = detail[0]
444+
dje_key = detail[1]
445+
license_context = detail [2]
446+
detail_list.append(dje_key)
447+
detail_list.append(license_context)
448+
key_text_dict[detail[0]] = detail_list
446449
else:
447-
license_list = [line['dje_license']]
448-
for lic in license_list:
449-
if not lic in license_dict:
450-
detail_list = []
451-
detail = self.get_license_details_from_api(api_url, api_username, api_key, lic)
452-
license_dict[lic] = detail[0]
453-
try:
454-
if line['dje_license_name']:
455-
line['dje_license_name'] += "\n " + detail[0]
456-
except:
457-
line['dje_license_name'] = detail[0]
458-
dje_key = detail[1]
459-
license_context = detail [2]
460-
detail_list.append(dje_key)
461-
detail_list.append(license_context)
462-
key_text_dict[detail[0]] = detail_list
463-
else:
464-
try:
465-
if line['dje_license_name']:
466-
line['dje_license_name'] += "\n " + license_dict[lic]
467-
except:
468-
line['dje_license_name'] = license_dict[lic]
450+
line['dje_license_name'] = license_dict[lic]
469451
except Exception:
470452
err = Warn('dje_license', '',
471453
'Missing "dje_license" for ' + line['about_file'])
@@ -475,14 +457,10 @@ def pre_process_and_dje_license_dict(self, input_list, api_url, api_username, ap
475457
def process_dje_licenses(self, dje_license_list, dje_license_dict, output_path):
476458
license_list_context = []
477459
for gen_path, license_name in dje_license_list:
478-
licenses = []
479-
if '\n' in license_name:
480-
licenses = license_name.split('\n ')
481-
else:
482-
licenses = [license_name]
460+
lic = license_name
483461
if gen_path.startswith('/'):
484462
gen_path = gen_path.partition('/')[2]
485-
for lic in licenses:
463+
if lic:
486464
license_key = dje_license_dict[lic][0]
487465
gen_license_path = join(output_path, gen_path, license_key) + '.LICENSE'
488466
if not _exists(gen_license_path) and not self.extract_dje_license_error:
@@ -566,6 +544,12 @@ def update_about_resource(self, line, about_file_exist):
566544
about_resource = line['about_file']
567545
if about_resource.endswith('/'):
568546
line['about_resource'] = '.'
547+
else: # 'about_resource' key present with no value
548+
about_resource = line['about_file']
549+
if about_resource.endswith('/'):
550+
line['about_resource'] = '.'
551+
else:
552+
line['about_resource'] = basename(about_resource)
569553
except:
570554
# Add the 'about_resource' field
571555
about_resource = line['about_file']
@@ -724,11 +708,17 @@ def main(parser, options, args):
724708
print('Invalid action: should be 0, 1, 2 or 3')
725709
sys.exit(errno.EINVAL)
726710

727-
if copy_files_path and not _exists(copy_files_path):
711+
if copy_files_path:
712+
# code to handle tilde character
713+
copy_files_path = os.path.abspath(expanduser(copy_files_path))
714+
if not _exists(copy_files_path):
728715
print("The project path does not exist.")
729716
sys.exit(errno.EINVAL)
730717

731-
if license_text_path and not _exists(license_text_path):
718+
if license_text_path:
719+
# code to handle tilde character
720+
license_text_path = os.path.abspath(expanduser(license_text_path))
721+
if not _exists(license_text_path):
732722
print("The license text path does not exist.")
733723
sys.exit(errno.EINVAL)
734724

@@ -789,13 +779,12 @@ def main(parser, options, args):
789779
print('Please fix the input file and re-run the tool.')
790780
sys.exit(errno.EINVAL)
791781

792-
# Clear the log file
793-
# FIXME: we should just delete the file, not override it
794-
# or we should append to it...
795-
with open(output_path + LOG_FILENAME, 'w'):
796-
pass
782+
# Remove the previous log file if exist
783+
log_path = join(output_path, LOG_FILENAME)
784+
if exists(log_path):
785+
os.remove(log_path)
797786

798-
file_handler = logging.FileHandler(output_path + LOG_FILENAME)
787+
file_handler = logging.FileHandler(log_path)
799788
file_logger.addHandler(file_handler)
800789

801790
input_list = gen.get_input_list(input_path)
@@ -819,30 +808,25 @@ def main(parser, options, args):
819808
print("The '--copy_files' <project_path> must be a directory.")
820809
print("'--copy_files' is skipped.")
821810
else:
822-
# if not copy_files_path.endswith('/'):
823-
# copy_files_path += '/'
824-
project_parent_dir = dirname(copy_files_path)
825811
licenses_in_project = True
826812
license_list = gen.verify_files_existence(input_list,
827-
project_parent_dir,
813+
copy_files_path,
828814
licenses_in_project)
829815
if not license_list:
830816
print("None of the file is found. '--copy_files' is ignored.")
831817
else:
832818
gen.copy_files(output_path, license_list)
833819

834820
if license_text_path:
821+
print(normpath(license_text_path))
835822
if not isdir(license_text_path):
836823
print("The '--license_text_location' <license_path> "
837824
"must be a directory.")
838825
print("'--license_text_location' is skipped.")
839826
else:
840-
# if not license_text_path.endswith('/'):
841-
# license_text_path += '/'
842-
license_dir = dirname(license_text_path)
843827
licenses_in_project = False
844828
license_list = gen.verify_files_existence(input_list,
845-
license_dir,
829+
license_text_path,
846830
licenses_in_project)
847831
if not license_list:
848832
print("None of the file is found. '--copy_files' is ignored.")

about_code_tool/genattrib.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222

2323
from __future__ import print_function
2424

25-
2625
import csv
2726
import errno
2827
import logging
2928
import optparse
29+
import os
3030
import sys
3131

32-
from os.path import exists, dirname, join, abspath, isdir, basename
32+
from os.path import exists, dirname, join, abspath, isdir, basename, expanduser, normpath
3333

3434
from about import Collector
3535
import genabout
@@ -157,8 +157,8 @@ def main(parser, options, args):
157157
input_path, output_path, component_subset_path = args
158158

159159
# TODO: need more path normalization (normpath, expanduser)
160-
# input_path = abspath(input_path)
161-
output_path = abspath(output_path)
160+
input_path = expanduser(normpath(input_path))
161+
output_path = expanduser(normpath(output_path))
162162

163163
# Add the following to solve the
164164
# UnicodeEncodeError: 'ascii' codec can't encode character
@@ -182,6 +182,13 @@ def main(parser, options, args):
182182
parser.print_help()
183183
sys.exit(errno.EEXIST)
184184

185+
if template_location:
186+
template_location = abspath(expanduser(template_location))
187+
if not exists(expanduser(template_location)):
188+
print('The defined template location does not exist.')
189+
parser.print_help()
190+
sys.exit(errno.EINVAL)
191+
185192
if component_subset_path and not exists(component_subset_path):
186193
print('Component Subset path does not exist.')
187194
parser.print_help()
@@ -212,15 +219,22 @@ def main(parser, options, args):
212219
outlist = update_path_to_about(sublist)
213220

214221
attrib_str = collector.generate_attribution(template_path=template_location, limit_to=outlist)
215-
with open(output_path, "w") as f:
216-
f.write(attrib_str)
217222
errors = collector.get_genattrib_errors()
218223

219-
# Clear the log file
220-
with open(join(dirname(output_path), LOG_FILENAME), 'w'):
221-
pass
224+
if attrib_str:
225+
try:
226+
with open(output_path, "w") as f:
227+
f.write(attrib_str)
228+
except Exception as e:
229+
print("Problem occurs. Attribution was not generated.")
230+
print(e)
231+
232+
# Remove the previous log file if exist
233+
log_path = join(dirname(output_path), LOG_FILENAME)
234+
if exists(log_path):
235+
os.remove(log_path)
222236

223-
file_handler = logging.FileHandler(join(dirname(output_path), LOG_FILENAME))
237+
file_handler = logging.FileHandler(log_path)
224238
file_logger.addHandler(file_handler)
225239
for error_msg in errors:
226240
logger.error(error_msg)

about_code_tool/templates/default.html

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@ <h1>OPEN SOURCE SOFTWARE INFORMATION</h1>
4141

4242
<div class="oss-table-of-contents">
4343
{% for about_object in about_objects %}
44-
<p><a href="#component_{{ loop.index0 }}">{{ about_object.name }}
45-
{% if about_object.version %}
46-
{{ about_object.version }}
47-
{% endif %}
48-
</a></p>
44+
<p><a href="#component_{{ loop.index0 }}">{{ about_object.name }}{% if about_object.version %} {{ about_object.version }}{% endif %}</a></p>
4945
{% endfor %}
5046
</div>
5147

@@ -67,13 +63,29 @@ <h3 class="component-name">{{ about_object.name }}
6763
{% elif about_object.notice_file %}
6864
<pre class="component-notice">{{ about_object.notice_text }}</pre>
6965
{% endif %}
70-
{% if about_object.license_text %}
71-
<pre>{{about_object.license_text | e}}</pre>
66+
{% if about_object.dje_license_name in common_licenses %}
67+
<p>Full text of
68+
<a class="{{ about_object.dje_license_name }}" href="#component-license-{{ about_object.dje_license_name }}">
69+
{{ about_object.dje_license_name }}
70+
</a>
71+
is available at the end of this document.</p>
72+
{% else %}
73+
{% if about_object.license_text %}
74+
<pre>{{about_object.license_text | e}}</pre>
75+
{% endif %}
7276
{% endif %}
7377
</div>
7478
{% endfor %}
7579
<hr>
7680

81+
<h3>Common Licenses Used in This Product</h3>
82+
{% for index in range(license_keys | count) %}
83+
{% if license_keys[index] in common_licenses %}
84+
<h3 id="component-license-{{ license_keys[index] }}">{{ license_keys[index] }}</h3>
85+
<pre>{{ license_texts[index]|e }}</pre>
86+
{% endif %}
87+
{% endfor %}
88+
7789
<h3><a id="End">End</a></h3>
7890
</body>
7991
</html>

0 commit comments

Comments
 (0)