makit 0.0.47 → 0.0.48
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/makit/apache.rb +32 -32
- data/lib/makit/cli/clean.rb +14 -14
- data/lib/makit/cli/clone.rb +59 -59
- data/lib/makit/cli/init.rb +38 -38
- data/lib/makit/cli/main.rb +33 -33
- data/lib/makit/cli/make.rb +54 -54
- data/lib/makit/cli/new.rb +37 -37
- data/lib/makit/cli/nuget_cache.rb +38 -38
- data/lib/makit/cli/pull.rb +31 -31
- data/lib/makit/cli/setup.rb +71 -71
- data/lib/makit/cli/work.rb +21 -21
- data/lib/makit/command_runner.rb +391 -400
- data/lib/makit/commands.rb +21 -21
- data/lib/makit/content/default_gitignore.rb +5 -5
- data/lib/makit/content/default_rakefile.rb +11 -11
- data/lib/makit/content/gem_rakefile.rb +14 -14
- data/lib/makit/data.rb +50 -50
- data/lib/makit/directories.rb +140 -140
- data/lib/makit/directory.rb +200 -200
- data/lib/makit/dotnet.rb +162 -163
- data/lib/makit/environment.rb +127 -127
- data/lib/makit/fileinfo.rb +16 -16
- data/lib/makit/files.rb +47 -47
- data/lib/makit/git.rb +87 -87
- data/lib/makit/gitlab_runner.rb +60 -60
- data/lib/makit/humanize.rb +129 -129
- data/lib/makit/indexer.rb +56 -56
- data/lib/makit/logging.rb +96 -96
- data/lib/makit/markdown.rb +75 -75
- data/lib/makit/mp/basic_object_mp.rb +16 -16
- data/lib/makit/mp/command_request.mp.rb +16 -16
- data/lib/makit/mp/project_mp.rb +210 -210
- data/lib/makit/mp/string_mp.rb +122 -140
- data/lib/makit/nuget.rb +57 -57
- data/lib/makit/protoc.rb +104 -104
- data/lib/makit/serializer.rb +115 -115
- data/lib/makit/show.rb +108 -108
- data/lib/makit/storage.rb +131 -131
- data/lib/makit/symbols.rb +149 -149
- data/lib/makit/tasks.rb +60 -61
- data/lib/makit/tree.rb +37 -37
- data/lib/makit/v1/makit.v1_pb.rb +34 -34
- data/lib/makit/v1/makit.v1_services_pb.rb +25 -25
- data/lib/makit/version.rb +52 -52
- data/lib/makit/wix.rb +95 -95
- data/lib/makit/zip.rb +17 -17
- data/lib/makit.rb +267 -267
- metadata +2 -4
- data/lib/generated/makit/v1/makit.v1_pb.rb +0 -34
- data/lib/generated/makit/v1/web/link_pb.rb +0 -20
data/lib/makit/command_runner.rb
CHANGED
@@ -1,400 +1,391 @@
|
|
1
|
-
require "English"
|
2
|
-
require "open3"
|
3
|
-
require "socket"
|
4
|
-
require "etc"
|
5
|
-
require "logger"
|
6
|
-
require_relative "mp/command_request.mp"
|
7
|
-
|
8
|
-
# This module provides classes for the Makit gem.
|
9
|
-
module Makit
|
10
|
-
# This class provide methods running commands.
|
11
|
-
#
|
12
|
-
class CommandRunner
|
13
|
-
attr_accessor :show_output_on_success, :log_to_artifacts, :commands
|
14
|
-
attr_accessor :debug, :default_modified
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@show_output_on_success = false
|
18
|
-
@log_to_artifacts = false
|
19
|
-
@commands = []
|
20
|
-
@debug = false
|
21
|
-
@default_modified = Makit::Git::get_file_infos.first.mtime # Makit::GIT_FILE_INFOS.first.mtime
|
22
|
-
end
|
23
|
-
|
24
|
-
# search command history for matching commands
|
25
|
-
def search(query)
|
26
|
-
results = []
|
27
|
-
commands.each do |command|
|
28
|
-
keywords = []
|
29
|
-
keywords << command.name.downcase
|
30
|
-
command.arguments.each { |argument|
|
31
|
-
keywords << argument.downcase unless keywords.include?(argument.downcase)
|
32
|
-
}
|
33
|
-
# output is bytes, so convert to UTF 8 string
|
34
|
-
#output_bytes = command.output.clone
|
35
|
-
#output = command.output.clone.force_encoding('UTF-8')
|
36
|
-
#error_bytes = command.error.clone
|
37
|
-
#error = error_bytes.force_encoding('UTF-8')
|
38
|
-
#output.split(" ").each {|word|
|
39
|
-
# if(word.length > 3)
|
40
|
-
# keywords << word.downcase unless keywords.include?(word.downcase)
|
41
|
-
# end
|
42
|
-
#}
|
43
|
-
#error.split(" ").each { |word|
|
44
|
-
# if(word.length > 3)
|
45
|
-
# keywords << word.downcase unless keywords.include?(word.downcase)
|
46
|
-
# end
|
47
|
-
#}
|
48
|
-
matchCount = 0
|
49
|
-
terms = query.downcase.split(" ")
|
50
|
-
terms.each { |term|
|
51
|
-
if (keywords.include?(term))
|
52
|
-
matchCount += 1
|
53
|
-
end
|
54
|
-
}
|
55
|
-
if (matchCount == terms.length)
|
56
|
-
results << command
|
57
|
-
end
|
58
|
-
end
|
59
|
-
results
|
60
|
-
end
|
61
|
-
|
62
|
-
def get_cache_filename(command)
|
63
|
-
int_hash = Digest::SHA256.hexdigest("#{command.name}.#{command.arguments.join(" ")}")
|
64
|
-
hash_string = "#{int_hash}"
|
65
|
-
cache_filename = Makit::Directories::PROJECT_ARTIFACTS +
|
66
|
-
"/commands/cache/#{hash_string}.pb"
|
67
|
-
# create the directory if it does not already exist
|
68
|
-
FileUtils.mkdir_p(File.dirname(cache_filename))
|
69
|
-
cache_filename
|
70
|
-
end
|
71
|
-
|
72
|
-
def cache_run(command_request)
|
73
|
-
cache_run(command_request, @default_modified)
|
74
|
-
end
|
75
|
-
|
76
|
-
# if there is a matching cached command result, that then the specified timestamp,
|
77
|
-
# then return the cached result
|
78
|
-
# otherwise run the command and save the result to a cache file
|
79
|
-
# then return the result
|
80
|
-
def cache_run(command_request, timestamp)
|
81
|
-
raise "Invalid command_request" unless command_request.is_a? Makit::V1::CommandRequest
|
82
|
-
cache_filename = get_cache_filename(command_request)
|
83
|
-
|
84
|
-
# Check if timestamp is a valid Time object
|
85
|
-
unless timestamp.is_a?(Time)
|
86
|
-
raise ArgumentError, "timestamp must be a Time object, got #{timestamp.class}"
|
87
|
-
end
|
88
|
-
|
89
|
-
if debug
|
90
|
-
puts " timestamp: #{Makit::Humanize.get_humanized_timestamp(timestamp)}"
|
91
|
-
puts " command.name: #{command_request.name}"
|
92
|
-
puts " command.arguments: #{command_request.arguments.join(" ")}"
|
93
|
-
puts " cache_filename: #{cache_filename}"
|
94
|
-
end
|
95
|
-
#cache_filename = Makit::Directories::PROJECT_ARTIFACTS + "/commands/#{command_request.name}.#{command_request.arguments.join("_")}.#{timestamp.seconds}.pb"
|
96
|
-
if File.exist?(cache_filename)
|
97
|
-
cache_timestamp = File.mtime(cache_filename)
|
98
|
-
if debug
|
99
|
-
puts " cache timestamp: #{Makit::Humanize.get_humanized_timestamp(cache_timestamp)}"
|
100
|
-
end
|
101
|
-
#puts "cache file date: #{File.mtime(cache_filename)}"
|
102
|
-
if (File.mtime(cache_filename) > timestamp)
|
103
|
-
|
104
|
-
#puts " found cached command (newer than #{timestamp})".colorize(:grey)
|
105
|
-
#puts " cache_filename: #{cache_filename}"
|
106
|
-
command = Makit::Serializer.open(cache_filename, Makit::V1::Command)
|
107
|
-
show_cached_command(command)
|
108
|
-
if command.exit_code != 0
|
109
|
-
abort "cached command failed: #{command.name} #{command.arguments.join(" ")}"
|
110
|
-
end
|
111
|
-
return command
|
112
|
-
else
|
113
|
-
puts " cache_filename exists, but is older than #{timestamp}" if debug
|
114
|
-
File.delete(cache_filename)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
command = run(command_request)
|
119
|
-
# make sure the cache directory exists
|
120
|
-
FileUtils.mkdir_p(File.dirname(cache_filename))
|
121
|
-
#puts "saving command to cache_filename"
|
122
|
-
Makit::Serializer.save_as(cache_filename, command)
|
123
|
-
commands.push(command)
|
124
|
-
command
|
125
|
-
end
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
puts
|
132
|
-
puts
|
133
|
-
puts
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
puts
|
146
|
-
puts
|
147
|
-
puts
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
request
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
def
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
Makit::
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
raise "Invalid source" unless source.is_a?
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
result
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
#
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
end
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
}
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
# Convert to float representation
|
393
|
-
duration_in_float = command.duration.seconds + (command.duration.nanos / 1_000_000_000.0)
|
394
|
-
#puts " #{command.name} took #{duration_in_float} seconds"
|
395
|
-
file.puts " " + Makit::CommandRunner.get_command_summary(command).strip_color_codes + " (#{command.duration.seconds} seconds)"
|
396
|
-
end
|
397
|
-
end
|
398
|
-
end
|
399
|
-
end # class CommandRunner
|
400
|
-
end # module Makit
|
1
|
+
require "English"
|
2
|
+
require "open3"
|
3
|
+
require "socket"
|
4
|
+
require "etc"
|
5
|
+
require "logger"
|
6
|
+
require_relative "mp/command_request.mp"
|
7
|
+
|
8
|
+
# This module provides classes for the Makit gem.
|
9
|
+
module Makit
|
10
|
+
# This class provide methods running commands.
|
11
|
+
#
|
12
|
+
class CommandRunner
|
13
|
+
attr_accessor :show_output_on_success, :log_to_artifacts, :commands
|
14
|
+
attr_accessor :debug, :default_modified
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@show_output_on_success = false
|
18
|
+
@log_to_artifacts = false
|
19
|
+
@commands = []
|
20
|
+
@debug = false
|
21
|
+
@default_modified = Makit::Git::get_file_infos.first.mtime # Makit::GIT_FILE_INFOS.first.mtime
|
22
|
+
end
|
23
|
+
|
24
|
+
# search command history for matching commands
|
25
|
+
def search(query)
|
26
|
+
results = []
|
27
|
+
commands.each do |command|
|
28
|
+
keywords = []
|
29
|
+
keywords << command.name.downcase
|
30
|
+
command.arguments.each { |argument|
|
31
|
+
keywords << argument.downcase unless keywords.include?(argument.downcase)
|
32
|
+
}
|
33
|
+
# output is bytes, so convert to UTF 8 string
|
34
|
+
#output_bytes = command.output.clone
|
35
|
+
#output = command.output.clone.force_encoding('UTF-8')
|
36
|
+
#error_bytes = command.error.clone
|
37
|
+
#error = error_bytes.force_encoding('UTF-8')
|
38
|
+
#output.split(" ").each {|word|
|
39
|
+
# if(word.length > 3)
|
40
|
+
# keywords << word.downcase unless keywords.include?(word.downcase)
|
41
|
+
# end
|
42
|
+
#}
|
43
|
+
#error.split(" ").each { |word|
|
44
|
+
# if(word.length > 3)
|
45
|
+
# keywords << word.downcase unless keywords.include?(word.downcase)
|
46
|
+
# end
|
47
|
+
#}
|
48
|
+
matchCount = 0
|
49
|
+
terms = query.downcase.split(" ")
|
50
|
+
terms.each { |term|
|
51
|
+
if (keywords.include?(term))
|
52
|
+
matchCount += 1
|
53
|
+
end
|
54
|
+
}
|
55
|
+
if (matchCount == terms.length)
|
56
|
+
results << command
|
57
|
+
end
|
58
|
+
end
|
59
|
+
results
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_cache_filename(command)
|
63
|
+
int_hash = Digest::SHA256.hexdigest("#{command.name}.#{command.arguments.join(" ")}")
|
64
|
+
hash_string = "#{int_hash}"
|
65
|
+
cache_filename = Makit::Directories::PROJECT_ARTIFACTS +
|
66
|
+
"/commands/cache/#{hash_string}.pb"
|
67
|
+
# create the directory if it does not already exist
|
68
|
+
FileUtils.mkdir_p(File.dirname(cache_filename))
|
69
|
+
cache_filename
|
70
|
+
end
|
71
|
+
|
72
|
+
def cache_run(command_request)
|
73
|
+
cache_run(command_request, @default_modified)
|
74
|
+
end
|
75
|
+
|
76
|
+
# if there is a matching cached command result, that then the specified timestamp,
|
77
|
+
# then return the cached result
|
78
|
+
# otherwise run the command and save the result to a cache file
|
79
|
+
# then return the result
|
80
|
+
def cache_run(command_request, timestamp)
|
81
|
+
raise "Invalid command_request" unless command_request.is_a? Makit::V1::CommandRequest
|
82
|
+
cache_filename = get_cache_filename(command_request)
|
83
|
+
|
84
|
+
# Check if timestamp is a valid Time object
|
85
|
+
unless timestamp.is_a?(Time)
|
86
|
+
raise ArgumentError, "timestamp must be a Time object, got #{timestamp.class}"
|
87
|
+
end
|
88
|
+
|
89
|
+
if debug
|
90
|
+
puts " timestamp: #{Makit::Humanize.get_humanized_timestamp(timestamp)}"
|
91
|
+
puts " command.name: #{command_request.name}"
|
92
|
+
puts " command.arguments: #{command_request.arguments.join(" ")}"
|
93
|
+
puts " cache_filename: #{cache_filename}"
|
94
|
+
end
|
95
|
+
#cache_filename = Makit::Directories::PROJECT_ARTIFACTS + "/commands/#{command_request.name}.#{command_request.arguments.join("_")}.#{timestamp.seconds}.pb"
|
96
|
+
if File.exist?(cache_filename)
|
97
|
+
cache_timestamp = File.mtime(cache_filename)
|
98
|
+
if debug
|
99
|
+
puts " cache timestamp: #{Makit::Humanize.get_humanized_timestamp(cache_timestamp)}"
|
100
|
+
end
|
101
|
+
#puts "cache file date: #{File.mtime(cache_filename)}"
|
102
|
+
if (File.mtime(cache_filename) > timestamp)
|
103
|
+
|
104
|
+
#puts " found cached command (newer than #{timestamp})".colorize(:grey)
|
105
|
+
#puts " cache_filename: #{cache_filename}"
|
106
|
+
command = Makit::Serializer.open(cache_filename, Makit::V1::Command)
|
107
|
+
show_cached_command(command)
|
108
|
+
if command.exit_code != 0
|
109
|
+
abort "cached command failed: #{command.name} #{command.arguments.join(" ")}"
|
110
|
+
end
|
111
|
+
return command
|
112
|
+
else
|
113
|
+
puts " cache_filename exists, but is older than #{timestamp}" if debug
|
114
|
+
File.delete(cache_filename)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
command = run(command_request)
|
119
|
+
# make sure the cache directory exists
|
120
|
+
FileUtils.mkdir_p(File.dirname(cache_filename))
|
121
|
+
#puts "saving command to cache_filename"
|
122
|
+
Makit::Serializer.save_as(cache_filename, command)
|
123
|
+
commands.push(command)
|
124
|
+
command
|
125
|
+
end
|
126
|
+
|
127
|
+
def show_command(command)
|
128
|
+
if command.exit_code != 0
|
129
|
+
puts Makit::CommandRunner.get_command_summary(command) + " (exit code #{command.exit_code})".colorize(:default)
|
130
|
+
puts " directory: #{command.directory}\n"
|
131
|
+
puts " duration: #{command.duration.seconds} seconds\n"
|
132
|
+
puts Makit::Humanize::indent_string(command.output, 2) if command.output.length > 0
|
133
|
+
puts Makit::Humanize::indent_string(command.error, 2) if command.error.length > 0
|
134
|
+
#exit 1 if command.exit_on_error
|
135
|
+
else
|
136
|
+
puts Makit::CommandRunner.get_command_summary(command) + " (#{command.duration.seconds} seconds)".colorize(:cyan)
|
137
|
+
puts Makit::Humanize::indent_string(command.output, 2).colorize(:default) if show_output_on_success
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def show_cached_command(command)
|
142
|
+
if command.exit_code != 0
|
143
|
+
puts Makit::CommandRunner.get_command_summary(command) + " (exit code #{command.exit_code})".colorize(:default)
|
144
|
+
puts " directory: #{command.directory}\n"
|
145
|
+
puts " duration: #{command.duration.seconds} seconds\n"
|
146
|
+
puts Makit::Humanize::indent_string(command.output, 2) if command.output.length > 0
|
147
|
+
puts Makit::Humanize::indent_string(command.error, 2) if command.error.length > 0
|
148
|
+
#exit 1 if command.exit_on_error
|
149
|
+
else
|
150
|
+
puts Makit::CommandRunner.get_command_summary(command).strip_color_codes.colorize(:grey) + " (#{command.duration.seconds} seconds)".colorize(:grey)
|
151
|
+
puts Makit::Humanize::indent_string(command.output, 2).colorize(:default) if show_output_on_success
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Run a command and return a Makit::V1::Command.
|
156
|
+
def run(command_request)
|
157
|
+
raise "Invalid command_request" unless command_request.is_a? Makit::V1::CommandRequest
|
158
|
+
command = execute(command_request)
|
159
|
+
show_output = true
|
160
|
+
exit_on_error = true
|
161
|
+
|
162
|
+
log_to_artifacts(command) if @log_to_artifacts
|
163
|
+
show_command(command)
|
164
|
+
if command.exit_code != 0
|
165
|
+
exit 1 if command_request.exit_on_error
|
166
|
+
end
|
167
|
+
commands.push(command)
|
168
|
+
command
|
169
|
+
end
|
170
|
+
|
171
|
+
def log_to_artifacts(command)
|
172
|
+
log_filename = get_cache_filename(command)
|
173
|
+
Makit::Serializer.save_as(log_filename, command)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Run a command and return a Makit::V1::Command.
|
177
|
+
def try(args)
|
178
|
+
request = parse_command_request(args)
|
179
|
+
request.exit_on_error = false
|
180
|
+
run(request)
|
181
|
+
#run2(args, false)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Show the output of a command and return a Makit::V1::Command.
|
185
|
+
def show(args)
|
186
|
+
request = parse_args(args)
|
187
|
+
command = execute(request)
|
188
|
+
|
189
|
+
show_output = true
|
190
|
+
exit_on_error = true
|
191
|
+
Makit::LOGGER.info(Makit::CommandRunner.get_command_summary(command))
|
192
|
+
show_output = true if command.exit_code != 0
|
193
|
+
Makit::LOGGER.info(indent_string("\n#{command.output}\n#{command.error}\n".strip, 2)) if show_output
|
194
|
+
exit(command.exit_code) if exit_on_error && command.exit_code != 0 # unless process_status.success?
|
195
|
+
command
|
196
|
+
end
|
197
|
+
|
198
|
+
# Parse and return a Makit::V1::CommandRequest.
|
199
|
+
def parse_command_request(source)
|
200
|
+
return Makit::V1::CommandRequest.new(source) if source.is_a? Hash
|
201
|
+
return source if source.is_a? Makit::V1::CommandRequest
|
202
|
+
if source.is_a? String
|
203
|
+
return parse_args(source)
|
204
|
+
end
|
205
|
+
|
206
|
+
raise "Invalid source" unless source.is_a? Makit::V1::CommandRequest
|
207
|
+
end
|
208
|
+
|
209
|
+
def parse_command_request_from_hash(hash)
|
210
|
+
raise "Invalid hash" unless hash.is_a? Hash
|
211
|
+
Makit::V1::CommandRequest.new(hash)
|
212
|
+
end
|
213
|
+
|
214
|
+
def parse_command_request_from_string(source)
|
215
|
+
raise "Invalid source" unless source.is_a? String
|
216
|
+
words = source.split(" ")
|
217
|
+
hash = {
|
218
|
+
name: words.shift,
|
219
|
+
arguments: words,
|
220
|
+
exit_on_error: true,
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
# Parse the command line arguments into a Makit::V1::CommandRequest.
|
225
|
+
def parse_args(args)
|
226
|
+
#raise "No command specified" if args.empty?
|
227
|
+
if args.is_a? Makit::V1::CommandRequest
|
228
|
+
args
|
229
|
+
else
|
230
|
+
if args.is_a? String
|
231
|
+
args = args.split(" ")
|
232
|
+
if (args.length == 1)
|
233
|
+
hash = {
|
234
|
+
name: args[0],
|
235
|
+
arguments: [],
|
236
|
+
exit_on_error: true,
|
237
|
+
}
|
238
|
+
Makit::V1::CommandRequest.new(hash)
|
239
|
+
else
|
240
|
+
hash = {
|
241
|
+
name: args.shift,
|
242
|
+
arguments: args,
|
243
|
+
exit_on_error: true,
|
244
|
+
}
|
245
|
+
|
246
|
+
Makit::V1::CommandRequest.new(hash)
|
247
|
+
end
|
248
|
+
else
|
249
|
+
Makit::V1::CommandRequest.new(args)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def get_path_name(name)
|
255
|
+
# replace all characters that a not valid in a filename with an underscore
|
256
|
+
name.gsub(/[^0-9a-z]/i, "_")
|
257
|
+
end
|
258
|
+
|
259
|
+
# Given a Makit::V1::CommandRequest, execute the command and return a Makit::V1::Command.
|
260
|
+
def execute(args)
|
261
|
+
command_request = parse_args(args)
|
262
|
+
command_request.directory = Dir.pwd if command_request.directory.nil?
|
263
|
+
command_request.directory = Dir.pwd if command_request.directory.length == 0
|
264
|
+
result = Makit::V1::Command.new(name: command_request.name)
|
265
|
+
command_request.arguments.each do |arg|
|
266
|
+
result.arguments.push(arg)
|
267
|
+
end
|
268
|
+
command = "#{command_request.name} #{command_request.arguments.join(" ")}"
|
269
|
+
result.directory = command_request.directory
|
270
|
+
start = Time.now
|
271
|
+
filename_friendly_timestamp = Time.now.strftime("%Y.%m.%d_%H%M%S")
|
272
|
+
log_filename = File.join(Makit::Directories::LOG, "#{filename_friendly_timestamp}.log")
|
273
|
+
|
274
|
+
# assign a directory variable to the current working directory, if not specified,
|
275
|
+
# otherwise assign the specified directory
|
276
|
+
command_request.directory = Dir.pwd if command_request.directory.nil?
|
277
|
+
command_request.directory = Dir.pwd if command_request.directory.length == 0
|
278
|
+
raise "Invalid directory" unless Dir.exist?(command_request.directory)
|
279
|
+
|
280
|
+
result.started_at = Google::Protobuf::Timestamp.new(seconds: start.to_i, nanos: start.nsec.to_i)
|
281
|
+
############# execute the command
|
282
|
+
(output, error, exit_code) = execute_command(command, command_request.directory, command_request.timeout)
|
283
|
+
result.output = output.force_encoding("ASCII-8BIT")
|
284
|
+
result.error = error.force_encoding("ASCII-8BIT")
|
285
|
+
result.exit_code = exit_code.nil? ? 0 : exit_code
|
286
|
+
|
287
|
+
elapsed_time = Time.now - start
|
288
|
+
seconds = elapsed_time.to_i
|
289
|
+
nanos = ((elapsed_time - seconds) * 1_000_000_000).to_i
|
290
|
+
|
291
|
+
result.duration = Google::Protobuf::Duration.new(seconds: seconds, nanos: nanos)
|
292
|
+
|
293
|
+
result
|
294
|
+
end
|
295
|
+
|
296
|
+
# pure function to execute a command
|
297
|
+
# returns (stdout, stderr, exit_code) or raise an exception
|
298
|
+
def execute_command(command, directory, timeout)
|
299
|
+
original_directory = Dir.pwd
|
300
|
+
begin
|
301
|
+
output = nil
|
302
|
+
error = nil
|
303
|
+
process_status = nil
|
304
|
+
Dir.chdir(directory) do
|
305
|
+
output, error, process_status = Open3.capture3(command)
|
306
|
+
end
|
307
|
+
return [output, error, process_status.exitstatus]
|
308
|
+
rescue => e
|
309
|
+
# restore the original working directory
|
310
|
+
Dir.chdir(original_directory)
|
311
|
+
message_parts = []
|
312
|
+
message_parts << "failed to execute #{command}"
|
313
|
+
message_parts << "directory: #{directory}"
|
314
|
+
message_parts << "timeout: #{timeout}" unless timeout.nil?
|
315
|
+
message_parts << "error: #{e.message}"
|
316
|
+
message = message_parts.join("\n") + "\n"
|
317
|
+
return ["", message, 1]
|
318
|
+
#raise Makit::Error, message
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def execute_command_request(command_request)
|
323
|
+
# if the command_request is not a Makit::V1::CommandRequest, raise an error
|
324
|
+
raise "Invalid command_request" unless command_request.is_a? Makit::V1::CommandRequest
|
325
|
+
|
326
|
+
args = Array.new
|
327
|
+
command_request.arguments.each do |arg|
|
328
|
+
args.push(arg)
|
329
|
+
end
|
330
|
+
result = Makit::V1::Command.new({
|
331
|
+
name: command_request.name,
|
332
|
+
arguments: args,
|
333
|
+
started_at: Google::Protobuf::Timestamp.new({ seconds: Time.now.to_i, nanos: Time.now.nsec }),
|
334
|
+
})
|
335
|
+
|
336
|
+
begin
|
337
|
+
rescue => e
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def indent_string(input_string, indent_spaces)
|
342
|
+
indentation = " " * indent_spaces
|
343
|
+
input_string.lines.map { |line| indentation + line }.join
|
344
|
+
end
|
345
|
+
|
346
|
+
def self.get_command_summary(command)
|
347
|
+
symbol = Makit::Symbols.warning
|
348
|
+
symbol = Makit::Symbols.checkmark if !command.exit_code.nil? && command.exit_code.zero?
|
349
|
+
symbol = Makit::Symbols.error if command.exit_code != 0
|
350
|
+
summary = "#{symbol} #{command.name.colorize(:yellow)} #{command.arguments.join(" ")}"
|
351
|
+
|
352
|
+
if summary.length > 80
|
353
|
+
summary = summary.to_lines(80, command.name.length + 3)
|
354
|
+
end
|
355
|
+
|
356
|
+
summary
|
357
|
+
end
|
358
|
+
|
359
|
+
def log_rake_commands
|
360
|
+
dir = File.join(Makit::Directories::PROJECT_ARTIFACTS, "commands")
|
361
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
362
|
+
|
363
|
+
# open a text file to write to
|
364
|
+
File.open(File.join(dir, "rake.commands.txt"), "w") do |file|
|
365
|
+
#rake_commands = commands.select { |command| command.name == "rake" }
|
366
|
+
commands.each do |command|
|
367
|
+
file.puts " " + Makit::CommandRunner.get_command_summary(command).strip_color_codes
|
368
|
+
file.puts " start time: #{command.started_at}"
|
369
|
+
file.puts command.output.strip_color_codes unless command.output.strip_color_codes.strip.length == 0
|
370
|
+
file.puts command.error.strip_color_codes unless command.error.strip_color_codes.strip.length == 0
|
371
|
+
file.puts " "
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def log_slowest_commands
|
377
|
+
dir = File.join(Makit::Directories::PROJECT_ARTIFACTS, "commands")
|
378
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
379
|
+
|
380
|
+
# open a text file to write to
|
381
|
+
File.open(File.join(dir, "slow.commands.txt"), "w") do |file|
|
382
|
+
Makit::RUNNER.commands.sort_by { |command| (command.duration.seconds + (command.duration.nanos / 1_000_000_000.0)) }.reverse.first(5).each do |command|
|
383
|
+
# Convert to float representation
|
384
|
+
duration_in_float = command.duration.seconds + (command.duration.nanos / 1_000_000_000.0)
|
385
|
+
#puts " #{command.name} took #{duration_in_float} seconds"
|
386
|
+
file.puts " " + Makit::CommandRunner.get_command_summary(command).strip_color_codes + " (#{command.duration.seconds} seconds)"
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end # class CommandRunner
|
391
|
+
end # module Makit
|