spud 0.2.3 → 0.2.4
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 +22 -19
- data/lib/spud/cli/results.rb +18 -11
- data/lib/spud/driver.rb +134 -0
- data/lib/spud/error.rb +1 -0
- data/lib/spud/help.rb +13 -14
- data/lib/spud/lister.rb +27 -22
- data/lib/spud/task_arg.rb +15 -12
- data/lib/spud/task_args.rb +20 -18
- data/lib/spud/task_runners/make/task.rb +66 -0
- data/lib/spud/task_runners/package.json/task.rb +70 -0
- data/lib/spud/{build_tools/spud → task_runners/spud_task_runner}/dependency.rb +3 -2
- data/lib/spud/task_runners/spud_task_runner/file_dsl.rb +56 -0
- data/lib/spud/task_runners/spud_task_runner/shell/command.rb +58 -0
- data/lib/spud/{build_tools/spud → task_runners/spud_task_runner}/shell/result.rb +9 -4
- data/lib/spud/task_runners/spud_task_runner/task.rb +143 -0
- data/lib/spud/task_runners/spud_task_runner/task_dsl.rb +82 -0
- data/lib/spud/task_runners/task.rb +43 -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 -17
- 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/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
data/lib/spud/lister.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'sorbet-runtime'
|
1
3
|
require 'stringio'
|
4
|
+
require 'spud/task_runners/task'
|
2
5
|
|
3
6
|
module Spud
|
4
7
|
class Lister
|
5
|
-
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig {params(tasks: T::Array[TaskRunners::Task]).void}
|
6
11
|
def initialize(tasks)
|
7
12
|
@tasks = tasks
|
8
13
|
end
|
9
14
|
|
10
|
-
|
11
|
-
def
|
15
|
+
sig {void}
|
16
|
+
def list_tasks!
|
12
17
|
builder = StringIO.new
|
13
18
|
|
14
19
|
@tasks.each do |task|
|
15
20
|
builder.write task.name.ljust(max_task_length)
|
16
21
|
|
17
|
-
if
|
22
|
+
if show_ordered_args?
|
18
23
|
builder.write ' '
|
19
|
-
builder.write task.args.
|
24
|
+
builder.write task.args.ordered.join(' ').ljust(max_ordered_string_length)
|
20
25
|
end
|
21
26
|
|
22
27
|
if show_named_args?
|
@@ -35,32 +40,37 @@ module Spud
|
|
35
40
|
puts builder.string
|
36
41
|
end
|
37
42
|
|
38
|
-
|
43
|
+
sig {void}
|
39
44
|
def list_filenames!
|
40
45
|
puts filenames.join("\n")
|
41
46
|
end
|
42
47
|
|
48
|
+
sig {returns(T::Array[String])}
|
49
|
+
def filenames
|
50
|
+
@filenames ||= @tasks.map(&:filename).uniq
|
51
|
+
end
|
52
|
+
|
43
53
|
private
|
44
54
|
|
45
|
-
|
55
|
+
sig {returns(Integer)}
|
46
56
|
def max_task_length
|
47
57
|
@max_task_length ||= @tasks.map { |task| task.name.length }.max
|
48
58
|
end
|
49
59
|
|
50
|
-
|
51
|
-
def
|
52
|
-
@
|
53
|
-
.map { |task| task.args.
|
60
|
+
sig {returns(Integer)}
|
61
|
+
def max_ordered_string_length
|
62
|
+
@max_ordered_string_length ||= @tasks
|
63
|
+
.map { |task| task.args.ordered.join(' ') }
|
54
64
|
.map(&:length)
|
55
65
|
.max
|
56
66
|
end
|
57
67
|
|
58
|
-
|
59
|
-
def
|
60
|
-
@
|
68
|
+
sig {returns(T::Boolean)}
|
69
|
+
def show_ordered_args?
|
70
|
+
@show_ordered_args ||= @tasks.any? { |task| task.args.any_ordered? }
|
61
71
|
end
|
62
72
|
|
63
|
-
|
73
|
+
sig {returns(Integer)}
|
64
74
|
def max_named_string_length
|
65
75
|
@max_named_string_length ||= @tasks
|
66
76
|
.map { |task| task.args.named.join(' ') }
|
@@ -68,17 +78,12 @@ module Spud
|
|
68
78
|
.max
|
69
79
|
end
|
70
80
|
|
71
|
-
|
81
|
+
sig {returns(T::Boolean)}
|
72
82
|
def show_named_args?
|
73
83
|
@show_named_args ||= @tasks.any? { |task| task.args.any_named? }
|
74
84
|
end
|
75
85
|
|
76
|
-
|
77
|
-
def filenames
|
78
|
-
@filenames ||= @tasks.map(&:filename).uniq
|
79
|
-
end
|
80
|
-
|
81
|
-
# @return [Boolean]
|
86
|
+
sig {returns(T::Boolean)}
|
82
87
|
def show_filenames?
|
83
88
|
filenames.length > 1
|
84
89
|
end
|
data/lib/spud/task_arg.rb
CHANGED
@@ -1,39 +1,42 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require 'sorbet-runtime'
|
3
|
+
|
1
4
|
module Spud
|
2
5
|
class TaskArg
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
sig {params(name: String, type: String, default: T.nilable(String)).void}
|
6
9
|
def initialize(name, type, default: nil)
|
7
|
-
raise 'must be of type "
|
10
|
+
raise 'must be of type "ordered" or "named"' unless %w[ordered named].include?(type)
|
8
11
|
|
9
12
|
@name = name
|
10
13
|
@type = type
|
11
14
|
@default = default
|
12
15
|
end
|
13
16
|
|
14
|
-
|
17
|
+
sig {returns(T::Boolean)}
|
15
18
|
def required?
|
16
19
|
!has_default?
|
17
20
|
end
|
18
21
|
|
19
|
-
|
22
|
+
sig {returns(T::Boolean)}
|
20
23
|
def has_default?
|
21
24
|
!!@default
|
22
25
|
end
|
23
26
|
|
24
|
-
|
25
|
-
def
|
26
|
-
@type == '
|
27
|
+
sig {returns(T::Boolean)}
|
28
|
+
def ordered?
|
29
|
+
@type == 'ordered'
|
27
30
|
end
|
28
31
|
|
29
|
-
|
32
|
+
sig {returns(T::Boolean)}
|
30
33
|
def named?
|
31
34
|
@type == 'named'
|
32
35
|
end
|
33
36
|
|
34
|
-
|
37
|
+
sig {returns(String)}
|
35
38
|
def to_s
|
36
|
-
if
|
39
|
+
if ordered?
|
37
40
|
if has_default?
|
38
41
|
"<#{@name}=#{@default}>"
|
39
42
|
else
|
data/lib/spud/task_args.rb
CHANGED
@@ -1,47 +1,49 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'sorbet-runtime'
|
1
3
|
require 'spud/task_arg'
|
2
|
-
require 'spud/
|
4
|
+
require 'spud/block_param_info'
|
3
5
|
|
4
6
|
module Spud
|
5
7
|
class TaskArgs < Array
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig {params(filename: String, block: Proc).returns(T.attached_class)}
|
9
11
|
def self.from_block(filename, &block)
|
10
|
-
info =
|
12
|
+
info = BlockParamInfo.new(filename, &block)
|
11
13
|
new(info.task_args)
|
12
14
|
end
|
13
15
|
|
14
|
-
|
16
|
+
sig {params(task_args: T::Array[TaskArg]).void}
|
15
17
|
def initialize(task_args)
|
16
18
|
super(task_args)
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
def
|
21
|
-
@
|
21
|
+
sig {returns(T::Array[TaskArg])}
|
22
|
+
def ordered
|
23
|
+
@ordered ||= select(&:ordered?)
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
|
-
def
|
26
|
-
@
|
26
|
+
sig {returns(T::Array[TaskArg])}
|
27
|
+
def required_ordered
|
28
|
+
@required_ordered ||= ordered.select(&:required?)
|
27
29
|
end
|
28
30
|
|
29
|
-
|
30
|
-
def
|
31
|
-
!
|
31
|
+
sig {returns(T::Boolean)}
|
32
|
+
def any_ordered?
|
33
|
+
!ordered.empty?
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
sig {returns(T::Array[TaskArg])}
|
35
37
|
def named
|
36
38
|
@named ||= select(&:named?)
|
37
39
|
end
|
38
40
|
|
39
|
-
|
41
|
+
sig {returns(T::Array[TaskArg])}
|
40
42
|
def required_named
|
41
43
|
@required_named ||= named.select(&:required?)
|
42
44
|
end
|
43
45
|
|
44
|
-
|
46
|
+
sig {returns(T::Boolean)}
|
45
47
|
def any_named?
|
46
48
|
!named.empty?
|
47
49
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require 'sorbet-runtime'
|
3
|
+
require 'stringio'
|
4
|
+
require 'spud/driver'
|
5
|
+
require 'spud/task_runners/task'
|
6
|
+
|
7
|
+
module Spud
|
8
|
+
module TaskRunners
|
9
|
+
module Make
|
10
|
+
class Task < TaskRunners::Task
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
sig {override.returns(String)}
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
sig {override.params(driver: Driver).returns(T::Array[TaskRunners::Task])}
|
17
|
+
def self.tasks(driver)
|
18
|
+
return [] unless File.exist?('Makefile')
|
19
|
+
|
20
|
+
if `command -v make`.empty?
|
21
|
+
puts 'Makefile detected, but no installation of `make` exists. Skipping make...'
|
22
|
+
return []
|
23
|
+
end
|
24
|
+
|
25
|
+
source = File.read('Makefile')
|
26
|
+
T.unsafe(source.scan(/^(\S+):.*/)).map(&:first).map do |name|
|
27
|
+
new(driver, name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
sig {params(driver: Driver, name: String).void}
|
32
|
+
def initialize(driver, name)
|
33
|
+
@driver = driver
|
34
|
+
@name = name
|
35
|
+
end
|
36
|
+
|
37
|
+
sig {override.params(ordered: T::Array[String], named: T::Hash[String, String]).returns(T.untyped)}
|
38
|
+
def invoke(ordered, named)
|
39
|
+
system('make', name)
|
40
|
+
end
|
41
|
+
|
42
|
+
sig {override.returns(String)}
|
43
|
+
def filename
|
44
|
+
'Makefile'
|
45
|
+
end
|
46
|
+
|
47
|
+
sig {override.returns(String)}
|
48
|
+
def details
|
49
|
+
source = File.read('Makefile')
|
50
|
+
lines = source.split("\n")
|
51
|
+
cursor = 0
|
52
|
+
|
53
|
+
cursor += 1 until lines[cursor]&.start_with?(name)
|
54
|
+
|
55
|
+
builder = StringIO.new
|
56
|
+
until lines[cursor]&.empty?
|
57
|
+
builder.puts lines[cursor]
|
58
|
+
cursor += 1
|
59
|
+
end
|
60
|
+
|
61
|
+
builder.string
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require 'sorbet-runtime'
|
3
|
+
require 'json'
|
4
|
+
require 'spud/driver'
|
5
|
+
require 'spud/task_args'
|
6
|
+
require 'spud/task_runners/task'
|
7
|
+
|
8
|
+
module Spud
|
9
|
+
module TaskRunners
|
10
|
+
module PackageJSON
|
11
|
+
class Task < TaskRunners::Task
|
12
|
+
extend T::Sig
|
13
|
+
|
14
|
+
sig {override.returns(String)}
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
sig {override.params(driver: Driver).returns(T::Array[TaskRunners::Task])}
|
18
|
+
def self.tasks(driver)
|
19
|
+
if File.exist?('package.lock')
|
20
|
+
if `command -v npm`.empty?
|
21
|
+
puts 'package.json detected, but no installation of `npm` exists. Skipping npm...'
|
22
|
+
return []
|
23
|
+
else
|
24
|
+
command = 'npm'
|
25
|
+
end
|
26
|
+
elsif File.exist?('yarn.lock')
|
27
|
+
if `command -v yarn`.empty?
|
28
|
+
puts 'package.json detected, but no installation of `yarn` exists. Skipping yarn...'
|
29
|
+
return []
|
30
|
+
else
|
31
|
+
command = 'yarn'
|
32
|
+
end
|
33
|
+
else
|
34
|
+
return []
|
35
|
+
end
|
36
|
+
|
37
|
+
source = File.read('package.json')
|
38
|
+
json = JSON.parse(source)
|
39
|
+
scripts = json['scripts']
|
40
|
+
return [] unless scripts
|
41
|
+
|
42
|
+
scripts.keys.map { |name| new(driver, name, command, scripts) }
|
43
|
+
end
|
44
|
+
|
45
|
+
sig {params(driver: Driver, name: String, command: String, scripts: T::Hash[String, String]).void}
|
46
|
+
def initialize(driver, name, command, scripts)
|
47
|
+
@driver = driver
|
48
|
+
@name = name
|
49
|
+
@command = command
|
50
|
+
@scripts = scripts
|
51
|
+
end
|
52
|
+
|
53
|
+
sig {override.params(ordered: T::Array[String], named: T::Hash[String, String]).returns(T.untyped)}
|
54
|
+
def invoke(ordered, named)
|
55
|
+
system("#{@command} run #{name}")
|
56
|
+
end
|
57
|
+
|
58
|
+
sig {override.returns(String)}
|
59
|
+
def filename
|
60
|
+
'package.json'
|
61
|
+
end
|
62
|
+
|
63
|
+
sig {override.returns(String)}
|
64
|
+
def details
|
65
|
+
%({ "#{name}": "#{@scripts[name]}" })
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'sorbet-runtime'
|
3
|
+
require 'spud/driver'
|
4
|
+
require 'spud/task_runners/spud_task_runner/task'
|
5
|
+
|
6
|
+
module Spud
|
7
|
+
module TaskRunners
|
8
|
+
module SpudTaskRunner
|
9
|
+
class FileDSL
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
sig {params(driver: Driver, filename: String).returns(T::Array[SpudTaskRunner::Task])}
|
13
|
+
def self.run(driver, filename)
|
14
|
+
dsl = new(driver, filename)
|
15
|
+
dsl.instance_eval(::File.read(filename), filename)
|
16
|
+
|
17
|
+
dsl.instance_variable_get(:@__tasks)
|
18
|
+
end
|
19
|
+
|
20
|
+
sig {params(driver: Driver, filename: String).void}
|
21
|
+
def initialize(driver, filename)
|
22
|
+
@__driver = driver
|
23
|
+
@__filename = filename
|
24
|
+
|
25
|
+
@__tasks = T.let([], T::Array[Task])
|
26
|
+
end
|
27
|
+
|
28
|
+
sig {params(name: String).returns(T::Boolean)}
|
29
|
+
def require_relative(name)
|
30
|
+
require("./#{name}")
|
31
|
+
end
|
32
|
+
|
33
|
+
sig do
|
34
|
+
params(
|
35
|
+
name: T.any(String, Symbol),
|
36
|
+
dependencies: T::Hash[T.any(String, T::Array[String]), T.any(String, T::Array[String])],
|
37
|
+
block: Proc,
|
38
|
+
).void
|
39
|
+
end
|
40
|
+
def task(name, dependencies = {}, &block)
|
41
|
+
@__tasks << Task.new(
|
42
|
+
driver: @__driver,
|
43
|
+
name: Task.qualified_name(@__filename, name.to_s),
|
44
|
+
filename: @__filename,
|
45
|
+
dependencies: dependencies,
|
46
|
+
&block
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(name, *args, &block)
|
51
|
+
T.unsafe(self).task(name, *args, &block)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'sorbet-runtime'
|
3
|
+
require 'stringio'
|
4
|
+
require 'open3'
|
5
|
+
require 'spud/driver'
|
6
|
+
require 'spud/task_runners/spud_task_runner/shell/result'
|
7
|
+
|
8
|
+
module Spud
|
9
|
+
module TaskRunners
|
10
|
+
module SpudTaskRunner
|
11
|
+
module Shell
|
12
|
+
class Command
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
attr_reader :result
|
16
|
+
|
17
|
+
sig {params(driver: Driver, command: String, silent: T::Boolean, handle: T.any(IO, StringIO)).returns(Result)}
|
18
|
+
def self.call(driver, command, silent: false, handle: STDOUT)
|
19
|
+
cmd = new(driver, command, silent: silent, handle: handle)
|
20
|
+
cmd.issue!
|
21
|
+
cmd.result
|
22
|
+
end
|
23
|
+
|
24
|
+
sig {params(driver: Driver, command: String, silent: T::Boolean, handle: T.any(IO, StringIO)).void}
|
25
|
+
def initialize(driver, command, silent: false, handle: STDOUT)
|
26
|
+
@command = command
|
27
|
+
@driver = driver
|
28
|
+
@silent = silent
|
29
|
+
@handle = handle
|
30
|
+
|
31
|
+
@result = T.let(nil, T.nilable(Result))
|
32
|
+
end
|
33
|
+
|
34
|
+
sig {void}
|
35
|
+
def issue!
|
36
|
+
capturer = StringIO.new
|
37
|
+
|
38
|
+
Open3.popen2e(@command) do |_stdin, stdout, thread|
|
39
|
+
@driver.register_subprocess(thread.pid)
|
40
|
+
|
41
|
+
loop do
|
42
|
+
line = stdout.gets
|
43
|
+
break unless line
|
44
|
+
|
45
|
+
@handle.write line unless @silent
|
46
|
+
capturer.puts line
|
47
|
+
end
|
48
|
+
|
49
|
+
@result = Result.new(capturer.string, T.cast(thread.value, Process::Status))
|
50
|
+
end
|
51
|
+
|
52
|
+
@driver.register_subprocess(nil)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|