/
assets.rb
173 lines (157 loc) · 4.17 KB
/
assets.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
require 'hanami/utils/class_attribute'
# Hanami
#
# @since 0.1.0
module Hanami
# Assets management for Ruby web applications
#
# @since 0.1.0
module Assets
# Base error for Hanami::Assets
#
# All the errors defined in this framework MUST inherit from it.
#
# @since 0.1.0
class Error < ::StandardError
end
require 'hanami/assets/version'
require 'hanami/assets/configuration'
require 'hanami/assets/config/global_sources'
require 'hanami/assets/helpers'
include Utils::ClassAttribute
# Configuration
#
# @since 0.1.0
# @api private
class_attribute :configuration
self.configuration = Configuration.new
# Configure framework
#
# @param blk [Proc] configuration code block
#
# @return self
#
# @since 0.1.0
#
# @see Hanami::Assets::Configuration
def self.configure(&blk)
configuration.instance_eval(&blk)
self
end
# Prepare assets for deploys
#
# @since 0.1.0
def self.deploy
require 'hanami/assets/precompiler'
require 'hanami/assets/bundler'
Precompiler.new(configuration, duplicates).run
Bundler.new(configuration, duplicates).run
end
# Precompile assets
#
# @since 0.4.0
def self.precompile(configurations)
require 'hanami/assets/precompiler'
require 'hanami/assets/bundler'
Precompiler.new(configuration, configurations).run
Bundler.new(configuration, configurations).run
end
# Preload the framework
#
# This MUST be used in production mode
#
# @since 0.1.0
#
# @example Direct Invocation
# require 'hanami/assets'
#
# Hanami::Assets.load!
#
# @example Load Via Configuration Block
# require 'hanami/assets'
#
# Hanami::Assets.configure do
# # ...
# end.load!
def self.load!
configuration.load!
end
# Global assets sources
#
# This is designed for third party integration gems with frontend frameworks
# like Bootstrap, Ember.js or React.
#
# Developers can maintain gems that ship static assets for these frameworks
# and make them available to Hanami::Assets.
#
# @return [Hanami::Assets::Config::GlobalSources]
#
# @since 0.1.0
#
# @example Ember.js Integration
# # lib/hanami/emberjs.rb (third party gem)
# require 'hanami/assets'
#
# Hanami::Assets.sources << '/path/to/emberjs/assets'
def self.sources
synchronize do
@@sources ||= Config::GlobalSources.new # rubocop:disable Style/ClassVars
end
end
# Duplicate the framework and generate modules for the target application
#
# @param _mod [Module] the Ruby namespace of the application
# @param blk [Proc] an optional block to configure the framework
#
# @return [Module] a copy of Hanami::Assets
#
# @since 0.1.0
#
# @see Hanami::Assets#dupe
# @see Hanami::Assets::Configuration
def self.duplicate(_mod, &blk)
dupe.tap do |duplicated|
duplicated.configure(&blk) if block_given?
duplicates << duplicated
end
end
# Duplicate Hanami::Assets in order to create a new separated instance
# of the framework.
#
# The new instance of the framework will be completely decoupled from the
# original. It will inherit the configuration, but all the changes that
# happen after the duplication, won't be reflected on the other copies.
#
# @return [Module] a copy of Hanami::Assets
#
# @since 0.1.0
# @api private
def self.dupe
dup.tap do |duplicated|
duplicated.configuration = configuration.duplicate
end
end
# Keep track of duplicated frameworks
#
# @return [Array] a collection of duplicated frameworks
#
# @since 0.1.0
# @api private
#
# @see Hanami::Assets#duplicate
# @see Hanami::Assets#dupe
def self.duplicates
synchronize do
@@duplicates ||= [] # rubocop:disable Style/ClassVars
end
end
class << self
private
# @since 0.1.0
# @api private
def synchronize(&blk)
Mutex.new.synchronize(&blk)
end
end
end
end