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 +4 -4
- data/lib/spud.rb +2 -187
- data/lib/spud/build_tools/build_tools.rb +13 -0
- data/lib/spud/build_tools/make/task.rb +27 -0
- data/lib/spud/build_tools/package.json/task.rb +47 -0
- data/lib/spud/build_tools/spud/block_param_info.rb +77 -0
- data/lib/spud/build_tools/spud/dsl/file.rb +23 -0
- data/lib/spud/build_tools/spud/dsl/task.rb +63 -0
- data/lib/spud/build_tools/spud/shell/command.rb +52 -0
- data/lib/spud/build_tools/spud/shell/result.rb +26 -0
- data/lib/spud/build_tools/spud/task.rb +125 -0
- data/lib/spud/build_tools/task.rb +33 -0
- data/lib/spud/cli/parser.rb +101 -0
- data/lib/spud/cli/results.rb +25 -0
- data/lib/{error.rb → spud/error.rb} +1 -0
- data/lib/spud/help.rb +23 -0
- data/lib/spud/lister.rb +86 -0
- data/lib/spud/options.rb +14 -0
- data/lib/spud/runtime.rb +104 -0
- data/lib/spud/task_arg.rb +51 -0
- data/lib/spud/task_args.rb +49 -0
- data/lib/spud/version.rb +3 -0
- metadata +48 -28
- data/lib/args.rb +0 -73
- data/lib/build_tools/build_rule.rb +0 -21
- data/lib/build_tools/build_tool.rb +0 -19
- data/lib/build_tools/build_tools.rb +0 -13
- data/lib/build_tools/make/make.rb +0 -33
- data/lib/build_tools/package.json/package.json.rb +0 -33
- data/lib/build_tools/spud/file_context.rb +0 -33
- data/lib/build_tools/spud/rule.rb +0 -121
- data/lib/build_tools/spud/rule_context.rb +0 -58
- data/lib/build_tools/spud/shell_error.rb +0 -7
- data/lib/build_tools/spud/spud.rb +0 -27
- data/lib/shell.rb +0 -34
- data/lib/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c55ea01a3c22d6170762c1097849e93cdd4d0444b4b1bd7bed95ecd73a642ded
|
4
|
+
data.tar.gz: a2744808ed721659bef1b3af24c87fee6913795dca9631ab86f7058b714e110c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09f1d72b9df4f1c0d6eda2815b1c508e2c06bb33d7d9f68829681b50ae3d04ac09b59afd47eaed0eb2952f25c29142fe9306791fd1e46aad3f25a5add8d8ff0e
|
7
|
+
data.tar.gz: d5379e5f5e250da3dec466f4cebe063e994a62c618cff987b202fd650be9a8e3a95fe61bce853b4d0ff8eaaa448883522306efc5c15d3da96d2672d27e1f743a
|
data/lib/spud.rb
CHANGED
@@ -1,192 +1,7 @@
|
|
1
|
-
|
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
|
-
|
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,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
|