-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_file_headers.py
More file actions
150 lines (110 loc) · 5.02 KB
/
Copy pathmake_file_headers.py
File metadata and controls
150 lines (110 loc) · 5.02 KB
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
#!/usr/bin/env python
# encoding: utf-8
"""
@Author: Edoardo Altamura
@Year: 2023
@Email: edoardo.altamura@outlook.com
@Copyright: Copyright (c) 2023 Edoardo Altamura
@Last Modified by: Edoardo Altamura
@Latest release: 5 Sep 2023
@Project: Election predictions (Data Science with The Economist)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@Description:
Add headers to files with selected extensions automatically.
The script will first list the files missing headers, then
prompt for confirmation. The modification is made inplace.
Usage:
python3 make_file_headers.py <header file> <root dir>
The script will first read the header template in <header file>,
then scan for source files recursively from <root dir>.
"""
import sys
import os
import os.path as path
import fileinput
from typing import List
src_extensions: List[str] = ['.py', '.mplstyles']
def is_src_file(file: str) -> bool:
"""
Check if a file's extension matches any of the specified source code extensions.
This function takes a filename as input and checks if its extension matches any
of the source code extensions defined in the global `src_extensions` list.
:param file: File name (including extension) to be checked.
:return: True if the file's extension is in `src_extensions`, False otherwise.
"""
results = [file.endswith(ext) for ext in src_extensions]
return True in results
def is_header_missing(file: str) -> bool:
"""
Check if a file is missing a shebang line at the beginning.
This function reads the contents of a file and checks if it begins with a shebang
line (a line starting with "#!"). If the file is empty or doesn't start with a shebang,
it is considered to have a missing header.
:param file: File path to be checked.
:return: True if the file is missing a shebang header, False otherwise.
"""
with open(file) as reader:
lines = reader.read().lstrip().splitlines()
if len(lines) > 0:
return not lines[0].startswith("#!")
return True
def get_src_files(dirname: str) -> List[str]:
"""
Find source code files in a directory and its subdirectories with missing headers.
This function recursively searches for source code files (based on the file extensions
specified in `src_extensions`) in the given directory and its subdirectories. It returns
a list of file paths for source code files that have missing headers.
:param dirname: Directory path to start the search.
:return: List of file paths for source code files with missing headers.
"""
src_files = []
for cur, _dirs, files in os.walk(dirname):
[src_files.append(path.join(cur, file)) for file in files if is_src_file(file)]
return [file for file in src_files if is_header_missing(file)]
def add_headers(files_target: List[str], header_file: str) -> None:
"""
Add headers to the specified files.
This function takes a list of file paths and a header string and adds the header
to the beginning of each file. It modifies the files in place.
:param files_target: List of file paths to which the header will be added.
:param header_file: Header content to be added to the files.
:return: None
"""
for line in fileinput.input(files_target, inplace=True):
if fileinput.isfirstline():
for h in header_file.splitlines():
print(h)
print(line, end="")
if __name__ == "__main__":
if len(sys.argv) < 3:
print(f"usage: {sys.argv[0]:s} <header file> <root dir>")
exit()
args = [path.abspath(arg) for arg in sys.argv]
root_path = path.abspath(args[2])
header = open(args[1]).read()
files = get_src_files(root_path)
print("Files with missing headers:")
for f in files:
print(f"\t- {f:s}")
if len(files) == 0:
print('\tNone found.')
print("\nHeader:")
print(header)
confirm = input("proceed ? [Y/n] ")
if confirm is not "Y":
exit(0)
add_headers(files, header)