rails-worktrees 0.1.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c6da0f27411c99c20b5ab3496a4ac0672ba6a3833e429b33b53b5884d3a3c76
4
- data.tar.gz: cb144472bad91868165d8a37de3ba12f0675255aabc2fa3df0d9e8d6c3d736ff
3
+ metadata.gz: 971ba5f8f872a37a91d2e8c1755bf838db8bf67a767dbfba1b105b727440d9b7
4
+ data.tar.gz: dd0441f61442afffc29b7ab5f70968abd0c35c59e2731247cc55ddeae6e18265
5
5
  SHA512:
6
- metadata.gz: 7d959fde216a23fa191dca31294ff776b0091e3f230db9191a87890e8736217c3182b773e2950b18cbc151c20f833b238b7f3a07e618a5a4aa997bad5191760e
7
- data.tar.gz: 7abecada6524724a90bd993b3975ce8b20a05e5123c0a9e2f6a2e8bc3d5435d04590a2ba3df83561ec41004d03d83627d48659866290b78b5ce4ed3bebbabfb1
6
+ metadata.gz: 1e77b1961db51bcaca110efe1b8c9c6c96e848b523f30e158cc55c94550023fb85289b124ec859abd6957542ae0fcc4e20a63f793985b87ea5a03e2302b9748a
7
+ data.tar.gz: 5955435a25990d85b834e9c22d3c37d9621cab21a69dac6c6b9e038e763bc8346a8f6a23886f37098285cd6f055496417f85b34f8351e9f5b4d3e6115b429753
@@ -1 +1 @@
1
- {".":"0.1.1"}
1
+ {".":"0.2.1"}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
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
+
10
+ ## [0.2.0](https://github.com/asjer/rails-worktrees/compare/v0.1.1...v0.2.0) (2026-03-30)
11
+
12
+
13
+ ### Features
14
+
15
+ * add `--yolo` mode to install common follow-ups without manual edits ([1ec82ec](https://github.com/asjer/rails-worktrees/commit/1ec82ec83726b5ca9cbaee39697c607fdb825f26))
16
+
3
17
  ## [0.1.1](https://github.com/asjer/rails-worktrees/compare/v0.1.0...v0.1.1) (2026-03-30)
4
18
 
5
19
 
data/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
  ```bash
14
14
  bundle add rails-worktrees
15
15
  bin/rails generate worktrees:install
16
+ # or, to apply the common Procfile.dev + Puma + mise follow-ups automatically:
17
+ bin/rails generate worktrees:install --yolo
16
18
  ```
17
19
 
18
20
  The installer adds:
@@ -22,6 +24,12 @@ The installer adds:
22
24
  - `Procfile.dev.worktree.example` — a copy-paste helper for `${DEV_PORT:-3000}` in `Procfile.dev`
23
25
  - a safe update to `config/database.yml` for common development/test database names
24
26
 
27
+ With `--yolo`, the installer also:
28
+
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
31
+ - updates `mise.toml` or `.mise.toml` to load `.env` from `[env]` when either file already exists
32
+
25
33
  ## Usage
26
34
 
27
35
  ```bash
@@ -115,12 +123,20 @@ When `bin/wt` creates a worktree it writes a worktree-local `.env` with:
115
123
 
116
124
  Existing `.env` values are never overwritten.
117
125
 
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:
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:
119
127
 
120
128
  ```text
121
129
  web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p ${DEV_PORT:-3000}
122
130
  ```
123
131
 
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:
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
136
+ - add `_.file = ".env"` to the `[env]` section of `mise.toml` or `.mise.toml`
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
+
124
140
  Use a project-local env loader like `mise` with `_.file = ".env"` to keep values scoped per-worktree.
125
141
 
126
142
  ## Development
@@ -141,8 +157,8 @@ This smoke test:
141
157
 
142
158
  - creates a temporary Rails app from a compatible Rails version
143
159
  - installs `rails-worktrees` from the current checkout path
144
- - runs `bin/rails generate worktrees:install`
145
- - verifies `bin/wt`, the generated initializer, the Procfile example, `config/database.yml` patching, and worktree `.env` bootstrapping
160
+ - runs `bin/rails generate worktrees:install --yolo`
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
146
162
  - creates a temporary bare `origin` and confirms `bin/wt smoke-branch` creates a real worktree
147
163
 
148
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.
@@ -11,7 +11,8 @@ module Rails
11
11
  [
12
12
  '',
13
13
  ' Tip:',
14
- ' Detected mise.toml. To auto-load the worktree-local .env when you enter a worktree,',
14
+ " Detected #{File.basename(mise_toml_path)}. To auto-load the worktree-local .env when",
15
+ ' you enter a worktree,',
15
16
  ' consider adding:',
16
17
  ' [env]',
17
18
  ' _.file = ".env"'
@@ -19,15 +20,24 @@ module Rails
19
20
  end
20
21
 
21
22
  def suggest_mise_env_file?
22
- File.file?(mise_toml_path) && !mise_env_file_configured?
23
+ mise_toml_path && !mise_env_file_configured?
23
24
  end
24
25
 
25
26
  def mise_env_file_configured?
26
- File.read(mise_toml_path).match?(/^\s*_.file\s*=\s*["']\.env["']\s*$/)
27
+ return false unless mise_toml_path
28
+
29
+ File.read(mise_toml_path).match?(/^\s*_.file\s*=\s*["']\.env["']\s*(?:#.*)?\s*$/)
27
30
  end
28
31
 
29
32
  def mise_toml_path
30
- File.join(destination_root, 'mise.toml')
33
+ @mise_toml_path ||= mise_toml_paths.find { |path| File.file?(path) }
34
+ end
35
+
36
+ def mise_toml_paths
37
+ [
38
+ File.join(destination_root, 'mise.toml'),
39
+ File.join(destination_root, '.mise.toml')
40
+ ]
31
41
  end
32
42
  end
33
43
  end
@@ -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,19 +2,27 @@ 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'
7
+ require_relative '../../../rails/worktrees/procfile_updater'
8
+ require_relative '../../../rails/worktrees/mise_toml_updater'
9
+ require_relative '../../../rails/worktrees/puma_config_updater'
6
10
 
7
11
  module Worktrees
8
12
  module Generators
9
13
  # Installs the wt wrapper, configuration, and safe database.yml updates.
14
+ # rubocop:disable Metrics/ClassLength
10
15
  class InstallGenerator < ::Rails::Generators::Base
11
16
  include ::Rails::Worktrees::Generators::MiseFollowUp
17
+ include ::Rails::Worktrees::Generators::PumaFollowUp
12
18
 
13
19
  namespace 'worktrees:install'
14
20
  desc 'Installs bin/wt, a Rails::Worktrees initializer, and updates config/database.yml when safe.'
15
21
  source_root File.expand_path('../../rails/worktrees/templates', __dir__)
16
22
  class_option :conductor, type: :boolean, default: false,
17
23
  desc: 'Configure the installer for ~/Sites/conductor/workspaces'
24
+ class_option :yolo, type: :boolean, default: false,
25
+ desc: 'Apply common Procfile.dev, config/puma.rb, and mise .env follow-up edits when safe'
18
26
 
19
27
  FOLLOW_UP_TEMPLATE = <<~TEXT.freeze
20
28
  ============================================
@@ -46,6 +54,14 @@ module Worktrees
46
54
  template('Procfile.dev.worktree.example.tt', 'Procfile.dev.worktree.example')
47
55
  end
48
56
 
57
+ def apply_yolo_follow_ups
58
+ return unless options[:yolo]
59
+
60
+ update_procfile
61
+ update_puma_config
62
+ update_mise_toml
63
+ end
64
+
49
65
  def update_database_configuration
50
66
  unless File.exist?(database_config_path)
51
67
  say_status(:skip, 'config/database.yml not found', :yellow)
@@ -76,6 +92,21 @@ module Worktrees
76
92
  File.join(destination_root, 'config/database.yml')
77
93
  end
78
94
 
95
+ def procfile_path
96
+ File.join(destination_root, 'Procfile.dev')
97
+ end
98
+
99
+ def puma_config_path
100
+ File.join(destination_root, 'config/puma.rb')
101
+ end
102
+
103
+ def mise_toml_paths
104
+ [
105
+ File.join(destination_root, 'mise.toml'),
106
+ File.join(destination_root, '.mise.toml')
107
+ ]
108
+ end
109
+
79
110
  def database_update_result
80
111
  result = ::Rails::Worktrees::DatabaseConfigUpdater.new(
81
112
  content: File.read(database_config_path)
@@ -90,6 +121,10 @@ module Worktrees
90
121
  "\n#{format(FOLLOW_UP_TEMPLATE, installed: installed_items_text, notes: follow_up_notes_text)}"
91
122
  end
92
123
 
124
+ def follow_up_notes_text
125
+ [super, puma_follow_up_notes_text].join
126
+ end
127
+
93
128
  def installed_items_text
94
129
  items = [
95
130
  ' • bin/wt',
@@ -117,6 +152,63 @@ module Worktrees
117
152
  result.messages.each { |message| say(message) }
118
153
  end
119
154
 
155
+ def update_procfile
156
+ unless File.exist?(procfile_path)
157
+ say_status(:skip, 'Procfile.dev not found', :yellow)
158
+ say('Skipped Procfile.dev yolo update because the file does not exist yet.')
159
+ return
160
+ end
161
+
162
+ result = ::Rails::Worktrees::ProcfileUpdater.new(content: File.read(procfile_path)).call
163
+ File.write(procfile_path, result.content) if result.changed?
164
+ announce_updater_result('Procfile.dev', result)
165
+ end
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
+
179
+ def update_mise_toml
180
+ path = first_mise_toml_path
181
+ return announce_missing_mise_toml unless path
182
+
183
+ result = ::Rails::Worktrees::MiseTomlUpdater.new(
184
+ content: File.read(path),
185
+ file_name: File.basename(path)
186
+ ).call
187
+
188
+ File.write(path, result.content) if result.changed?
189
+ announce_updater_result(File.basename(path), result)
190
+ end
191
+
192
+ def announce_updater_result(path, result)
193
+ status, color = case result.status
194
+ when :updated then %i[update green]
195
+ when :identical then %i[identical blue]
196
+ else %i[skip yellow]
197
+ end
198
+
199
+ say_status(status, path, color)
200
+ result.messages.each { |message| say(message) }
201
+ end
202
+
203
+ def first_mise_toml_path
204
+ mise_toml_paths.find { |candidate| File.file?(candidate) }
205
+ end
206
+
207
+ def announce_missing_mise_toml
208
+ say_status(:skip, 'mise.toml/.mise.toml not found', :yellow)
209
+ say('Skipped mise yolo update because no supported mise config file was found.')
210
+ end
211
+
120
212
  def git_repo?
121
213
  _stdout_str, _stderr_str, status = Open3.capture3(
122
214
  'git', 'rev-parse', '--is-inside-work-tree', chdir: destination_root
@@ -130,5 +222,6 @@ module Worktrees
130
222
  "File.expand_path('~/Sites/conductor/workspaces')"
131
223
  end
132
224
  end
225
+ # rubocop:enable Metrics/ClassLength
133
226
  end
134
227
  end
@@ -0,0 +1,82 @@
1
+ module Rails
2
+ module Worktrees
3
+ # Safely updates mise config to load the worktree-local .env.
4
+ class MiseTomlUpdater
5
+ Result = Struct.new(:content, :changed, :status, :messages) do
6
+ def changed?
7
+ changed
8
+ end
9
+ end
10
+
11
+ ENV_SECTION_PATTERN = /\A\s*\[env\]\s*(?:#.*)?\z/
12
+ ENV_FILE_PATTERN = /\A\s*_.file\s*=\s*["']\.env["']\s*(?:#.*)?\z/
13
+ SECTION_PATTERN = /\A\s*\[[^\]]+\]\s*(?:#.*)?\z/
14
+ ENV_FILE_ENTRY = '_.file = ".env"'.freeze
15
+
16
+ def initialize(content:, file_name:)
17
+ @content = content
18
+ @file_name = file_name
19
+ end
20
+
21
+ def call
22
+ lines = @content.lines(chomp: true)
23
+ return update_existing_env_section(lines) if env_section_present?(lines)
24
+
25
+ append_env_section(lines)
26
+ end
27
+
28
+ private
29
+
30
+ def update_existing_env_section(lines)
31
+ env_section_start, env_section_end = env_section_bounds(lines)
32
+ return identical_result if env_file_configured?(lines, env_section_start, env_section_end)
33
+
34
+ updated_lines = lines.dup
35
+ updated_lines.insert(env_section_end, ENV_FILE_ENTRY)
36
+ updated_result(rebuild_content(updated_lines, trailing_newline: @content.end_with?("\n")))
37
+ end
38
+
39
+ def append_env_section(lines)
40
+ updated_lines = lines.dup
41
+ updated_lines << '' if updated_lines.any? && !updated_lines.last.empty?
42
+ updated_lines << '[env]'
43
+ updated_lines << ENV_FILE_ENTRY
44
+
45
+ updated_result(rebuild_content(updated_lines, trailing_newline: true))
46
+ end
47
+
48
+ def updated_result(content)
49
+ Result.new(content, true, :updated, ["Configured #{@file_name} to load .env from [env]."])
50
+ end
51
+
52
+ def identical_result
53
+ Result.new(@content, false, :identical, ["#{@file_name} already loads .env from [env]."])
54
+ end
55
+
56
+ def env_section_bounds(lines)
57
+ start_index = lines.find_index { |line| line.match?(ENV_SECTION_PATTERN) }
58
+ return [nil, nil] unless start_index
59
+
60
+ end_index = ((start_index + 1)...lines.length).find do |index|
61
+ lines[index].match?(SECTION_PATTERN)
62
+ end || lines.length
63
+ [start_index, end_index]
64
+ end
65
+
66
+ def env_section_present?(lines)
67
+ env_section_bounds(lines).first
68
+ end
69
+
70
+ def env_file_configured?(lines, start_index, end_index)
71
+ lines[(start_index + 1)...end_index].any? { |line| line.match?(ENV_FILE_PATTERN) }
72
+ end
73
+
74
+ def rebuild_content(lines, trailing_newline:)
75
+ content = lines.join("\n")
76
+ return content if content.empty? || !trailing_newline
77
+
78
+ "#{content}\n"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,69 @@
1
+ module Rails
2
+ module Worktrees
3
+ # Safely updates Procfile.dev to use the worktree-local DEV_PORT.
4
+ class ProcfileUpdater
5
+ Result = Struct.new(:content, :changed, :status, :messages) do
6
+ def changed?
7
+ changed
8
+ end
9
+ end
10
+
11
+ STANDARD_WEB_ENTRY = 'web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p ${DEV_PORT:-3000}'.freeze
12
+ WEB_ENTRY_PATTERN = /\Aweb:\s*.*\z/
13
+
14
+ def initialize(content:)
15
+ @content = content
16
+ end
17
+
18
+ def call
19
+ lines = @content.lines(chomp: true)
20
+ web_entry_indexes = web_entry_indexes(lines)
21
+ return skip_result if web_entry_indexes.empty?
22
+
23
+ updated_content = rebuild_content(
24
+ replace_web_entries(lines, web_entry_indexes),
25
+ trailing_newline: @content.end_with?("\n")
26
+ )
27
+
28
+ build_result(updated_content)
29
+ end
30
+
31
+ private
32
+
33
+ def updated_result(content)
34
+ Result.new(content, true, :updated, ['Updated Procfile.dev web entry to use DEV_PORT.'])
35
+ end
36
+
37
+ def identical_result(content)
38
+ Result.new(content, false, :identical, ['Procfile.dev already uses the DEV_PORT-aware web entry.'])
39
+ end
40
+
41
+ def skip_result
42
+ Result.new(@content, false, :skip, ['No web: entry found in Procfile.dev; update it manually if needed.'])
43
+ end
44
+
45
+ def web_entry_indexes(lines)
46
+ lines.each_index.select { |index| lines[index].match?(WEB_ENTRY_PATTERN) }
47
+ end
48
+
49
+ def replace_web_entries(lines, web_entry_indexes)
50
+ lines.dup.tap do |updated_lines|
51
+ web_entry_indexes.each { |index| updated_lines[index] = STANDARD_WEB_ENTRY }
52
+ end
53
+ end
54
+
55
+ def build_result(content)
56
+ return identical_result(content) if content == @content
57
+
58
+ updated_result(content)
59
+ end
60
+
61
+ def rebuild_content(lines, trailing_newline:)
62
+ content = lines.join("\n")
63
+ return content if content.empty? || !trailing_newline
64
+
65
+ "#{content}\n"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Rails
2
2
  module Worktrees
3
- VERSION = '0.1.1'.freeze
3
+ VERSION = '0.2.1'.freeze
4
4
  end
5
5
  end
@@ -6,6 +6,9 @@ require_relative 'worktrees/env_bootstrapper'
6
6
  require_relative 'worktrees/command'
7
7
  require_relative 'worktrees/cli'
8
8
  require_relative 'worktrees/database_config_updater'
9
+ require_relative 'worktrees/procfile_updater'
10
+ require_relative 'worktrees/mise_toml_updater'
11
+ require_relative 'worktrees/puma_config_updater'
9
12
 
10
13
  module Rails
11
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.1.1
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
@@ -61,7 +62,10 @@ files:
61
62
  - lib/rails/worktrees/configuration.rb
62
63
  - lib/rails/worktrees/database_config_updater.rb
63
64
  - lib/rails/worktrees/env_bootstrapper.rb
65
+ - lib/rails/worktrees/mise_toml_updater.rb
64
66
  - lib/rails/worktrees/names/cities.txt
67
+ - lib/rails/worktrees/procfile_updater.rb
68
+ - lib/rails/worktrees/puma_config_updater.rb
65
69
  - lib/rails/worktrees/railtie.rb
66
70
  - lib/rails/worktrees/version.rb
67
71
  - mise.toml