Changeset View
Changeset View
Standalone View
Standalone View
contrib/devtools/copyright_header.py
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | def applies_to_file(filename): | ||||
return ((EXCLUDE_COMPILED.match(filename) is None) | return ((EXCLUDE_COMPILED.match(filename) is None) | ||||
and (INCLUDE_COMPILED.match(filename) is not None)) | and (INCLUDE_COMPILED.match(filename) is not None)) | ||||
########################################################################## | ########################################################################## | ||||
# obtain list of files in repo according to INCLUDE and EXCLUDE | # obtain list of files in repo according to INCLUDE and EXCLUDE | ||||
########################################################################## | ########################################################################## | ||||
GIT_LS_CMD = 'git ls-files' | GIT_LS_CMD = 'git ls-files --full-name'.split(' ') | ||||
GIT_TOPLEVEL_CMD = 'git rev-parse --show-toplevel'.split(' ') | |||||
def call_git_ls(): | def call_git_ls(base_directory): | ||||
out = subprocess.check_output(GIT_LS_CMD.split(' ')) | out = subprocess.check_output([*GIT_LS_CMD, base_directory]) | ||||
return [f for f in out.decode("utf-8").split('\n') if f != ''] | return [f for f in out.decode("utf-8").split('\n') if f != ''] | ||||
def get_filenames_to_examine(): | def call_git_toplevel(): | ||||
filenames = call_git_ls() | "Returns the absolute path to the project root" | ||||
return sorted([filename for filename in filenames if | return subprocess.check_output(GIT_TOPLEVEL_CMD).strip().decode("utf-8") | ||||
def get_filenames_to_examine(base_directory): | |||||
"Returns an array of absolute paths to any project files in the base_directory that pass the include/exclude filters" | |||||
root = call_git_toplevel() | |||||
filenames = call_git_ls(base_directory) | |||||
return sorted([os.path.join(root, filename) for filename in filenames if | |||||
applies_to_file(filename)]) | applies_to_file(filename)]) | ||||
########################################################################## | ########################################################################## | ||||
# define and compile regexes for the patterns we are looking for | # define and compile regexes for the patterns we are looking for | ||||
########################################################################## | ########################################################################## | ||||
COPYRIGHT_WITH_C = r'Copyright \(c\)' | COPYRIGHT_WITH_C = r'Copyright \(c\)' | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | def file_has_without_c_style_copyright_for_holder(contents, holder_name): | ||||
return match is not None | return match is not None | ||||
########################################################################## | ########################################################################## | ||||
# get file info | # get file info | ||||
########################################################################## | ########################################################################## | ||||
def read_file(filename): | def read_file(filename): | ||||
return open(os.path.abspath(filename), 'r', encoding="utf8").read() | return open(filename, 'r', encoding="utf8").read() | ||||
def gather_file_info(filename): | def gather_file_info(filename): | ||||
info = {} | info = {} | ||||
info['filename'] = filename | info['filename'] = filename | ||||
c = read_file(filename) | c = read_file(filename) | ||||
info['contents'] = c | info['contents'] = c | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | unclassified_copyrights = [i['filename'] for i in file_infos if | ||||
i['classified_copyrights'] < i['all_copyrights']] | i['classified_copyrights'] < i['all_copyrights']] | ||||
print("{} with unexpected copyright holder names".format( | print("{} with unexpected copyright holder names".format( | ||||
len(unclassified_copyrights))) | len(unclassified_copyrights))) | ||||
print_filenames(unclassified_copyrights, verbose) | print_filenames(unclassified_copyrights, verbose) | ||||
print(SEPARATOR) | print(SEPARATOR) | ||||
def exec_report(base_directory, verbose): | def exec_report(base_directory, verbose): | ||||
original_cwd = os.getcwd() | filenames = get_filenames_to_examine(base_directory) | ||||
os.chdir(base_directory) | |||||
filenames = get_filenames_to_examine() | |||||
file_infos = [gather_file_info(f) for f in filenames] | file_infos = [gather_file_info(f) for f in filenames] | ||||
print_report(file_infos, verbose) | print_report(file_infos, verbose) | ||||
os.chdir(original_cwd) | |||||
########################################################################## | ########################################################################## | ||||
# report cmd | # report cmd | ||||
########################################################################## | ########################################################################## | ||||
REPORT_USAGE = """ | REPORT_USAGE = """ | ||||
Produces a report of all copyright header notices found inside the source files | Produces a report of all copyright header notices found inside the source files | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | def get_most_recent_git_change_year(filename): | ||||
return max(get_git_change_years(filename)) | return max(get_git_change_years(filename)) | ||||
########################################################################## | ########################################################################## | ||||
# read and write to file | # read and write to file | ||||
########################################################################## | ########################################################################## | ||||
def read_file_lines(filename): | def read_file_lines(filename): | ||||
f = open(os.path.abspath(filename), 'r', encoding="utf8") | f = open(filename, 'r', encoding="utf8") | ||||
file_lines = f.readlines() | file_lines = f.readlines() | ||||
f.close() | f.close() | ||||
return file_lines | return file_lines | ||||
def write_file_lines(filename, file_lines): | def write_file_lines(filename, file_lines): | ||||
f = open(os.path.abspath(filename), 'w', encoding="utf8") | f = open(filename, 'w', encoding="utf8") | ||||
f.write(''.join(file_lines)) | f.write(''.join(file_lines)) | ||||
f.close() | f.close() | ||||
########################################################################## | ########################################################################## | ||||
# update header years execution | # update header years execution | ||||
########################################################################## | ########################################################################## | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | def update_updatable_copyright(filename): | ||||
file_lines[index] = new_line | file_lines[index] = new_line | ||||
write_file_lines(filename, file_lines) | write_file_lines(filename, file_lines) | ||||
print_file_action_message(filename, | print_file_action_message(filename, | ||||
"Copyright updated! -> {}".format( | "Copyright updated! -> {}".format( | ||||
last_git_change_year)) | last_git_change_year)) | ||||
def exec_update_header_year(base_directory): | def exec_update_header_year(base_directory): | ||||
original_cwd = os.getcwd() | for filename in get_filenames_to_examine(base_directory): | ||||
os.chdir(base_directory) | |||||
for filename in get_filenames_to_examine(): | |||||
update_updatable_copyright(filename) | update_updatable_copyright(filename) | ||||
os.chdir(original_cwd) | |||||
########################################################################## | ########################################################################## | ||||
# update cmd | # update cmd | ||||
########################################################################## | ########################################################################## | ||||
UPDATE_USAGE = """ | UPDATE_USAGE = """ | ||||
Updates all the copyright headers of "The Bitcoin developers" which were | Updates all the copyright headers of "The Bitcoin developers" which were | ||||
▲ Show 20 Lines • Show All 223 Lines • Show Last 20 Lines |