yarrow 0.9.2 → 0.9.4
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/.github/workflows/ruby.yml +2 -2
- data/README.md +10 -7
- data/lib/yarrow/config.rb +76 -13
- data/lib/yarrow/configuration.rb +5 -18
- data/lib/yarrow/content/collection.rb +7 -0
- data/lib/yarrow/content/expansion/aggregator.rb +3 -3
- data/lib/yarrow/content/expansion/filename_map.rb +1 -1
- data/lib/yarrow/content/policy.rb +48 -42
- data/lib/yarrow/defaults.yml +15 -2
- data/lib/yarrow/output/build.rb +37 -0
- data/lib/yarrow/schema/definitions.rb +1 -1
- data/lib/yarrow/schema/dictionary.rb +3 -2
- data/lib/yarrow/schema/entity.rb +18 -12
- data/lib/yarrow/schema/types.rb +63 -33
- data/lib/yarrow/schema/value.rb +21 -12
- data/lib/yarrow/symbols.rb +14 -0
- data/lib/yarrow/version.rb +1 -1
- data/lib/yarrow/web/document.rb +22 -1
- data/lib/yarrow/web/manifest.rb +22 -0
- data/lib/yarrow/web/url.rb +29 -0
- data/lib/yarrow.rb +3 -2
- metadata +5 -9
- data/lib/yarrow/assets/manifest.rb +0 -118
- data/lib/yarrow/assets/pipeline.rb +0 -126
- data/lib/yarrow/assets.rb +0 -2
- data/lib/yarrow/output/context.rb +0 -16
- data/lib/yarrow/output/web/indexed_file.rb +0 -45
- data/lib/yarrow/source/graph.rb +0 -6
- data/lib/yarrow/tools/front_matter.rb +0 -37
data/lib/yarrow/schema/types.rb
CHANGED
|
@@ -53,14 +53,37 @@ module Yarrow
|
|
|
53
53
|
accepts.key?(input.class)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
# Coerce input into the defined format based on configured
|
|
57
|
+
# accept rules.
|
|
58
|
+
#
|
|
59
|
+
# Will use the unit type’s constructor by default unless
|
|
60
|
+
# an alternative factory method and constructor arguments are
|
|
61
|
+
# provided in the accept rule or passed in via context.
|
|
62
|
+
#
|
|
63
|
+
# Most object coercions use the defaults, but the context
|
|
64
|
+
# and options enable specific customisations, such as passing
|
|
65
|
+
# in an assigned attribute name or the hash key that the input
|
|
66
|
+
# is a value of.
|
|
67
|
+
#
|
|
68
|
+
# @param [Object] input
|
|
69
|
+
# @param [nil, Hash] context
|
|
70
|
+
#
|
|
71
|
+
# @return [Object] instance of unit type represented by this wrapper
|
|
72
|
+
def coerce(input, context=nil)
|
|
57
73
|
constructor, options = accepts[input.class]
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
context_args = if context.nil?
|
|
76
|
+
options.clone
|
|
77
|
+
elsif options.nil?
|
|
78
|
+
context.clone
|
|
79
|
+
else
|
|
80
|
+
options.merge(context)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if context_args.nil?
|
|
61
84
|
unit.send(constructor, input)
|
|
62
85
|
else
|
|
63
|
-
unit.send(constructor, input,
|
|
86
|
+
unit.send(constructor, input, context_args)
|
|
64
87
|
end
|
|
65
88
|
end
|
|
66
89
|
|
|
@@ -88,14 +111,14 @@ module Yarrow
|
|
|
88
111
|
end
|
|
89
112
|
end
|
|
90
113
|
|
|
91
|
-
def cast(input)
|
|
92
|
-
return coerce(input) if should_coerce?(input)
|
|
114
|
+
def cast(input, context=nil)
|
|
115
|
+
return coerce(input, context) if should_coerce?(input)
|
|
93
116
|
check(input)
|
|
94
117
|
end
|
|
95
118
|
end
|
|
96
119
|
|
|
97
120
|
class Any < TypeClass
|
|
98
|
-
def cast(input)
|
|
121
|
+
def cast(input, context=nil)
|
|
99
122
|
input
|
|
100
123
|
end
|
|
101
124
|
end
|
|
@@ -141,39 +164,40 @@ module Yarrow
|
|
|
141
164
|
end
|
|
142
165
|
end
|
|
143
166
|
|
|
144
|
-
|
|
145
|
-
def
|
|
146
|
-
|
|
147
|
-
|
|
167
|
+
class List < TypeClass
|
|
168
|
+
def self.any
|
|
169
|
+
# Constraint: must be array instance
|
|
170
|
+
new(Instance.of(Array), Any.new)
|
|
148
171
|
end
|
|
149
172
|
|
|
150
|
-
def
|
|
151
|
-
|
|
152
|
-
self
|
|
173
|
+
def self.of(wrapped_type)
|
|
174
|
+
new(Instance.of(Array), Instance.of(wrapped_type))
|
|
153
175
|
end
|
|
154
176
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
self
|
|
158
|
-
end
|
|
159
|
-
end
|
|
177
|
+
attr_reader :element_type
|
|
178
|
+
alias container_type unit
|
|
160
179
|
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
def initialize(unit_type, element_type)
|
|
181
|
+
@element_type = element_type
|
|
182
|
+
super(unit_type)
|
|
183
|
+
end
|
|
163
184
|
|
|
164
|
-
def
|
|
165
|
-
|
|
185
|
+
def accept_elements(accept_type)
|
|
186
|
+
element_type.accept(accept_type)
|
|
187
|
+
self
|
|
166
188
|
end
|
|
167
189
|
|
|
168
|
-
def
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
def check(input)
|
|
191
|
+
converted = container_type.cast(input)
|
|
192
|
+
|
|
193
|
+
converted.map do |item|
|
|
194
|
+
element_type.cast(item)
|
|
171
195
|
end
|
|
172
196
|
end
|
|
173
197
|
end
|
|
174
198
|
|
|
175
199
|
class Map < TypeClass
|
|
176
|
-
include CompoundType
|
|
200
|
+
#include CompoundType
|
|
177
201
|
|
|
178
202
|
def self.of(map_spec)
|
|
179
203
|
if map_spec.is_a?(Hash)
|
|
@@ -198,15 +222,21 @@ module Yarrow
|
|
|
198
222
|
super(value_type)
|
|
199
223
|
end
|
|
200
224
|
|
|
225
|
+
def accept_elements(accept_type, constructor=:new, options=nil)
|
|
226
|
+
value_type.accept(accept_type, constructor, options)
|
|
227
|
+
self
|
|
228
|
+
end
|
|
229
|
+
|
|
201
230
|
def check(input)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
value_type.cast(value)
|
|
231
|
+
result = {}
|
|
232
|
+
|
|
233
|
+
input.each_pair do |key, value|
|
|
234
|
+
checked_key = key_type.cast(key)
|
|
235
|
+
checked_value = value_type.cast(value, { key: checked_key })
|
|
236
|
+
result[checked_key] = checked_value
|
|
207
237
|
end
|
|
208
238
|
|
|
209
|
-
|
|
239
|
+
result
|
|
210
240
|
end
|
|
211
241
|
end
|
|
212
242
|
|
data/lib/yarrow/schema/value.rb
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
module Yarrow
|
|
2
2
|
module Schema
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
class ValueType < Struct
|
|
4
|
+
def self.register(label)
|
|
5
|
+
class_type = Yarrow::Schema::Types::Instance.of(self).accept(Hash)
|
|
6
|
+
Yarrow::Schema::Definitions.register(label, class_type)
|
|
7
|
+
self
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Automatically register when struct is defined as a class extension
|
|
11
|
+
# rather than anonymous struct class.
|
|
12
|
+
def self.inherited(subclass)
|
|
13
|
+
if subclass.name
|
|
14
|
+
self.register(subclass.name.downcase.to_sym)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
13
18
|
|
|
14
19
|
# Value object (with comparison by value equality). This just chucks back a
|
|
15
20
|
# Ruby struct but wraps the constructor with method advice that handles
|
|
@@ -33,12 +38,16 @@ module Yarrow
|
|
|
33
38
|
|
|
34
39
|
validator = Dictionary.new(fields_spec)
|
|
35
40
|
|
|
36
|
-
struct =
|
|
41
|
+
struct = ValueType.new(*slots_spec, keyword_init: true, &block)
|
|
37
42
|
|
|
38
43
|
struct.define_method :initialize do |*args, **kwargs|
|
|
39
44
|
attr_values = if args.any?
|
|
40
45
|
raise ArgumentError.new("cannot mix slots and kwargs") if kwargs.any?
|
|
41
|
-
|
|
46
|
+
if args.first.instance_of?(Hash) and args.count == 1
|
|
47
|
+
args.first
|
|
48
|
+
else
|
|
49
|
+
Hash[slots.zip(args)]
|
|
50
|
+
end
|
|
42
51
|
else
|
|
43
52
|
kwargs
|
|
44
53
|
end
|
data/lib/yarrow/symbols.rb
CHANGED
|
@@ -19,6 +19,20 @@ module Yarrow
|
|
|
19
19
|
Object.const_get(Strings::Case.pascalcase(atom.to_s).to_sym)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# Converts a string name of class const to a symbol atom
|
|
23
|
+
#
|
|
24
|
+
# @param [Class, String, #to_s] const_obj
|
|
25
|
+
# @return [Symbol]
|
|
26
|
+
def self.from_const(const_obj)
|
|
27
|
+
const_lookup = if const_obj.respond_to?(:name)
|
|
28
|
+
const_obj.name
|
|
29
|
+
else
|
|
30
|
+
const_obj.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Strings::Case.underscore(const_lookup).to_sym
|
|
34
|
+
end
|
|
35
|
+
|
|
22
36
|
# @param [Symbol, String] atom
|
|
23
37
|
# @return [Symbol]
|
|
24
38
|
def self.to_singular(atom)
|
data/lib/yarrow/version.rb
CHANGED
data/lib/yarrow/web/document.rb
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
module Yarrow
|
|
2
2
|
module Web
|
|
3
|
+
class Document
|
|
4
|
+
attr_reader :content_node
|
|
5
|
+
|
|
6
|
+
def initialize(node, manifest)
|
|
7
|
+
@content_node = node
|
|
8
|
+
#manifest.add_document(self)
|
|
9
|
+
@manifest = manifest
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resource
|
|
13
|
+
content_node.props[:resource]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def url
|
|
17
|
+
@url ||= URL.generate(resource)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Deprecated
|
|
23
|
+
module LegacyWeb
|
|
3
24
|
class BaseDocument
|
|
4
25
|
def resource
|
|
5
26
|
@resource
|
data/lib/yarrow/web/manifest.rb
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
module Yarrow
|
|
2
2
|
module Web
|
|
3
|
+
class NewManifest
|
|
4
|
+
def initialize
|
|
5
|
+
@documents_index = {}
|
|
6
|
+
@documents = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :documents
|
|
10
|
+
|
|
11
|
+
def add_resource(resource)
|
|
12
|
+
add_document(Document.new(resource, self))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def add_document(document)
|
|
16
|
+
if @documents_index.key?(document.url)
|
|
17
|
+
raise "#{document.url} already exists in manifest"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@documents << document
|
|
21
|
+
@documents_index[document.url] = @documents.count - 1
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
3
25
|
class Manifest
|
|
4
26
|
def self.build(graph)
|
|
5
27
|
manifest = new
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Yarrow
|
|
2
|
+
module Web
|
|
3
|
+
module URI
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class URL
|
|
7
|
+
def self.generate(resource)
|
|
8
|
+
path = if resource.respond_to?(:url)
|
|
9
|
+
resource.url
|
|
10
|
+
elsif resource.respond_to?(:permalink)
|
|
11
|
+
resource.permalink
|
|
12
|
+
else
|
|
13
|
+
# TODO: URL generation strategy
|
|
14
|
+
"/one/two/three"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
new(path)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(path)
|
|
21
|
+
@path = path
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
@path
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/yarrow.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "kramdown"
|
|
|
4
4
|
require "toml-rb"
|
|
5
5
|
require "mustache"
|
|
6
6
|
require "parallel"
|
|
7
|
+
require "addressable/template"
|
|
7
8
|
|
|
8
9
|
require "extensions/mementus"
|
|
9
10
|
|
|
@@ -28,11 +29,11 @@ require "yarrow/content/expansion/directory_merge"
|
|
|
28
29
|
require "yarrow/content/expansion/traversal"
|
|
29
30
|
require "yarrow/content/resource"
|
|
30
31
|
require "yarrow/web/manifest"
|
|
32
|
+
require "yarrow/web/url"
|
|
31
33
|
require "yarrow/web/document"
|
|
32
34
|
require "yarrow/web/generator"
|
|
33
35
|
require "yarrow/web/template"
|
|
34
|
-
require "yarrow/output/
|
|
35
|
-
require "yarrow/output/web/indexed_file"
|
|
36
|
+
require "yarrow/output/build"
|
|
36
37
|
require "yarrow/content_map"
|
|
37
38
|
require "yarrow/server"
|
|
38
39
|
require "yarrow/server/livereload"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yarrow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mark Rickerby
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-02-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: addressable
|
|
@@ -297,12 +297,10 @@ files:
|
|
|
297
297
|
- bin/yarrow-server
|
|
298
298
|
- lib/extensions/mementus.rb
|
|
299
299
|
- lib/yarrow.rb
|
|
300
|
-
- lib/yarrow/assets.rb
|
|
301
|
-
- lib/yarrow/assets/manifest.rb
|
|
302
|
-
- lib/yarrow/assets/pipeline.rb
|
|
303
300
|
- lib/yarrow/config.rb
|
|
304
301
|
- lib/yarrow/configuration.rb
|
|
305
302
|
- lib/yarrow/console_runner.rb
|
|
303
|
+
- lib/yarrow/content/collection.rb
|
|
306
304
|
- lib/yarrow/content/expansion/aggregator.rb
|
|
307
305
|
- lib/yarrow/content/expansion/basename_merge.rb
|
|
308
306
|
- lib/yarrow/content/expansion/directory_merge.rb
|
|
@@ -330,8 +328,7 @@ files:
|
|
|
330
328
|
- lib/yarrow/generator.rb
|
|
331
329
|
- lib/yarrow/help.txt
|
|
332
330
|
- lib/yarrow/logging.rb
|
|
333
|
-
- lib/yarrow/output/
|
|
334
|
-
- lib/yarrow/output/web/indexed_file.rb
|
|
331
|
+
- lib/yarrow/output/build.rb
|
|
335
332
|
- lib/yarrow/process/expand_content.rb
|
|
336
333
|
- lib/yarrow/process/extract_source.rb
|
|
337
334
|
- lib/yarrow/process/project_manifest.rb
|
|
@@ -348,15 +345,14 @@ files:
|
|
|
348
345
|
- lib/yarrow/schema/value.rb
|
|
349
346
|
- lib/yarrow/server.rb
|
|
350
347
|
- lib/yarrow/server/livereload.rb
|
|
351
|
-
- lib/yarrow/source/graph.rb
|
|
352
348
|
- lib/yarrow/symbols.rb
|
|
353
|
-
- lib/yarrow/tools/front_matter.rb
|
|
354
349
|
- lib/yarrow/version.rb
|
|
355
350
|
- lib/yarrow/web/document.rb
|
|
356
351
|
- lib/yarrow/web/generator.rb
|
|
357
352
|
- lib/yarrow/web/manifest.rb
|
|
358
353
|
- lib/yarrow/web/static_asset.rb
|
|
359
354
|
- lib/yarrow/web/template.rb
|
|
355
|
+
- lib/yarrow/web/url.rb
|
|
360
356
|
- yarrow.gemspec
|
|
361
357
|
homepage: http://rubygemspec.org/gems/yarrow
|
|
362
358
|
licenses:
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# TODO: where else is this used?
|
|
2
|
-
require 'json'
|
|
3
|
-
|
|
4
|
-
module Yarrow
|
|
5
|
-
module Assets
|
|
6
|
-
##
|
|
7
|
-
# Provides access to the bundle of compiled CSS and JS assets.
|
|
8
|
-
#
|
|
9
|
-
# This is currently based on the output structure of the JSON manifest file
|
|
10
|
-
# generated by Sprockets, but this class isn't coupled to the Sprockets API
|
|
11
|
-
# so could be used as a generic manifest reader.
|
|
12
|
-
#
|
|
13
|
-
# - `logical_path` represents the core named path to an asset sans version, eg: `main.css`
|
|
14
|
-
# - `digest_path` represents the versioned instance of an asset with associated digest,
|
|
15
|
-
# eg: `main-4362eea15558e73d3663de653cdeb81e.css`
|
|
16
|
-
class Manifest
|
|
17
|
-
##
|
|
18
|
-
# Initializes the manifest from a Sprockets-style JSON file.
|
|
19
|
-
#
|
|
20
|
-
# If no assets directory is given, looks for a manifest in the main output directory.
|
|
21
|
-
#
|
|
22
|
-
# @param config [Yarrow::Configuration]
|
|
23
|
-
def initialize(config)
|
|
24
|
-
raise Yarrow::ConfigurationError if config.assets.nil?
|
|
25
|
-
|
|
26
|
-
if config.assets.output_dir
|
|
27
|
-
manifest_path = Pathname.new(config.assets.output_dir) + config.assets.manifest_file
|
|
28
|
-
else
|
|
29
|
-
manifest_path = Pathname.new(config.output_dir) + config.assets.manifest_file
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
if File.exists?(manifest_path)
|
|
33
|
-
manifest_data = JSON.parse(File.read(manifest_path))
|
|
34
|
-
|
|
35
|
-
@manifest_index = if manifest_data.key?('assets')
|
|
36
|
-
manifest_data['assets']
|
|
37
|
-
else
|
|
38
|
-
manifest_data
|
|
39
|
-
end
|
|
40
|
-
else
|
|
41
|
-
@manifest_index = {}
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
##
|
|
46
|
-
# True if the named asset exists.
|
|
47
|
-
#
|
|
48
|
-
# @param logical_path [String]
|
|
49
|
-
# @return [Boolean]
|
|
50
|
-
def exists?(logical_path)
|
|
51
|
-
@manifest_index.key? logical_path
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
##
|
|
55
|
-
# Returns the generated digest path to a named asset.
|
|
56
|
-
#
|
|
57
|
-
# @param logical_path [String]
|
|
58
|
-
# @return [String]
|
|
59
|
-
def digest_path(logical_path)
|
|
60
|
-
@manifest_index[logical_path]
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
##
|
|
64
|
-
# Returns the list of named assets in the manifest.
|
|
65
|
-
#
|
|
66
|
-
# @return [Array<String>]
|
|
67
|
-
def logical_paths
|
|
68
|
-
@manifest_index.keys
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
##
|
|
72
|
-
# Returns the list of generated digest paths in the manifest.
|
|
73
|
-
#
|
|
74
|
-
# @return [Array<String>]
|
|
75
|
-
def digest_paths
|
|
76
|
-
@manifest_index.values
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
##
|
|
80
|
-
# Returns the list of named CSS assets in the manifest.
|
|
81
|
-
#
|
|
82
|
-
# @return [Array<String>]
|
|
83
|
-
def css_logical_paths
|
|
84
|
-
select_by_extension(logical_paths, '.css')
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
##
|
|
88
|
-
# Returns the list of named JS assets in the manifest.
|
|
89
|
-
#
|
|
90
|
-
# @return [Array<String>]
|
|
91
|
-
def js_logical_paths
|
|
92
|
-
select_by_extension(logical_paths, '.js')
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
##
|
|
96
|
-
# Returns the list of generated CSS assets in the manifest.
|
|
97
|
-
#
|
|
98
|
-
# @return [Array<String>]
|
|
99
|
-
def css_digest_paths
|
|
100
|
-
select_by_extension(digest_paths, '.css')
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
##
|
|
104
|
-
# Returns the list of generated JS assets in the manifest.
|
|
105
|
-
#
|
|
106
|
-
# @return [Array<String>]
|
|
107
|
-
def js_digest_paths
|
|
108
|
-
select_by_extension(digest_paths, '.js')
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
private
|
|
112
|
-
|
|
113
|
-
def select_by_extension(collection, ext)
|
|
114
|
-
collection.select { |asset| asset.end_with?(ext) }
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
require 'pathname'
|
|
2
|
-
require 'fileutils'
|
|
3
|
-
require 'sprockets'
|
|
4
|
-
|
|
5
|
-
module Yarrow
|
|
6
|
-
module Assets
|
|
7
|
-
##
|
|
8
|
-
# Processes static assets using Sprockets.
|
|
9
|
-
class Pipeline
|
|
10
|
-
|
|
11
|
-
include Loggable
|
|
12
|
-
|
|
13
|
-
attr_reader :input_dir, :output_dir, :append_paths, :bundles, :assets
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
# @param config [Yarrow::Configuration]
|
|
17
|
-
def initialize(config)
|
|
18
|
-
raise Yarrow::ConfigurationError if config.assets.nil?
|
|
19
|
-
|
|
20
|
-
@input_dir = config.assets.input_dir || default_input_dir
|
|
21
|
-
|
|
22
|
-
if config.assets.output_dir
|
|
23
|
-
@output_dir = config.assets.output_dir
|
|
24
|
-
else
|
|
25
|
-
@output_dir = config.output_dir || default_output_dir
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
@append_paths = []
|
|
29
|
-
|
|
30
|
-
case config.assets.append_paths
|
|
31
|
-
when Array
|
|
32
|
-
@append_paths = config.assets.append_paths
|
|
33
|
-
when '*'
|
|
34
|
-
@append_paths = Dir[@input_dir + '/*'].select do |path|
|
|
35
|
-
File.directory?(path)
|
|
36
|
-
end.map do |path|
|
|
37
|
-
File.basename(path)
|
|
38
|
-
end
|
|
39
|
-
when String
|
|
40
|
-
@append_paths << config.assets.append_paths
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
##
|
|
45
|
-
# Compiles an asset manifest and processed output files from the given input bundles.
|
|
46
|
-
# Also generates a manifest linking each output bundle to its given input name.
|
|
47
|
-
#
|
|
48
|
-
# @param bundles [Array<String>]
|
|
49
|
-
def compile(bundles = [])
|
|
50
|
-
bundles.each do |bundle|
|
|
51
|
-
if bundle.include? '*'
|
|
52
|
-
Dir["#{@input_dir}/#{bundle}"].each do |asset|
|
|
53
|
-
logger.info "Compiling: #{asset}"
|
|
54
|
-
manifest.compile(File.basename(asset))
|
|
55
|
-
end
|
|
56
|
-
else
|
|
57
|
-
logger.info "Compiling: #{bundle}"
|
|
58
|
-
manifest.compile(bundle)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
##
|
|
64
|
-
# Copy the given files to the output path without processing or renaming.
|
|
65
|
-
#
|
|
66
|
-
# @param bundle [Array<String>]
|
|
67
|
-
def copy(bundles = [])
|
|
68
|
-
bundles.each do |bundle|
|
|
69
|
-
FileUtils.cp_r "#{@input_dir}/#{bundle}", "#{@output_dir}/#{bundle}"
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
##
|
|
74
|
-
# Purges redundant compiled assets from the output path.
|
|
75
|
-
#
|
|
76
|
-
# @example Purge all assets except those created in the last 10 minutes
|
|
77
|
-
# pipeline.purge(0, )
|
|
78
|
-
#
|
|
79
|
-
# @param keep [Integer] Number of previous revisions to keep. Defaults to 2.
|
|
80
|
-
# @param age [Integer] Purge all assets older than this date. Defaults to 1 hour.
|
|
81
|
-
def purge(keep = 2, age = 3600)
|
|
82
|
-
# TODO: upgrade to Sprockets 3.0 to support the age arg
|
|
83
|
-
manifest.clean(keep)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
##
|
|
87
|
-
# Access instance of the Sprockets environment.
|
|
88
|
-
#
|
|
89
|
-
# @return [Sprockets::Environment]
|
|
90
|
-
def environment
|
|
91
|
-
# TODO: decouple dependency on Sprockets
|
|
92
|
-
@environment ||= create_environment
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
private
|
|
96
|
-
|
|
97
|
-
def default_input_dir
|
|
98
|
-
"#{Dir.pwd}/assets"
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def default_output_dir
|
|
102
|
-
"#{Dir.pwd}/public/assets"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def manifest_file_path
|
|
106
|
-
"#{@output_dir}/manifest.json"
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def manifest
|
|
110
|
-
Sprockets::Manifest.new(environment, manifest_file_path)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def create_environment
|
|
114
|
-
environment = Sprockets::Environment.new(@input_dir)
|
|
115
|
-
|
|
116
|
-
@append_paths.each do |path|
|
|
117
|
-
environment.append_path path
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
environment
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
end
|
|
126
|
-
end
|
data/lib/yarrow/assets.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Yarrow
|
|
2
|
-
module Output
|
|
3
|
-
# Provides a data context for rendering a template.
|
|
4
|
-
#
|
|
5
|
-
# Methods provided by this class become available as named variables in
|
|
6
|
-
# Mustache templates.
|
|
7
|
-
class Context
|
|
8
|
-
def initialize(attributes)
|
|
9
|
-
metaclass = class << self; self; end
|
|
10
|
-
attributes.each do |name, value|
|
|
11
|
-
metaclass.send :define_method, name, lambda { value }
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|