leap_cli 1.8.1 → 1.9
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/bin/leap +6 -12
- data/lib/leap_cli.rb +3 -23
- data/lib/leap_cli/bootstrap.rb +36 -12
- data/lib/leap_cli/commands/common.rb +88 -46
- data/lib/leap_cli/commands/new.rb +24 -17
- data/lib/leap_cli/commands/pre.rb +3 -1
- data/lib/leap_cli/core_ext/hash.rb +19 -0
- data/lib/leap_cli/leapfile.rb +47 -32
- data/lib/leap_cli/log.rb +196 -88
- data/lib/leap_cli/path.rb +5 -5
- data/lib/leap_cli/util.rb +28 -18
- data/lib/leap_cli/version.rb +8 -3
- data/vendor/acme-client/lib/acme-client.rb +1 -0
- data/vendor/acme-client/lib/acme/client.rb +122 -0
- data/vendor/acme-client/lib/acme/client/certificate.rb +30 -0
- data/vendor/acme-client/lib/acme/client/certificate_request.rb +111 -0
- data/vendor/acme-client/lib/acme/client/crypto.rb +98 -0
- data/vendor/acme-client/lib/acme/client/error.rb +16 -0
- data/vendor/acme-client/lib/acme/client/faraday_middleware.rb +123 -0
- data/vendor/acme-client/lib/acme/client/resources.rb +5 -0
- data/vendor/acme-client/lib/acme/client/resources/authorization.rb +44 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges.rb +6 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/base.rb +43 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb +19 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb +18 -0
- data/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb +24 -0
- data/vendor/acme-client/lib/acme/client/resources/registration.rb +37 -0
- data/vendor/acme-client/lib/acme/client/self_sign_certificate.rb +60 -0
- data/vendor/acme-client/lib/acme/client/version.rb +7 -0
- data/vendor/base32/lib/base32.rb +67 -0
- data/vendor/certificate_authority/lib/certificate_authority.rb +2 -1
- data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +4 -4
- data/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb +7 -5
- data/vendor/certificate_authority/lib/certificate_authority/core_extensions.rb +46 -0
- data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +6 -2
- data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +10 -3
- data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +11 -9
- data/vendor/certificate_authority/lib/certificate_authority/ocsp_handler.rb +3 -3
- data/vendor/certificate_authority/lib/certificate_authority/pkcs11_key_material.rb +0 -2
- data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +8 -2
- data/vendor/certificate_authority/lib/certificate_authority/validations.rb +31 -0
- data/vendor/rsync_command/lib/rsync_command.rb +49 -12
- metadata +50 -91
- data/lib/leap/platform.rb +0 -90
- data/lib/leap_cli/config/environment.rb +0 -180
- data/lib/leap_cli/config/filter.rb +0 -178
- data/lib/leap_cli/config/manager.rb +0 -419
- data/lib/leap_cli/config/node.rb +0 -77
- data/lib/leap_cli/config/object.rb +0 -428
- data/lib/leap_cli/config/object_list.rb +0 -209
- data/lib/leap_cli/config/provider.rb +0 -22
- data/lib/leap_cli/config/secrets.rb +0 -87
- data/lib/leap_cli/config/sources.rb +0 -11
- data/lib/leap_cli/config/tag.rb +0 -25
- data/lib/leap_cli/lib_ext/capistrano_connections.rb +0 -16
- data/lib/leap_cli/logger.rb +0 -237
- data/lib/leap_cli/remote/leap_plugin.rb +0 -192
- data/lib/leap_cli/remote/puppet_plugin.rb +0 -26
- data/lib/leap_cli/remote/rsync_plugin.rb +0 -35
- data/lib/leap_cli/remote/tasks.rb +0 -51
- data/lib/leap_cli/ssh_key.rb +0 -195
- data/lib/leap_cli/util/remote_command.rb +0 -158
- data/lib/leap_cli/util/secret.rb +0 -55
- data/lib/leap_cli/util/x509.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c76581ff17beffa03bea2e6447ec048d9282cd43
|
4
|
+
data.tar.gz: e1b082558769fad1644c0bf78afa138aa66fcb15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc24e99df33af964af23fdff085bb2a87808a92138545378c70fd43e0a1c0581394c3d7c9faffa774feffb063c3da491f7a892267beb985672d736c603aff79a
|
7
|
+
data.tar.gz: 67c3838bc0eeaf0bd72eaf1d6c843fbfeca25414bec9ccc4120cf2e514cb2f157cad942fd4b7c67b4d9803097e11694ff0360f4eb0cf0b1e312bf0734fce1449
|
data/bin/leap
CHANGED
@@ -14,6 +14,7 @@ else
|
|
14
14
|
$VERBOSE=nil
|
15
15
|
DEBUG=false
|
16
16
|
end
|
17
|
+
TEST = false
|
17
18
|
|
18
19
|
LEAP_CLI_BASE_DIR = File.expand_path('..', File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__))
|
19
20
|
|
@@ -27,8 +28,6 @@ rescue LoadError
|
|
27
28
|
end
|
28
29
|
|
29
30
|
require 'gli'
|
30
|
-
require 'highline'
|
31
|
-
require 'forwardable'
|
32
31
|
require 'leap_cli/lib_ext/gli' # our custom extensions to gli
|
33
32
|
|
34
33
|
#
|
@@ -40,16 +39,6 @@ require 'leap_cli/lib_ext/gli' # our custom extensions to gli
|
|
40
39
|
#
|
41
40
|
module LeapCli::Commands
|
42
41
|
extend GLI::App
|
43
|
-
extend Forwardable
|
44
|
-
|
45
|
-
# delegate highline methods to make them available to sub-commands
|
46
|
-
@terminal = HighLine.new
|
47
|
-
def_delegator :@terminal, :ask, 'self.ask'
|
48
|
-
def_delegator :@terminal, :agree, 'self.agree'
|
49
|
-
def_delegator :@terminal, :choose, 'self.choose'
|
50
|
-
def_delegator :@terminal, :say, 'self.say'
|
51
|
-
def_delegator :@terminal, :color, 'self.color'
|
52
|
-
def_delegator :@terminal, :list, 'self.list'
|
53
42
|
|
54
43
|
# make config manager available as 'manager'
|
55
44
|
def self.manager
|
@@ -90,6 +79,9 @@ module LeapCli::Commands
|
|
90
79
|
|
91
80
|
# run command
|
92
81
|
begin
|
82
|
+
if ARGV.any?
|
83
|
+
LeapCli.log_raw(:log, nil, "COMMAND") { 'leap ' + ARGV.join(' ') }
|
84
|
+
end
|
93
85
|
exit_status = run(ARGV)
|
94
86
|
exit(LeapCli::Util.exit_status || exit_status)
|
95
87
|
rescue StandardError => exc
|
@@ -102,6 +94,8 @@ module LeapCli::Commands
|
|
102
94
|
end
|
103
95
|
if DEBUG
|
104
96
|
raise exc
|
97
|
+
else
|
98
|
+
exit(1)
|
105
99
|
end
|
106
100
|
end
|
107
101
|
end
|
data/lib/leap_cli.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module LeapCli
|
2
|
-
module Commands; end # for commands in leap_cli/commands
|
3
|
-
module Macro; end # for macros in leap_platform/
|
2
|
+
module Commands; end # for commands in leap_platform/lib/leap_cli/commands
|
3
|
+
module Macro; end # for macros in leap_platform/lib/leap_cli/macros
|
4
4
|
end
|
5
5
|
|
6
6
|
$ruby_version = RUBY_VERSION.split('.').collect{ |i| i.to_i }.extend(Comparable)
|
@@ -11,11 +11,8 @@ $:.unshift(File.expand_path('../leap_cli/override',__FILE__))
|
|
11
11
|
# for a few gems, things will break if using earlier versions.
|
12
12
|
# enforce the compatible versions here:
|
13
13
|
require 'rubygems'
|
14
|
-
gem 'net-ssh', '~> 2.7'
|
15
14
|
gem 'gli', '~> 2.12', '>= 2.12.0'
|
16
15
|
|
17
|
-
require 'leap/platform'
|
18
|
-
|
19
16
|
require 'leap_cli/version'
|
20
17
|
require 'leap_cli/exceptions'
|
21
18
|
|
@@ -32,30 +29,13 @@ require 'leap_cli/core_ext/yaml'
|
|
32
29
|
require 'leap_cli/log'
|
33
30
|
require 'leap_cli/path'
|
34
31
|
require 'leap_cli/util'
|
35
|
-
require 'leap_cli/util/secret'
|
36
|
-
require 'leap_cli/util/remote_command'
|
37
|
-
require 'leap_cli/util/x509'
|
38
|
-
require 'leap_cli/logger'
|
39
32
|
require 'leap_cli/bootstrap'
|
40
33
|
|
41
|
-
require 'leap_cli/ssh_key'
|
42
|
-
require 'leap_cli/config/object'
|
43
|
-
require 'leap_cli/config/node'
|
44
|
-
require 'leap_cli/config/tag'
|
45
|
-
require 'leap_cli/config/provider'
|
46
|
-
require 'leap_cli/config/secrets'
|
47
|
-
require 'leap_cli/config/object_list'
|
48
|
-
require 'leap_cli/config/filter'
|
49
|
-
require 'leap_cli/config/environment'
|
50
|
-
require 'leap_cli/config/manager'
|
51
|
-
|
52
34
|
require 'leap_cli/markdown_document_listener'
|
53
35
|
|
54
36
|
#
|
55
37
|
# allow everyone easy access to log() command.
|
56
38
|
#
|
57
39
|
module LeapCli
|
58
|
-
|
59
|
-
Config::Manager.send(:include, LeapCli::Log)
|
60
|
-
extend LeapCli::Log
|
40
|
+
extend LeapCli::LogCommand
|
61
41
|
end
|
data/lib/leap_cli/bootstrap.rb
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
|
6
6
|
module LeapCli
|
7
7
|
module Bootstrap
|
8
|
-
extend LeapCli::Log
|
9
8
|
extend self
|
9
|
+
extend LeapCli::LogCommand
|
10
10
|
|
11
11
|
#
|
12
12
|
# the argument leapfile_path is only used for tests
|
@@ -36,9 +36,11 @@ module LeapCli
|
|
36
36
|
# called from leap executable.
|
37
37
|
#
|
38
38
|
def load_libraries(app)
|
39
|
-
if LeapCli.log_level >= 2
|
39
|
+
if LeapCli.logger.log_level >= 2
|
40
40
|
log_version
|
41
41
|
end
|
42
|
+
add_platform_lib_to_path
|
43
|
+
load_platform_libraries
|
42
44
|
load_commands(app)
|
43
45
|
load_macros
|
44
46
|
end
|
@@ -72,14 +74,14 @@ module LeapCli
|
|
72
74
|
options = parse_logging_options(argv)
|
73
75
|
verbose = (options[:verbose] || 1).to_i
|
74
76
|
if verbose
|
75
|
-
LeapCli.
|
77
|
+
LeapCli.logger.log_level = verbose
|
76
78
|
end
|
77
79
|
if options[:log]
|
78
|
-
LeapCli.log_file = options[:log]
|
79
|
-
LeapCli
|
80
|
+
LeapCli.logger.log_file = options[:log]
|
81
|
+
LeapCli.logger.log_raw(:log) { $0 + ' ' + argv.join(' ')}
|
80
82
|
end
|
81
83
|
unless options[:color].nil?
|
82
|
-
LeapCli.log_in_color = options[:color]
|
84
|
+
LeapCli.logger.log_in_color = options[:color]
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
@@ -97,17 +99,16 @@ module LeapCli
|
|
97
99
|
if !Path.platform || !File.directory?(Path.platform)
|
98
100
|
bail! { log :missing, "platform directory '#{Path.platform}'" }
|
99
101
|
end
|
100
|
-
if LeapCli.log_file.nil? && LeapCli.leapfile.log
|
101
|
-
LeapCli.log_file = LeapCli.leapfile.log
|
102
|
+
if LeapCli.logger.log_file.nil? && LeapCli.leapfile.log
|
103
|
+
LeapCli.logger.log_file = LeapCli.leapfile.log
|
102
104
|
end
|
103
105
|
elsif !leapfile_optional?(argv)
|
104
106
|
puts
|
105
107
|
puts " ="
|
106
|
-
log :
|
107
|
-
" =
|
108
|
+
log :NOTE, "There is no `Leapfile` in this directory, or any parent directory.\n"+
|
109
|
+
" = "+
|
108
110
|
"Without this file, most commands will not be available."
|
109
111
|
puts " ="
|
110
|
-
puts
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
@@ -158,7 +159,9 @@ module LeapCli
|
|
158
159
|
# Yes, hacky.
|
159
160
|
#
|
160
161
|
def leapfile_optional?(argv)
|
161
|
-
if
|
162
|
+
if TEST
|
163
|
+
return true
|
164
|
+
elsif argv.include?('--version')
|
162
165
|
return true
|
163
166
|
else
|
164
167
|
without_flags = argv.select {|i| i !~ /^-/}
|
@@ -193,5 +196,26 @@ module LeapCli
|
|
193
196
|
end
|
194
197
|
end
|
195
198
|
|
199
|
+
#
|
200
|
+
# makes all the ruby libraries in the leap_platform/lib directory
|
201
|
+
# available for inclusion.
|
202
|
+
#
|
203
|
+
def add_platform_lib_to_path
|
204
|
+
if Path.platform
|
205
|
+
path = File.join(Path.platform, 'lib')
|
206
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
#
|
211
|
+
# loads libraries that live in the platform and should
|
212
|
+
# always be available.
|
213
|
+
#
|
214
|
+
def load_platform_libraries
|
215
|
+
if Path.platform
|
216
|
+
require 'leap_cli/load_libraries'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
196
220
|
end
|
197
221
|
end
|
@@ -1,61 +1,103 @@
|
|
1
|
-
|
2
|
-
# Some common helpers available to all LeapCli::Commands
|
3
|
-
#
|
4
|
-
# This also includes utility methods, and makes all instance
|
5
|
-
# methods available as class methods.
|
6
|
-
#
|
1
|
+
require 'readline'
|
7
2
|
|
8
|
-
module LeapCli
|
9
|
-
module Commands
|
3
|
+
module LeapCli; module Commands
|
10
4
|
|
11
|
-
|
12
|
-
|
13
|
-
extend LeapCli::Util
|
14
|
-
extend LeapCli::Util::RemoteCommand
|
5
|
+
extend LeapCli::LogCommand
|
6
|
+
extend LeapCli::Util
|
15
7
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Path.named_path(name)
|
20
|
-
end
|
8
|
+
def path(name)
|
9
|
+
Path.named_path(name)
|
10
|
+
end
|
21
11
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
12
|
+
#
|
13
|
+
# keeps prompting the user for a numbered choice, until they pick a good one or bail out.
|
14
|
+
#
|
15
|
+
# block is yielded and is responsible for rendering the choices.
|
16
|
+
#
|
17
|
+
def numbered_choice_menu(msg, items, &block)
|
18
|
+
while true
|
19
|
+
say("\n" + msg + ':')
|
20
|
+
items.each_with_index(&block)
|
21
|
+
say("q. quit")
|
22
|
+
index = ask("number 1-#{items.length}> ")
|
23
|
+
if index.nil? || index.empty?
|
24
|
+
next
|
25
|
+
elsif index =~ /q/
|
26
|
+
bail!
|
27
|
+
else
|
28
|
+
i = index.to_i - 1
|
29
|
+
if i < 0 || i >= items.length
|
36
30
|
bail!
|
37
31
|
else
|
38
|
-
i
|
39
|
-
if i < 0 || i >= items.length
|
40
|
-
bail!
|
41
|
-
else
|
42
|
-
return i
|
43
|
-
end
|
32
|
+
return i
|
44
33
|
end
|
45
34
|
end
|
46
35
|
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_node_list(nodes)
|
39
|
+
if nodes.is_a? Config::Object
|
40
|
+
Config::ObjectList.new(nodes)
|
41
|
+
elsif nodes.is_a? Config::ObjectList
|
42
|
+
nodes
|
43
|
+
elsif nodes.is_a? String
|
44
|
+
manager.filter!(nodes)
|
45
|
+
else
|
46
|
+
bail! "argument error"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def say(statement)
|
51
|
+
if ends_in_whitespace?(statement)
|
52
|
+
$stdout.print(statement)
|
53
|
+
$stdout.flush
|
54
|
+
else
|
55
|
+
$stdout.puts(statement)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def ask(question, options={})
|
60
|
+
default = options[:default]
|
61
|
+
if default
|
62
|
+
if ends_in_whitespace?(question)
|
63
|
+
question = question + "|" + default + "| "
|
64
|
+
else
|
65
|
+
question = question + "|" + default + "|"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
response = Readline.readline(question, true) # set to false if ever reading passwords.
|
69
|
+
if response
|
70
|
+
response = response.strip
|
71
|
+
if response.empty?
|
72
|
+
return default
|
73
|
+
else
|
74
|
+
return response
|
75
|
+
end
|
76
|
+
else
|
77
|
+
return default
|
78
|
+
end
|
79
|
+
end
|
47
80
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
elsif
|
54
|
-
|
81
|
+
def agree(question, options={})
|
82
|
+
while true
|
83
|
+
response = ask(question, options)
|
84
|
+
if response.nil?
|
85
|
+
say('Please enter "yes" or "no".')
|
86
|
+
elsif ["y","yes", "ye"].include?(response.downcase)
|
87
|
+
return true
|
88
|
+
elsif ["n", "no"].include?(response.downcase)
|
89
|
+
return false
|
55
90
|
else
|
56
|
-
|
91
|
+
say('Please enter "yes" or "no".')
|
57
92
|
end
|
58
93
|
end
|
94
|
+
end
|
59
95
|
|
96
|
+
private
|
97
|
+
|
98
|
+
# true if str ends in whitespace before a color escape code.
|
99
|
+
def ends_in_whitespace?(str)
|
100
|
+
/[ \t](\e\[\d+(;\d+)*m)?\Z/ =~ str
|
60
101
|
end
|
61
|
-
|
102
|
+
|
103
|
+
end; end
|
@@ -4,7 +4,6 @@ module LeapCli; module Commands
|
|
4
4
|
|
5
5
|
desc 'Creates a new provider instance in the specified directory, creating it if necessary.'
|
6
6
|
arg_name 'DIRECTORY'
|
7
|
-
#skips_pre
|
8
7
|
command :new do |c|
|
9
8
|
c.flag 'name', :desc => "The name of the provider." #, :default_value => 'Example'
|
10
9
|
c.flag 'domain', :desc => "The primary domain of the provider." #, :default_value => 'example.org'
|
@@ -12,19 +11,7 @@ module LeapCli; module Commands
|
|
12
11
|
c.flag 'contacts', :desc => "Default email address contacts." #, :default_value => 'root'
|
13
12
|
|
14
13
|
c.action do |global, options, args|
|
15
|
-
|
16
|
-
# this should not be needed, but GLI is not making it required.
|
17
|
-
bail! "Argument DIRECTORY is required."
|
18
|
-
end
|
19
|
-
directory = File.expand_path(args.first)
|
20
|
-
create_provider_directory(global, directory)
|
21
|
-
options[:domain] ||= ask_string("The primary domain of the provider: ") {|q| q.default = 'example.org'}
|
22
|
-
options[:name] ||= ask_string("The name of the provider: ") {|q| q.default = 'Example'}
|
23
|
-
options[:platform] ||= ask_string("File path of the leap_platform directory: ") {|q| q.default = File.expand_path('../leap_platform', directory)}
|
24
|
-
options[:platform] = "./" + options[:platform] unless options[:platform] =~ /^\//
|
25
|
-
options[:contacts] ||= ask_string("Default email address contacts: ") {|q| q.default = 'root@' + options[:domain]}
|
26
|
-
options[:platform] = relative_path(options[:platform])
|
27
|
-
create_initial_provider_files(directory, global, options)
|
14
|
+
new_provider_action(global, options, args)
|
28
15
|
end
|
29
16
|
end
|
30
17
|
|
@@ -32,13 +19,33 @@ module LeapCli; module Commands
|
|
32
19
|
|
33
20
|
DEFAULT_REPO = 'https://leap.se/git/leap_platform.git'
|
34
21
|
|
22
|
+
def new_provider_action(global, options, args)
|
23
|
+
unless args.first
|
24
|
+
# this should not be needed, but GLI is not making it required.
|
25
|
+
bail! "Argument DIRECTORY is required."
|
26
|
+
end
|
27
|
+
directory = File.expand_path(args.first)
|
28
|
+
create_provider_directory(global, directory)
|
29
|
+
options[:domain] ||= ask_string("The primary domain of the provider: ",
|
30
|
+
default: 'example.org')
|
31
|
+
options[:name] ||= ask_string("The name of the provider: ",
|
32
|
+
default: 'Example')
|
33
|
+
options[:platform] ||= ask_string("File path of the leap_platform directory: ",
|
34
|
+
default: File.expand_path('../leap_platform', directory))
|
35
|
+
options[:platform] = "./" + options[:platform] unless options[:platform] =~ /^\//
|
36
|
+
options[:contacts] ||= ask_string("Default email address contacts: ",
|
37
|
+
default: 'root@' + options[:domain])
|
38
|
+
options[:platform] = relative_path(options[:platform])
|
39
|
+
create_initial_provider_files(directory, global, options)
|
40
|
+
end
|
41
|
+
|
35
42
|
#
|
36
43
|
# don't let the user specify any of the following: y, yes, n, no
|
37
44
|
# they must actually input a real string
|
38
45
|
#
|
39
|
-
def ask_string(str,
|
46
|
+
def ask_string(str, options={})
|
40
47
|
while true
|
41
|
-
value = ask(str,
|
48
|
+
value = ask(str, options)
|
42
49
|
if value =~ /^(y|yes|n|no)$/i
|
43
50
|
say "`#{value}` is not a valid value. Try again"
|
44
51
|
else
|
@@ -54,7 +61,7 @@ module LeapCli; module Commands
|
|
54
61
|
unless directory && directory.any?
|
55
62
|
help! "Directory name is required."
|
56
63
|
end
|
57
|
-
unless File.
|
64
|
+
unless File.exist?(directory)
|
58
65
|
if global[:yes] || agree("Create directory #{directory}? ")
|
59
66
|
ensure_dir directory
|
60
67
|
else
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
1
|
#
|
3
2
|
# check to make sure we can find the root directory of the platform
|
4
3
|
#
|
5
4
|
module LeapCli; module Commands
|
6
5
|
|
6
|
+
extend self # this is a trick to make all instance methods
|
7
|
+
# available as class methods.
|
8
|
+
|
7
9
|
desc 'Verbosity level 0..5'
|
8
10
|
arg_name 'LEVEL'
|
9
11
|
default_value '1'
|