brunch 0.8.0 → 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: f77dd24e00604eea2485dff005164094eb6f6e8633d81e96616df5bf25420ef2
4
- data.tar.gz: 578505da516fbd81dfdd6c54e397ac0d4861e25e7af5b482a6e4f8fcf2aa4043
3
+ metadata.gz: 954abfa5f0f95a57eb872a2f140b0eed41d06ccbc7ff5ed5961e12ff73b371fd
4
+ data.tar.gz: 650c7a5a55c2557191e35cd94da369e6d89708623963e9c2721f04664c9ecbe7
5
5
  SHA512:
6
- metadata.gz: c80c84a7078a91a71c69517d68d9b5093d13c6e97b8662e5ec98aecf2b2d2b07daaa49713da6046c51ca16c41c63cc58b50c2e6c286f1c5ede0ed0c3f2ce5ab2
7
- data.tar.gz: 759c3e32ad7957cdec4b3babe27ad211262ce4f177b0ce6a2f4a0f9d3db26ed81ed332c930e2690e7cc3f9195f7528a5fa80b5ddf8cd4aa7063c32f9e0c18648
6
+ metadata.gz: 422d99f190dc07133f0517690a21ec2fda19f17a909b58437374bd49b982625cee2738f5fbe5ab6095898cadd758abdb83df4e21ea856f91270abe4cd16d42be
7
+ data.tar.gz: c328e3b0a2ba453afd8dd5beb073a221ca5d5b1ba33caafcf59ee1a5396591d5c5b374ef85999511c9b0b8dd558fe963289c2098f76aca42ed650e3ac8e43c61
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
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
+
11
+ ## 0.8.1 - 2026-09-29
12
+
13
+ - Reorganize the README into a step-by-step guide for branches, parallel
14
+ worktrees, managers, and everyday commands.
15
+
5
16
  ## 0.8.0 - 2026-09-29
6
17
 
7
18
  - Use one worktree-based lifecycle for both branch switches and parallel
data/README.md CHANGED
@@ -2,51 +2,46 @@
2
2
 
3
3
  ![Brunch — container per branch and worktree](brunch.webp)
4
4
 
5
- Brunch runs isolated development environments for Git worktrees. The main
6
- checkout is a worktree too: switching branches there reuses its port, while
7
- additional worktrees run in parallel on different host ports. Docker Compose
8
- is the default manager; Podman
9
- Compose, local processes, and project commands are also supported.
5
+ Brunch runs isolated development environments for Git branches and worktrees.
10
6
 
11
- Each branch environment has a distinct Compose project name, network, and
12
- named volumes. The active environment runs from its live worktree directory,
13
- including uncommitted changes when the manager rebuilds or reloads the app.
7
+ Each branch gets its own environment. With Compose, that means a separate project, network, containers, and named volumes. Branches checked out in the same worktree share its host port, while additional worktrees get different ports and can run in parallel.
8
+
9
+ Docker Compose is the default manager. Podman Compose, local processes, and custom project commands are also supported.
14
10
 
15
11
  ## Requirements
16
12
 
17
- - Ruby 3.1 or newer
18
- - Git 2.28 or newer
19
- - A supported environment manager: Docker Compose, Podman Compose, or project commands
20
- - [`git-hooks-ext`](https://github.com/ciembor/git-hooks-ext)
13
+ - Ruby 3.1+
14
+ - Git 2.28+
15
+ - Docker Compose, Podman Compose, or another supported manager
16
+ - [git-hooks-ext](https://github.com/ciembor/git-hooks-ext)
21
17
 
22
18
  ## Installation
23
19
 
24
- Install [`git-hooks-ext`](https://github.com/ciembor/git-hooks-ext) so that
25
- `ghe` is on your `PATH`, then install Brunch:
20
+ Install [git-hooks-ext](https://github.com/ciembor/git-hooks-ext) so that `ghe` is available on your `PATH`, then install Brunch:
26
21
 
27
- ```sh
22
+ ```bash
28
23
  gem install brunch
29
24
  ```
30
25
 
31
- Run `brunch install` inside each Git repository you want Brunch to manage.
32
- It installs the `git-hooks-ext` bridge and project-local hooks, and refuses
33
- to replace an existing hook owned by another tool.
26
+ Inside each repository you want Brunch to manage:
27
+
28
+ ```bash
29
+ brunch install
30
+ ```
31
+
32
+ Brunch installs its hooks through `git-hooks-ext` and will not overwrite hooks owned by another tool.
34
33
 
35
- ## Project configuration
34
+ ## Configuration
36
35
 
37
- Add `brunch.yml` to the project root. Docker Compose is the default, so the
38
- following remains sufficient for Compose projects:
36
+ Add `brunch.yml` to the repository root.
37
+
38
+ For Docker Compose:
39
39
 
40
40
  ```yaml
41
41
  compose_file: compose.yaml
42
42
  ```
43
43
 
44
- The referenced Compose file belongs to the application. Brunch does not impose
45
- a database or service stack: applications may define PostgreSQL, MySQL, Redis,
46
- Sidekiq, Elasticsearch, or any other services they need.
47
- Unknown `brunch.yml` fields are errors, so configuration typos are not ignored.
48
-
49
- Expose the application port with `BRUNCH_PORT`:
44
+ Expose the application through `BRUNCH_PORT`:
50
45
 
51
46
  ```yaml
52
47
  services:
@@ -55,121 +50,141 @@ services:
55
50
  - "127.0.0.1:${BRUNCH_PORT}:3000"
56
51
  ```
57
52
 
58
- The first activated worktree prefers `127.0.0.1:3000`. Every worktree keeps
59
- its assigned host port while its branches take turns using it. Other worktrees
60
- receive a different free port; running containers can never bind the same host
61
- address and port. To prefer another starting port, set `preferred_port: 4000`.
62
- Brunch persists assignments privately in `.git/brunch/state.json`.
53
+ The first activated worktree prefers port `3000`. Additional worktrees receive another free port.
63
54
 
64
- ## Using Brunch
55
+ To prefer a different starting port:
65
56
 
66
- First, commit `brunch.yml` and your Compose file (or the configuration for
67
- another manager). The repository needs at least one commit before Brunch can
68
- start an environment. Install the hooks once per repository, then activate
69
- the checked-out branch:
57
+ ```yaml
58
+ preferred_port: 4000
59
+ ```
70
60
 
71
- ```sh
61
+ Port assignments are persisted per worktree in `.git/brunch/state.json`.
62
+
63
+ ## Getting started
64
+
65
+ Commit `brunch.yml` and the application configuration first. The repository must contain at least one commit.
66
+
67
+ Then run:
68
+
69
+ ```bash
72
70
  brunch install
73
71
  brunch doctor
74
72
  brunch activate
75
73
  brunch status
74
+ ```
75
+
76
+ `brunch activate` starts the environment for the currently checked-out branch.
77
+
78
+ To print only the current worktree's port:
79
+
80
+ ```bash
76
81
  brunch port
77
82
  ```
78
83
 
79
- Open `http://127.0.0.1:3000` if port 3000 is free, or use the port printed by
80
- `brunch activate` / `brunch port`. Brunch starts the application in the
81
- background. With Compose, the app must listen on the container port mapped in
82
- `compose.yaml`.
84
+ Open the application on the printed port, for example:
83
85
 
84
- ### Branches in one checkout
86
+ ```text
87
+ http://127.0.0.1:3000
88
+ ```
89
+
90
+ With Compose, the application must listen on the container port mapped in the Compose file.
91
+
92
+ ## Branch switching
85
93
 
86
- Once the hooks are installed, ordinary Git branch switches stop the old
87
- environment and start the new one automatically:
94
+ Once the hooks are installed, normal Git branch switches automatically stop the previous branch environment and start the new one:
88
95
 
89
- ```sh
96
+ ```bash
90
97
  git switch -c feature/login
91
- brunch status
92
98
  git switch main
93
99
  ```
94
100
 
95
- Both branches use this checkout's assigned host port. With Compose, they keep
96
- separate projects and volumes. To start the checked-out branch manually (for
97
- example, after `brunch stop`), run `brunch activate`. Run `brunch restart` to
98
- rebuild it after changing files that are copied into the image.
101
+ Branches checked out in the same worktree reuse that worktree's host port.
99
102
 
100
- ### Parallel worktrees
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.
101
106
 
102
- There is no mode switch. Commit the same `brunch.yml` in your repository, then
103
- create additional worktrees. Run `brunch install` again after upgrading Brunch
104
- to install its worktree hooks.
107
+ To manually start the environment after `brunch stop`:
105
108
 
106
- ```sh
109
+ ```bash
110
+ brunch activate
111
+ ```
112
+
113
+ To rebuild and recreate its containers explicitly:
114
+
115
+ ```bash
116
+ brunch restart
117
+ ```
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
+
122
+ Compose builds use files from the live worktree, including uncommitted changes.
123
+
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.
125
+
126
+ ## Parallel worktrees
127
+
128
+ Additional worktrees run independently on different host ports.
129
+
130
+ Create them with `git-hooks-ext`:
131
+
132
+ ```bash
107
133
  ghe worktree add -b feature-a ../feature-a
108
134
  ghe worktree add -b feature-b ../feature-b
135
+ ```
136
+
137
+ Then:
138
+
139
+ ```bash
109
140
  cd ../feature-a
110
- brunch port # port for this worktree
111
- brunch ports # ports for all worktrees
112
- ```
113
-
114
- Each worktree runs independently on a different host port, so `feature-a` and
115
- `feature-b` can be used at the same time. Run `brunch status` or `brunch port`
116
- inside each worktree to find its address. Switching branches inside one
117
- worktree does not stop the others.
118
-
119
- `ghe worktree add`, `move`, and `remove` emit lifecycle events. Git's
120
- `post-checkout` hook handles branch changes inside any worktree, including the
121
- main checkout. If you use plain `git worktree add`, run `brunch activate` in the
122
- new worktree; after a plain move or removal, run `brunch cleanup` from a
123
- remaining worktree.
124
-
125
- The source directory is never deleted by Brunch. It keeps a separate control
126
- copy under `.git/brunch/controls` so it can shut down Compose or run a custom
127
- `remove` command after a worktree has been removed. Switching branches within
128
- one worktree keeps the old branch's environment stopped, with its own named
129
- volumes. Removing the worktree removes all of its Brunch environments. The
130
- `local_process` manager also writes its log to the control directory, keeping
131
- the worktree clean. Custom `remove` commands that depend on project files must
132
- be committed, because the control copy is based on the worktree's last commit.
133
-
134
- Docker builds read uncommitted files from the live worktree. To see edits in
135
- an already running container without rebuilding, configure a source bind
136
- mount or another reload mechanism in the project's Compose file.
137
- `brunch restart` rebuilds the current environment.
138
-
139
- Before upgrading from an older branch-only configuration, stop its running
140
- environment and clean up its legacy state. Brunch refuses to reinterpret an
141
- old non-empty branch state as worktree state, preventing orphaned containers.
142
-
143
- ### Custom manager commands
144
-
145
- Use the `command` manager when the project is started by another tool. Brunch
146
- runs commands from the live worktree with these variables: `BRUNCH_REF`,
147
- `BRUNCH_PORT`, `BRUNCH_PROJECT`, and `BRUNCH_SNAPSHOT`. The last variable points
148
- to the live worktree for compatibility with manager adapters.
149
141
 
150
- ```yaml
151
- manager: command
152
- commands:
153
- create: bin/environment create
154
- start: bin/environment start
155
- stop: bin/environment stop
156
- remove: bin/environment remove
142
+ brunch port
143
+ brunch ports
144
+ ```
145
+
146
+ `brunch port` prints the current worktree's port.
147
+
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.
151
+
152
+ Switching branches inside one worktree does not affect environments running in other worktrees.
153
+
154
+ If you create a worktree with plain Git:
155
+
156
+ ```bash
157
+ git worktree add -b feature-c ../feature-c
158
+ ```
159
+
160
+ activate Brunch manually inside it:
161
+
162
+ ```bash
163
+ cd ../feature-c
164
+ brunch activate
157
165
  ```
158
166
 
159
- `create` provisions manager-owned resources; it is optional for the `command`
160
- manager. `start` must return after
161
- it has launched the environment (for example, by delegating to a daemon or
162
- supervisor). `stop` is used when switching branches; `remove` is used when
163
- a worktree is deleted and should remove any manager-owned persistent
164
- resources. This makes the adapter suitable for Podman, Kubernetes wrappers,
165
- Foreman/Overmind wrappers, or a project-specific script.
167
+ After moving or removing worktrees with plain Git, run:
168
+
169
+ ```bash
170
+ brunch cleanup
171
+ ```
166
172
 
167
- Optional `status`, `health`, and `logs` commands power the corresponding Brunch
168
- commands. A successful `health` command reports a healthy environment.
173
+ Brunch never deletes the worktree source directory.
174
+
175
+ ## Managers
176
+
177
+ ### Docker Compose
178
+
179
+ Docker Compose is the default manager:
180
+
181
+ ```yaml
182
+ compose_file: compose.yaml
183
+ ```
169
184
 
170
185
  ### Podman Compose
171
186
 
172
- Podman Compose uses the same Compose file contract as Docker Compose:
187
+ Podman Compose uses the same Compose file contract:
173
188
 
174
189
  ```yaml
175
190
  manager: podman_compose
@@ -178,66 +193,170 @@ compose_file: compose.yaml
178
193
 
179
194
  ### Local process
180
195
 
181
- Use `local_process` for a development command such as `bin/dev`.
182
- Brunch starts it in a dedicated process group, records its PID, stops that
183
- group on a branch switch, and saves its output under `.git/brunch/controls`.
196
+ Use `local_process` for a development command such as `bin/dev`:
184
197
 
185
198
  ```yaml
186
199
  manager: local_process
187
200
  command: bin/dev
188
201
  ```
189
202
 
190
- ## Lifecycle
203
+ Brunch starts and stops the process together with the branch environment and stores its output under `.git/brunch/controls`.
191
204
 
192
- - A branch checkout stops the previous environment in that worktree, then
193
- creates and starts the new one on the same port.
194
- - Each worktree keeps its own current environment and port. Other worktrees
195
- continue running during branch switches.
196
- - Checking out a remote branch into a new local tracking branch works through
197
- the same `post-checkout` hook.
198
- - `brunch cleanup` removes environments belonging to deleted worktrees.
205
+ ### Custom commands
199
206
 
200
- Git 2.39 cannot reliably report a normal `git branch -d` operation to a hook.
201
- Stopped branch environments remain until their worktree is removed.
207
+ Use the `command` manager to integrate Brunch with project-specific tooling:
202
208
 
203
- ## Operations
209
+ ```yaml
210
+ manager: command
211
+ commands:
212
+ create: bin/environment create
213
+ start: bin/environment start
214
+ stop: bin/environment stop
215
+ remove: bin/environment remove
216
+ ```
217
+
218
+ Brunch runs these commands from the live worktree with:
219
+
220
+ ```text
221
+ BRUNCH_REF
222
+ BRUNCH_PORT
223
+ BRUNCH_PROJECT
224
+ BRUNCH_SNAPSHOT
225
+ ```
226
+
227
+ `BRUNCH_SNAPSHOT` points to the live worktree for compatibility with manager adapters.
228
+
229
+ `create` is optional.
230
+
231
+ `start` must return after launching the environment.
232
+
233
+ `stop` is called when switching away from the active branch.
234
+
235
+ `remove` is called when the corresponding worktree environment is deleted and should remove manager-owned persistent resources.
236
+
237
+ Optional commands:
238
+
239
+ ```yaml
240
+ commands:
241
+ status: bin/environment status
242
+ health: bin/environment health
243
+ logs: bin/environment logs
244
+ ```
245
+
246
+ These power the corresponding Brunch operations.
204
247
 
205
- ```sh
206
- brunch status # current worktree environment, manager status and port
207
- brunch ports # worktree-to-port list; current worktree is marked in green
208
- brunch port # only the current worktree's port, suitable for scripts
209
- brunch stop # stop the active environment without deleting it
210
- brunch restart # recreate and start the active environment
211
- brunch logs # show the last 100 logs (or run commands.logs)
248
+ ## Worktree lifecycle
249
+
250
+ A branch checkout stops the previous environment in that worktree and starts the new one on the same host port.
251
+
252
+ Other worktrees continue running.
253
+
254
+ Removing a worktree removes its Brunch environments. Brunch keeps the information needed to shut down manager resources under `.git/brunch/controls`, so cleanup can still run after the worktree itself is gone.
255
+
256
+ If a custom `remove` command depends on project files, those files must be committed because cleanup after worktree removal uses the last committed state.
257
+
258
+ `brunch cleanup` removes environments belonging to worktrees that no longer exist.
259
+
260
+ Git does not expose every branch deletion workflow reliably to hooks, so stopped branch environments may remain until their worktree is removed.
261
+
262
+ ## Commands
263
+
264
+ ```bash
265
+ brunch install
266
+ ```
267
+
268
+ Install Brunch hooks for the repository.
269
+
270
+ ```bash
271
+ brunch activate
272
+ ```
273
+
274
+ Start the environment for the current branch.
275
+
276
+ ```bash
277
+ brunch status
278
+ ```
279
+
280
+ Show the current environment, manager status, and port.
281
+
282
+ ```bash
283
+ brunch port
284
+ ```
285
+
286
+ Print the current worktree's port.
287
+
288
+ ```bash
289
+ brunch ports
290
+ ```
291
+
292
+ List current and stopped branch environments grouped by worktree.
293
+
294
+ ```bash
295
+ brunch stop
296
+ ```
297
+
298
+ Stop the active environment without removing it.
299
+
300
+ ```bash
301
+ brunch restart
302
+ ```
303
+
304
+ Recreate and start the active environment.
305
+
306
+ ```bash
307
+ brunch logs
212
308
  brunch logs --follow
213
- brunch run -- bin/rails console # runs on the host in the live worktree, not in a container
214
- brunch doctor # verify Git, installed hooks, configuration, manager and ports
215
- brunch cleanup # delete environments for removed worktrees
216
309
  ```
217
310
 
218
- Brunch coordinates commands with locks under `.git/brunch`, writes `state.json`
219
- atomically, and retries interrupted environment setup on the next activation.
311
+ Show environment logs.
312
+
313
+ ```bash
314
+ brunch run -- bin/rails console
315
+ ```
316
+
317
+ Run a command on the host from the live worktree.
318
+
319
+ ```bash
320
+ brunch doctor
321
+ ```
322
+
323
+ Check Git, installed hooks, configuration, manager availability, and ports.
324
+
325
+ ```bash
326
+ brunch cleanup
327
+ ```
328
+
329
+ Remove environments belonging to deleted worktrees.
330
+
331
+ ## Upgrading from older configurations
332
+
333
+ Before upgrading from an older branch-only configuration, stop its running environment and clean up its legacy state.
334
+
335
+ Brunch will not reinterpret an existing non-empty branch-only state as worktree state.
220
336
 
221
337
  ## Development
222
338
 
223
- ```sh
339
+ ```bash
224
340
  bundle install
225
341
  bin/install-pre-commit
226
342
  bundle exec rake quality
227
343
  gem build brunch.gemspec
228
344
  ```
229
345
 
230
- Container E2E tests use real temporary Git repositories, Compose containers,
231
- and HTTP requests. Run them with Docker or Podman:
346
+ Run container integration tests with Docker Compose:
232
347
 
233
- ```sh
348
+ ```bash
234
349
  BRUNCH_INTEGRATION_MANAGER=docker_compose bundle exec rake test
350
+ ```
351
+
352
+ Or Podman Compose:
353
+
354
+ ```bash
235
355
  BRUNCH_INTEGRATION_MANAGER=podman_compose bundle exec rake test
236
356
  ```
237
357
 
238
- CI runs both managers on pushes and pull requests. Without the environment
239
- variable, container tests are skipped by the local quality check.
358
+ Without `BRUNCH_INTEGRATION_MANAGER`, container integration tests are skipped by the local quality check.
359
+
360
+ The pre-commit hook runs RuboCop with automatic corrections, Reek, and the full test suite. SimpleCov requires 100% line and branch coverage for `lib/**/*.rb`.
240
361
 
241
- The pre-commit hook runs RuboCop with automatic corrections, Reek, and the full
242
- test suite. SimpleCov requires 100% line and branch coverage of `lib/**/*.rb`. When
243
- RuboCop changes a file, review and stage the correction before committing.
362
+ If RuboCop modifies a file, review and stage the changes before committing.
@@ -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.0"
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.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Ciemborowicz