wslc-wip 0.14.2 → 0.15.0
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 +12 -1
- data/lib/wip/cli.rb +3 -1
- data/lib/wip/initializer.rb +171 -62
- data/lib/wip/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8248f18abf8e946e333de3e2e9b70e72b9b0f8806a3216c97e62bfe83ad53bb
|
|
4
|
+
data.tar.gz: 19119fe6787aad4b17cc6ed9e1f1048d664cbcd119414bd4bc4b86e0c26dfb5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91535a4b496bc4cc2e55cc44d7feadbf8709811df0ab660c7d7fe8e6f20feccac18a497804b13bd83a6d2775396e3061c51f64040864e3d6635eeaf22edf9b8e
|
|
7
|
+
data.tar.gz: 1151d286900c2c11812c607f123d966862ea41b1ac5ee01a74d957f0626667c616fdabf13f618fdad4a62a1b4c8a26f1c68bf837030f1e8f4508a8f2d0e733b1
|
data/README.md
CHANGED
|
@@ -181,6 +181,17 @@ sync:
|
|
|
181
181
|
tag: null # optional (default: "wip-sync-<container>:latest")
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
`wip init --template NAME` writes `exclude`'s default list live, picked from that stack's own
|
|
185
|
+
`github/gitignore` template:
|
|
186
|
+
|
|
187
|
+
| `--template` | Stack | Default `exclude` |
|
|
188
|
+
|---|---|---|
|
|
189
|
+
| `rails` | Rails | `.git`, `log/`, `tmp/`, `storage/`, `public/assets/`, `public/packs/`, `.bundle/`, `vendor/bundle/`, `coverage/`, `node_modules/` |
|
|
190
|
+
| `node` | Node.js | `.git`, `node_modules/`, `dist/`, `build/`, `.next/`, `.cache/`, `coverage/` |
|
|
191
|
+
| `rust` | Rust | `.git`, `target/` |
|
|
192
|
+
| `csharp` | C# | `.git`, `bin/`, `obj/`, `.vs/`, `packages/` |
|
|
193
|
+
| (omitted) | — | `.git`, `tmp/`, `node_modules/` |
|
|
194
|
+
|
|
184
195
|
Everything below `sync:` is optional — `sync: {}` alone already works. With it in place:
|
|
185
196
|
|
|
186
197
|
- Any `volumes` entry on the primary container mounting `target` (the usual `.:/app`) is replaced
|
|
@@ -341,7 +352,7 @@ valid compose.yml over sections it doesn't need to look at:
|
|
|
341
352
|
|
|
342
353
|
| Command | Description |
|
|
343
354
|
|---|---|
|
|
344
|
-
| `wip init [--force]` | Write a starter `wip.yml`: `mode: compose-native` if a `compose.yml`/`docker-compose.yml` is found next to it, `mode: container` otherwise. Refuses to overwrite an existing `wip.yml` unless `--force` |
|
|
355
|
+
| `wip init [--force] [--template NAME]` | Write a starter `wip.yml`: `mode: compose-native` if a `compose.yml`/`docker-compose.yml` is found next to it, `mode: container` otherwise. `--template` picks `sync.exclude`'s default patterns for a stack (`rails`, `node`, `rust`, `csharp`); omitted, it falls back to `.git`/`tmp/`/`node_modules/`. Refuses to overwrite an existing `wip.yml` unless `--force` |
|
|
345
356
|
| `wip version` | wip's version, plus WSLC's if it can be detected |
|
|
346
357
|
| `wip doctor` | Diagnose WSL2, interop, WSLC, config, architecture, and Git |
|
|
347
358
|
| `wip config` | Print the effective configuration (secrets masked) |
|
data/lib/wip/cli.rb
CHANGED
|
@@ -42,11 +42,13 @@ module Wip
|
|
|
42
42
|
|
|
43
43
|
desc 'init', 'Create a starter wip.yml (detects an existing compose.yml/docker-compose.yml)'
|
|
44
44
|
option :force, type: :boolean, default: false, desc: 'Overwrite an existing wip.yml'
|
|
45
|
+
option :template, type: :string,
|
|
46
|
+
desc: "sync.exclude preset: #{Initializer::TEMPLATE_LABELS.keys.join(', ')} (default: none)"
|
|
45
47
|
def init
|
|
46
48
|
path = Pathname(options[:config] || ConfigLoader::FILENAME).expand_path
|
|
47
49
|
raise Error, "#{path} already exists (use --force to overwrite)" if path.file? && !options[:force]
|
|
48
50
|
|
|
49
|
-
initializer = Initializer.new(dir: path.dirname)
|
|
51
|
+
initializer = Initializer.new(dir: path.dirname, template: options[:template])
|
|
50
52
|
path.write(initializer.call)
|
|
51
53
|
warn "wip: wrote #{path} (mode: #{initializer.compose? ? 'compose-native' : 'container'})"
|
|
52
54
|
end
|
data/lib/wip/initializer.rb
CHANGED
|
@@ -8,72 +8,54 @@ module Wip
|
|
|
8
8
|
# mode: compose-native and mode: container, since that's the one decision
|
|
9
9
|
# `wip init` can't leave to a placeholder.
|
|
10
10
|
class Initializer
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
# --template values wip init accepts, and the label used in the exclude: comment.
|
|
12
|
+
TEMPLATE_LABELS = {
|
|
13
|
+
'rails' => 'Rails',
|
|
14
|
+
'node' => 'Node.js',
|
|
15
|
+
'rust' => 'Rust',
|
|
16
|
+
'csharp' => 'C#'
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
# sync.exclude patterns written live for each --template. They mirror that
|
|
20
|
+
# stack's own github/gitignore template — directories that are either
|
|
21
|
+
# regenerated inside the container or too large/irrelevant to mirror over rsync.
|
|
22
|
+
TEMPLATE_EXCLUDES = {
|
|
23
|
+
'rails' => %w[.git log/ tmp/ storage/ public/assets/ public/packs/ .bundle/ vendor/bundle/
|
|
24
|
+
coverage/ node_modules/],
|
|
25
|
+
'node' => %w[.git node_modules/ dist/ build/ .next/ .cache/ coverage/],
|
|
26
|
+
'rust' => %w[.git target/],
|
|
27
|
+
'csharp' => %w[.git bin/ obj/ .vs/ packages/]
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
# Used when --template is omitted — the same starting point the README's own
|
|
31
|
+
# example uses.
|
|
32
|
+
FALLBACK_EXCLUDES = %w[.git tmp/ node_modules/].freeze
|
|
33
33
|
|
|
34
34
|
# Appended to both templates after dependencies/compose. commands: itself is left
|
|
35
35
|
# commented since an empty commands: {} is indistinguishable from omitting the key.
|
|
36
36
|
COMMANDS_EXAMPLE = <<~YAML.chomp
|
|
37
|
-
#
|
|
37
|
+
# optional; custom subcommands, e.g. `wip test` — see README
|
|
38
|
+
# commands:
|
|
38
39
|
# test:
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
YAML
|
|
42
|
-
|
|
43
|
-
CONTAINER_TEMPLATE = <<~YAML.freeze
|
|
44
|
-
version: 1
|
|
45
|
-
mode: container # container | compose | compose-native (see README)
|
|
46
|
-
container: app # TODO: rename freely, as long as it matches a key under dependencies: below
|
|
47
|
-
|
|
48
|
-
wslc:
|
|
49
|
-
command: auto # optional; wslc binary/path wip shells out to ("auto" resolves it for you)
|
|
40
|
+
# optional; exec (default, runs in the running container) | run (fresh container) | build
|
|
41
|
+
# type: exec
|
|
50
42
|
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
dependencies:
|
|
54
|
-
app: # this is the container wip creates, execs into, and runs commands in
|
|
55
|
-
image: your/image:tag # TODO: image to run
|
|
56
|
-
workdir: /app # TODO: adjust to match your image, or delete this line
|
|
57
|
-
interactive: false # optional; keep stdin open / allocate a tty
|
|
58
|
-
remove: true # optional; remove the container after each run
|
|
59
|
-
env: {} # optional; environment variables passed to the container, e.g. {FOO: bar}
|
|
60
|
-
ports: [] # optional; published ports, e.g. ["3000:3000"]
|
|
61
|
-
volumes: [] # optional; extra -v specs beyond the sync mounts below
|
|
62
|
-
|
|
63
|
-
#{COMMANDS_EXAMPLE}
|
|
64
|
-
|
|
65
|
-
sync: # optional; mirrors the source into a named volume instead of bind-mounting it live
|
|
66
|
-
#{SYNC_EXTRAS}
|
|
43
|
+
# TODO
|
|
44
|
+
# command: bundle exec rspec
|
|
67
45
|
YAML
|
|
68
46
|
|
|
69
|
-
def initialize(dir: Dir.pwd)
|
|
47
|
+
def initialize(dir: Dir.pwd, template: nil)
|
|
48
|
+
raise Error, "unknown --template #{template.inspect} (valid: #{TEMPLATE_LABELS.keys.join(', ')})" \
|
|
49
|
+
if template && !TEMPLATE_LABELS.key?(template)
|
|
50
|
+
|
|
70
51
|
@dir = dir
|
|
52
|
+
@template = template
|
|
71
53
|
end
|
|
72
54
|
|
|
73
55
|
def compose? = !!compose_file
|
|
74
56
|
|
|
75
57
|
def call
|
|
76
|
-
compose? ? compose_template :
|
|
58
|
+
compose? ? compose_template : container_template
|
|
77
59
|
end
|
|
78
60
|
|
|
79
61
|
private
|
|
@@ -87,29 +69,156 @@ module Wip
|
|
|
87
69
|
# without duplicating it as a live value that would go stale if the directory moves.
|
|
88
70
|
def compose_project_default = Pathname(@dir).basename.to_s
|
|
89
71
|
|
|
72
|
+
def exclude_comment
|
|
73
|
+
if @template
|
|
74
|
+
"# optional; rsync --exclude patterns picked for --template #{@template} (#{TEMPLATE_LABELS[@template]})"
|
|
75
|
+
else
|
|
76
|
+
'# optional; rsync --exclude patterns, e.g. ["node_modules", "*.log"]'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def exclude_list
|
|
81
|
+
patterns = @template ? TEMPLATE_EXCLUDES.fetch(@template) : FALLBACK_EXCLUDES
|
|
82
|
+
patterns.map { |pattern| " - #{pattern}" }.join("\n")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Appended to sync: in both templates. Every key here is either a plain constant
|
|
86
|
+
# default (safe to state literally) or, where commented, a value SyncSettings
|
|
87
|
+
# derives from another key (target from workdir, volume from the container/service
|
|
88
|
+
# name) — those stay unset so they keep tracking that key instead of going stale.
|
|
89
|
+
# A blank line separates every key from its neighbor; the gsub only indents
|
|
90
|
+
# non-blank lines so those separators stay actual blank lines, not trailing
|
|
91
|
+
# whitespace.
|
|
92
|
+
def sync_extras
|
|
93
|
+
<<~YAML.chomp.gsub(/^(?=.)/, ' ')
|
|
94
|
+
# optional; host path to mirror (default: wip.yml directory)
|
|
95
|
+
source: .
|
|
96
|
+
|
|
97
|
+
# optional; in-container mount point for the mirror (default: the container's workdir, else /app)
|
|
98
|
+
# target: /app
|
|
99
|
+
|
|
100
|
+
# optional; read-only host mount inside the container
|
|
101
|
+
mount: /host-src
|
|
102
|
+
|
|
103
|
+
# optional; named volume holding the mirrored tree (default: "<container>-src")
|
|
104
|
+
# volume: app-src
|
|
105
|
+
|
|
106
|
+
# optional; rsync --delete so removals on the host are mirrored too
|
|
107
|
+
delete: true
|
|
108
|
+
|
|
109
|
+
#{exclude_comment}
|
|
110
|
+
exclude:
|
|
111
|
+
#{exclude_list}
|
|
112
|
+
|
|
113
|
+
# optional; mirror binary to shell out to
|
|
114
|
+
command: rsync
|
|
115
|
+
|
|
116
|
+
# optional; extra flags appended to the mirror command
|
|
117
|
+
options: []
|
|
118
|
+
|
|
119
|
+
# optional; seconds between mirrors
|
|
120
|
+
interval: 2
|
|
121
|
+
|
|
122
|
+
# optional; exec (default, mirrors into the running container) | run (always a fresh container)
|
|
123
|
+
mode: exec
|
|
124
|
+
|
|
125
|
+
# only needed if sync.mode: run (or under mode: compose); image the mirror container runs
|
|
126
|
+
# image: your/image:tag
|
|
127
|
+
|
|
128
|
+
# alternative to image — let wip build a small dedicated mirror image itself
|
|
129
|
+
# build:
|
|
130
|
+
# dockerfile: |
|
|
131
|
+
# FROM alpine:latest
|
|
132
|
+
# RUN apk add --no-cache rsync
|
|
133
|
+
|
|
134
|
+
# optional (default: wip-sync-<container>:latest)
|
|
135
|
+
# tag: wip-sync-app:latest
|
|
136
|
+
YAML
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def container_template
|
|
140
|
+
<<~YAML
|
|
141
|
+
version: 1
|
|
142
|
+
|
|
143
|
+
# container | compose | compose-native (see README)
|
|
144
|
+
mode: container
|
|
145
|
+
|
|
146
|
+
# TODO: rename freely, as long as it matches a key under dependencies: below
|
|
147
|
+
container: app
|
|
148
|
+
|
|
149
|
+
wslc:
|
|
150
|
+
# optional; wslc binary/path wip shells out to ("auto" resolves it for you)
|
|
151
|
+
command: auto
|
|
152
|
+
|
|
153
|
+
# optional; container network name (mode: container only)
|
|
154
|
+
# network: my-network
|
|
155
|
+
|
|
156
|
+
dependencies:
|
|
157
|
+
# this is the container wip creates, execs into, and runs commands in
|
|
158
|
+
app:
|
|
159
|
+
# TODO: image to run
|
|
160
|
+
image: your/image:tag
|
|
161
|
+
|
|
162
|
+
# TODO: adjust to match your image, or delete this line
|
|
163
|
+
workdir: /app
|
|
164
|
+
|
|
165
|
+
# optional; keep stdin open / allocate a tty
|
|
166
|
+
interactive: false
|
|
167
|
+
|
|
168
|
+
# optional; remove the container after each run
|
|
169
|
+
remove: true
|
|
170
|
+
|
|
171
|
+
# optional; environment variables passed to the container, e.g. {FOO: bar}
|
|
172
|
+
env: {}
|
|
173
|
+
|
|
174
|
+
# optional; published ports, e.g. ["3000:3000"]
|
|
175
|
+
ports: []
|
|
176
|
+
|
|
177
|
+
# optional; extra -v specs beyond the sync mounts below
|
|
178
|
+
volumes: []
|
|
179
|
+
|
|
180
|
+
#{COMMANDS_EXAMPLE}
|
|
181
|
+
|
|
182
|
+
# optional; mirrors the source into a named volume instead of bind-mounting it live
|
|
183
|
+
sync:
|
|
184
|
+
#{sync_extras}
|
|
185
|
+
YAML
|
|
186
|
+
end
|
|
187
|
+
|
|
90
188
|
def compose_template
|
|
91
189
|
<<~YAML
|
|
92
190
|
version: 1
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
191
|
+
|
|
192
|
+
# wip parses #{compose_file} itself and drives wslc directly — no external
|
|
193
|
+
# compose-for-wslc binary needed. Prefer a real compose tool instead? Use
|
|
194
|
+
# mode: compose (see README "Compose mode") and set compose.command.
|
|
195
|
+
mode: compose-native
|
|
96
196
|
|
|
97
197
|
wslc:
|
|
98
|
-
|
|
198
|
+
# optional; wslc binary/path wip shells out to ("auto" resolves it for you)
|
|
199
|
+
command: auto
|
|
99
200
|
|
|
100
201
|
compose:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
#
|
|
202
|
+
# TODO: which service in #{compose_file} wip run/exec/NAME target
|
|
203
|
+
service: app
|
|
204
|
+
|
|
205
|
+
# optional; override which compose file wip parses (default: auto-detected)
|
|
206
|
+
# file: #{compose_file}
|
|
207
|
+
|
|
208
|
+
# optional; project/network name (default: this directory's name)
|
|
209
|
+
# project: #{compose_project_default}
|
|
210
|
+
|
|
211
|
+
# only used under mode: compose (external compose-for-wslc binary); unused here under compose-native
|
|
212
|
+
# command:
|
|
105
213
|
|
|
106
214
|
# network: is derived from compose.project above (or this directory's name) — setting it
|
|
107
215
|
# directly conflicts with compose: (ConfigError), so it's intentionally left out here.
|
|
108
216
|
|
|
109
217
|
#{COMMANDS_EXAMPLE}
|
|
110
218
|
|
|
111
|
-
|
|
112
|
-
|
|
219
|
+
# optional; mirrors the source into a named volume instead of bind-mounting it live
|
|
220
|
+
sync:
|
|
221
|
+
#{sync_extras}
|
|
113
222
|
YAML
|
|
114
223
|
end
|
|
115
224
|
end
|
data/lib/wip/version.rb
CHANGED