wip logo

wip

Tests Gem Version License: MIT Ruby

Homepage: https://wslc-wip.slidict.com/ · Full documentation: wip Wiki

wip is a Ruby-built OSS CLI wrapper that brings a dip-like workflow to Microsoft WSLC. It collects a project's container, image, environment variables, and commands into a single wip.yml, and forwards them to wslc.exe / wslc as safe argument arrays (no shell interpolation).

wip demo

Status: early release. Expect to track WSLC's own interface as it evolves.

This README covers the fastest path to a running wip.yml. For everything else — every config key, every command's flags, guides, and troubleshooting — see the wip Wiki.

Contents

Which mode should you use?

wip.yml runs in one of three modes, set with mode:. Pick the one that matches your project:

Situation Use
No compose.yml — wip manages containers directly mode: container (default)
Have compose.yml, don't want to install a third-party tool mode: compose-native
Have compose.yml and already use/prefer a third-party compose-for-wslc tool mode: compose

wip init picks compose-native automatically when it finds a compose.yml, compose.yaml, docker-compose.yml, or docker-compose.yaml next to it, and container otherwise — see Commands. For the full breakdown and trade-offs, see Choosing a Mode on the wiki.

Requirements & installation

Ruby 3.2+, WSL2, and Microsoft WSLC.

gem install wslc-wip

From source: bundle install && bundle exec exe/wip version.

Quick start

This walks through mode: container (the default). Already have a compose.yml? See Which mode should you use? first, or read the wiki's Getting Started guide.

gem install wslc-wip
cd my-project
wip init   # writes a starter wip.yml; edit the TODOs, then:
wip doctor
wip build
wip up -d
wip rails console

Configuration

Put a wip.yml in your project root. Running from a subdirectory walks up to find it, or pass --config PATH to point at one explicitly.

version: 1
mode: container # default
wslc:
  command: auto # tries wslc.exe, wslc, then System32; an absolute path also works
container: app # required once dependencies: has entries; which one `up`/`exec`/`run`/`build`/`interaction:`
               # target. No default — a project must say which entry is the primary one explicitly.
network: app-tier # optional; shared by every dependencies: entry so containers can resolve each other by name
dependencies:
  app: # container: points here — the one container wip execs into and runs commands in
    image: slidict/slidict:development
    workdir: /app
    interactive: false
    remove: true
    command: server # extra args appended when `wip up` creates the container
                     # (omit to use the image's default CMD)
    env:
      RAILS_ENV: development
      PORT: "3000"
    ports:
      - "3000:3000"
    volumes:
      - ".:/app"
  redis:
    image: redis:latest
  development.mysql:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    env:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: development
interaction:
  rails:
    type: exec
    command: bin/rails
    container: app
    interactive: true
    workdir: /app
    env:
      RAILS_ENV: development
  bundle:
    command: bundle
  rspec:
    command: bundle exec rspec
  shell:
    command: bash
    interactive: true
  migrate:
    type: run
    command: bundle exec rails db:migrate
    image: slidict/slidict:development
    remove: true
  build:
    type: build
    context: .
    tag: slidict/slidict:development
    shadow_context: /mnt/c/Users/me/AppData/Local/wip/build-contexts
sync: # optional; mirror the source into a named volume instead of bind-mounting it live
  exclude:
    - .git
    - tmp/
    - node_modules/

env values are stringified. wip config masks any key matching token, password, secret, credential, or auth. Keep real secrets out of the config file and in your runtime environment instead — see Secret Masking.

interaction: can also be spelled commands: — the same block under a different name, e.g. for projects that already use commands:. The two are aliases for the same feature; declaring both in the same wip.yml is a ConfigError. See Interactions.

Every key above is covered across the wiki's feature pages, with the full behavior, edge cases, and examples — start at the Configuration Reference. Notably:

Commands

Command Description
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
wip version wip's version, plus WSLC's if it can be detected
wip doctor Diagnose WSL2, interop, WSLC, config, architecture, and Git
wip config Print the effective configuration (secrets masked)
wip build [--no-cache] [-- OPTIONS] Build the image from the build definition
wip up [-d] [--no-sync] [--no-cache] [--watch] [--interval N] Start the configured stack, creating it if necessary
wip stop Stop the configured stack without removing it
wip down Stop and remove the configured stack
wip exec [--no-interactive] COMMAND... Run a command in the existing container
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)
wip shell Open the configured shell, falling back to bash then sh
wip logs [-f] [SERVICE...] Follow compose service logs (compose modes only; under mode: compose-native, at most one SERVICE)
`wip sync [-w\ --watch] [--interval N]` Mirror the source into the sync volume once, or keep re-syncing with --watch (needs sync:)
wip NAME ARGS... Run interaction.NAME, appending any extra arguments

Every command has flags, per-mode behavior, and examples on its own wiki page — see the CLI Command Reference.

Pass --debug (or set WIP_DEBUG=1) to see where time is going: wip prints each step it takes, along with a periodic host resource snapshot (load, memory, disk I/O, top processes), so a hang is visible even before a command produces output. See Debug Output for the full behavior and the --debug-log option.

wip doctor prints [OK]/[WARN]/[FAIL] per check; warnings alone exit 0, a blocking problem exits 1. See wip doctor.

Common errors

More errors, causes, and fixes are indexed on the wiki's Troubleshooting & FAQ page, including Configuration Errors (every ConfigError and what triggers it).

Development

git clone https://github.com/slidict/wip.git
cd wip
bundle install
bundle exec rspec
bundle exec rubocop
bundle exec rake

The test suite doesn't need WSLC — the resolution, build, and execution layers are all swappable. This project uses RuboCop for Ruby style and static analysis; bundle exec rake runs both RSpec and RuboCop. GitHub Actions checks them on Ruby 3.2, 3.3, 3.4, and 4.0. See Development and Architecture on the wiki for more.

Contributing

Bug reports and pull requests are welcome on GitHub. See CONTRIBUTING.md for commit conventions, versioning policy, and the PR checklist.

License

MIT License