spud 0.2.1 → 0.2.6

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 +5 -5
  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 +136 -0
  8. data/lib/spud/error.rb +6 -1
  9. data/lib/spud/help.rb +17 -14
  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 +50 -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 +149 -0
  20. data/lib/spud/task_runners/spud_task_runner/task_dsl.rb +95 -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 +51 -20
  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
- SHA256:
3
- metadata.gz: 12c0947e9a6ed28a7e5be6d84476232612e567b239beff99648ada975921dc51
4
- data.tar.gz: 12dc859d0cfd9307bc4fcd6ed5858e75af83179ad59c1a17ac21d83955e04ba5
2
+ SHA1:
3
+ metadata.gz: ea40b0df03085beb5350590ed0336f4bbac760ff
4
+ data.tar.gz: 93427f8d7a3d1906d8f5ac082b54ee7a343afbec
5
5
  SHA512:
6
- metadata.gz: 06f7ddbab9f8369e52fd3ecf467a2afcb12536b59ab50c97f2aa731ebac12af6f0b4bac9c0034309451073331472fa04aeeb6d11e8541e27fd5387f7028ee453
7
- data.tar.gz: 227eeefc6c59f2bd6a9f02470070c5424fa3b53e4f872613da31026bf342909d432b8d5e2a49ded2b28372b435ab96d92c616a810dc2d9dd4fb5484702670d5f
6
+ metadata.gz: 9e5125c223b8e4733a018cbfc31239f6f9dc9a7b6912785f3167cebf67f07886f64106f64940e1f5fe50e7516d76b5c0dddbbfe4ed53d7b2edc837a08b193068
7
+ data.tar.gz: 052fb31ba933ffaf3520669830d37bf292f325c1d54072ce29642b20d3dac53d71f76ef9afb7eb5e6eb1ecd8d76da0a3dc7368c66b17b65cceaec387c1296a05
@@ -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,136 @@
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 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 do
70
+ params(name: String, ordered: T::Array[String], named: T::Hash[T.any(String, Symbol), String]).returns(T.untyped)
71
+ end
72
+ def invoke(name, ordered, named)
73
+ get_task(name).invoke(ordered, stringify_keys(named))
74
+ end
75
+
76
+ sig {params(pid: T.nilable(Integer)).void}
77
+ def register_subprocess(pid)
78
+ @subprocess_pid = pid
79
+ end
80
+
81
+ sig {returns(T::Boolean)}
82
+ def debug?
83
+ @debug ||= ENV.key?('SPUD_DEBUG') && ENV['SPUD_DEBUG'] != 'false'
84
+ end
85
+
86
+ private
87
+
88
+ sig {void}
89
+ def watch!
90
+ Watch.run!(
91
+ driver: self,
92
+ task: T.must(args.task),
93
+ ordered: args.ordered,
94
+ named: args.named,
95
+ watches: options.watches,
96
+ )
97
+ end
98
+
99
+ sig {params(task_name: String).returns(TaskRunners::Task)}
100
+ def get_task(task_name)
101
+ task = tasks[task_name]
102
+ raise Error, "no task found for '#{task_name}'" unless task
103
+
104
+ task
105
+ end
106
+
107
+ sig {returns(T::Hash[String, TaskRunners::Task])}
108
+ def tasks
109
+ @tasks ||= TaskRunners.get.each_with_object({}) do |task_runner, tasks|
110
+ task_runner.tasks(self).each do |task|
111
+ tasks[task.name] = task
112
+ end
113
+ end
114
+ end
115
+
116
+ sig {returns(CLI::Results)}
117
+ def args
118
+ @args ||= CLI::Parser.parse!
119
+ end
120
+
121
+ sig {returns(Lister)}
122
+ def lister
123
+ @lister ||= Lister.new(tasks.values)
124
+ end
125
+
126
+ sig {returns(CLI::Options)}
127
+ def options
128
+ args.options
129
+ end
130
+
131
+ sig {params(hash: T::Hash[T.any(String, Symbol), T.untyped]).returns(T::Hash[String, T.untyped])}
132
+ def stringify_keys(hash)
133
+ hash.each_with_object({}) { |(key, value), new_hash| new_hash[key.to_s] = value }
134
+ end
135
+ end
136
+ end
@@ -1,6 +1,11 @@
1
+ # typed: true
2
+ require 'sorbet-runtime'
3
+
1
4
  module Spud
2
5
  class Error < StandardError
3
- # @return [String]
6
+ extend T::Sig
7
+
8
+ sig {override.returns(String)}
4
9
  def message
5
10
  "spud: #{super}"
6
11
  end