Class: Wip::CLI

Inherits:
Thor
  • Object
show all
Defined in:
lib/wip/cli.rb

Overview

Thor-based command-line interface for wip.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.dispatch(meth, given_args, given_opts, config) ⇒ Object

Thor only falls back to the default task when no command name is given at all; an unrecognized first argument (e.g. a custom wip.yml command name) would otherwise raise "Could not find command". Route those to dispatch.



24
25
26
27
28
29
30
31
# File 'lib/wip/cli.rb', line 24

def self.dispatch(meth, given_args, given_opts, config)
  name = given_args.first
  if meth.nil? && name && !name.to_s.start_with?('-') && find_command_possibilities(name).empty?
    return super('dispatch', given_args, given_opts, config)
  end

  super
end

.exit_on_failure?Boolean

Returns:

  • (Boolean)


19
# File 'lib/wip/cli.rb', line 19

def self.exit_on_failure? = true

Instance Method Details

#build(*extra) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/wip/cli.rb', line 67

def build(*extra)
  extra.shift if extra.first == '--'
  settings = load_config.command('build') || {}
  context = settings['context'] || '.'
  BuildContext.new(context).stage do |staged_context|
    execute(builder.build(settings: settings.merge('context' => staged_context), extra: extra))
  end
end

#configObject



62
63
64
# File 'lib/wip/cli.rb', line 62

def config
  puts YAML.dump(load_config.to_h)
end

#dispatch(name = nil, *arguments) ⇒ Object

Raises:



164
165
166
167
168
169
170
171
# File 'lib/wip/cli.rb', line 164

def dispatch(name = nil, *arguments)
  raise ConfigError, 'A command is required' unless name

  values = load_config.command(name) || raise(ConfigError, "Unknown command: #{name}")
  return dispatch_compose(name, values, arguments) if load_config.compose?

  execute(builder.custom(name, arguments), interactive: tty?(values.fetch('interactive', false)))
end

#doctorObject



55
56
57
58
59
# File 'lib/wip/cli.rb', line 55

def doctor
  results = Doctor.new(loader: loader).call
  results.each { |item| puts "[#{item.level.to_s.upcase}] #{item.message}" }
  exit(1) if results.any? { |item| item.level == :fail }
end

#downObject



112
113
114
115
116
117
118
119
120
121
# File 'lib/wip/cli.rb', line 112

def down
  return execute(compose_bridge.down, exit_on_failure: false) if load_config.compose?

  execute(builder.down, exit_on_failure: false)
  execute(builder.remove, exit_on_failure: false)
  sidecar_names.each do |name|
    execute(builder.dependency_down(name), exit_on_failure: false)
    execute(builder.dependency_remove(name), exit_on_failure: false)
  end
end

#exec(*command) ⇒ Object



125
126
127
# File 'lib/wip/cli.rb', line 125

def exec(*command)
  execute(exec_target(command, interactive: options[:interactive]), interactive: tty?(options[:interactive]))
end

#initObject

Raises:



45
46
47
48
49
50
51
52
# File 'lib/wip/cli.rb', line 45

def init
  path = Pathname(options[:config] || ConfigLoader::FILENAME).expand_path
  raise Error, "#{path} already exists (use --force to overwrite)" if path.file? && !options[:force]

  initializer = Initializer.new(dir: path.dirname)
  path.write(initializer.call)
  warn "wip: wrote #{path} (mode: #{initializer.compose? ? 'compose' : 'container'})"
end

#logs(*services) ⇒ Object

Raises:



157
158
159
160
161
# File 'lib/wip/cli.rb', line 157

def logs(*services)
  raise ConfigError, '`wip logs` is only available in compose mode' unless load_config.compose?

  execute(compose_bridge.logs(services: services, follow: options[:follow]), interactive: true)
end

#run_command(*command) ⇒ Object



131
132
133
134
135
136
137
138
139
140
# File 'lib/wip/cli.rb', line 131

def run_command(*command)
  if load_config.compose?
    warn "wip: compose mode has no ephemeral 'run'; executing in the running " \
         "'#{load_config.compose_service}' service instead"
    return execute(exec_target(command, interactive: options[:interactive]),
                   interactive: tty?(options[:interactive]))
  end

  execute(builder.run(command, interactive: options[:interactive]), interactive: tty?(options[:interactive]))
end

#shell_commandObject



144
145
146
147
148
149
150
151
152
# File 'lib/wip/cli.rb', line 144

def shell_command
  configured = load_config.command('shell')
  return dispatch('shell') if configured

  code = execute(exec_target(['bash'], interactive: true), interactive: tty?(true), exit_on_failure: false)
  return if code.zero?

  execute(exec_target(['sh'], interactive: true), interactive: tty?(true))
end

#syncObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/wip/cli.rb', line 94

def sync
  settings = sync_settings!
  warn_shadowed_command('sync')
  ensure_sync_image(settings)
  return run_sync unless options[:watch]

  interval = watch_interval(settings)
  warn "wip: syncing #{settings.source} -> #{settings.volume}:#{settings.target} " \
       "every #{interval}s (Ctrl-C to stop)"
  loop do
    run_sync(exit_on_failure: false)
    sleep interval
  end
rescue Interrupt
  warn "\nwip: sync stopped"
end

#upObject



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/wip/cli.rb', line 79

def up
  if load_config.compose?
    sync_before_boot if options[:sync]
    return execute(compose_bridge.up(detach: options[:detach]), interactive: tty?(!options[:detach]))
  end

  ensure_network
  sidecar_names.each { |name| ensure_dependency(name) }
  sync_before_boot if options[:sync]
  ensure_container
end

#versionObject



34
35
36
37
38
39
40
41
# File 'lib/wip/cli.rb', line 34

def version
  puts "wip #{VERSION}"
  config = load_config
  command = resolver.resolve(config.wslc_command)
  system(command, 'version')
rescue Error
  nil
end