autobuild 1.14.0 → 1.14.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc3844e5cb144f3b3e1fda8a22ac5b6531c12439
4
- data.tar.gz: ddbecdd7203bd378c2c4504d1598e8da3be460aa
3
+ metadata.gz: 25014dd95ce502bebe2ffe0c7e8247042d4c64c1
4
+ data.tar.gz: 795990e0fb678cbc772882121735c50e306a1d21
5
5
  SHA512:
6
- metadata.gz: aa366e2f4f0b29e6c9f2752528fb44445cb419cc7b1e0fd697f7b4a1cf66d174d86f11e5eabc5872ba90e8f27ec0cdbcc68a1a097096fa5d3d3fc59fdf8558e3
7
- data.tar.gz: 72ec8e6137f757cd13af392076b7e6b3b04af67963628e4d8a4de823fe1b631363d3b45f03dc22a69b1432a6dd198a4e51144105231b3924153928ea453b7262
6
+ metadata.gz: afefb1dcef0ae0ad2413715f69ec890283ed51b581dae702c1e55a9f32615527d06029c575e8c94f02f18b054c1652a8d46a39a45174c68e4a66cd98db4d4c47
7
+ data.tar.gz: 7663d891ffc50ad4099daecbfd6af60b2793696e64b9e5bd59aedca72cf417f03bba1cce095023dc12b01b5d9cb951bc604a02ce8bf48cdad1f9b89259720ed9
@@ -22,6 +22,8 @@ Gem::Specification.new do |s|
22
22
  s.add_runtime_dependency "rake", "~> 12.0", ">= 12.3.0"
23
23
  s.add_runtime_dependency "utilrb", "~> 3.0", ">= 3.0"
24
24
  s.add_runtime_dependency 'tty-prompt', '~> 0.15.0'
25
+ s.add_runtime_dependency 'tty-cursor', '~> 0.5.0'
26
+ s.add_runtime_dependency 'tty-screen', '~> 0.6.4'
25
27
  s.add_runtime_dependency 'pastel', '~> 0.7.0', '>= 0.7.0'
26
28
  s.add_development_dependency "flexmock", '~> 2.0', ">= 2.0.0"
27
29
  s.add_development_dependency "minitest", "~> 5.0", ">= 5.0"
@@ -85,26 +85,6 @@ def full_build?
85
85
  register_utility_class 'doc', Utility, disabled_by_default: false
86
86
  register_utility_class 'test', TestUtility, disabled_by_default: true
87
87
 
88
- @colorizer = Pastel.new
89
- class << self
90
- def color=(flag)
91
- @colorizer =
92
- if flag.nil?
93
- Pastel.new
94
- else
95
- Pastel.new(enabled: flag)
96
- end
97
- end
98
-
99
- def color?
100
- @colorizer.enabled?
101
- end
102
- end
103
-
104
- def self.color(message, *style)
105
- @colorizer.decorate(message, *style)
106
- end
107
-
108
88
  DEFAULT_OPTIONS = { :nice => nil,
109
89
  :srcdir => Dir.pwd, :prefix => Dir.pwd, :logdir => nil,
110
90
  :verbose => false, :debug => false, :do_build => true, :do_forced_build => false, :do_rebuild => false, :do_update => true,
@@ -485,17 +485,13 @@ def message(*args)
485
485
  Autobuild.message(*args)
486
486
  end
487
487
 
488
- def progress_start(*args, &block)
488
+ def progress_start(*args, done_message: nil, **raw_options, &block)
489
489
  args[0] = process_formatting_string(args[0], :bold)
490
- if args.last.kind_of?(Hash)
491
- options, raw_options = Kernel.filter_options args.last, :done_message
492
- if options[:done_message]
493
- options[:done_message] = process_formatting_string(options[:done_message])
494
- end
495
- args[-1] = options.merge(raw_options)
490
+ if done_message
491
+ done_message = process_formatting_string(done_message)
496
492
  end
497
-
498
- Autobuild.progress_start(self, *args, &block)
493
+ Autobuild.progress_start(self, *args,
494
+ done_message: done_message, **raw_options, &block)
499
495
  end
500
496
 
501
497
  def progress(*args)
@@ -504,10 +500,8 @@ def progress(*args)
504
500
  end
505
501
 
506
502
  def progress_done(done_message = nil)
507
- if done_message && Autobuild.has_progress_for?(self)
508
- progress(process_formatting_string(done_message))
509
- end
510
- Autobuild.progress_done(self)
503
+ done_message = process_formatting_string(done_message) if done_message
504
+ Autobuild.progress_done(self, message: done_message)
511
505
  end
512
506
 
513
507
  def apply_post_install
@@ -0,0 +1,209 @@
1
+ module Autobuild
2
+ # Management of the progress display
3
+ class ProgressDisplay
4
+ def initialize(io, color: ::Autobuild.method(:color))
5
+ @io = io
6
+ #@cursor = Blank.new
7
+ @cursor = TTY::Cursor
8
+ @last_formatted_progress = []
9
+ @progress_messages = []
10
+
11
+ @silent = false
12
+ @color = color
13
+ @progress_enabled = true
14
+ @display_lock = Mutex.new
15
+ end
16
+
17
+ attr_writer :silent
18
+
19
+ def silent?
20
+ @silent
21
+ end
22
+
23
+ def silent
24
+ @silent, silent = true, @silent
25
+ yield
26
+ ensure
27
+ @silent = silent
28
+ end
29
+
30
+ attr_writer :progress_enabled
31
+
32
+ def progress_enabled?
33
+ !@silent && @progress_enabled
34
+ end
35
+
36
+ def message(message, *args, io: @io)
37
+ return if silent?
38
+
39
+ if args.last.respond_to?(:to_io)
40
+ io = args.pop
41
+ end
42
+
43
+ @display_lock.synchronize do
44
+ io.print "#{@cursor.clear_screen_down}#{@color.call(message, *args)}\n"
45
+ io.flush if @io != io
46
+ display_progress
47
+ @io.flush
48
+ end
49
+ end
50
+
51
+ def progress_start(key, *args, done_message: nil)
52
+ progress_done(key)
53
+
54
+ formatted_message = @color.call(*args)
55
+ @progress_messages << [key, formatted_message]
56
+ if progress_enabled?
57
+ @display_lock.synchronize do
58
+ display_progress
59
+ end
60
+ else
61
+ message " #{formatted_message}"
62
+ end
63
+
64
+ if block_given?
65
+ begin
66
+ result = yield
67
+ progress_done(key, message: done_message)
68
+ result
69
+ rescue Exception
70
+ progress_done(key)
71
+ raise
72
+ end
73
+ end
74
+ end
75
+
76
+ def progress(key, *args)
77
+ @display_lock.synchronize do
78
+ found = false
79
+ @progress_messages.map! do |msg_key, msg|
80
+ if msg_key == key
81
+ found = true
82
+ [msg_key, @color.call(*args)]
83
+ else
84
+ [msg_key, msg]
85
+ end
86
+ end
87
+ @progress_messages << [key, @color.call(*args)] unless found
88
+ display_progress
89
+ end
90
+ end
91
+
92
+ def progress_done(key, display_last = true, message: nil)
93
+ changed = @display_lock.synchronize do
94
+ current_size = @progress_messages.size
95
+ @progress_messages.delete_if do |msg_key, msg|
96
+ if msg_key == key
97
+ if display_last && !message
98
+ message = msg
99
+ end
100
+ true
101
+ end
102
+ end
103
+ current_size != @progress_messages.size
104
+ end
105
+
106
+ if changed
107
+ if message
108
+ message(" #{message}")
109
+ # Note: message calls display_progress already
110
+ else
111
+ @display_lock.synchronize do
112
+ display_progress
113
+ end
114
+ end
115
+ true
116
+ end
117
+ end
118
+
119
+
120
+ def display_progress
121
+ return unless progress_enabled?
122
+
123
+ formatted = format_grouped_messages(@progress_messages.map(&:last), indent: " ")
124
+ @io.print @cursor.clear_screen_down
125
+ @io.print formatted.join("\n")
126
+ if formatted.size > 1
127
+ @io.print "#{@cursor.up(formatted.size - 1)}#{@cursor.column(0)}"
128
+ else
129
+ @io.print @cursor.column(0)
130
+ end
131
+ @io.flush
132
+ end
133
+
134
+ def find_common_prefix(msg, other_msg)
135
+ msg = msg.split(" ")
136
+ other_msg = other_msg.split(" ")
137
+ msg.each_with_index do |token, idx|
138
+ if other_msg[idx] != token
139
+ prefix = msg[0..(idx - 1)].join(" ")
140
+ if !prefix.empty?
141
+ prefix << " "
142
+ end
143
+ return prefix
144
+ end
145
+ end
146
+ return msg.join(" ")
147
+ end
148
+
149
+ def group_messages(messages)
150
+ messages = messages.sort
151
+
152
+ groups = Array.new
153
+ groups << ["", (0...messages.size)]
154
+ messages.each_with_index do |msg, idx|
155
+ prefix, grouping = nil, false
156
+ messages[(idx + 1)..-1].each_with_index do |other_msg, other_idx|
157
+ other_idx += idx + 1
158
+ prefix ||= find_common_prefix(msg, other_msg)
159
+ break if !other_msg.start_with?(prefix)
160
+
161
+ if grouping
162
+ break if prefix != groups.last[0]
163
+ groups.last[1] << other_idx
164
+ else
165
+ current_prefix, current_group = groups.last
166
+ if prefix.size > current_prefix.size # create a new group from there
167
+ groups.last[1] = (current_group.first..[idx-1,current_group.last].min)
168
+ groups << [prefix, [idx, other_idx]]
169
+ grouping = true
170
+ else break
171
+ end
172
+ end
173
+ end
174
+ end
175
+ if groups.last.last.last < messages.size
176
+ groups << ["", (groups.last.last.last + 1)...(messages.size)]
177
+ end
178
+
179
+ groups.map do |prefix, indexes|
180
+ indexes = indexes.to_a
181
+ next if indexes.empty?
182
+ range = (prefix.size)..-1
183
+ [prefix, indexes.map { |i| messages[i][range] }]
184
+ end.compact
185
+ end
186
+
187
+ def format_grouped_messages(messages, indent: " ")
188
+ terminal_w = TTY::Screen.width
189
+ groups = group_messages(messages)
190
+ groups.each_with_object([]) do |(prefix, messages), lines|
191
+ if prefix.empty?
192
+ lines << "#{indent}#{messages.shift}"
193
+ else
194
+ lines << "#{indent}#{prefix.dup.strip} #{messages.shift}"
195
+ end
196
+ until messages.empty?
197
+ msg = messages.shift.strip
198
+ if lines.last.size + 2 + msg.size > terminal_w
199
+ lines << "#{indent} #{msg}"
200
+ else
201
+ lines.last << ", #{msg}"
202
+ end
203
+ end
204
+ lines
205
+ end
206
+ end
207
+ end
208
+ end
209
+
@@ -1,245 +1,78 @@
1
1
  require 'autobuild/exceptions'
2
+ require 'pastel'
3
+
2
4
  module Autobuild
5
+ @colorizer = Pastel.new
3
6
  class << self
4
- attr_reader :display_lock
5
- def silent?
6
- @silent
7
+ def color=(flag)
8
+ @colorizer =
9
+ if flag.nil?
10
+ Pastel.new
11
+ else
12
+ Pastel.new(enabled: flag)
13
+ end
7
14
  end
8
- attr_writer :silent
9
- end
10
- @display_lock = Mutex.new
11
- @silent = false
12
15
 
13
- def self.silent
14
- Autobuild.silent, silent = true, Autobuild.silent?
15
- yield
16
- ensure
17
- Autobuild.silent = silent
18
- end
19
-
20
- def self.progress_display_enabled?
21
- @progress_display_enabled
22
- end
23
-
24
- def self.progress_display_enabled=(value)
25
- @progress_display_enabled = value
16
+ def color?
17
+ @colorizer.enabled?
18
+ end
19
+ def color(message, *style)
20
+ @colorizer.decorate(message, *style)
21
+ end
26
22
  end
23
+ end
27
24
 
28
- @progress_display_enabled = true
29
- @last_progress_msg = nil
25
+ require 'tty/cursor'
26
+ require 'tty/screen'
27
+ require 'autobuild/progress_display'
30
28
 
31
- def self.message(*args)
32
- return if silent?
33
- display_lock.synchronize do
34
- display_message(*args)
29
+ module Autobuild
30
+ class << self
31
+ def silent?
32
+ @display.silent?
33
+ end
34
+ def silent=(flag)
35
+ @display.silent = flag
35
36
  end
36
37
  end
38
+ @display = ProgressDisplay.new(STDOUT)
37
39
 
38
- def self.display_message(*args)
39
- io = STDOUT
40
- if args.last.kind_of?(IO)
41
- io = args.pop
42
- end
43
- msg =
44
- if args.empty? then ""
45
- else "#{color(*args)}"
46
- end
40
+ def self.silent(&block)
41
+ @display.silent(&block)
42
+ end
47
43
 
48
- if !Autobuild.progress_display_enabled?
49
- if !silent?
50
- io.puts msg
51
- end
52
- return
53
- end
44
+ def self.progress_display_enabled?
45
+ @display.progress_enabled?
46
+ end
54
47
 
55
- if !silent?
56
- io.puts "#{clear_line}#{msg}"
57
- if @last_progress_msg
58
- io.print @last_progress_msg
59
- end
60
- end
48
+ def self.progress_display_enabled=(value)
49
+ @display.progress_enabled = value
61
50
  end
62
51
 
63
- class << self
64
- attr_reader :progress_messages
52
+ def self.message(*args, **options)
53
+ @display.message(*args, **options)
65
54
  end
66
- @progress_messages = Array.new
67
55
 
68
56
  # Displays an error message
69
57
  def self.error(message = "")
70
- message(" ERROR: #{message}", :red, :bold, STDERR)
58
+ message(" ERROR: #{message}", :red, :bold, io: STDERR)
71
59
  end
72
60
 
73
61
  # Displays a warning message
74
62
  def self.warn(message = "", *style)
75
- message(" WARN: #{message}", :magenta, *style, STDERR)
63
+ message(" WARN: #{message}", :magenta, *style, io: STDERR)
76
64
  end
77
65
 
78
- # @return [Boolean] true if there is some progress messages for the given
79
- # key
80
- def self.has_progress_for?(key)
81
- progress_messages.any? { |msg_key, _| msg_key == key }
66
+ def self.progress_start(key, *args, **options, &block)
67
+ @display.progress_start(key, *args, **options, &block)
82
68
  end
83
69
 
84
- def self.clear_line
85
- "\e[2K\e[1G"
86
- end
87
-
88
- def self.progress_start(key, *args)
89
- if args.last.kind_of?(Hash)
90
- options = Kernel.validate_options args.pop, :done_message => nil
91
- else
92
- options = Hash.new
93
- end
94
-
95
- progress_done(key)
96
- display_lock.synchronize do
97
- progress_messages << [key, color(*args)]
98
- if Autobuild.progress_display_enabled?
99
- display_progress
100
- else
101
- display_message(" " + color(*args))
102
- end
103
- end
104
-
105
- if block_given?
106
- begin
107
- result = yield
108
- if options[:done_message] && has_progress_for?(key)
109
- progress(key, *options[:done_message])
110
- end
111
- progress_done(key, true)
112
- result
113
- rescue Exception
114
- progress_done(key, false)
115
- raise
116
- end
117
- end
118
- end
119
70
  def self.progress(key, *args)
120
- found = false
121
- display_lock.synchronize do
122
- progress_messages.map! do |msg_key, msg|
123
- if msg_key == key
124
- found = true
125
- [msg_key, color(*args)]
126
- else
127
- [msg_key, msg]
128
- end
129
- end
130
- if !found
131
- progress_messages << [key, color(*args)]
132
- end
133
-
134
- return if !Autobuild.progress_display_enabled?
135
-
136
- display_progress
137
- end
71
+ @display.progress(key, *args)
138
72
  end
139
73
 
140
- def self.progress_done(key, display_last = true)
141
- found = false
142
- display_lock.synchronize do
143
- last_msg = nil
144
- progress_messages.delete_if do |msg_key, msg|
145
- if msg_key == key
146
- found = true
147
- last_msg = msg
148
- end
149
- end
150
- if found
151
- if display_last
152
- display_message(" #{last_msg}")
153
- end
154
- if @last_progress_msg
155
- display_progress
156
- end
157
- end
158
- end
159
- found
160
- end
161
-
162
- def self.find_common_prefix(msg, other_msg)
163
- msg = msg.split(" ")
164
- other_msg = other_msg.split(" ")
165
- msg.each_with_index do |token, idx|
166
- if other_msg[idx] != token
167
- prefix = msg[0..(idx - 1)].join(" ")
168
- if !prefix.empty?
169
- prefix << " "
170
- end
171
- return prefix
172
- end
173
- end
174
- return msg.join(" ")
175
- end
176
-
177
- def self.format_progress_message(messages)
178
- messages = messages.sort
179
-
180
- groups = Array.new
181
- groups << ["", (0...messages.size)]
182
- messages.each_with_index do |msg, idx|
183
- prefix, grouping = nil, false
184
- messages[(idx + 1)..-1].each_with_index do |other_msg, other_idx|
185
- other_idx += idx + 1
186
- prefix ||= find_common_prefix(msg, other_msg)
187
- break if !other_msg.start_with?(prefix)
188
-
189
- if grouping
190
- break if prefix != groups.last[0]
191
- groups.last[1] << other_idx
192
- else
193
- current_prefix, current_group = groups.last
194
- if prefix.size > current_prefix.size # create a new group from there
195
- groups.last[1] = (current_group.first..[idx-1,current_group.last].min)
196
- groups << [prefix, [idx, other_idx]]
197
- grouping = true
198
- else break
199
- end
200
- end
201
- end
202
- end
203
- if groups.last.last.last < messages.size
204
- groups << ["", (groups.last.last.last + 1)...(messages.size)]
205
- end
206
-
207
- result = []
208
- groups.each do |prefix, indexes|
209
- if prefix.empty?
210
- indexes.each do |index|
211
- result << messages[index]
212
- end
213
- else
214
- grouped_messages = []
215
- indexes.each do |index|
216
- grouped_messages << messages[index][(prefix.size)..-1]
217
- end
218
- if !grouped_messages.empty?
219
- result << "#{prefix}#{grouped_messages.uniq.join(", ")}"
220
- end
221
- end
222
- end
223
- result.join(" | ")
224
- end
225
-
226
- def self.display_progress
227
- msg = format_progress_message(progress_messages.map(&:last))
228
-
229
- if msg.empty?
230
- @last_progress_msg = nil
231
- else
232
- msg = " #{msg}"
233
- @last_progress_msg = msg
234
- end
235
-
236
- if !silent?
237
- if Autobuild.progress_display_enabled?
238
- print "#{clear_line}#{msg}"
239
- elsif @last_progress_msg
240
- puts msg
241
- end
242
- end
74
+ def self.progress_done(key, display_last = true, message: nil)
75
+ @display.progress_done(key, display_last, message: message)
243
76
  end
244
77
 
245
78
  ## The reporting module provides the framework # to run commands in
@@ -289,6 +122,9 @@ def self.default_report_on_package_failures
289
122
  # @param [Symbol] on_package_failures how does the reporting should behave.
290
123
  #
291
124
  def self.report_finish_on_error(errors, on_package_failures: default_report_on_package_failures, interrupted_by: nil)
125
+ if not_package_error = errors.find { |e| !e.respond_to?(:fatal?) }
126
+ raise not_package_error
127
+ end
292
128
  if ![:raise, :report_silent, :exit_silent].include?(on_package_failures)
293
129
  errors.each { |e| error(e) }
294
130
  end
@@ -1,3 +1,3 @@
1
1
  module Autobuild
2
- VERSION = "1.14.0" unless defined? Autobuild::VERSION
2
+ VERSION = "1.14.1" unless defined? Autobuild::VERSION
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autobuild
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-27 00:00:00.000000000 Z
11
+ date: 2018-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -64,6 +64,34 @@ dependencies:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
66
  version: 0.15.0
67
+ - !ruby/object:Gem::Dependency
68
+ name: tty-cursor
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: 0.5.0
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: 0.5.0
81
+ - !ruby/object:Gem::Dependency
82
+ name: tty-screen
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: 0.6.4
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: 0.6.4
67
95
  - !ruby/object:Gem::Dependency
68
96
  name: pastel
69
97
  requirement: !ruby/object:Gem::Requirement
@@ -200,6 +228,7 @@ files:
200
228
  - lib/autobuild/packages/ruby.rb
201
229
  - lib/autobuild/parallel.rb
202
230
  - lib/autobuild/pkgconfig.rb
231
+ - lib/autobuild/progress_display.rb
203
232
  - lib/autobuild/rake_task_extension.rb
204
233
  - lib/autobuild/reporting.rb
205
234
  - lib/autobuild/subcommand.rb