spud 0.2.3 → 0.2.10
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/lib/spud.rb +3 -2
- data/lib/spud/block_param_info.rb +80 -0
- data/lib/spud/cli/options.rb +29 -0
- data/lib/spud/cli/parser.rb +22 -20
- data/lib/spud/cli/results.rb +18 -11
- data/lib/spud/driver.rb +141 -0
- data/lib/spud/error.rb +6 -1
- data/lib/spud/help.rb +16 -15
- data/lib/spud/lister.rb +65 -29
- data/lib/spud/shell/command.rb +75 -0
- data/lib/spud/shell/result.rb +33 -0
- data/lib/spud/task_arg.rb +24 -12
- data/lib/spud/task_args.rb +20 -18
- data/lib/spud/task_runners/docker-compose/task.rb +56 -0
- data/lib/spud/task_runners/make/task.rb +67 -0
- data/lib/spud/task_runners/package.json/task.rb +71 -0
- data/lib/spud/task_runners/rake_task_runner/task.rb +59 -0
- data/lib/spud/{build_tools/spud → task_runners/spud_task_runner}/dependency.rb +16 -4
- data/lib/spud/task_runners/spud_task_runner/file_dsl.rb +64 -0
- data/lib/spud/task_runners/spud_task_runner/task.rb +154 -0
- data/lib/spud/task_runners/spud_task_runner/task_dsl.rb +95 -0
- data/lib/spud/task_runners/task.rb +41 -0
- data/lib/spud/task_runners/task_runners.rb +28 -0
- data/lib/spud/version.rb +2 -1
- data/lib/spud/watch.rb +74 -0
- metadata +67 -21
- data/lib/spud/build_tools/build_tools.rb +0 -13
- data/lib/spud/build_tools/make/task.rb +0 -27
- data/lib/spud/build_tools/package.json/task.rb +0 -47
- data/lib/spud/build_tools/spud/block_param_info.rb +0 -77
- data/lib/spud/build_tools/spud/dsl/file.rb +0 -23
- data/lib/spud/build_tools/spud/dsl/task.rb +0 -63
- data/lib/spud/build_tools/spud/shell/command.rb +0 -52
- data/lib/spud/build_tools/spud/shell/result.rb +0 -26
- data/lib/spud/build_tools/spud/task.rb +0 -177
- data/lib/spud/build_tools/task.rb +0 -41
- data/lib/spud/options.rb +0 -14
- data/lib/spud/runtime.rb +0 -114
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: d0b081b3d20c3a0b253e2383b4a514aac28edcf8
|
|
4
|
+
data.tar.gz: da8443efc8c52b187e84158075cee7d5875de020
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3798ff8d115c5c1cdafcca5f134531f5df5932a7bbfafd1d33b07486dd132cf49674888fa45c1708d058a9f2b6653f2ce8e642c93112313cec684a31b6ebde7d
|
|
7
|
+
data.tar.gz: e0f7c61cfc28af1d0f4b821fb904731240e842f35846c6d3257153223d814adc6875cf49241d046cfa0dd1c24d33f39fc59abe009a99c6ad6acb22e9493e4e04
|
data/lib/spud.rb
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'sorbet-runtime'
|
|
3
|
+
require 'spud/task_arg'
|
|
4
|
+
|
|
5
|
+
module Spud
|
|
6
|
+
class BlockParamInfo
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
9
|
+
sig {params(filename: String, block: Proc).void}
|
|
10
|
+
def initialize(filename, &block)
|
|
11
|
+
@filename = filename
|
|
12
|
+
@block = block
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
sig {returns(T::Array[TaskArg])}
|
|
16
|
+
def task_args
|
|
17
|
+
parameters.map do |type, name|
|
|
18
|
+
name_string = name.to_s
|
|
19
|
+
|
|
20
|
+
case type
|
|
21
|
+
when :req
|
|
22
|
+
TaskArg.new(name_string, 'ordered')
|
|
23
|
+
when :opt
|
|
24
|
+
TaskArg.new(name_string, 'ordered', default: arg_values[name])
|
|
25
|
+
when :keyreq
|
|
26
|
+
TaskArg.new(name_string, 'named')
|
|
27
|
+
when :key
|
|
28
|
+
TaskArg.new(name_string, 'named', default: arg_values[name])
|
|
29
|
+
else
|
|
30
|
+
raise "invalid proc arg type: '#{type}'"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
sig {returns([T::Array[NilClass], T::Hash[Symbol, NilClass]])}
|
|
36
|
+
def dummy_args
|
|
37
|
+
[dummy_ordered_args, dummy_named_args]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
sig {returns(T::Array[NilClass])}
|
|
41
|
+
def dummy_ordered_args
|
|
42
|
+
Array.new(parameters.count { |p| p.first == :req })
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
sig {returns(T::Hash[Symbol, NilClass])}
|
|
46
|
+
def dummy_named_args
|
|
47
|
+
parameters.select { |p| p.first == :keyreq }.map(&:last).each_with_object({}) { |n, h| h[n] = nil }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
sig {returns(String)}
|
|
51
|
+
def arg_hash_string
|
|
52
|
+
"{ #{parameters.map(&:last).map { |n| "#{n}: #{n}" }.join(', ')} }"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
sig {returns(T::Hash[Symbol, T.nilable(String)])}
|
|
56
|
+
def arg_values
|
|
57
|
+
@arg_values ||= begin
|
|
58
|
+
ordered, named = dummy_args
|
|
59
|
+
T.unsafe(lambda(arg_hash_string)).call(*ordered, **named)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
sig {returns(T::Array[[Symbol, Symbol]])}
|
|
64
|
+
def parameters
|
|
65
|
+
@parameters ||= lambda.parameters
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
sig {params(body: T.nilable(String)).returns(Proc)}
|
|
69
|
+
def lambda(body = nil)
|
|
70
|
+
line = File.read(@filename).split("\n")[@block.source_location.last - 1]
|
|
71
|
+
|
|
72
|
+
match = /(do|{)\s*\|(?<params>[^|]+)\|/.match(line)
|
|
73
|
+
return -> {} unless match
|
|
74
|
+
|
|
75
|
+
param_source = T.must(match[:params])
|
|
76
|
+
param_source += ', _: nil, __: nil, ___: nil' if body
|
|
77
|
+
eval "-> (#{param_source}) { #{body} }"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'sorbet-runtime'
|
|
3
|
+
|
|
4
|
+
module Spud
|
|
5
|
+
module CLI
|
|
6
|
+
class Options
|
|
7
|
+
extend T::Sig
|
|
8
|
+
|
|
9
|
+
attr_writer :help
|
|
10
|
+
attr_writer :inspect
|
|
11
|
+
|
|
12
|
+
sig {returns(T::Array[String])}
|
|
13
|
+
def watches
|
|
14
|
+
@watches = T.let(@watches, T.nilable(T::Array[String]))
|
|
15
|
+
@watches ||= []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
sig {returns(T::Boolean)}
|
|
19
|
+
def help?
|
|
20
|
+
!!@help
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
sig {returns(T::Boolean)}
|
|
24
|
+
def inspect?
|
|
25
|
+
!!@inspect
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/spud/cli/parser.rb
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'sorbet-runtime'
|
|
1
3
|
require 'spud/cli/results'
|
|
4
|
+
require 'spud/cli/options'
|
|
2
5
|
|
|
3
6
|
module Spud
|
|
4
7
|
module CLI
|
|
5
8
|
class Parser
|
|
6
|
-
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
sig {returns(Results)}
|
|
7
12
|
attr_reader :results
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
sig {returns(Results)}
|
|
10
15
|
def self.parse!
|
|
11
16
|
parse(ARGV)
|
|
12
17
|
end
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
# @return [Spud::CLI::Results]
|
|
19
|
+
sig {params(args: T::Array[String]).returns(Results)}
|
|
16
20
|
def self.parse(args)
|
|
17
21
|
new(args).parse!
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
sig {params(args: T::Array[String]).void}
|
|
21
25
|
def initialize(args)
|
|
22
26
|
@args = args.dup
|
|
23
27
|
@results = Results.new
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
sig {returns(Results)}
|
|
27
31
|
def parse!
|
|
28
32
|
parse_arg! until done?
|
|
29
33
|
results
|
|
@@ -31,7 +35,7 @@ module Spud
|
|
|
31
35
|
|
|
32
36
|
private
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
sig {void}
|
|
35
39
|
def parse_arg!
|
|
36
40
|
if before_task_name?
|
|
37
41
|
flag? ? handle_option! : set_task_name!
|
|
@@ -39,61 +43,59 @@ module Spud
|
|
|
39
43
|
if flag?
|
|
40
44
|
results.named[lstrip_hyphens(take!)] = take!
|
|
41
45
|
else
|
|
42
|
-
results.
|
|
46
|
+
results.ordered << take!
|
|
43
47
|
end
|
|
44
48
|
end
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
sig {void}
|
|
48
52
|
def handle_option!
|
|
49
53
|
flag = take!
|
|
50
54
|
case flag
|
|
51
55
|
when '-h', '--help' then options.help = true
|
|
52
|
-
when '-f', '--files' then options.files = true
|
|
53
|
-
when '-i', '--inspect' then options.inspect = true
|
|
54
56
|
when '-w', '--watch' then options.watches << take!
|
|
55
|
-
when '--
|
|
57
|
+
when '-i', '--inspect' then options.inspect = true
|
|
56
58
|
else raise Error, "invalid option: '#{flag}'"
|
|
57
59
|
end
|
|
58
60
|
end
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
sig {returns(Options)}
|
|
61
63
|
def options
|
|
62
64
|
results.options
|
|
63
65
|
end
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
# @return [String]
|
|
67
|
+
sig {params(flag: String).returns(String)}
|
|
67
68
|
def lstrip_hyphens(flag)
|
|
68
69
|
flag.gsub(/^-+/, '')
|
|
69
70
|
end
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
sig {returns(T::Boolean)}
|
|
72
73
|
def before_task_name?
|
|
73
74
|
!results.task
|
|
74
75
|
end
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
sig {void}
|
|
77
78
|
def set_task_name!
|
|
78
79
|
results.task = take!
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
sig {returns(String)}
|
|
82
83
|
def take!
|
|
83
84
|
@args.shift
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
# @return [String]
|
|
88
|
+
sig {returns(String)}
|
|
87
89
|
def arg
|
|
88
90
|
@args.first
|
|
89
91
|
end
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
sig {returns(T::Boolean)}
|
|
92
94
|
def flag?
|
|
93
95
|
arg.start_with?('-')
|
|
94
96
|
end
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
sig {returns(T::Boolean)}
|
|
97
99
|
def done?
|
|
98
100
|
@args.empty?
|
|
99
101
|
end
|
data/lib/spud/cli/results.rb
CHANGED
|
@@ -1,25 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
# typed: strict
|
|
2
|
+
require 'sorbet-runtime'
|
|
3
|
+
require 'spud/cli/options'
|
|
2
4
|
|
|
3
5
|
module Spud
|
|
4
6
|
module CLI
|
|
5
7
|
class Results
|
|
6
|
-
|
|
7
|
-
attr_accessor :task
|
|
8
|
+
extend T::Sig
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@options ||= Options.new
|
|
12
|
-
end
|
|
10
|
+
sig {returns(T.nilable(String))}
|
|
11
|
+
attr_accessor :task
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
def
|
|
16
|
-
@
|
|
13
|
+
sig {returns(T::Array[String])}
|
|
14
|
+
def ordered
|
|
15
|
+
@ordered = T.let(@ordered, T.nilable(T::Array[String]))
|
|
16
|
+
@ordered ||= []
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
sig {returns(T::Hash[String, String])}
|
|
20
20
|
def named
|
|
21
|
+
@named = T.let(@named, T.nilable(T::Hash[String, String]))
|
|
21
22
|
@named ||= {}
|
|
22
23
|
end
|
|
24
|
+
|
|
25
|
+
sig {returns(Options)}
|
|
26
|
+
def options
|
|
27
|
+
@options = T.let(@options, T.nilable(Options))
|
|
28
|
+
@options ||= Options.new
|
|
29
|
+
end
|
|
23
30
|
end
|
|
24
31
|
end
|
|
25
32
|
end
|
data/lib/spud/driver.rb
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'sorbet-runtime'
|
|
3
|
+
require 'spud/error'
|
|
4
|
+
require 'spud/help'
|
|
5
|
+
require 'spud/lister'
|
|
6
|
+
require 'spud/watch'
|
|
7
|
+
require 'spud/cli/parser'
|
|
8
|
+
require 'spud/cli/options'
|
|
9
|
+
require 'spud/task_runners/task'
|
|
10
|
+
require 'spud/task_runners/task_runners'
|
|
11
|
+
require 'spud/task_runners/spud_task_runner/task'
|
|
12
|
+
|
|
13
|
+
module Spud
|
|
14
|
+
class Driver
|
|
15
|
+
extend T::Sig
|
|
16
|
+
|
|
17
|
+
sig {returns(T.nilable(Integer))}
|
|
18
|
+
attr_reader :subprocess_pid
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
@subprocess_pid = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
sig {void}
|
|
25
|
+
def run!
|
|
26
|
+
if debug?
|
|
27
|
+
puts "options: #{options.inspect}"
|
|
28
|
+
puts "task: #{args.task}"
|
|
29
|
+
puts "ordered: #{args.ordered}"
|
|
30
|
+
puts "named: #{args.named}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if options.help?
|
|
34
|
+
Help.print!
|
|
35
|
+
return
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
unless args.task
|
|
39
|
+
lister.list_tasks!
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if options.inspect?
|
|
44
|
+
inspect!
|
|
45
|
+
return
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
invoke!
|
|
49
|
+
rescue Error => error
|
|
50
|
+
puts error.message
|
|
51
|
+
raise error if debug?
|
|
52
|
+
rescue Interrupt => error
|
|
53
|
+
puts "handled interrupt #{error}" if debug?
|
|
54
|
+
rescue => error
|
|
55
|
+
puts "fatal: #{error.message}"
|
|
56
|
+
raise error if debug?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
sig {params(name: String, ordered: T::Array[String], named: T::Hash[T.any(String, Symbol), String]).returns(T.untyped)}
|
|
60
|
+
def invoke(name, ordered, named)
|
|
61
|
+
get_task(name).invoke(ordered, stringify_keys(named))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
sig {params(pid: T.nilable(Integer)).void}
|
|
65
|
+
def register_subprocess(pid)
|
|
66
|
+
@subprocess_pid = pid
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
sig {returns(T::Boolean)}
|
|
70
|
+
def debug?
|
|
71
|
+
@debug ||= ENV.key?('SPUD_DEBUG') && ENV['SPUD_DEBUG'] != 'false'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
sig {void}
|
|
77
|
+
def invoke!
|
|
78
|
+
task_name = T.must(args.task)
|
|
79
|
+
task = get_task(task_name)
|
|
80
|
+
|
|
81
|
+
watches = options.watches
|
|
82
|
+
watches = task.watches if watches.empty?
|
|
83
|
+
|
|
84
|
+
if watches.empty?
|
|
85
|
+
invoke(task_name, args.ordered, args.named)
|
|
86
|
+
else
|
|
87
|
+
raise Error, "watches only supported for Spud tasks" unless task.is_a?(TaskRunners::SpudTaskRunner::Task)
|
|
88
|
+
|
|
89
|
+
Watch.run!(
|
|
90
|
+
driver: self,
|
|
91
|
+
task: task_name,
|
|
92
|
+
ordered: args.ordered,
|
|
93
|
+
named: args.named,
|
|
94
|
+
watches: watches,
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
sig {void}
|
|
100
|
+
def inspect!
|
|
101
|
+
puts get_task(T.must(args.task)).details
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
sig {params(task_name: String).returns(TaskRunners::Task)}
|
|
105
|
+
def get_task(task_name)
|
|
106
|
+
task = tasks[task_name]
|
|
107
|
+
raise Error, "no task found for '#{task_name}'" unless task
|
|
108
|
+
|
|
109
|
+
task
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
sig {returns(T::Hash[String, TaskRunners::Task])}
|
|
113
|
+
def tasks
|
|
114
|
+
@tasks ||= TaskRunners.get.each_with_object({}) do |task_runner, tasks|
|
|
115
|
+
task_runner.tasks(self).each do |task|
|
|
116
|
+
tasks[task.name] = task
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
sig {returns(CLI::Results)}
|
|
122
|
+
def args
|
|
123
|
+
@args ||= CLI::Parser.parse!
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
sig {returns(Lister)}
|
|
127
|
+
def lister
|
|
128
|
+
@lister ||= Lister.new(tasks.values)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
sig {returns(CLI::Options)}
|
|
132
|
+
def options
|
|
133
|
+
args.options
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
sig {params(hash: T::Hash[T.any(String, Symbol), T.untyped]).returns(T::Hash[String, T.untyped])}
|
|
137
|
+
def stringify_keys(hash)
|
|
138
|
+
hash.each_with_object({}) { |(key, value), new_hash| new_hash[key.to_s] = value }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|