Skip to content

Commit 8100792

Browse files
justin808claude
andauthored
Add bin/setup for unified development environment setup (#2191)
## Summary Adds a unified `bin/setup` script that installs all dependencies across the monorepo, making it easy for new contributors to get started quickly with a single command. ## Changes - Add `bin/setup` script for unified development environment setup - Update `CONTRIBUTING.md` with quick setup instructions referencing the new script - Script handles all directories: root, react_on_rails/spec/dummy, and react_on_rails_pro/* (if present) ## Features - Prerequisite checking (pnpm, bundle, node, ruby) with version display - Colored output with clear step indicators - Path verification to ensure script is run from correct directory - Build artifact verification after `rake node_package` - Graceful handling of missing directories (e.g., react_on_rails_pro for non-Pro contributors) - Uses `--frozen-lockfile` for pnpm to match CI behavior - `--skip-pro` flag for contributors without Pro access - `--help` flag for usage information - Elapsed time display at completion - Git hooks documentation in completion message ## Manual Testing Requirements Before merging, verify the following (per CLAUDE.md requirements): ### Test Scenarios - [ ] **Fresh clone**: Test in a fresh clone (not existing dev environment) - [ ] **Pro directory present**: Test with Pro directory available - [ ] **Pro directory absent**: Test without Pro directory (or use `--skip-pro`) - [ ] **--skip-pro flag**: Verify it correctly skips Pro setup ### Build Verification After setup completes, verify: ```bash ls -la packages/react-on-rails/lib/ReactOnRails.full.js ``` ### Post-Setup Commands Verify these work after setup: ```bash rake # Should run tests successfully rake lint # Should pass linting ``` ### Additional Tests - [ ] Test running from different working directories - [ ] Verify `--help` shows usage - [ ] Verify unknown options show error message ## Usage ```sh # First, verify your versions match the project requirements ruby -v # Should show 3.4.x or version in .ruby-version node -v # Should show 22.x or version in .node-version # Then run the setup script bin/setup # Or skip Pro setup (for contributors without Pro access) bin/setup --skip-pro ``` ## Test plan - [x] Tested `bin/setup --help` displays usage correctly - [x] Tested error handling for unknown flags - [x] Tested path verification logic (missing Rakefile detection) - [x] Verified trailing newlines on all files - [x] Pre-commit hooks pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 61f1f4d commit 8100792

File tree

2 files changed

+337
-4
lines changed

2 files changed

+337
-4
lines changed

CONTRIBUTING.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ During this transition:
2626

2727
Git hooks are installed automatically when you run the standard setup commands. They will run automatic linting on **all changed files (staged + unstaged + untracked)** - making commits fast while preventing CI failures.
2828

29+
- After cloning the repo, run `bin/setup` from the root directory to install all dependencies.
30+
2931
- After updating code via Git, to prepare all examples:
3032

3133
```sh
32-
cd react_on_rails/
3334
bundle && pnpm install && rake shakapacker_examples:gen_all && rake node_package && rake
3435
```
3536

36-
See [Dev Initial Setup](#dev-initial-setup) below for, well... initial setup,
37+
See [Dev Initial Setup](#dev-initial-setup) below for initial setup details,
3738
and [Running tests](#running-tests) for more details on running tests.
3839

3940
# IDE/IDE SETUP
@@ -199,9 +200,57 @@ or the equivalent command for your package manager.
199200

200201
## Dev Initial Setup
201202

202-
### Prereqs
203+
### Quick Setup (Recommended)
204+
205+
After checking out the repo and ensuring you have Ruby and Node version managers set up (such as rvm and nvm, or rbenv and nodenv, etc.) with the correct versions active, run:
206+
207+
```sh
208+
# First, verify your versions match the project requirements
209+
ruby -v # Should show 3.4.x or version in .ruby-version
210+
node -v # Should show 22.x or version in .node-version
211+
212+
# Then run the setup script
213+
bin/setup
214+
215+
# Or skip Pro setup (for contributors without Pro access)
216+
bin/setup --skip-pro
217+
```
218+
219+
This single command installs all dependencies across the monorepo:
220+
221+
- Root pnpm and bundle dependencies
222+
- Builds the node package
223+
- Sets up `react_on_rails/spec/dummy`
224+
- Sets up `react_on_rails_pro` (if present)
225+
- Sets up `react_on_rails_pro/spec/dummy` (if present)
226+
- Sets up `react_on_rails_pro/spec/execjs-compatible-dummy` (if present)
227+
228+
### Manual Setup (Alternative)
229+
230+
If you prefer to set up manually or need more control:
231+
232+
1. Install root dependencies:
233+
234+
```sh
235+
bundle install
236+
pnpm install
237+
```
238+
239+
2. Build the node package:
240+
241+
```sh
242+
rake node_package
243+
```
244+
245+
3. Set up the dummy app:
246+
247+
```sh
248+
cd react_on_rails/spec/dummy
249+
bundle install
250+
pnpm install
251+
```
203252

204-
After checking out the repo, making sure you have Ruby and Node version managers set up (such as rvm and nvm, or rbenv and nodenv, etc.), cd to `react_on_rails/spec/dummy` and run `bin/setup` to install ruby dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
253+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
205254

206255
### Local Node Package
207256

bin/setup

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
#!/usr/bin/env bash
2+
#
3+
# bin/setup - Unified development environment setup for React on Rails
4+
#
5+
# This script installs all dependencies across all directories in the monorepo,
6+
# making it easy for new contributors to get started quickly.
7+
#
8+
# Usage:
9+
# bin/setup # Full setup of all packages
10+
# bin/setup --skip-pro # Skip Pro package setup
11+
# bin/setup --help # Show this help message
12+
#
13+
14+
set -euo pipefail
15+
16+
# Colors for output
17+
RED='\033[0;31m'
18+
GREEN='\033[0;32m'
19+
YELLOW='\033[1;33m'
20+
BLUE='\033[0;34m'
21+
NC='\033[0m' # No Color
22+
23+
# Script directory (for running from anywhere)
24+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25+
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
26+
27+
# Track start time for elapsed time display
28+
START_TIME=$(date +%s)
29+
30+
# Flags
31+
SKIP_PRO=false
32+
33+
show_help() {
34+
echo "Usage: bin/setup [OPTIONS]"
35+
echo ""
36+
echo "Sets up the React on Rails development environment by installing"
37+
echo "all dependencies across the monorepo."
38+
echo ""
39+
echo "Options:"
40+
echo " --skip-pro Skip react_on_rails_pro setup (for contributors without Pro access)"
41+
echo " --help Show this help message"
42+
echo ""
43+
echo "This script will:"
44+
echo " 1. Install root pnpm and bundle dependencies"
45+
echo " 2. Build the node package"
46+
echo " 3. Set up react_on_rails/spec/dummy"
47+
echo " 4. Set up react_on_rails_pro (if present and not skipped)"
48+
echo " 5. Set up react_on_rails_pro/spec/dummy (if present and not skipped)"
49+
echo " 6. Set up react_on_rails_pro/spec/execjs-compatible-dummy (if present and not skipped)"
50+
}
51+
52+
print_step() {
53+
echo -e "\n${BLUE}==>${NC} ${GREEN}$1${NC}"
54+
}
55+
56+
print_warning() {
57+
echo -e "${YELLOW}Warning:${NC} $1"
58+
}
59+
60+
print_error() {
61+
echo -e "${RED}Error:${NC} $1"
62+
}
63+
64+
print_success() {
65+
echo -e "${GREEN}${NC} $1"
66+
}
67+
68+
check_prerequisites() {
69+
local missing=()
70+
71+
if ! command -v pnpm &> /dev/null; then
72+
missing+=("pnpm")
73+
fi
74+
75+
if ! command -v bundle &> /dev/null; then
76+
missing+=("bundler")
77+
fi
78+
79+
if ! command -v node &> /dev/null; then
80+
missing+=("node")
81+
fi
82+
83+
if ! command -v ruby &> /dev/null; then
84+
missing+=("ruby")
85+
fi
86+
87+
if [ ${#missing[@]} -ne 0 ]; then
88+
print_error "Missing required tools: ${missing[*]}"
89+
echo ""
90+
echo "Please install the following before running this script:"
91+
for tool in "${missing[@]}"; do
92+
case $tool in
93+
pnpm)
94+
echo " - pnpm: https://pnpm.io/installation"
95+
;;
96+
bundler)
97+
echo " - bundler: gem install bundler"
98+
;;
99+
node)
100+
echo " - node: https://nodejs.org/ (or use nvm/nodenv)"
101+
;;
102+
ruby)
103+
echo " - ruby: https://www.ruby-lang.org/ (or use rvm/rbenv)"
104+
;;
105+
esac
106+
done
107+
exit 1
108+
fi
109+
110+
# Display versions found
111+
echo " Ruby: $(ruby -v | head -1)"
112+
echo " Node: $(node -v)"
113+
echo " pnpm: $(pnpm -v)"
114+
echo " Bundler: $(bundle -v)"
115+
}
116+
117+
verify_root_directory() {
118+
if [ ! -f "$ROOT_DIR/Rakefile" ]; then
119+
print_error "Rakefile not found. Are you in the correct directory?"
120+
print_error "Expected location: $ROOT_DIR/Rakefile"
121+
exit 1
122+
fi
123+
124+
if [ ! -f "$ROOT_DIR/package.json" ]; then
125+
print_error "package.json not found. Are you in the correct directory?"
126+
print_error "Expected location: $ROOT_DIR/package.json"
127+
exit 1
128+
fi
129+
}
130+
131+
install_dependencies() {
132+
local dir="$1"
133+
local name="$2"
134+
135+
if [ ! -d "$dir" ]; then
136+
print_warning "Directory not found: $dir (skipping)"
137+
return 0
138+
fi
139+
140+
print_step "Setting up $name..."
141+
cd "$dir"
142+
143+
# Install Ruby dependencies if Gemfile exists
144+
if [ -f "Gemfile" ]; then
145+
echo " Installing Ruby dependencies..."
146+
if bundle check &> /dev/null; then
147+
print_success "Ruby dependencies already satisfied"
148+
else
149+
if ! bundle install; then
150+
print_error "Failed to install Ruby dependencies in $name"
151+
exit 1
152+
fi
153+
print_success "Ruby dependencies installed"
154+
fi
155+
fi
156+
157+
# Install JS dependencies if package.json exists
158+
# Use --frozen-lockfile to match CI behavior and ensure lockfile integrity
159+
if [ -f "package.json" ]; then
160+
echo " Installing JavaScript dependencies..."
161+
if ! pnpm install --frozen-lockfile; then
162+
print_error "Failed to install JavaScript dependencies in $name"
163+
exit 1
164+
fi
165+
print_success "JavaScript dependencies installed"
166+
fi
167+
168+
cd "$ROOT_DIR"
169+
}
170+
171+
build_node_package() {
172+
# Builds TypeScript packages and runs pnpm yalc:publish for local development.
173+
# This compiles node_package/src/ to lib/ and makes packages available locally.
174+
print_step "Building node package..."
175+
if ! rake node_package; then
176+
print_error "Failed to build node package"
177+
exit 1
178+
fi
179+
print_success "Node package built"
180+
}
181+
182+
verify_build_artifacts() {
183+
print_step "Verifying build artifacts..."
184+
185+
local artifact="packages/react-on-rails/lib/ReactOnRails.full.js"
186+
if [ ! -f "$ROOT_DIR/$artifact" ]; then
187+
print_error "Build failed: $artifact not found"
188+
print_error "Expected location: $ROOT_DIR/$artifact"
189+
exit 1
190+
fi
191+
print_success "Build artifacts verified"
192+
}
193+
194+
show_elapsed_time() {
195+
local END_TIME=$(date +%s)
196+
local ELAPSED=$((END_TIME - START_TIME))
197+
local MINUTES=$((ELAPSED / 60))
198+
local SECONDS=$((ELAPSED % 60))
199+
200+
if [ $MINUTES -gt 0 ]; then
201+
echo -e "Total time: ${BLUE}${MINUTES}m ${SECONDS}s${NC}"
202+
else
203+
echo -e "Total time: ${BLUE}${SECONDS}s${NC}"
204+
fi
205+
}
206+
207+
main() {
208+
# Parse arguments
209+
while [[ $# -gt 0 ]]; do
210+
case $1 in
211+
--help|-h)
212+
show_help
213+
exit 0
214+
;;
215+
--skip-pro)
216+
SKIP_PRO=true
217+
shift
218+
;;
219+
*)
220+
print_error "Unknown option: $1"
221+
echo "Run 'bin/setup --help' for usage information."
222+
exit 1
223+
;;
224+
esac
225+
done
226+
227+
echo -e "${GREEN}Setting up React on Rails development environment...${NC}"
228+
echo ""
229+
230+
cd "$ROOT_DIR"
231+
232+
# Verify we're in the correct directory
233+
print_step "Verifying project directory..."
234+
verify_root_directory
235+
print_success "Project directory verified"
236+
237+
# Check prerequisites
238+
print_step "Checking prerequisites..."
239+
check_prerequisites
240+
print_success "All prerequisites found"
241+
242+
# Root dependencies
243+
install_dependencies "$ROOT_DIR" "root directory"
244+
245+
# Build node package
246+
build_node_package
247+
248+
# Verify build artifacts
249+
verify_build_artifacts
250+
251+
# react_on_rails/spec/dummy
252+
install_dependencies "$ROOT_DIR/react_on_rails/spec/dummy" "react_on_rails/spec/dummy"
253+
254+
# react_on_rails_pro (if present and not skipped)
255+
if [ "$SKIP_PRO" = true ]; then
256+
print_warning "Skipping react_on_rails_pro setup (--skip-pro flag)"
257+
elif [ -d "$ROOT_DIR/react_on_rails_pro" ]; then
258+
install_dependencies "$ROOT_DIR/react_on_rails_pro" "react_on_rails_pro"
259+
260+
# react_on_rails_pro/spec/dummy
261+
install_dependencies "$ROOT_DIR/react_on_rails_pro/spec/dummy" "react_on_rails_pro/spec/dummy"
262+
263+
# react_on_rails_pro/spec/execjs-compatible-dummy
264+
install_dependencies "$ROOT_DIR/react_on_rails_pro/spec/execjs-compatible-dummy" "react_on_rails_pro/spec/execjs-compatible-dummy"
265+
fi
266+
267+
echo ""
268+
echo -e "${GREEN}========================================${NC}"
269+
echo -e "${GREEN}Setup complete!${NC}"
270+
echo -e "${GREEN}========================================${NC}"
271+
show_elapsed_time
272+
echo ""
273+
echo "Git hooks have been automatically installed during setup."
274+
echo "They will run linting on changed files before each commit."
275+
echo ""
276+
echo "You can now run:"
277+
echo " rake # Run all tests"
278+
echo " rake lint # Run linters"
279+
echo " rake all_but_examples # Run tests (excluding generator examples)"
280+
echo ""
281+
echo "For more information, see CONTRIBUTING.md"
282+
}
283+
284+
main "$@"

0 commit comments

Comments
 (0)