]>
Commit | Line | Data |
---|---|---|
ac37fd5e | 1 | #!/usr/bin/env bash |
69ed6f25 RF |
2 | # |
3 | # Script to clang-format suricata C code changes | |
4 | # | |
5 | # Rewriting branch parts of it is inspired by | |
6 | # https://www.thetopsites.net/article/53885283.shtml | |
7 | ||
8 | #set -x | |
9 | ||
10 | # We verify the minimal clang-format version for better error messaging as older clang-format | |
11 | # will barf on unknown settings with a generic error. | |
12 | CLANG_FORMAT_REQUIRED_VERSION=9 | |
13 | ||
14 | EXIT_CODE_ERROR=2 | |
15 | EXIT_CODE_FORMATTING_REQUIRED=1 | |
16 | EXIT_CODE_OK=0 | |
17 | ||
18 | PRINT_DEBUG=0 | |
19 | # Debug output if PRINT_DEBUG is 1 | |
20 | function Debug { | |
21 | if [ $PRINT_DEBUG -ne 0 ]; then | |
22 | echo "DEBUG: $@" | |
23 | fi | |
24 | } | |
25 | ||
26 | # ignore text formatting by default | |
27 | bold= | |
28 | normal= | |
29 | italic= | |
30 | # $TERM is set to dumb when calling scripts in github actions. | |
31 | if [ -n "$TERM" -a "$TERM" != "dumb" ]; then | |
32 | Debug "TERM: '$TERM'" | |
33 | # tput, albeit unlikely, might not be installed | |
34 | command -v tput >/dev/null 2>&1 # built-in which | |
35 | if [ $? -eq 0 ]; then | |
36 | Debug "Setting text formatting" | |
37 | bold=$(tput bold) | |
38 | normal=$(tput sgr0) | |
39 | italic=$(echo -e '\E[3m') | |
40 | fi | |
41 | else | |
42 | Debug "No text formatting" | |
43 | fi | |
44 | ||
45 | EXEC=$(basename $0) | |
46 | pushd . >/dev/null # we might change dir - save so that we can revert | |
47 | ||
48 | USAGE=$(cat << EOM | |
49 | usage: $EXEC --help | |
50 | $EXEC help <command> | |
51 | $EXEC <command> [<args>] | |
52 | ||
53 | Format selected changes using clang-format. | |
54 | ||
55 | Note: This does ONLY format the changed code, not the whole file! It | |
56 | uses ${italic}git-clang-format${normal} for the actual formatting. If you want to format | |
57 | whole files, use ${italic}clang-format -i <file>${normal}. | |
58 | ||
59 | It auto-detects the correct clang-format version and compared to ${italic}git-clang-format${normal} | |
60 | proper it provides additional functionality such as reformatting of all commits on a branch. | |
61 | ||
62 | Commands used in various situations: | |
63 | ||
64 | Formatting branch changes (compared to master): | |
65 | branch Format all changes in branch as additional commit | |
66 | rewrite-branch Format every commit in branch and rewrite history | |
67 | ||
68 | Formatting single changes: | |
69 | cached Format changes in git staging | |
70 | commit Format changes in most recent commit | |
71 | ||
72 | Checking if formatting is correct: | |
73 | check-branch Checks if formatting for branch changes is correct | |
74 | ||
75 | More info an a command: | |
76 | help Display more info for a particular <command> | |
77 | EOM | |
78 | ) | |
79 | ||
80 | HELP_BRANCH=$(cat << EOM | |
81 | ${bold}NAME${normal} | |
82 | $EXEC branch - Format all changes in branch as additional commit | |
83 | ||
84 | ${bold}SYNOPSIS${normal} | |
85 | $EXEC branch [--force] | |
86 | ||
87 | ${bold}DESCRIPTION${normal} | |
88 | Format all changes in your branch enabling you to add it as an additional | |
89 | formatting commit. It automatically detects all commits on your branch. | |
90 | ||
91 | Requires that all changes are committed unless --force is provided. | |
92 | ||
93 | You will need to commit the reformatted code. | |
94 | ||
95 | This is equivalent to calling: | |
96 | $ git clang-format --extensions c,h [--force] first_commit_on_current_branch^ | |
97 | ||
98 | ${bold}OPTIONS${normal} | |
99 | -f, --force | |
100 | Allow changes to unstaged files. | |
101 | ||
102 | ${bold}EXAMPLES${normal} | |
103 | On your branch whose changes you want to reformat: | |
104 | ||
105 | $ $EXEC branch | |
106 | ||
107 | ${bold}EXIT STATUS${normal} | |
108 | $EXEC exits with a status of zero if the changes were successfully | |
109 | formatted, or if no formatting change was required. A status of two will | |
110 | be returned if any errors were encountered. | |
111 | EOM | |
112 | ) | |
113 | ||
114 | HELP_CACHED=$(cat << EOM | |
115 | ${bold}NAME${normal} | |
116 | $EXEC cached - Format changes in git staging | |
117 | ||
118 | ${bold}SYNOPSIS${normal} | |
119 | $EXEC cached [--force] | |
120 | ||
121 | ${bold}DESCRIPTION${normal} | |
122 | Format staged changes using clang-format. | |
123 | ||
124 | You will need to commit the reformatted code. | |
125 | ||
126 | This is equivalent to calling: | |
127 | $ git clang-format --extensions c,h [--force] | |
128 | ||
129 | ${bold}OPTIONS${normal} | |
130 | -f, --force | |
131 | Allow changes to unstaged files. | |
132 | ||
133 | ${bold}EXAMPLES${normal} | |
134 | Format all changes in staging, i.e. in files added with ${italic}git add <file>${normal}. | |
135 | ||
136 | $ $EXEC cached | |
137 | ||
138 | ${bold}EXIT STATUS${normal} | |
139 | $EXEC exits with a status of zero if the changes were successfully | |
140 | formatted, or if no formatting change was required. A status of two will | |
141 | be returned if any errors were encountered. | |
142 | EOM | |
143 | ) | |
144 | ||
145 | HELP_CHECK_BRANCH=$(cat << EOM | |
146 | ${bold}NAME${normal} | |
147 | $EXEC check-branch - Checks if formatting for branch changes is correct | |
148 | ||
149 | ${bold}SYNOPSIS${normal} | |
150 | $EXEC check-branch [--show-commits] [--quiet] | |
151 | $EXEC check-branch --diff [--show-commits] [--quiet] | |
152 | $EXEC check-branch --diffstat [--show-commits] [--quiet] | |
153 | ||
154 | ${bold}DESCRIPTION${normal} | |
155 | Check if all branch changes are correctly formatted. | |
156 | ||
157 | Note, it does not check every commit's formatting, but rather the | |
158 | overall diff between HEAD and master. | |
159 | ||
160 | Returns 1 if formatting is off, 0 if it is correct. | |
161 | ||
162 | ${bold}OPTIONS${normal} | |
163 | -d, --diff | |
164 | Print formatting diff, i.e. diff of each file with correct formatting. | |
165 | -s, --diffstat | |
166 | Print formatting diffstat output, i.e. files with wrong formatting. | |
167 | -c, --show-commits | |
168 | Print branch commits. | |
169 | -q, --quiet | |
170 | Do not print any error if formatting is off, only set exit code. | |
171 | ||
172 | ${bold}EXIT STATUS${normal} | |
173 | $EXEC exits with a status of zero if the formatting is correct. A | |
174 | status of one will be returned if the formatting is not correct. A status | |
175 | of two will be returned if any errors were encountered. | |
176 | EOM | |
177 | ) | |
178 | ||
179 | HELP_COMMIT=$(cat << EOM | |
180 | ${bold}NAME${normal} | |
181 | $EXEC commit - Format changes in most recent commit | |
182 | ||
183 | ${bold}SYNOPSIS${normal} | |
184 | $EXEC commit | |
185 | ||
186 | ${bold}DESCRIPTION${normal} | |
187 | Format changes in most recent commit using clang-format. | |
188 | ||
189 | You will need to commit the reformatted code. | |
190 | ||
191 | This is equivalent to calling: | |
192 | $ git clang-format --extensions c,h HEAD^ | |
193 | ||
194 | ${bold}EXAMPLES${normal} | |
195 | Format all changes in most recent commit: | |
196 | ||
197 | $ $EXEC commit | |
198 | ||
199 | Note that this modifies the files, but doesn’t commit them – you’ll likely want to run | |
200 | ||
201 | $ git commit --amend -a | |
202 | ||
203 | ${bold}EXIT STATUS${normal} | |
204 | $EXEC exits with a status of zero if the changes were successfully | |
205 | formatted, or if no formatting change was required. A status of two will | |
206 | be returned if any errors were encountered. | |
207 | EOM | |
208 | ) | |
209 | ||
210 | HELP_REWRITE_BRANCH=$(cat << EOM | |
211 | ${bold}NAME${normal} | |
212 | $EXEC rewrite-branch - Format every commit in branch and rewrite history | |
213 | ||
214 | ${bold}SYNOPSIS${normal} | |
215 | $EXEC rewrite-branch | |
216 | ||
217 | ${bold}DESCRIPTION${normal} | |
218 | Reformat all commits in branch off master one-by-one. This will ${bold}rewrite | |
219 | the branch history${normal} using the existing commit metadata! | |
220 | It automatically detects all commits on your branch. | |
221 | ||
222 | This is handy in case you want to format all of your branch commits | |
223 | while keeping the commits. | |
224 | ||
225 | This can also be helpful if you have multiple commits in your branch and | |
226 | the changed files have been reformatted, i.e. where a git rebase would | |
227 | fail in many ways over-and-over again. | |
228 | ||
229 | You can achieve the same manually on a separate branch by: | |
230 | ${italic}git checkout -n <original_commit>${normal}, | |
231 | ${italic}git clang-format${normal} and ${italic}git commit${normal} for each original commit in your branch. | |
232 | ||
233 | ${bold}OPTIONS${normal} | |
234 | None | |
235 | ||
236 | ${bold}EXAMPLES${normal} | |
237 | In your branch that you want to reformat. Commit all your changes prior | |
238 | to calling: | |
239 | ||
240 | $ $EXEC rewrite-branch | |
241 | ||
242 | ${bold}EXIT STATUS${normal} | |
243 | $EXEC exits with a status of zero if the changes were successfully | |
244 | formatted, or if no formatting change was required. A status of two will | |
245 | be returned if any errors were encountered. | |
246 | EOM | |
247 | ) | |
248 | ||
249 | # Error message on stderr | |
250 | function Error { | |
251 | echo "${bold}ERROR${normal}: $@" 1>&2 | |
252 | } | |
253 | ||
254 | # Exit program (and reset path) | |
255 | function ExitWith { | |
256 | popd >/dev/null # we might have changed dir | |
257 | ||
258 | if [ $# -ne 1 ]; then | |
259 | # Huh? No exit value provided? | |
260 | Error "Internal: ExitWith requires parameter" | |
261 | exit $EXIT_CODE_ERROR | |
262 | else | |
263 | exit $1 | |
264 | fi | |
265 | } | |
266 | ||
267 | # Failure exit with error message | |
268 | function Die { | |
269 | Error $@ | |
270 | ExitWith $EXIT_CODE_ERROR | |
271 | } | |
272 | ||
273 | # Ensure required program exists. Exits with failure if not found. | |
274 | # Call with | |
275 | # RequireProgram ENVVAR_TO_SET program ... | |
276 | # One can provide multiple alternative programs. Returns first program found in | |
277 | # provided list. | |
278 | function RequireProgram { | |
279 | if [ $# -lt 2 ]; then | |
280 | Die "Internal - RequireProgram: Need env and program parameters" | |
281 | fi | |
282 | ||
283 | # eat variable to set | |
284 | local envvar=$1 | |
285 | shift | |
286 | ||
287 | for program in $@; do | |
288 | command -v $program >/dev/null 2>&1 # built-in which | |
289 | if [ $? -eq 0 ]; then | |
290 | eval "$envvar=$(command -v $program)" | |
291 | return | |
292 | fi | |
293 | done | |
294 | ||
295 | if [ $# -eq 1 ]; then | |
296 | Die "$1 not found" | |
297 | else | |
298 | Die "None of $@ found" | |
299 | fi | |
300 | } | |
301 | ||
302 | # Make sure we are running from the top-level git directory. | |
303 | # Same approach as for setup-decoder.sh. Good enough. | |
304 | # We could probably use git rev-parse --show-toplevel to do so, as long as we | |
305 | # handle the libhtp subfolder correctly. | |
306 | function SetTopLevelDir { | |
307 | if [ -e ./src/suricata.c ]; then | |
308 | # Do nothing. | |
309 | true | |
310 | elif [ -e ./suricata.c -o -e ../src/suricata.c ]; then | |
311 | cd .. | |
312 | else | |
313 | Die "This does not appear to be a suricata source directory." | |
314 | fi | |
315 | } | |
316 | ||
317 | # print help for given command | |
318 | function HelpCommand { | |
319 | local help_command=$1 | |
320 | local HELP_COMMAND=$(echo "HELP_$help_command" | sed "s/-/_/g" | tr [:lower:] [:upper:]) | |
321 | case $help_command in | |
322 | branch|cached|check-branch|commit|rewrite-branch) | |
323 | echo "${!HELP_COMMAND}"; | |
324 | ;; | |
325 | ||
326 | "") | |
327 | echo "$USAGE"; | |
328 | ;; | |
329 | ||
330 | *) | |
331 | echo "$USAGE"; | |
332 | echo ""; | |
333 | Die "No manual entry for $help_command" | |
334 | ;; | |
335 | esac | |
336 | } | |
337 | ||
338 | # Return first commit of branch (off master). | |
339 | # | |
340 | # Use $first_commit^ if you need the commit on master we branched off. | |
341 | # Do not compare with master directly as it will diff with the latest commit | |
342 | # on master. If our branch has not been rebased on the latest master, this | |
343 | # would result in including all new commits on master! | |
344 | function FirstCommitOfBranch { | |
345 | local first_commit=$(git rev-list origin/master..HEAD | tail -n 1) | |
346 | echo $first_commit | |
347 | } | |
348 | ||
349 | # Check if branch formatting is correct. | |
350 | # Compares with master branch as baseline which means it's limited to branches | |
351 | # other than master. | |
352 | # Exits with 1 if not, 0 if ok. | |
353 | function CheckBranch { | |
354 | # check parameters | |
355 | local quiet=0 | |
356 | local show_diff=0 | |
357 | local show_diffstat=0 | |
358 | local show_commits=0 | |
359 | local git_clang_format="$GIT_CLANG_FORMAT --diff" | |
360 | while [[ $# -gt 0 ]] | |
361 | do | |
362 | case "$1" in | |
363 | -q|--quiet) | |
364 | quiet=1 | |
365 | shift | |
366 | ;; | |
367 | ||
368 | -d|--diff) | |
369 | show_diff=1 | |
370 | shift | |
371 | ;; | |
372 | ||
373 | -s|--diffstat) | |
374 | show_diffstat=1 | |
375 | git_clang_format="$GIT_CLANG_FORMAT_DIFFSTAT --diffstat" | |
376 | shift | |
377 | ;; | |
378 | ||
379 | -c|--show-commits) | |
380 | show_commits=1 | |
381 | shift | |
382 | ;; | |
383 | ||
384 | *) # unknown option | |
385 | echo "$HELP_CHECK_BRANCH"; | |
386 | echo ""; | |
387 | Die "Unknown $command option: $1" | |
388 | ;; | |
389 | esac | |
390 | done | |
391 | ||
392 | if [ $show_diffstat -eq 1 -a $show_diff -eq 1 ]; then | |
393 | echo "$HELP_CHECK_BRANCH"; | |
394 | echo ""; | |
395 | Die "Cannot combine $command options --diffstat with --diff" | |
396 | fi | |
397 | ||
398 | # Find first commit on branch. Use $first_commit^ if you need the | |
399 | # commit on master we branched off. | |
400 | local first_commit=$(FirstCommitOfBranch) | |
401 | ||
402 | # git-clang-format is a python script that does not like SIGPIPE shut down | |
403 | # by "| head" prematurely. Use work-around with writing to tmpfile first. | |
404 | local format_changes="$git_clang_format --extensions c,h $first_commit^" | |
405 | local tmpfile=$(mktemp /tmp/clang-format.check.XXXXXX) | |
406 | $format_changes > $tmpfile | |
407 | local changes=$(cat $tmpfile | head -1) | |
408 | if [ $show_diff -eq 1 -o $show_diffstat -eq 1 ]; then | |
409 | cat $tmpfile | |
410 | echo "" | |
411 | fi | |
412 | rm $tmpfile | |
413 | ||
414 | # Branch commits can help with trouble shooting. Print after diff/diffstat | |
415 | # as output might be tail'd | |
416 | if [ $show_commits -eq 1 ]; then | |
417 | echo "Commits on branch (new -> old):" | |
418 | git log --oneline $first_commit^..HEAD | |
419 | echo "" | |
420 | else | |
421 | if [ $quiet -ne 1 ]; then | |
422 | echo "First commit on branch: $first_commit" | |
423 | fi | |
424 | fi | |
425 | ||
426 | # Exit code of git-clang-format is useless as it's 0 no matter if files | |
427 | # changed or not. Check actual output. Not ideal, but works. | |
428 | if [ "${changes}" != "no modified files to format" -a \ | |
429 | "${changes}" != "clang-format did not modify any files" ]; then | |
430 | if [ $quiet -ne 1 ]; then | |
431 | Error "Branch requires formatting" | |
432 | Debug "View required changes with clang-format: ${italic}$format_changes${normal}" | |
433 | Error "View required changes with: ${italic}$EXEC $command --diff${normal}" | |
434 | Error "Use ${italic}$EXEC rewrite-branch${normal} or ${italic}$EXEC branch${normal} to fix formatting" | |
435 | ExitWith $EXIT_CODE_FORMATTING_REQUIRED | |
436 | else | |
437 | return $EXIT_CODE_FORMATTING_REQUIRED | |
438 | fi | |
439 | else | |
440 | if [ $quiet -ne 1 ]; then | |
441 | echo "no modified files to format" | |
442 | fi | |
443 | return $EXIT_CODE_OK | |
444 | fi | |
445 | } | |
446 | ||
447 | # Reformat all changes in branch as a separate commit. | |
448 | function ReformatBranch { | |
449 | # check parameters | |
450 | local with_unstaged= | |
451 | if [ $# -gt 1 ]; then | |
452 | echo "$HELP_BRANCH"; | |
453 | echo ""; | |
454 | Die "Too many $command options: $1" | |
455 | elif [ $# -eq 1 ]; then | |
456 | if [ "$1" == "--force" -o "$1" == "-f" ]; then | |
457 | with_unstaged='--force' | |
458 | else | |
459 | echo "$HELP_BRANCH"; | |
460 | echo ""; | |
461 | Die "Unknown $command option: $1" | |
462 | fi | |
463 | fi | |
464 | ||
465 | # Find first commit on branch. Use $first_commit^ if you need the | |
466 | # commit on master we branched off. | |
467 | local first_commit=$(FirstCommitOfBranch) | |
468 | echo "First commit on branch: $first_commit" | |
469 | ||
470 | $GIT_CLANG_FORMAT --style file --extensions c,h $with_unstaged $first_commit^ | |
471 | if [ $? -ne 0 ]; then | |
472 | Die "Cannot reformat branch. git clang-format failed" | |
473 | fi | |
474 | } | |
475 | ||
476 | # Reformat changes in commit | |
477 | function ReformatCommit { | |
478 | # check parameters | |
479 | local commit=HEAD^ # only most recent for now | |
480 | if [ $# -gt 0 ]; then | |
481 | echo "$HELP_MOST_RECENT"; | |
482 | echo ""; | |
483 | Die "Too many $command options: $1" | |
484 | fi | |
485 | ||
486 | $GIT_CLANG_FORMAT --style file --extensions c,h $commit | |
487 | if [ $? -ne 0 ]; then | |
488 | Die "Cannot reformat most recent commit. git clang-format failed" | |
489 | fi | |
490 | } | |
491 | ||
492 | # Reformat currently staged changes | |
493 | function ReformatCached { | |
494 | # check parameters | |
495 | local with_unstaged= | |
496 | if [ $# -gt 1 ]; then | |
497 | echo "$HELP_CACHED"; | |
498 | echo ""; | |
499 | Die "Too many $command options: $1" | |
500 | elif [ $# -eq 1 ]; then | |
501 | if [ "$1" == "--force" -o "$1" == "-f" ]; then | |
502 | with_unstaged='--force' | |
503 | else | |
504 | echo "$HELP_CACHED"; | |
505 | echo ""; | |
506 | Die "Unknown $command option: $1" | |
507 | fi | |
508 | fi | |
509 | ||
510 | $GIT_CLANG_FORMAT --style file --extensions c,h $with_unstaged | |
511 | if [ $? -ne 0 ]; then | |
512 | Die "Cannot reformat staging. git clang-format failed" | |
513 | fi | |
514 | } | |
515 | ||
516 | # Reformat all commits of a branch (compared with master) and rewrites | |
517 | # the history with the formatted commits one-by-one. | |
518 | # This is helpful for quickly reformatting branches with multiple commits, | |
519 | # or where the master version of a file has been reformatted. | |
520 | # | |
521 | # You can achieve the same manually by git checkout -n <commit>, git clang-format | |
522 | # for each commit in your branch. | |
523 | function ReformatCommitsOnBranch { | |
524 | # Do not allow rewriting of master. | |
525 | # CheckBranch below will also tell us there are no changes compared with | |
526 | # master, but let's make this foolproof and explicit here. | |
527 | local current_branch=$(git rev-parse --abbrev-ref HEAD) | |
528 | if [ "$current_branch" == "master" ]; then | |
529 | Die "Must not rewrite master branch history." | |
530 | fi | |
531 | ||
532 | CheckBranch "--quiet" | |
533 | if [ $? -eq 0 ]; then | |
534 | echo "no modified files to format" | |
535 | else | |
536 | # Only rewrite if there are changes | |
537 | # Squelch warning. Our usage of git filter-branch is limited and should be ok. | |
538 | # Should investigate using git-filter-repo in the future instead. | |
539 | export FILTER_BRANCH_SQUELCH_WARNING=1 | |
540 | ||
541 | # Find first commit on branch. Use $first_commit^ if you need the | |
542 | # commit on master we branched off. | |
543 | local first_commit=$(FirstCommitOfBranch) | |
544 | echo "First commit on branch: $first_commit" | |
545 | # Use --force in case it's run a second time on the same branch | |
546 | git filter-branch --force --tree-filter "$GIT_CLANG_FORMAT $first_commit^" -- $first_commit..HEAD | |
547 | if [ $? -ne 0 ]; then | |
548 | Die "Cannot rewrite branch. git filter-branch failed" | |
549 | fi | |
550 | fi | |
551 | } | |
552 | ||
553 | if [ $# -eq 0 ]; then | |
554 | echo "$USAGE"; | |
555 | Die "Missing arguments. Call with one argument" | |
556 | fi | |
557 | ||
558 | SetTopLevelDir | |
559 | ||
560 | RequireProgram GIT git | |
561 | # ubuntu uses clang-format-{version} name for newer versions. fedora not. | |
562 | RequireProgram GIT_CLANG_FORMAT git-clang-format-11 git-clang-format-10 git-clang-format-9 git-clang-format | |
563 | GIT_CLANG_FORMAT_BINARY=clang-format | |
564 | if [[ $GIT_CLANG_FORMAT =~ .*git-clang-format-11$ ]]; then | |
565 | # default binary is clang-format, specify the correct version. | |
566 | # Alternative: git config clangformat.binary "clang-format-11" | |
567 | GIT_CLANG_FORMAT_BINARY="clang-format-11" | |
568 | elif [[ $GIT_CLANG_FORMAT =~ .*git-clang-format-10$ ]]; then | |
569 | # default binary is clang-format, specify the correct version. | |
570 | # Alternative: git config clangformat.binary "clang-format-10" | |
571 | GIT_CLANG_FORMAT_BINARY="clang-format-10" | |
572 | elif [[ $GIT_CLANG_FORMAT =~ .*git-clang-format-9$ ]]; then | |
573 | # default binary is clang-format, specify the correct version. | |
574 | # Alternative: git config clangformat.binary "clang-format-9" | |
575 | GIT_CLANG_FORMAT_BINARY="clang-format-9" | |
576 | elif [[ $GIT_CLANG_FORMAT =~ .*git-clang-format$ ]]; then | |
577 | Debug "Using regular clang-format" | |
578 | else | |
579 | Debug "Internal: unhandled clang-format version" | |
580 | fi | |
581 | ||
582 | # enforce minimal clang-format version as required by .clang-format | |
583 | clang_format_version=$($GIT_CLANG_FORMAT_BINARY --version | sed 's/.*clang-format version \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/') | |
584 | Debug "Found clang-format version: $clang_format_version" | |
585 | clang_format_version_major=$(echo $clang_format_version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1/') | |
586 | Debug "clang-format version major: $clang_format_version_major" | |
587 | if [ $((clang_format_version_major + 0)) -lt $((CLANG_FORMAT_REQUIRED_VERSION + 0)) ]; then | |
588 | Die "Require clang version $CLANG_FORMAT_REQUIRED_VERSION, found $clang_format_version_major ($clang_format_version)." | |
589 | fi | |
590 | ||
591 | # overwite git-clang-version for --diffstat as upstream does not have that yet | |
592 | RequireProgram GIT_CLANG_FORMAT_DIFFSTAT scripts/git-clang-format-custom | |
593 | if [ "$GIT_CLANG_FORMAT_BINARY" != "clang-format" ]; then | |
594 | GIT_CLANG_FORMAT="$GIT_CLANG_FORMAT --binary $GIT_CLANG_FORMAT_BINARY" | |
595 | GIT_CLANG_FORMAT_DIFFSTAT="$GIT_CLANG_FORMAT_DIFFSTAT --binary $GIT_CLANG_FORMAT_BINARY" | |
596 | fi | |
597 | Debug "Using $GIT_CLANG_FORMAT" | |
598 | Debug "Using $GIT_CLANG_FORMAT_DIFFSTAT" | |
599 | ||
600 | command_rc=0 | |
601 | command=$1 | |
602 | case $command in | |
603 | branch) | |
604 | shift; | |
605 | ReformatBranch "$@"; | |
606 | ;; | |
607 | ||
608 | check-branch) | |
609 | shift; | |
610 | CheckBranch "$@"; | |
611 | command_rc=$?; | |
612 | ;; | |
613 | ||
614 | cached) | |
615 | shift; | |
616 | ReformatCached "$@"; | |
617 | ;; | |
618 | ||
619 | commit) | |
620 | shift; | |
621 | ReformatCommit "$@"; | |
622 | ;; | |
623 | ||
624 | rewrite-branch) | |
625 | ReformatCommitsOnBranch | |
626 | ;; | |
627 | ||
628 | help) | |
629 | shift; | |
630 | HelpCommand $1; | |
631 | ;; | |
632 | ||
633 | -h|--help) | |
634 | echo "$USAGE"; | |
635 | ;; | |
636 | ||
637 | *) | |
638 | Die "$EXEC: '$command' is not a command. See '$EXEC --help'" | |
639 | ;; | |
640 | esac | |
641 | ||
642 | ExitWith $command_rc |