rails-worktrees 0.2.0 → 0.2.1
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 +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +7 -0
- data/README.md +8 -4
- data/lib/generators/rails/worktrees/puma_follow_up.rb +45 -0
- data/lib/generators/worktrees/install/install_generator.rb +25 -1
- data/lib/rails/worktrees/puma_config_updater.rb +91 -0
- data/lib/rails/worktrees/version.rb +1 -1
- data/lib/rails/worktrees.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 971ba5f8f872a37a91d2e8c1755bf838db8bf67a767dbfba1b105b727440d9b7
|
|
4
|
+
data.tar.gz: dd0441f61442afffc29b7ab5f70968abd0c35c59e2731247cc55ddeae6e18265
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e77b1961db51bcaca110efe1b8c9c6c96e848b523f30e158cc55c94550023fb85289b124ec859abd6957542ae0fcc4e20a63f793985b87ea5a03e2302b9748a
|
|
7
|
+
data.tar.gz: 5955435a25990d85b834e9c22d3c37d9621cab21a69dac6c6b9e038e763bc8346a8f6a23886f37098285cd6f055496417f85b34f8351e9f5b4d3e6115b429753
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{".":"0.2.
|
|
1
|
+
{".":"0.2.1"}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.1](https://github.com/asjer/rails-worktrees/compare/v0.2.0...v0.2.1) (2026-03-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **puma:** add missing `DEV_PORT` support to config/puma.rb ([3fd71a0](https://github.com/asjer/rails-worktrees/commit/3fd71a04d79732bed4cf626951abe06ddbc01153))
|
|
9
|
+
|
|
3
10
|
## [0.2.0](https://github.com/asjer/rails-worktrees/compare/v0.1.1...v0.2.0) (2026-03-30)
|
|
4
11
|
|
|
5
12
|
|
data/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
```bash
|
|
14
14
|
bundle add rails-worktrees
|
|
15
15
|
bin/rails generate worktrees:install
|
|
16
|
-
# or, to apply the common Procfile.dev + mise follow-ups automatically:
|
|
16
|
+
# or, to apply the common Procfile.dev + Puma + mise follow-ups automatically:
|
|
17
17
|
bin/rails generate worktrees:install --yolo
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -27,6 +27,7 @@ The installer adds:
|
|
|
27
27
|
With `--yolo`, the installer also:
|
|
28
28
|
|
|
29
29
|
- replaces the existing `web:` entry in `Procfile.dev` with the DEV_PORT-aware command when `Procfile.dev` already exists
|
|
30
|
+
- updates `config/puma.rb` to use `port ENV['DEV_PORT'] || ENV.fetch('PORT', 3000)` when it still uses a supported default `PORT` binding
|
|
30
31
|
- updates `mise.toml` or `.mise.toml` to load `.env` from `[env]` when either file already exists
|
|
31
32
|
|
|
32
33
|
## Usage
|
|
@@ -122,17 +123,20 @@ When `bin/wt` creates a worktree it writes a worktree-local `.env` with:
|
|
|
122
123
|
|
|
123
124
|
Existing `.env` values are never overwritten.
|
|
124
125
|
|
|
125
|
-
By default, the installer does **not** edit your `Procfile.dev` or `mise` config. It generates `Procfile.dev.worktree.example` with a ready-to-copy line:
|
|
126
|
+
By default, the installer does **not** edit your `Procfile.dev`, `config/puma.rb`, or `mise` config. It generates `Procfile.dev.worktree.example` with a ready-to-copy line:
|
|
126
127
|
|
|
127
128
|
```text
|
|
128
129
|
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p ${DEV_PORT:-3000}
|
|
129
130
|
```
|
|
130
131
|
|
|
131
|
-
If you run `bin/rails generate worktrees:install --yolo`, the installer applies the
|
|
132
|
+
If you run `bin/rails generate worktrees:install --yolo`, the installer applies the three common follow-ups for you when the files already exist:
|
|
132
133
|
|
|
133
134
|
- replace the existing `web:` entry in `Procfile.dev`
|
|
135
|
+
- update `config/puma.rb` to `port ENV['DEV_PORT'] || ENV.fetch('PORT', 3000)` when it still uses a supported default `PORT` binding
|
|
134
136
|
- add `_.file = ".env"` to the `[env]` section of `mise.toml` or `.mise.toml`
|
|
135
137
|
|
|
138
|
+
On a regular install, the follow-up message also suggests the same `config/puma.rb` edit when Puma still uses the default `PORT` binding.
|
|
139
|
+
|
|
136
140
|
Use a project-local env loader like `mise` with `_.file = ".env"` to keep values scoped per-worktree.
|
|
137
141
|
|
|
138
142
|
## Development
|
|
@@ -154,7 +158,7 @@ This smoke test:
|
|
|
154
158
|
- creates a temporary Rails app from a compatible Rails version
|
|
155
159
|
- installs `rails-worktrees` from the current checkout path
|
|
156
160
|
- runs `bin/rails generate worktrees:install --yolo`
|
|
157
|
-
- verifies `bin/wt`, the generated initializer, the Procfile example, yolo updates to `Procfile.dev` and `mise.toml`, `config/database.yml` patching, and worktree `.env` bootstrapping
|
|
161
|
+
- verifies `bin/wt`, the generated initializer, the Procfile example, yolo updates to `Procfile.dev`, `config/puma.rb`, and `mise.toml`, `config/database.yml` patching, and worktree `.env` bootstrapping
|
|
158
162
|
- creates a temporary bare `origin` and confirms `bin/wt smoke-branch` creates a real worktree
|
|
159
163
|
|
|
160
164
|
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.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Worktrees
|
|
3
|
+
module Generators
|
|
4
|
+
# Detects config/puma.rb setups that should prefer the worktree-local DEV_PORT.
|
|
5
|
+
module PumaFollowUp
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def puma_follow_up_notes_text
|
|
9
|
+
return '' unless suggest_puma_dev_port_update?
|
|
10
|
+
|
|
11
|
+
[
|
|
12
|
+
'',
|
|
13
|
+
' Tip:',
|
|
14
|
+
' Detected config/puma.rb. To bind Puma to the worktree-local DEV_PORT,',
|
|
15
|
+
' consider changing the port line to:',
|
|
16
|
+
" #{::Rails::Worktrees::PumaConfigUpdater::STANDARD_PORT_LINE}"
|
|
17
|
+
].join("\n")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def suggest_puma_dev_port_update?
|
|
21
|
+
existing_puma_config_path && puma_update_result.status == :updated
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def puma_update_result
|
|
25
|
+
return missing_puma_update_result unless existing_puma_config_path
|
|
26
|
+
|
|
27
|
+
::Rails::Worktrees::PumaConfigUpdater.new(content: File.read(existing_puma_config_path)).call
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def missing_puma_update_result
|
|
31
|
+
::Rails::Worktrees::PumaConfigUpdater::Result.new(nil, false, :skip, [])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def puma_config_path
|
|
35
|
+
File.join(destination_root, 'config/puma.rb')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def existing_puma_config_path
|
|
39
|
+
path = puma_config_path
|
|
40
|
+
File.file?(path) ? path : nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -2,9 +2,11 @@ require 'open3'
|
|
|
2
2
|
require 'rails/generators'
|
|
3
3
|
|
|
4
4
|
require_relative '../../rails/worktrees/mise_follow_up'
|
|
5
|
+
require_relative '../../rails/worktrees/puma_follow_up'
|
|
5
6
|
require_relative '../../../rails/worktrees/database_config_updater'
|
|
6
7
|
require_relative '../../../rails/worktrees/procfile_updater'
|
|
7
8
|
require_relative '../../../rails/worktrees/mise_toml_updater'
|
|
9
|
+
require_relative '../../../rails/worktrees/puma_config_updater'
|
|
8
10
|
|
|
9
11
|
module Worktrees
|
|
10
12
|
module Generators
|
|
@@ -12,6 +14,7 @@ module Worktrees
|
|
|
12
14
|
# rubocop:disable Metrics/ClassLength
|
|
13
15
|
class InstallGenerator < ::Rails::Generators::Base
|
|
14
16
|
include ::Rails::Worktrees::Generators::MiseFollowUp
|
|
17
|
+
include ::Rails::Worktrees::Generators::PumaFollowUp
|
|
15
18
|
|
|
16
19
|
namespace 'worktrees:install'
|
|
17
20
|
desc 'Installs bin/wt, a Rails::Worktrees initializer, and updates config/database.yml when safe.'
|
|
@@ -19,7 +22,7 @@ module Worktrees
|
|
|
19
22
|
class_option :conductor, type: :boolean, default: false,
|
|
20
23
|
desc: 'Configure the installer for ~/Sites/conductor/workspaces'
|
|
21
24
|
class_option :yolo, type: :boolean, default: false,
|
|
22
|
-
desc: 'Apply common Procfile.dev and mise .env follow-up edits when safe'
|
|
25
|
+
desc: 'Apply common Procfile.dev, config/puma.rb, and mise .env follow-up edits when safe'
|
|
23
26
|
|
|
24
27
|
FOLLOW_UP_TEMPLATE = <<~TEXT.freeze
|
|
25
28
|
============================================
|
|
@@ -55,6 +58,7 @@ module Worktrees
|
|
|
55
58
|
return unless options[:yolo]
|
|
56
59
|
|
|
57
60
|
update_procfile
|
|
61
|
+
update_puma_config
|
|
58
62
|
update_mise_toml
|
|
59
63
|
end
|
|
60
64
|
|
|
@@ -92,6 +96,10 @@ module Worktrees
|
|
|
92
96
|
File.join(destination_root, 'Procfile.dev')
|
|
93
97
|
end
|
|
94
98
|
|
|
99
|
+
def puma_config_path
|
|
100
|
+
File.join(destination_root, 'config/puma.rb')
|
|
101
|
+
end
|
|
102
|
+
|
|
95
103
|
def mise_toml_paths
|
|
96
104
|
[
|
|
97
105
|
File.join(destination_root, 'mise.toml'),
|
|
@@ -113,6 +121,10 @@ module Worktrees
|
|
|
113
121
|
"\n#{format(FOLLOW_UP_TEMPLATE, installed: installed_items_text, notes: follow_up_notes_text)}"
|
|
114
122
|
end
|
|
115
123
|
|
|
124
|
+
def follow_up_notes_text
|
|
125
|
+
[super, puma_follow_up_notes_text].join
|
|
126
|
+
end
|
|
127
|
+
|
|
116
128
|
def installed_items_text
|
|
117
129
|
items = [
|
|
118
130
|
' • bin/wt',
|
|
@@ -152,6 +164,18 @@ module Worktrees
|
|
|
152
164
|
announce_updater_result('Procfile.dev', result)
|
|
153
165
|
end
|
|
154
166
|
|
|
167
|
+
def update_puma_config
|
|
168
|
+
unless File.exist?(puma_config_path)
|
|
169
|
+
say_status(:skip, 'config/puma.rb not found', :yellow)
|
|
170
|
+
say('Skipped config/puma.rb yolo update because the file does not exist yet.')
|
|
171
|
+
return
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
result = ::Rails::Worktrees::PumaConfigUpdater.new(content: File.read(puma_config_path)).call
|
|
175
|
+
File.write(puma_config_path, result.content) if result.changed?
|
|
176
|
+
announce_updater_result('config/puma.rb', result)
|
|
177
|
+
end
|
|
178
|
+
|
|
155
179
|
def update_mise_toml
|
|
156
180
|
path = first_mise_toml_path
|
|
157
181
|
return announce_missing_mise_toml unless path
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Worktrees
|
|
3
|
+
# Safely updates config/puma.rb to bind Puma to the worktree-local DEV_PORT.
|
|
4
|
+
class PumaConfigUpdater
|
|
5
|
+
Result = Struct.new(:content, :changed, :status, :messages) do
|
|
6
|
+
def changed?
|
|
7
|
+
changed
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
STANDARD_PORT_LINE = "port ENV['DEV_PORT'] || ENV.fetch('PORT', 3000)".freeze
|
|
12
|
+
CURRENT_PORT_PATTERN = /\A\s*port\s+ENV\.fetch\(["']PORT["'],\s*3000\)\s*(?:#.*)?\z/
|
|
13
|
+
LEGACY_PORT_PATTERN = /\A\s*port\s+ENV\.fetch\(["']PORT["']\)\s*\{\s*3000\s*\}\s*(?:#.*)?\z/
|
|
14
|
+
PORT_LINE_PATTERN = /\A\s*port\s+/
|
|
15
|
+
DEV_PORT_ACCESS_PATTERN = /ENV\[(["'])DEV_PORT\1\]/
|
|
16
|
+
DEV_PORT_FETCH_PATTERN = /ENV\.fetch\((["'])DEV_PORT\1(?:\s*,|\s*\))/
|
|
17
|
+
|
|
18
|
+
def initialize(content:)
|
|
19
|
+
@content = content
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def call
|
|
23
|
+
lines = @content.lines(chomp: true)
|
|
24
|
+
return identical_result(@content) if dev_port_configured?(lines)
|
|
25
|
+
|
|
26
|
+
port_line_indexes = supported_port_line_indexes(lines)
|
|
27
|
+
return skip_result if port_line_indexes.empty?
|
|
28
|
+
|
|
29
|
+
updated_content = rebuild_content(
|
|
30
|
+
replace_port_lines(lines, port_line_indexes),
|
|
31
|
+
trailing_newline: @content.end_with?("\n")
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
updated_result(updated_content)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def updated_result(content)
|
|
40
|
+
Result.new(content, true, :updated, ['Updated config/puma.rb to prefer DEV_PORT before PORT.'])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def identical_result(content)
|
|
44
|
+
Result.new(content, false, :identical, ['config/puma.rb already uses DEV_PORT-aware port binding.'])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def skip_result
|
|
48
|
+
Result.new(
|
|
49
|
+
@content,
|
|
50
|
+
false,
|
|
51
|
+
:skip,
|
|
52
|
+
['No supported Puma port binding found in config/puma.rb; update it manually if needed.']
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def dev_port_configured?(lines)
|
|
57
|
+
lines.any? do |line|
|
|
58
|
+
line.match?(PORT_LINE_PATTERN) &&
|
|
59
|
+
(line.match?(DEV_PORT_ACCESS_PATTERN) || line.match?(DEV_PORT_FETCH_PATTERN))
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def supported_port_line_indexes(lines)
|
|
64
|
+
lines.each_index.select { |index| supported_port_line?(lines[index]) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def supported_port_line?(line)
|
|
68
|
+
line.match?(CURRENT_PORT_PATTERN) || line.match?(LEGACY_PORT_PATTERN)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def replace_port_lines(lines, port_line_indexes)
|
|
72
|
+
lines.dup.tap do |updated_lines|
|
|
73
|
+
port_line_indexes.each do |index|
|
|
74
|
+
original_line = lines[index]
|
|
75
|
+
indent = original_line[/\A\s*/]
|
|
76
|
+
trailing_comment = original_line[/(\s*#.*)\z/, 1].to_s
|
|
77
|
+
|
|
78
|
+
updated_lines[index] = "#{indent}#{STANDARD_PORT_LINE}#{trailing_comment}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def rebuild_content(lines, trailing_newline:)
|
|
84
|
+
content = lines.join("\n")
|
|
85
|
+
return content if content.empty? || !trailing_newline
|
|
86
|
+
|
|
87
|
+
"#{content}\n"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/rails/worktrees.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative 'worktrees/cli'
|
|
|
8
8
|
require_relative 'worktrees/database_config_updater'
|
|
9
9
|
require_relative 'worktrees/procfile_updater'
|
|
10
10
|
require_relative 'worktrees/mise_toml_updater'
|
|
11
|
+
require_relative 'worktrees/puma_config_updater'
|
|
11
12
|
|
|
12
13
|
module Rails
|
|
13
14
|
# Rails-specific git worktree helpers and installer support.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-worktrees
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Asjer Querido
|
|
@@ -46,6 +46,7 @@ files:
|
|
|
46
46
|
- exe/wt
|
|
47
47
|
- lefthook.yml
|
|
48
48
|
- lib/generators/rails/worktrees/mise_follow_up.rb
|
|
49
|
+
- lib/generators/rails/worktrees/puma_follow_up.rb
|
|
49
50
|
- lib/generators/rails/worktrees/templates/Procfile.dev.worktree.example.tt
|
|
50
51
|
- lib/generators/rails/worktrees/templates/bin/wt
|
|
51
52
|
- lib/generators/rails/worktrees/templates/rails_worktrees.rb.tt
|
|
@@ -64,6 +65,7 @@ files:
|
|
|
64
65
|
- lib/rails/worktrees/mise_toml_updater.rb
|
|
65
66
|
- lib/rails/worktrees/names/cities.txt
|
|
66
67
|
- lib/rails/worktrees/procfile_updater.rb
|
|
68
|
+
- lib/rails/worktrees/puma_config_updater.rb
|
|
67
69
|
- lib/rails/worktrees/railtie.rb
|
|
68
70
|
- lib/rails/worktrees/version.rb
|
|
69
71
|
- mise.toml
|