Skip to content

Commit 8095cb1

Browse files
committed
Remove Bootsnap cache priming support
The `--only-bootsnap-rbs-cache` flag and read-only cache path supported sharing a primed cache between CI jobs. That workflow is no longer used. Keep the cache local and writable. Normal `tapioca dsl` runs populate it, and lockfile changes reset the cached iseq payload.
1 parent 53c987f commit 8095cb1

6 files changed

Lines changed: 47 additions & 203 deletions

File tree

README.md

Lines changed: 29 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ Tapioca makes it easy to work with [Sorbet](https://sorbet.org) in your codebase
5252
* [Writing custom DSL extensions](#writing-custom-dsl-extensions)
5353
* [Rewriting RBS comments to Sorbet signatures](#rewriting-rbs-comments-to-sorbet-signatures)
5454
* [Caching rewrites with Bootsnap](#caching-rewrites-with-bootsnap)
55-
* [Priming the cache from CI](#priming-the-cache-from-ci)
5655
* [RBI files for missing constants and methods](#rbi-files-for-missing-constants-and-methods)
5756
* [Configuration](#configuration)
5857
* [Editor Integration](#editor-integration)
@@ -492,37 +491,35 @@ Usage:
492491
tapioca dsl [constant...]
493492
494493
Options:
495-
--out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
496-
# Default: sorbet/rbi/dsl
497-
[--file-header], [--no-file-header], [--skip-file-header] # Add a "This file is generated" header on top of each generated RBI file
498-
# Default: true
499-
[--only=compiler [compiler ...]] # Only run supplied DSL compiler(s)
500-
[--exclude=compiler [compiler ...]] # Exclude supplied DSL compiler(s)
501-
[--verify], [--no-verify], [--skip-verify] # Verifies RBIs are up-to-date
502-
# Default: false
503-
[--only-bootsnap-rbs-cache], [--no-only-bootsnap-rbs-cache], [--skip-only-bootsnap-rbs-cache] # Only boot the application and load DSL extensions/compilers to populate the bootsnap iseq cache, then exit. Skips compiler execution and RBI generation. Mutually exclusive with --verify and --list-compilers.
504-
# Default: false
505-
-q, [--quiet], [--no-quiet], [--skip-quiet] # Suppresses file creation output
506-
# Default: false
507-
-w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: auto)
508-
[--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
509-
# Default: 120
510-
[--max-diff-lines=N] # Max number of diff lines to include in the `dsl --verify` output
511-
# Default: 250
512-
-e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
513-
# Default: development
514-
-l, [--list-compilers], [--no-list-compilers], [--skip-list-compilers] # List all loaded compilers
515-
# Default: false
516-
[--app-root=APP_ROOT] # The path to the Rails application
517-
# Default: .
518-
[--halt-upon-load-error], [--no-halt-upon-load-error], [--skip-halt-upon-load-error] # Halt upon a load error while loading the Rails application
519-
# Default: true
520-
[--skip-constant=constant [constant ...]] # Do not generate RBI definitions for the given application constant(s)
521-
[--compiler-options=key:value] # Options to pass to the DSL compilers
522-
-c, [--config=<config file path>] # Path to the Tapioca configuration file
523-
# Default: sorbet/tapioca/config.yml
524-
-V, [--verbose], [--no-verbose], [--skip-verbose] # Verbose output for debugging purposes
525-
# Default: false
494+
--out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
495+
# Default: sorbet/rbi/dsl
496+
[--file-header], [--no-file-header], [--skip-file-header] # Add a "This file is generated" header on top of each generated RBI file
497+
# Default: true
498+
[--only=compiler [compiler ...]] # Only run supplied DSL compiler(s)
499+
[--exclude=compiler [compiler ...]] # Exclude supplied DSL compiler(s)
500+
[--verify], [--no-verify], [--skip-verify] # Verifies RBIs are up-to-date
501+
# Default: false
502+
-q, [--quiet], [--no-quiet], [--skip-quiet] # Suppresses file creation output
503+
# Default: false
504+
-w, [--workers=N] # Number of parallel workers to use when generating RBIs (default: auto)
505+
[--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
506+
# Default: 120
507+
[--max-diff-lines=N] # Max number of diff lines to include in the `dsl --verify` output
508+
# Default: 250
509+
-e, [--environment=ENVIRONMENT] # The Rack/Rails environment to use when generating RBIs
510+
# Default: development
511+
-l, [--list-compilers], [--no-list-compilers], [--skip-list-compilers] # List all loaded compilers
512+
# Default: false
513+
[--app-root=APP_ROOT] # The path to the Rails application
514+
# Default: .
515+
[--halt-upon-load-error], [--no-halt-upon-load-error], [--skip-halt-upon-load-error] # Halt upon a load error while loading the Rails application
516+
# Default: true
517+
[--skip-constant=constant [constant ...]] # Do not generate RBI definitions for the given application constant(s)
518+
[--compiler-options=key:value] # Options to pass to the DSL compilers
519+
-c, [--config=<config file path>] # Path to the Tapioca configuration file
520+
# Default: sorbet/tapioca/config.yml
521+
-V, [--verbose], [--no-verbose], [--skip-verbose] # Verbose output for debugging purposes
522+
# Default: false
526523
527524
Generate RBIs for dynamic methods
528525
```
@@ -865,29 +862,13 @@ lockfile changes, Tapioca sees the digest mismatch and resets Bootsnap's cache p
865862
This lets gem bumps that affect rewriting, such as `tapioca`, start from a fresh cache without accumulating old cache
866863
directories.
867864
868-
The first run is slower because every file is rewritten and the result is baked into the iseq cache; subsequent runs
869-
against the same lockfile skip the rewrite entirely.
870-
871865
`Bootsnap.setup` mutates a process-wide singleton, and a second call would overwrite Tapioca's dedicated cache directory and start writing rewritten iseqs into the host's normal cache. Tapioca enforces this under `TAPIOCA_RBS_CACHE=1`: after its own setup runs, any subsequent `Bootsnap.setup` raises a clear error pointing at the fix. Gate your host's `Bootsnap.setup` on the same env var. Rails apps do this in `config/boot.rb`:
872866
873867
```ruby
874868
# e.g. config/boot.rb
875869
require "bootsnap/setup" unless ENV["TAPIOCA_RBS_CACHE"] == "1"
876870
```
877871
878-
#### Priming the cache from CI
879-
880-
For CI pipelines that want to populate the cache once and have downstream jobs read from a warm copy, use `--only-bootsnap-rbs-cache`. This pattern lets you scope cache writes to a single job (the prime) so PR-side jobs read from it without uploading on every successful build:
881-
882-
```shell
883-
# Prime: populate the cache.
884-
$ TAPIOCA_RBS_CACHE=1 bin/tapioca dsl --only-bootsnap-rbs-cache
885-
886-
# Consumer: read from the populated cache.
887-
# BOOTSNAP_READONLY=1 prevents bootsnap from writing back to a read-only mount.
888-
$ TAPIOCA_RBS_CACHE=1 BOOTSNAP_READONLY=1 bin/tapioca dsl
889-
```
890-
891872
### RBI files for missing constants and methods
892873
893874
Even after generating the RBIs, it is possible that some constants or methods are still undefined for Sorbet.
@@ -1009,7 +990,6 @@ dsl:
1009990
only: []
1010991
exclude: []
1011992
verify: false
1012-
only_bootsnap_rbs_cache: false
1013993
quiet: false
1014994
workers: 1
1015995
rbi_max_line_length: 120

lib/tapioca/cli.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ def todo
103103
type: :boolean,
104104
default: false,
105105
desc: "Verifies RBIs are up-to-date"
106-
option :only_bootsnap_rbs_cache,
107-
type: :boolean,
108-
default: false,
109-
desc: "Only boot the application and load DSL extensions/compilers to populate the bootsnap iseq cache, then exit. Skips compiler execution and RBI generation. Mutually exclusive with --verify and --list-compilers."
110106
option :quiet,
111107
aliases: ["-q"],
112108
type: :boolean,
@@ -154,12 +150,6 @@ def todo
154150
def dsl(*constant_or_paths)
155151
set_environment(options)
156152

157-
if options[:only_bootsnap_rbs_cache] && (options[:verify] || options[:list_compilers])
158-
conflicting = options[:verify] ? "--verify" : "--list-compilers"
159-
raise MalformattedArgumentError,
160-
"Options '--only-bootsnap-rbs-cache' and '#{conflicting}' are mutually exclusive"
161-
end
162-
163153
# Assume anything starting with a capital letter or colon is a class, otherwise a path
164154
constants, paths = constant_or_paths.partition { |c| c =~ /\A[A-Z:]/ }
165155

@@ -192,7 +182,7 @@ def dsl(*constant_or_paths)
192182
elsif options[:list_compilers]
193183
Commands::DslCompilerList.new(**command_args)
194184
else
195-
Commands::DslGenerate.new(**command_args, only_bootsnap_rbs_cache: options[:only_bootsnap_rbs_cache])
185+
Commands::DslGenerate.new(**command_args)
196186
end
197187

198188
command.run

lib/tapioca/commands/dsl_generate.rb

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,13 @@
44
module Tapioca
55
module Commands
66
class DslGenerate < AbstractDsl
7-
#: (?only_bootsnap_rbs_cache: bool, **untyped) -> void
8-
def initialize(only_bootsnap_rbs_cache: false, **kwargs)
9-
@only_bootsnap_rbs_cache = only_bootsnap_rbs_cache
10-
super(**T.unsafe(kwargs))
11-
end
12-
137
private
148

159
# @override
1610
#: -> void
1711
def execute
1812
load_application
1913

20-
if @only_bootsnap_rbs_cache
21-
if ENV["TAPIOCA_RBS_CACHE"] == "1"
22-
say("Bootsnap RBS cache populated, exiting before RBI generation.", :green)
23-
else
24-
say_error("Warning: --only-bootsnap-rbs-cache requires TAPIOCA_RBS_CACHE=1 to populate the cache", :yellow)
25-
end
26-
return
27-
end
28-
2914
say("Compiling DSL RBI files...")
3015
say("")
3116

lib/tapioca/rbs/bootsnap_cache.rb

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,20 @@ module RBS
1313
# source files are unchanged.
1414
# To account for this, we store the current Gemfile.lock SHA256 in a
1515
# `.gemfile-lock-digest` file.
16-
# On writable runs, a digest mismatch deletes Bootsnap's cache payload and
17-
# records the new digest, so this run rebuilds the cache from scratch. On
18-
# read-only runs, a digest mismatch means the cache is stale and must not be
19-
# used.
16+
# A digest mismatch deletes Bootsnap's cache payload and records the new
17+
# digest, so this run rebuilds the cache from scratch.
2018
module BootsnapCache
21-
PrepareResult = Struct.new(:setup_bootsnap, keyword_init: true)
22-
2319
DIGEST_FILE = ".gemfile-lock-digest" #: String
2420

2521
class << self
26-
#: (String, readonly: bool) -> PrepareResult
27-
def prepare_for_setup(cache_dir, readonly:)
22+
#: (String) -> void
23+
def prepare_for_setup(cache_dir)
2824
digest = gemfile_lock_digest
25+
return if digest_matches?(cache_dir, digest)
2926

30-
if readonly
31-
return PrepareResult.new(setup_bootsnap: digest_matches?(cache_dir, digest))
32-
end
33-
34-
unless digest_matches?(cache_dir, digest)
35-
FileUtils.rm_rf(File.join(cache_dir, "bootsnap"))
36-
FileUtils.mkdir_p(cache_dir)
37-
File.write(digest_path(cache_dir), digest)
38-
end
39-
40-
PrepareResult.new(setup_bootsnap: true)
27+
FileUtils.rm_rf(File.join(cache_dir, "bootsnap"))
28+
FileUtils.mkdir_p(cache_dir)
29+
File.write(digest_path(cache_dir), digest)
4130
end
4231

4332
private

lib/tapioca/rbs/rewriter.rb

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,49 +32,40 @@ def setup(**_kwargs)
3232
end
3333
end
3434

35-
module BootsnapSetup
35+
module BootsnapIntegration
3636
class << self
3737
extend T::Sig
3838

3939
sig { void }
4040
def setup
4141
require "bootsnap"
4242

43-
# Respect BOOTSNAP_READONLY for consumers reading a pre-populated cache
44-
# (e.g. a CI prime step).
45-
readonly = !["0", "false", false].include?(ENV.fetch("BOOTSNAP_READONLY") { false })
4643
cache_dir = ENV.fetch("TAPIOCA_BOOTSNAP_CACHE_DIR", File.join(Dir.pwd, "tmp/cache/bootsnap-tapioca-rbs"))
47-
# A read-only cache with a mismatched lockfile digest may contain stale rewritten iseqs,
48-
# and this process cannot reset it.
49-
return unless Tapioca::RBS::BootsnapCache.prepare_for_setup(
50-
cache_dir,
51-
readonly: readonly,
52-
).setup_bootsnap
44+
Tapioca::RBS::BootsnapCache.prepare_for_setup(cache_dir)
5345

5446
Bootsnap.setup(
5547
cache_dir: cache_dir,
5648
development_mode: true,
5749
load_path_cache: true,
5850
compile_cache_iseq: true,
5951
compile_cache_yaml: true,
60-
readonly: readonly,
52+
readonly: false,
6153
revalidation: true,
6254
)
6355
Bootsnap.log_stats!
64-
ensure
65-
Bootsnap.singleton_class.prepend(Tapioca::RBS::BootsnapGuard) if defined?(Bootsnap)
56+
57+
Bootsnap.singleton_class.prepend(Tapioca::RBS::BootsnapGuard)
6658
end
6759
end
6860
end
6961
end
7062
end
7163

7264
# When TAPIOCA_RBS_CACHE=1, use a dedicated Bootsnap cache directory for
73-
# RBS-rewritten iseqs. Stale read-only caches are skipped because this process
74-
# cannot reset them.
65+
# RBS-rewritten iseqs.
7566
if ENV["TAPIOCA_RBS_CACHE"] == "1"
7667
begin
77-
Tapioca::RBS::BootsnapSetup.setup
68+
Tapioca::RBS::BootsnapIntegration.setup
7869
rescue LoadError
7970
# Bootsnap is not in the bundle, skip iseq caching.
8071
end

0 commit comments

Comments
 (0)