brunch 0.8.1 → 0.8.2

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: 318ff646dd610a9647612d8ea0fcc446e5122215f4517d665fc639b5bfca740d
4
- data.tar.gz: e4aeddec12c82d9b0d33caddf6a366840e3db8badd45fec4114f57bd034c3d86
3
+ metadata.gz: 954abfa5f0f95a57eb872a2f140b0eed41d06ccbc7ff5ed5961e12ff73b371fd
4
+ data.tar.gz: 650c7a5a55c2557191e35cd94da369e6d89708623963e9c2721f04664c9ecbe7
5
5
  SHA512:
6
- metadata.gz: d334e9cc379f39f4866626e8801adbdc9cbe8aace2d0249b8b4a6a81020b34ec35eca8b8dcf742622e06545d58086966ed087784b077460bdc7e56e5ec150f1c
7
- data.tar.gz: b34f7f1baf8dbbf6a56669ccc310846eab6aa23d891fa05e4adbe541e1ab1ccea954bfdb46c087fba7a47e3601f45f967efb1de8ff93d7678cb361abaec6eb1c
6
+ metadata.gz: 422d99f190dc07133f0517690a21ec2fda19f17a909b58437374bd49b982625cee2738f5fbe5ab6095898cadd758abdb83df4e21ea856f91270abe4cd16d42be
7
+ data.tar.gz: c328e3b0a2ba453afd8dd5beb073a221ca5d5b1ba33caafcf59ee1a5396591d5c5b374ef85999511c9b0b8dd558fe963289c2098f76aca42ed650e3ac8e43c61
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.8.2 - 2026-09-29
6
+
7
+ - Resume stopped branch containers without rebuilding or replacing them when
8
+ switching back, preserving files in their writable layers.
9
+ - Group `brunch ports` by worktree and show stopped branch environments in gray.
10
+
5
11
  ## 0.8.1 - 2026-09-29
6
12
 
7
13
  - Reorganize the README into a step-by-step guide for branches, parallel
data/README.md CHANGED
@@ -101,6 +101,8 @@ git switch main
101
101
  Branches checked out in the same worktree reuse that worktree's host port.
102
102
 
103
103
  With Compose, each branch keeps its own Compose project and named volumes, so persistent resources remain isolated between branches.
104
+ Returning to a previously activated branch starts its stopped containers again,
105
+ preserving files written inside them. The branch keeps the same host port.
104
106
 
105
107
  To manually start the environment after `brunch stop`:
106
108
 
@@ -108,12 +110,15 @@ To manually start the environment after `brunch stop`:
108
110
  brunch activate
109
111
  ```
110
112
 
111
- To rebuild and restart it:
113
+ To rebuild and recreate its containers explicitly:
112
114
 
113
115
  ```bash
114
116
  brunch restart
115
117
  ```
116
118
 
119
+ `brunch restart` may discard data stored only in a container's writable layer.
120
+ Put important data, such as databases, in named volumes.
121
+
117
122
  Compose builds use files from the live worktree, including uncommitted changes.
118
123
 
119
124
  If you want source edits to appear in an already running container without rebuilding, configure a bind mount or another reload mechanism in your Compose setup.
@@ -140,7 +145,9 @@ brunch ports
140
145
 
141
146
  `brunch port` prints the current worktree's port.
142
147
 
143
- `brunch ports` lists ports assigned to all worktrees.
148
+ `brunch ports` groups the current and previously activated branches under each
149
+ worktree. Stopped branches appear in gray and retain their worktree's port for
150
+ the next activation.
144
151
 
145
152
  Switching branches inside one worktree does not affect environments running in other worktrees.
146
153
 
@@ -282,7 +289,7 @@ Print the current worktree's port.
282
289
  brunch ports
283
290
  ```
284
291
 
285
- List ports assigned to all worktrees.
292
+ List current and stopped branch environments grouped by worktree.
286
293
 
287
294
  ```bash
288
295
  brunch stop
@@ -15,6 +15,8 @@ module Brunch
15
15
 
16
16
  def create(_entry) = true
17
17
 
18
+ def resume(entry) = start(entry)
19
+
18
20
  def environment(entry)
19
21
  {
20
22
  "BRUNCH_REF" => entry.fetch("ref", ""),
@@ -66,6 +68,7 @@ module Brunch
66
68
  end
67
69
 
68
70
  def start(entry) = compose(entry, "up", "--detach", "--build", "--remove-orphans")
71
+ def resume(entry) = compose(entry, "start")
69
72
 
70
73
  def status(entry)
71
74
  return "unavailable" unless available?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Brunch
4
- VERSION = "0.8.1"
4
+ VERSION = "0.8.2"
5
5
  end
@@ -100,11 +100,13 @@ module Brunch
100
100
  abort "#{config.fetch('manager')} is unavailable." unless manager.available?
101
101
 
102
102
  existing = nil
103
+ current_ref = nil
103
104
  with_state_lock do |data|
104
105
  record = data.fetch("worktrees", {})[id]
105
106
  existing = record&.fetch("environments", {})&.[](ref)
107
+ current_ref = record&.[]("current")
106
108
  end
107
- return if existing && !force && existing["snapshot"] == path && existing["head"] == head && existing["status"] == "running"
109
+ return if existing && !force && existing["snapshot"] == path && existing["status"] == "running" && current_ref == ref
108
110
 
109
111
  previous = nil
110
112
  port = nil
@@ -120,6 +122,16 @@ module Brunch
120
122
  data.fetch("worktrees").fetch(id).fetch("environments").fetch(previous.fetch("ref"))["status"] = "stopped"
121
123
  end
122
124
  end
125
+ if existing && !force && existing["snapshot"] == path && existing["status"] != "starting"
126
+ with_state_lock { |data| data.fetch("worktrees").fetch(id)["current"] = ref }
127
+ abort "Could not resume environment for #{path}. Run brunch restart to rebuild it." unless worktree_manager(existing).resume(existing)
128
+
129
+ with_state_lock do |data|
130
+ data.fetch("worktrees").fetch(id).fetch("environments").fetch(ref)["status"] = "running"
131
+ end
132
+ puts "Resumed #{ref} in #{path} at http://127.0.0.1:#{existing.fetch('port')}"
133
+ return
134
+ end
123
135
  abort "Could not reset environment for #{path}." if existing && !worktree_manager(existing).reset(existing)
124
136
 
125
137
  project = "brunch-#{id[0, 12]}-#{Digest::SHA256.hexdigest(ref)[0, 12]}"
@@ -252,12 +264,22 @@ module Brunch
252
264
  data = state
253
265
  current_id = worktree_identity(repo_root)
254
266
  data.fetch("worktrees", {}).sort_by { |_id, record| record.fetch("path") }.each do |id, record|
255
- entry = record.fetch("environments", {})[record["current"]]
256
- next unless entry
267
+ environments = record.fetch("environments", {})
268
+ next if environments.empty?
257
269
 
258
- marker = id == current_id ? color("●", 32) : "○"
259
- name = id == current_id ? color(entry.fetch("ref"), 32) : entry.fetch("ref")
260
- puts "#{marker} #{name} #{record.fetch('port')} #{record.fetch('path')}"
270
+ path = record.fetch("path")
271
+ puts(id == current_id ? color("● #{path}", 32) : "○ #{path}")
272
+ branches = environments.sort_by { |ref, _entry| [ref == record["current"] ? 0 : 1, ref] }
273
+ branches.each_with_index do |(ref, entry), index|
274
+ prefix = index == branches.length - 1 ? " └─" : " ├─"
275
+ running = ref == record["current"] && entry["status"] == "running"
276
+ unless running
277
+ puts color("#{prefix} ○ #{ref} #{entry.fetch('port')}", 90)
278
+ next
279
+ end
280
+
281
+ puts "#{prefix} #{color("● #{ref}", 32)} #{entry.fetch('port')}"
282
+ end
261
283
  end
262
284
  end
263
285
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brunch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Ciemborowicz