spud 0.2.0 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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]