vanagon 0.15.37 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +48 -23
- data/bin/build +4 -25
- data/bin/build_host_info +4 -17
- data/bin/build_requirements +4 -31
- data/bin/inspect +4 -21
- data/bin/render +4 -22
- data/bin/ship +4 -28
- data/bin/sign +4 -11
- data/bin/vanagon +7 -0
- data/extras/completions/vanagon.bash +38 -0
- data/extras/completions/vanagon.zsh +41 -0
- data/lib/vanagon.rb +1 -1
- data/lib/vanagon/cli.rb +102 -0
- data/lib/vanagon/cli/build.rb +83 -0
- data/lib/vanagon/cli/build_host_info.rb +57 -0
- data/lib/vanagon/cli/build_requirements.rb +68 -0
- data/lib/vanagon/cli/completion.rb +43 -0
- data/lib/vanagon/cli/inspect.rb +73 -0
- data/lib/vanagon/cli/list.rb +75 -0
- data/lib/vanagon/cli/render.rb +59 -0
- data/lib/vanagon/cli/ship.rb +52 -0
- data/lib/vanagon/cli/sign.rb +34 -0
- data/lib/vanagon/driver.rb +34 -28
- data/lib/vanagon/engine/always_be_scheduling.rb +271 -1
- data/lib/vanagon/engine/docker.rb +101 -14
- data/lib/vanagon/engine/pooler.rb +7 -3
- data/lib/vanagon/platform.rb +5 -3
- data/lib/vanagon/platform/deb.rb +3 -1
- data/lib/vanagon/platform/dsl.rb +11 -0
- data/lib/vanagon/platform/rpm.rb +1 -1
- data/lib/vanagon/platform/windows.rb +29 -2
- data/lib/vanagon/project.rb +23 -4
- data/lib/vanagon/project/dsl.rb +33 -0
- data/lib/vanagon/utilities.rb +30 -8
- data/resources/osx/postinstall.erb +1 -1
- data/resources/solaris/10/postinstall.erb +1 -1
- data/spec/lib/vanagon/cli_spec.rb +226 -0
- data/spec/lib/vanagon/driver_spec.rb +1 -1
- data/spec/lib/vanagon/engine/always_be_scheduling_spec.rb +113 -1
- data/spec/lib/vanagon/engine/docker_spec.rb +74 -16
- data/spec/lib/vanagon/engine/ec2_spec.rb +2 -0
- data/spec/lib/vanagon/engine/pooler_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- metadata +57 -30
- data/lib/vanagon/optparse.rb +0 -86
- data/spec/lib/vanagon/optparse_spec.rb +0 -64
@@ -0,0 +1,41 @@
|
|
1
|
+
_vanagon()
|
2
|
+
{
|
3
|
+
local line commands template_arg_commands projects
|
4
|
+
|
5
|
+
commands="build build_host_info build_requirements completion inspect list render sign ship help"
|
6
|
+
template_arg_commands=("build" "build_host_info" "build_requirements" "inspect" "render")
|
7
|
+
projects=($({ vanagon list -r | sed 1d; } 2>/dev/null))
|
8
|
+
|
9
|
+
# '%p:globbed-files:' sets completion to only offer files matching a
|
10
|
+
# described pattern.
|
11
|
+
zstyle ':completion:*' file-patterns '%p:globbed-files:'
|
12
|
+
|
13
|
+
# arguments function provides potential completions to zsh
|
14
|
+
# specs are of the form n:message:action
|
15
|
+
_arguments -C \
|
16
|
+
": :(${commands})" \
|
17
|
+
"*::arg:->args"
|
18
|
+
|
19
|
+
# (Ie)prevents "invalid subscript"
|
20
|
+
if ((template_arg_commands[(Ie)$line[1]])); then
|
21
|
+
_vanagon_template_sub_projects
|
22
|
+
fi
|
23
|
+
if [[ $projects =~ (^| )$line[2]($| ) ]]; then
|
24
|
+
_vanagon_template_sub_platforms
|
25
|
+
fi
|
26
|
+
}
|
27
|
+
|
28
|
+
_vanagon_template_sub_projects()
|
29
|
+
{
|
30
|
+
# -W look in certain path but don't append path to tab compelte
|
31
|
+
# -g enables file matching pattern
|
32
|
+
# (:r) removes the file extension `.rb` from the completion
|
33
|
+
_arguments "1: :_files -W $(PWD)/configs/projects/ -g '*.rb(:r)'"
|
34
|
+
}
|
35
|
+
|
36
|
+
_vanagon_template_sub_platforms()
|
37
|
+
{
|
38
|
+
_arguments "*: :_files -W $(PWD)/configs/platforms/ -g '*.rb(:r)'"
|
39
|
+
}
|
40
|
+
# compdef registeres the completion function: compdef <function-name> <program>
|
41
|
+
compdef _vanagon vanagon
|
data/lib/vanagon.rb
CHANGED
@@ -8,7 +8,7 @@ VANAGON_VERSION = Gem.loaded_specs["vanagon"].version.to_s
|
|
8
8
|
$:.unshift(LIBDIR) unless
|
9
9
|
$:.include?(File.dirname(__FILE__)) || $:.include?(LIBDIR)
|
10
10
|
|
11
|
-
require 'vanagon/
|
11
|
+
require 'vanagon/cli'
|
12
12
|
require 'vanagon/driver'
|
13
13
|
|
14
14
|
# The main entry point is {Vanagon::Driver}.
|
data/lib/vanagon/cli.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'vanagon/extensions/ostruct/json'
|
5
|
+
require 'vanagon/extensions/set/json'
|
6
|
+
require 'vanagon/extensions/hashable'
|
7
|
+
|
8
|
+
require 'vanagon/cli/build'
|
9
|
+
require 'vanagon/cli/build_host_info'
|
10
|
+
require 'vanagon/cli/build_requirements'
|
11
|
+
require 'vanagon/cli/completion'
|
12
|
+
require 'vanagon/cli/inspect'
|
13
|
+
require 'vanagon/cli/list'
|
14
|
+
require 'vanagon/cli/render'
|
15
|
+
require 'vanagon/cli/ship'
|
16
|
+
require 'vanagon/cli/sign'
|
17
|
+
|
18
|
+
|
19
|
+
class Vanagon
|
20
|
+
class InvalidArgument < StandardError
|
21
|
+
end
|
22
|
+
|
23
|
+
class CLI
|
24
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
25
|
+
Usage:
|
26
|
+
vanagon <command> [<args>]...
|
27
|
+
|
28
|
+
Commands are:
|
29
|
+
build build a package given a project and platform
|
30
|
+
build_host_info print information about build hosts
|
31
|
+
build_requirements print external packages required to build project
|
32
|
+
completion outputs path to tab completion script
|
33
|
+
inspect a build dry-run, printing lots of information about the build
|
34
|
+
list shows a list of available projects and platforms
|
35
|
+
render create local versions of packaging artifacts for project
|
36
|
+
sign sign a package
|
37
|
+
ship upload a package to a distribution server
|
38
|
+
help print this help
|
39
|
+
DOCOPT
|
40
|
+
|
41
|
+
def parse(argv) # rubocop:disable Metrics/AbcSize
|
42
|
+
parsed_options = parse_options(argv)
|
43
|
+
sub_command = parsed_options['<command>']
|
44
|
+
sub_argv = parsed_options['<args>']
|
45
|
+
|
46
|
+
case sub_command
|
47
|
+
when 'build'
|
48
|
+
@sub_parser = Vanagon::CLI::Build.new
|
49
|
+
when 'build_host_info'
|
50
|
+
@sub_parser = Vanagon::CLI::BuildHostInfo.new
|
51
|
+
when 'build_requirements'
|
52
|
+
@sub_parser = Vanagon::CLI::BuildRequirements.new
|
53
|
+
when 'completion'
|
54
|
+
@sub_parser = Vanagon::CLI::Completion.new
|
55
|
+
when 'inspect'
|
56
|
+
@sub_parser = Vanagon::CLI::Inspect.new
|
57
|
+
when 'render'
|
58
|
+
@sub_parser = Vanagon::CLI::Render.new
|
59
|
+
when 'list'
|
60
|
+
@sub_parser = Vanagon::CLI::List.new
|
61
|
+
when 'sign'
|
62
|
+
@sub_parser = Vanagon::CLI::Sign.new
|
63
|
+
when 'ship'
|
64
|
+
@sub_parser = Vanagon::CLI::Ship.new
|
65
|
+
when 'help'
|
66
|
+
puts DOCUMENTATION
|
67
|
+
exit 0
|
68
|
+
else
|
69
|
+
warn "vanagon: Error: unknown command: \"#{sub_command}\"\n\n#{DOCUMENTATION}"
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
|
73
|
+
raw_options = @sub_parser.parse(sub_argv)
|
74
|
+
options = @sub_parser.options_translate(raw_options)
|
75
|
+
@sub_parser.options_validate(options)
|
76
|
+
return options
|
77
|
+
end
|
78
|
+
|
79
|
+
def run(options)
|
80
|
+
@sub_parser.run(options)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Do validation of options
|
84
|
+
def options_validate(options)
|
85
|
+
options
|
86
|
+
end
|
87
|
+
|
88
|
+
# Provide a translation from parsed docopt options to older optparse options
|
89
|
+
def options_translate(docopt_options)
|
90
|
+
docopt_options
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def parse_options(argv)
|
96
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv, options_first: true })
|
97
|
+
rescue Docopt::Exit => e
|
98
|
+
puts e.message
|
99
|
+
exit 1
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
|
3
|
+
class Vanagon
|
4
|
+
class CLI
|
5
|
+
class Build < Vanagon::CLI
|
6
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
7
|
+
Usage:
|
8
|
+
build [options] <project-name> <platforms> [<targets>]
|
9
|
+
|
10
|
+
Options:
|
11
|
+
-h, --help Display help
|
12
|
+
-c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
|
13
|
+
-e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
|
14
|
+
-o, --only-build COMPONENT,COMPONENT,...
|
15
|
+
Only build listed COMPONENTs
|
16
|
+
-p, --preserve [RULE] Rule for VM preservation: never, on-failure, always
|
17
|
+
[Default: always]
|
18
|
+
-r, --remote-workdir DIRECTORY Working directory on the remote host
|
19
|
+
-s, --skipcheck Skip the "check" stage when building components
|
20
|
+
-w, --workdir DIRECTORY Working directory on the local host
|
21
|
+
-v, --verbose Only here for backwards compatibility. Does nothing.
|
22
|
+
|
23
|
+
Engines:
|
24
|
+
always_be_scheduling: default engine using Puppet's ABS infrastructure
|
25
|
+
docker: a docker container on the local host
|
26
|
+
ec2: an Amazon EC2 instance
|
27
|
+
hardware: a dedicated hardware device
|
28
|
+
local: the local machine, cannot be used with a target
|
29
|
+
pooler: [deprecated] Puppet's vmpooler
|
30
|
+
DOCOPT
|
31
|
+
|
32
|
+
def parse(argv)
|
33
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv })
|
34
|
+
rescue Docopt::Exit => e
|
35
|
+
puts e.message
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def run(options) # rubocop:disable Metrics/AbcSize
|
40
|
+
project = options[:project_name]
|
41
|
+
platform_list = options[:platforms].split(',')
|
42
|
+
target_list = []
|
43
|
+
unless options[:targets].nil? || options[:targets].empty?
|
44
|
+
target_list = options[:targets].split(',')
|
45
|
+
end
|
46
|
+
|
47
|
+
platform_list.zip(target_list).each do |pair|
|
48
|
+
platform, target = pair
|
49
|
+
artifact = Vanagon::Driver.new(platform, project, options.merge({ :target => target }))
|
50
|
+
artifact.run
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def options_translate(docopt_options)
|
55
|
+
translations = {
|
56
|
+
'--verbose' => :verbose,
|
57
|
+
'--workdir' => :workdir,
|
58
|
+
'--remote-workdir' => :"remote-workdir",
|
59
|
+
'--configdir' => :configdir,
|
60
|
+
'--engine' => :engine,
|
61
|
+
'--skipcheck' => :skipcheck,
|
62
|
+
'--preserve' => :preserve,
|
63
|
+
'--only-build' => :only_build,
|
64
|
+
'<project-name>' => :project_name,
|
65
|
+
'<platforms>' => :platforms,
|
66
|
+
'<targets>' => :targets
|
67
|
+
}
|
68
|
+
return docopt_options.map { |k, v| [translations[k], v] }.to_h
|
69
|
+
end
|
70
|
+
|
71
|
+
def options_validate(options)
|
72
|
+
# Handle --preserve option checking
|
73
|
+
valid_preserves = %w[always never on-failure]
|
74
|
+
unless valid_preserves.include? options[:preserve]
|
75
|
+
raise InvalidArgument, "--preserve option can only be one of: " +
|
76
|
+
valid_preserves.join(', ')
|
77
|
+
end
|
78
|
+
options[:preserve] = options[:preserve].to_sym
|
79
|
+
return options
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
|
3
|
+
class Vanagon
|
4
|
+
class CLI
|
5
|
+
class BuildHostInfo < Vanagon::CLI
|
6
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
7
|
+
Usage:
|
8
|
+
build_host_info [options] <project-name> <platforms>
|
9
|
+
|
10
|
+
Options:
|
11
|
+
-h, --help Display help
|
12
|
+
-c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
|
13
|
+
-e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
|
14
|
+
-w, --workdir DIRECTORY Working directory on the local host
|
15
|
+
-v, --verbose Only here for backwards compatibility. Does nothing.
|
16
|
+
|
17
|
+
Engines:
|
18
|
+
always_be_scheduling: default engine using Puppet's ABS infrastructure
|
19
|
+
docker: a docker container on the local host
|
20
|
+
ec2: an Amazon EC2 instance
|
21
|
+
hardware: a dedicated hardware device
|
22
|
+
local: the local machine, cannot be used with a target
|
23
|
+
pooler: [deprecated] Puppet's vmpooler
|
24
|
+
DOCOPT
|
25
|
+
|
26
|
+
def parse(argv)
|
27
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv })
|
28
|
+
rescue Docopt::Exit => e
|
29
|
+
puts e.message
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def run(options)
|
34
|
+
platforms = options[:platforms].split(',')
|
35
|
+
project = options[:project_name]
|
36
|
+
|
37
|
+
platforms.each do |platform|
|
38
|
+
driver = Vanagon::Driver.new(platform, project, options)
|
39
|
+
$stdout.puts JSON.generate(driver.build_host_info)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def options_translate(docopt_options)
|
44
|
+
translations = {
|
45
|
+
'--verbose' => :verbose,
|
46
|
+
'--workdir' => :workdir,
|
47
|
+
'--configdir' => :configdir,
|
48
|
+
'--engine' => :engine,
|
49
|
+
'<project-name>' => :project_name,
|
50
|
+
'<platforms>' => :platforms,
|
51
|
+
'<targets>' => :targets
|
52
|
+
}
|
53
|
+
return docopt_options.map { |k, v| [translations[k], v] }.to_h
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class Vanagon
|
5
|
+
class CLI
|
6
|
+
class BuildRequirements < Vanagon::CLI
|
7
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
8
|
+
Usage:
|
9
|
+
build_requirements [options] <project-name> <platform>
|
10
|
+
|
11
|
+
Options:
|
12
|
+
-h, --help Display help
|
13
|
+
-c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
|
14
|
+
-e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
|
15
|
+
-w, --workdir DIRECTORY Working directory on the local host
|
16
|
+
-v, --verbose Only here for backwards compatibility. Does nothing.
|
17
|
+
|
18
|
+
Engines:
|
19
|
+
always_be_scheduling: default engine using Puppet's ABS infrastructure
|
20
|
+
docker: a docker container on the local host
|
21
|
+
ec2: an Amazon EC2 instance
|
22
|
+
hardware: a dedicated hardware device
|
23
|
+
local: the local machine, cannot be used with a target
|
24
|
+
pooler: [deprecated] Puppet's vmpooler
|
25
|
+
DOCOPT
|
26
|
+
|
27
|
+
def parse(argv)
|
28
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv })
|
29
|
+
rescue Docopt::Exit => e
|
30
|
+
puts e.message
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def run(options) # rubocop:disable Metrics/AbcSize
|
35
|
+
platform = options[:platform]
|
36
|
+
project = options[:project_name]
|
37
|
+
driver = Vanagon::Driver.new(platform, project)
|
38
|
+
|
39
|
+
components = driver.project.components
|
40
|
+
component_names = components.map(&:name)
|
41
|
+
build_requirements = []
|
42
|
+
components.each do |component|
|
43
|
+
build_requirements << component.build_requires.reject do |requirement|
|
44
|
+
# only include external requirements: i.e. those that do not match
|
45
|
+
# other components in the project
|
46
|
+
component_names.include?(requirement)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
$stdout.puts
|
51
|
+
$stdout.puts "**** External packages required to build #{project} on #{platform}: ***"
|
52
|
+
$stdout.puts JSON.pretty_generate(build_requirements.flatten.uniq.sort)
|
53
|
+
end
|
54
|
+
|
55
|
+
def options_translate(docopt_options)
|
56
|
+
translations = {
|
57
|
+
'--verbose' => :verbose,
|
58
|
+
'--workdir' => :workdir,
|
59
|
+
'--configdir' => :configdir,
|
60
|
+
'--engine' => :engine,
|
61
|
+
'<project-name>' => :project_name,
|
62
|
+
'<platform>' => :platform,
|
63
|
+
}
|
64
|
+
return docopt_options.map { |k, v| [translations[k], v] }.to_h
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
|
3
|
+
class Vanagon
|
4
|
+
class CLI
|
5
|
+
class Completion < Vanagon::CLI
|
6
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
7
|
+
Usage:
|
8
|
+
completion [options]
|
9
|
+
|
10
|
+
Options:
|
11
|
+
-h, --help Display help
|
12
|
+
-s, --shell SHELL Specify shell for completion script [default: bash]
|
13
|
+
DOCOPT
|
14
|
+
|
15
|
+
def parse(argv)
|
16
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv })
|
17
|
+
rescue Docopt::Exit => e
|
18
|
+
puts e.message
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(options)
|
23
|
+
shell = options[:shell].downcase.strip
|
24
|
+
completion_file = File.expand_path(File.join('..', '..', '..', '..', 'extras', 'completions', "vanagon.#{shell}"), __FILE__)
|
25
|
+
|
26
|
+
if File.exist?(completion_file)
|
27
|
+
puts completion_file
|
28
|
+
exit 0
|
29
|
+
else
|
30
|
+
puts "Could not find completion file for '#{shell}': No such file #{completion_file}"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def options_translate(docopt_options)
|
36
|
+
translations = {
|
37
|
+
'--shell' => :shell,
|
38
|
+
}
|
39
|
+
return docopt_options.map { |k, v| [translations[k], v] }.to_h
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'docopt'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class Vanagon
|
5
|
+
class CLI
|
6
|
+
class Inspect < Vanagon::CLI
|
7
|
+
DOCUMENTATION = <<~DOCOPT.freeze
|
8
|
+
Usage:
|
9
|
+
inspect [options] <project-name> <platforms>
|
10
|
+
|
11
|
+
Options:
|
12
|
+
-h, --help Display help
|
13
|
+
-c, --configdir DIRECTORY Configuration directory [default: #{Dir.pwd}/configs]
|
14
|
+
-e, --engine ENGINE Custom engine to use [default: always_be_scheduling]
|
15
|
+
|
16
|
+
-p, --preserve [RULE] Rule for VM preservation: never, on-failure, always
|
17
|
+
[Default: on-failure]
|
18
|
+
-w, --workdir DIRECTORY Working directory on the local host
|
19
|
+
-v, --verbose Only here for backwards compatibility. Does nothing.
|
20
|
+
|
21
|
+
Engines:
|
22
|
+
always_be_scheduling: default engine using Puppet's ABS infrastructure
|
23
|
+
docker: a docker container on the local host
|
24
|
+
ec2: an Amazon EC2 instance
|
25
|
+
hardware: a dedicated hardware device
|
26
|
+
local: the local machine, cannot be used with a target
|
27
|
+
pooler: [deprecated] Puppet's vmpooler
|
28
|
+
DOCOPT
|
29
|
+
|
30
|
+
def parse(argv)
|
31
|
+
Docopt.docopt(DOCUMENTATION, { argv: argv })
|
32
|
+
rescue Docopt::Exit => e
|
33
|
+
puts e.message
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def run(options)
|
38
|
+
platforms = options[:platforms].split(',')
|
39
|
+
project = options[:project_name]
|
40
|
+
|
41
|
+
platforms.each do |platform|
|
42
|
+
driver = Vanagon::Driver.new(platform, project, options)
|
43
|
+
components = driver.project.components.map(&:to_hash)
|
44
|
+
$stdout.puts JSON.pretty_generate(components)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def options_translate(docopt_options)
|
49
|
+
translations = {
|
50
|
+
'--verbose' => :verbose,
|
51
|
+
'--workdir' => :workdir,
|
52
|
+
'--configdir' => :configdir,
|
53
|
+
'--engine' => :engine,
|
54
|
+
'--preserve' => :preserve,
|
55
|
+
'<project-name>' => :project_name,
|
56
|
+
'<platforms>' => :platforms
|
57
|
+
}
|
58
|
+
return docopt_options.map { |k, v| [translations[k], v] }.to_h
|
59
|
+
end
|
60
|
+
|
61
|
+
def options_validate(options)
|
62
|
+
# Handle --preserve option checking
|
63
|
+
valid_preserves = %w[always never on-failure]
|
64
|
+
unless valid_preserves.include? options[:preserve]
|
65
|
+
raise InvalidArgument, "--preserve option can only be one of: " +
|
66
|
+
valid_preserves.join(', ')
|
67
|
+
end
|
68
|
+
options[:preserve] = options[:preserve].to_sym
|
69
|
+
return options
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|