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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/spud.rb +3 -2
  3. data/lib/spud/block_param_info.rb +80 -0
  4. data/lib/spud/cli/options.rb +35 -0
  5. data/lib/spud/cli/parser.rb +23 -19
  6. data/lib/spud/cli/results.rb +18 -11
  7. data/lib/spud/driver.rb +135 -0
  8. data/lib/spud/error.rb +1 -0
  9. data/lib/spud/help.rb +13 -13
  10. data/lib/spud/lister.rb +27 -22
  11. data/lib/spud/shell/command.rb +75 -0
  12. data/lib/spud/shell/result.rb +33 -0
  13. data/lib/spud/task_arg.rb +24 -12
  14. data/lib/spud/task_args.rb +20 -18
  15. data/lib/spud/task_runners/make/task.rb +67 -0
  16. data/lib/spud/task_runners/package.json/task.rb +71 -0
  17. data/lib/spud/task_runners/spud_task_runner/dependency.rb +49 -0
  18. data/lib/spud/task_runners/spud_task_runner/file_dsl.rb +57 -0
  19. data/lib/spud/task_runners/spud_task_runner/task.rb +148 -0
  20. data/lib/spud/task_runners/spud_task_runner/task_dsl.rb +90 -0
  21. data/lib/spud/task_runners/task.rb +40 -0
  22. data/lib/spud/task_runners/task_runners.rb +25 -0
  23. data/lib/spud/version.rb +2 -1
  24. data/lib/spud/watch.rb +73 -0
  25. metadata +46 -16
  26. data/lib/spud/build_tools/build_tools.rb +0 -13
  27. data/lib/spud/build_tools/make/task.rb +0 -27
  28. data/lib/spud/build_tools/package.json/task.rb +0 -47
  29. data/lib/spud/build_tools/spud/block_param_info.rb +0 -77
  30. data/lib/spud/build_tools/spud/dsl/file.rb +0 -23
  31. data/lib/spud/build_tools/spud/dsl/task.rb +0 -63
  32. data/lib/spud/build_tools/spud/shell/command.rb +0 -52
  33. data/lib/spud/build_tools/spud/shell/result.rb +0 -26
  34. data/lib/spud/build_tools/spud/task.rb +0 -125
  35. data/lib/spud/build_tools/task.rb +0 -33
  36. data/lib/spud/options.rb +0 -14
  37. data/lib/spud/runtime.rb +0 -104
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c55ea01a3c22d6170762c1097849e93cdd4d0444b4b1bd7bed95ecd73a642ded
4
- data.tar.gz: a2744808ed721659bef1b3af24c87fee6913795dca9631ab86f7058b714e110c
3
+ metadata.gz: 28a274884358f6717d4e649d7ad01ea399317c89a02d2595576a15d35465b8de
4
+ data.tar.gz: 1866b4fc335245a0a86fb21ad60c875596af2cc545399aa22db440d34e51bbf3
5
5
  SHA512:
6
- metadata.gz: 09f1d72b9df4f1c0d6eda2815b1c508e2c06bb33d7d9f68829681b50ae3d04ac09b59afd47eaed0eb2952f25c29142fe9306791fd1e46aad3f25a5add8d8ff0e
7
- data.tar.gz: d5379e5f5e250da3dec466f4cebe063e994a62c618cff987b202fd650be9a8e3a95fe61bce853b4d0ff8eaaa448883522306efc5c15d3da96d2672d27e1f743a
6
+ metadata.gz: b44fd607406fe417224470905701c9f37fbb616ebc207df2ad041650f3368c5d6a15d5cf07778641d72d47f9c6af1b3fca7c774f09660bff679f44e50a946ea9
7
+ data.tar.gz: e4e08a44cce308f92d7ff769ddf4f2ad4f75dfe8f4ca54643b4d84e9266cce9fbed191fd6e85710839440b8d85126b57dfaeadc881e17f412850f77432b46b51
@@ -1,7 +1,8 @@
1
- require_relative 'spud/runtime'
1
+ # typed: true
2
+ require_relative 'spud/driver'
2
3
 
3
4
  module Spud
4
5
  def self.run!
5
- Runtime.run!
6
+ Driver.new.run!
6
7
  end
7
8
  end
@@ -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
@@ -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
- # @return [Spud::CLI::Results]
9
+ extend T::Sig
10
+
11
+ sig {returns(Results)}
7
12
  attr_reader :results
8
13
 
9
- # @return [void]
14
+ sig {returns(Results)}
10
15
  def self.parse!
11
16
  parse(ARGV)
12
17
  end
13
18
 
14
- # @param args [Array<String>]
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
- # @param args [Array<String>]
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
- # @return [void]
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
- # @return [void]
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.positional << take!
46
+ results.ordered << take!
43
47
  end
44
48
  end
45
49
  end
46
50
 
47
- # @return [void]
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 '--debug' then options.debug = true
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
- # @return [Spud::Options]
63
+ sig {returns(Options)}
60
64
  def options
61
65
  results.options
62
66
  end
63
67
 
64
- # @param flag [String]
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
- # @return [Boolean]
73
+ sig {returns(T::Boolean)}
71
74
  def before_task_name?
72
75
  !results.task
73
76
  end
74
77
 
75
- # @return [void]
78
+ sig {void}
76
79
  def set_task_name!
77
80
  results.task = take!
78
81
  end
79
82
 
80
- # @return [String]
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
- # @return [Boolean]
94
+ sig {returns(T::Boolean)}
91
95
  def flag?
92
96
  arg.start_with?('-')
93
97
  end
94
98
 
95
- # @return [Boolean]
99
+ sig {returns(T::Boolean)}
96
100
  def done?
97
101
  @args.empty?
98
102
  end
@@ -1,25 +1,32 @@
1
- require 'spud/options'
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
- # @return [String]
7
- attr_accessor :task
8
+ extend T::Sig
8
9
 
9
- # @return [Spud::Options]
10
- def options
11
- @options ||= Options.new
12
- end
10
+ sig {returns(T.nilable(String))}
11
+ attr_accessor :task
13
12
 
14
- # @return [Array<String>]
15
- def positional
16
- @positional ||= []
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
- # @return [Hash{String->String}]
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
@@ -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
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Spud
2
3
  class Error < StandardError
3
4
  # @return [String]