configmonkey_cli 1.0.0 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/VERSION +1 -1
- data/configmonkey_cli.gemspec +1 -0
- data/lib/configmonkey_cli.rb +1 -0
- data/lib/configmonkey_cli/application.rb +2 -2
- data/lib/configmonkey_cli/application/manifest.rb +34 -3
- data/lib/configmonkey_cli/application/manifest_actions/base.rb +1 -14
- data/lib/configmonkey_cli/application/manifest_actions/copy.rb +18 -2
- data/lib/configmonkey_cli/application/manifest_actions/invoke.rb +5 -2
- data/lib/configmonkey_cli/application/manifest_actions/sync_links.rb +22 -2
- data/lib/configmonkey_cli/application/manifest_actions/template.rb +8 -12
- data/lib/configmonkey_cli/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 391f6c9bbafb6e640823708c4cff1f0b5955436a65b986f4254c916784ad6816
|
4
|
+
data.tar.gz: eec65f85b8b493b2b7230905fa374de3652f1390124ed03feca376814200f38d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41fae277325b89e41e69295403e6128a69a401f070a20ee4ca536a9a55bbcfd937268883b550617083aa5e21f6458213cba961fba5ddbd4dd7e26c07875be117
|
7
|
+
data.tar.gz: ee4cf475e8415e90ec9afe0177cc6e7ec3c2d17eacb28c681cbf389816eadd60202e5cfb23634b27c92400b6545b716ff5293021a56016bfbdd07a16be8ef0a8
|
data/README.md
CHANGED
@@ -45,7 +45,7 @@ To get a list of available options invoke Configmonkey with the `--help` or `-h`
|
|
45
45
|
# Application options
|
46
46
|
--generate-manifest Generates an example manifest in current directory
|
47
47
|
-a, --accept accept all defaults
|
48
|
-
-b, --
|
48
|
+
-b, --bell ring a bell when asked
|
49
49
|
-D, --diff change default diff tool
|
50
50
|
-f, --fake-host HOST override hostname
|
51
51
|
-i, --in DIR operate from this source directory instead of pwd
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.5
|
data/configmonkey_cli.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency "activesupport"
|
22
22
|
spec.add_dependency "httparty"
|
23
23
|
spec.add_dependency "thor"
|
24
|
+
spec.add_dependency "tty-prompt"
|
24
25
|
spec.add_development_dependency "pry"
|
25
26
|
spec.add_development_dependency "bundler"
|
26
27
|
spec.add_development_dependency "rake"
|
data/lib/configmonkey_cli.rb
CHANGED
@@ -41,7 +41,7 @@ module ConfigmonkeyCli
|
|
41
41
|
hostname: `hostname`.chomp, # -f flag
|
42
42
|
diff_tool: nil, # -D flag
|
43
43
|
merge_tool: nil, # -M flag
|
44
|
-
bell:
|
44
|
+
bell: false, # -b flag
|
45
45
|
default_accept: false, # -a flag
|
46
46
|
default_yes: false, # -y flag
|
47
47
|
dispatch: :index, # (internal) action to dispatch
|
@@ -106,7 +106,7 @@ module ConfigmonkeyCli
|
|
106
106
|
opts.separator(c "# Application options", :blue)
|
107
107
|
opts.on("--generate-manifest", "Generates an example manifest in current directory") { @opts[:dispatch] = :generate_manifest }
|
108
108
|
opts.on("-a", "--accept", "accept all defaults") { @opts[:default_accept] = true }
|
109
|
-
opts.on("-b", "--
|
109
|
+
opts.on("-b", "--bell", "dont ring a bell when asked") { @opts[:bell] = true }
|
110
110
|
opts.on("-D", "--diff", "change default diff tool") {|s| @opts[:diff_tool] = s }
|
111
111
|
opts.on("-f", "--fake-host HOST", "override hostname") {|s| @opts[:hostname] = s }
|
112
112
|
opts.on("-i", "--in DIR", "operate from this source directory instead of pwd") {|s| @opts[:working_directory] = s }
|
@@ -112,6 +112,18 @@ module ConfigmonkeyCli
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
+
def run_action which, simulate = nil, *args, &block
|
116
|
+
simulate = app.opts[:simulation] if simulate.nil?
|
117
|
+
action = case which
|
118
|
+
when String, Symbol
|
119
|
+
"ConfigmonkeyCli::Application::ManifestAction::#{which.to_s.camelize}".constantize.new(app, self, *args, &block)
|
120
|
+
else
|
121
|
+
action = which
|
122
|
+
end
|
123
|
+
action.prepare
|
124
|
+
simulate ? action.simulate : action.destructive
|
125
|
+
end
|
126
|
+
|
115
127
|
def _dump!
|
116
128
|
@actions.each do |constraint, action, instance|
|
117
129
|
begin
|
@@ -143,8 +155,7 @@ module ConfigmonkeyCli
|
|
143
155
|
$cm_current_action_index = index
|
144
156
|
$cm_current_action_name = action
|
145
157
|
$cm_current_action_color = :magenta
|
146
|
-
instance
|
147
|
-
simulate ? instance.simulate : instance.destructive
|
158
|
+
run_action(instance, simulate)
|
148
159
|
ensure
|
149
160
|
$cm_current_action_index = $cm_current_action_name = $cm_current_action_color = nil
|
150
161
|
app.haltpoint
|
@@ -195,7 +206,8 @@ module ConfigmonkeyCli
|
|
195
206
|
|
196
207
|
def push_action *args
|
197
208
|
if $cm_current_action_index
|
198
|
-
|
209
|
+
$cm_current_action_index += 1
|
210
|
+
@actions.insert $cm_current_action_index, [@host_constraint.dup] + args
|
199
211
|
else
|
200
212
|
@actions.push [@host_constraint.dup] + args
|
201
213
|
end
|
@@ -232,6 +244,25 @@ module ConfigmonkeyCli
|
|
232
244
|
thor.say((color.any? ? c(str.to_s, *color) : str.to_s))
|
233
245
|
end
|
234
246
|
|
247
|
+
def prompt opts = {}
|
248
|
+
TTY::Prompt.new(opts).tap do |prompt|
|
249
|
+
yield(prompt) if block_given?
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def status name, *args
|
254
|
+
case args.length
|
255
|
+
when 0
|
256
|
+
raise ArgumentError("at least name and string is required")
|
257
|
+
when 1 # status :fake, rel(@destination)
|
258
|
+
thor.say_status name, args[0], :green
|
259
|
+
when 2 # status :fake, :green, rel(@destination)
|
260
|
+
thor.say_status name, args[1], args[0]
|
261
|
+
when 3 # status :fake, :green, rel(@destination), :red
|
262
|
+
thor.say_status name, thor.set_color(args[1], *args[2..-1]), args[0]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
235
266
|
# do block no matter the `hostname`
|
236
267
|
def all &block
|
237
268
|
_with_constraint(:any, &block)
|
@@ -53,20 +53,7 @@ module ConfigmonkeyCli
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
|
-
case args.length
|
58
|
-
when 0
|
59
|
-
raise ArgumentError("at least name and string is required")
|
60
|
-
when 1 # status :fake, rel(@destination)
|
61
|
-
thor.say_status name, args[0], :green
|
62
|
-
when 2 # status :fake, :green, rel(@destination)
|
63
|
-
thor.say_status name, args[1], args[0]
|
64
|
-
when 3 # status :fake, :green, rel(@destination), :red
|
65
|
-
thor.say_status name, thor.set_color(args[1], *args[2..-1]), args[0]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
[:padded, :c, :say, :ask, :yes?, :no?].each do |meth|
|
56
|
+
([:padded, :c, :say, :status, :prompt, :ask, :yes?, :no?, :run_action] + Manifest::MANIFEST_ACTIONS).each do |meth|
|
70
57
|
define_method(meth) do |*args, &block|
|
71
58
|
manifest.send(meth, *args, &block)
|
72
59
|
end
|
@@ -22,15 +22,31 @@ module ConfigmonkeyCli
|
|
22
22
|
|
23
23
|
def destructive
|
24
24
|
absolute_source = File.join(thor.source_paths[0], @source)
|
25
|
+
has_changed = !File.exist?(@destination)
|
26
|
+
|
27
|
+
if @opts[:after_change] && File.exist?(@destination)
|
28
|
+
has_changed = File.binread(absolute_source) != File.binread(@destination)
|
29
|
+
end
|
30
|
+
|
25
31
|
if FileTest.directory?(absolute_source)
|
26
|
-
|
32
|
+
_perform_directory(@source, @destination, @opts)
|
27
33
|
else
|
28
|
-
|
34
|
+
_perform_file(@source, @destination, @opts)
|
29
35
|
if @opts[:chmod] && File.exist?(absolute_source) && File.exist?(@destination)
|
30
36
|
mode = @opts[:chmod] == true ? File.stat(absolute_source).mode - 0100000 : @opts[:chmod]
|
31
37
|
thor.chmod(@destination, mode) unless mode == File.stat(@destination).mode - 0100000
|
32
38
|
end
|
33
39
|
end
|
40
|
+
|
41
|
+
@opts[:after_change].call if has_changed && @opts[:after_change]
|
42
|
+
end
|
43
|
+
|
44
|
+
def _perform_directory(source, destination, opts)
|
45
|
+
thor.directory(source, destination, opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
def _perform_file(source, destination, opts)
|
49
|
+
thor.copy_file(source, destination, opts)
|
34
50
|
end
|
35
51
|
end
|
36
52
|
end
|
@@ -20,10 +20,13 @@ module ConfigmonkeyCli
|
|
20
20
|
code, res = exec(@args[0], @opts[:chomp])
|
21
21
|
|
22
22
|
if opts[:echo]
|
23
|
+
lines = res.split("\n")
|
23
24
|
if code.exitstatus.zero?
|
24
|
-
say padded("#{c "[OK]", :green} #{
|
25
|
+
say padded("#{c "[OK]", :green} #{lines[0]}", :black)
|
26
|
+
lines[1..-1].each{|l| say padded(" #{l}") } if lines.length > 1
|
25
27
|
else
|
26
|
-
say padded("[#{code.exitstatus}] #{
|
28
|
+
say padded("[#{code.exitstatus}] #{lines[0]}", :red)
|
29
|
+
lines[1..-1].each{|l| say padded(" #{l}") } if lines.length > 1
|
27
30
|
raise "Invoked process exited with status #{code.exitstatus}: #{res}" if opts[:fail]
|
28
31
|
end
|
29
32
|
end
|
@@ -8,6 +8,7 @@ module ConfigmonkeyCli
|
|
8
8
|
prefix: nil,
|
9
9
|
map: "d:dp",
|
10
10
|
hard: false,
|
11
|
+
exclude: [],
|
11
12
|
})
|
12
13
|
end
|
13
14
|
|
@@ -42,16 +43,35 @@ module ConfigmonkeyCli
|
|
42
43
|
def destructive
|
43
44
|
prefixed_sources = @sources.map do |src|
|
44
45
|
File.join(@destination, "#{@prefix}#{File.basename(src)}")
|
45
|
-
end
|
46
|
+
end.reject{|f| excluded?(f) }
|
46
47
|
|
47
48
|
if @purge
|
48
49
|
(Dir["#{File.join(@destination, @prefix)}*"] - prefixed_sources).each do |f|
|
49
50
|
thor.remove_file(f)
|
51
|
+
# @todo fix for https://github.com/erikhuda/thor/pull/720
|
52
|
+
::FileUtils.rm_rf(f) if File.symlink?(f)
|
50
53
|
end
|
51
54
|
end
|
52
55
|
|
53
56
|
@sources.each do |src|
|
54
|
-
|
57
|
+
if r = excluded?(src)
|
58
|
+
status :excluded, :black, rel(src) << c(" #{r.inspect}", :black)
|
59
|
+
else
|
60
|
+
thor.create_link("#{@destination}/#{@prefix}#{File.basename(src)}", src, @opts)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def excluded? src
|
66
|
+
[*@opts[:exclude]].detect do |filter|
|
67
|
+
case filter
|
68
|
+
when Proc
|
69
|
+
filter.call(src)
|
70
|
+
when Regexp
|
71
|
+
src.match(filter)
|
72
|
+
when String
|
73
|
+
src.ends_with?(filter)
|
74
|
+
end
|
55
75
|
end
|
56
76
|
end
|
57
77
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ConfigmonkeyCli
|
2
2
|
class Application
|
3
3
|
module ManifestAction
|
4
|
-
class Template <
|
4
|
+
class Template < Copy
|
5
5
|
def init hargs_and_opts = {}
|
6
6
|
@args, @opts = args_and_opts(hargs_and_opts)
|
7
7
|
end
|
@@ -20,17 +20,13 @@ module ConfigmonkeyCli
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
mode = @opts[:chmod] == true ? File.stat(absolute_source).mode - 0100000 : @opts[:chmod]
|
31
|
-
thor.chmod(@destination, mode) unless mode == File.stat(@destination).mode - 0100000
|
32
|
-
end
|
33
|
-
end
|
23
|
+
def _perform_directory(source, destination, opts)
|
24
|
+
status :invalid, :red, "directory not allowed for template", :red
|
25
|
+
end
|
26
|
+
|
27
|
+
def _perform_file(source, destination, opts)
|
28
|
+
hostname = app.opts[:hostname]
|
29
|
+
thor.template(@source, @destination, @opts.merge(context: binding))
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configmonkey_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Pachnit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tty-prompt
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: pry
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|