spud 0.2.3 → 0.2.4

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