Skip to content

Commit 6a4901a

Browse files
jonmeowgeoffromer
andauthored
Remove LLVM gtest dep and add pre-commit regression check. (carbon-language#1040)
Co-authored-by: Geoff Romer <[email protected]>
1 parent b048bb7 commit 6a4901a

File tree

5 files changed

+150
-59
lines changed

5 files changed

+150
-59
lines changed

.github/workflows/pre-commit.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v2
17+
with:
18+
submodules: true
1719
- uses: actions/setup-python@v2
1820
- uses: pre-commit/[email protected]
1921
env:

.pre-commit-config.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ repos:
6767
hooks:
6868
- id: prettier
6969
# Run linters last, as formatters and other checks may fix issues.
70+
- repo: local
71+
hooks:
72+
- id: forbid-llvm-googletest
73+
name: Checks for deps on LLVM's version of GoogleTest
74+
entry: scripts/forbid_llvm_googletest.py
75+
language: python
76+
files: ^.*/BUILD$
77+
pass_filenames: false
7078
- repo: https://github.com/PyCQA/flake8
7179
rev: cbeb4c9c4137cff1568659fcc48e8b85cddd0c8d # frozen: 4.0.1
7280
hooks:

common/BUILD

-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,5 @@ cc_test(
6161
":string_helpers",
6262
"@com_google_googletest//:gtest_main",
6363
"@llvm-project//llvm:Support",
64-
"@llvm-project//llvm:TestingSupport",
6564
],
6665
)

common/string_helpers_test.cpp

+63-58
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
#include <string>
1111

1212
#include "llvm/Support/Error.h"
13-
#include "llvm/Testing/Support/Error.h"
1413

15-
using ::llvm::FailedWithMessage;
16-
using ::llvm::HasValue;
14+
using ::llvm::toString;
1715
using ::testing::Eq;
1816
using ::testing::Optional;
1917

@@ -58,137 +56,144 @@ TEST(UnescapeStringLiteral, Nul) {
5856
}
5957

6058
TEST(ParseBlockStringLiteral, FailTooFewLines) {
61-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(""),
62-
FailedWithMessage("Too few lines"));
59+
EXPECT_THAT(toString(ParseBlockStringLiteral("").takeError()),
60+
Eq("Too few lines"));
6361
}
6462

6563
TEST(ParseBlockStringLiteral, FailNoLeadingTripleQuotes) {
66-
EXPECT_THAT_EXPECTED(
67-
ParseBlockStringLiteral("'a'\n"),
68-
FailedWithMessage("Should start with triple quotes: 'a'"));
64+
EXPECT_THAT(toString(ParseBlockStringLiteral("'a'\n").takeError()),
65+
Eq("Should start with triple quotes: 'a'"));
6966
}
7067

7168
TEST(ParseBlockStringLiteral, FailInvalideFiletypeIndicator) {
72-
EXPECT_THAT_EXPECTED(
73-
ParseBlockStringLiteral("\"\"\"carbon file\n"),
74-
FailedWithMessage(
75-
"Invalid characters in file type indicator: carbon file"));
69+
EXPECT_THAT(
70+
toString(ParseBlockStringLiteral("\"\"\"carbon file\n").takeError()),
71+
Eq("Invalid characters in file type indicator: carbon file"));
7672
}
7773

7874
TEST(ParseBlockStringLiteral, FailEndingTripleQuotes) {
79-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral("\"\"\"\n"),
80-
FailedWithMessage("Should end with triple quotes: "));
75+
EXPECT_THAT(toString(ParseBlockStringLiteral("\"\"\"\n").takeError()),
76+
Eq("Should end with triple quotes: "));
8177
}
8278

8379
TEST(ParseBlockStringLiteral, FailWrongIndent) {
84-
EXPECT_THAT_EXPECTED(
85-
ParseBlockStringLiteral(R"("""
80+
constexpr char Input[] = R"("""
8681
A block string literal
8782
with wrong indent
88-
""")"),
89-
FailedWithMessage(
90-
"Wrong indent for line: with wrong indent, expected 5"));
83+
""")";
84+
EXPECT_THAT(toString(ParseBlockStringLiteral(Input).takeError()),
85+
Eq("Wrong indent for line: with wrong indent, expected 5"));
9186
}
9287

9388
TEST(ParseBlockStringLiteral, FailInvalidEscaping) {
94-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
89+
constexpr char Input[] = R"("""
9590
\q
96-
""")"),
97-
FailedWithMessage("Invalid escaping in \\q"));
91+
""")";
92+
EXPECT_THAT(toString(ParseBlockStringLiteral(Input).takeError()),
93+
Eq("Invalid escaping in \\q"));
9894
}
9995

10096
TEST(ParseBlockStringLiteral, OkEmptyString) {
101-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
102-
""")"),
103-
HasValue(""));
97+
constexpr char Input[] = R"("""
98+
""")";
99+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(""));
104100
}
105101

106102
TEST(ParseBlockStringLiteral, OkOneLineString) {
107-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
103+
constexpr char Input[] = R"("""
108104
A block string literal
109-
""")"),
110-
HasValue(R"(A block string literal
111-
)"));
105+
""")";
106+
constexpr char Expected[] = R"(A block string literal
107+
)";
108+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
112109
}
113110

114111
TEST(ParseBlockStringLiteral, OkTwoLineString) {
115-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
112+
constexpr char Input[] = R"("""
116113
A block string literal
117114
with indent.
118-
""")"),
119-
HasValue(R"(A block string literal
115+
""")";
116+
constexpr char Expected[] = R"(A block string literal
120117
with indent.
121-
)"));
118+
)";
119+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
122120
}
123121

124122
TEST(ParseBlockStringLiteral, OkWithFileTypeIndicator) {
125-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""carbon
123+
constexpr char Input[] = R"("""carbon
126124
A block string literal
127125
with file type indicator.
128-
""")"),
129-
HasValue(R"(A block string literal
126+
""")";
127+
constexpr char Expected[] = R"(A block string literal
130128
with file type indicator.
131-
)"));
129+
)";
130+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
132131
}
133132

134133
TEST(ParseBlockStringLiteral, OkWhitespaceAfterOpeningQuotes) {
135-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
134+
constexpr char Input[] = R"("""
136135
A block string literal
137-
""")"),
138-
HasValue(R"(A block string literal
139-
)"));
136+
""")";
137+
constexpr char Expected[] = R"(A block string literal
138+
)";
139+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
140140
}
141141

142142
TEST(ParseBlockStringLiteral, OkWithEmptyLines) {
143-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
143+
constexpr char Input[] = R"("""
144144
A block string literal
145145
146146
with
147147
148148
empty
149149
150150
lines.
151-
""")"),
152-
HasValue(R"(A block string literal
151+
""")";
152+
constexpr char Expected[] = R"(A block string literal
153153
154154
with
155155
156156
empty
157157
158158
lines.
159-
)"));
159+
)";
160+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
160161
}
161162

162163
TEST(ParseBlockStringLiteral, OkWithSlashNewlineEscape) {
163-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
164+
constexpr char Input[] = R"("""
164165
A block string literal\
165-
""")"),
166-
HasValue("A block string literal"));
166+
""")";
167+
constexpr char Expected[] = "A block string literal";
168+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
167169
}
168170

169171
TEST(ParseBlockStringLiteral, OkWithDoubleSlashNewline) {
170-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
172+
constexpr char Input[] = R"("""
171173
A block string literal\\
172-
""")"),
173-
HasValue(R"(A block string literal\
174-
)"));
174+
""")";
175+
constexpr char Expected[] = R"(A block string literal\
176+
)";
177+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
175178
}
176179

177180
TEST(ParseBlockStringLiteral, OkWithTripleSlashNewline) {
178-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
181+
constexpr char Input[] = R"("""
179182
A block string literal\\\
180-
""")"),
181-
HasValue(R"(A block string literal\)"));
183+
""")";
184+
constexpr char Expected[] = R"(A block string literal\)";
185+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
182186
}
183187

184188
TEST(ParseBlockStringLiteral, OkMultipleSlashes) {
185-
EXPECT_THAT_EXPECTED(ParseBlockStringLiteral(R"("""
189+
constexpr char Input[] = R"("""
186190
A block string literal\
187191
\
188192
\
189193
\
190-
""")"),
191-
HasValue("A block string literal"));
194+
""")";
195+
constexpr char Expected[] = "A block string literal";
196+
EXPECT_THAT(ParseBlockStringLiteral(Input).get(), Eq(Expected));
192197
}
193198

194199
} // namespace

scripts/forbid_llvm_googletest.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
3+
"""Detects and prevents dependencies on LLVM's googletest.
4+
5+
Carbon uses googletest directly, and it's a significantly more recent version
6+
than is provided by LLVM. Using both versions in the same binary leads to
7+
problems, so this detects dependencies.
8+
9+
We also have some dependency checking at //bazel/check_deps. This is a separate
10+
script because check_deps relies on being able to validate specific binaries
11+
which change infrequently, whereas this effectively monitors all cc_test rules,
12+
the set of which is expected to be altered more often.
13+
"""
14+
15+
__copyright__ = """
16+
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
17+
Exceptions. See /LICENSE for license information.
18+
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
19+
"""
20+
21+
import os
22+
import shutil
23+
import subprocess
24+
from pathlib import Path
25+
26+
_MESSAGE = """\
27+
Dependencies on @llvm-project//llvm:gtest are forbidden, but a dependency path
28+
was detected:
29+
30+
%s
31+
Carbon uses GoogleTest through @com_google_googletest, which is a different
32+
version than LLVM uses at @llvm-project//llvm:gtest. As a consequence,
33+
dependencies on @llvm-project//llvm:gtest must be avoided.
34+
"""
35+
36+
37+
def locate_bazel() -> str:
38+
"""Returns the bazel command.
39+
40+
We use the `BAZEL` environment variable if present. If not, then we try to
41+
use `bazelisk` and then `bazel`.
42+
"""
43+
bazel = os.environ.get("BAZEL")
44+
if bazel:
45+
return bazel
46+
47+
if shutil.which("bazelisk"):
48+
return "bazelisk"
49+
50+
if shutil.which("bazel"):
51+
return "bazel"
52+
53+
exit("Unable to run Bazel")
54+
55+
56+
def main() -> None:
57+
# Change the working directory to the repository root so that the remaining
58+
# operations reliably operate relative to that root.
59+
os.chdir(Path(__file__).parent.parent)
60+
args = [
61+
locate_bazel(),
62+
"query",
63+
"somepath(//..., @llvm-project//llvm:gtest)",
64+
]
65+
p = subprocess.run(
66+
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8"
67+
)
68+
if p.returncode != 0:
69+
print(p.stderr)
70+
exit(f"bazel query returned {p.returncode}")
71+
if p.stdout:
72+
exit(_MESSAGE % p.stdout)
73+
print("Done!")
74+
75+
76+
if __name__ == "__main__":
77+
main()

0 commit comments

Comments
 (0)