wslc-wip 1.1.3 → 1.1.4
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/README.md +59 -535
- data/lib/wip/initializer.rb +2 -0
- data/lib/wip/version.rb +1 -1
- metadata +4 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 585bcc92d8ab78eb38c134e779738c6eb527dd57b8aad87bbfae18a724a10974
|
|
4
|
+
data.tar.gz: 908afba4af5470c777896379a143a6759ab08ef453f6d8baf727e22ff4a8adf2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c01879ea531294531b0283b53a7fdfe01586a8c9c17dbd83814ad92c11d915cecd5f141a0ffd6f94f96dd633e0e63657f15a10ec4f1e372cc53ea0207a8b22be
|
|
7
|
+
data.tar.gz: e3cb38ab627b56487b8965f9107c03f7081fd24defb2a731415af8e9533cd51e5af1eea5da3f0075d854371cbb77ed6e1b75c8843737df4528e806965bfc5137
|
data/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<img src="docs/logo.png" alt="wip logo" width="120" align="left">
|
|
2
|
+
|
|
1
3
|
# wip
|
|
2
4
|
|
|
3
5
|
[](https://github.com/slidict/wip/actions/workflows/test.yml)
|
|
@@ -5,7 +7,7 @@
|
|
|
5
7
|
[](LICENSE)
|
|
6
8
|
[](wslc-wip.gemspec)
|
|
7
9
|
|
|
8
|
-
Homepage: https://wslc-wip.slidict.com/
|
|
10
|
+
Homepage: https://wslc-wip.slidict.com/ · **[Full documentation: wip Wiki](https://github.com/slidict/wip/wiki)**
|
|
9
11
|
|
|
10
12
|
`wip` is a Ruby-built OSS CLI wrapper that brings a [`dip`](https://github.com/bibendi/dip)-like
|
|
11
13
|
workflow to Microsoft WSLC. It collects a project's container, image, environment variables, and
|
|
@@ -16,25 +18,19 @@ commands into a single `wip.yml`, and forwards them to `wslc.exe` / `wslc` as sa
|
|
|
16
18
|
|
|
17
19
|
> **Status:** early release. Expect to track WSLC's own interface as it evolves.
|
|
18
20
|
|
|
21
|
+
This README covers the fastest path to a running `wip.yml`. For everything else — every config
|
|
22
|
+
key, every command's flags, guides, and troubleshooting — see the **[wip Wiki](https://github.com/slidict/wip/wiki)**.
|
|
23
|
+
|
|
19
24
|
## Contents
|
|
20
25
|
|
|
21
26
|
- [Which mode should you use?](#which-mode-should-you-use)
|
|
22
27
|
- [Requirements & installation](#requirements--installation)
|
|
23
28
|
- [Quick start](#quick-start)
|
|
24
29
|
- [Configuration](#configuration)
|
|
25
|
-
- [Container mode](#container-mode)
|
|
26
|
-
- [Compose mode](#compose-mode)
|
|
27
|
-
- [Compose mode (native)](#compose-mode-native)
|
|
28
|
-
- [.env](#env)
|
|
29
|
-
- [.dockerignore](#dockerignore)
|
|
30
|
-
- [Source sync](#source-sync)
|
|
31
30
|
- [Commands](#commands)
|
|
32
|
-
- [doctor](#doctor)
|
|
33
31
|
- [Common errors](#common-errors)
|
|
34
|
-
- [FAQ](#faq)
|
|
35
32
|
- [Development](#development)
|
|
36
33
|
- [Contributing](#contributing)
|
|
37
|
-
- [Roadmap](#roadmap)
|
|
38
34
|
- [License](#license)
|
|
39
35
|
|
|
40
36
|
## Which mode should you use?
|
|
@@ -43,12 +39,14 @@ commands into a single `wip.yml`, and forwards them to `wslc.exe` / `wslc` as sa
|
|
|
43
39
|
|
|
44
40
|
| Situation | Use |
|
|
45
41
|
|---|---|
|
|
46
|
-
| No `compose.yml` — wip manages containers directly |
|
|
47
|
-
| Have `compose.yml`, don't want to install a third-party tool |
|
|
48
|
-
| Have `compose.yml` and already use/prefer a third-party compose-for-`wslc` tool |
|
|
42
|
+
| No `compose.yml` — wip manages containers directly | `mode: container` (default) |
|
|
43
|
+
| Have `compose.yml`, don't want to install a third-party tool | `mode: compose-native` |
|
|
44
|
+
| Have `compose.yml` and already use/prefer a third-party compose-for-`wslc` tool | `mode: compose` |
|
|
49
45
|
|
|
50
|
-
`wip init` picks `compose-native` automatically when it finds a `compose.yml
|
|
51
|
-
next to it, and `container` otherwise — see
|
|
46
|
+
`wip init` picks `compose-native` automatically when it finds a `compose.yml`, `compose.yaml`,
|
|
47
|
+
`docker-compose.yml`, or `docker-compose.yaml` next to it, and `container` otherwise — see
|
|
48
|
+
[Commands](#commands). For the full breakdown and trade-offs, see
|
|
49
|
+
[Choosing a Mode](https://github.com/slidict/wip/wiki/Choosing-a-Mode) on the wiki.
|
|
52
50
|
|
|
53
51
|
## Requirements & installation
|
|
54
52
|
|
|
@@ -63,7 +61,8 @@ From source: `bundle install && bundle exec exe/wip version`.
|
|
|
63
61
|
## Quick start
|
|
64
62
|
|
|
65
63
|
This walks through `mode: container` (the default). Already have a `compose.yml`? See
|
|
66
|
-
[Which mode should you use?](#which-mode-should-you-use) first
|
|
64
|
+
[Which mode should you use?](#which-mode-should-you-use) first, or read the wiki's
|
|
65
|
+
[Getting Started](https://github.com/slidict/wip/wiki/Getting-Started) guide.
|
|
67
66
|
|
|
68
67
|
```bash
|
|
69
68
|
gem install wslc-wip
|
|
@@ -80,8 +79,6 @@ wip rails console
|
|
|
80
79
|
Put a `wip.yml` in your project root. Running from a subdirectory walks up to find it, or pass
|
|
81
80
|
`--config PATH` to point at one explicitly.
|
|
82
81
|
|
|
83
|
-
### Container mode
|
|
84
|
-
|
|
85
82
|
```yaml
|
|
86
83
|
version: 1
|
|
87
84
|
mode: container # default
|
|
@@ -148,495 +145,67 @@ sync: # optional; mirror the source into a named volume instead of bind-mounting
|
|
|
148
145
|
|
|
149
146
|
`env` values are stringified. `wip config` masks any key matching token, password, secret,
|
|
150
147
|
credential, or auth. Keep real secrets out of the config file and in your runtime environment
|
|
151
|
-
instead.
|
|
148
|
+
instead — see [Secret Masking](https://github.com/slidict/wip/wiki/Secret-Masking).
|
|
152
149
|
|
|
153
150
|
`interaction:` can also be spelled `commands:` — the same block under a different name, e.g. for
|
|
154
|
-
projects that already use `commands:`.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
[
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
What sets the primary entry apart is operational, not structural: `wip up` brings up every other
|
|
170
|
-
entry by name first (creating `network:` beforehand if it doesn't exist and set), then boots or
|
|
171
|
-
starts the primary one — so `bin/rails c` (or anything else run inside it) can reach
|
|
172
|
-
`development.mysql`/`redis`/etc. by their dependency name, the same way Compose's service names
|
|
173
|
-
resolve. `wip down` tears the primary container and all sidecars down (the network itself is left
|
|
174
|
-
in place). Only the primary container is a target for `exec`/`run`/`build`/`interaction:` — sidecars
|
|
175
|
-
are only ever started and stopped, matching Compose's own service-vs-you-exec-into-one-of-them
|
|
176
|
-
split.
|
|
177
|
-
|
|
178
|
-
#### Restarting exited dependencies (`wip up --watch`)
|
|
179
|
-
|
|
180
|
-
Real Compose auto-restarts a container tagged `restart: always`/`unless-stopped`/`on-failure` when
|
|
181
|
-
it exits. `wslc` has no such policy, and no push-based "container exited" notification for `wip` to
|
|
182
|
-
hook into, so the closest approximation is polling: `wip up --watch` brings everything up the same
|
|
183
|
-
way `wip up -d` does, then keeps checking (`--interval SECONDS`, default 5) whether any
|
|
184
|
-
dependency — the primary container included — has exited, restarting the ones whose `restart:`
|
|
185
|
-
allows it.
|
|
186
|
-
|
|
187
|
-
```console
|
|
188
|
-
$ wip up --watch
|
|
189
|
-
wip: watching app, mysql for exited restart: containers every 5s (running detached; Ctrl-C to stop)
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
- `restart:` accepts the same values Compose does — `no` (the default), `always`, `unless-stopped`,
|
|
193
|
-
`on-failure`, optionally with a `:MAX_RETRIES` suffix. `wip up --watch` treats the three
|
|
194
|
-
restarting values identically: it restarts on any exited container regardless of exit code,
|
|
195
|
-
unlike real `on-failure`, which skips a clean (zero) exit — reading an exit code needs a heavier
|
|
196
|
-
call this polling loop doesn't make.
|
|
197
|
-
- This is a foreground loop, not a background daemon or service — the project intentionally has
|
|
198
|
-
neither (see [Roadmap](#roadmap)). Keep the terminal it's running in open, the same as
|
|
199
|
-
`wip sync --watch`; Ctrl-C (or closing the terminal) stops the supervision.
|
|
200
|
-
- `--watch` implies `-d`: it can't attach a TTY to the primary container and poll in a loop on the
|
|
201
|
-
same thread, so the primary container always runs detached under `--watch`, whether or not you
|
|
202
|
-
also passed `-d`.
|
|
203
|
-
- Not available under `mode: compose` — wip never parses a service list in that mode, so there's
|
|
204
|
-
nothing for it to poll; use whatever restart support your external compose-for-`wslc` tool offers.
|
|
205
|
-
- It's status-based, not event-based: each tick checks whether a dependency is currently exited, not
|
|
206
|
-
whether it *just* exited. It can't tell "crashed on its own" apart from "you ran `wip stop`/
|
|
207
|
-
`wip down` in another terminal" — Ctrl-C the `--watch` loop first, or it may race and restart
|
|
208
|
-
what you just stopped.
|
|
209
|
-
- Re-running `wip up -d --watch` against an already-running stack is safe: an already-running
|
|
210
|
-
container's `start` is a no-op, the same as it is for plain `wip up`.
|
|
211
|
-
- The exit-detection reads `wslc list --all --format json`'s `State` field as a raw integer, per
|
|
212
|
-
`WslcContainerState` ([wsl.dev](https://wsl.dev/api-reference/c/enumerations/wslccontainerstate/)):
|
|
213
|
-
`0` invalid, `1` created, `2` running, `3` exited, `4` deleted. Unlike Docker, there's no separate
|
|
214
|
-
`dead` state — a `deleted` container is gone and needs `wip up` (not `--watch`) to recreate it.
|
|
215
|
-
If `--watch` never restarts anything you believe really exited, run `wip up --watch --debug` and
|
|
216
|
-
check the logged `list` entry against this enum.
|
|
217
|
-
|
|
218
|
-
### Compose mode
|
|
219
|
-
|
|
220
|
-
If your project already has a real `compose.yml`, don't duplicate it in `dependencies:` — point
|
|
221
|
-
`wip` at it instead:
|
|
222
|
-
|
|
223
|
-
```yaml
|
|
224
|
-
version: 1
|
|
225
|
-
mode: compose # required to enable compose mode; a compose: block with no mode: compose is an error
|
|
226
|
-
compose:
|
|
227
|
-
service: app # required: which compose service wip run/exec/NAME target
|
|
228
|
-
command: wslc-compose # required: the compose-for-wslc binary/path you have installed
|
|
229
|
-
file: compose.yml # optional; auto-detected next to wip.yml otherwise
|
|
230
|
-
project: myapp # optional; omitted lets the compose tool pick its own default
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
`compose:` is mutually exclusive with `dependencies:`/`network` — pick one orchestration path per
|
|
234
|
-
project. In compose mode, `wip` becomes a thin bridge to an external compose-for-`wslc` CLI rather
|
|
235
|
-
than reimplementing Compose itself.
|
|
236
|
-
|
|
237
|
-
`wslc` itself has no native Compose support yet (tracked upstream in
|
|
238
|
-
[microsoft/WSL#40948](https://github.com/microsoft/WSL/issues/40948)), and until it does,
|
|
239
|
-
independent third-party tools fill the gap — for example
|
|
240
|
-
[bacarndiaye/wslc-compose](https://github.com/bacarndiaye/wslc-compose) (Python) and
|
|
241
|
-
[inuyume/wslc-compose](https://github.com/inuyume/wslc-compose) (Go), among others. `wslc` is new
|
|
242
|
-
and still evolving, so expect more of these to show up (and existing ones to change) over time.
|
|
243
|
-
`wip` deliberately doesn't pick a winner or default to any of them (unlike `wslc.command`, which
|
|
244
|
-
defaults to `auto` and searches for `wslc.exe`/`wslc`): `compose.command` is required and treats
|
|
245
|
-
every implementation equally — set it to whichever binary name or absolute path you've installed.
|
|
246
|
-
Whichever one you use needs to understand `-f FILE [-p PROJECT] up|down|exec|logs`, the subset of
|
|
247
|
-
the Compose CLI vocabulary `wip` drives. `wip doctor` reports whether the configured command is
|
|
248
|
-
found, its version, and which compose file `wip` resolved.
|
|
249
|
-
|
|
250
|
-
- `wip up`/`wip down` delegate straight to `<compose command> up -d`/`down`.
|
|
251
|
-
- `wip exec`/`wip NAME` (custom `interaction:`) run inside `compose.service`.
|
|
252
|
-
- `wip shell` also goes through the bridge: unless `interaction.shell` is defined in `wip.yml`, it
|
|
253
|
-
`exec`s `bash` against `compose.service`, falling back to `sh`.
|
|
254
|
-
- `wip logs [-f] [SERVICE...]` is only available in compose mode.
|
|
255
|
-
- `wip run` has no ephemeral-container equivalent in this exec-only vocabulary, so it falls back
|
|
256
|
-
to `exec` against the already-running `compose.service` (wip warns when this happens).
|
|
257
|
-
- `interaction:` entries with `type: run`/`type: build` aren't supported in compose mode — use your
|
|
258
|
-
compose tool's own `build`/`up --build` directly; compose owns builds for its own services.
|
|
259
|
-
|
|
260
|
-
### Compose mode (native)
|
|
261
|
-
|
|
262
|
-
Don't want to install a third-party compose-for-`wslc` tool at all? `mode: compose-native` parses
|
|
263
|
-
`compose.yml` itself and drives `wslc` directly, the same way `mode: container` +`dependencies:`
|
|
264
|
-
already does — no external binary, and `wip run` gets a real ephemeral `wslc run --rm` instead of
|
|
265
|
-
the `exec` fallback above:
|
|
266
|
-
|
|
267
|
-
```yaml
|
|
268
|
-
version: 1
|
|
269
|
-
mode: compose-native
|
|
270
|
-
|
|
271
|
-
compose:
|
|
272
|
-
service: app # required: which compose service wip run/exec/NAME target
|
|
273
|
-
file: compose.yml # optional; auto-detected next to wip.yml otherwise
|
|
274
|
-
project: myapp # optional; also names wip's own project network (defaults to the wip.yml
|
|
275
|
-
# directory's name) so services can reach each other by name
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
There's no `compose.command` here (no external binary to name), and no top-level `container:` —
|
|
279
|
-
`compose.service` already names it.
|
|
280
|
-
|
|
281
|
-
This is explicitly a stopgap for as long as `wslc` itself has no native Compose support (tracked
|
|
282
|
-
upstream in [microsoft/WSL#40948](https://github.com/microsoft/WSL/issues/40948)) and third-party
|
|
283
|
-
compose-for-`wslc` tools stay incomplete. It only understands a minimal subset of the Compose spec.
|
|
284
|
-
Within `services.<name>:`, anything outside that subset is a load-time `ConfigError` naming the
|
|
285
|
-
offending key, rather than silently ignored — but everything *outside* `services:` at the document's
|
|
286
|
-
top level (`networks:`, `volumes:`, `configs:`, `secrets:`, ...) is the one exception: it's read by
|
|
287
|
-
real Compose tools, not by `wip`, so `wip` silently ignores it rather than rejecting an otherwise
|
|
288
|
-
valid compose.yml over sections it doesn't need to look at:
|
|
289
|
-
|
|
290
|
-
- Per service: `image`, `build` (string or `{context:, dockerfile:, args:, shadow_context:}`;
|
|
291
|
-
`context` is resolved relative to `compose.yml`, not wherever `wip` is invoked from; `dockerfile`
|
|
292
|
-
stays relative to `context` itself — see [.dockerignore](#dockerignore) for what `shadow_context`
|
|
293
|
-
does), `command` (shell or exec form), `environment`
|
|
294
|
-
(mapping or `KEY=VALUE` array — a mapping value must not be null; host environment pass-through
|
|
295
|
-
isn't supported), `ports`/`volumes` (short syntax only — `"host:container"` strings, not
|
|
296
|
-
long-syntax mappings), `working_dir`, `user`, `restart` (stored as-is; `no` is the default —
|
|
297
|
-
`wip up --watch` is what actually acts on it, see
|
|
298
|
-
[Restarting exited dependencies](#restarting-exited-dependencies-wip-up---watch)), `depends_on`
|
|
299
|
-
(ordering only — a `condition:` other than `service_started` is rejected, since there's no
|
|
300
|
-
health-check support). `tty`, `stdin_open`, and `networks` are accepted but silently ignored:
|
|
301
|
-
TTY/stdin allocation is already decided per invocation (see "TTY allocation" below), not fixed
|
|
302
|
-
per service, and every service already shares the one project network `compose.project` sets up.
|
|
303
|
-
- `wip logs` takes at most one `SERVICE` (defaulting to `compose.service`) — `wslc logs`, like
|
|
304
|
-
`docker logs`, follows a single container, unlike a real compose tool's multi-service view.
|
|
305
|
-
- `sync:` behaves exactly like `mode: container`'s (falls back to the primary service's own image,
|
|
306
|
-
defaults to `sync.mode: exec`) — none of the external bridge's `sync.image`/`sync.build`
|
|
307
|
-
requirement applies, since wip itself boots every container here.
|
|
308
|
-
|
|
309
|
-
### .env
|
|
310
|
-
|
|
311
|
-
Like `docker compose`, `wip` automatically loads a `.env` file next to `wip.yml` (one `KEY=VALUE`
|
|
312
|
-
per line; `#` comments, blank lines, `export` prefixes, and quoted values are all supported) and
|
|
313
|
-
passes its keys through as container environment variables on `build`, `up`, `run`, `exec`, and
|
|
314
|
-
custom commands. `.env` only fills in keys that aren't already set by the primary container's
|
|
315
|
-
`env` or a command/dependency's own `env` — those always win on conflict. Pass `--env-file PATH`
|
|
316
|
-
to load a different file instead.
|
|
317
|
-
|
|
318
|
-
### .dockerignore
|
|
319
|
-
|
|
320
|
-
`wip build` reads `.dockerignore` from the build context and excludes anything it matches before
|
|
321
|
-
handing the context to `wslc build`, since `wslc` sends the context as-is otherwise. Set
|
|
322
|
-
`commands.build.shadow_context` in `wip.yml` (or `build.shadow_context` on a compose-native
|
|
323
|
-
`build:` service in `compose.yml`) to a directory on the Windows filesystem to enable a persistent
|
|
324
|
-
shadow context for projects outside `/mnt/<drive>`. The first build copies every included file;
|
|
325
|
-
later builds only copy added or changed files and remove deleted or newly ignored files. Without
|
|
326
|
-
this setting the optimization is disabled, and it only applies under WSL2 — on WSL1 (or anywhere
|
|
327
|
-
else) the context is handed to `wslc build` directly. Projects already on `/mnt/c` (or another
|
|
328
|
-
mounted Windows drive) also continue to build directly even when the setting is present. The path
|
|
329
|
-
must live outside the build context itself, or `wip build`/`wip up` refuses it.
|
|
330
|
-
|
|
331
|
-
### Source sync
|
|
332
|
-
|
|
333
|
-
Bind-mounting the app directory (`.:/app`) is what usually makes a container boot crawl under
|
|
334
|
-
wslc — see [Slow boot when the app directory is
|
|
335
|
-
bind-mounted](#slow-boot-when-the-app-directory-is-bind-mounted) for why. A `sync:` block hands
|
|
336
|
-
that problem to `wip`: the source is mounted read-only, the app runs off a named volume, and wip
|
|
337
|
-
mirrors one into the other with `rsync`.
|
|
338
|
-
|
|
339
|
-
`wip up`'s pre-boot mirror always uses a throwaway container (the primary one isn't running yet),
|
|
340
|
-
so `sync.image`/`sync.build` apply there regardless of `sync.mode` — falling back to the primary
|
|
341
|
-
container's own image if neither is set under `mode: container`/`compose-native` (both have a
|
|
342
|
-
`dependencies:` entry to borrow it from); `mode: compose` has no such entry, so one of
|
|
343
|
-
`sync.image`/`sync.build` is required there. Where `sync.mode` actually matters is every mirror
|
|
344
|
-
*after* that: under `sync.mode: exec` (the default for `mode: container`/`compose-native`), `wip
|
|
345
|
-
sync`/`wip sync --watch` run `rsync` inside the already-running primary container instead, so
|
|
346
|
-
*that* image needs `rsync` installed — `sync.image`/`sync.build` are ignored for these. Under
|
|
347
|
-
`sync.mode: run`, every mirror (pre-boot included) uses a throwaway container, so `sync.image`/
|
|
348
|
-
`sync.build` (or the primary image fallback, where available) need `rsync` throughout.
|
|
349
|
-
|
|
350
|
-
```yaml
|
|
351
|
-
sync:
|
|
352
|
-
source: . # host path, relative to wip.yml (default: the wip.yml directory)
|
|
353
|
-
target: /app # container path served by the volume (default: the primary container's workdir, else /app)
|
|
354
|
-
volume: app-src # named volume holding the mirror (default: "<container>-src")
|
|
355
|
-
mount: /host-src # where the source is bind-mounted read-only (default: /host-src)
|
|
356
|
-
exclude: # rsync --exclude patterns
|
|
357
|
-
- .git
|
|
358
|
-
- tmp/
|
|
359
|
-
- node_modules/
|
|
360
|
-
delete: true # rsync --delete (default: true)
|
|
361
|
-
command: rsync # binary that does the mirroring (default: rsync)
|
|
362
|
-
options: [] # extra flags appended to the rsync invocation
|
|
363
|
-
interval: 2 # seconds between syncs for `wip sync --watch` (default: 2)
|
|
364
|
-
mode: exec # exec (mirror inside the running container) or run (a throwaway one);
|
|
365
|
-
# default: exec for `mode: container`, run for `mode: compose`
|
|
366
|
-
image: null # image for the mirror container; unused under mode: container unless set
|
|
367
|
-
# (falls back to the primary container's own image). Under mode: compose,
|
|
368
|
-
# one of image or build is required (there's no dependencies: entry to fall
|
|
369
|
-
# back to)
|
|
370
|
-
build: # optional; has wip build the mirror image itself instead of requiring one to
|
|
371
|
-
# already exist. build.tag wins over image if both are set.
|
|
372
|
-
dockerfile: |
|
|
373
|
-
FROM alpine:latest
|
|
374
|
-
RUN apk add --no-cache rsync
|
|
375
|
-
tag: null # optional (default: "wip-sync-<container>:latest")
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
`wip init --template NAME` writes `exclude`'s default list live, picked from that stack's own
|
|
379
|
-
`github/gitignore` template:
|
|
380
|
-
|
|
381
|
-
| `--template` | Stack | Default `exclude` |
|
|
382
|
-
|---|---|---|
|
|
383
|
-
| `rails` | Rails | `.git`, `log/`, `tmp/`, `storage/`, `public/assets/`, `public/packs/`, `.bundle/`, `vendor/bundle/`, `coverage/`, `node_modules/` |
|
|
384
|
-
| `node` | Node.js | `.git`, `node_modules/`, `dist/`, `build/`, `.next/`, `.cache/`, `coverage/` |
|
|
385
|
-
| `rust` | Rust | `.git`, `target/` |
|
|
386
|
-
| `csharp` | C# | `.git`, `bin/`, `obj/`, `.vs/`, `packages/` |
|
|
387
|
-
| (omitted) | — | `.git`, `tmp/`, `node_modules/` |
|
|
388
|
-
|
|
389
|
-
Everything below `sync:` is optional — `sync: {}` alone already works. With it in place:
|
|
390
|
-
|
|
391
|
-
- Any `volumes` entry on the primary container mounting `target` (the usual `.:/app`) is replaced
|
|
392
|
-
by `<source>:/host-src:ro` plus `app-src:/app`, so the running app only ever touches the volume.
|
|
393
|
-
Other volumes (`bundle:/usr/local/bundle`, ...) are passed through untouched, and sidecar
|
|
394
|
-
`dependencies:` entries keep mounting whatever they declare.
|
|
395
|
-
- `wip up` mirrors the source into the volume before the container boots; `wip up --no-sync`
|
|
396
|
-
skips that step.
|
|
397
|
-
- `wip sync` mirrors on demand: `sync.mode: exec` (the default under `mode: container`) execs
|
|
398
|
-
rsync inside the already-running container; `sync.mode: run` always uses a throwaway container
|
|
399
|
-
with the same mounts instead. Which one runs is fixed by config, not guessed at from whether a
|
|
400
|
-
container happens to be up.
|
|
401
|
-
- `wip sync --watch [--interval N]` keeps re-syncing until Ctrl-C, so host edits reach the
|
|
402
|
-
container with a short delay. Run it in a second terminal alongside `wip up -d`.
|
|
403
|
-
- `wip doctor` reports the resolved source, volume, and target, and fails if the source is missing.
|
|
404
|
-
- With `sync.build` configured, `wip build`s that image once per `wip up`/`wip sync` invocation
|
|
405
|
-
(including once before a `--watch` loop starts, not on every tick) before mirroring with it.
|
|
406
|
-
|
|
407
|
-
Like every built-in command, `wip sync` takes precedence over an `interaction:` entry of the same
|
|
408
|
-
name; wip says so and points at `wip dispatch sync`, which still runs yours.
|
|
409
|
-
|
|
410
|
-
Two things to keep in mind. The mirror runs `rsync` *inside* the container, so the image needs it
|
|
411
|
-
(`RUN apt-get update && apt-get install -y rsync`) — or point `sync.command` at a copy tool the
|
|
412
|
-
image already has. And the mirror is one-way (host → volume): anything the app writes under
|
|
413
|
-
`target` is removed by the next `--delete` pass unless you `exclude` it, give it its own volume,
|
|
414
|
-
or set `delete: false`.
|
|
415
|
-
|
|
416
|
-
`sync:` works alongside `mode: compose` too, but two things change:
|
|
417
|
-
|
|
418
|
-
- Compose still owns the volume layout, so wip doesn't rewrite any mounts for you: the compose
|
|
419
|
-
service that runs your app must itself declare a named volume with the exact same name as
|
|
420
|
-
`sync.volume` (`<container>-src` by default) mounted at the path your app expects, e.g.:
|
|
421
|
-
```yaml
|
|
422
|
-
# compose.yml
|
|
423
|
-
services:
|
|
424
|
-
app:
|
|
425
|
-
volumes:
|
|
426
|
-
- app-src:/app
|
|
427
|
-
volumes:
|
|
428
|
-
app-src:
|
|
429
|
-
```
|
|
430
|
-
wip's mirror writes into that volume from a separate, disposable container; it never touches
|
|
431
|
-
the compose service directly.
|
|
432
|
-
- `sync.mode` defaults to `run` and can't be set to `exec` (only a container wip itself booted is
|
|
433
|
-
guaranteed to have the read-only source mount attached, which compose services never do), and
|
|
434
|
-
`sync.image` or `sync.build` becomes required, since that disposable container needs an image
|
|
435
|
-
from somewhere — under `mode: container` it borrows the primary `dependencies:` entry's image,
|
|
436
|
-
but compose mode has no such entry to borrow from.
|
|
437
|
-
|
|
438
|
-
`wip up`'s pre-boot mirror (and the `--no-sync` flag that skips it) works the same way under
|
|
439
|
-
`mode: compose` as it does otherwise: the source is mirrored into the volume before
|
|
440
|
-
`compose up` starts the service that mounts it.
|
|
441
|
-
|
|
442
|
-
Since `sync.mode: run` boots a fresh container on every mirror, reusing your app's full image here
|
|
443
|
-
just adds startup overhead for something that only ever runs `rsync`. A dedicated, minimal image is
|
|
444
|
-
worth it — `wip` doesn't publish or default to one itself (same reasoning as `compose.command`:
|
|
445
|
-
picking a specific third-party image for you isn't its call to make), but `sync.build` covers it
|
|
446
|
-
without needing to manage a separate image yourself:
|
|
447
|
-
|
|
448
|
-
```yaml
|
|
449
|
-
sync:
|
|
450
|
-
build:
|
|
451
|
-
dockerfile: |
|
|
452
|
-
FROM alpine:latest
|
|
453
|
-
RUN apk add --no-cache rsync
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
wip builds this once per `wip up`/`wip sync` invocation (not on every `--watch` tick — see above)
|
|
457
|
-
and uses the result, tagged `wip-sync-<container>:latest` by default (`build.tag` overrides it).
|
|
458
|
-
Prefer managing the image yourself instead? Build and tag it however you like, then set `sync.image`
|
|
459
|
-
to that tag directly — `sync.build`'s tag wins if both are set, so don't configure both at once.
|
|
151
|
+
projects that already use `commands:`. The two are aliases for the same feature; declaring both in
|
|
152
|
+
the same `wip.yml` is a `ConfigError`. See [Interactions](https://github.com/slidict/wip/wiki/Interactions).
|
|
153
|
+
|
|
154
|
+
Every key above is covered across the wiki's feature pages, with the full behavior, edge cases,
|
|
155
|
+
and examples — start at the
|
|
156
|
+
**[Configuration Reference](https://github.com/slidict/wip/wiki/Configuration-Reference)**. Notably:
|
|
157
|
+
|
|
158
|
+
- [Dependencies](https://github.com/slidict/wip/wiki/Dependencies) — the primary container vs. sidecars
|
|
159
|
+
- [Restart Policies](https://github.com/slidict/wip/wiki/Restart-Policies) /
|
|
160
|
+
[Auto Restarting Containers](https://github.com/slidict/wip/wiki/Auto-Restarting-Containers) — `restart:` and `wip up --watch`
|
|
161
|
+
- [Compose Mode](https://github.com/slidict/wip/wiki/Compose-Mode) — bridging to a third-party compose-for-`wslc` tool
|
|
162
|
+
- [Compose Native Mode](https://github.com/slidict/wip/wiki/Compose-Native-Mode) — wip parsing `compose.yml` itself
|
|
163
|
+
- [Env Files](https://github.com/slidict/wip/wiki/Env-Files) — `.env` loading and precedence
|
|
164
|
+
- [Dockerignore](https://github.com/slidict/wip/wiki/Dockerignore) / [Shadow Build Context](https://github.com/slidict/wip/wiki/Shadow-Build-Context)
|
|
165
|
+
- [Source Sync](https://github.com/slidict/wip/wiki/Source-Sync) / [Sync Modes](https://github.com/slidict/wip/wiki/Sync-Modes) / [Continuous Sync](https://github.com/slidict/wip/wiki/Continuous-Sync)
|
|
460
166
|
|
|
461
167
|
## Commands
|
|
462
168
|
|
|
463
169
|
| Command | Description |
|
|
464
170
|
|---|---|
|
|
465
|
-
| `wip init [--force] [--template NAME]` | Write a starter `wip.yml`: `mode: compose-native` if a `compose.yml
|
|
171
|
+
| `wip init [--force] [--template NAME]` | Write a starter `wip.yml`: `mode: compose-native` if a `compose.yml`, `compose.yaml`, `docker-compose.yml`, or `docker-compose.yaml` is found next to it, `mode: container` otherwise |
|
|
466
172
|
| `wip version` | wip's version, plus WSLC's if it can be detected |
|
|
467
173
|
| `wip doctor` | Diagnose WSL2, interop, WSLC, config, architecture, and Git |
|
|
468
174
|
| `wip config` | Print the effective configuration (secrets masked) |
|
|
469
|
-
| `wip build [--no-cache] [-- OPTIONS]` | Build the image from the `build` definition
|
|
470
|
-
| `wip up [-d] [--no-sync] [--no-cache] [--watch] [--interval N]` | Start the
|
|
471
|
-
| `wip stop` | Stop the
|
|
472
|
-
| `wip down` | Stop and remove the
|
|
175
|
+
| `wip build [--no-cache] [-- OPTIONS]` | Build the image from the `build` definition |
|
|
176
|
+
| `wip up [-d] [--no-sync] [--no-cache] [--watch] [--interval N]` | Start the configured stack, creating it if necessary |
|
|
177
|
+
| `wip stop` | Stop the configured stack without removing it |
|
|
178
|
+
| `wip down` | Stop and remove the configured stack |
|
|
473
179
|
| `wip exec [--no-interactive] COMMAND...` | Run a command in the existing container |
|
|
474
|
-
| `wip run [--no-interactive] COMMAND...` | Run a command in a new `--rm` container (mode: compose `exec`
|
|
180
|
+
| `wip run [--no-interactive] COMMAND...` | Run a command in a new `--rm` container (`mode: compose` has no ephemeral run — falls back to `exec` in the running service, with a warning) |
|
|
475
181
|
| `wip shell` | Open the configured shell, falling back to `bash` then `sh` |
|
|
476
|
-
| `wip logs [-f] [SERVICE...]` | Follow compose service logs (compose modes only; mode: compose-native
|
|
477
|
-
| `wip sync [-w] [--interval N]` | Mirror the source into the sync volume once, or keep re-syncing with `--watch` (needs `sync:`) |
|
|
182
|
+
| `wip logs [-f] [SERVICE...]` | Follow compose service logs (compose modes only; under `mode: compose-native`, at most one `SERVICE`) |
|
|
183
|
+
| `wip sync [-w\|--watch] [--interval N]` | Mirror the source into the sync volume once, or keep re-syncing with `--watch` (needs `sync:`) |
|
|
478
184
|
| `wip NAME ARGS...` | Run `interaction.NAME`, appending any extra arguments |
|
|
479
185
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
Pass `--debug` (or set `WIP_DEBUG=1`) to see where time is going: wip prints each step it takes —
|
|
484
|
-
checking for an existing network/container/dependency, and running the resolved `wslc`/`docker`
|
|
485
|
-
command — along with how long that step took, e.g.:
|
|
486
|
-
|
|
487
|
-
```console
|
|
488
|
-
$ wip rails c --debug
|
|
489
|
-
wip: [debug] running: wslc.exe exec -it -w /app app bin/rails c
|
|
490
|
-
+ wslc.exe exec -it -w /app app bin/rails c
|
|
491
|
-
...
|
|
492
|
-
wip: [debug] done in 4.32s: running: wslc.exe exec -it -w /app app bin/rails c
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
For long-running interactive commands (like `rails c`), the "done" line only prints after you
|
|
496
|
-
exit, but the timestamp of the `+ ...` line tells you when wip finished its own setup and handed
|
|
497
|
-
off to `wslc`/`docker` — useful for telling wip-side overhead apart from time spent booting inside
|
|
498
|
-
the container.
|
|
499
|
-
|
|
500
|
-
While a step is still running, wip also prints a host resource snapshot (load average, memory,
|
|
501
|
-
disk I/O, and the top CPU-consuming processes) every 5 seconds, so a hang is visible even before
|
|
502
|
-
the command has produced any output of its own:
|
|
503
|
-
|
|
504
|
-
```console
|
|
505
|
-
wip: [debug] still running (load 3.42 2.10 1.05 | mem 6.1G/15.6G | io read 12000KB/s write 400KB/s | top: wslc.exe(8842) cpu 61.0%/mem 3.2%, ...): running: wslc.exe exec -it -w /app app bin/rails c
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
The disk I/O figure is worth watching first if the host's CPU and memory look idle — a slow
|
|
509
|
-
`bundle`/`rails` boot is often WSL2's bind-mounted (`.:/app`-style) volumes doing a lot of small
|
|
510
|
-
reads, not the container starving for CPU.
|
|
511
|
-
|
|
512
|
-
For commands that hand the real terminal to the child (`-it`, e.g. `rails c`), these periodic
|
|
513
|
-
snapshots go to a log file instead of your terminal — wip prints the path once at the start —
|
|
514
|
-
since writing into a terminal the child controls in raw mode would garble both outputs. Commands
|
|
515
|
-
that don't need a TTY still get the snapshots printed live.
|
|
516
|
-
|
|
517
|
-
Override that choice with `--debug-log`:
|
|
186
|
+
Every command has flags, per-mode behavior, and examples on its own wiki page — see the
|
|
187
|
+
**[CLI Command Reference](https://github.com/slidict/wip/wiki/CLI-Command-Reference)**.
|
|
518
188
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
189
|
+
Pass `--debug` (or set `WIP_DEBUG=1`) to see where time is going: wip prints each step it takes,
|
|
190
|
+
along with a periodic host resource snapshot (load, memory, disk I/O, top processes), so a hang is
|
|
191
|
+
visible even before a command produces output. See
|
|
192
|
+
[Debug Output](https://github.com/slidict/wip/wiki/Debug-Output) for the full behavior and the
|
|
193
|
+
`--debug-log` option.
|
|
523
194
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
Each check prints as `[OK]`, `[WARN]`, or `[FAIL]`. Warnings alone exit 0; a WSL2, interop, WSLC,
|
|
527
|
-
or config problem that blocks execution exits 1. Git being unreachable from the real build
|
|
528
|
-
environment is only a warning.
|
|
195
|
+
`wip doctor` prints `[OK]`/`[WARN]`/`[FAIL]` per check; warnings alone exit 0, a blocking problem
|
|
196
|
+
exits 1. See [`wip doctor`](https://github.com/slidict/wip/wiki/wip-doctor).
|
|
529
197
|
|
|
530
198
|
## Common errors
|
|
531
199
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
### Docker Hub authentication
|
|
200
|
+
- [WSLC not found](https://github.com/slidict/wip/wiki/WSLC-Not-Found)
|
|
201
|
+
- [Docker Hub / registry authentication](https://github.com/slidict/wip/wiki/Registry-Authentication)
|
|
202
|
+
- [Slow boot when the app directory is bind-mounted](https://github.com/slidict/wip/wiki/Fixing-a-Slow-Boot)
|
|
203
|
+
- [CPU architecture mismatch](https://github.com/slidict/wip/wiki/Architecture-Mismatch)
|
|
538
204
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### Slow boot when the app directory is bind-mounted
|
|
546
|
-
|
|
547
|
-
wslc containers run in their own VM, so a bind-mounted host directory (`.:/app`) is always shared
|
|
548
|
-
in over virtiofs, even when the host path is already on WSL's native filesystem. Frameworks that
|
|
549
|
-
scan large directory trees at startup (Ruby's Zeitwerk autoloader, for example) issue many small
|
|
550
|
-
per-file stat/open calls, and each one is a round trip through that layer — CPU on the Windows
|
|
551
|
-
side can look busy while almost no data is actually transferred, and the process can appear hung
|
|
552
|
-
for minutes with barely any resource usage to show for it.
|
|
553
|
-
|
|
554
|
-
If a debug log shows a boot-time command "stuck" with low CPU/mem/IO in `resource_monitor`'s
|
|
555
|
-
output, this is worth checking before assuming the app itself is broken. The fix is to stop
|
|
556
|
-
bind-mounting the source live and mirror it into a named volume instead, so the app only ever
|
|
557
|
-
touches fast native storage once it's running. `wip` does that for you — add a `sync:` block and
|
|
558
|
-
it rewrites the mounts, mirrors before boot, and re-syncs on demand. See [Source
|
|
559
|
-
sync](#source-sync).
|
|
560
|
-
|
|
561
|
-
### CPU architecture mismatch
|
|
562
|
-
|
|
563
|
-
Check the image and publish a multi-arch (amd64/arm64) image:
|
|
564
|
-
|
|
565
|
-
```bash
|
|
566
|
-
docker buildx imagetools inspect <image>
|
|
567
|
-
docker buildx build \
|
|
568
|
-
--platform linux/amd64,linux/arm64 \
|
|
569
|
-
-t <image> \
|
|
570
|
-
--push .
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
## FAQ
|
|
574
|
-
|
|
575
|
-
**Which mode should I start with?**
|
|
576
|
-
Pick whichever `mode:` fits your project — see [Which mode should you use?](#which-mode-should-you-use)
|
|
577
|
-
for the breakdown.
|
|
578
|
-
|
|
579
|
-
**Can I use `dependencies:` and `compose:` together?**
|
|
580
|
-
No — `compose:` is mutually exclusive with `dependencies:`/`network`. Pick one orchestration path
|
|
581
|
-
per project; see [Configuration](#configuration).
|
|
582
|
-
|
|
583
|
-
**What's the difference between `mode: compose` and `mode: compose-native`?**
|
|
584
|
-
`compose` delegates to a third-party compose-for-`wslc` binary you install yourself
|
|
585
|
-
(`compose.command`); `compose-native` parses `compose.yml` itself and drives `wslc` directly, no
|
|
586
|
-
external tool required. `compose-native`'s Compose coverage isn't frozen at whatever it handles
|
|
587
|
-
today — it keeps growing until `wslc` ships native Compose support of its own. See
|
|
588
|
-
[Compose mode](#compose-mode) and [Compose mode (native)](#compose-mode-native).
|
|
589
|
-
|
|
590
|
-
**`dependencies:` already gives me sidecar containers — why would I need `compose-native` too?**
|
|
591
|
-
`dependencies:` and `compose-native` aren't really alternatives to each other — they're for two
|
|
592
|
-
different starting points. No `compose.yml`? Declare containers directly in `wip.yml`'s own shape
|
|
593
|
-
with `dependencies:`. Already have a `compose.yml`? Reusing it is where `compose-native` and
|
|
594
|
-
`mode: compose` both come in, so the real comparison is between those two, not against
|
|
595
|
-
`dependencies:`: `mode: compose` reuses it too, but only by delegating to a third-party
|
|
596
|
-
compose-for-`wslc` binary you install yourself; `compose-native` reuses the same `compose.yml`
|
|
597
|
-
without installing anything external, parsing it and driving `wslc` directly — and gets a real
|
|
598
|
-
`wslc run --rm` for `wip run` instead of the `exec` fallback `mode: compose` falls back to.
|
|
599
|
-
`mode: compose`'s coverage is whatever the external tool you point it at supports; `compose-native`'s
|
|
600
|
-
is maintained in this repo and actively extended, not treated as a permanent ceiling. See
|
|
601
|
-
[Which mode should you use?](#which-mode-should-you-use) for the full picture.
|
|
602
|
-
|
|
603
|
-
**What happens to `compose-native` once `wslc` gets official Compose support?**
|
|
604
|
-
`compose-native` exists to close the gap for as long as `wslc` has no native Compose support of its
|
|
605
|
-
own (tracked upstream in [microsoft/WSL#40948](https://github.com/microsoft/WSL/issues/40948)), and
|
|
606
|
-
we intend to keep extending its Compose coverage until that lands — see
|
|
607
|
-
[Compose mode (native)](#compose-mode-native) and [Roadmap](#roadmap). `wip.yml`'s shape (`mode:`,
|
|
608
|
-
`compose:`) isn't planned to change for existing `container`/`compose`/`compose-native` setups, so
|
|
609
|
-
whatever we do once `wslc` catches up won't require rewriting your config.
|
|
610
|
-
|
|
611
|
-
**Is `sync:` required?**
|
|
612
|
-
No, it's entirely optional. Add it if boot times feel slow with a bind-mounted app directory — see
|
|
613
|
-
[Slow boot when the app directory is bind-mounted](#slow-boot-when-the-app-directory-is-bind-mounted).
|
|
614
|
-
|
|
615
|
-
**How does `wip` actually fix the slow bind-mount boot problem?**
|
|
616
|
-
The slowness comes from `.:/app`-style bind mounts going through virtiofs, where frameworks that
|
|
617
|
-
stat/open many small files at startup (e.g. Ruby's Zeitwerk) pay a round trip per file. A `sync:`
|
|
618
|
-
block moves the app off that path entirely: the host source is mounted read-only, the app itself
|
|
619
|
-
runs off a named volume (fast native storage inside the VM), and `wip` mirrors the read-only
|
|
620
|
-
source into that volume with `rsync` — once before boot, and on demand afterward via `wip sync`
|
|
621
|
-
(or continuously with `wip sync --watch`). Since the app never touches the bind mount directly, its
|
|
622
|
-
own file access is no longer paying the virtiofs cost; the trade-off is a one-way, slightly-delayed
|
|
623
|
-
mirror instead of an always-live view of host edits. See [Source sync](#source-sync) for the full
|
|
624
|
-
config and [Slow boot when the app directory is bind-mounted](#slow-boot-when-the-app-directory-is-bind-mounted)
|
|
625
|
-
for the root cause.
|
|
626
|
-
|
|
627
|
-
**Is it safe to put passwords/secrets in `wip.yml`?**
|
|
628
|
-
`wip config` masks any key matching token/password/secret/credential/auth when printing, but the
|
|
629
|
-
raw file itself is not encrypted. Keep real secrets in your runtime environment or `.env` instead
|
|
630
|
-
of committing them in `wip.yml` — but `.env` is only safe if it's actually untracked: add `.env` to
|
|
631
|
-
`.gitignore` (and confirm with `git check-ignore .env`) before putting anything sensitive in it.
|
|
632
|
-
|
|
633
|
-
**`wslc.exe`/`wslc` isn't found — what do I do?**
|
|
634
|
-
See [WSLC not found](#wslc-not-found) under Common errors.
|
|
635
|
-
|
|
636
|
-
**I'm migrating from `dip` — do I have to rename `interaction:`?**
|
|
637
|
-
No, `wip.yml` accepts `interaction:` as-is — it's the primary spelling, same as in `dip`. `commands:`
|
|
638
|
-
also works as an alias if you prefer it, but not both in the same file (that's a `ConfigError`). See
|
|
639
|
-
[Container mode](#container-mode).
|
|
205
|
+
More errors, causes, and fixes are indexed on the wiki's
|
|
206
|
+
**[Troubleshooting & FAQ](https://github.com/slidict/wip/wiki/Troubleshooting-and-FAQ)** page,
|
|
207
|
+
including [Configuration Errors](https://github.com/slidict/wip/wiki/Configuration-Errors) (every
|
|
208
|
+
`ConfigError` and what triggers it).
|
|
640
209
|
|
|
641
210
|
## Development
|
|
642
211
|
|
|
@@ -651,7 +220,9 @@ bundle exec rake
|
|
|
651
220
|
|
|
652
221
|
The test suite doesn't need WSLC — the resolution, build, and execution layers are all
|
|
653
222
|
swappable. This project uses RuboCop for Ruby style and static analysis; `bundle exec rake` runs
|
|
654
|
-
both RSpec and RuboCop. GitHub Actions checks them on Ruby 3.2, 3.3, 3.4, and 4.0.
|
|
223
|
+
both RSpec and RuboCop. GitHub Actions checks them on Ruby 3.2, 3.3, 3.4, and 4.0. See
|
|
224
|
+
[Development](https://github.com/slidict/wip/wiki/Development) and
|
|
225
|
+
[Architecture](https://github.com/slidict/wip/wiki/Architecture) on the wiki for more.
|
|
655
226
|
|
|
656
227
|
## Contributing
|
|
657
228
|
|
|
@@ -659,53 +230,6 @@ Bug reports and pull requests are welcome on [GitHub](https://github.com/slidict
|
|
|
659
230
|
[CONTRIBUTING.md](CONTRIBUTING.md) for commit conventions, versioning policy, and the PR
|
|
660
231
|
checklist.
|
|
661
232
|
|
|
662
|
-
## Roadmap
|
|
663
|
-
|
|
664
|
-
`wip` already covers most of what [`dip`](https://github.com/bibendi/dip) adds on top of Compose —
|
|
665
|
-
named commands (`interaction:`), `run`/`exec` hidden behind a single verb, `.env` passthrough, and
|
|
666
|
-
sidecar services via `dependencies:` + `network:`. Rather than waiting on `wslc`'s own Compose
|
|
667
|
-
support ([microsoft/WSL#40948](https://github.com/microsoft/WSL/issues/40948)) or an external
|
|
668
|
-
compose-for-`wslc` tool staying complete, `mode: compose-native` (see
|
|
669
|
-
[Compose mode (native)](#compose-mode-native)) parses `compose.yml` itself and drives `wslc`
|
|
670
|
-
directly — no external binary in the loop, `wip run` gets a real `--rm` container, and iterating
|
|
671
|
-
on the parser is faster than chasing a third-party tool's own bugs. It's still a deliberately
|
|
672
|
-
minimal subset (`depends_on` ordering but no health checks, single-container `logs`, no named
|
|
673
|
-
volumes/scaling), and `dependencies:` + `network:` remains the escape hatch for sidecars it
|
|
674
|
-
doesn't model. Fuller Compose semantics beyond that subset stay behind delegating to a separate
|
|
675
|
-
compose-for-`wslc` tool in [compose mode](#compose-mode) — which of those actually work is
|
|
676
|
-
entirely up to the external tool you point `compose.command` at; `wip` only forwards
|
|
677
|
-
`-f FILE [-p PROJECT] up|down|exec|logs`, so treat that list as what Compose offers, not as
|
|
678
|
-
something `wip` guarantees. See that section for what compose mode covers
|
|
679
|
-
and its current limitations (`run`, and `interaction:` of type `run`/`build`).
|
|
680
|
-
|
|
681
|
-
Beyond Compose parity, a resident/daemon process, a GUI, PowerShell-specific tuning, direct
|
|
682
|
-
registry API/manifest parsing, self-update, and plugins are all unimplemented and not currently
|
|
683
|
-
planned. (`wip up --watch`'s restart-policy poll loop isn't an exception to this — it's a
|
|
684
|
-
foreground, opt-in loop you keep a terminal open for, the same shape as `wip sync --watch`, not a
|
|
685
|
-
background service; see
|
|
686
|
-
[Restarting exited dependencies](#restarting-exited-dependencies-wip-up---watch).) What's still
|
|
687
|
-
planned for `wip`, roughly in priority order:
|
|
688
|
-
|
|
689
|
-
1. **`wip provision`** — a dip-style one-shot bootstrap hook (build → up deps → install deps →
|
|
690
|
-
create/migrate/seed DB) so a new contributor can go from `git clone` to a working environment
|
|
691
|
-
in two commands (`wip provision && wip up`).
|
|
692
|
-
2. **Config file merging** — `--config` currently accepts one file; support layering
|
|
693
|
-
(`wip.yml` + `wip.override.yml`, or a `WIP_CONFIG` list) for dev/CI/debug variants without
|
|
694
|
-
duplicating the whole file, plus a `wip config --resolved` view of the merged result.
|
|
695
|
-
3. **Bind-mount boot time (`rails c`, `bundle`, ...)** — commands like `wip rails c` still start
|
|
696
|
-
noticeably slower than the equivalent under `docker compose`, mostly from WSL2 bind-mounted
|
|
697
|
-
(`.:/app`-style) volumes doing many small reads for gems/`node_modules` (use `--debug` to
|
|
698
|
-
confirm it's disk I/O and not `wip`'s own overhead). [Source sync](#source-sync) works around
|
|
699
|
-
this today by running the app off a named volume and mirroring the host tree into it, at the
|
|
700
|
-
cost of a one-way sync with a short delay. A tighter loop (host-side file watching instead of
|
|
701
|
-
interval polling, two-way sync) is the natural next step. We're also hoping for improvements on
|
|
702
|
-
the `wslc` side itself (faster bind-mount/cache behavior); `wip` will pick those up for free as
|
|
703
|
-
soon as they land.
|
|
704
|
-
|
|
705
|
-
Each of these should stay additive to the existing `wip.yml` shape — no breaking changes to
|
|
706
|
-
`container`, `network`, `commands`, `dependencies`, or `compose` are planned. A resident daemon
|
|
707
|
-
and a GUI remain out of scope.
|
|
708
|
-
|
|
709
233
|
## License
|
|
710
234
|
|
|
711
235
|
[MIT License](LICENSE)
|
data/lib/wip/initializer.rb
CHANGED
|
@@ -11,6 +11,7 @@ module Wip
|
|
|
11
11
|
# --template values wip init accepts, and the label used in the exclude: comment.
|
|
12
12
|
TEMPLATE_LABELS = {
|
|
13
13
|
'rails' => 'Rails',
|
|
14
|
+
'ruby' => 'Ruby',
|
|
14
15
|
'node' => 'Node.js',
|
|
15
16
|
'rust' => 'Rust',
|
|
16
17
|
'csharp' => 'C#'
|
|
@@ -22,6 +23,7 @@ module Wip
|
|
|
22
23
|
TEMPLATE_EXCLUDES = {
|
|
23
24
|
'rails' => %w[.git log/ tmp/ storage/ public/assets/ public/packs/ .bundle/ vendor/bundle/
|
|
24
25
|
coverage/ node_modules/],
|
|
26
|
+
'ruby' => %w[.git log/ tmp/ .bundle/ vendor/bundle/ coverage/],
|
|
25
27
|
'node' => %w[.git node_modules/ dist/ build/ .next/ .cache/ coverage/],
|
|
26
28
|
'rust' => %w[.git target/],
|
|
27
29
|
'csharp' => %w[.git bin/ obj/ .vs/ packages/]
|
data/lib/wip/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wslc-wip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wip contributors
|
|
@@ -56,15 +56,14 @@ files:
|
|
|
56
56
|
- lib/wip/sync_settings.rb
|
|
57
57
|
- lib/wip/variable_interpolation.rb
|
|
58
58
|
- lib/wip/version.rb
|
|
59
|
-
homepage: https://
|
|
59
|
+
homepage: https://github.com/slidict/wip
|
|
60
60
|
licenses:
|
|
61
61
|
- MIT
|
|
62
62
|
metadata:
|
|
63
63
|
rubygems_mfa_required: 'true'
|
|
64
|
-
homepage_uri: https://
|
|
65
|
-
source_code_uri: https://github.com/slidict/wip
|
|
64
|
+
homepage_uri: https://github.com/slidict/wip
|
|
66
65
|
changelog_uri: https://github.com/slidict/wip/releases
|
|
67
|
-
|
|
66
|
+
source_code_uri: https://github.com/slidict/wip/tree/v1.1.4
|
|
68
67
|
rdoc_options: []
|
|
69
68
|
require_paths:
|
|
70
69
|
- lib
|