2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 import ThirdPartyPaths
15 def copy_dir_contents(src
, dest
):
16 for f
in glob
.glob("%s/*" % src
):
18 destname
= "%s/%s" % (dest
, os
.path
.basename(f
))
20 shutil
.copytree(f
, destname
)
22 shutil
.copy2(f
, destname
)
24 if e
.errno
== errno
.ENOTDIR
:
25 shutil
.copy2(f
, destname
)
26 elif e
.errno
== errno
.EEXIST
:
28 copy_dir_contents(f
, destname
)
31 shutil
.copy2(f
, destname
)
33 raise Exception("Directory not copied. Error: %s" % e
)
36 def write_cmake(module_path
, import_options
):
37 names
= [" " + os
.path
.basename(f
) for f
in glob
.glob("%s/*.cpp" % module_path
)]
39 if import_options
["external"]:
41 " " + os
.path
.join("external", os
.path
.basename(f
))
42 for f
in glob
.glob("%s/external/*.cpp" % (module_path
))
45 if import_options
["alpha"]:
47 " " + os
.path
.join("alpha", os
.path
.basename(f
))
48 for f
in glob
.glob("%s/alpha/*.cpp" % (module_path
))
51 with
open(os
.path
.join(module_path
, "CMakeLists.txt"), "w") as f
:
53 """set(LLVM_LINK_COMPONENTS support)
55 add_definitions( -DCLANG_TIDY )
57 add_clang_library(clangTidyMozillaModule
63 clangTidyReadabilityModule
68 clang_target_link_libraries(clangTidyMozillaModule
75 % {"names": "\n".join(names
)}
79 def add_moz_module(cmake_path
):
80 with
open(cmake_path
, "r") as f
:
85 idx
= lines
.index("set(ALL_CLANG_TIDY_CHECKS\n")
86 lines
.insert(idx
+ 1, " clangTidyMozillaModule\n")
88 with
open(cmake_path
, "w") as f
:
92 raise Exception("Unable to find ALL_CLANG_TIDY_CHECKS in {}".format(cmake_path
))
95 def write_third_party_paths(mozilla_path
, module_path
):
96 tpp_txt
= os
.path
.join(mozilla_path
, "../../tools/rewriting/ThirdPartyPaths.txt")
97 generated_txt
= os
.path
.join(mozilla_path
, "../../tools/rewriting/Generated.txt")
98 with
open(os
.path
.join(module_path
, "ThirdPartyPaths.cpp"), "w") as f
:
99 ThirdPartyPaths
.generate(f
, tpp_txt
, generated_txt
)
102 def generate_thread_allows(mozilla_path
, module_path
):
103 names
= os
.path
.join(mozilla_path
, "../../build/clang-plugin/ThreadAllows.txt")
104 files
= os
.path
.join(mozilla_path
, "../../build/clang-plugin/ThreadFileAllows.txt")
105 with
open(os
.path
.join(module_path
, "ThreadAllows.h"), "w") as f
:
107 ThreadAllows
.generate_allows(allowed_names
=[names
], allowed_files
=[files
])
111 def do_import(mozilla_path
, clang_tidy_path
, import_options
):
113 module_path
= os
.path
.join(clang_tidy_path
, module
)
115 os
.makedirs(module_path
)
117 if e
.errno
!= errno
.EEXIST
:
120 copy_dir_contents(mozilla_path
, module_path
)
121 write_third_party_paths(mozilla_path
, module_path
)
122 generate_thread_allows(mozilla_path
, module_path
)
123 write_cmake(module_path
, import_options
)
124 add_moz_module(os
.path
.join(module_path
, "..", "CMakeLists.txt"))
125 with
open(os
.path
.join(module_path
, "..", "CMakeLists.txt"), "a") as f
:
126 f
.write("add_subdirectory(%s)\n" % module
)
127 # A better place for this would be in `ClangTidyForceLinker.h` but `ClangTidyMain.cpp`
129 with
open(os
.path
.join(module_path
, "..", "tool", "ClangTidyMain.cpp"), "a") as f
:
132 // This anchor is used to force the linker to link the MozillaModule.
133 extern volatile int MozillaModuleAnchorSource;
134 static int LLVM_ATTRIBUTE_UNUSED MozillaModuleAnchorDestination =
135 MozillaModuleAnchorSource;
143 parser
= argparse
.ArgumentParser(
144 usage
="import_mozilla_checks.py <mozilla-clang-plugin-path> <clang-tidy-path> [option]",
145 description
="Imports the Mozilla static analysis checks into a clang-tidy source tree.",
148 "mozilla_path", help="Full path to mozilla-central/build/clang-plugin"
151 "clang_tidy_path", help="Full path to llvm-project/clang-tools-extra/clang-tidy"
155 help="Enable import of in-tree alpha checks",
160 help="Enable import of in-tree external checks",
163 args
= parser
.parse_args()
165 if not os
.path
.isdir(args
.mozilla_path
):
166 print("Invalid path to mozilla clang plugin")
168 if not os
.path
.isdir(args
.clang_tidy_path
):
169 print("Invalid path to clang-tidy source directory")
171 import_options
= {"alpha": args
.import_alpha
, "external": args
.import_external
}
173 do_import(args
.mozilla_path
, args
.clang_tidy_path
, import_options
)
176 if __name__
== "__main__":