spud 0.1.15 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff2253281ad17fa26000da387d071fca88fe39e6c01913573bf1aa78148c9302
4
- data.tar.gz: 449e2aead6ea9686659c8b928ca9f4fa07f582156d30e2ae24bbc5680382cd58
3
+ metadata.gz: c55ea01a3c22d6170762c1097849e93cdd4d0444b4b1bd7bed95ecd73a642ded
4
+ data.tar.gz: a2744808ed721659bef1b3af24c87fee6913795dca9631ab86f7058b714e110c
5
5
  SHA512:
6
- metadata.gz: 3f29e51971b0f78eb223e0561bc28a641fa167d72a5e10f996752fffefe8ead8c8fbb09707a24b2192c72b341dd039711808cfe2d6b7dbe78e5cb416c71075a8
7
- data.tar.gz: 244352f4d935f8f00bc307b88f810743358e1eed079c9f7ef8ffabaca55df1929e9eb7933c5ae76a29bdfa4f9037a519b1ee205e592e49ed3e49f1207a1d4f51
6
+ metadata.gz: 09f1d72b9df4f1c0d6eda2815b1c508e2c06bb33d7d9f68829681b50ae3d04ac09b59afd47eaed0eb2952f25c29142fe9306791fd1e46aad3f25a5add8d8ff0e
7
+ data.tar.gz: d5379e5f5e250da3dec466f4cebe063e994a62c618cff987b202fd650be9a8e3a95fe61bce853b4d0ff8eaaa448883522306efc5c15d3da96d2672d27e1f743a
@@ -1,192 +1,7 @@
1
- require 'stringio'
2
- require_relative 'args'
3
- require_relative 'version'
4
- require_relative 'build_tools/build_tools'
5
- require_relative 'build_tools/spud/shell_error'
1
+ require_relative 'spud/runtime'
6
2
 
7
3
  module Spud
8
4
  def self.run!
9
- Spud.new.run!
10
- end
11
-
12
- class Spud
13
- def run!
14
- if options[:help]
15
- print_help!
16
- return
17
- end
18
-
19
- if options[:version]
20
- puts VERSION
21
- return
22
- end
23
-
24
- unless rule_name
25
- print_rules!
26
- return
27
- end
28
-
29
- unless options[:watches].empty?
30
- watch(options[:watches], rule_name, *args[:positional], **args[:keyword])
31
- return
32
- end
33
-
34
- invoke(rule_name, *args[:positional], **args[:keyword])
35
- rescue BuildTools::SpudBuild::ShellError => e
36
- raise e if options[:debug]
37
-
38
- rescue => e
39
- raise e if options[:debug]
40
- puts e.message
41
- end
42
-
43
- def invoke(name, *args, **kwargs)
44
- rule = rules[name.to_s]
45
- raise Error, "no rule found for '#{name}'" unless rule
46
- rule.invoke(*args, **kwargs)
47
- end
48
-
49
- def watch(globs, name, *args, **kwargs)
50
- rule = rules[name.to_s]
51
- raise Error, "no rule found for '#{name}'" unless rule
52
-
53
- thread = nil
54
- timestamps = {}
55
- loop do
56
- begin
57
- filenames = Dir.glob(*globs)
58
- filenames.each do |filename|
59
- new_timestamp = File.mtime(filename)
60
- old_timestamp = timestamps[filename]
61
-
62
- if !old_timestamp || new_timestamp > old_timestamp
63
- timestamps[filename] = new_timestamp
64
-
65
- thread.kill if thread
66
- thread = Thread.new { invoke(name, *args, **kwargs) }
67
- break
68
- end
69
- end
70
-
71
- sleep 0.1
72
- rescue Interrupt
73
- thread.kill if thread
74
- break
75
- end
76
- end
77
- end
78
-
79
- private
80
-
81
- # Rules
82
- def rules
83
- @rules ||= build_tools.reduce({}) { |rules, tool| rules.merge(tool.rules) }
84
- end
85
-
86
- def build_tools
87
- @build_tools ||= BuildTools::BUILD_TOOLS
88
- .reverse
89
- .map { |tool| tool.new(self) }
90
- .each(&:mount!)
91
- end
92
-
93
- def print_rules!
94
- #table = rules.map { |name, rule| { name: name, filename: rule.filename } }
95
-
96
- longest_name = 0
97
- longest_filename = 0
98
- longest_positional = 0
99
- longest_keyword = 0
100
- table = []
101
- rules.each do |name, rule|
102
- longest_name = name.length if name.length > longest_name
103
-
104
- positional = rule.positional_params.map(&method(:wrap_param)).join(' ')
105
- longest_positional = positional.length if positional.length > longest_positional
106
-
107
- keyword = rule.keyword_params.map(&method(:prefix_param)).join(' ')
108
- longest_keyword = keyword.length if keyword.length > longest_keyword
109
-
110
- longest_filename = rule.filename.length if rule.filename.length > longest_filename
111
-
112
- table << [name, positional, keyword, rule.filename]
113
- end
114
-
115
- table.each do |(name, positional, keyword, filename)|
116
- fields = [name.ljust(longest_name)]
117
- fields << positional.ljust(longest_positional) unless longest_positional == 0
118
- fields << keyword.ljust(longest_keyword) unless longest_keyword == 0
119
- fields << filename.ljust(longest_filename)
120
-
121
- puts fields.join(' ')
122
- end
123
-
124
- return
125
-
126
- longest_rule = 0
127
- longest_filename = 0
128
- longest_positional = 0
129
- longest_keyword = 0
130
- table.each do |(rule, filename)|
131
- longest_rule = rule.length if rule.length > longest_rule
132
- longest_filename = filename.length if filename.length > longest_filename
133
-
134
- positional = rule.positional_params.map(&method(:wrap_param)).join(' ')
135
- longest_positional = positional.length if positional.length > longest_positional
136
-
137
- keyword = rule.keyword_params.map(&method(:prefix_param)).join(' ')
138
- longest_keyword = keyword.length if keyword.length > longest_keyword
139
- end
140
-
141
- table.each do |(rule, filename)|
142
- [
143
- [rule, longest_rule],
144
- [positional, longest_positional],
145
- [filename, longest_filename],
146
- [filename, longest_filename],
147
- ]
148
-
149
- puts "#{rule.ljust(longest_rule)} #{filename.ljust(longest_filename)}"
150
- end
151
- end
152
-
153
- def wrap_param(name)
154
- "<#{name}>"
155
- end
156
-
157
- def prefix_param(name)
158
- name.length == 1 ? "-#{name}" : "--#{name}"
159
- end
160
-
161
- # Help
162
- def print_help!
163
- help = StringIO.new
164
-
165
- help.puts "spud #{VERSION}"
166
- help.puts
167
- help.puts 'usage:'
168
- help.puts ' spud [options] <rule> [args]'
169
- help.puts
170
- help.puts 'options:'
171
- help.puts ' -h, --help show this help dialog dialog'
172
- help.puts ' -v, --version show spud version'
173
- help.puts ' -w, --watch <files> watch files for changes'
174
- help.puts ' --debug run in debug mode'
175
-
176
- puts help.string
177
- end
178
-
179
- # Args
180
- def options
181
- @options ||= args[:options]
182
- end
183
-
184
- def rule_name
185
- @rule_name ||= args[:rule]
186
- end
187
-
188
- def args
189
- @args ||= Args.parse_args!
190
- end
5
+ Runtime.run!
191
6
  end
192
7
  end
@@ -0,0 +1,13 @@
1
+ require 'spud/build_tools/spud/task'
2
+ require 'spud/build_tools/make/task'
3
+ require 'spud/build_tools/package.json/task'
4
+
5
+ module Spud
6
+ module BuildTools
7
+ BUILD_TOOLS = [
8
+ Spud::Task,
9
+ Make::Task,
10
+ PackageJSON::Task,
11
+ ]
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ require 'spud/build_tools/task'
2
+
3
+ module Spud
4
+ module BuildTools
5
+ module Make
6
+ class Task < BuildTools::Task
7
+ def self.mount!
8
+ return unless File.exist?('Makefile')
9
+
10
+ if `command -v make`.empty?
11
+ puts 'Makefile detected, but no installation of `make` exists. Skipping make...'
12
+ return
13
+ end
14
+
15
+ source = File.read('Makefile')
16
+ source.scan(/^(\S+):.*/).map(&:first).each do |name|
17
+ new(name: name, filename: 'Makefile')
18
+ end
19
+ end
20
+
21
+ def invoke(*)
22
+ system('make', name)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ require 'json'
2
+ require 'spud/build_tools/task'
3
+
4
+ module Spud
5
+ module BuildTools
6
+ module PackageJSON
7
+ class Task < BuildTools::Task
8
+ def self.mount!
9
+ return unless File.exist?('package.json')
10
+
11
+ opening_commands = %w[npm run]
12
+ if File.exist?('package.lock')
13
+ if `command -v npm`.empty?
14
+ puts 'package.json detected, but no installation of `npm` exists. Skipping npm...'
15
+ return
16
+ end
17
+ elsif File.exist?('yarn.lock')
18
+ if `command -v yarn`.empty?
19
+ puts 'package.json detected, but no installation of `yarn` exists. Skipping yarn...'
20
+ return
21
+ else
22
+ opening_commands = %w[yarn run]
23
+ end
24
+ end
25
+
26
+ source = File.read('package.json')
27
+ json = JSON.parse(source)
28
+ scripts = json['scripts']
29
+ return unless scripts
30
+
31
+ scripts.keys.each do |name|
32
+ new(name: name, filename: 'package.json', opening_commands: opening_commands)
33
+ end
34
+ end
35
+
36
+ def initialize(name:, filename:, opening_commands:)
37
+ super(name: name, filename: filename)
38
+ @opening_commands = opening_commands
39
+ end
40
+
41
+ def invoke(*)
42
+ system(*(@opening_commands + [name]))
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,77 @@
1
+ require 'spud/task_arg'
2
+
3
+ module Spud
4
+ module BuildTools
5
+ module Spud
6
+ class BlockParamInfo
7
+ # @param filename [String]
8
+ # @param block [Proc]
9
+ def initialize(filename, &block)
10
+ @filename = filename
11
+ @block = block
12
+ end
13
+
14
+ # @return [Array<Spud::TaskArg>]
15
+ def task_args
16
+ parameters.map do |type, name|
17
+ case type
18
+ when :req
19
+ TaskArg.new(name, 'positional')
20
+ when :opt
21
+ TaskArg.new(name, 'positional', default: arg_values[name])
22
+ when :keyreq
23
+ TaskArg.new(name, 'named')
24
+ when :key
25
+ TaskArg.new(name, 'named', default: arg_values[name])
26
+ end
27
+ end
28
+ end
29
+
30
+ # @return [Array]
31
+ def dummy_args
32
+ [dummy_positional_args, dummy_named_args]
33
+ end
34
+
35
+ # @return [Array<NilClass>]
36
+ def dummy_positional_args
37
+ Array.new(parameters.count { |p| p.first == :req })
38
+ end
39
+
40
+ # @return [Hash{Symbol->NilClass}]
41
+ def dummy_named_args
42
+ parameters.select { |p| p.first == :keyreq }.map(&:last).each_with_object({}) { |n, h| h[n] = nil }
43
+ end
44
+
45
+ # @return [String]
46
+ def arg_hash_string
47
+ "{ #{parameters.map(&:last).map { |n| "#{n}: #{n}" }.join(', ')} }"
48
+ end
49
+
50
+ # @return [Hash]
51
+ def arg_values
52
+ @arg_values ||= begin
53
+ positional, named = dummy_args
54
+ lambda(arg_hash_string).call(*positional, **named)
55
+ end
56
+ end
57
+
58
+ # @return [Array<Array<Symbol>>]
59
+ def parameters
60
+ @parameters ||= lambda.parameters
61
+ end
62
+
63
+ # @return [Proc]
64
+ def lambda(body = nil)
65
+ line = File.read(@filename).split("\n")[@block.source_location.last - 1]
66
+
67
+ match = /(do|{)\s*\|(?<params>[^|]+)\|/.match(line)
68
+ return -> {} unless match
69
+
70
+ param_source = match[:params]
71
+ param_source += ', _: nil, __: nil, ___: nil' if body
72
+ eval "-> (#{param_source}) { #{body} }"
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,23 @@
1
+ require 'spud/build_tools/spud/task'
2
+
3
+ module Spud
4
+ module BuildTools
5
+ module Spud
6
+ module DSL
7
+ class File
8
+ def require_relative(name)
9
+ require("./#{name}")
10
+ end
11
+
12
+ def task(name, *, &block)
13
+ BuildTools::Spud::Task.add_task(name, &block)
14
+ end
15
+
16
+ def method_missing(name, *args, &block)
17
+ task(name, *args, &block)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,63 @@
1
+ require 'spud/error'
2
+ require 'spud/build_tools/spud/task'
3
+ require 'spud/build_tools/spud/shell/command'
4
+
5
+ module Spud
6
+ module BuildTools
7
+ module Spud
8
+ module DSL
9
+ class Task
10
+ def initialize(filename)
11
+ @filename = filename
12
+ end
13
+
14
+ def sh(command)
15
+ puts command
16
+ Shell::Command.(command)
17
+ end
18
+
19
+ def shh(command)
20
+ Shell::Command.(command)
21
+ end
22
+
23
+ def shhh(command)
24
+ Shell::Command.(command, silent: true)
25
+ end
26
+
27
+ def sh!(command)
28
+ puts command
29
+ result = Shell::Command.(command)
30
+ raise Error, "sh failed for '#{command}'" unless result.success?
31
+ result
32
+ end
33
+
34
+ def shh!(command)
35
+ result = Shell::Command.(command)
36
+ raise Error, "sh failed for '#{command}'" unless result.success?
37
+ result
38
+ end
39
+
40
+ def shhh!(command)
41
+ result = Shell::Command.(command, silent: true)
42
+ raise Error, "sh failed for '#{command}'" unless result.success?
43
+ result
44
+ end
45
+
46
+ def invoke(task, *positional, **named)
47
+ Spud::Task.invoke(@filename, task, positional, named)
48
+ rescue Error => error
49
+ puts "invoke failed for #{task}: #{error}"
50
+ end
51
+
52
+ def invoke!(task, *positional, **named)
53
+ Spud::Task.invoke(@filename, task, positional, named)
54
+ end
55
+
56
+ def method_missing(symbol, *positional, **named)
57
+ Spud::Task.task_for(@filename, symbol) ? Spud::Task.invoke(@filename, symbol, positional, named) : super
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end