feat(iwyu): add scripts for Include What You Use analysis and results review
This commit is contained in:
parent
169bcf96c4
commit
b7dc3dd38d
@ -7,6 +7,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
|||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
# Build essentials
|
# Build essentials
|
||||||
build-essential \
|
build-essential \
|
||||||
|
# Standard clang tools (this will install the default version)
|
||||||
clang \
|
clang \
|
||||||
clang-format \
|
clang-format \
|
||||||
clang-tidy \
|
clang-tidy \
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ build-*
|
|||||||
.cache
|
.cache
|
||||||
webserv.log
|
webserv.log
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
iwyu_results/
|
||||||
17
.iwyu.imp
Normal file
17
.iwyu.imp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[
|
||||||
|
# Standard C++ library mappings
|
||||||
|
{ include: ["<bits/std_abs.h>", "private", "<cstdlib>", "public"] },
|
||||||
|
{ include: ["<bits/stdint-intn.h>", "private", "<cstdint>", "public"] },
|
||||||
|
{ include: ["<bits/stdint-uintn.h>", "private", "<cstdint>", "public"] },
|
||||||
|
|
||||||
|
# System headers
|
||||||
|
{ include: ["<sys/socket.h>", "public", "<sys/socket.h>", "public"] },
|
||||||
|
{ include: ["<netinet/in.h>", "public", "<netinet/in.h>", "public"] },
|
||||||
|
{ include: ["<arpa/inet.h>", "public", "<arpa/inet.h>", "public"] },
|
||||||
|
|
||||||
|
# Project mappings - adjust these to your actual header structure
|
||||||
|
{ include: ["\"webserv/server/Server.hpp\"", "public", "\"webserv/server/Server.hpp\"", "public"] },
|
||||||
|
{ include: ["\"webserv/log/Log.hpp\"", "public", "\"webserv/log/Log.hpp\"", "public"] },
|
||||||
|
{ include: ["\"webserv/socket/Socket.hpp\"", "public", "\"webserv/socket/Socket.hpp\"", "public"] },
|
||||||
|
{ include: ["\"webserv/client/Client.hpp\"", "public", "\"webserv/client/Client.hpp\"", "public"] }
|
||||||
|
]
|
||||||
179
check_iwyu.sh
Executable file
179
check_iwyu.sh
Executable file
@ -0,0 +1,179 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Don't exit on first error - we want to continue checking all files
|
||||||
|
# set -e
|
||||||
|
|
||||||
|
# Detect project root - try container path first, then current directory
|
||||||
|
if [ -d "/workspace" ]; then
|
||||||
|
PROJECT_ROOT="/workspace"
|
||||||
|
else
|
||||||
|
PROJECT_ROOT="$(pwd)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find the build directory - check multiple possible locations
|
||||||
|
BUILD_DIR=""
|
||||||
|
echo -e "${BLUE}🔍 Looking for build directory with compile_commands.json...${NC}"
|
||||||
|
for build_candidate in "$PROJECT_ROOT/build-container" "$PROJECT_ROOT/build-local" "$PROJECT_ROOT/build"; do
|
||||||
|
echo -e " Checking: $build_candidate"
|
||||||
|
if [ -d "$build_candidate" ] && [ -f "$build_candidate/compile_commands.json" ]; then
|
||||||
|
BUILD_DIR="$build_candidate"
|
||||||
|
echo -e "${GREEN} ✅ Found!${NC}"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW} ❌ Not found or no compile_commands.json${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
IWYU_MAPPING="$PROJECT_ROOT/.iwyu.imp"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${BLUE}🔍 Running Include What You Use Analysis...${NC}"
|
||||||
|
echo -e "${BLUE}📁 Project root: $PROJECT_ROOT${NC}"
|
||||||
|
|
||||||
|
# Check if IWYU is available (try both common names)
|
||||||
|
IWYU_CMD=""
|
||||||
|
if command -v include-what-you-use >/dev/null 2>&1; then
|
||||||
|
IWYU_CMD="include-what-you-use"
|
||||||
|
echo -e "${GREEN}✅ Found IWYU as: include-what-you-use${NC}"
|
||||||
|
elif command -v iwyu >/dev/null 2>&1; then
|
||||||
|
IWYU_CMD="iwyu"
|
||||||
|
echo -e "${GREEN}✅ Found IWYU as: iwyu${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ IWYU not found. Please install it first.${NC}"
|
||||||
|
echo -e "${YELLOW}💡 Try: sudo apt install iwyu or yay -S include-what-you-use${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}🛠️ Using IWYU command: $IWYU_CMD${NC}"
|
||||||
|
|
||||||
|
# Check if we found a build directory
|
||||||
|
if [ -z "$BUILD_DIR" ]; then
|
||||||
|
echo -e "${YELLOW}⚠️ No build directory with compile_commands.json found.${NC}"
|
||||||
|
echo -e "${YELLOW}📂 Checked: build-container/, build-local/, build/${NC}"
|
||||||
|
echo -e "${YELLOW}🔨 Running cmake to create build directory...${NC}"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
# Try to create build directory (prefer build-container in container, build-local otherwise)
|
||||||
|
if [ -d "/workspace" ]; then
|
||||||
|
BUILD_DIR="$PROJECT_ROOT/build-container"
|
||||||
|
else
|
||||||
|
BUILD_DIR="$PROJECT_ROOT/build-local"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
cd "$BUILD_DIR"
|
||||||
|
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✅ Found build directory: $BUILD_DIR${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Final check that compile_commands.json exists
|
||||||
|
if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then
|
||||||
|
echo -e "${RED}❌ Failed to create compile_commands.json in $BUILD_DIR${NC}"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
cmake -B "$BUILD_DIR" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
|
||||||
|
# Check again after cmake
|
||||||
|
if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then
|
||||||
|
echo -e "${RED}❌ Still no compile_commands.json after cmake. Exiting.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create results directory
|
||||||
|
RESULTS_DIR="$PROJECT_ROOT/iwyu_results"
|
||||||
|
mkdir -p "$RESULTS_DIR"
|
||||||
|
|
||||||
|
# Function to run IWYU on a single file
|
||||||
|
run_iwyu_on_file() {
|
||||||
|
local file="$1"
|
||||||
|
local relative_path="${file#$PROJECT_ROOT/}"
|
||||||
|
local output_file="$RESULTS_DIR/$(basename "$file" .cpp).iwyu"
|
||||||
|
|
||||||
|
echo -e "${BLUE}Analyzing: ${relative_path}${NC}"
|
||||||
|
|
||||||
|
# Run IWYU with compile commands
|
||||||
|
if "$IWYU_CMD" \
|
||||||
|
-I"$PROJECT_ROOT" \
|
||||||
|
-std=c++20 \
|
||||||
|
-Xiwyu --verbose=3 \
|
||||||
|
-Xiwyu --quoted_includes_first \
|
||||||
|
-Xiwyu --cxx17ns \
|
||||||
|
"$file" \
|
||||||
|
2>&1 | tee "$output_file"; then
|
||||||
|
|
||||||
|
# Check if IWYU found issues
|
||||||
|
if grep -q "should add these lines:" "$output_file" || grep -q "should remove these lines:" "$output_file"; then
|
||||||
|
echo -e "${YELLOW}⚠️ Issues found in $relative_path${NC}"
|
||||||
|
return 2 # Issues found (not a script failure)
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✅ $relative_path looks good${NC}"
|
||||||
|
return 0 # All good
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
local iwyu_exit_code=$?
|
||||||
|
echo -e "${RED}❌ IWYU failed for $relative_path (exit code: $iwyu_exit_code)${NC}"
|
||||||
|
return 1 # IWYU execution failed
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find all C++ source files
|
||||||
|
echo -e "\n${BLUE}Finding C++ source files...${NC}"
|
||||||
|
cpp_files=()
|
||||||
|
while IFS= read -r -d '' file; do
|
||||||
|
cpp_files+=("$file")
|
||||||
|
done < <(find "$PROJECT_ROOT/webserv" -name "*.cpp" -print0 2>/dev/null)
|
||||||
|
|
||||||
|
if [ ${#cpp_files[@]} -eq 0 ]; then
|
||||||
|
echo -e "${RED}❌ No .cpp files found in webserv directory${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}Found ${#cpp_files[@]} C++ source files${NC}\n"
|
||||||
|
|
||||||
|
# Run IWYU on all files
|
||||||
|
issues_found=0
|
||||||
|
total_files=${#cpp_files[@]}
|
||||||
|
current_file=0
|
||||||
|
|
||||||
|
for file in "${cpp_files[@]}"; do
|
||||||
|
((current_file++))
|
||||||
|
echo -e "${BLUE}[$current_file/$total_files]${NC}"
|
||||||
|
|
||||||
|
run_iwyu_on_file "$file"
|
||||||
|
exit_code=$?
|
||||||
|
|
||||||
|
if [ $exit_code -eq 2 ]; then
|
||||||
|
# Issues found (normal)
|
||||||
|
((issues_found++))
|
||||||
|
elif [ $exit_code -eq 1 ]; then
|
||||||
|
# IWYU execution failed (error)
|
||||||
|
echo -e "${RED}⚠️ IWYU execution error for $(basename "$file")${NC}"
|
||||||
|
((issues_found++))
|
||||||
|
fi
|
||||||
|
# exit_code 0 means no issues found
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo -e "${BLUE}📊 IWYU Analysis Summary${NC}"
|
||||||
|
echo -e "Total files analyzed: $total_files"
|
||||||
|
echo -e "Files with issues: $issues_found"
|
||||||
|
echo -e "Results saved in: $RESULTS_DIR"
|
||||||
|
|
||||||
|
if [ $issues_found -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}🎉 All files have proper includes!${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ $issues_found files need attention${NC}"
|
||||||
|
echo -e "${BLUE}💡 Run './fix_iwyu.sh' to review suggested fixes${NC}"
|
||||||
|
exit 0 # Don't fail the script for include suggestions
|
||||||
|
fi
|
||||||
78
fix_iwyu.sh
Executable file
78
fix_iwyu.sh
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PROJECT_ROOT="/workspace"
|
||||||
|
RESULTS_DIR="$PROJECT_ROOT/iwyu_results"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${BLUE}🔧 Reviewing IWYU fixes...${NC}"
|
||||||
|
|
||||||
|
if [ ! -d "$RESULTS_DIR" ]; then
|
||||||
|
echo -e "${RED}❌ No IWYU results found. Run './check_iwyu.sh' first.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if there are any result files
|
||||||
|
result_files=("$RESULTS_DIR"/*.iwyu)
|
||||||
|
if [ ! -f "${result_files[0]}" ]; then
|
||||||
|
echo -e "${YELLOW}⚠️ No IWYU result files found.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}💡 IWYU Analysis Results - Manual Review Required${NC}"
|
||||||
|
echo -e "${YELLOW}Note: Automatic fixing requires careful review before applying changes.${NC}\n"
|
||||||
|
|
||||||
|
files_with_issues=0
|
||||||
|
|
||||||
|
for result_file in "$RESULTS_DIR"/*.iwyu; do
|
||||||
|
if [ -f "$result_file" ]; then
|
||||||
|
filename=$(basename "$result_file" .iwyu)
|
||||||
|
|
||||||
|
# Check if this file has suggestions
|
||||||
|
if grep -q "should add these lines:\|should remove these lines:" "$result_file"; then
|
||||||
|
((files_with_issues++))
|
||||||
|
|
||||||
|
echo -e "${BLUE}=== $filename.cpp ===${NC}"
|
||||||
|
|
||||||
|
# Show additions
|
||||||
|
if grep -q "should add these lines:" "$result_file"; then
|
||||||
|
echo -e "${GREEN}📥 Suggested additions:${NC}"
|
||||||
|
sed -n '/should add these lines:/,/^$/p' "$result_file" | grep -v "should add these lines:" | head -20
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show removals
|
||||||
|
if grep -q "should remove these lines:" "$result_file"; then
|
||||||
|
echo -e "${RED}📤 Suggested removals:${NC}"
|
||||||
|
sed -n '/should remove these lines:/,/^$/p' "$result_file" | grep -v "should remove these lines:" | head -20
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show full analysis (first 30 lines for context)
|
||||||
|
echo -e "${BLUE}📋 Full analysis:${NC}"
|
||||||
|
head -30 "$result_file"
|
||||||
|
echo -e "${YELLOW}... (see $result_file for complete output)${NC}"
|
||||||
|
echo -e "${BLUE}${'='*60}${NC}\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $files_with_issues -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}🎉 No issues found in any analyzed files!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}📊 Summary: $files_with_issues files have suggested changes${NC}"
|
||||||
|
echo -e "${BLUE}💡 Tips for applying fixes:${NC}"
|
||||||
|
echo -e " • Review each suggestion carefully"
|
||||||
|
echo -e " • Test compilation after each change"
|
||||||
|
echo -e " • Some suggestions might be false positives"
|
||||||
|
echo -e " • Consider project-specific header policies"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}🗂️ Detailed results available in: $RESULTS_DIR${NC}"
|
||||||
|
fi
|
||||||
Loading…
Reference in New Issue
Block a user