rails-worktrees 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.release-please-manifest.json +1 -0
- data/CHANGELOG.md +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +160 -0
- data/Rakefile +27 -0
- data/exe/wt +9 -0
- data/lefthook.yml +5 -0
- data/lib/generators/rails/worktrees/install_generator.rb +137 -0
- data/lib/generators/rails/worktrees/mise_follow_up.rb +37 -0
- data/lib/generators/rails/worktrees/templates/Procfile.dev.worktree.example.tt +4 -0
- data/lib/generators/rails/worktrees/templates/bin/wt +7 -0
- data/lib/generators/rails/worktrees/templates/rails_worktrees.rb.tt +21 -0
- data/lib/rails/worktrees/cli.rb +30 -0
- data/lib/rails/worktrees/command/environment_support.rb +47 -0
- data/lib/rails/worktrees/command/git_operations.rb +144 -0
- data/lib/rails/worktrees/command/name_picking.rb +156 -0
- data/lib/rails/worktrees/command/output.rb +131 -0
- data/lib/rails/worktrees/command/workspace_paths.rb +60 -0
- data/lib/rails/worktrees/command.rb +151 -0
- data/lib/rails/worktrees/configuration.rb +45 -0
- data/lib/rails/worktrees/database_config_updater.rb +129 -0
- data/lib/rails/worktrees/env_bootstrapper.rb +153 -0
- data/lib/rails/worktrees/names/cities.txt +96 -0
- data/lib/rails/worktrees/railtie.rb +8 -0
- data/lib/rails/worktrees/version.rb +7 -0
- data/lib/rails/worktrees.rb +32 -0
- data/mise.toml +5 -0
- data/release-please-config.json +12 -0
- data/sig/rails/worktrees.rbs +23 -0
- metadata +98 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fc7ddb67fbc5fde18c04ab164229207c6f54284dc4bb5c1fb955f40544706cbb
|
|
4
|
+
data.tar.gz: a4005286b6c1dbad990d94ca3999b1490f2532c981fa8e5a7fb9b5768e4f30d6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8eef6c43ad39e5fc38c3dbdc10fc2618fc07f0ccd65c5c25bef94ae3991aeff143687ee45a37983846cc7ec8fc4c031d39b2b4cd6abcdd37d31243bb705a24a0
|
|
7
|
+
data.tar.gz: dfdeeb6c73a81e8c3c8147883b5ca752b79ff4a63e318db409792c6723c4fd84ae3f9effc93edc1d456f74fa22f326e954ac7239d044a27709436d1e462810b6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{".":"0.1.0"}
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-03-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add wt command and rails installer ([5d798d5](https://github.com/asjer/rails-worktrees/commit/5d798d5129585331780f0259b39061194feb66e3))
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
- Add a gem-managed `wt` CLI for creating Rails worktrees.
|
|
13
|
+
- Add a Rails installer generator that creates `bin/wt` and `config/initializers/rails_worktrees.rb`.
|
|
14
|
+
- Add conservative `config/database.yml` patching for common development/test database names.
|
|
15
|
+
- Add a manual-dispatch GitHub Actions workflow for the disposable Rails smoke test.
|
|
16
|
+
- Add smoke-test workflow debug controls for retained artifacts and verbose output.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Asjer Querido
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Rails::Worktrees
|
|
2
|
+
|
|
3
|
+
`rails-worktrees` adds a Rails-friendly `bin/wt` command for creating Git worktrees with isolated development and test databases.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Ruby >= 3.2.0
|
|
8
|
+
- Rails >= 7.1, < 8.2
|
|
9
|
+
- Git
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bundle add rails-worktrees
|
|
15
|
+
bin/rails generate rails:worktrees:install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The installer adds:
|
|
19
|
+
|
|
20
|
+
- `bin/wt` — a thin wrapper that executes the gem-owned CLI
|
|
21
|
+
- `config/initializers/rails_worktrees.rb` — optional configuration
|
|
22
|
+
- `Procfile.dev.worktree.example` — a copy-paste helper for `${DEV_PORT:-3000}` in `Procfile.dev`
|
|
23
|
+
- a safe update to `config/database.yml` for common development/test database names
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bin/wt # auto-pick a name from bundled *.txt lists
|
|
29
|
+
bin/wt my-feature # use an explicit worktree name
|
|
30
|
+
bin/wt --dry-run my-feature # preview the full setup without changing anything
|
|
31
|
+
bin/wt --print-env my-feature # preview DEV_PORT and WORKTREE_DATABASE_SUFFIX
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Options
|
|
35
|
+
|
|
36
|
+
| Flag | Description |
|
|
37
|
+
|------|-------------|
|
|
38
|
+
| `-h`, `--help` | Show the help message |
|
|
39
|
+
| `-v`, `--version` | Show the script version |
|
|
40
|
+
| `--dry-run [name]` | Preview the full worktree setup without changing anything |
|
|
41
|
+
| `--env`, `--print-env <name>` | Preview `DEV_PORT` and `WORKTREE_DATABASE_SUFFIX` |
|
|
42
|
+
|
|
43
|
+
### Default behavior
|
|
44
|
+
|
|
45
|
+
By default `bin/wt`:
|
|
46
|
+
|
|
47
|
+
- creates a sibling directory next to your app: `workspace/my-project.worktrees/<name>`
|
|
48
|
+
- uses a branch named `🚂/<name>`
|
|
49
|
+
- creates new branches from `origin`'s default branch
|
|
50
|
+
- auto-picks names from bundled `.txt` files when no explicit name is given
|
|
51
|
+
- retires bundled names so they are not picked twice
|
|
52
|
+
- bootstraps a worktree-local `.env` with deterministic `DEV_PORT` and `WORKTREE_DATABASE_SUFFIX` values
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
workspace/
|
|
56
|
+
├── my-project/
|
|
57
|
+
└── my-project.worktrees/
|
|
58
|
+
├── feature-auth/
|
|
59
|
+
├── bugfix-123/
|
|
60
|
+
└── experiment/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`WT_WORKSPACES_ROOT` or `config.workspace_root` overrides the destination root and uses the layout `<root>/<project>/<name>`.
|
|
64
|
+
|
|
65
|
+
### Interactive prompts
|
|
66
|
+
|
|
67
|
+
`bin/wt` handles several edge cases interactively:
|
|
68
|
+
|
|
69
|
+
- **Branch already exists locally** — asks whether to attach a new worktree to it
|
|
70
|
+
- **Branch already exists on origin** — asks whether to create a local tracking worktree
|
|
71
|
+
- **Target directory already exists with matching branch** — asks whether to reuse it
|
|
72
|
+
- **Target directory already exists with a different branch** — asks whether to remove and recreate it
|
|
73
|
+
- **Retired bundled name used explicitly** — rejects it and suggests running `wt` with no argument
|
|
74
|
+
|
|
75
|
+
### Name validation
|
|
76
|
+
|
|
77
|
+
Worktree names must not contain `/` or whitespace, must not be `.` or `..`, and must be a valid Git ref component.
|
|
78
|
+
|
|
79
|
+
### Configuration
|
|
80
|
+
|
|
81
|
+
The installer generates `config/initializers/rails_worktrees.rb` where you can override:
|
|
82
|
+
|
|
83
|
+
| Option | Default | Description |
|
|
84
|
+
|--------|---------|-------------|
|
|
85
|
+
| `bootstrap_env` | `true` | Write `.env` when creating a worktree |
|
|
86
|
+
| `workspace_root` | `nil` | Override the destination root (sibling layout when `nil`) |
|
|
87
|
+
| `dev_port_range` | `3000..3999` | Port range for deterministic `DEV_PORT` allocation |
|
|
88
|
+
| `branch_prefix` | `🚂` | Prefix for worktree branch names |
|
|
89
|
+
| `name_sources_path` | bundled `names/` | Directory containing `.txt` name lists |
|
|
90
|
+
| `used_names_file` | `~/.local/state/rails-worktrees/used-names.tsv` | TSV tracking retired names |
|
|
91
|
+
| `worktree_database_suffix_max_length` | `18` | Max length for generated database suffixes |
|
|
92
|
+
|
|
93
|
+
### Database naming
|
|
94
|
+
|
|
95
|
+
The installer adds `WORKTREE_DATABASE_SUFFIX` to common `development` and `test` database names in `config/database.yml`. For a multi-database app, the target shape is:
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
development:
|
|
99
|
+
primary:
|
|
100
|
+
database: my_app_development<%= ENV.fetch('WORKTREE_DATABASE_SUFFIX', '') %>_primary
|
|
101
|
+
|
|
102
|
+
test:
|
|
103
|
+
primary:
|
|
104
|
+
database: my_app_test<%= ENV.fetch('WORKTREE_DATABASE_SUFFIX', '') %>_primary
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
If your `database.yml` is too custom to patch safely, the installer leaves it alone and tells you what to update manually.
|
|
108
|
+
|
|
109
|
+
### Environment bootstrap
|
|
110
|
+
|
|
111
|
+
When `bin/wt` creates a worktree it writes a worktree-local `.env` with:
|
|
112
|
+
|
|
113
|
+
- `DEV_PORT` — deterministic port derived from the worktree name via CRC32, rotated through `dev_port_range`, skipping ports already claimed by peer worktrees
|
|
114
|
+
- `WORKTREE_DATABASE_SUFFIX` — derived from the worktree name so the `database.yml` ERB works immediately
|
|
115
|
+
|
|
116
|
+
Existing `.env` values are never overwritten.
|
|
117
|
+
|
|
118
|
+
The gem does **not** edit your `Procfile.dev` or add dotenv. The installer generates `Procfile.dev.worktree.example` with a ready-to-copy line:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p ${DEV_PORT:-3000}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Use a project-local env loader like `mise` with `_.file = ".env"` to keep values scoped per-worktree.
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
129
|
+
|
|
130
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
131
|
+
|
|
132
|
+
### Smoke testing
|
|
133
|
+
|
|
134
|
+
RSpec remains the main automated test suite. For installer and integration changes, you can also run a disposable Rails app smoke test:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
bundle exec rake smoke_test
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This smoke test:
|
|
141
|
+
|
|
142
|
+
- creates a temporary Rails app from a compatible Rails version
|
|
143
|
+
- installs `rails-worktrees` from the current checkout path
|
|
144
|
+
- runs `bin/rails generate rails:worktrees:install`
|
|
145
|
+
- verifies `bin/wt`, the generated initializer, the Procfile example, `config/database.yml` patching, and worktree `.env` bootstrapping
|
|
146
|
+
- creates a temporary bare `origin` and confirms `bin/wt smoke-branch` creates a real worktree
|
|
147
|
+
|
|
148
|
+
By default, the script cleans up all temp directories after the run. Set `KEEP_SMOKE_TEST_ARTIFACTS=1` to keep them around for debugging, or set `RAILS_WORKTREES_SMOKE_RAILS_VERSION` to try a different compatible Rails version.
|
|
149
|
+
|
|
150
|
+
There is also a manually triggered GitHub Actions workflow named `Smoke Test` for running the same disposable-app verification in CI without slowing down the default pull request checks.
|
|
151
|
+
|
|
152
|
+
The workflow accepts optional `ruby_version`, `rails_version`, `keep_artifacts`, and `verbose` inputs. Enable `keep_artifacts` when you want the disposable app, bare origin, and worktree directories uploaded from CI for debugging, and enable `verbose` when you want shell tracing in the smoke-test log.
|
|
153
|
+
|
|
154
|
+
## Contributing
|
|
155
|
+
|
|
156
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/asjer/rails-worktrees.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
+
|
|
8
|
+
require 'rubocop/rake_task'
|
|
9
|
+
|
|
10
|
+
RuboCop::RakeTask.new
|
|
11
|
+
|
|
12
|
+
namespace :smoke do
|
|
13
|
+
desc 'Run the disposable Rails app smoke test'
|
|
14
|
+
task :test do
|
|
15
|
+
script = File.expand_path('spec/integration/smoke_test.sh', __dir__)
|
|
16
|
+
|
|
17
|
+
Bundler.with_unbundled_env do
|
|
18
|
+
success = system(script)
|
|
19
|
+
abort('Smoke test failed') unless success
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc 'Run the disposable Rails app smoke test'
|
|
25
|
+
task smoke_test: 'smoke:test'
|
|
26
|
+
|
|
27
|
+
task default: %i[spec rubocop]
|
data/exe/wt
ADDED
data/lefthook.yml
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
require 'rails/generators'
|
|
5
|
+
require_relative 'mise_follow_up'
|
|
6
|
+
require_relative '../../../rails/worktrees/database_config_updater'
|
|
7
|
+
|
|
8
|
+
module Rails
|
|
9
|
+
module Worktrees
|
|
10
|
+
module Generators
|
|
11
|
+
# Installs the wt wrapper, configuration, and safe database.yml updates.
|
|
12
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
13
|
+
include MiseFollowUp
|
|
14
|
+
|
|
15
|
+
namespace 'rails:worktrees:install'
|
|
16
|
+
desc 'Installs bin/wt, a Rails::Worktrees initializer, and updates config/database.yml when safe.'
|
|
17
|
+
source_root File.expand_path('templates', __dir__)
|
|
18
|
+
class_option :conductor, type: :boolean, default: false,
|
|
19
|
+
desc: 'Configure the installer for ~/Sites/conductor/workspaces'
|
|
20
|
+
|
|
21
|
+
FOLLOW_UP_TEMPLATE = <<~TEXT
|
|
22
|
+
============================================
|
|
23
|
+
rails-worktrees installed successfully! 🚂
|
|
24
|
+
|
|
25
|
+
Installed:
|
|
26
|
+
%<installed>s
|
|
27
|
+
|
|
28
|
+
Get started:
|
|
29
|
+
$ bin/wt
|
|
30
|
+
$ bin/wt my-feature
|
|
31
|
+
|
|
32
|
+
Configure:
|
|
33
|
+
config/initializers/rails_worktrees.rb
|
|
34
|
+
%<notes>s
|
|
35
|
+
============================================
|
|
36
|
+
TEXT
|
|
37
|
+
|
|
38
|
+
def create_bin_wrapper
|
|
39
|
+
template('bin/wt', 'bin/wt')
|
|
40
|
+
chmod('bin/wt', 0o755)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def create_initializer
|
|
44
|
+
template('rails_worktrees.rb.tt', 'config/initializers/rails_worktrees.rb')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_procfile_worktree_example
|
|
48
|
+
template('Procfile.dev.worktree.example.tt', 'Procfile.dev.worktree.example')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def update_database_configuration
|
|
52
|
+
unless File.exist?(database_config_path)
|
|
53
|
+
say_status(:skip, 'config/database.yml not found', :yellow)
|
|
54
|
+
@database_outcome = :not_found
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
result = database_update_result
|
|
59
|
+
@database_outcome = result.changed? ? :updated : :identical
|
|
60
|
+
announce_database_update(result)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def verify_installation
|
|
64
|
+
if git_repo?
|
|
65
|
+
say_status(:ok, 'git repository detected', :green)
|
|
66
|
+
else
|
|
67
|
+
say_status(:warning, 'run inside a git repository for bin/wt to work', :yellow)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def show_follow_up
|
|
72
|
+
say(follow_up_message)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def database_config_path
|
|
78
|
+
File.join(destination_root, 'config/database.yml')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def database_update_result
|
|
82
|
+
result = ::Rails::Worktrees::DatabaseConfigUpdater.new(
|
|
83
|
+
content: File.read(database_config_path)
|
|
84
|
+
).call
|
|
85
|
+
|
|
86
|
+
File.write(database_config_path, result.content) if result.changed?
|
|
87
|
+
|
|
88
|
+
result
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def follow_up_message
|
|
92
|
+
"\n#{format(FOLLOW_UP_TEMPLATE, installed: installed_items_text, notes: follow_up_notes_text)}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def installed_items_text
|
|
96
|
+
items = [
|
|
97
|
+
' • bin/wt',
|
|
98
|
+
' • config/initializers/rails_worktrees.rb',
|
|
99
|
+
' • Procfile.dev.worktree.example'
|
|
100
|
+
]
|
|
101
|
+
items << database_follow_up_line if database_follow_up_line
|
|
102
|
+
items.join("\n")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def database_follow_up_line
|
|
106
|
+
case @database_outcome
|
|
107
|
+
when :updated
|
|
108
|
+
' • config/database.yml (updated with WORKTREE_DATABASE_SUFFIX)'
|
|
109
|
+
when :not_found
|
|
110
|
+
' • config/database.yml was not found — see README for manual setup'
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def announce_database_update(result)
|
|
115
|
+
status = result.changed? ? :update : :identical
|
|
116
|
+
color = result.changed? ? :green : :blue
|
|
117
|
+
|
|
118
|
+
say_status(status, 'config/database.yml', color)
|
|
119
|
+
result.messages.each { |message| say(message) }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def git_repo?
|
|
123
|
+
_stdout_str, _stderr_str, status = Open3.capture3(
|
|
124
|
+
'git', 'rev-parse', '--is-inside-work-tree', chdir: destination_root
|
|
125
|
+
)
|
|
126
|
+
status.success?
|
|
127
|
+
rescue Errno::ENOENT
|
|
128
|
+
false
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def conductor_workspace_root
|
|
132
|
+
"File.expand_path('~/Sites/conductor/workspaces')"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Worktrees
|
|
5
|
+
module Generators
|
|
6
|
+
# Detects common mise.toml setups and suggests loading the worktree-local .env.
|
|
7
|
+
module MiseFollowUp
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def follow_up_notes_text
|
|
11
|
+
return '' unless suggest_mise_env_file?
|
|
12
|
+
|
|
13
|
+
[
|
|
14
|
+
'',
|
|
15
|
+
' Tip:',
|
|
16
|
+
' Detected mise.toml. To auto-load the worktree-local .env when you enter a worktree,',
|
|
17
|
+
' consider adding:',
|
|
18
|
+
' [env]',
|
|
19
|
+
' _.file = ".env"'
|
|
20
|
+
].join("\n")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def suggest_mise_env_file?
|
|
24
|
+
File.file?(mise_toml_path) && !mise_env_file_configured?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def mise_env_file_configured?
|
|
28
|
+
File.read(mise_toml_path).match?(/^\s*_.file\s*=\s*["']\.env["']\s*$/)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def mise_toml_path
|
|
32
|
+
File.join(destination_root, 'mise.toml')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Example Procfile.dev entry for worktree-aware DEV_PORT usage.
|
|
2
|
+
# Copy the web line into your Procfile.dev if you want bin/dev, Foreman, or Overmind
|
|
3
|
+
# to respect the worktree-local DEV_PORT that bin/wt writes into .env.
|
|
4
|
+
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p ${DEV_PORT:-3000}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Rails::Worktrees.configure do |config|
|
|
4
|
+
<% if options['conductor'] -%>
|
|
5
|
+
config.workspace_root = <%= conductor_workspace_root %>
|
|
6
|
+
<% else -%>
|
|
7
|
+
# By default, worktrees go in a sibling "<project>.worktrees" directory.
|
|
8
|
+
# Uncomment to override with a custom parent directory that uses <root>/<project>/<name>.
|
|
9
|
+
# config.workspace_root = File.expand_path('~/worktrees')
|
|
10
|
+
<% end -%>
|
|
11
|
+
# config.bootstrap_env = false
|
|
12
|
+
# config.dev_port_range = 3000..3999
|
|
13
|
+
# config.worktree_database_suffix_max_length = 18
|
|
14
|
+
# config.branch_prefix = '🚂'
|
|
15
|
+
# config.name_sources_path = Rails.root.join('config/worktree_names').to_s
|
|
16
|
+
# config.used_names_file = File.join(
|
|
17
|
+
# ENV.fetch('XDG_STATE_HOME', File.expand_path('~/.local/state')),
|
|
18
|
+
# 'rails-worktrees',
|
|
19
|
+
# 'used-names.tsv'
|
|
20
|
+
# )
|
|
21
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Worktrees
|
|
5
|
+
# Shell entrypoint for the wt executable.
|
|
6
|
+
class CLI
|
|
7
|
+
def initialize(
|
|
8
|
+
argv: ARGV,
|
|
9
|
+
io: { stdin: $stdin, stdout: $stdout, stderr: $stderr },
|
|
10
|
+
env: ENV,
|
|
11
|
+
cwd: Dir.pwd
|
|
12
|
+
)
|
|
13
|
+
@argv = argv
|
|
14
|
+
@io = io
|
|
15
|
+
@env = env
|
|
16
|
+
@cwd = cwd
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def start
|
|
20
|
+
Command.new(
|
|
21
|
+
argv: @argv,
|
|
22
|
+
io: @io,
|
|
23
|
+
env: @env,
|
|
24
|
+
cwd: @cwd,
|
|
25
|
+
configuration: ::Rails::Worktrees.configuration
|
|
26
|
+
).run
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Worktrees
|
|
5
|
+
class Command
|
|
6
|
+
# Env bootstrap helpers and preview output.
|
|
7
|
+
module EnvironmentSupport
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def preview_worktree_environment_command
|
|
11
|
+
raise Error, 'Usage: wt --print-env <worktree-name>' unless @argv.length == 2
|
|
12
|
+
|
|
13
|
+
require_git_repo
|
|
14
|
+
context = resolve_worktree_context(explicit_worktree_name: @argv[1])
|
|
15
|
+
result = env_bootstrapper_for(context).preview
|
|
16
|
+
|
|
17
|
+
print_env_preview(result.values)
|
|
18
|
+
0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def env_bootstrapper_for(context)
|
|
22
|
+
EnvBootstrapper.new(
|
|
23
|
+
target_dir: context[:target_dir],
|
|
24
|
+
worktree_name: context[:worktree_name],
|
|
25
|
+
configuration: @configuration
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def bootstrap_worktree_environment(context)
|
|
30
|
+
result = env_bootstrapper_for(context).call(dry_run: dry_run?)
|
|
31
|
+
|
|
32
|
+
result.messages.each { |message| info(message) }
|
|
33
|
+
result
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
warning("Could not bootstrap #{context[:target_dir]}/.env: #{e.message}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def preview_worktree_environment(context)
|
|
39
|
+
env_bootstrapper_for(context).preview
|
|
40
|
+
rescue StandardError => e
|
|
41
|
+
warning("Could not inspect #{context[:target_dir]}/.env: #{e.message}")
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|