forked from LibrePCB/LibrePCB
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsort_qmake_file_entries.py
executable file
·100 lines (84 loc) · 3.62 KB
/
sort_qmake_file_entries.py
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import glob
from shutil import copyfile
"""
This script sorts the entries of HEADERS, SOURCES and FORMS variables in
all qmake project files (*.pro) in alphabetical order (except those in
submodules). This reduces the risk of conflicts when merging or rebasing
commits which modify *.pro files and makes those files cleaner and thus
easier to read.
This script may be used as a pre-commit hook:
ln -rsT sort_qmake_file_entries.py ../.git/hooks/pre-commit
"""
def get_repository_root_dir(start_dir):
if os.path.isdir(os.path.join(start_dir, '.git')):
return start_dir
else:
parent_dir = os.path.dirname(start_dir)
if parent_dir != start_dir:
return get_repository_root_dir(parent_dir)
else:
return None
def sort_qmake_file(project_root, filepath):
with open(filepath, 'r') as file:
old_lines = list(file.readlines())
new_lines = list(old_lines)
block_start_index = None
for line_index, line in enumerate(old_lines):
if block_start_index is None:
is_headers = line.startswith("HEADERS += \\")
is_sources = line.startswith("SOURCES += \\")
is_forms = line.startswith("FORMS += \\")
if is_headers or is_sources or is_forms:
block_start_index = line_index + 1
else:
if not line.strip():
block_end_index = line_index
block_lines = sorted(old_lines[block_start_index:block_end_index])
for i, l in enumerate(block_lines):
adjusted_line = l.replace("\\", "").rstrip() + " \\\n"
new_lines[block_start_index+i] = adjusted_line
block_start_index = None
relative_path = os.path.relpath(filepath, project_root)
if new_lines != old_lines:
print("[M] {}".format(relative_path))
copyfile(filepath, filepath + '~')
with open(filepath, 'w') as file:
file.writelines(new_lines)
return 1
else:
print("[ ] {}".format(relative_path))
return 0
def sort_qmake_files_in_dir(project_root, dir):
modified_files = 0
dot_git_file = os.path.join(dir, '.git')
if not os.path.isfile(dot_git_file):
has_qmake_file = False
for entry in glob.glob(os.path.join(dir, '*.pro')):
if os.path.isfile(entry):
has_qmake_file = True
modified_files += sort_qmake_file(project_root, entry)
if has_qmake_file is True:
for entry in glob.glob(os.path.join(dir, '*/')):
filename = os.path.basename(entry)
if not os.path.basename(entry).startswith('.'):
modified_files += sort_qmake_files_in_dir(project_root, entry)
return modified_files
def main():
# get the root directory of the project's repository
script_dir = os.path.dirname(os.path.realpath(__file__))
project_root_dir = get_repository_root_dir(script_dir)
if not os.path.isfile(os.path.join(project_root_dir, 'librepcb.pro')):
raise Exception("Could not find 'librepcb.pro' in the project's root directory!")
# search all *.pro files and sort their HEADERS, SOURCES and FORMS entries
print("Sort *.pro file entries...")
modified_files = sort_qmake_files_in_dir(project_root_dir, project_root_dir)
print("Finished: {} Files modified.".format(modified_files))
return modified_files
if __name__ == "__main__":
# exit with code != 0 if files were modified
# -> aborts the commit when used as pre-commit hook!
exit(main())