spud 0.2.3 → 0.2.10

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