feat: support dependency containers and a shared network for wip up - #13
Conversation
`wip rails c` was reported broken again on slidict.io even after the TTY fix; the actual cause turned out to be architectural: wip only ever managed a single container, so `wip up` never started the MySQL/Redis services that config/database.yml requires (host: development.mysql), and `bin/rails c` hung forever trying to resolve a hostname that didn't exist on any network. compose.yml already models this via a bridge network + service names, but wip.yml had no equivalent. Add `defaults.network` and a `dependencies` map to wip.yml. `wip up` now creates the network first (if missing), brings up each dependency by name (reusing the same find/start-or-create flow as the main container), then starts the main container attached to that network so it can resolve dependencies by name — mirroring Compose service resolution. `wip down` tears down the main container and all dependencies (network is left in place). Verified end-to-end against a real wslc.exe + slidict.io: created the network, started development.mysql + redis + app together, confirmed DNS resolution and a live TCP connection from app to development.mysql:3306 across the shared network. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 46 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
Changes依存コンテナとネットワーク対応
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant Config
participant CommandBuilder
participant Docker
CLI->>Config: network と dependencies を取得
CLI->>CommandBuilder: network_list を生成
CLI->>Docker: ネットワーク一覧を取得
CLI->>CommandBuilder: network_create を生成
CLI->>Docker: ネットワークを作成
CLI->>CommandBuilder: dependency_find を生成
CLI->>Docker: 依存コンテナの存在を確認
CLI->>CommandBuilder: dependency_up または dependency_start を生成
CLI->>Docker: 依存コンテナを起動
CLI->>CommandBuilder: up を生成
CLI->>Docker: メインコンテナを起動
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/wip/cli.rb`:
- Around line 154-157: 既存コンテナを開始する前に配置ネットワークへの接続を保証するよう、lib/wip/cli.rb の
ensure_dependency(154-157行)と ensure_container(164-169行)を更新してください。wslc container
inspect の NetworkSettings を確認し、未接続なら network connect または再作成を start
より先に実行してください。spec/wip/cli_spec.rb(63-110行)には、未接続の既存依存コンテナとメインコンテナで接続処理または再作成が最初に呼ばれるケースを追加してください。
In `@lib/wip/command_builder.rb`:
- Around line 77-79: Update dependency_start and the corresponding
main-container start flow so existing containers are connected to the configured
defaults.network after ensure_network runs. Reapply the network to both
containers, or recreate containers with the network option when their existing
network configuration is stale, while preserving normal start behavior.
In `@lib/wip/config.rb`:
- Around line 61-64: Update validate_dependencies! to reject any dependency name
that matches defaults.container before validating dependency entries, raising
the existing configuration error with a clear message. Add or update the
configuration specification to document that dependency names must not duplicate
defaults.container.
- Around line 51-52: 構成読み込み時の検証フロー(validate_commands! と validate_dependencies!
の呼び出し箇所)に defaults.network の検証を追加し、空文字列および空白のみの値を無効として ConfigError
を即時に報告してください。これにより無効なネットワーク値が wip up まで通過しないようにし、空文字列と空白文字列の構成例も追加してください。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 69728743-23c2-4d73-80db-804989fd9322
📒 Files selected for processing (7)
README.mdlib/wip/cli.rblib/wip/command_builder.rblib/wip/config.rbspec/wip/cli_spec.rbspec/wip/command_builder_spec.rbspec/wip/config_spec.rb
| def ensure_dependency(name) | ||
| if resource_exists?(builder.dependency_find(name)) | ||
| warn "wip: starting existing dependency '#{name}'" | ||
| execute(builder.dependency_start(name)) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ast-grep outline lib/wip/command_builder.rb --items all
rg -nP -C 4 \
'def\s+(up|start|dependency_up|dependency_start|network_\w+)|network\s+(connect|inspect)|\binspect\b' \
lib/wip/command_builder.rb lib/wip/cli.rb spec/wip/cli_spec.rbRepository: slidict/wip
Length of output: 3899
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,190p' lib/wip/cli.rb
printf '\n--- spec snippet ---\n'
sed -n '1,140p' spec/wip/cli_spec.rb
printf '\n--- relevant builder methods ---\n'
sed -n '20,115p' lib/wip/command_builder.rbRepository: slidict/wip
Length of output: 13733
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- all network-related occurrences ---'
rg -n -C 3 '"network"|network|Network|networks|container.*network|Containers' lib spec
printf '%s\n' '--- CLI test coverage around existing containers/networks ---'
rg -n -C 3 "existing|network|dependency|connect|start app|start redis|app-tier" spec/lib spec/wip lib/wip/cli.rb spec/wip/cli_spec.rbRepository: slidict/wip
Length of output: 25675
🌐 Web query:
wslc net container inspect networks JSON
💡 Result:
In the WSL container feature (WSL Containers), the command to inspect a container's networking configuration is: wslc container inspect <container_id_or_name> The wslc CLI (available in Windows Subsystem for Linux public preview as of July 2026) outputs container information in JSON format [1]. When you run the inspect command, the output includes a NetworkSettings object within the container's inspection data [2]. The InspectContainer schema, which dictates the structure of this JSON output, is defined in the WSL codebase [2]. The NetworkSettings section contains details about the networks the container is connected to, specifically mapping network names to endpoint settings (represented as an InspectEndpointSettings object) [2]. Because wslc commands like container inspect are designed to output structured JSON directly to the console [1], you can pipe or redirect this output as needed for parsing or further processing. [1].
Citations:
- 1: https://github.com/microsoft/WSL/blob/4f48477d/src/windows/wslc/tasks/ContainerTasks.cpp
- 2: https://github.com/microsoft/WSL/blob/4f48477d/src/windows/inc/wslc_schema.h
🌐 Web query:
Microsoft WSL wslc container inspect NetworkSettings endpoints configuration
💡 Result:
In the Microsoft Windows Subsystem for Linux (WSL) container feature, the wslc CLI tool uses an inspection mechanism to retrieve detailed information about containers, which includes their network configurations [1][2]. ### Inspecting Network Settings To view the network configuration of a container, you use the wslc container inspect command (or the Inspect method in the WSL container API) [1][2]. The output is a JSON-formatted structure that maps to an internal schema [2]. The NetworkSettings configuration within this inspection data is defined by an InspectNetworkSettings object [3]. This object primarily contains a map of InspectEndpointSettings keyed by the network name [3]: - InspectNetworkSettings: Contains a collection (std::map) of network endpoints associated with the container [3]. - InspectEndpointSettings: Represents the configuration for a specific network endpoint, which may include settings such as IP addresses, network aliases, links, and driver-specific options [3][4][5]. ### Context and Usage - CLI Interaction: The wslc binary allows you to manage containers with a familiar interface, supporting commands like wslc container inspect <container_id> [6][7]. This command triggers the backend Inspect logic, which gathers the container state, configuration, and network settings, then outputs the result as JSON [1][2]. - API Layer: For developers using the WSL container API (available via NuGet), the Container object provides an Inspect method that returns an InspectContainer structure [8][7]. This structure includes the NetworkSettings field, allowing programmatic access to the container's network topology, including endpoints created via wslc container run or wslc network connect [1][4]. - Network Capabilities: Recent updates have extended the endpoint configuration to support Docker-style settings such as --network-alias, --ip, --link, --link-local-ip, and --driver-opt [4][5]. These endpoint configurations are persisted and surfaced through the inspection flow, enabling the retrieval of detailed network state [4][5]. For further details on the exact schema structure, you can refer to the wslc_schema.h file in the official Microsoft WSL repository [3].
Citations:
- 1: https://github.com/microsoft/WSL/blob/5744201d/src/windows/wslc/services/ContainerService.cpp
- 2: https://github.com/microsoft/WSL/blob/4f48477d/src/windows/wslc/tasks/ContainerTasks.cpp
- 3: https://github.com/microsoft/WSL/blob/4f48477d/src/windows/inc/wslc_schema.h
- 4: Add --ip, --link, --link-local-ip, --driver-opt, --network-alias flag… microsoft/WSL#41070
- 5: Support Docker-style network aliases in wslc microsoft/WSL#40972
- 6: https://devblogs.microsoft.com/commandline/wsl-container-is-now-available-for-public-preview/
- 7: https://learn.microsoft.com/en-us/windows/wsl/wsl-container
- 8: https://learn.microsoft.com/en-us/windows/wsl/wsl-container?tabs=csharp
既存コンテナの共有ネットワーク接続を保証してください。
up は配置ネットワークを作成/存在確認するだけで、既存の依存コンテナ・メインコンテナがそのネットワークに接続済みであるとは限りません。
lib/wip/cli.rbのensure_dependencyとensure_containerは、既存リソースに対してstartだけを実行します。- 配置ネットワークが存在する既存コンテナの場合、
start前にwslc container inspectでNetworkSettingsにそのネットワークのエンターポイントがあるか確認し、未接続ならnetwork connectするか再作成してください。 spec/wip/cli_spec.rbにも既存かつ未接続の依存コンテナ・メインコンテナのケースを追加し、接続または再作成が最初に実行されることを検証してください。
📍 Affects 2 files
lib/wip/cli.rb#L154-L157(this comment)lib/wip/cli.rb#L164-L169spec/wip/cli_spec.rb#L63-L110
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/wip/cli.rb` around lines 154 - 157,
既存コンテナを開始する前に配置ネットワークへの接続を保証するよう、lib/wip/cli.rb の ensure_dependency(154-157行)と
ensure_container(164-169行)を更新してください。wslc container inspect の NetworkSettings
を確認し、未接続なら network connect または再作成を start
より先に実行してください。spec/wip/cli_spec.rb(63-110行)には、未接続の既存依存コンテナとメインコンテナで接続処理または再作成が最初に呼ばれるケースを追加してください。
| def dependency_start(name) | ||
| [@wslc, 'start', name.to_s] | ||
| end |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 4 --glob '*.rb' \
'\b(network\s+(connect|disconnect)|dependency_start|ensure_dependency|ensure_container|start\s*\()' \
lib specRepository: slidict/wip
Length of output: 7251
🌐 Web query:
Does Microsoft WSLC start attach an existing container to a newly configured network? If not, what command connects an existing container to a network?
💡 Result:
The wslc start command is used to start an existing container, but it does not connect a container to a new network [1]. To connect an existing container to a network, you should use the wslc network connect command [2][3]. The wslc network connect command allows you to add an existing container to a specified network [2][3]. It supports various flags to configure the connection, including: - --network-alias: Defines a network alias for the container [3]. - --ip: Assigns a static IP address on the network [3]. - --link: Adds network links [3]. - --link-local-ip: Specifies link-local IP addresses [3]. - --driver-opt: Provides arbitrary driver options [3]. The WSL container feature, introduced in 2026, provides the wslc.exe CLI for managing containers, images, and networks [4][5]. While container networking configuration (such as the initial network) is often handled during the create or run phases [6][3], wslc network connect provides the mechanism for modifying the network membership of an existing, provisioned container [2][3].
Citations:
- 1: https://github.com/microsoft/WSL/blob/master/src/windows/wslc/services/ContainerService.cpp
- 2: Add wslc network connect and disconnect commands microsoft/WSL#41011
- 3: Add --ip, --link, --link-local-ip, --driver-opt, --network-alias flag… microsoft/WSL#41070
- 4: microsoft/WSL@358ab87
- 5: https://devblogs.microsoft.com/commandline/wsl-container-is-now-available-for-public-preview/
- 6: Support Docker-style network aliases in wslc microsoft/WSL#40972
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- command_builder.rb relevant ---\n'
sed -n '1,140p' lib/wip/command_builder.rb
printf '\n--- cli.rb ensure dependency/container/network ---\n'
sed -n '1,240p' lib/wip/cli.rb
printf '\n--- tests around existing containers and network ordering ---\n'
sed -n '30,120p' spec/wip/cli_spec.rbRepository: slidict/wip
Length of output: 240
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- command_builder.rb relevant ---'
sed -n '1,140p' lib/wip/command_builder.rb
echo
echo '--- cli.rb ensure dependency/container/network ---'
sed -n '1,240p' lib/wip/cli.rb
echo
echo '--- tests around existing containers and network ordering ---'
sed -n '30,120p' spec/wip/cli_spec.rbRepository: slidict/wip
Length of output: 14269
既存コンテナを network に接続してください。
up では ensure_network を先に実行していますが、既存の main container と dependency container はそれぞれ start / dependency_start のみで起動されます。wslc start は既存コンテナの network 配置を変更しないため、defaults.network を後から追加した既存コンテナは shared network に入っていません。network の再適用で両方を接続するか、古い network 配置を持つ場合は再作成して --network を渡してください。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/wip/command_builder.rb` around lines 77 - 79, Update dependency_start and
the corresponding main-container start flow so existing containers are connected
to the configured defaults.network after ensure_network runs. Reapply the
network to both containers, or recreate containers with the network option when
their existing network configuration is stale, while preserving normal start
behavior.
| validate_commands! | ||
| validate_dependencies! |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
defaults.network を構成読み込み時に検証してください。
defaults.network: "" は現在通過します。Ruby では空文字列が真値なので、CLI はネットワーク作成を試み、後で required_network が ConfigError を送出します。空白だけの値も拒否してください。無効な値は wip up ではなく構成読み込み時に報告してください。
修正案
def validate!
raise ConfigError, "Unsupported configuration version: #{`@raw`['version']}" unless (`@raw`['version'] || 1) == 1
raise ConfigError, 'up must be a mapping' if `@raw.key`?('up') && !`@raw`['up'].is_a?(Hash)
validate_commands!
validate_dependencies!
+ validate_network!
end
+
+def validate_network!
+ network = `@raw.dig`('defaults', 'network')
+ return if network.nil?
+
+ unless network.is_a?(String) && !network.strip.empty?
+ raise ConfigError, 'defaults.network must be a non-empty string'
+ end
+enddefaults.network: "" と空白文字列の構成例も追加してください。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/wip/config.rb` around lines 51 - 52, 構成読み込み時の検証フロー(validate_commands! と
validate_dependencies! の呼び出し箇所)に defaults.network の検証を追加し、空文字列および空白のみの値を無効として
ConfigError を即時に報告してください。これにより無効なネットワーク値が wip up
まで通過しないようにし、空文字列と空白文字列の構成例も追加してください。
| def validate_dependencies! | ||
| raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash) | ||
|
|
||
| dependencies.each { |name, entry| validate_dependency!(name, entry) } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
依存コンテナ名と defaults.container の重複を拒否してください。
依存名が main container 名と同じ場合、up は先に依存コンテナを作成します。その後、main container の検索が同じコンテナを検出します。結果として main container は作成されず、down は同じコンテナを複数回停止・削除しようとします。
修正案
def validate_dependencies!
raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash)
- dependencies.each { |name, entry| validate_dependency!(name, entry) }
+ dependencies.each do |name, entry|
+ if name == defaults['container'].to_s
+ raise ConfigError, "dependencies.#{name} must not match defaults.container"
+ end
+
+ validate_dependency!(name, entry)
+ end
enddependencies に defaults.container と同じ名前を設定した場合の仕様も追加してください。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def validate_dependencies! | |
| raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash) | |
| dependencies.each { |name, entry| validate_dependency!(name, entry) } | |
| def validate_dependencies! | |
| raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash) | |
| dependencies.each do |name, entry| | |
| if name == defaults['container'].to_s | |
| raise ConfigError, "dependencies.#{name} must not match defaults.container" | |
| end | |
| validate_dependency!(name, entry) | |
| end |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/wip/config.rb` around lines 61 - 64, Update validate_dependencies! to
reject any dependency name that matches defaults.container before validating
dependency entries, raising the existing configuration error with a clear
message. Add or update the configuration specification to document that
dependency names must not duplicate defaults.container.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Investigated the report that
wip rails cwas still broken on slidict.io even with the interactive-TTY fix (#11) in place. Root cause turned out to be architectural, not a bug in the Ruby code:wip.ymlonly ever describes one container (defaults).wip uphad no way to start anything else.config/database.ymlconnects tohost: development.mysql, andcompose.ymlalso depends onredis— both defined as separate Compose services on a shared bridge network with DNS aliases.wip uponly startedapp(no network, no mysql/redis),bin/rails chung indefinitely trying to resolvedevelopment.mysql, which is exactly what I reproduced: multiple stuckbin/rails cprocesses piling up inside the container, and a direct TCP connect confirming there was nothing listening.This is a real gap, not something fixable by tweaking
CommandRunner/CommandBuilder— wip needed a way to model dependency containers.Change
defaults.network(optional) and top-leveldependenciesmap inwip.yml:wip up: creates the network first if it doesn't exist, then brings up each dependency (same quiet find → start-or-create flow already used for the main container), then starts the main container attached to that network — so it can resolve dependencies by name, mirroring Compose service DNS.wip down: tears down the main container and all dependencies (network is left in place; shared infra, not owned by a single teardown).CommandBuilder:network_create/network_list,dependency_up/dependency_start/dependency_find/dependency_down/dependency_remove.Config:dependencies,dependency(name),network, with validation (must be a mapping, each entry needsimage).Verification
bundle exec rspec(38 examples, 0 failures) — added specs forConfig#dependency/#network, all the newCommandBuildermethods, and aCLIspec asserting the fullwip upcommand sequence (network list → network create → dependency find → dependency run → container find → container run).bundle exec rubocop(no offenses)wslc.exewith slidict.io: addednetwork: slidict-app-tier+development.mysql/redisto itswip.yml, ranwip up -d, confirmed all three containers came up on the shared network,getent hosts development.mysql redisresolved from insideapp, and a live TCP connect fromapptodevelopment.mysql:3306succeeded. (Reverted thatwip.ymlchange afterward — it's the user's file to opt into.)🤖 Generated with Claude Code
Summary by CodeRabbit
新機能
ドキュメント
up・downコマンドの利用方法を追加・更新しました。