Class: DCE

Inherits:
Object
  • Object
show all
Defined in:
lib/dce.rb

Overview

The dce commmand class.

Instance Method Summary collapse

Instance Method Details

#containersObject

Read containers from docker-compose.yml



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dce.rb', line 130

def containers
  unless @containers
    # Older Psychs took whether to allow YAML aliases as a fourth
    # argument, while newer has a keyword argument. Try both to be
    # compatible with as many versions as possible.
    begin
      content = YAML.safe_load(File.read(docker_compose_file), aliases: true)
    rescue ArgumentError
      content = YAML.safe_load(File.read(docker_compose_file), [], [], true)
    end
    @containers = content.key?('services') ? content['services'].keys : content.keys
  end

  @containers
end

#docker_compose_fileObject

Return path to the docker-compose.yml file Will exit with an error if not found



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/dce.rb', line 52

def docker_compose_file
  unless @compose_file
    dir = Dir.pwd
    while dir != '/'
      file = Dir.glob('docker-compose.{yml,yaml}', base: dir).first
      if file
        @compose_file = File.join(dir, file)
        break
      end
      dir = File.dirname(dir)
    end

    abort 'No docker-compose.yml file found.' unless @compose_file
  end

  @compose_file
end

#parse_argsObject

Parse command line arguments



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/dce.rb', line 71

def parse_args
  # Not using a proper option parse library, as it will get confused
  # by options for the command given. We use a simple parser.
  while /^-/ =~ ARGV[0]
    option = ARGV.shift
    case option
    when '-c', '--container'
      @container = ARGV.shift
      abort "Unknown container #{@container}" unless containers.include? @container
    when '-v', '--verbose'
      @verbose = true
    when '-n', '--dry-run'
      @verbose = true
      @dry_run = true
    when '-?', '--print-service'
      @query = true
    when '-l', '--list-containers'
      @list_containers = true
    when '-h', '--help'
      warn "        Usage: \#{File.basename($PROGRAM_NAME)} [OPTIONS]... COMMAND\n        Runs COMMAND in docker compose container.\n\n        On first run, asks for the service container to use and saves it to .dce_container next\n        to the docker-compose.yml file.\n\n        If no command given, opens a shell.\n\n        Options:\n          -c, --container SERVICE     use the container of the specified service\n                            replaces the selected container in the .dce_container\n          -v, --verbose               print exec'ed command\n          -n, --dry-run               only print exec'ed command, don't run\n          -?, --print-service         print the service saved\n          -l, --list-containers       print the containers available\n          -h, --help                  print this help and exit\n\n      HEREDOC\n      exit\n    else\n      abort \"Unknown option \#{option}\"\n    end\n  end\n\n  @command = ARGV.join(' ')\nend\n"

#query_containerObject

Ask the user to select a container The options are taken from the docker-compose.yml file



120
121
122
123
124
125
126
127
# File 'lib/dce.rb', line 120

def query_container
  warn "Please select container [#{containers.join(', ')}]"
  choice = $stdin.gets.strip
  exit if choice.empty?

  abort 'Illegal choice.' unless containers.include?(choice)
  choice
end

#runObject

Run the command



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/dce.rb', line 10

def run
  parse_args

  @conf_file = File.join(File.dirname(docker_compose_file), '.dce_container')
  config_container = nil
  config_container = File.read(@conf_file) if File.exist? @conf_file

  if @list_containers
    $stdout.puts(containers.join(', '))
    exit
  end

  if @query
    if config_container
      $stdout.puts(config_container)
      exit
    else
      abort 'No container saved.'
    end
  end

  @container ||= config_container || query_container

  File.write(@conf_file, @container) if @container != config_container

  # If no command given, open a shell.
  if @command.strip.empty?
    @command = 'if [ -e /usr/bin/fish ]; then /usr/bin/fish; elif [ -e /bin/bash ]; then /bin/bash; else /bin/sh; fi'
  end

  container_id = `docker compose ps -q #{@container}`.chomp

  abort("Container #{@container} not created.") if container_id.empty?

  tty = $stdin.tty? ? 't' : ''
  command = "docker exec -i#{tty} #{container_id} sh -c '#{@command}'"
  warn "Exec'ing: #{command}" if @verbose
  exec command unless @dry_run
end