2 # A tool to parse creates a document outlining how clang formatted the
8 from datetime
import datetime
11 def get_git_revision_short_hash():
12 return subprocess
.check_output(['git', 'rev-parse', '--short', 'HEAD']
13 ).decode(sys
.stdout
.encoding
).strip()
16 def get_style(count
, passed
):
25 TOP_DIR
= os
.path
.join(os
.path
.dirname(__file__
), '../../..')
26 CLANG_DIR
= os
.path
.join(os
.path
.dirname(__file__
), '../..')
27 DOC_FILE
= os
.path
.join(CLANG_DIR
, 'docs/ClangFormattedStatus.rst')
31 skipped_dirs
= [".git", "test"]
32 suffixes
= (".cpp", ".h")
37 <style type="text/css">
38 .none {{ background-color: #FFCC99 }}
39 .part {{ background-color: #FFFF99 }}
40 .good {{ background-color: #2CCCFF }}
41 .total {{ font-weight: bold; }}
49 ======================
50 Clang Formatted Status
51 ======================
53 :doc:`ClangFormattedStatus` describes the state of LLVM source
54 tree in terms of conformance to :doc:`ClangFormat` as of: {today} (`{sha} <https://github.com/llvm/llvm-project/commit/{sha}>`_).
57 .. list-table:: LLVM Clang-Format Status
58 :widths: 50 25 25 25 25
72 - {style2}`{percent}%`
75 FNULL
= open(os
.devnull
, 'w')
77 with
open(DOC_FILE
, 'wb') as output
:
78 sha
= get_git_revision_short_hash()
79 today
= datetime
.now().strftime("%B %d, %Y %H:%M:%S")
80 output
.write(bytes(rst_prefix
.format(today
=today
,
81 sha
=sha
).encode("utf-8")))
86 for root
, subdirs
, files
in os
.walk(rootdir
):
87 for subdir
in subdirs
:
88 if any(sd
== subdir
for sd
in skipped_dirs
):
89 subdirs
.remove(subdir
)
91 act_sub_dir
= os
.path
.join(root
, subdir
)
92 # Check the git index to see if the directory contains tracked
93 # files. Reditect the output to a null descriptor as we aren't
94 # interested in it, just the return code.
95 git_check
= subprocess
.Popen(
96 ["git", "ls-files", "--error-unmatch", act_sub_dir
],
99 if git_check
.wait() != 0:
100 print("Skipping directory: ", act_sub_dir
)
101 subdirs
.remove(subdir
)
103 path
= os
.path
.relpath(root
, TOP_DIR
)
104 path
= path
.replace('\\', '/')
109 for filename
in files
:
110 file_path
= os
.path
.join(root
, filename
)
111 ext
= os
.path
.splitext(file_path
)[-1].lower()
112 if not ext
.endswith(suffixes
):
117 args
= ["clang-format", "-n", file_path
]
118 cmd
= subprocess
.Popen(args
, stderr
=subprocess
.PIPE
)
119 stdout
, err
= cmd
.communicate()
121 relpath
= os
.path
.relpath(file_path
, TOP_DIR
)
122 relpath
= relpath
.replace('\\', '/')
123 if err
.decode(sys
.stdout
.encoding
).find(': warning:') > 0:
124 print(relpath
, ":", "FAIL")
127 print(relpath
, ":", "PASS")
130 total_files_count
+= file_count
131 total_files_pass
+= file_pass
132 total_files_fail
+= file_fail
135 percent
= (int(100.0 * (float(file_pass
)/float(file_count
))))
136 style
= get_style(file_count
, file_pass
)
137 output
.write(bytes(table_row
.format(path
=path
,
141 percent
=str(percent
), style
="",
142 style2
=style
).encode("utf-8")))
146 print(path
, file_count
, file_pass
, file_fail
, percent
)
149 total_percent
= (float(total_files_pass
)/float(total_files_count
))
150 percent_str
= str(int(100.0 * total_percent
))
151 output
.write(bytes(table_row
.format(path
="Total",
152 count
=total_files_count
,
153 passes
=total_files_pass
,
154 fails
=total_files_fail
,
155 percent
=percent_str
, style
=":total:",
156 style2
=":total:").encode("utf-8")))