Skip to content

Commit 3ab8c13

Browse files
committed
Apply add mode to add license and copyright
1 parent f6ab0be commit 3ab8c13

File tree

8 files changed

+326
-14
lines changed

8 files changed

+326
-14
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Here a short summary:
2121

2222
- `report` --- Convert [oss-pkg-info.yaml](https://github.com/fosslight/fosslight_reuse/blob/main/tests/report/oss-pkg-info.yaml) to [FOSSLight-Report.xlsx](https://fosslight.org/fosslight-guide-en/learn/2_fosslight_report.html) and vice versa.
2323

24+
- `add` --- Add copyright and license to missing file(s)
25+
2426

2527
## 👏 How to report issue
2628

src/fosslight_reuse/_add.py

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# Copyright (c) 2021 LG Electronics Inc.
4+
# SPDX-License-Identifier: GPL-3.0-only
5+
import os
6+
import re
7+
import logging
8+
import fosslight_util.constant as constant
9+
from yaml import safe_dump
10+
from fosslight_util.set_log import init_log
11+
from datetime import datetime
12+
from ._fosslight_reuse import reuse_for_project, reuse_for_files, print_error
13+
from reuse.header import run
14+
from reuse._comment import EXTENSION_COMMENT_STYLE_MAP_LOWERCASE
15+
from reuse._main import parser as reuse_arg_parser
16+
17+
_PKG_NAME = "fosslight_reuse"
18+
_auto_add_mode = False
19+
_result_log = {}
20+
logger = logging.getLogger(constant.LOGGER_NAME)
21+
22+
23+
def check_file_extension(file_list):
24+
files_filtered = []
25+
26+
if file_list != "":
27+
for file in file_list:
28+
try:
29+
file_extension = os.path.splitext(file)[1].lower()
30+
if file_extension == "":
31+
logger.warning("Error - can't check file extension : " + file)
32+
if file_extension in EXTENSION_COMMENT_STYLE_MAP_LOWERCASE:
33+
files_filtered.append(file)
34+
except Exception as ex:
35+
logger.warning("Error - Unknown error to check file exteion " + ex)
36+
37+
return files_filtered
38+
39+
40+
def check_license_and_copyright(path_to_find, all_files, missing_license, missing_copyright):
41+
# Check file extension for each list
42+
all_files_fitered = check_file_extension(all_files)
43+
missing_license_filtered = check_file_extension(missing_license)
44+
missing_copyright_filtered = check_file_extension(missing_copyright)
45+
46+
skip_files = sorted(list(set(all_files_fitered) - set(missing_license_filtered) - set(missing_copyright_filtered)))
47+
logger.info("# File list that have both license and copyright : {count} / {total}".format(
48+
count=len(skip_files),
49+
total=len(all_files)))
50+
51+
for file in skip_files:
52+
file_list = list()
53+
file_list.append(file)
54+
55+
unused_lic_list, usused_cop_list, error_occurred, project = reuse_for_files(path_to_find, file_list)
56+
57+
return missing_license_filtered, missing_copyright_filtered
58+
59+
60+
def convert_to_spdx_format(input_string):
61+
input_string = input_string.replace(" ", "-")
62+
input_converted = "LicenseRef-" + input_string
63+
return input_converted
64+
65+
66+
def check_input_format(input_copyright):
67+
regex = re.compile(r'Copyright(\s)+(\(c\)\s)?\s*\d{4}(-\d{4})*(\s)+(\S)+')
68+
check_ok = True
69+
70+
if regex.match(input_copyright) is None:
71+
logger.warning(" You have to input with following format - 'Copyright <year> <name>'")
72+
check_ok = False
73+
74+
return check_ok
75+
76+
77+
def set_missing_license_copyright(missing_license_filtered, missing_copyright_filtered, project, path_to_find, license, copyright):
78+
input_license = None
79+
input_copyright = None
80+
81+
try:
82+
main_parser = reuse_arg_parser()
83+
except Exception as ex:
84+
print_error('Error_get_arg_parser :' + str(ex))
85+
86+
# Print missing license
87+
if missing_license_filtered is not None and len(missing_license_filtered) > 0:
88+
input_str = ""
89+
missing_license_list = []
90+
91+
logger.info("# Missing license File(s) ")
92+
for lic_file in sorted(missing_license_filtered):
93+
logger.info(f" * {lic_file}")
94+
missing_license_list.append(path_to_find + '/' + lic_file)
95+
96+
if _auto_add_mode:
97+
# Automatic add mode
98+
input_license = license
99+
else:
100+
# Manual add Mode
101+
logger.info("# Select a license to write in the license missing files ")
102+
select = input(" 1.MIT, 2.Apache-2.0, 3.LGE-Proprietary, 4.Manaully Input, 5.Not select now : ")
103+
if select == '1' or select == 'MIT':
104+
input_license = 'MIT'
105+
elif select == '2' or select == 'Apache-2.0':
106+
input_license = 'Apache-2.0'
107+
elif select == '3' or select == 'LGE Proprietary License':
108+
input_license = 'LicenseRef-LGE-Proprietary'
109+
elif select == '4' or select == 'Manually Input':
110+
input_str = input(" ## Input your License : ")
111+
input_license = input_str
112+
elif select == '5' or select == 'Quit' or select == 'quit':
113+
logger.info(" Not selected any license to write ")
114+
return
115+
116+
if input_license != "":
117+
logger.warning(f" * Your input license : {input_license}")
118+
parsed_args = main_parser.parse_args(['addheader', '--license', str(input_license)] + missing_license_list)
119+
try:
120+
run(parsed_args, project)
121+
except Exception as ex:
122+
print_error('Error_call_run_in_license :' + str(ex))
123+
124+
# Print copyright
125+
if missing_copyright_filtered is not None and len(missing_copyright_filtered) > 0:
126+
missing_copyright_list = []
127+
128+
logger.info("# Missing Copyright File(s) ")
129+
for cop_file in sorted(missing_copyright_filtered):
130+
logger.info(f" * {cop_file}")
131+
missing_copyright_list.append(os.getcwd() + '/' + path_to_find + '/' + cop_file)
132+
133+
if _auto_add_mode:
134+
# Automatic add mode
135+
input_copyright = copyright
136+
else:
137+
# Manual add Mode
138+
input_copyright = input("# Input Copyright to write in the copyright missing files (ex, 'Copyright <year> <name>'') : ")
139+
if input_copyright == 'Quit' or input_copyright == 'quit' or input_copyright == 'Q':
140+
return
141+
142+
input_ok = check_input_format(input_copyright)
143+
if input_ok is False:
144+
return
145+
146+
if input_copyright != "":
147+
logger.warning(f" * Your input Copyright : {input_copyright}")
148+
parsed_args = main_parser.parse_args(['addheader', '--copyright',
149+
'SPDX-FileCopyrightText: ' + str(input_copyright),
150+
'--exclude-year'] + missing_copyright_list)
151+
try:
152+
run(parsed_args, project)
153+
except Exception as ex:
154+
print_error('Error_call_run_in_copyright :' + str(ex))
155+
156+
157+
def get_allfiles_list(path):
158+
all_files = []
159+
160+
try:
161+
for root, dirs, files in os.walk(path):
162+
for file in files:
163+
file_lower_case = file.lower()
164+
file_abs_path = os.path.join(root, file_lower_case)
165+
file_rel_path = os.path.relpath(file_abs_path, path)
166+
all_files.append(file_rel_path)
167+
except Exception as ex:
168+
print_error('Error_Get_AllFiles : ' + str(ex))
169+
170+
return all_files
171+
172+
173+
def save_result_log():
174+
try:
175+
_str_final_result_log = safe_dump(_result_log, allow_unicode=True, sort_keys=True)
176+
logger.info(_str_final_result_log)
177+
except Exception as ex:
178+
logger.warning("Failed to print add result log. " + str(ex))
179+
180+
181+
def add_content(path_to_find, file, manual_mode, input_license="", input_copyright=""):
182+
global _auto_add_mode, _result_log
183+
file_to_check_list = []
184+
_auto_add_mode = False
185+
_check_only_file_mode = False
186+
187+
if path_to_find == "":
188+
path_to_find = os.getcwd()
189+
190+
now = datetime.now().strftime('%Y%m%d_%H-%M-%S')
191+
output_dir = os.getcwd()
192+
logger, _result_log = init_log(os.path.join(output_dir, "fosslight_reuse_add_log_"+now+".txt"),
193+
True, logging.INFO, logging.DEBUG, _PKG_NAME, path_to_find)
194+
195+
if input_copyright != "" and manual_mode is False:
196+
input_ok = check_input_format(input_copyright)
197+
if input_ok is False:
198+
return
199+
200+
if file != "":
201+
file_to_check_list = file.split(',')
202+
_check_only_file_mode = True
203+
204+
if not manual_mode and _check_only_file_mode is False:
205+
if input_license == "" and input_copyright == "":
206+
logger.info(" You have to input license and copyright to add with -l and -c option")
207+
return
208+
_auto_add_mode = True
209+
210+
if _check_only_file_mode:
211+
main_parser = reuse_arg_parser()
212+
213+
missing_license_list, missing_copyright_list, error_occurred, project = reuse_for_files(path_to_find, file_to_check_list)
214+
215+
if missing_license_list is not None and len(missing_license_list) > 0:
216+
logger.warning(f" * Your input license : {input_license}")
217+
parsed_args = main_parser.parse_args(['addheader', '--license', str(input_license)] + missing_license_list)
218+
try:
219+
run(parsed_args, project)
220+
except Exception as ex:
221+
print_error('Error_call_run_in_license_file_only :' + str(ex))
222+
223+
if missing_copyright_list is not None and len(missing_copyright_list) > 0:
224+
logger.warning(f" * Your input Copyright : {input_copyright}")
225+
parsed_args = main_parser.parse_args(['addheader', '--copyright',
226+
'SPDX-FileCopyrightText: ' + str(input_copyright),
227+
'--exclude-year'] + missing_copyright_list)
228+
try:
229+
run(parsed_args, project)
230+
except Exception as ex:
231+
print_error('Error_call_run_in_copyright_file_only :' + str(ex))
232+
else:
233+
# Get all files List in path
234+
all_files_list = get_allfiles_list(path_to_find)
235+
236+
str_lint_result, missing_license, missing_copyright, oss_pkg_info, error_occurred, project = reuse_for_project(path_to_find)
237+
238+
# Print Skipped Files
239+
missing_license_filtered, missing_copyright_filtered = \
240+
check_license_and_copyright(path_to_find, all_files_list, missing_license, missing_copyright)
241+
242+
# Set missing license and copyright
243+
set_missing_license_copyright(missing_license_filtered,
244+
missing_copyright_filtered,
245+
project,
246+
path_to_find,
247+
input_license,
248+
input_copyright)
249+
250+
save_result_log()

0 commit comments

Comments
 (0)