spud 0.2.3 → 0.2.10

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