-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit_lynx.py
executable file
·239 lines (207 loc) · 8.21 KB
/
git_lynx.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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/env python3
# Copyright 2024 The Lynx Authors. All rights reserved.
# Licensed under the Apache License Version 2.0 that can be found in the
# LICENSE file in the root directory of this source tree.
import inspect
import optparse
import os
import pkgutil
import checkers
import subcommand
import sys
import subprocess
from checkers.checker import Checker, CheckResult
from checkers.checker_manager import CheckerManager
from utils.merge_request import MergeRequest
from config import Config
def print_cutting_line(desc="", width=80):
if desc:
half_line = "=" * int((width - len(desc) - 2) / 2)
line = half_line + " " + desc + " " + half_line
if len(line) < width:
line = line + "="
else:
line = "=" * width
print(line)
# git lynx build: Run build.
def CMDbuild(parser, args):
parser.add_option("--ios", action="store_true", help="Check iOS build.")
parser.add_option("--android", action="store_true", help="Check Android build")
parser.add_option("--unittests", action="store_true", help="Check unittests build")
parser.add_option(
"--encoder-ut", action="store_true", help="Check encoder ut build"
)
parser.add_option("--debug", action="store_true", help="If --debug, Build debug ut")
parser.add_option(
"--enable-relax-tests", action="store_true", help="Check relax tests build"
)
parser.add_option("--asan", action="store_true", help="run ut on asan mode")
options, args = parser.parse_args(args)
mr = MergeRequest()
root_directory = mr.GetRootDirectory()
try:
ci_build_path = os.path.join(root_directory, "tools", "ci")
sys.path.append(ci_build_path)
from check_android_build import CheckAndroidBuild
from check_test_build import CheckTestTargetBuild, CheckEncoderUTBuild
except ImportError as error:
print(("Import Error: %s" % (error)))
old_cwd = os.getcwd()
os.chdir(root_directory)
try:
if options.unittests:
CheckTestTargetBuild(options)
elif options.encoder_ut:
CheckEncoderUTBuild(options)
elif options.android:
CheckAndroidBuild()
else:
print("Error build check: invalid target")
finally:
os.chdir(old_cwd)
def CMDcheck(parser, args):
parser.add_option("--checkers", help="Checkers to run, default all", default="all")
parser.add_option("--list", action="store_true", help="List available checkers")
parser.add_option(
"--all", action="store_true", help="Check all source files in the project."
)
parser.add_option("--changed", action="store_true", help="Check all changed files")
parser.add_option("--verbose", action="store_true", help="Print details")
parser.add_option(
"--ignore", help="Ignore checkers, separated with commas", default="none"
)
options, args = parser.parse_args(args)
checker_manager = CheckerManager(options.ignore)
if options.list:
print("Available checkers:")
print(
"\n\n".join(
" " + name + ": " + cls.help
for name, cls in checker_manager.checker_classes.items()
)
)
return
mr = MergeRequest()
if options.all:
changed_files = mr.GetAllFiles()
elif options.changed:
changed_files = mr.GetChangedFiles()
else:
changed_files = mr.GetLastCommitFiles()
if options.verbose:
print("Changed files:\n " + "\n ".join(changed_files) + "\n")
# If a user specifies to skip certain check(s) in the commit message, skip local check(s)
# as well.
#
# e.g. adding a "SkipChecks: dependency-check, macros-check" at the end of commit message
# to skip CQ jobs dependency-check and macros-check as well as local git lynx check of
# deps and macro.
log = mr.GetCommitLog().split("\n")
skipped_checks = []
for line in log:
if line.startswith("SkipChecks:"):
items = line.split(":", 1)[1].split(",")
skipped_checks.extend([i.strip() for i in items])
if skipped_checks:
print(f"{skipped_checks} has been skipped due to commit message.")
# filter checkers
target_checkers = []
if options.checkers == "all":
target_checkers = [
c()
for c in checker_manager.checker_classes.values()
if c.name not in skipped_checks
]
else:
checker_names = options.checkers.split(",")
for name in checker_names:
if name not in checker_manager.checker_classes:
raise Exception("Checker " + name + " not found")
target_checkers.append(checker_manager.checker_classes.get(name)())
old_cwd = os.getcwd()
os.chdir(mr.GetRootDirectory())
try:
for c in target_checkers:
if options.checkers != "all" and c.name not in options.checkers.split(","):
continue
print_cutting_line(c.name)
res = c.run(options, mr, changed_files)
print("\n[%s] %s" % (c.name, res))
print_cutting_line()
print("")
if res != CheckResult.PASSED:
sys.exit(1)
finally:
os.chdir(old_cwd)
# git lynx format: Run clang-format for lynx
def CMDformat(parser, args):
parser.add_option(
"--all", action="store_true", help="Format all source files in the project."
)
parser.add_option("--changed", action="store_true", help="Format all changed files")
parser.add_option(
"--verbose", action="store_true", help="Verbose the process of clang-format."
)
options, args = parser.parse_args(args)
try:
import checkers.format_file_filter as format_file_filter
except ImportError:
print("Can not find format_file_filter in the project.")
return 1
old_cwd = os.getcwd()
mr = MergeRequest()
os.chdir(mr.GetRootDirectory())
try:
if options.all:
changed_files = mr.GetAllFiles()
elif options.changed:
changed_files = mr.GetChangedFiles()
else:
changed_files = mr.GetLastCommitFiles()
for filename in changed_files:
if format_file_filter.shouldFormatFile(filename):
command = format_file_filter.getFormatCommand(filename)
output, error = mr.RunCommand(command)
if error:
print(("Error clang-format %s: %s" % (filename, error)))
continue
if options.verbose:
print(("Formatting %s: %s" % (filename, output)))
finally:
os.chdir(old_cwd)
# git lynx commit: The encapsulation of [git commit -t (template-file) ],
# the commit message template used is located in /git_templates/normal.
# When editing the commit message, [label], summary, and issue fields are automatically generated .
def CMDcommit(parser, args):
script_dir = os.path.dirname(os.path.realpath(__file__))
os.system("git commit -t" + script_dir + "/git_templates/normal")
def CMDhelp(parser, args):
if not any(i in ("-h", "--help") for i in args):
args = args + ["--help"]
parser.parse_args(args)
assert False
class OptionParser(optparse.OptionParser):
def __init__(self, *args, **kwargs):
optparse.OptionParser.__init__(self, *args, prog="git lynx", **kwargs)
def parse_args(self, args=None, _values=None):
try:
return self._parse_args(args)
finally:
pass
def _parse_args(self, args=None):
# Create an optparse.Values object that will store only the actual passed
# options, without the defaults.
actual_options = optparse.Values()
_, args = optparse.OptionParser.parse_args(self, args, actual_options)
# Create an optparse.Values object with the default options.
options = optparse.Values(self.get_default_values().__dict__)
# Update it with the options passed by the user.
options._update_careful(actual_options.__dict__)
return options, args
def main(argv):
usage = "git lynx subcommand"
dispatcher = subcommand.CommandDispatcher(__name__)
dispatcher.execute(OptionParser(), argv)
if __name__ == "__main__":
Config.init()
sys.exit(main(sys.argv[1:]))