Module: Bundler::Spinel::Scaffold
- Defined in:
- lib/bundler/spinel/engine_installer.rb
Overview
Scaffolds a minimal Spinel project so onboarding is ‘bundle install && spinel-compat init && bin/build` (spinelgems#9, stretch). Writes a Gemfile with the engine marker + a framework gem, a hello entrypoint, and a bin/build that provisions the engine, vendors deps, and compiles.
Class Method Summary collapse
- .app_rb ⇒ Object
- .build_sh ⇒ Object
- .gemfile ⇒ Object
- .gitignore ⇒ Object
- .init(dir, out: $stdout, rev: nil) ⇒ Object
- .write(out, path, body) ⇒ Object
Class Method Details
.app_rb ⇒ Object
212 213 214 215 216 217 218 219 220 |
# File 'lib/bundler/spinel/engine_installer.rb', line 212 def app_rb <<~RUBY require "tep" get "/" do "hello from a Spinel-compiled Tep app\\n" end RUBY end |
.build_sh ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/bundler/spinel/engine_installer.rb', line 222 def build_sh <<~SH #!/usr/bin/env bash # From a fresh checkout to a native binary. The Gemfile's `engine: spinel` # marker makes `bundle install` refuse to run under CRuby, so we resolve # with `bundle lock` and place deps with `spinel-compat vendor` instead. set -e command -v tep >/dev/null 2>&1 || gem install tep # the tep build CLI (a compile-time tool) [ -f Gemfile.lock ] || bundle lock # resolve deps (NOT `bundle install`) spinel-compat install-engine # fetch+build the pinned engine (cached) export SPINEL="${SPINEL:-$HOME/.cache/spinel/current/spinel}" # tell tep where the engine is spinel-compat vendor # place deps where Spinel follows them tep build app.rb -o app # compile -> ./app echo "built ./app — run it with: ./app -p 4567" SH end |
.gemfile ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/bundler/spinel/engine_installer.rb', line 195 def gemfile <<~RUBY source "https://rubygems.org" # Spinel is the engine: code here is compiled ahead-of-time to a native # binary, not run on CRuby. `engine_version` is advisory and must be a # version literal (bundler parses it as a Gem requirement); the actual # engine revision install-engine builds is pinned in ./SPINEL_PIN. ruby "3.3.0", engine: "spinel", engine_version: "0.0.0" # The web framework — Sinatra-style, compiles via Spinel. >= 0.11.1 builds # its C helpers on demand (needed for `gem install tep` without `make`). # (For an unreleased sibling instead: gem "tep", git: "https://github.com/OriPekelman/tep.git") gem "tep", ">= 0.11.1" RUBY end |
.gitignore ⇒ Object
239 240 241 242 243 244 245 246 |
# File 'lib/bundler/spinel/engine_installer.rb', line 239 def gitignore <<~TXT /app /vendor *.o *.bin TXT end |
.init(dir, out: $stdout, rev: nil) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/bundler/spinel/engine_installer.rb', line 160 def init(dir, out: $stdout, rev: nil) FileUtils.mkdir_p(dir) engine_rev = rev || EngineInstaller::DEFAULT_REV write(out, File.join(dir, "Gemfile"), gemfile) # The engine revision is a git SHA — NOT a valid `engine_version:` (bundler # parses that as a Gem version requirement and `bundle lock` errors on a # SHA). So the rev lives in a SPINEL_PIN file, which `install-engine` # reads; the Gemfile keeps a version-literal advisory marker. write(out, File.join(dir, "SPINEL_PIN"), "#{engine_rev}\n") write(out, File.join(dir, "app.rb"), app_rb) bin = File.join(dir, "bin", "build") FileUtils.mkdir_p(File.dirname(bin)) write(out, bin, build_sh) File.chmod(0o755, bin) write(out, File.join(dir, ".gitignore"), gitignore) out.puts "" out.puts "Scaffolded a Spinel + Tep project in #{dir}/" out.puts "Next:" out.puts " cd #{dir}" unless File.(dir) == Dir.pwd out.puts " ./bin/build # ensures tep, resolves + vendors deps, provisions Spinel, compiles" out.puts " ./app -p 4567 # run the native binary" out.puts "" out.puts "(The `engine: spinel` Gemfile marker makes `bundle install` refuse to run" out.puts " under CRuby by design — bin/build uses `bundle lock` + `spinel-compat vendor`.)" end |
.write(out, path, body) ⇒ Object
186 187 188 189 190 191 192 193 |
# File 'lib/bundler/spinel/engine_installer.rb', line 186 def write(out, path, body) if File.exist?(path) out.puts " skip (exists): #{path}" else File.write(path, body) out.puts " create: #{path}" end end |