run_tasks 2.1.0 → 3.0.0
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 +5 -5
- data/bin/run +2 -1
- data/completions/_run +11 -0
- data/src/bootstrap.rb +53 -10
- data/src/run/core/help.rb +90 -4
- data/src/run/core.rb +133 -28
- data/src/run/error/aborted.rb +2 -0
- data/src/run/error/existing_task.rb +2 -0
- data/src/run/error/non_existing_runfile.rb +6 -0
- data/src/run/error/non_existing_task.rb +12 -0
- data/src/run/error/reserved_task_name.rb +2 -0
- data/src/run/error/runfile_version_mismatch.rb +11 -0
- data/src/run/error/unknown_task.rb +2 -0
- data/src/run/helper/are_you_sure_helper.rb +3 -1
- data/src/run/helper/bind_helper.rb +74 -0
- data/src/run/helper/catch_interruption_helper.rb +2 -0
- data/src/run/helper/expand_helper.rb +2 -0
- data/src/run/helper/menu_helper.rb +2 -0
- data/src/run/helper/pause_helper.rb +13 -1
- data/src/run/helper/question_helper.rb +2 -0
- data/src/run/helper/wait_for_interruption_helper.rb +2 -0
- data/src/run/task/block_task.rb +2 -0
- data/src/run/task/system_task.rb +3 -3
- metadata +50 -21
- data/src/gemspec/metadata.rb +0 -23
- data/src/markdown/abstract_tag.rb +0 -47
- data/src/markdown/bold_tag.rb +0 -20
- data/src/markdown/code_tag.rb +0 -20
- data/src/markdown/engine.rb +0 -17
- data/src/markdown/italic_tag.rb +0 -20
- data/src/monkey/string.rb +0 -55
- data/src/run/core/verify_run_version.rb +0 -23
- data/src/version/local_gemspec_version.rb +0 -13
- data/src/version/remote_gemspec_version.rb +0 -23
- data/src/version/semver.rb +0 -62
- data/src/version/unreachable_error.rb +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 857247c762c39960c83e5689ec558c8e39a5b36aafc84db9a8fd08931697df22
|
|
4
|
+
data.tar.gz: 90dd7fd4183acee7232f3c881c2fe550deeb4c326ca23c0c10fd7330b60d2b54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb448955e6889e99bdf60235edb7294af0c381a90c8dddf7d805fbcc7ce56d307dbafcf128ec2ff66f786184df5324743b4d60925894bb44012e6737f511ccc1
|
|
7
|
+
data.tar.gz: f96b6ea0d728dcaff2b851163bf173af427729dab2df12bbddaf6adef442117b88b77a4d3255d185384ffbe3521a36beb34470f4545e0a4d9b9f570216c4ae54
|
data/bin/run
CHANGED
data/completions/_run
ADDED
data/src/bootstrap.rb
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "digest"
|
|
2
4
|
require "fileutils"
|
|
3
5
|
require "io/console"
|
|
4
6
|
require "readline"
|
|
5
7
|
require "rubygems"
|
|
6
8
|
require "securerandom"
|
|
9
|
+
require "rb_monkey"
|
|
10
|
+
require "rb_gemspec"
|
|
11
|
+
require "rb_markdown"
|
|
7
12
|
|
|
8
13
|
# Require all files.
|
|
9
14
|
Dir.glob(
|
|
10
|
-
File.join(__dir__, "
|
|
15
|
+
File.join(__dir__, "run", "**", "*.rb"),
|
|
11
16
|
&method(:require)
|
|
12
17
|
)
|
|
13
18
|
|
|
14
|
-
# Check for new versions.
|
|
15
|
-
if rand(1..5) == 5
|
|
16
|
-
Run::Core::VerifyRunVersion.run
|
|
17
|
-
end
|
|
18
|
-
|
|
19
19
|
# Expose global methods.
|
|
20
20
|
[:task, :run].each do |name|
|
|
21
21
|
define_method name do |*args, **options, &block|
|
|
@@ -27,8 +27,12 @@ end
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
define_method :version do |version|
|
|
31
|
+
Run::Core.runfile_version = version
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Run Rspec tests (if any).
|
|
35
|
+
task :rspec do |path = "spec/src"|
|
|
32
36
|
command = "bundle exec rspec"
|
|
33
37
|
|
|
34
38
|
if !path
|
|
@@ -40,6 +44,39 @@ task :rspec do |path|
|
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
|
|
47
|
+
# Install ZSH completions.
|
|
48
|
+
task :install_completions do
|
|
49
|
+
source = File.expand_path(File.join(__dir__, '..', 'completions', '_run'))
|
|
50
|
+
dir = File.expand_path('~/.zfunc')
|
|
51
|
+
dest = File.join(dir, '_run')
|
|
52
|
+
zshrc = File.expand_path('~/.zshrc')
|
|
53
|
+
|
|
54
|
+
FileUtils.mkdir_p(dir)
|
|
55
|
+
FileUtils.cp(source, dest)
|
|
56
|
+
|
|
57
|
+
content = File.exist?(zshrc) ? File.read(zshrc) : ''
|
|
58
|
+
additions = []
|
|
59
|
+
additions << 'fpath=(~/.zfunc $fpath)' unless content.include?('~/.zfunc')
|
|
60
|
+
additions << 'autoload -Uz compinit && compinit' unless content.match?(/compinit/)
|
|
61
|
+
|
|
62
|
+
if additions.any?
|
|
63
|
+
File.open(zshrc, 'a') { |f| f.puts "\n# run completions\n#{additions.join("\n")}" }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
puts "ZSH completions installed."
|
|
67
|
+
puts "Run 'source ~/.zshrc' to activate."
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Publish the gem (if publishable).
|
|
71
|
+
task :publish do
|
|
72
|
+
gemspec_files = Dir.glob(File.join(Dir.pwd, "*.gemspec"))
|
|
73
|
+
raise ".gemspec file not found in the project directory" if gemspec_files.empty?
|
|
74
|
+
gemspec = Gem::Specification::load(gemspec_files.first)
|
|
75
|
+
run "gem build #{gemspec.name}"
|
|
76
|
+
run "gem push #{gemspec.name}-#{gemspec.version}.gem"
|
|
77
|
+
`rm #{gemspec.name}-#{gemspec.version}.gem`
|
|
78
|
+
end
|
|
79
|
+
|
|
43
80
|
# Expose helpers.
|
|
44
81
|
Dir.glob(File.join(__dir__, "run", "helper", "*.rb")) do |path|
|
|
45
82
|
filename = File.basename(path, ".rb")
|
|
@@ -78,14 +115,20 @@ rescue SyntaxError => error
|
|
|
78
115
|
rescue ArgumentError => error
|
|
79
116
|
format_error error
|
|
80
117
|
exit 6
|
|
81
|
-
rescue Run::Error::NonExistingRunfile
|
|
82
|
-
puts
|
|
118
|
+
rescue Run::Error::NonExistingRunfile => error
|
|
119
|
+
puts error.message.red
|
|
83
120
|
exit 7
|
|
84
121
|
rescue Run::Error::Aborted => error
|
|
85
122
|
exit 9
|
|
86
123
|
rescue Run::Error::ExistingTask => error
|
|
87
124
|
puts error.message.red
|
|
88
125
|
exit 10
|
|
126
|
+
rescue Run::Error::NonExistingTask => error
|
|
127
|
+
puts error.message.red
|
|
128
|
+
exit 12
|
|
129
|
+
rescue Run::Error::RunfileVersionMismatch => error
|
|
130
|
+
puts error.message.red
|
|
131
|
+
exit 13
|
|
89
132
|
rescue => error
|
|
90
133
|
format_error error
|
|
91
134
|
exit 4
|
data/src/run/core/help.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "ripper"
|
|
2
4
|
|
|
3
5
|
module Run
|
|
@@ -16,9 +18,10 @@ module Run
|
|
|
16
18
|
|
|
17
19
|
if help_verbatim[:comments].size > 0
|
|
18
20
|
help_verbatim[:comments].each_with_index do |comment, comment_line|
|
|
21
|
+
terminal_width = (STDOUT.winsize[1] rescue 80)
|
|
19
22
|
split_comment = split_verbatim(
|
|
20
23
|
comment,
|
|
21
|
-
|
|
24
|
+
terminal_width - tasks_column_length - 2
|
|
22
25
|
)
|
|
23
26
|
split_comment.map.with_index do |chunk, chunk_line|
|
|
24
27
|
text = comment_line == 0 && chunk_line == 0 ?
|
|
@@ -32,10 +35,17 @@ module Run
|
|
|
32
35
|
output += "#{name_verbatim}\n"
|
|
33
36
|
end
|
|
34
37
|
|
|
38
|
+
if help_verbatim[:params].any?
|
|
39
|
+
indent = " " * tasks_column_length
|
|
40
|
+
help_verbatim[:params].each do |p|
|
|
41
|
+
output += "#{indent} - #{format_param(p)}\n"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
35
45
|
output
|
|
36
46
|
end
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
output
|
|
39
49
|
end
|
|
40
50
|
|
|
41
51
|
private
|
|
@@ -50,6 +60,7 @@ module Run
|
|
|
50
60
|
lines_to_scan = (0..(task[:line] - 2 < 0 ? 0 : task[:line] - 2)).to_a.reverse
|
|
51
61
|
{
|
|
52
62
|
names: task[:names],
|
|
63
|
+
params: task[:params],
|
|
53
64
|
comments: lines_to_scan.each_with_object([]) do |current_line, comments|
|
|
54
65
|
match = /^\s*#\s*(?<comment>.*?)\s*$/.match(lines[current_line])
|
|
55
66
|
break comments if !match
|
|
@@ -62,8 +73,10 @@ module Run
|
|
|
62
73
|
# @param contents [String]
|
|
63
74
|
# @return [Array<Hash>]
|
|
64
75
|
def self.extract_tasks(contents)
|
|
65
|
-
Ripper.sexp(contents)[1].each_with_object([]) do |
|
|
66
|
-
next if
|
|
76
|
+
Ripper.sexp(contents)[1].each_with_object([]) do |node, tasks|
|
|
77
|
+
next if node[0] != :method_add_block
|
|
78
|
+
sexp = node[1]
|
|
79
|
+
next if sexp.fetch(1, nil)&.fetch(1, nil) != "task"
|
|
67
80
|
|
|
68
81
|
names = case sexp[2][1][0][0]
|
|
69
82
|
when :symbol_literal
|
|
@@ -86,12 +99,85 @@ module Run
|
|
|
86
99
|
tasks << {
|
|
87
100
|
names: names,
|
|
88
101
|
line: line,
|
|
102
|
+
params: extract_params(node[2]),
|
|
89
103
|
}
|
|
90
104
|
end.sort do |a, b|
|
|
91
105
|
a[:names].first <=> b[:names].first
|
|
92
106
|
end
|
|
93
107
|
end
|
|
94
108
|
|
|
109
|
+
# @param block_node [Array, nil]
|
|
110
|
+
# @return [Array<Hash>]
|
|
111
|
+
def self.extract_params(block_node)
|
|
112
|
+
return [] if block_node.nil?
|
|
113
|
+
block_var = block_node[1]
|
|
114
|
+
return [] if block_var.nil?
|
|
115
|
+
params = block_var[1]
|
|
116
|
+
return [] if params.nil?
|
|
117
|
+
|
|
118
|
+
result = []
|
|
119
|
+
|
|
120
|
+
(params[1] || []).each do |p|
|
|
121
|
+
result << { name: p[1], required: true, keyword: false, default: nil }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
(params[2] || []).each do |p|
|
|
125
|
+
result << { name: p[0][1], required: false, keyword: false, default: node_to_s(p[1]) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
(params[5] || []).each do |p|
|
|
129
|
+
name = p[0][1].chomp(":")
|
|
130
|
+
if p[1] == false
|
|
131
|
+
result << { name: name, required: true, keyword: true, default: nil }
|
|
132
|
+
else
|
|
133
|
+
result << { name: name, required: false, keyword: true, default: node_to_s(p[1]) }
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
result
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @param node [Array, nil]
|
|
141
|
+
# @return [String]
|
|
142
|
+
def self.node_to_s(node)
|
|
143
|
+
return "nil" if node.nil?
|
|
144
|
+
case node[0]
|
|
145
|
+
when :string_literal
|
|
146
|
+
node[1][1..-1].map { |p| p[0] == :@tstring_content ? p[1] : "..." }.join
|
|
147
|
+
when :@int, :@float
|
|
148
|
+
node[1]
|
|
149
|
+
when :var_ref
|
|
150
|
+
node[1][1]
|
|
151
|
+
when :symbol_literal
|
|
152
|
+
node[1][1][1]
|
|
153
|
+
when :array
|
|
154
|
+
"[]"
|
|
155
|
+
when :hash
|
|
156
|
+
"{}"
|
|
157
|
+
else
|
|
158
|
+
"..."
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# @param param [Hash]
|
|
163
|
+
# @return [String]
|
|
164
|
+
def self.format_param(param)
|
|
165
|
+
name = param[:name]
|
|
166
|
+
if param[:keyword]
|
|
167
|
+
if param[:required]
|
|
168
|
+
"<#{name}=<value>>"
|
|
169
|
+
else
|
|
170
|
+
"[#{name}=<value>] " + param[:default].bright_cyan
|
|
171
|
+
end
|
|
172
|
+
else
|
|
173
|
+
if param[:required]
|
|
174
|
+
"<#{name}>"
|
|
175
|
+
else
|
|
176
|
+
"[#{name}] " + param[:default].bright_cyan
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
95
181
|
# @param tasks [Array<Hash>]
|
|
96
182
|
# @return [Integer]
|
|
97
183
|
def self.compute_tasks_column_length(tasks)
|
data/src/run/core.rb
CHANGED
|
@@ -1,14 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Run
|
|
2
4
|
module Core
|
|
3
|
-
RUNFILE_FILENAME =
|
|
5
|
+
RUNFILE_FILENAME = ENV.fetch('RUNFILE', 'Runfile.rb')
|
|
4
6
|
RESERVED_TASK_NAMES = ["help", "version"]
|
|
5
7
|
@@tasks = []
|
|
8
|
+
@@runfile_version = nil
|
|
9
|
+
|
|
10
|
+
# @param version [Integer]
|
|
11
|
+
# @return [void]
|
|
12
|
+
def self.runfile_version=(version)
|
|
13
|
+
@@runfile_version = version.to_i
|
|
14
|
+
end
|
|
6
15
|
|
|
7
16
|
# @return [void]
|
|
8
17
|
def self.run_run
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
if ARGV.size == 1 && ARGV[0] == "--completions"
|
|
19
|
+
require File.expand_path(RUNFILE_FILENAME) if File.exist?(RUNFILE_FILENAME)
|
|
20
|
+
puts completions.join("\n")
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
raise Run::Error::NonExistingRunfile.new if !File.file?(RUNFILE_FILENAME)
|
|
24
|
+
if ARGV.size == 1 && ARGV[0] == "version"
|
|
25
|
+
puts version
|
|
26
|
+
elsif ARGV.size == 0 || (ARGV.size == 1 && ARGV[0] == "help")
|
|
27
|
+
require File.expand_path(RUNFILE_FILENAME)
|
|
28
|
+
check_runfile_version!
|
|
29
|
+
display_help
|
|
30
|
+
else
|
|
31
|
+
require File.expand_path(RUNFILE_FILENAME)
|
|
32
|
+
check_runfile_version!
|
|
33
|
+
run_requested_task
|
|
34
|
+
end
|
|
12
35
|
end
|
|
13
36
|
|
|
14
37
|
# @param task_name_or_command [Symbol, String]
|
|
@@ -16,10 +39,13 @@ module Run
|
|
|
16
39
|
# @param options [Hash] Optional options sent to the task.
|
|
17
40
|
# @return [void]
|
|
18
41
|
def self.run(task_name_or_command, *arguments, **options)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
quiet = options.delete(:quiet) || quiet?
|
|
43
|
+
with_quiet_context(quiet) do
|
|
44
|
+
if task_name_or_command.is_a?(Symbol)
|
|
45
|
+
run_block_task(task_name_or_command, *arguments, **options)
|
|
46
|
+
else
|
|
47
|
+
run_system_task(task_name_or_command)
|
|
48
|
+
end
|
|
23
49
|
end
|
|
24
50
|
end
|
|
25
51
|
|
|
@@ -45,16 +71,39 @@ module Run
|
|
|
45
71
|
|
|
46
72
|
private
|
|
47
73
|
|
|
48
|
-
# @return [
|
|
49
|
-
def self.
|
|
50
|
-
if
|
|
74
|
+
# @return [void]
|
|
75
|
+
def self.check_runfile_version!
|
|
76
|
+
if (@@runfile_version || 2) != version.to_s.split(".").first.to_i
|
|
77
|
+
raise Run::Error::RunfileVersionMismatch.new
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @return [void]
|
|
82
|
+
def self.display_version
|
|
83
|
+
puts Gemspec::Metadata.new("run_tasks").read.version
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @return [void]
|
|
87
|
+
def self.completions
|
|
88
|
+
(@@tasks.flat_map{ |t| t[:names] }.map(&:to_s) + RESERVED_TASK_NAMES).sort.uniq
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @return [void]
|
|
92
|
+
def self.display_help
|
|
93
|
+
puts
|
|
94
|
+
puts " Run v#{version}".bright_blue
|
|
95
|
+
contents = Run::Core::Help.run(File.read(File.join(Dir.pwd, RUNFILE_FILENAME)))
|
|
96
|
+
if contents.strip.size > 0
|
|
51
97
|
puts
|
|
52
|
-
puts "
|
|
98
|
+
puts " Project tasks:".magenta
|
|
53
99
|
puts
|
|
54
|
-
|
|
55
|
-
return true
|
|
100
|
+
puts contents
|
|
56
101
|
end
|
|
57
|
-
|
|
102
|
+
puts
|
|
103
|
+
puts " Global tasks:".magenta
|
|
104
|
+
puts
|
|
105
|
+
puts Run::Core::Help.run(File.read(File.join(__dir__, "..", "bootstrap.rb")))
|
|
106
|
+
puts
|
|
58
107
|
end
|
|
59
108
|
|
|
60
109
|
# @return [void]
|
|
@@ -62,17 +111,25 @@ module Run
|
|
|
62
111
|
name = ARGV[0].gsub('-', '_').to_sym # Auto-replace hyphens to underscores.
|
|
63
112
|
raise Run::Error::UnknownTask.new(name) if !task_exist?(name)
|
|
64
113
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
114
|
+
args = []
|
|
115
|
+
options = {}
|
|
116
|
+
|
|
117
|
+
ARGV.slice(1, ARGV.size - 1).each do |arg|
|
|
118
|
+
if (match = arg.match(/^\+(\w+)$/))
|
|
119
|
+
options[match[1].to_sym] = true
|
|
120
|
+
elsif (match = arg.match(/^-(\w+)$/))
|
|
121
|
+
options[match[1].to_sym] = false
|
|
122
|
+
else
|
|
123
|
+
value = Float(arg) rescue nil
|
|
124
|
+
next args << value if !value.nil?
|
|
125
|
+
next args << true if arg == "true"
|
|
126
|
+
next args << false if arg == "false"
|
|
127
|
+
next args << arg.to_sym if arg.match?(/^\w+$/)
|
|
128
|
+
args << arg
|
|
129
|
+
end
|
|
73
130
|
end
|
|
74
131
|
|
|
75
|
-
run name, *args
|
|
132
|
+
run name, *args, **options
|
|
76
133
|
end
|
|
77
134
|
|
|
78
135
|
# @param name [Symbol]
|
|
@@ -86,13 +143,61 @@ module Run
|
|
|
86
143
|
# @param options [Hash]
|
|
87
144
|
# @return [void]
|
|
88
145
|
def self.run_block_task(name, *args, **options)
|
|
89
|
-
@@tasks.find{ |item| item[:names].include? name }
|
|
146
|
+
task = @@tasks.find{ |item| item[:names].include? name }
|
|
147
|
+
raise Error::NonExistingTask.new(name) if task.nil?
|
|
148
|
+
|
|
149
|
+
task[:task].run(*args, **options)
|
|
90
150
|
end
|
|
91
151
|
|
|
92
|
-
# @param
|
|
152
|
+
# @param command [String]
|
|
153
|
+
# @return [void]
|
|
154
|
+
def self.run_system_task(command)
|
|
155
|
+
Run::Task::SystemTask.new(command).run
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# @return [String]
|
|
159
|
+
def self.version
|
|
160
|
+
gemspec_files = Dir.glob(File.join(Dir.pwd, "*.gemspec"))
|
|
161
|
+
|
|
162
|
+
if gemspec_files.first
|
|
163
|
+
Gem::Specification::load(gemspec_files.first).version.to_s
|
|
164
|
+
else
|
|
165
|
+
Gemspec::Metadata.new("run_tasks").read.version
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @return [Boolean]
|
|
170
|
+
def self.quiet?
|
|
171
|
+
!!Thread.current[:quiet]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @param quiet [Boolean]
|
|
93
175
|
# @return [void]
|
|
94
|
-
def self.
|
|
95
|
-
|
|
176
|
+
def self.with_quiet_context(quiet)
|
|
177
|
+
already_quiet = quiet?
|
|
178
|
+
Thread.current[:quiet] = quiet || already_quiet
|
|
179
|
+
|
|
180
|
+
prev_stdout = nil
|
|
181
|
+
prev_stderr = nil
|
|
182
|
+
|
|
183
|
+
if quiet && !already_quiet
|
|
184
|
+
prev_stdout = $stdout.dup
|
|
185
|
+
prev_stderr = $stderr.dup
|
|
186
|
+
$stdout.reopen(File::NULL)
|
|
187
|
+
$stderr.reopen(File::NULL)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
yield
|
|
191
|
+
rescue Interrupt
|
|
192
|
+
raise unless Thread.current[:quiet]
|
|
193
|
+
ensure
|
|
194
|
+
if prev_stdout
|
|
195
|
+
$stdout.reopen(prev_stdout)
|
|
196
|
+
$stderr.reopen(prev_stderr)
|
|
197
|
+
prev_stdout.close
|
|
198
|
+
prev_stderr.close
|
|
199
|
+
end
|
|
200
|
+
Thread.current[:quiet] = already_quiet
|
|
96
201
|
end
|
|
97
202
|
end
|
|
98
203
|
end
|
data/src/run/error/aborted.rb
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Run
|
|
2
4
|
module Error
|
|
3
5
|
class NonExistingRunfile < StandardError
|
|
6
|
+
def initialize
|
|
7
|
+
path = ENV['RUNFILE'] || 'Runfile.rb'
|
|
8
|
+
super File.file?(path) ? "Runfile.rb does not exist in '#{Dir.pwd}'" : "'#{path}' is not a valid Runfile"
|
|
9
|
+
end
|
|
4
10
|
end
|
|
5
11
|
end
|
|
6
12
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Run
|
|
2
4
|
module Helper
|
|
3
5
|
class AreYouSureHelper
|
|
@@ -17,7 +19,7 @@ module Run
|
|
|
17
19
|
|
|
18
20
|
# @return [String, Nil]
|
|
19
21
|
def answer
|
|
20
|
-
STDIN.gets
|
|
22
|
+
STDIN.gets&.chomp&.downcase&.chars&.first || "n"
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Run
|
|
4
|
+
module Helper
|
|
5
|
+
class BindHelper
|
|
6
|
+
TERM_TIMEOUT = 3
|
|
7
|
+
COLORS = %i[cyan magenta yellow green blue]
|
|
8
|
+
|
|
9
|
+
def initialize(*names)
|
|
10
|
+
@names = names
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
pgids = {}
|
|
15
|
+
threads = []
|
|
16
|
+
mutex = Mutex.new
|
|
17
|
+
shutting_down = false
|
|
18
|
+
|
|
19
|
+
shutdown = lambda do
|
|
20
|
+
return if shutting_down
|
|
21
|
+
shutting_down = true
|
|
22
|
+
pgids.each_value { |pgid| Process.kill('TERM', -pgid) rescue nil }
|
|
23
|
+
Thread.new do
|
|
24
|
+
sleep TERM_TIMEOUT
|
|
25
|
+
pgids.each_value { |pgid| Process.kill('KILL', -pgid) rescue nil }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Signal.trap('INT') { shutdown.call }
|
|
30
|
+
Signal.trap('TERM') { shutdown.call }
|
|
31
|
+
|
|
32
|
+
@names.each_with_index do |name, index|
|
|
33
|
+
prefix = "[#{name}]".send(COLORS[index % COLORS.size])
|
|
34
|
+
rd, wr = IO.pipe
|
|
35
|
+
|
|
36
|
+
pid = fork do
|
|
37
|
+
rd.close
|
|
38
|
+
$stdout.reopen(wr)
|
|
39
|
+
$stderr.reopen(wr)
|
|
40
|
+
wr.close
|
|
41
|
+
Process.setpgrp
|
|
42
|
+
Signal.trap('TERM') { exit 0 }
|
|
43
|
+
begin
|
|
44
|
+
Run::Core.run(name)
|
|
45
|
+
exit 0
|
|
46
|
+
rescue SystemExit => e
|
|
47
|
+
exit e.status
|
|
48
|
+
rescue Exception
|
|
49
|
+
exit 1
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
wr.close
|
|
54
|
+
pgids[name] = pid
|
|
55
|
+
|
|
56
|
+
threads << Thread.new(rd, prefix) do |pipe, pre|
|
|
57
|
+
pipe.each_line { |line| mutex.synchronize { STDOUT.write("#{pre} #{line}") } }
|
|
58
|
+
pipe.close
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
begin
|
|
63
|
+
loop do
|
|
64
|
+
Process.wait(-1)
|
|
65
|
+
shutdown.call
|
|
66
|
+
end
|
|
67
|
+
rescue Errno::ECHILD
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
threads.each(&:join)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Run
|
|
2
4
|
module Helper
|
|
3
5
|
class PauseHelper
|
|
6
|
+
DEFAULT_TEXT = "Press enter to continue"
|
|
7
|
+
|
|
8
|
+
# @param text [String]
|
|
9
|
+
def initialize(text = DEFAULT_TEXT)
|
|
10
|
+
raise ArgumentError.new("'text' must be a String") if !text.is_a?(String)
|
|
11
|
+
|
|
12
|
+
@text = text
|
|
13
|
+
end
|
|
14
|
+
|
|
4
15
|
# @return [void]
|
|
5
16
|
def run
|
|
17
|
+
print "#{@text}..."
|
|
6
18
|
STDIN.gets("\n")
|
|
7
19
|
end
|
|
8
20
|
end
|
|
9
21
|
end
|
|
10
|
-
end
|
|
22
|
+
end
|
data/src/run/task/block_task.rb
CHANGED
data/src/run/task/system_task.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Run
|
|
2
4
|
module Task
|
|
3
5
|
class SystemTask
|
|
@@ -6,10 +8,8 @@ module Run
|
|
|
6
8
|
@command = command
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
# @param arguments [Array] (unused)
|
|
10
|
-
# @param options [Hash] (unused)
|
|
11
11
|
# @return [void]
|
|
12
|
-
def run
|
|
12
|
+
def run
|
|
13
13
|
puts ">".bright_blue + " #{@command}".bright_white
|
|
14
14
|
puts
|
|
15
15
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: run_tasks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aurélien Delogu
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: tty-prompt
|
|
@@ -24,7 +23,48 @@ dependencies:
|
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: 0.23.1
|
|
27
|
-
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rb_monkey
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.1.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.1.0
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rb_gemspec
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 0.1.0
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 0.1.0
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rb_markdown
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 0.1.0
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 0.1.0
|
|
28
68
|
email: aurelien.delogu@gmail.com
|
|
29
69
|
executables:
|
|
30
70
|
- run
|
|
@@ -32,23 +72,19 @@ extensions: []
|
|
|
32
72
|
extra_rdoc_files: []
|
|
33
73
|
files:
|
|
34
74
|
- bin/run
|
|
75
|
+
- completions/_run
|
|
35
76
|
- src/bootstrap.rb
|
|
36
|
-
- src/gemspec/metadata.rb
|
|
37
|
-
- src/markdown/abstract_tag.rb
|
|
38
|
-
- src/markdown/bold_tag.rb
|
|
39
|
-
- src/markdown/code_tag.rb
|
|
40
|
-
- src/markdown/engine.rb
|
|
41
|
-
- src/markdown/italic_tag.rb
|
|
42
|
-
- src/monkey/string.rb
|
|
43
77
|
- src/run/core.rb
|
|
44
78
|
- src/run/core/help.rb
|
|
45
|
-
- src/run/core/verify_run_version.rb
|
|
46
79
|
- src/run/error/aborted.rb
|
|
47
80
|
- src/run/error/existing_task.rb
|
|
48
81
|
- src/run/error/non_existing_runfile.rb
|
|
82
|
+
- src/run/error/non_existing_task.rb
|
|
49
83
|
- src/run/error/reserved_task_name.rb
|
|
84
|
+
- src/run/error/runfile_version_mismatch.rb
|
|
50
85
|
- src/run/error/unknown_task.rb
|
|
51
86
|
- src/run/helper/are_you_sure_helper.rb
|
|
87
|
+
- src/run/helper/bind_helper.rb
|
|
52
88
|
- src/run/helper/catch_interruption_helper.rb
|
|
53
89
|
- src/run/helper/expand_helper.rb
|
|
54
90
|
- src/run/helper/menu_helper.rb
|
|
@@ -57,15 +93,10 @@ files:
|
|
|
57
93
|
- src/run/helper/wait_for_interruption_helper.rb
|
|
58
94
|
- src/run/task/block_task.rb
|
|
59
95
|
- src/run/task/system_task.rb
|
|
60
|
-
- src/version/local_gemspec_version.rb
|
|
61
|
-
- src/version/remote_gemspec_version.rb
|
|
62
|
-
- src/version/semver.rb
|
|
63
|
-
- src/version/unreachable_error.rb
|
|
64
96
|
homepage: https://github.com/pyrsmk/run
|
|
65
97
|
licenses:
|
|
66
98
|
- MIT
|
|
67
99
|
metadata: {}
|
|
68
|
-
post_install_message:
|
|
69
100
|
rdoc_options: []
|
|
70
101
|
require_paths:
|
|
71
102
|
- lib
|
|
@@ -80,9 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
80
111
|
- !ruby/object:Gem::Version
|
|
81
112
|
version: '0'
|
|
82
113
|
requirements: []
|
|
83
|
-
|
|
84
|
-
rubygems_version: 2.6.14.4
|
|
85
|
-
signing_key:
|
|
114
|
+
rubygems_version: 4.0.11
|
|
86
115
|
specification_version: 4
|
|
87
|
-
summary:
|
|
116
|
+
summary: Task runner for the masses
|
|
88
117
|
test_files: []
|
data/src/gemspec/metadata.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Gemspec
|
|
2
|
-
class Metadata
|
|
3
|
-
# @param lib_name [String]
|
|
4
|
-
def initialize(lib_name)
|
|
5
|
-
@lib_name = lib_name
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
# @return [Hash]
|
|
9
|
-
def read
|
|
10
|
-
@_read ||= (
|
|
11
|
-
path = "#{__dir__}/../../#{@lib_name}.gemspec"
|
|
12
|
-
|
|
13
|
-
# Development.
|
|
14
|
-
if File.exist?(path)
|
|
15
|
-
Gem::Specification::load(path)
|
|
16
|
-
# Production.
|
|
17
|
-
else
|
|
18
|
-
Gem::Specification::find_by_name(@lib_name) rescue nil
|
|
19
|
-
end
|
|
20
|
-
)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module Markdown
|
|
2
|
-
module AbstractTag
|
|
3
|
-
def initialize(value)
|
|
4
|
-
case value
|
|
5
|
-
when String
|
|
6
|
-
@string = value
|
|
7
|
-
when AbstractTag
|
|
8
|
-
@tag = value
|
|
9
|
-
else
|
|
10
|
-
raise ArgumentError.new("Invalid value of '#{value.class.name}' class")
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def to_ansi
|
|
15
|
-
string = @string || @tag.to_ansi
|
|
16
|
-
pattern = Regexp.new(
|
|
17
|
-
"(^|.+?)" \
|
|
18
|
-
"(?:#{tokens.map{ |token| "\\" + token.chars.join("\\") }.join('|')})" \
|
|
19
|
-
"(.+?)" \
|
|
20
|
-
"(?:#{tokens.map{ |token| "\\" + token.chars.join("\\") }.join('|')})" \
|
|
21
|
-
"($|.+)"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
loop do
|
|
25
|
-
string = string.sub(pattern) do
|
|
26
|
-
Regexp.last_match[1] + convert(Regexp.last_match[2]) + Regexp.last_match[3]
|
|
27
|
-
end
|
|
28
|
-
break if !Regexp.last_match
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
string
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
protected
|
|
35
|
-
|
|
36
|
-
# @return [Array<String>]
|
|
37
|
-
def tokens
|
|
38
|
-
raise NotImplementedError.new
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @param string [String]
|
|
42
|
-
# @return [String]
|
|
43
|
-
def convert(string)
|
|
44
|
-
raise NotImplementedError.new
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
data/src/markdown/bold_tag.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require_relative "./abstract_tag"
|
|
2
|
-
|
|
3
|
-
module Markdown
|
|
4
|
-
class BoldTag
|
|
5
|
-
include AbstractTag
|
|
6
|
-
|
|
7
|
-
protected
|
|
8
|
-
|
|
9
|
-
# @return [Array<String>]
|
|
10
|
-
def tokens
|
|
11
|
-
["**", "__"]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param string [String]
|
|
15
|
-
# @return [String]
|
|
16
|
-
def convert(string)
|
|
17
|
-
string.bold
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/src/markdown/code_tag.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require_relative "./abstract_tag"
|
|
2
|
-
|
|
3
|
-
module Markdown
|
|
4
|
-
class CodeTag
|
|
5
|
-
include AbstractTag
|
|
6
|
-
|
|
7
|
-
protected
|
|
8
|
-
|
|
9
|
-
# @return [Array<String>]
|
|
10
|
-
def tokens
|
|
11
|
-
["`"]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param string [String]
|
|
15
|
-
# @return [String]
|
|
16
|
-
def convert(string)
|
|
17
|
-
string.cyan
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/src/markdown/engine.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require_relative "./bold_tag"
|
|
2
|
-
require_relative "./code_tag"
|
|
3
|
-
require_relative "./italic_tag"
|
|
4
|
-
|
|
5
|
-
module Markdown
|
|
6
|
-
class Engine
|
|
7
|
-
def initialize(string)
|
|
8
|
-
@string = string
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def to_ansi
|
|
12
|
-
# The tags are ordered by priority.
|
|
13
|
-
# For example: `Bold` should run before `Italic`.
|
|
14
|
-
CodeTag.new(ItalicTag.new(BoldTag.new(@string))).to_ansi
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
data/src/markdown/italic_tag.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require_relative "./abstract_tag"
|
|
2
|
-
|
|
3
|
-
module Markdown
|
|
4
|
-
class ItalicTag
|
|
5
|
-
include AbstractTag
|
|
6
|
-
|
|
7
|
-
protected
|
|
8
|
-
|
|
9
|
-
# @return [Array<String>]
|
|
10
|
-
def tokens
|
|
11
|
-
["*", "_"]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param string [String]
|
|
15
|
-
# @return [String]
|
|
16
|
-
def convert(string)
|
|
17
|
-
string.italic
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/src/monkey/string.rb
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
|
2
|
-
class String
|
|
3
|
-
@@styles = {
|
|
4
|
-
:bold => "1",
|
|
5
|
-
:dim => "2",
|
|
6
|
-
:italic => "3",
|
|
7
|
-
:underline => "4",
|
|
8
|
-
:inverse => "7",
|
|
9
|
-
:strikethrough => "9",
|
|
10
|
-
:fg_black => "30",
|
|
11
|
-
:fg_red => "31",
|
|
12
|
-
:fg_green => "32",
|
|
13
|
-
:fg_yellow => "33",
|
|
14
|
-
:fg_blue => "34",
|
|
15
|
-
:fg_magenta => "35",
|
|
16
|
-
:fg_cyan => "36",
|
|
17
|
-
:fg_white => "37",
|
|
18
|
-
:fg_bright_black => "30;1",
|
|
19
|
-
:fg_bright_red => "31;1",
|
|
20
|
-
:fg_bright_green => "32;1",
|
|
21
|
-
:fg_bright_yellow => "33;1",
|
|
22
|
-
:fg_bright_blue => "34;1",
|
|
23
|
-
:fg_bright_magenta => "35;1",
|
|
24
|
-
:fg_bright_cyan => "36;1",
|
|
25
|
-
:fg_bright_white => "37;1",
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# To be able to handle more styles (with method chaining) we should refactor this.
|
|
29
|
-
def stylize(style)
|
|
30
|
-
"\033[#{@@styles[style.to_sym]}m#{self}\033[0m"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def bold; stylize(:bold); end
|
|
34
|
-
def dim; stylize(:dim); end
|
|
35
|
-
def italic; stylize(:italic); end
|
|
36
|
-
def underline; stylize(:underline); end
|
|
37
|
-
def inverse; stylize(:inverse); end
|
|
38
|
-
def strikethrough; stylize(:strikethrough); end
|
|
39
|
-
def black; stylize(:fg_black); end
|
|
40
|
-
def red; stylize(:fg_red); end
|
|
41
|
-
def green; stylize(:fg_green); end
|
|
42
|
-
def yellow; stylize(:fg_yellow); end
|
|
43
|
-
def blue; stylize(:fg_blue); end
|
|
44
|
-
def magenta; stylize(:fg_magenta); end
|
|
45
|
-
def cyan; stylize(:fg_cyan); end
|
|
46
|
-
def white; stylize(:fg_white); end
|
|
47
|
-
def bright_black; stylize(:fg_bright_black); end
|
|
48
|
-
def bright_red; stylize(:fg_bright_red); end
|
|
49
|
-
def bright_green; stylize(:fg_bright_green); end
|
|
50
|
-
def bright_yellow; stylize(:fg_bright_yellow); end
|
|
51
|
-
def bright_blue; stylize(:fg_bright_blue); end
|
|
52
|
-
def bright_magenta; stylize(:fg_bright_magenta); end
|
|
53
|
-
def bright_cyan; stylize(:fg_bright_cyan); end
|
|
54
|
-
def bright_white; stylize(:fg_bright_white); end
|
|
55
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Run
|
|
2
|
-
module Core
|
|
3
|
-
module VerifyRunVersion
|
|
4
|
-
REMOTE_GEMSPEC_URL = "https://raw.githubusercontent.com/pyrsmk/run/master/run_tasks.gemspec"
|
|
5
|
-
|
|
6
|
-
# @return [void]
|
|
7
|
-
def self.run
|
|
8
|
-
local_version = Version::Semver.new(
|
|
9
|
-
Version::LocalGemspecVersion.new(Gemspec::Metadata.new("run_tasks")).extract
|
|
10
|
-
)
|
|
11
|
-
remote_version = Version::Semver.new(
|
|
12
|
-
Version::RemoteGemspecVersion.new(REMOTE_GEMSPEC_URL).extract
|
|
13
|
-
)
|
|
14
|
-
if local_version.major == remote_version.major && local_version < remote_version
|
|
15
|
-
puts
|
|
16
|
-
puts " A new version of Run is available: #{remote_version.major}.#{remote_version.minor}.#{remote_version.patch}".bright_yellow
|
|
17
|
-
puts " Please update with: `gem update run_tasks`".bright_yellow
|
|
18
|
-
end
|
|
19
|
-
rescue Version::UnreachableError
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require "open-uri"
|
|
2
|
-
require "socket"
|
|
3
|
-
|
|
4
|
-
module Version
|
|
5
|
-
class RemoteGemspecVersion
|
|
6
|
-
# @param url [String]
|
|
7
|
-
def initialize(url)
|
|
8
|
-
@url = url
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# @return [String]
|
|
12
|
-
def extract
|
|
13
|
-
# `mode` and `perm` options are not used, but we need to set them in order to set
|
|
14
|
-
# options...
|
|
15
|
-
contents = URI.parse(@url).open("r", 0666, open_timeout: 1, read_timeout: 1).read
|
|
16
|
-
matches = /^\s*s.version\s*=\s*"(.+?)"\s*$/.match(contents)
|
|
17
|
-
raise UnreachableError.new if matches.nil?
|
|
18
|
-
matches[1]
|
|
19
|
-
rescue SocketError
|
|
20
|
-
raise UnreachableError.new
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/src/version/semver.rb
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
module Version
|
|
2
|
-
class Semver
|
|
3
|
-
# @return [String]
|
|
4
|
-
def initialize(version)
|
|
5
|
-
match = /^(\d+)\.(\d+)\.(\d+)$/.match(version)
|
|
6
|
-
raise ArgumentError.new("Invalid SEMVER number") if match.nil?
|
|
7
|
-
|
|
8
|
-
@major = match[1].to_i
|
|
9
|
-
@minor = match[2].to_i
|
|
10
|
-
@patch = match[3].to_i
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# @return [Integer]
|
|
14
|
-
def major
|
|
15
|
-
@major
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @return [Integer]
|
|
19
|
-
def minor
|
|
20
|
-
@minor
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# @return [Integer]
|
|
24
|
-
def patch
|
|
25
|
-
@patch
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# @return [Boolean]
|
|
29
|
-
def <(semver)
|
|
30
|
-
is_a_semver?(semver)
|
|
31
|
-
|
|
32
|
-
@major < semver.major ||
|
|
33
|
-
(@major == semver.major && @minor < semver.minor) ||
|
|
34
|
-
(@major == semver.major && @minor == semver.minor && @patch < semver.patch)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @return [Boolean]
|
|
38
|
-
def >(semver)
|
|
39
|
-
is_a_semver?(semver)
|
|
40
|
-
|
|
41
|
-
@major > semver.major ||
|
|
42
|
-
(@major == semver.major && @minor > semver.minor) ||
|
|
43
|
-
(@major == semver.major && @minor == semver.minor && @patch > semver.patch)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# @return [Boolean]
|
|
47
|
-
def ==(semver)
|
|
48
|
-
is_a_semver?(semver)
|
|
49
|
-
|
|
50
|
-
@major == semver.major && @minor == semver.minor && @patch == semver.patch
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
# @return [Boolean]
|
|
56
|
-
def is_a_semver?(semver)
|
|
57
|
-
if !semver.respond_to?(:major) || !semver.respond_to?(:minor) || !semver.respond_to?(:patch)
|
|
58
|
-
raise ArgumentError.new("SemVer compatible object expected")
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|