spud 0.1.14 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e82f5c891574a3fc3f13aa2b46005c7deafbf6720d378b4432726b3358e65dda
4
- data.tar.gz: 9e46fcd73f03b45bc7bf8ff79a6f15aac02535ec02349112320fbf9003cae213
3
+ metadata.gz: c320efae9cee00187448b9d22ea6cb967b8a148f2f2cadc44ef417e63e36ab2c
4
+ data.tar.gz: e41403612c56fa90768a8c133d2f8d35aa1e3bf6ac123b3980e3abda7bd57362
5
5
  SHA512:
6
- metadata.gz: 0acce351760b00b50ca4ae4b0734143d1745aa5f2c81cc35c968b2e86186a5fa0a5f2138e6ca095ab7404220bd74b8abaa053a2985baa237e170164df71043f5
7
- data.tar.gz: 075957df7f73c4cf6022ffc0c8c7f28acd31e94f4963e25c875534b3e72c965cf505af6c1bc74a58d0b54896b4b0451c10c3452e2fad252b66b2eeb1404d3920
6
+ metadata.gz: a0409df20a76ab9ff43141b509d166ebf4ae1f6f0e2782fe31217f5b0fc4d0bd468086032c4f28ce4ef9c4d8b2e274140044975d356ba7e7bcb9e5057fb23e1c
7
+ data.tar.gz: 8696e8d13cf3266f88a1fb6cb53d3382a5fb1cb020de418fe9bd82ab43f3c3944428254c27747d8198c964977004e05f7aef9666cad80535f92041bc55775aab
@@ -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