Skip to content

Commit

Permalink
add docker compose profiles support (bibendi#163)
Browse files Browse the repository at this point in the history
* add docker compose profiles support

```
  full:
    description: Run all services
    runner: docker_compose
    compose:
      profiles: [workers, backend]
```
Config like this will run `docker compose --profile workers --profile backend up`
command. Run options and service configs are ignored even if provided.
Can also be a part of subcommand:
```
  rails:
    description: Run Rails commands
    service: backend
    command: bundle exec rails
    subcommands:
      all:
        description: Run Rails server, Sidekiq and RabbitMQ workers
        compose:
          profiles: [workers, backend]
```

* fix rubocop findings

* do not nullify `service` option when profiles are used
  • Loading branch information
nilcolor authored May 14, 2023
1 parent f7a393e commit 62ac8d2
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 8 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ interaction:
compose:
run_options: [service-ports, use-aliases]

stack:
description: Run full stack (server, workers, etc.)
runner: docker_compose
compose:
profiles: [web, workers]

sidekiq:
description: Run sidekiq in background
service: worker
Expand Down
2 changes: 1 addition & 1 deletion lib/dip/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def down(*argv)
require_relative "commands/down_all"
Dip::Commands::DownAll.new.execute
else
compose("down", *argv)
compose("down", *argv.push("--remove-orphans"))
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/dip/commands/compose.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Compose < Dip::Command
attr_reader :argv, :config, :shell

def initialize(*argv, shell: true)
@argv = argv
@argv = argv.compact
@shell = shell
@config = ::Dip.config.compose || {}
end
Expand Down
21 changes: 21 additions & 0 deletions lib/dip/commands/runners/docker_compose_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Runners
class DockerComposeRunner < Base
def execute
Commands::Compose.new(
*compose_profiles,
command[:compose][:method],
*compose_arguments,
shell: command[:shell]
Expand All @@ -17,6 +18,16 @@ def execute

private

def compose_profiles
return [] if command[:compose][:profiles].empty?

update_command_for_profiles

command[:compose][:profiles].each_with_object([]) do |profile, argv|
argv.concat(["--profile", profile])
end
end

def compose_arguments
compose_argv = command[:compose][:run_options].dup

Expand Down Expand Up @@ -57,6 +68,16 @@ def published_ports
[]
end
end

def update_command_for_profiles
# NOTE: When using profiles, the method is always `up`.
# This is because `docker-compose` does not support profiles
# for other commands. Also, run options need to be removed
# because they are not supported by `up`.
command[:compose][:method] = "up"
command[:command] = ""
command[:compose][:run_options] = []
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/dip/interaction_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def build_command(entry)
environment: entry[:environment] || {},
compose: {
method: entry.dig(:compose, :method) || entry[:compose_method] || "run",
profiles: Array(entry.dig(:compose, :profiles)),
run_options: compose_run_options(entry.dig(:compose, :run_options) || entry[:compose_run_options])
}
}
Expand Down
12 changes: 6 additions & 6 deletions spec/lib/dip/commands/compose_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@
context "when config contains multiple docker-compose files", config: true do
context "and some files are not exist" do
let(:config) { {compose: {files: %w[file1.yml file2.yml file3.yml]}} }
let(:file1) { fixture_path("empty", "file1.yml") }
let(:file2) { fixture_path("empty", "file2.yml") }
let(:file3) { fixture_path("empty", "file3.yml") }
let(:global_file) { fixture_path("empty", "file1.yml") }
let(:local_file) { fixture_path("empty", "file2.yml") }
let(:override_file) { fixture_path("empty", "file3.yml") }

before do
allow_any_instance_of(Pathname).to receive(:exist?) do |obj|
case obj.to_s
when file1, file3
when global_file, override_file
true
when file2
when local_file
false
else
File.exist?(obj.to_s)
Expand All @@ -95,7 +95,7 @@
cli.start "compose run".shellsplit
end

it { expected_exec("docker-compose", ["--file", file1, "--file", file3, "run"]) }
it { expected_exec("docker-compose", ["--file", global_file, "--file", override_file, "run"]) }
end

context "and a file name contains env var", env: true do
Expand Down
31 changes: 31 additions & 0 deletions spec/lib/dip/commands/runners/docker_compose_runner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,22 @@
it { expected_exec("docker-compose", ["run", "--rm", "app", "rspec"], env: hash_including("RAILS_ENV" => "test")) }
end

context "when config with profiles" do
let(:commands) do
{
stack: {
runner: "docker_compose",
compose_run_options: ["foo", "-bar", "--baz=qux"],
compose: {profiles: ["foo", "bar"]}
}
}
end

before { cli.start "run stack".shellsplit }

it { expected_exec("docker-compose", ["--profile", "foo", "--profile", "bar", "up"]) }
end

context "when config with subcommands" do
let(:commands) { {rails: {service: "app", command: "rails", subcommands: subcommands}} }
let(:subcommands) { {s: {command: "rails server"}} }
Expand Down Expand Up @@ -188,5 +204,20 @@
env: hash_including("RAILS_ENV" => "test"))
end
end

context "when config with profiles" do
let(:subcommands) do
{
all: {
compose_run_options: ["foo", "-bar", "--baz=qux"],
compose: {profiles: ["foo", "bar"]}
}
}
end

before { cli.start "run rails all".shellsplit }

it { expected_exec("docker-compose", ["--profile", "foo", "--profile", "bar", "up", "app"]) }
end
end
end

0 comments on commit 62ac8d2

Please sign in to comment.