multisync 0.3.5 → 0.3.6
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/lib/multisync.rb +3 -0
- data/lib/multisync/catalog.rb +2 -13
- data/lib/multisync/cli.rb +26 -63
- data/lib/multisync/list.rb +44 -0
- data/lib/multisync/runtime.rb +1 -1
- data/lib/multisync/{catalog/filter.rb → selector.rb} +17 -7
- data/lib/multisync/summary.rb +55 -0
- data/lib/multisync/version.rb +1 -1
- metadata +6 -5
- data/lib/multisync/catalog/list.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0293de3d6bf07fd58fcaf551c5469aad676d1b51682dcf58a59b85024dbe1f5
|
4
|
+
data.tar.gz: 55170bd7e42c82b2f3e3dcb7c5a9caede2ad53980611f209d7adad2c2a613ffc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf970e9e365204d4af64b975ec165ba616f17bcf90fb6e752cf22348dccf8c515d57471ea22b4410bee8a38fa2de08030922835b8d43eac1bcf88c434bd187a5
|
7
|
+
data.tar.gz: 4ce7a0b3dc4d9317883558e2c137c2da63e2ed4c8a9a103dffa6e4d24a3ae74f15af04ac07036f4868dc9e5425b769503d5be514df213035d1d34a0e5ab8b46c
|
data/lib/multisync.rb
CHANGED
@@ -4,6 +4,9 @@ module Multisync
|
|
4
4
|
autoload :Cli, 'multisync/cli'
|
5
5
|
autoload :Definition, 'multisync/definition'
|
6
6
|
autoload :Catalog, 'multisync/catalog'
|
7
|
+
autoload :Selector, 'multisync/selector'
|
7
8
|
autoload :Runtime, 'multisync/runtime'
|
8
9
|
autoload :RsyncStat, 'multisync/rsync_stat'
|
10
|
+
autoload :Summary, 'multisync/summary'
|
11
|
+
autoload :List, 'multisync/list'
|
9
12
|
end
|
data/lib/multisync/catalog.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
|
2
2
|
class Multisync::Catalog
|
3
|
-
autoload :List, 'multisync/catalog/list'
|
4
|
-
autoload :Filter, 'multisync/catalog/filter'
|
5
|
-
|
6
3
|
# top entity of definition
|
7
4
|
attr_reader :definition
|
8
5
|
|
@@ -16,18 +13,10 @@ class Multisync::Catalog
|
|
16
13
|
end
|
17
14
|
end
|
18
15
|
|
19
|
-
def
|
20
|
-
|
21
|
-
definition.accept(catalog_list)
|
22
|
-
catalog_list.result
|
16
|
+
def traverse visitor
|
17
|
+
definition.accept visitor
|
23
18
|
end
|
24
19
|
|
25
|
-
def filter sets
|
26
|
-
catalog_filter = Multisync::Catalog::Filter.new sets
|
27
|
-
definition.accept(catalog_filter)
|
28
|
-
catalog_filter.result
|
29
|
-
end
|
30
|
-
|
31
20
|
def path
|
32
21
|
return @path if File.exist? @path
|
33
22
|
sample_path = File.expand_path('../../../sample/multisync.rb', __FILE__)
|
data/lib/multisync/cli.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
require 'optparse'
|
2
3
|
require 'rainbow/ext/string'
|
3
4
|
require 'terminal-table'
|
@@ -43,73 +44,39 @@ class Multisync::Cli
|
|
43
44
|
|
44
45
|
def start
|
45
46
|
parser.parse!
|
46
|
-
|
47
|
+
options[:quiet] = false if options[:print]
|
47
48
|
|
48
|
-
|
49
|
-
when options[:list]
|
50
|
-
list_definitions
|
51
|
-
else
|
52
|
-
run_tasks
|
53
|
-
end
|
54
|
-
puts
|
55
|
-
end
|
56
|
-
|
57
|
-
def list_definitions
|
58
|
-
puts "Catalog: #{options[:file].color(:cyan)}"
|
59
|
-
table = Terminal::Table.new(rows: catalog.list, style: table_style)
|
60
|
-
puts
|
61
|
-
puts table
|
62
|
-
end
|
63
|
-
|
64
|
-
def run_tasks
|
65
|
-
begin
|
66
|
-
tasks.each do |task|
|
67
|
-
runtime.run task
|
68
|
-
end
|
69
|
-
return if options[:print]
|
70
|
-
rescue Interrupt => e
|
71
|
-
$stderr.puts "\nAborted!".color(:red)
|
72
|
-
end
|
73
|
-
table = Terminal::Table.new(headings: summary_headings, rows: summary_data, style: table_style)
|
74
|
-
puts
|
75
|
-
puts
|
76
|
-
puts table
|
77
|
-
end
|
78
|
-
|
79
|
-
def summary_headings
|
80
|
-
%w( Source Destination Files + - → ∑ ↑ ).zip(%i( left left right right right right right right )).map{|v,a| {value: v, alignment: a} }
|
81
|
-
end
|
82
|
-
|
83
|
-
def summary_data
|
84
|
-
# Exclude tasks with an empty result (> not run) first
|
85
|
-
tasks.map do |task|
|
86
|
-
result = task.result
|
87
|
-
desc = [task.source_description, "--> #{task.destination_description}"]
|
88
|
-
|
89
|
-
case result[:action]
|
90
|
-
when :run
|
91
|
-
if result[:status] && result[:status].success?
|
92
|
-
# successfull run
|
93
|
-
stat = Multisync::RsyncStat.new(result[:stdout]).parse
|
94
|
-
[*desc, *stat.to_a.map{|e| {value: e.color(:green), alignment: :right} } ]
|
95
|
-
else
|
96
|
-
# failed or interrupted run
|
97
|
-
[*desc, { value: (result[:stderr] || 'n/a').strip.color(:red), colspan: 6 } ]
|
98
|
-
end
|
49
|
+
@sets = ARGV
|
99
50
|
|
100
|
-
|
101
|
-
|
102
|
-
|
51
|
+
if options[:list]
|
52
|
+
# List tasks
|
53
|
+
puts "Catalog: #{options[:file].color(:cyan)}"
|
54
|
+
puts
|
55
|
+
puts Multisync::List.new catalog
|
103
56
|
|
104
|
-
|
105
|
-
|
106
|
-
|
57
|
+
else
|
58
|
+
# Run tasks
|
59
|
+
return if tasks.empty?
|
60
|
+
begin
|
61
|
+
tasks.each do |task|
|
62
|
+
runtime.run task
|
63
|
+
end
|
64
|
+
rescue Interrupt => e
|
65
|
+
$stderr.puts "\nAborted!".color(:red)
|
66
|
+
end
|
67
|
+
unless options[:print]
|
68
|
+
puts
|
69
|
+
puts
|
70
|
+
puts Multisync::Summary.new tasks
|
107
71
|
end
|
108
72
|
end
|
73
|
+
|
74
|
+
puts
|
109
75
|
end
|
110
76
|
|
111
77
|
def tasks
|
112
|
-
@_tasks ||= catalog
|
78
|
+
@_tasks ||= Multisync::Selector.new(catalog, sets).tasks
|
79
|
+
# @_tasks ||= catalog.filter sets
|
113
80
|
end
|
114
81
|
|
115
82
|
def catalog
|
@@ -130,8 +97,4 @@ class Multisync::Cli
|
|
130
97
|
timeout: 31536000, # 1 year
|
131
98
|
}
|
132
99
|
end
|
133
|
-
|
134
|
-
def table_style
|
135
|
-
{ border_top: false, border_bottom: false, border_x: '–', border_y: '', border_i: '', padding_left: 0, padding_right: 3 }
|
136
|
-
end
|
137
100
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require 'rainbow/ext/string'
|
3
|
+
|
4
|
+
class Multisync::List
|
5
|
+
|
6
|
+
# Given catalog
|
7
|
+
attr_reader :catalog
|
8
|
+
|
9
|
+
# Tasks
|
10
|
+
attr_reader :tasks
|
11
|
+
|
12
|
+
def initialize catalog
|
13
|
+
@catalog = catalog
|
14
|
+
@tasks = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
catalog.traverse self
|
19
|
+
table.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def table
|
23
|
+
Terminal::Table.new(rows: tasks, style: table_style)
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit subject, level
|
27
|
+
if level > 0
|
28
|
+
tab = ''.ljust(2*(level-1), ' ')
|
29
|
+
default = subject.default? ? ' *' : ''
|
30
|
+
name = "#{tab}#{subject.name}#{default}"
|
31
|
+
tasks << [name, *description(subject).map(&:faint)]
|
32
|
+
# puts "#{name.ljust(32, ' ')}#{description(subject)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def description subject
|
37
|
+
desc = [subject.source_description, subject.destination_description]
|
38
|
+
desc.any?(&:empty?) ? [] : [desc.first, ['--> ', desc.last].join]
|
39
|
+
end
|
40
|
+
|
41
|
+
def table_style
|
42
|
+
{ border_top: false, border_bottom: false, border_x: '–', border_y: '', border_i: '', padding_left: 0, padding_right: 3 }
|
43
|
+
end
|
44
|
+
end
|
data/lib/multisync/runtime.rb
CHANGED
@@ -81,7 +81,7 @@ class Multisync::Runtime
|
|
81
81
|
puts rsync.command
|
82
82
|
else
|
83
83
|
sync.result[:action] = :run
|
84
|
-
puts rsync.command if dryrun?
|
84
|
+
puts rsync.command if dryrun? && !quiet?
|
85
85
|
rsync.run_command
|
86
86
|
sync.result[:status] = rsync.status
|
87
87
|
sync.result[:stdout] = rsync.stdout
|
@@ -1,16 +1,26 @@
|
|
1
1
|
|
2
|
-
class Multisync::
|
3
|
-
|
2
|
+
class Multisync::Selector
|
3
|
+
|
4
|
+
# Given catalog
|
5
|
+
attr_reader :catalog
|
6
|
+
|
7
|
+
# Given set names
|
4
8
|
attr_reader :sets
|
5
9
|
|
6
|
-
#
|
10
|
+
# Selected tasks
|
7
11
|
attr_reader :result
|
8
12
|
|
9
|
-
def initialize sets
|
10
|
-
@
|
13
|
+
def initialize catalog, sets
|
14
|
+
@catalog = catalog
|
15
|
+
@sets = sets
|
11
16
|
@result = []
|
12
17
|
end
|
13
|
-
|
18
|
+
|
19
|
+
def tasks
|
20
|
+
catalog.traverse self
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
14
24
|
def visit subject, _level
|
15
25
|
result << subject if selected?(subject)
|
16
26
|
end
|
@@ -23,4 +33,4 @@ class Multisync::Catalog::Filter
|
|
23
33
|
# subject matches any of the given sets
|
24
34
|
sets.any? {|set| /\b#{set}\b/.match subject.fullname }
|
25
35
|
end
|
26
|
-
end
|
36
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
class Multisync::Summary
|
3
|
+
|
4
|
+
# All tasks to include in the summary
|
5
|
+
attr_reader :tasks
|
6
|
+
|
7
|
+
def initialize tasks
|
8
|
+
@tasks = tasks
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
table.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def table
|
16
|
+
Terminal::Table.new(headings: headings, rows: data, style: table_style)
|
17
|
+
end
|
18
|
+
|
19
|
+
def headings
|
20
|
+
%w( Source Destination Files + - → ∑ ↑ ).zip(%i( left left right right right right right right )).map{|v,a| {value: v, alignment: a} }
|
21
|
+
end
|
22
|
+
|
23
|
+
def data
|
24
|
+
# Exclude tasks with an empty result (> not run) first
|
25
|
+
tasks.map do |task|
|
26
|
+
result = task.result
|
27
|
+
desc = [task.source_description, "--> #{task.destination_description}"]
|
28
|
+
|
29
|
+
case result[:action]
|
30
|
+
when :run
|
31
|
+
if result[:status] && result[:status].success?
|
32
|
+
# successfull run
|
33
|
+
stat = Multisync::RsyncStat.new(result[:stdout]).parse
|
34
|
+
[*desc, *stat.to_a.map{|e| {value: e.color(:green), alignment: :right} } ]
|
35
|
+
else
|
36
|
+
# failed or interrupted run
|
37
|
+
[*desc, { value: (result[:stderr] || 'n/a').strip.color(:red), colspan: 6 } ]
|
38
|
+
end
|
39
|
+
|
40
|
+
when :skip
|
41
|
+
# skiped sync
|
42
|
+
[*desc, { value: result[:skip_message].color(:yellow), colspan: 6 } ]
|
43
|
+
|
44
|
+
else
|
45
|
+
# not executed
|
46
|
+
[*desc, { value: 'not executed'.faint, colspan: 6 } ]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def table_style
|
52
|
+
{ border_top: false, border_bottom: false, border_x: '–', border_y: '', border_i: '', padding_left: 0, padding_right: 3 }
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/lib/multisync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multisync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Marchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-shellout
|
@@ -142,16 +142,17 @@ files:
|
|
142
142
|
- exe/multisync
|
143
143
|
- lib/multisync.rb
|
144
144
|
- lib/multisync/catalog.rb
|
145
|
-
- lib/multisync/catalog/filter.rb
|
146
|
-
- lib/multisync/catalog/list.rb
|
147
145
|
- lib/multisync/cli.rb
|
148
146
|
- lib/multisync/definition.rb
|
149
147
|
- lib/multisync/definition/dsl.rb
|
150
148
|
- lib/multisync/definition/entity.rb
|
151
149
|
- lib/multisync/definition/null.rb
|
152
150
|
- lib/multisync/definition/template.rb
|
151
|
+
- lib/multisync/list.rb
|
153
152
|
- lib/multisync/rsync_stat.rb
|
154
153
|
- lib/multisync/runtime.rb
|
154
|
+
- lib/multisync/selector.rb
|
155
|
+
- lib/multisync/summary.rb
|
155
156
|
- lib/multisync/version.rb
|
156
157
|
- multisync.gemspec
|
157
158
|
- sample/multisync.rb
|
@@ -177,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
178
|
- !ruby/object:Gem::Version
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
|
-
rubygems_version: 3.0.
|
181
|
+
rubygems_version: 3.0.3
|
181
182
|
signing_key:
|
182
183
|
specification_version: 4
|
183
184
|
summary: DSL for rsync.
|
@@ -1,24 +0,0 @@
|
|
1
|
-
|
2
|
-
class Multisync::Catalog::List
|
3
|
-
# result
|
4
|
-
attr_reader :result
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@result = []
|
8
|
-
end
|
9
|
-
|
10
|
-
def visit subject, level
|
11
|
-
if level > 0
|
12
|
-
tab = ''.ljust(2*(level-1), ' ')
|
13
|
-
default = subject.default? ? ' *' : ''
|
14
|
-
name = "#{tab}#{subject.name}#{default}"
|
15
|
-
@result << [name, *description(subject)]
|
16
|
-
# puts "#{name.ljust(32, ' ')}#{description(subject)}"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def description subject
|
21
|
-
desc = [subject.source_description, subject.destination_description]
|
22
|
-
desc.any?(&:empty?) ? [] : [desc.first, ['--> ', desc.last].join]
|
23
|
-
end
|
24
|
-
end
|