Skip to content

Commit 9475e42

Browse files
committed
reorganized bin/scripts dirs
1 parent e982601 commit 9475e42

25 files changed

+374
-66
lines changed

.cspell/project-words.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ vercel
4949
wordlists
5050
xorshift
5151
yardoc
52+
TESTOPTS

.github/workflows/test.yml

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,40 @@ jobs:
2525
uses: actions/setup-node@v4
2626
with:
2727
node-version: 20
28-
cache: 'npm'
29-
cache-dependency-path: |
30-
package-lock.json
31-
site/package-lock.json
3228

33-
- name: Install dependencies
29+
- name: Setup pnpm
30+
uses: pnpm/action-setup@v4
31+
with:
32+
version: latest
33+
34+
- name: Get pnpm store directory
35+
shell: bash
3436
run: |
35-
# Install root and site npm dependencies
36-
npm ci
37-
cd site && npm ci && cd ..
37+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
38+
39+
- name: Setup pnpm cache
40+
uses: actions/cache@v4
41+
with:
42+
path: ${{ env.STORE_PATH }}
43+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
44+
restore-keys: |
45+
${{ runner.os }}-pnpm-store-
3846
39-
# Make sure bundler is using the correct Ruby version
40-
ruby -v
47+
- name: Install npm packages
48+
run: |
49+
# Install root and site pnpm dependencies
50+
pnpm install --frozen-lockfile
51+
cd site && pnpm install --frozen-lockfile && cd ..
4152
4253
- name: Generate CSpell dictionaries from package lockfiles
4354
run: |
44-
bin/generate_lockfile_words
55+
scripts/generate_lockfile_words.sh
4556
4657
- name: CSpell (Spellcheck)
47-
run: bin/spellcheck
58+
run: scripts/spellcheck.sh
4859

4960
- name: Prettier (Formatting)
50-
run: bin/prettier --check
61+
run: scripts/prettier.sh --check
5162

5263
- name: Tapioca (Verify RBI files)
5364
run: |
@@ -74,10 +85,10 @@ jobs:
7485
fi
7586
7687
- name: RuboCop (Linting/Formatting)
77-
run: bin/rubocop
88+
run: scripts/rubocop.rb
7889

7990
- name: Sorbet (Typecheck)
80-
run: bin/typecheck
91+
run: scripts/typecheck.sh
8192

8293
site:
8394
name: 'Next.js Site Tests'
@@ -95,23 +106,39 @@ jobs:
95106
uses: actions/setup-node@v4
96107
with:
97108
node-version: 20
98-
cache: 'npm'
99-
cache-dependency-path: 'site/package-lock.json'
109+
110+
- name: Setup pnpm
111+
uses: pnpm/action-setup@v4
112+
with:
113+
version: latest
114+
115+
- name: Get pnpm store directory
116+
shell: bash
117+
run: |
118+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
119+
120+
- name: Setup pnpm cache
121+
uses: actions/cache@v4
122+
with:
123+
path: ${{ env.STORE_PATH }}
124+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
125+
restore-keys: |
126+
${{ runner.os }}-pnpm-store-
100127
101128
- name: Install site dependencies
102-
run: cd site && npm ci
129+
run: cd site && pnpm install --frozen-lockfile
103130

104131
- name: Export TypeScript types from LogStruct
105132
run: |
106133
scripts/export_typescript_types.rb
107134
108135
- name: TypeScript type checking
109136
run: |
110-
cd site && npx tsc --noEmit
137+
cd site && pnpm exec tsc --noEmit
111138
112139
- name: Run TypeScript tests
113140
run: |
114-
cd site && npm test
141+
cd site && pnpm test
115142
116143
pilot:
117144
name: 'Pilot Test: Ruby 3.4 / Rails 8.0'
@@ -136,15 +163,15 @@ jobs:
136163

137164
# Coverage: /coverage
138165
- name: Run tests
139-
run: bin/test
166+
run: scripts/test.rb
140167

141168
# Coverage: /coverage_rails
142169
- name: Run Rails integration tests
143-
run: bin/rails_tests
170+
run: scripts/rails_tests.sh
144171

145172
# Merges /coverage and /coverage_rails into /site/public/coverage/
146173
- name: Merge coverage reports
147-
run: bin/merge_coverage
174+
run: scripts/merge_coverage.sh
148175

149176
# Save merged coverage data as an artifact for deploy workflow
150177
- name: Upload coverage reports
@@ -196,7 +223,7 @@ jobs:
196223
bundler-cache: true
197224

198225
- name: Run Ruby tests
199-
run: bin/test
226+
run: scripts/test.rb
200227

201228
- name: Run Rails integration tests
202-
run: bin/rails_tests
229+
run: scripts/rails_tests.sh

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ AllCops:
2121
- sorbet/rbi/gems/**/*
2222
- sorbet/rbi/annotations/**/*
2323
- rails_test_app/logstruct_test_app/**/*
24+
- bin/**/* # Exclude bundler-generated binstubs
2425

2526
Layout/MultilineHashKeyLineBreaks:
2627
Enabled: true
@@ -92,6 +93,8 @@ Sorbet/TrueSigil:
9293
- 'test/**/*.rb'
9394
- 'rails_test_app/**/*.rb'
9495
- 'scripts/**/*.rb'
96+
Exclude:
97+
- 'scripts/test.rb' # Has dynamic code that Sorbet can't handle
9598
SuggestedStrictness: true
9699

97100
# Don't try to validate typing on generated Sorbet RBI files

CLAUDE.md

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,47 @@
22

33
## 🚨 CRITICAL RULES - MUST ALWAYS BE FOLLOWED 🚨
44

5-
1. **NEVER mark a feature as done until `./bin/all_check` is passing (all linters and tests)**
6-
2. **NO EXCEPTIONS to the above rules - features are NOT complete until all checks pass**
7-
3. **This rule must ALWAYS be followed no matter what**
5+
1. **NEVER mark a feature as done until `./scripts/all_check.sh` and `./scripts/all_tests.sh` are ALL passing**
6+
2. **ALWAYS run both `./scripts/all_check.sh` and `./scripts/all_tests.sh` before claiming completion**
7+
3. **NO EXCEPTIONS to the above rules - features are NOT complete until all checks pass**
8+
4. **This rule must ALWAYS be followed no matter what**
89

910
## Commands
1011

1112
### Core Commands
1213

13-
- Setup: `bin/setup`
14-
- Run all checks: `bin/all` (runs typecheck, export, lint, test, etc.)
15-
- Interactive console: `bin/console`
14+
- Setup: `scripts/setup.sh`
15+
- Run all checks: `scripts/all_check.sh` (runs typecheck, export, lint, test, etc.)
16+
- Run all checks with auto-fix: `scripts/all_write.sh`
17+
- Interactive console: `scripts/console.rb`
1618

1719
### Testing Commands
1820

19-
- Run all tests (unit + Rails integration): `bin/all_tests`
20-
- Run all Ruby unit tests: `bin/test`
21-
- Run single test file: `bin/test test/path_to_test.rb`
22-
- Run test at specific line: `bin/test test/path_to_test.rb:LINE_NUMBER`
23-
- Run test by name: `bin/test -n=test_method_name`
21+
- Run all tests (unit + Rails integration): `scripts/all_tests.sh`
22+
- Run all Ruby unit tests: `scripts/test.rb`
23+
- Run single test file: `scripts/test.rb test/path_to_test.rb`
24+
- Run test at specific line: `scripts/test.rb test/path_to_test.rb:LINE_NUMBER`
25+
- Run test by name: `scripts/test.rb -n=test_method_name`
2426
- Debug a specific test: Add `debugger` statements (developer only)
25-
- Run Rails integration tests: `bin/rails_tests`
26-
- Merge coverage reports: `bin/merge_coverage`
27+
- Run Rails integration tests: `scripts/rails_tests.sh`
28+
- Merge coverage reports: `scripts/merge_coverage.sh`
2729
- Run Next.js TypeScript tests: `cd site && npm test`
2830

2931
### Quality Commands
3032

31-
- Ruby typecheck: `bin/typecheck`
32-
- Next.js typecheck: `cd site && npx tsc --noEmit`
33-
- Lint Ruby: `bin/rubocop`
34-
- Format Ruby: `bin/rubocop -A`
35-
- Format JS/TS/JSON: `bin/prettier --write`
36-
- Lint JS/TS/JSON: `bin/prettier --check`
37-
- Spellcheck: `bin/spellcheck`
33+
- Ruby typecheck: `scripts/typecheck.sh`
34+
- Next.js typecheck: `cd site && pnpm exec tsc --noEmit`
35+
- Lint Ruby: `scripts/rubocop.rb`
36+
- Format Ruby: `scripts/rubocop.rb -A`
37+
- Format JS/TS/JSON: `scripts/prettier.sh --write`
38+
- Lint JS/TS/JSON: `scripts/prettier.sh --check`
39+
- Spellcheck: `scripts/spellcheck.sh`
3840

3941
### Development Commands
4042

41-
- Generate Sorbet RBI files: `bin/tapioca`
42-
- Generate spellcheck dictionary: `bin/generate_lockfile_words`
43-
- Generate TypeScript types from Ruby log structs: `ruby scripts/export_typescript_types.rb`
43+
- Generate Sorbet RBI files: `scripts/tapioca.rb`
44+
- Generate spellcheck dictionary: `scripts/generate_lockfile_words.sh`
45+
- Generate TypeScript types from Ruby log structs: `scripts/export_typescript_types.rb`
4446

4547
# Core Dependencies
4648

DEVELOPMENT.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ And you always need to check for any third-party gems that are not part of Rails
107107
- Follow test-driven development principles
108108
- Write tests for all new features
109109
- Ensure all tests pass before submitting a pull request
110-
- Regular tests: `bin/test`
111-
- Rails integration tests: `bin/test_with_rails`
112-
- You can specify Rails version for integration tests: `RAILS_VERSION=7.1.3 bin/test_with_rails`
110+
- Regular tests: `scripts/test.rb`
111+
- Rails integration tests: `scripts/rails_tests.sh`
112+
- You can specify Rails version for integration tests: `RAILS_VERSION=7.1.3 scripts/rails_tests.sh`
113113

114114
## Working with Sorbet and Tapioca
115115

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Dir.glob("tasks/*.rake").each { |r| load r }
1919
# Rails application integration tests
2020
desc "Run Rails integration tests"
2121
task :rails_tests do
22-
script_path = File.expand_path("bin/rails_tests", __dir__)
22+
script_path = File.expand_path("scripts/rails_tests.sh", __dir__)
2323
system(script_path) || abort("Rails tests failed")
2424
end
2525

bin/bundle

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
#
5+
# This file was generated by Bundler.
6+
#
7+
# The application 'bundle' is installed as part of a gem, and
8+
# this file is here to facilitate running it.
9+
#
10+
11+
require "rubygems"
12+
13+
m = Module.new do
14+
module_function
15+
16+
def invoked_as_script?
17+
File.expand_path($0) == File.expand_path(__FILE__)
18+
end
19+
20+
def env_var_version
21+
ENV["BUNDLER_VERSION"]
22+
end
23+
24+
def cli_arg_version
25+
return unless invoked_as_script? # don't want to hijack other binstubs
26+
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27+
bundler_version = nil
28+
update_index = nil
29+
ARGV.each_with_index do |a, i|
30+
if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
31+
bundler_version = a
32+
end
33+
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34+
bundler_version = $1
35+
update_index = i
36+
end
37+
bundler_version
38+
end
39+
40+
def gemfile
41+
gemfile = ENV["BUNDLE_GEMFILE"]
42+
return gemfile if gemfile && !gemfile.empty?
43+
44+
File.expand_path("../Gemfile", __dir__)
45+
end
46+
47+
def lockfile
48+
lockfile =
49+
case File.basename(gemfile)
50+
when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51+
else "#{gemfile}.lock"
52+
end
53+
File.expand_path(lockfile)
54+
end
55+
56+
def lockfile_version
57+
return unless File.file?(lockfile)
58+
lockfile_contents = File.read(lockfile)
59+
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60+
Regexp.last_match(1)
61+
end
62+
63+
def bundler_requirement
64+
@bundler_requirement ||=
65+
env_var_version ||
66+
cli_arg_version ||
67+
bundler_requirement_for(lockfile_version)
68+
end
69+
70+
def bundler_requirement_for(version)
71+
return "#{Gem::Requirement.default}.a" unless version
72+
73+
bundler_gem_version = Gem::Version.new(version)
74+
75+
bundler_gem_version.approximate_recommendation
76+
end
77+
78+
def load_bundler!
79+
ENV["BUNDLE_GEMFILE"] ||= gemfile
80+
81+
activate_bundler
82+
end
83+
84+
def activate_bundler
85+
gem_error = activation_error_handling do
86+
gem "bundler", bundler_requirement
87+
end
88+
return if gem_error.nil?
89+
require_error = activation_error_handling do
90+
require "bundler/version"
91+
end
92+
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93+
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94+
exit 42
95+
end
96+
97+
def activation_error_handling
98+
yield
99+
nil
100+
rescue StandardError, LoadError => e
101+
e
102+
end
103+
end
104+
105+
m.load_bundler!
106+
107+
if m.invoked_as_script?
108+
load Gem.bin_path("bundler", "bundle")
109+
end

bin/rails

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
#
5+
# This file was generated by Bundler.
6+
#
7+
# The application 'rails' is installed as part of a gem, and
8+
# this file is here to facilitate running it.
9+
#
10+
11+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12+
13+
bundle_binstub = File.expand_path("bundle", __dir__)
14+
15+
if File.file?(bundle_binstub)
16+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17+
load(bundle_binstub)
18+
else
19+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21+
end
22+
end
23+
24+
require "rubygems"
25+
require "bundler/setup"
26+
27+
load Gem.bin_path("railties", "rails")

0 commit comments

Comments
 (0)