Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ tmux attach -t <session-name>

### Running Tests
```bash
# Run all tests (499 tests)
# Run all tests (508 tests)
npm test

# Run specific test suites
Expand Down Expand Up @@ -459,7 +459,7 @@ Ralph uses advanced error detection with two-stage filtering to eliminate false

## Test Suite

### Test Files (499 tests total)
### Test Files (508 tests total)

| File | Tests | Description |
|------|-------|-------------|
Expand All @@ -473,9 +473,9 @@ Ralph uses advanced error detection with two-stage filtering to eliminate false
| `test_loop_execution.bats` | 20 | Integration tests |
| `test_edge_cases.bats` | 25 | Edge case handling |
| `test_installation.bats` | 14 | Global installation/uninstall workflows |
| `test_project_setup.bats` | 44 | Project setup (setup.sh) validation + .ralphrc permissions |
| `test_project_setup.bats` | 49 | Project setup (setup.sh) validation + .ralphrc permissions + .gitignore (#174) |
| `test_prd_import.bats` | 33 | PRD import (ralph_import.sh) workflows + modern CLI tests |
| `test_enable_core.bats` | 32 | Enable core library (idempotency, project detection, template generation) |
| `test_enable_core.bats` | 36 | Enable core library (idempotency, project detection, template generation, .gitignore #174) |
| `test_task_sources.bats` | 23 | Task sources (beads, GitHub, PRD extraction, normalization) |
| `test_ralph_enable.bats` | 22 | Ralph enable integration tests (wizard, CI version, JSON output) |
| `test_wizard_utils.bats` | 20 | Wizard utility functions (stdout/stderr separation, prompt functions) |
Expand Down
11 changes: 11 additions & 0 deletions lib/enable_core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,17 @@ enable_ralph_in_directory() {
fix_plan_content=$(generate_fix_plan_md "$task_content")
safe_create_file ".ralph/fix_plan.md" "$fix_plan_content"

# Copy .gitignore template to project root (if available)
local templates_dir
templates_dir=$(get_templates_dir 2>/dev/null) || true
if [[ -n "$templates_dir" ]] && [[ -f "$templates_dir/.gitignore" ]]; then
local gitignore_content
gitignore_content=$(<"$templates_dir/.gitignore")
safe_create_file ".gitignore" "$gitignore_content"
else
enable_log "WARN" ".gitignore template not found, skipping"
fi

# Detect task sources for .ralphrc
detect_task_sources
local task_sources="local"
Expand Down
5 changes: 5 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ cp "$TEMPLATES_DIR/fix_plan.md" .ralph/fix_plan.md
cp "$TEMPLATES_DIR/AGENT.md" .ralph/AGENT.md
cp -r "$TEMPLATES_DIR/specs"/* .ralph/specs/ 2>/dev/null || true

# Copy .gitignore template to project root (if available)
if [[ -f "$TEMPLATES_DIR/.gitignore" ]]; then
cp "$TEMPLATES_DIR/.gitignore" .gitignore
fi
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
Outdated

# Generate .ralphrc configuration file
# Source enable_core.sh if available for generate_ralphrc(), otherwise create inline
if [[ -f "$LIB_DIR/enable_core.sh" ]]; then
Expand Down
47 changes: 47 additions & 0 deletions templates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Ralph generated files (inside .ralph/ subfolder)
.ralph/.call_count
.ralph/.last_reset
.ralph/.exit_signals
.ralph/status.json
.ralph/.ralph_session
.ralph/.ralph_session_history
.ralph/.claude_session_id
.ralph/.response_analysis
.ralph/.circuit_breaker_state
.ralph/.circuit_breaker_history

# Ralph logs and generated docs
.ralph/logs/*
!.ralph/logs/.gitkeep
.ralph/docs/generated/*
!.ralph/docs/generated/.gitkeep

# General logs
*.log

# OS files
.DS_Store
Thumbs.db

# Temporary files
*.tmp
.temp/

# Node modules (if using Node.js projects)
node_modules/

# Python cache (if using Python projects)
__pycache__/
*.pyc

# Rust build (if using Rust projects)
target/

# IDE files
.vscode/
.idea/
*.swp
*.swo

# Ralph backup directories (created by migration)
.ralph_backup_*
68 changes: 68 additions & 0 deletions tests/integration/test_project_setup.bats
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,71 @@ teardown() {
# .ralphrc should reference the project name
grep -q "my-custom-project" my-custom-project/.ralphrc
}

# =============================================================================
# Test: .gitignore Generation (Issue #174)
# =============================================================================

@test "setup.sh creates .gitignore file" {
# Create .gitignore template
cat > templates/.gitignore << 'EOF'
# Ralph generated files
.ralph/.call_count
.ralph/.last_reset
.ralph/status.json
EOF

run bash "$SETUP_SCRIPT" test-project

assert_success
assert_file_exists "test-project/.gitignore"
}

@test "setup.sh .gitignore contains Ralph runtime patterns" {
cat > templates/.gitignore << 'EOF'
.ralph/.call_count
.ralph/.last_reset
.ralph/status.json
.ralph/.circuit_breaker_state
EOF

bash "$SETUP_SCRIPT" test-project

grep -q ".ralph/.call_count" test-project/.gitignore
grep -q ".ralph/.circuit_breaker_state" test-project/.gitignore
}

@test "setup.sh .gitignore is committed in initial git commit" {
cat > templates/.gitignore << 'EOF'
.ralph/.call_count
EOF

bash "$SETUP_SCRIPT" test-project

cd test-project
run command git ls-files .gitignore

assert_success
assert_equal "$output" ".gitignore"
}

@test "setup.sh .gitignore content matches template" {
cat > templates/.gitignore << 'EOF'
# Ralph generated files
.ralph/.call_count
.ralph/.last_reset
EOF

bash "$SETUP_SCRIPT" test-project

diff templates/.gitignore test-project/.gitignore
}

@test "setup.sh succeeds when .gitignore template is missing" {
# Do NOT create templates/.gitignore — should still succeed
run bash "$SETUP_SCRIPT" test-project

assert_success
# .gitignore should not exist since template was missing
[[ ! -f "test-project/.gitignore" ]]
}
82 changes: 82 additions & 0 deletions tests/unit/test_enable_core.bats
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@ load '../helpers/fixtures'

# Path to enable_core.sh
ENABLE_CORE="${BATS_TEST_DIRNAME}/../../lib/enable_core.sh"
ORIGINAL_HOME="$HOME"

setup() {
# Create temporary test directory
TEST_DIR="$(mktemp -d)"
cd "$TEST_DIR"

# Isolate HOME so tests that write to ~/.ralph don't leak to real home dir
export HOME="$TEST_DIR/home"
mkdir -p "$HOME"

# Source the library (disable set -e for testing)
set +e
source "$ENABLE_CORE"
set -e
}

teardown() {
export HOME="$ORIGINAL_HOME"
if [[ -n "$TEST_DIR" ]] && [[ -d "$TEST_DIR" ]]; then
cd /
rm -rf "$TEST_DIR"
Expand Down Expand Up @@ -386,3 +392,79 @@ EOF
content=$(cat test_file.txt)
[[ "$content" == "original content" ]]
}

# =============================================================================
# .GITIGNORE CREATION (Issue #174) (4 tests)
# =============================================================================

@test "enable_ralph_in_directory creates .gitignore when template exists" {
# HOME is already isolated to TEST_DIR/home by setup()
mkdir -p "$HOME/.ralph/templates"
cat > "$HOME/.ralph/templates/.gitignore" << 'EOF'
.ralph/.call_count
.ralph/.last_reset
.ralph/status.json
EOF

export ENABLE_FORCE="false"
export ENABLE_SKIP_TASKS="true"
export ENABLE_PROJECT_NAME="test-project"

run enable_ralph_in_directory

assert_success
[[ -f ".gitignore" ]]
grep -q ".ralph/.call_count" .gitignore
}

@test "enable_ralph_in_directory skips .gitignore when one exists and no force" {
mkdir -p "$HOME/.ralph/templates"
echo ".ralph/.call_count" > "$HOME/.ralph/templates/.gitignore"

# Pre-existing .gitignore
echo "my-custom-ignore" > .gitignore

export ENABLE_FORCE="false"
export ENABLE_SKIP_TASKS="true"
export ENABLE_PROJECT_NAME="test-project"

run enable_ralph_in_directory

assert_success
# Should preserve existing .gitignore content
grep -q "my-custom-ignore" .gitignore
}

@test "enable_ralph_in_directory overwrites .gitignore with force" {
mkdir -p "$HOME/.ralph/templates"
echo ".ralph/.call_count" > "$HOME/.ralph/templates/.gitignore"

# Pre-existing .gitignore with different content
echo "my-custom-ignore" > .gitignore

export ENABLE_FORCE="true"
export ENABLE_SKIP_TASKS="true"
export ENABLE_PROJECT_NAME="test-project"

run enable_ralph_in_directory

assert_success
# Should have template content, not old content
grep -q ".ralph/.call_count" .gitignore
! grep -q "my-custom-ignore" .gitignore
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

@test "enable_ralph_in_directory succeeds when templates dir exists but .gitignore is missing" {
# Templates dir exists but no .gitignore template inside
mkdir -p "$HOME/.ralph/templates"

export ENABLE_FORCE="false"
export ENABLE_SKIP_TASKS="true"
export ENABLE_PROJECT_NAME="test-project"

run enable_ralph_in_directory

assert_success
# .gitignore should not be created
[[ ! -f ".gitignore" ]]
}