Skip to content

Commit 41239b0

Browse files
maolingdcapwell
authored andcommitted
Add AGENTS.md and CLAUDE.md
patch by Ling Mao; reviewed by David Capwell, Stefan Miklosovic for CASSANDRA-21301 Co-authored-by: David Capwell <dcapwell@gmail.com>
1 parent 890ba2a commit 41239b0

9 files changed

Lines changed: 583 additions & 0 deletions

File tree

.build/build-rat.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
<!-- legal files -->
8989
<exclude NAME="NOTICE.txt"/>
9090
<exclude NAME="LICENSE.txt"/>
91+
<!-- AI agent instruction files -->
92+
<exclude NAME="AGENTS.md"/>
93+
<exclude NAME="CLAUDE.md"/>
9194
<!-- misc -->
9295
<exclude NAME="**/*.patch"/>
9396
<exclude NAME="**/*.diff"/>

.build/sh/ai-build

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
#set -o xtrace
19+
set -o errexit
20+
set -o pipefail
21+
set -o nounset
22+
23+
bin="$(cd "$(dirname "$0")" > /dev/null; pwd)"
24+
home="$(cd "$bin/../.." > /dev/null; pwd)" # this script lives in .build/sh
25+
26+
usage() {
27+
if [[ $# -gt 0 ]]; then
28+
echo "$*" 1>&2
29+
fi
30+
cat <<EOF
31+
Usage: $(basename "$0") (options)*
32+
Options:
33+
--no-checkstyle - runs with all checkstyle disabled
34+
-h|--help - this help page
35+
EOF
36+
exit 1
37+
}
38+
39+
no_checkstyle=false
40+
41+
while [[ "$#" -gt 0 ]]; do
42+
case "$1" in
43+
--no-checkstyle)
44+
no_checkstyle=true
45+
shift
46+
;;
47+
-h|--help)
48+
usage
49+
shift
50+
;;
51+
*)
52+
usage "Unknown argument $1"
53+
;;
54+
esac
55+
done
56+
57+
# Switch to the project root so all commands work properly
58+
cd "$home"
59+
60+
opts=(
61+
-Dant.gen-doc.skip=true
62+
-Drat.skip=true
63+
)
64+
65+
if [ $no_checkstyle ]; then
66+
ant -Dno-checkstyle=true "${opts[@]}" clean jar "$@" 2>&1 | "$bin"/ant-log-summary.py -
67+
else
68+
ant "${opts[@]}" clean jar checkstyle checkstyle-test "$@" 2>&1 | "$bin"/ant-log-summary.py -
69+
fi
70+

.build/sh/ai-ci-test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
#set -o xtrace
19+
set -o errexit
20+
set -o pipefail
21+
set -o nounset
22+
23+
bin="$(cd "$(dirname "$0")" > /dev/null; pwd)"
24+
home="$(cd "$bin/../.." > /dev/null; pwd)" # this script lives in .build/sh
25+
26+
# Switch to the project root so all commands work properly
27+
cd "$home"
28+
29+
"$bin"/ci-test "$@" 2>&1 | "$bin"/ant-log-summary.py -

.build/sh/ant-log-summary.py

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing, software
15+
# distributed under the License is distributed on an "AS IS" BASIS,
16+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
# See the License for the specific language governing permissions and
18+
# limitations under the License.
19+
20+
import argparse
21+
import sys
22+
23+
24+
def parse_args():
25+
parser = argparse.ArgumentParser(
26+
description="Parse Apache Cassandra ant build logs and summarize failures"
27+
)
28+
parser.add_argument(
29+
"log_file",
30+
help='Path to the ant build log file to analyze (use "-" to read from stdin)',
31+
)
32+
return parser.parse_args()
33+
34+
35+
def find_build_failures(content):
36+
"""
37+
Parse the log content and extract failure information.
38+
Returns a tuple: (is_failed, failed_target, failure_output)
39+
"""
40+
lines = content.split("\n")
41+
42+
# Check if build was successful first
43+
if "BUILD FAILED" not in content:
44+
return False, None, []
45+
46+
# Track what ant targets are running before the build failed
47+
failed_target = None
48+
failed_target_line = -1
49+
for i, line in enumerate(lines):
50+
if "BUILD FAILED" in line:
51+
break
52+
# Keep track of tasks so when we finally see the BUILD FAILED we know what the last task was
53+
line_stripped = line.strip()
54+
if line_stripped.endswith(":") and not line.startswith(" ") and "[" not in line:
55+
failed_target = line_stripped[:-1]
56+
failed_target_line = i
57+
58+
target_start_idx = 0
59+
if failed_target and failed_target_line >= 0:
60+
target_start_idx = failed_target_line
61+
62+
# Collect the output from the failed target up to BUILD FAILED
63+
failure_output = []
64+
for line in lines[target_start_idx:]:
65+
stripped = line.strip()
66+
if stripped:
67+
failure_output.append(line.rstrip())
68+
69+
return True, failed_target, failure_output
70+
71+
72+
def extract_compilation_errors(content):
73+
"""Extract compilation error details specifically."""
74+
lines = content.split("\n")
75+
error_lines = []
76+
77+
for line in lines:
78+
if "[javac]" in line and ("error:" in line or "errors" in line):
79+
# Clean up the line to show just the error
80+
clean_line = line.replace("[javac]", "").strip()
81+
if clean_line:
82+
error_lines.append(clean_line)
83+
84+
return error_lines
85+
86+
87+
def extract_test_failures(content):
88+
"""Extract test failure details specifically."""
89+
lines = content.split("\n")
90+
test_failures = []
91+
92+
for line in lines:
93+
if "Test " in line and "FAILED" in line:
94+
test_failures.append(line.strip())
95+
96+
return test_failures
97+
98+
99+
def main():
100+
args = parse_args()
101+
102+
try:
103+
if args.log_file == "-":
104+
content = sys.stdin.read()
105+
else:
106+
with open(args.log_file, "r") as f:
107+
content = f.read()
108+
except FileNotFoundError:
109+
print(f"Error: Log file '{args.log_file}' not found")
110+
sys.exit(1)
111+
except Exception as e:
112+
print(f"Error reading log file: {e}")
113+
sys.exit(1)
114+
115+
is_failed, failed_target, failure_output = find_build_failures(content)
116+
117+
if not is_failed:
118+
print("BUILD SUCCESSFUL")
119+
sys.exit(0)
120+
121+
print("BUILD FAILED")
122+
if failed_target:
123+
print(f"Failed target: {failed_target}")
124+
125+
print("=" * 50)
126+
127+
# Special handling for compilation and test failures
128+
if failed_target and (
129+
"test" in failed_target.lower() or "compile" in failed_target.lower()
130+
):
131+
# Extract compilation errors if it's a compile-related target
132+
compilation_errors = extract_compilation_errors("\n".join(failure_output))
133+
if compilation_errors:
134+
print("\nCompilation Errors:")
135+
print("-" * 20)
136+
for error in compilation_errors:
137+
print(error)
138+
# Also show the full output for context
139+
print(f"\nFull output from failed target '{failed_target}':")
140+
print("-" * 40)
141+
for line in failure_output:
142+
print(line)
143+
sys.exit(1)
144+
145+
# Extract test failures if it's a test-related target
146+
test_failures = extract_test_failures("\n".join(failure_output))
147+
if test_failures:
148+
print("\nTest Failures:")
149+
print("-" * 15)
150+
for failure in test_failures:
151+
print(failure)
152+
# Always show the full output for test failures - this is crucial for debugging
153+
print(f"\nFull output from failed target '{failed_target}':")
154+
print("-" * 40)
155+
for line in failure_output:
156+
print(line)
157+
sys.exit(1)
158+
159+
# For all other targets or if no specific errors found, show the task output
160+
if failure_output:
161+
print(f"\nOutput from failed target '{failed_target}':")
162+
print("-" * 40)
163+
for line in failure_output:
164+
print(line)
165+
166+
sys.exit(1)
167+
168+
169+
if __name__ == "__main__":
170+
main()

0 commit comments

Comments
 (0)