spud 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/spud.rb +2 -182
- 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 -124
- data/lib/build_tools/spud/rule_context.rb +0 -62
- data/lib/build_tools/spud/shell_error.rb +0 -7
- data/lib/build_tools/spud/spud.rb +0 -27
- data/lib/shell.rb +0 -38
- 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: c320efae9cee00187448b9d22ea6cb967b8a148f2f2cadc44ef417e63e36ab2c
|
4
|
+
data.tar.gz: e41403612c56fa90768a8c133d2f8d35aa1e3bf6ac123b3980e3abda7bd57362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0409df20a76ab9ff43141b509d166ebf4ae1f6f0e2782fe31217f5b0fc4d0bd468086032c4f28ce4ef9c4d8b2e274140044975d356ba7e7bcb9e5057fb23e1c
|
7
|
+
data.tar.gz: 8696e8d13cf3266f88a1fb6cb53d3382a5fb1cb020de418fe9bd82ab43f3c3944428254c27747d8198c964977004e05f7aef9666cad80535f92041bc55775aab
|
data/lib/spud.rb
CHANGED
@@ -1,187 +1,7 @@
|
|
1
|
-
|
2
|
-
require_relative 'args'
|
3
|
-
require_relative 'version'
|
4
|
-
require_relative 'shell'
|
5
|
-
require_relative 'build_tools/build_tools'
|
6
|
-
require_relative 'build_tools/spud/shell_error'
|
1
|
+
require_relative 'spud/runtime'
|
7
2
|
|
8
3
|
module Spud
|
9
4
|
def self.run!
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
class Spud
|
14
|
-
attr_accessor :watch_process
|
15
|
-
|
16
|
-
def run!
|
17
|
-
puts options if debug?
|
18
|
-
puts watches_present: watches_present? if debug?
|
19
|
-
puts wait: wait? if debug?
|
20
|
-
|
21
|
-
if help?
|
22
|
-
print_help!
|
23
|
-
return
|
24
|
-
end
|
25
|
-
|
26
|
-
if version?
|
27
|
-
puts VERSION
|
28
|
-
return
|
29
|
-
end
|
30
|
-
|
31
|
-
unless rule_present?
|
32
|
-
print_rules!
|
33
|
-
return
|
34
|
-
end
|
35
|
-
|
36
|
-
if watches_present?
|
37
|
-
watch(options[:watches], rule_name, *args[:positional], **args[:keyword])
|
38
|
-
return
|
39
|
-
end
|
40
|
-
|
41
|
-
invoke(rule_name, *args[:positional], **args[:keyword])
|
42
|
-
rescue BuildTools::SpudBuild::ShellError => e
|
43
|
-
raise e if debug?
|
44
|
-
|
45
|
-
rescue => e
|
46
|
-
raise e if debug?
|
47
|
-
puts e.message
|
48
|
-
end
|
49
|
-
|
50
|
-
def invoke(name, *args, **kwargs)
|
51
|
-
rule = rules[name.to_s]
|
52
|
-
raise Error, "no rule found for '#{name}'" unless rule
|
53
|
-
rule.invoke(*args, **kwargs)
|
54
|
-
end
|
55
|
-
|
56
|
-
def watch(globs, name, *args, **kwargs)
|
57
|
-
rule = rules[name.to_s]
|
58
|
-
raise Error, "no rule found for '#{name}'" unless rule
|
59
|
-
|
60
|
-
thread = nil
|
61
|
-
timestamps = {}
|
62
|
-
loop do
|
63
|
-
begin
|
64
|
-
filenames = Dir.glob(*globs)
|
65
|
-
filenames.each do |filename|
|
66
|
-
new_timestamp = File.mtime(filename)
|
67
|
-
old_timestamp = timestamps[filename]
|
68
|
-
|
69
|
-
if !old_timestamp || new_timestamp > old_timestamp
|
70
|
-
timestamps[filename] = new_timestamp
|
71
|
-
|
72
|
-
watch_process.kill! if watch_process
|
73
|
-
thread.kill if thread
|
74
|
-
|
75
|
-
thread = Thread.new { invoke(name, *args, **kwargs) }
|
76
|
-
break
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
sleep 0.1
|
81
|
-
rescue Interrupt
|
82
|
-
thread.kill if thread
|
83
|
-
watch_process.kill! if watch_process
|
84
|
-
break
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def wait?
|
90
|
-
@wait ||= !watches_present?
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
# Rules
|
96
|
-
def rules
|
97
|
-
@rules ||= build_tools.reduce({}) { |rules, tool| rules.merge(tool.rules) }
|
98
|
-
end
|
99
|
-
|
100
|
-
def build_tools
|
101
|
-
@build_tools ||= BuildTools::BUILD_TOOLS
|
102
|
-
.reverse
|
103
|
-
.map { |tool| tool.new(self) }
|
104
|
-
.each(&:mount!)
|
105
|
-
end
|
106
|
-
|
107
|
-
def print_rules!
|
108
|
-
longest_name = 0
|
109
|
-
longest_filename = 0
|
110
|
-
longest_positional = 0
|
111
|
-
longest_keyword = 0
|
112
|
-
table = []
|
113
|
-
rules.each do |name, rule|
|
114
|
-
longest_name = name.length if name.length > longest_name
|
115
|
-
|
116
|
-
positional = rule.positional_params.map(&method(:wrap_param)).join(' ')
|
117
|
-
longest_positional = positional.length if positional.length > longest_positional
|
118
|
-
|
119
|
-
keyword = rule.keyword_params.map(&method(:prefix_param)).join(' ')
|
120
|
-
longest_keyword = keyword.length if keyword.length > longest_keyword
|
121
|
-
|
122
|
-
longest_filename = rule.filename.length if rule.filename.length > longest_filename
|
123
|
-
|
124
|
-
table << [name, positional, keyword, rule.filename]
|
125
|
-
end
|
126
|
-
|
127
|
-
table.each do |(name, positional, keyword, filename)|
|
128
|
-
fields = [name.ljust(longest_name)]
|
129
|
-
fields << positional.ljust(longest_positional) unless longest_positional == 0
|
130
|
-
fields << keyword.ljust(longest_keyword) unless longest_keyword == 0
|
131
|
-
fields << filename.ljust(longest_filename)
|
132
|
-
|
133
|
-
puts fields.join(' ')
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def wrap_param(name)
|
138
|
-
"<#{name}>"
|
139
|
-
end
|
140
|
-
|
141
|
-
def prefix_param(name)
|
142
|
-
name.length == 1 ? "-#{name}" : "--#{name}"
|
143
|
-
end
|
144
|
-
|
145
|
-
# Help
|
146
|
-
def print_help!
|
147
|
-
help = StringIO.new
|
148
|
-
|
149
|
-
help.puts "spud #{VERSION}"
|
150
|
-
help.puts
|
151
|
-
help.puts 'usage:'
|
152
|
-
help.puts ' spud [options] <rule> [args]'
|
153
|
-
help.puts
|
154
|
-
help.puts 'options:'
|
155
|
-
help.puts ' -h, --help show this help dialog dialog'
|
156
|
-
help.puts ' -v, --version show spud version'
|
157
|
-
help.puts ' -w, --watch <files> watch files for changes'
|
158
|
-
help.puts ' --debug run in debug mode'
|
159
|
-
|
160
|
-
puts help.string
|
161
|
-
end
|
162
|
-
|
163
|
-
# Options
|
164
|
-
def watches_present?
|
165
|
-
@watches_present ||= !options[:watches].empty?
|
166
|
-
end
|
167
|
-
|
168
|
-
%i[help version debug].each { |option| define_method("#{option}?") { options[option] } }
|
169
|
-
|
170
|
-
# Args
|
171
|
-
def rule_present?
|
172
|
-
rule_name
|
173
|
-
end
|
174
|
-
|
175
|
-
def options
|
176
|
-
@options ||= args[:options]
|
177
|
-
end
|
178
|
-
|
179
|
-
def rule_name
|
180
|
-
@rule_name ||= args[:rule]
|
181
|
-
end
|
182
|
-
|
183
|
-
def args
|
184
|
-
@args ||= Args.parse_args!
|
185
|
-
end
|
5
|
+
Runtime.run!
|
186
6
|
end
|
187
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
|