1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
"""
@file generation_utils.py
@copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
Univ. Bordeaux. All rights reserved.
@author Camille Ordronneau
@date 2024-07-16
Script to automatically update the header of every files in the project
"""
import time
import subprocess
# Normalized author names in the format : Login -> Firstname Lastname
authors_name_dict = {
"Arthur CHEVALIER" : "Arthur Chevalier",
"Arthur Redondy" : "Arthur Redondy",
"Augustin Degomme" : "Augustin Degomme",
"augustin" : "Augustin Gauchet",
"Camille Ordronneau" : "Camille Ordronneau",
"Ordronneau Camille" : "Camille Ordronneau",
"Cédric Augonnet" : "Cedric Augonnet",
"Clément Vuchener" : "Clement Vuchener",
"Florent Pruvost" : "Florent Pruvost",
"Francois Broquedis" : "Francois Broquedis",
"François Trahay" : "Francois Trahay",
"Francois Trahay" : "Francois Trahay",
"francois.trahay" : "Francois Trahay",
"BENMENDIL Hamza" : "Hamza Benmendil",
"BAHHOU Houssam" : "Houssam Bahhou",
"Elomariismail00" : "Ismail Elomari Alaoui",
"Jean-Alexandre Collin" : "Jean-Alexandre Collin",
"Jérémie Gaidamour" : "Jeremie Gaidamour",
"Laszlo Joel" : "Joel Laszlo",
"Johnny Jazeix" : "Johnny Jazeix",
"Jonnhy Jazeix" : "Johnny Jazeix",
"Jule Marcoueille" : "Jule Marcoueille",
"Kevin Coulomb" : "Kevin Coulomb",
"DIEU Killian" : "Killian Dieu",
"Killian Dieu" : "Killian Dieu",
"Tackwin" : "Luca Bourroux",
"Luca Bourroux" : "Luca Bourroux",
"GUEDON Lucas" : "Lucas Guedon",
"Lucas G" : "Lucas Guedon",
"CANNAROZZO Luigi" : "Luigi Cannarozzo",
"THIOLIERE Martin" : "Martin Thioliere",
"Mathieu Faverge" : "Mathieu Faverge",
"BOULLIT Mohamed_Faycal" : "Mohamed Faycal Boullit",
"Nicolas Richart" : "Nicolas Richart",
"nbredel" : "Nolan Bredel",
"Olivier Lagrasse" : "Olivier Lagrasse",
"Pascal Noisette" : "Pascal Noisette",
"Philippe SWARTVAGHER" : "Philippe Swartvagher",
"Samuel Thibault" : "Samuel Thibault",
"Thibault Soucarre" : "Thibault Soucarre",
"Thomas Herault" : "Thomas Herault",
"Xavier Lacoste" : "Xavier Lacoste",
"" : "",
}
def file_authors(filepath):
'''
Return authors of a file
'''
# Get every line changes -> Get author -> Remove duplicate -> Remove first word "author" to only get the author name
command = f'git blame "{filepath}" --porcelain | grep "^author " | sort -u | cut -d " " -f 2-'
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
authors = result.stdout.strip().split("\n")
if "Not Committed Yet" in authors:
authors.remove("Not Committed Yet")
if "root" in authors:
authors.remove("root")
# Convert to real normalized names
authors = [authors_name_dict[a] for a in authors]
# Remove duplicate
authors = list(set(authors))
authors_list_string = ""
for a in authors:
authors_list_string += " * @author "
authors_list_string += a
authors_list_string += "\n"
return authors_list_string
def file_date(filepath):
'''
Return date of last modification
'''
command = f'git log -1 --pretty="format:%cs" {filepath}'
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return result.stdout.strip()
def create_header(filepath):
command = f'git log -1 --pretty="format:%cs" "{filepath}" | cut -c-4'
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
last_change_year = result.stdout.strip()
return '''/**
*
* @file '''+ filepath +'''
*
* @copyright 2008-'''+ last_change_year +''' Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
* Univ. Bordeaux. All rights reserved.
*
''' + file_authors(filepath) + ''' *
* @date ''' + file_date(filepath) + '''
*/'''
def update_header(filepath):
global file_error_list
with open(filepath, 'r') as file:
lines = file.readlines()
if lines[0].strip() != "/**" :
print("\n[ERROR] : File " + filepath + " has not the right header format")
print("It seems like the file " + filepath + " does not already contains any header in the current project format.")
print("This could be because the file has seen its header removed or is a new file.\n")
print("If you want to take into account this file in the header update please put :\n/**\n *\n */\n\nAt the beginning of the file.")
print("If you want to remove this error without updating the file :")
print(" - Go to file " + __file__ + " and edit the 'command' variable inside the 'project_file_list' function.\n")
file_error_list.append(filepath)
return
if is_file_up_to_date(filepath):
return
# Take the first line equal to "*/"
header_end_line = 0
for i, line in enumerate(lines):
if line.strip() == "*/" :
header_end_line = i + 1
break
# Format the header to a list of lines
header = create_header(filepath).split("\n")
header = [line + "\n" for line in header]
# Put in place the new header
new_file_content = header + lines[header_end_line:]
# Write it to the file
with open(filepath, 'w') as file:
file.writelines(new_file_content)
def is_file_up_to_date(filepath):
command = f'git log -1 --pretty="format:%cs" {filepath}'
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
last_change_date = result.stdout.strip()
command = f'grep "@date" {filepath} | cut -d \' \' -f 4'
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
header_date = result.stdout.strip()
return header_date == last_change_date
def project_file_list():
'''
Return authors of a file
'''
command = f'''
git ls-files '*.cpp' '*.hpp' '*.c' '*.h' |
grep -v "externals/*" |
grep -v "src/trace/portable_*" |
grep -v "src/core/getopt.*"
'''
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
file_list = result.stdout.strip().split("\n")
return file_list
file_error_list = []
for filepath in project_file_list():
update_header(filepath)
if file_error_list != []:
print("File that caused an error :")
for file in file_error_list:
print(" - " + file)
|