spud 0.2.0 → 0.2.5
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/spud.rb +3 -2
- data/lib/spud/block_param_info.rb +80 -0
- data/lib/spud/cli/options.rb +35 -0
- data/lib/spud/cli/parser.rb +23 -19
- data/lib/spud/cli/results.rb +18 -11
- data/lib/spud/driver.rb +135 -0
- data/lib/spud/error.rb +1 -0
- data/lib/spud/help.rb +13 -13
- data/lib/spud/lister.rb +27 -22
- 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/make/task.rb +67 -0
- data/lib/spud/task_runners/package.json/task.rb +71 -0
- data/lib/spud/task_runners/spud_task_runner/dependency.rb +49 -0
- data/lib/spud/task_runners/spud_task_runner/file_dsl.rb +57 -0
- data/lib/spud/task_runners/spud_task_runner/task.rb +148 -0
- data/lib/spud/task_runners/spud_task_runner/task_dsl.rb +90 -0
- data/lib/spud/task_runners/task.rb +40 -0
- data/lib/spud/task_runners/task_runners.rb +25 -0
- data/lib/spud/version.rb +2 -1
- data/lib/spud/watch.rb +73 -0
- metadata +46 -16
- 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 -125
- data/lib/spud/build_tools/task.rb +0 -33
- data/lib/spud/options.rb +0 -14
- data/lib/spud/runtime.rb +0 -104
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28a274884358f6717d4e649d7ad01ea399317c89a02d2595576a15d35465b8de
|
4
|
+
data.tar.gz: 1866b4fc335245a0a86fb21ad60c875596af2cc545399aa22db440d34e51bbf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b44fd607406fe417224470905701c9f37fbb616ebc207df2ad041650f3368c5d6a15d5cf07778641d72d47f9c6af1b3fca7c774f09660bff679f44e50a946ea9
|
7
|
+
data.tar.gz: e4e08a44cce308f92d7ff769ddf4f2ad4f75dfe8f4ca54643b4d84e9266cce9fbed191fd6e85710839440b8d85126b57dfaeadc881e17f412850f77432b46b51
|
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,35 @@
|
|
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 :files
|
11
|
+
attr_writer :inspect
|
12
|
+
|
13
|
+
sig {returns(T::Array[String])}
|
14
|
+
def watches
|
15
|
+
@watches = T.let(@watches, T.nilable(T::Array[String]))
|
16
|
+
@watches ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
sig {returns(T::Boolean)}
|
20
|
+
def help?
|
21
|
+
!!@help
|
22
|
+
end
|
23
|
+
|
24
|
+
sig {returns(T::Boolean)}
|
25
|
+
def files?
|
26
|
+
!!@files
|
27
|
+
end
|
28
|
+
|
29
|
+
sig {returns(T::Boolean)}
|
30
|
+
def inspect?
|
31
|
+
!!@inspect
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
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,60 +43,60 @@ 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
56
|
when '-w', '--watch' then options.watches << take!
|
54
|
-
when '--
|
57
|
+
when '-f', '--files' then options.files = true
|
58
|
+
when '-i', '--inspect' then options.inspect = true
|
55
59
|
else raise Error, "invalid option: '#{flag}'"
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
|
-
|
63
|
+
sig {returns(Options)}
|
60
64
|
def options
|
61
65
|
results.options
|
62
66
|
end
|
63
67
|
|
64
|
-
|
65
|
-
# @return [String]
|
68
|
+
sig {params(flag: String).returns(String)}
|
66
69
|
def lstrip_hyphens(flag)
|
67
70
|
flag.gsub(/^-+/, '')
|
68
71
|
end
|
69
72
|
|
70
|
-
|
73
|
+
sig {returns(T::Boolean)}
|
71
74
|
def before_task_name?
|
72
75
|
!results.task
|
73
76
|
end
|
74
77
|
|
75
|
-
|
78
|
+
sig {void}
|
76
79
|
def set_task_name!
|
77
80
|
results.task = take!
|
78
81
|
end
|
79
82
|
|
80
|
-
|
83
|
+
sig {returns(String)}
|
81
84
|
def take!
|
82
85
|
@args.shift
|
83
86
|
end
|
84
87
|
|
85
88
|
# @return [String]
|
89
|
+
sig {returns(String)}
|
86
90
|
def arg
|
87
91
|
@args.first
|
88
92
|
end
|
89
93
|
|
90
|
-
|
94
|
+
sig {returns(T::Boolean)}
|
91
95
|
def flag?
|
92
96
|
arg.start_with?('-')
|
93
97
|
end
|
94
98
|
|
95
|
-
|
99
|
+
sig {returns(T::Boolean)}
|
96
100
|
def done?
|
97
101
|
@args.empty?
|
98
102
|
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,135 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'spud/error'
|
3
|
+
require 'spud/help'
|
4
|
+
require 'spud/lister'
|
5
|
+
require 'spud/watch'
|
6
|
+
require 'spud/cli/parser'
|
7
|
+
require 'spud/cli/options'
|
8
|
+
require 'spud/task_runners/task'
|
9
|
+
require 'spud/task_runners/task_runners'
|
10
|
+
|
11
|
+
module Spud
|
12
|
+
class Driver
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
sig {returns(T.nilable(Integer))}
|
16
|
+
attr_reader :subprocess_pid
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@subprocess_pid = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
sig {void}
|
23
|
+
def run!
|
24
|
+
if debug?
|
25
|
+
puts "options: #{options.inspect}"
|
26
|
+
puts "task: #{args.task}"
|
27
|
+
puts "ordered: #{args.ordered}"
|
28
|
+
puts "named: #{args.named}"
|
29
|
+
end
|
30
|
+
|
31
|
+
if options.help?
|
32
|
+
Help.print!
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
if options.files?
|
37
|
+
lister.list_filenames!
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
unless args.task
|
42
|
+
lister.list_tasks!
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
task = T.must(args.task)
|
47
|
+
if options.inspect?
|
48
|
+
puts get_task(task).details
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
unless options.watches.empty?
|
53
|
+
watch!
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
invoke(task, args.ordered, args.named)
|
58
|
+
rescue Error => error
|
59
|
+
puts error.message
|
60
|
+
raise error if debug?
|
61
|
+
rescue SystemExit, Interrupt => error
|
62
|
+
puts "handled interrupt #{error}" if debug?
|
63
|
+
rescue => error
|
64
|
+
puts "fatal: #{error.message}"
|
65
|
+
raise error if debug?
|
66
|
+
end
|
67
|
+
|
68
|
+
sig do
|
69
|
+
params(name: String, ordered: T::Array[String], named: T::Hash[T.any(String, Symbol), String]).returns(T.untyped)
|
70
|
+
end
|
71
|
+
def invoke(name, ordered, named)
|
72
|
+
get_task(name).invoke(ordered, stringify_keys(named))
|
73
|
+
end
|
74
|
+
|
75
|
+
sig {params(pid: T.nilable(Integer)).void}
|
76
|
+
def register_subprocess(pid)
|
77
|
+
@subprocess_pid = pid
|
78
|
+
end
|
79
|
+
|
80
|
+
sig {returns(T::Boolean)}
|
81
|
+
def debug?
|
82
|
+
@debug ||= ENV.key?('SPUD_DEBUG') && ENV['SPUD_DEBUG'] != 'false'
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
sig {void}
|
88
|
+
def watch!
|
89
|
+
Watch.run!(
|
90
|
+
driver: self,
|
91
|
+
task: T.must(args.task),
|
92
|
+
ordered: args.ordered,
|
93
|
+
named: args.named,
|
94
|
+
watches: options.watches,
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
sig {params(task_name: String).returns(TaskRunners::Task)}
|
99
|
+
def get_task(task_name)
|
100
|
+
task = tasks[task_name]
|
101
|
+
raise Error, "no task found for '#{task_name}'" unless task
|
102
|
+
|
103
|
+
task
|
104
|
+
end
|
105
|
+
|
106
|
+
sig {returns(T::Hash[String, TaskRunners::Task])}
|
107
|
+
def tasks
|
108
|
+
@tasks ||= TaskRunners.get.each_with_object({}) do |task_runner, tasks|
|
109
|
+
task_runner.tasks(self).each do |task|
|
110
|
+
tasks[task.name] = task
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
sig {returns(CLI::Results)}
|
116
|
+
def args
|
117
|
+
@args ||= CLI::Parser.parse!
|
118
|
+
end
|
119
|
+
|
120
|
+
sig {returns(Lister)}
|
121
|
+
def lister
|
122
|
+
@lister ||= Lister.new(tasks.values)
|
123
|
+
end
|
124
|
+
|
125
|
+
sig {returns(CLI::Options)}
|
126
|
+
def options
|
127
|
+
args.options
|
128
|
+
end
|
129
|
+
|
130
|
+
sig {params(hash: T::Hash[T.any(String, Symbol), T.untyped]).returns(T::Hash[String, T.untyped])}
|
131
|
+
def stringify_keys(hash)
|
132
|
+
hash.each_with_object({}) { |(key, value), new_hash| new_hash[key.to_s] = value }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/lib/spud/error.rb
CHANGED