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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa81b0371b1f3ef182f0c4394faa41c60289de2ce3ab22164319925b157dfc21
4
- data.tar.gz: 584760dc017bc85b1f47a5ba3abda0823aa5becc27debc2a4e8c96b43fc22805
3
+ metadata.gz: c320efae9cee00187448b9d22ea6cb967b8a148f2f2cadc44ef417e63e36ab2c
4
+ data.tar.gz: e41403612c56fa90768a8c133d2f8d35aa1e3bf6ac123b3980e3abda7bd57362
5
5
  SHA512:
6
- metadata.gz: 06fac4af72e066543594415437b1ff5dd1587c0a41836bd68e823d53d60677d8a8aef39db52788e7f16524e1f287f303a9d1037d7a270fef68e513f4e5986ee5
7
- data.tar.gz: 48dc23a4b8ffeb9a7ee19c89641e5ee3b5e4accf4ce72d9fe4167ec4aa541c79041f216f230707b550d502541120af4dcd9ec3919c7ed967c56024fbe7d8af81
6
+ metadata.gz: a0409df20a76ab9ff43141b509d166ebf4ae1f6f0e2782fe31217f5b0fc4d0bd468086032c4f28ce4ef9c4d8b2e274140044975d356ba7e7bcb9e5057fb23e1c
7
+ data.tar.gz: 8696e8d13cf3266f88a1fb6cb53d3382a5fb1cb020de418fe9bd82ab43f3c3944428254c27747d8198c964977004e05f7aef9666cad80535f92041bc55775aab
@@ -1,187 +1,7 @@
1
- require 'stringio'
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
- Spud.new.run!
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,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