Class: Wip::Config
- Inherits:
-
Object
- Object
- Wip::Config
- Defined in:
- lib/wip/config.rb
Overview
Validated, defaulted access to a parsed wip.yml document.
Constant Summary collapse
- DEPENDENCY_DEFAULTS =
Applied to every dependencies: entry, primary container included — there is no separate, differently-shaped bucket for "the one you exec into."
{ 'workdir' => nil, 'user' => nil, 'interactive' => false, 'remove' => true, 'env' => {}, 'ports' => [], 'volumes' => [] }.freeze
- SECRET_PATTERN =
/token|password|secret|credential|auth/i- MODES =
Which orchestration path
up/down/sync/etc. take. Explicit rather than inferred from acompose:block's presence, so a config reader doesn't have to know that rule to predict which mode wip runs in. compose bridges to an external compose-for-wslc binary (ComposeBridge); compose-native parses compose.yml itself and drives wslc directly (ComposeFile) — a stopgap for as long as those external tools stay incomplete (missingrun, etc.). %w[container compose compose-native].freeze
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
- #command(name) ⇒ Object
- #commands ⇒ Object
- #compose ⇒ Object
- #compose? ⇒ Boolean
-
#compose_build_specs ⇒ Object
name => dockerfile:, tag: for compose-native services with a build: instead of an image: — empty otherwise.
- #compose_command ⇒ Object
- #compose_file ⇒ Object
- #compose_mode? ⇒ Boolean
- #compose_native? ⇒ Boolean
- #compose_project ⇒ Object
- #compose_service ⇒ Object
-
#container ⇒ Object
Which dependencies: entry
up/down/exec/run/build/commands:target by default — the one container wip itself considers "the app." Everything else in dependencies: is a sidecar wip only starts and stops. - #dependencies ⇒ Object
- #dependency(name) ⇒ Object
-
#initialize(raw, path = nil) ⇒ Config
constructor
A new instance of Config.
- #mode ⇒ Object
-
#network ⇒ Object
Under compose-native mode, wip creates its own project network (compose.project, or the wip.yml directory's name) so services can reach each other by name — the same guarantee real Compose's per-project network gives.
-
#primary ⇒ Object
The dependencies: entry
containerpoints at, or nil if it isn't defined. -
#raw_dependencies ⇒ Object
Raw dependencies: block as written in wip.yml.
- #sync ⇒ Object
- #sync? ⇒ Boolean
- #to_h(redact: true) ⇒ Object
- #wslc_command ⇒ Object
Constructor Details
#initialize(raw, path = nil) ⇒ Config
Returns a new instance of Config.
22 23 24 25 26 |
# File 'lib/wip/config.rb', line 22 def initialize(raw, path = nil) @raw = stringify(raw) @path = path validate! end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
20 21 22 |
# File 'lib/wip/config.rb', line 20 def path @path end |
Instance Method Details
#command(name) ⇒ Object
72 73 74 75 76 77 |
# File 'lib/wip/config.rb', line 72 def command(name) entry = commands[name.to_s] return unless entry (primary || {}).merge('type' => 'exec').merge(entry) end |
#commands ⇒ Object
29 30 31 32 |
# File 'lib/wip/config.rb', line 29 def commands = @raw['commands'] || {} # Raw dependencies: block as written in wip.yml. Under compose-native mode this stays # empty by construction (validate_compose! forbids combining the two) — #dependencies # below is what callers actually want, since it's synthesized from compose.yml there. |
#compose ⇒ Object
49 |
# File 'lib/wip/config.rb', line 49 def compose = @raw['compose'] |
#compose? ⇒ Boolean
50 |
# File 'lib/wip/config.rb', line 50 def compose? = mode == 'compose' |
#compose_build_specs ⇒ Object
name => dockerfile:, tag: for compose-native services with a build:
instead of an image: — empty otherwise. Consumed by wip up to build each one
before starting it (see CommandBuilder#build).
60 |
# File 'lib/wip/config.rb', line 60 def compose_build_specs = compose_native? ? parsed_compose_file.build_specs : {} |
#compose_command ⇒ Object
56 57 58 59 |
# File 'lib/wip/config.rb', line 56 def compose_command = compose && compose['command'] # name => {context:, dockerfile:, tag:} for compose-native services with a build: # instead of an image: — empty otherwise. Consumed by `wip up` to build each one # before starting it (see CommandBuilder#build). |
#compose_file ⇒ Object
54 |
# File 'lib/wip/config.rb', line 54 def compose_file = compose && compose['file'] |
#compose_mode? ⇒ Boolean
52 |
# File 'lib/wip/config.rb', line 52 def compose_mode? = compose? || compose_native? |
#compose_native? ⇒ Boolean
51 |
# File 'lib/wip/config.rb', line 51 def compose_native? = mode == 'compose-native' |
#compose_project ⇒ Object
55 |
# File 'lib/wip/config.rb', line 55 def compose_project = compose && compose['project'] |
#compose_service ⇒ Object
53 |
# File 'lib/wip/config.rb', line 53 def compose_service = compose && compose['service'] |
#container ⇒ Object
Which dependencies: entry up/down/exec/run/build/commands: target
by default — the one container wip itself considers "the app." Everything
else in dependencies: is a sidecar wip only starts and stops. No default:
guessing a name here (the old default was "app") either matches by luck or
fails in a way that doesn't point at the real problem (a differently-named
entry), so a project with any dependencies: must say which one explicitly.
Under compose-native mode, container: is compose.service — compose.yml already
names the service, so there's no separate container: key to set in wip.yml.
43 44 45 46 |
# File 'lib/wip/config.rb', line 43 def container = compose_native? ? compose_service : presence(@raw['container']) # Under compose-native mode, wip creates its own project network (compose.project, # or the wip.yml directory's name) so services can reach each other by name — the # same guarantee real Compose's per-project network gives. |
#dependencies ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/wip/config.rb', line 34 def dependencies = compose_native? ? parsed_compose_file.to_dependencies_hash : raw_dependencies # Which dependencies: entry `up`/`down`/`exec`/`run`/`build`/`commands:` target # by default — the one container wip itself considers "the app." Everything # else in dependencies: is a sidecar wip only starts and stops. No default: # guessing a name here (the old default was "app") either matches by luck or # fails in a way that doesn't point at the real problem (a differently-named # entry), so a project with any dependencies: must say which one explicitly. # Under compose-native mode, container: is compose.service — compose.yml already # names the service, so there's no separate container: key to set in wip.yml. |
#dependency(name) ⇒ Object
79 80 81 82 83 84 |
# File 'lib/wip/config.rb', line 79 def dependency(name) entry = dependencies[name.to_s] return unless entry DEPENDENCY_DEFAULTS.merge(entry) end |
#mode ⇒ Object
48 |
# File 'lib/wip/config.rb', line 48 def mode = @raw['mode'] || 'container' |
#network ⇒ Object
Under compose-native mode, wip creates its own project network (compose.project, or the wip.yml directory's name) so services can reach each other by name — the same guarantee real Compose's per-project network gives.
47 |
# File 'lib/wip/config.rb', line 47 def network = compose_native? ? (compose_project || default_compose_network) : @raw['network'] |
#primary ⇒ Object
The dependencies: entry container points at, or nil if it isn't defined.
70 |
# File 'lib/wip/config.rb', line 70 def primary = dependency(container) |
#raw_dependencies ⇒ Object
Raw dependencies: block as written in wip.yml. Under compose-native mode this stays empty by construction (validate_compose! forbids combining the two) — #dependencies below is what callers actually want, since it's synthesized from compose.yml there.
33 |
# File 'lib/wip/config.rb', line 33 def raw_dependencies = @raw['dependencies'] || {} |
#sync ⇒ Object
63 64 65 66 67 |
# File 'lib/wip/config.rb', line 63 def sync return @sync if defined?(@sync) @sync = @raw.key?('sync') ? build_sync : nil end |
#sync? ⇒ Boolean
61 |
# File 'lib/wip/config.rb', line 61 def sync? = !!sync |
#to_h(redact: true) ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/wip/config.rb', line 86 def to_h(redact: true) value = { 'version' => 1, 'wslc' => { 'command' => wslc_command }, 'mode' => mode, 'container' => container, 'network' => network, 'dependencies' => dependencies, 'compose' => compose, 'sync' => sync&.to_h, 'commands' => commands.transform_values do |entry| (primary || {}).merge('type' => 'exec').merge(entry) end } redact ? redact_secrets(value) : value end |
#wslc_command ⇒ Object
28 |
# File 'lib/wip/config.rb', line 28 def wslc_command = @raw.dig('wslc', 'command') || 'auto' |