Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "local-dev-proxy"
version = "0.0.16"
version = "0.0.17"
edition = "2024"
description = "Local development process orchestration with a built-in reverse proxy"
authors = ["Andrew Chen <hello@andrewtheguy.com>"]
Expand Down
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ the active file (`.log.1` is newest). This bounds each log to about 60 MiB. Rota
renames completed files rather than truncating a file while it is being written; once
the retention limit is reached, only the oldest backup is removed.

Edit the configuration in the manager window (**View Config → Stop All & Edit Config**,
then **Validate**, **Save**, or **Start All**), or edit the file by hand while the
application is stopped, check it with `local-dev-proxy --check-config`, and start the
application again.
Edit the configuration in the manager window (**Edit Config**, then **Validate**,
**Save**, or **Apply**) while everything keeps running, or edit the file by hand, check
it with `local-dev-proxy --check-config`, and apply it from the editor (or restart the
application).

## Usage

Expand All @@ -121,11 +121,14 @@ service's combined stdout/stderr goes to `logs/<service>.log`.
The manager window has three tabs:

- **Services** — each service's status, PID, restart count, and last exit code. Select a
row to start, stop, or restart it; double-click a row to open its log. **View Config**
shows the running configuration; **Stop All & Edit Config** stops everything and opens
the editor, where **Start All** validates, saves, and launches the edited file. If the
configuration fails to start, the editor opens with the error. Both views highlight
the TOML syntax.
row to start, stop, or restart it; double-click a row to open its log. **Edit Config**
opens the configuration editor (with TOML syntax highlighting) without stopping
anything; **Cancel** discards unsaved edits and goes back to the service list. **Save**
only writes the file; **Apply** validates and saves it, then restarts the proxy and
every service only if the configuration differs from the running one (comment and
formatting changes do not count). While stopped the button is **Start All** instead. If
the configuration fails to start, everything stays stopped and the editor opens with
the error.
- **Logs** — the tail of a service's log, with a line count and **Follow** to keep it
updating.
- **Routes** — every service's hosts and targets. Click a URL to open it in the browser.
Expand All @@ -140,11 +143,11 @@ absent or disabled:
| Ctrl+Up / Ctrl+Down | Select the previous / next service |
| Ctrl+Shift+S / Ctrl+Shift+X / Ctrl+Shift+R | Start / Stop / Restart the selected service |
| Ctrl+L | Open the selected service's log |
| Ctrl+E | View Config, or back to the service list |
| Ctrl+Shift+E | Stop All & Edit Config |
| Ctrl+E | Edit Config |
| Escape | Cancel: discard unsaved edits and go back to the service list |
| Ctrl+K / Ctrl+S | Validate / Save the configuration being edited |
| Ctrl+Enter | Start All (validate, save, and launch the edited configuration) |
| Ctrl+R | Reload what the current tab shows: the editor from disk, the log, or the routes |
| Ctrl+Enter | Apply (validate, save, and restart if it changed), or Start All while stopped |
| Ctrl+R | Reload what the current tab shows: the log or the routes |
| Ctrl+Q | Quit |

Only one instance runs per profile. Launching it again while it is running brings the
Expand Down Expand Up @@ -303,9 +306,9 @@ disagree, the workflow is right and the script is stale.

`ci/unix/e2e.sh` launches the real binary against a throwaway profile, on the headless
labwc session of the development host, and drives the manager window through its
keyboard shortcuts: select, stop, start and restart a service, open its log, the routes
and the read-only configuration, stop everything to edit, save, validate, start again,
and quit. After each step it checks the proxy's answer over HTTP and the text on screen,
keyboard shortcuts: select, stop, start and restart a service, open its log and the
routes, edit the configuration while it keeps running, save, validate, apply it unchanged
(nothing restarts) and changed (everything restarts), and quit. After each step it checks the proxy's answer over HTTP and the text on screen,
read from a screenshot with tesseract. `ci/unix/ci.sh` runs it on a Linux host where the
session is up and skips it elsewhere; `ci/unix/e2e.sh --available` says which. It needs
the labwc session's `DISPLAY` in the systemd user environment (or
Expand Down
38 changes: 27 additions & 11 deletions ci/unix/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
#
# The scenario launches the manager against a throwaway profile whose one
# service is a busybox httpd, then walks every keyboard shortcut: select the
# service, stop, start and restart it, open its log, the routes and the
# read-only configuration, stop everything to edit, save, validate, start
# again, and quit. After each step it checks what a user would check: the
# service, stop, start and restart it, open its log and the routes, edit the
# configuration while it keeps running, cancel, edit again, save, validate,
# apply it unchanged (nothing restarts), apply a change (everything
# restarts), and quit. After each step it checks what a user would check: the
# proxy's answer over HTTP, and the text on screen (a screenshot of the
# session, read back with tesseract). tmp/e2e/ keeps the numbered screenshots
# and the app's logs, for looking at after a failure.
Expand Down Expand Up @@ -205,21 +206,36 @@ key ctrl+3
# The target column; tesseract skips the blue URL text.
expect_screen routes "localhost:$web_port"
key ctrl+1
key ctrl+e
expect_screen config 'Viewing configuration'

# Stop everything and edit, then start it all again.
key ctrl+shift+e
expect_screen editing 'Editing configuration'
expect_http 'proxy down while editing' web.localhost 000
# Edit while everything keeps running; applying it unchanged restarts nothing.
key ctrl+e
expect_screen editing 'services keep running'
expect_http 'proxy up while editing' web.localhost 200
key Escape
expect_screen cancelled 'Edit Config'
key ctrl+e
expect_screen editing-again 'services keep running'
key ctrl+s
expect_screen saved '\bsaved\b'
key ctrl+k
# Word-bounded: the banner says "validates".
expect_screen valid '\bvalid\b'
key ctrl+Return
expect_screen restarted-all 'saved.{1,3}started'
expect_http 'started again' web.localhost 200
expect_screen unchanged 'no changes'
expect_http 'still up after an unchanged apply' web.localhost 200
grep -c 'web starting on' "$profile/logs/web.log" | grep -qx 3 || fail 'an unchanged apply restarted the service'

# A changed configuration (written to disk; the editor loads it) restarts
# everything with it.
new_web_port=$(free_port)
sed -i "s/WEB_PORT = \"$web_port\"/WEB_PORT = \"$new_web_port\"/" "$profile/services.toml"
key ctrl+e
expect_screen edited "$new_web_port"
key ctrl+Return
expect_screen restarted-all 'saved.{1,3}restarted'
expect_http 'restarted with the change' web.localhost 200
grep -q "web starting on $new_web_port" "$profile/logs/web.log" || fail 'the service did not restart on the new port'
web_port=$new_web_port

# Quit takes the service down with it.
key ctrl+q
Expand Down
Loading
Loading