palimpsest 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.kateproject +4 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +4 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +20 -0
- data/README.md +70 -0
- data/Rakefile +7 -0
- data/lib/palimpsest/assets.rb +189 -0
- data/lib/palimpsest/environment.rb +263 -0
- data/lib/palimpsest/utility.rb +69 -0
- data/lib/palimpsest/version.rb +4 -0
- data/lib/palimpsest.rb +9 -0
- data/palimpsest.gemspec +40 -0
- data/spec/assets_spec.rb +360 -0
- data/spec/environment_spec.rb +305 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/utility_spec.rb +56 -0
- metadata +297 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bb9471fad6a53da1e1cc97a04c7883e81bfa6756
|
4
|
+
data.tar.gz: ad2694a1fecbbe589e1bd2287d003398c0d4408c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 44c0455bd09f9084fbb2b90cd24c97f833ccb2e70594788a0632846955db6a8dd23b43425ac4e68a740a1c0c0a5c9b8c5c05e91bc831c50a4fdaf6cc413aa2fd
|
7
|
+
data.tar.gz: 6e9e38fa4cead06576012f74eda7cc94baf115578be4fd282a810ae7586d13dcbe19a0ccdc595e76cd4bf7ea51bd520a156023f6ad69228eb09a7264fd759431
|
data/.gitignore
ADDED
data/.kateproject
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Palimpsest ChangeLog
|
2
|
+
|
3
|
+
## 0.0.1
|
4
|
+
|
5
|
+
Initial release.
|
6
|
+
|
7
|
+
- Populating working environment from git repo or directory.
|
8
|
+
- Flexible asset pipeline with sprockets.
|
9
|
+
* `Palimpsest::Assets` class can be used standalone.
|
10
|
+
* Environment automatically compiles assets referenced in source files.
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
guard :rspec, cli: '--color --format Fuubar' do
|
2
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
3
|
+
watch(%r{^lib/palimpsest/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
|
+
watch(%r{^spec/.+_spec\.rb$})
|
5
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
6
|
+
end
|
7
|
+
|
8
|
+
guard :yard do
|
9
|
+
watch(%r{^lib/(.+)\.rb$})
|
10
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Evan Boyd Sosenko
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Palimpsest
|
2
|
+
|
3
|
+
by Evan Boyd Sosenko.
|
4
|
+
|
5
|
+
_No web framework, no problem: Palimpsest gives any custom or legacy project a modern workflow and toolset._
|
6
|
+
|
7
|
+
Built flexible, simple, and customizable.
|
8
|
+
Palimpsest runs on top of any project and acts as a post processor for your code.
|
9
|
+
Features a [Sprockets](https://github.com/sstephenson/sprockets) asset pipeline
|
10
|
+
and easy integration with [Kit](https://github.com/razor-x/kit).
|
11
|
+
|
12
|
+
[![Dependency Status](https://gemnasium.com/razor-x/palimpsest.png)](https://gemnasium.com/razor-x/palimpsest)
|
13
|
+
[![Build Status](https://travis-ci.org/razor-x/palimpsest.png?branch=master)](https://travis-ci.org/razor-x/palimpsest)
|
14
|
+
[![Coverage Status](https://coveralls.io/repos/razor-x/palimpsest/badge.png)](https://coveralls.io/r/razor-x/palimpsest)
|
15
|
+
[![Code Climate](https://codeclimate.com/github/razor-x/palimpsest.png)](https://codeclimate.com/github/razor-x/palimpsest)
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
gem 'palimpsest'
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
````bash
|
26
|
+
$ bundle
|
27
|
+
````
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
````bash
|
32
|
+
$ gem install palimpsest
|
33
|
+
````
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
**Palimpsest should not be considered stable until version 0.1.0 is released.**
|
38
|
+
|
39
|
+
### Documentation
|
40
|
+
|
41
|
+
_Comprehensive documentation and examples will be added to this REAME soon._
|
42
|
+
|
43
|
+
_For now, reference the YARD documentation below._
|
44
|
+
|
45
|
+
The primary documentation for Palimpsest is this README and the YARD source documentation.
|
46
|
+
|
47
|
+
YARD documentation for all gem versions is hosted on the [Palimpsest gem page](https://rubygems.org/gems/palimpsest).
|
48
|
+
Documentation for the latest commits is hosted on [the RubyDoc.info project page](http://rubydoc.info/github/razor-x/palimpsest/frames).
|
49
|
+
|
50
|
+
## Development
|
51
|
+
|
52
|
+
### Source Repository
|
53
|
+
|
54
|
+
The [Palimpsest source](https://github.com/razor-x/palimpsest) is hosted at github.
|
55
|
+
To clone the project run
|
56
|
+
|
57
|
+
````bash
|
58
|
+
$ git clone git@github.com:razor-x/palimpsest.git
|
59
|
+
````
|
60
|
+
|
61
|
+
## License
|
62
|
+
|
63
|
+
Palimpsest is licensed under the MIT license.
|
64
|
+
|
65
|
+
## Warranty
|
66
|
+
|
67
|
+
This software is provided "as is" and without any express or
|
68
|
+
implied warranties, including, without limitation, the implied
|
69
|
+
warranties of merchantibility and fitness for a particular
|
70
|
+
purpose.
|
data/Rakefile
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require 'open3'
|
3
|
+
require 'sprockets'
|
4
|
+
|
5
|
+
module Palimpsest
|
6
|
+
|
7
|
+
# Flexible asset pipeline using Sprockets.
|
8
|
+
# Paths are loaded into a `Sprockets::Environment` (relative to {#directory} if given).
|
9
|
+
# Asset tags are used in source code and replaced
|
10
|
+
# with generated asset path or compiled source if `inline` is used.
|
11
|
+
#
|
12
|
+
# For example, if type is set to `:javascripts` the following replacements would be made:
|
13
|
+
#
|
14
|
+
# [% javascript app %] -> app-9413c7f112033f0c6f2a8e8dd313399c18d93878.js
|
15
|
+
# [% javascript lib/jquery %] -> lib/jquery-e2a8cde3f5b3cdb011e38a673556c7a94729e0d1.js
|
16
|
+
# [% javascript inline tracking %] -> <compiled source of tracking.js asset>
|
17
|
+
#
|
18
|
+
class Assets
|
19
|
+
|
20
|
+
# Default {#options}.
|
21
|
+
DEFAULT_OPTIONS = {
|
22
|
+
# default path to output all saved assets (relative to directory)
|
23
|
+
output: '',
|
24
|
+
|
25
|
+
# assume assets will be served under this url
|
26
|
+
# e.g. `https://cdn.example.com/`
|
27
|
+
cdn: '',
|
28
|
+
|
29
|
+
# keyword to use in asset tag for inline assets
|
30
|
+
inline: 'inline',
|
31
|
+
|
32
|
+
# if true, also generate a gzipped asset
|
33
|
+
gzip: false,
|
34
|
+
|
35
|
+
# include hash in asset name
|
36
|
+
hash: true,
|
37
|
+
|
38
|
+
# opening and closing brackets for asset source tags
|
39
|
+
src_pre: '[%',
|
40
|
+
src_post: '%]',
|
41
|
+
|
42
|
+
# allowed options for `Sprockets::Environment`
|
43
|
+
sprockets_options: [ :js_compressor, :css_compressor ]
|
44
|
+
}
|
45
|
+
|
46
|
+
# @!attribute directory
|
47
|
+
# @return [String] directory which all paths will be relative to if set
|
48
|
+
#
|
49
|
+
# @!attribute paths
|
50
|
+
# @return [Array] paths to load into sprockets environment
|
51
|
+
#
|
52
|
+
# @!attribute type
|
53
|
+
# @return [Symbol] type of asset
|
54
|
+
attr_accessor :directory, :paths, :type
|
55
|
+
|
56
|
+
def initialize directory: '', options: {}, paths: {}
|
57
|
+
self.options options
|
58
|
+
self.directory = directory
|
59
|
+
self.paths = paths
|
60
|
+
end
|
61
|
+
|
62
|
+
# Uses {DEFAULT_OPTIONS} as initial value.
|
63
|
+
# @param options [Hash] merged with current options
|
64
|
+
# @return [Hash] current options
|
65
|
+
def options options={}
|
66
|
+
@options ||= DEFAULT_OPTIONS
|
67
|
+
@options = @options.merge options
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Sprockets::Environment] the current sprockets environment
|
71
|
+
def sprockets
|
72
|
+
@sprockets ||= Sprockets::Environment.new
|
73
|
+
end
|
74
|
+
|
75
|
+
# Load options into the sprockets environment.
|
76
|
+
# Values are loaded from {#options}.
|
77
|
+
def load_options
|
78
|
+
options[:sprockets_options].each do |opt|
|
79
|
+
sprockets.send "#{opt}=".to_sym, options[opt] if options[opt]
|
80
|
+
end
|
81
|
+
return self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Load paths into the sprockets environment.
|
85
|
+
# Values are loaded from {#paths}.
|
86
|
+
def load_paths
|
87
|
+
paths.each do |path|
|
88
|
+
sprockets.append_path "#{directory + '/' unless directory.empty?}#{path}"
|
89
|
+
end
|
90
|
+
return self
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Sprockets::Environment] sprockets environment with {#options} and {#paths} loaded
|
94
|
+
def assets
|
95
|
+
unless @loaded
|
96
|
+
load_options
|
97
|
+
load_paths
|
98
|
+
end
|
99
|
+
@loaded = true
|
100
|
+
sprockets
|
101
|
+
end
|
102
|
+
|
103
|
+
# Write a target asset to file with a hashed name.
|
104
|
+
# @param target [String] logical path to asset
|
105
|
+
# @param gzip [Boolean] if the asset should be gzipped
|
106
|
+
# @param hash [Boolean] if the asset name should include the hash
|
107
|
+
# @return [String, nil] the relative path to the written asset or `nil` if no such asset
|
108
|
+
def write target, gzip: options[:gzip], hash: options[:hash]
|
109
|
+
asset = assets[target]
|
110
|
+
|
111
|
+
return if asset.nil?
|
112
|
+
|
113
|
+
name = hash ? asset.digest_path : asset.logical_path.to_s
|
114
|
+
name = "#{options[:output]}/#{name}" unless options[:output].empty?
|
115
|
+
|
116
|
+
path = directory.empty? ? '' : "#{directory}/"
|
117
|
+
path << name
|
118
|
+
|
119
|
+
asset.write_to "#{path}.gz", compress: true if gzip
|
120
|
+
asset.write_to path
|
121
|
+
name
|
122
|
+
end
|
123
|
+
|
124
|
+
# (see #update_source)
|
125
|
+
# @note this modifies the `source` `String` in place
|
126
|
+
def update_source! source
|
127
|
+
# e.g. /\[%\s+javascript\s+((\S+)\s?(\S+))\s+%\]/
|
128
|
+
regex = /#{Regexp.escape options[:src_pre]}\s+#{type.to_s.singularize}\s+((\S+)\s?(\S+))\s+#{Regexp.escape options[:src_post]}/
|
129
|
+
source.gsub! regex do
|
130
|
+
if $2 == options[:inline]
|
131
|
+
assets[$3].to_s
|
132
|
+
else
|
133
|
+
asset = write $1
|
134
|
+
|
135
|
+
# @todo raise warning or error if asset not found
|
136
|
+
p "asset not found: #{$1}" and next if asset.nil?
|
137
|
+
|
138
|
+
options[:cdn].empty? ? asset : options[:cdn] + asset
|
139
|
+
end
|
140
|
+
end
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
|
144
|
+
# Replaces all asset tags in source string with asset path or asset source.
|
145
|
+
# Writes any referenced assets to disk.
|
146
|
+
# @param source [String] code to find and replace asset tags
|
147
|
+
# @return [String] copy of `source` with asset tags replaced
|
148
|
+
def update_source source
|
149
|
+
s = source
|
150
|
+
update_source! s
|
151
|
+
s
|
152
|
+
end
|
153
|
+
|
154
|
+
# Scans all non-binary files under `path` ({#directory} by default) for asset tags.
|
155
|
+
# Uses current asset {#type} (if set) and {#options}.
|
156
|
+
# @param path [String] where to look for source files
|
157
|
+
# @return [Array] files with asset tags
|
158
|
+
def find_tags path: directory
|
159
|
+
self.class.find_tags path, type, options
|
160
|
+
end
|
161
|
+
|
162
|
+
# Scans all non-binary files under `path` for asset tags.
|
163
|
+
# @param path [String] where to look for source files
|
164
|
+
# @param type [String, nil] only look for asset tags with this type (or any type if `nil`)
|
165
|
+
# @param options [Hash] merged with {DEFAULT_OPTIONS}
|
166
|
+
# (see #find_tags)
|
167
|
+
def self.find_tags path, type=nil, options={}
|
168
|
+
raise ArgumentError, 'path cannot be empty' if path.empty?
|
169
|
+
|
170
|
+
options = DEFAULT_OPTIONS.merge options
|
171
|
+
pre = Regexp.escape options[:src_pre]
|
172
|
+
post= Regexp.escape options[:src_post]
|
173
|
+
|
174
|
+
cmd = [ 'grep' ]
|
175
|
+
cmd.concat [ '-l', '-I', '-r', '-E' ]
|
176
|
+
cmd << \
|
177
|
+
if type.nil?
|
178
|
+
pre + '(.*?)' + post
|
179
|
+
else
|
180
|
+
pre + '\s+' + type.to_s + '\s+(.*?)' + post
|
181
|
+
end
|
182
|
+
cmd << path
|
183
|
+
|
184
|
+
files = []
|
185
|
+
Open3.capture2(*cmd).first.each_line { |l| files << l.chomp unless l.empty? }
|
186
|
+
files
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require 'grit'
|
2
|
+
|
3
|
+
module Palimpsest
|
4
|
+
|
5
|
+
# An environment is populated with the contents of
|
6
|
+
# a site's repository at a specified commit.
|
7
|
+
# The environment's files are rooted in a temporary {#directory}.
|
8
|
+
# An environment is the primary way to interact with a site's files.
|
9
|
+
#
|
10
|
+
# An environment loads a {#config} file from the working {#directory};
|
11
|
+
# by default, `palimpsest_config.yml`.
|
12
|
+
#
|
13
|
+
# Paths are all relative to the working {#directory}.
|
14
|
+
#
|
15
|
+
# ````yml
|
16
|
+
# palimpsest_config.yml
|
17
|
+
#
|
18
|
+
# # asset settings
|
19
|
+
# :assets:
|
20
|
+
# # all options are passed to `Palimpsest::Assets#options` and will use those defaults if unset
|
21
|
+
# # unless otherwise mentioned, options can be set or overridden per asset type
|
22
|
+
# :options:
|
23
|
+
# # opening and closing brackets for asset source tags
|
24
|
+
# # global option only: cannot be overridden per asset type
|
25
|
+
# :src_pre: "[%"
|
26
|
+
# :src_post: "%]"
|
27
|
+
#
|
28
|
+
# # relative directory to save compiled assets
|
29
|
+
# :output: compiled
|
30
|
+
#
|
31
|
+
# # assume assets will be served under here
|
32
|
+
# :cdn: https://cdn.example.com/
|
33
|
+
#
|
34
|
+
# # compiled asset names include a uniqe hash by default
|
35
|
+
# # this can be toggled off
|
36
|
+
# :hash: false
|
37
|
+
#
|
38
|
+
# # directories to scan for files with asset tags
|
39
|
+
# :sources:
|
40
|
+
# # putting assets/stylesheets first would allow asset tags,
|
41
|
+
# # e.g. for images, to be used in your stylesheets
|
42
|
+
# - assets/stylesheets
|
43
|
+
# - public
|
44
|
+
# - app/src
|
45
|
+
#
|
46
|
+
# # all other keys are asset types
|
47
|
+
# :javascripts:
|
48
|
+
# :options:
|
49
|
+
# :js_compressor: :uglifier
|
50
|
+
# # these paths are loaded into the sprockets environment
|
51
|
+
# :paths:
|
52
|
+
# - assets/javascripts
|
53
|
+
# - other/javascripts
|
54
|
+
#
|
55
|
+
# # this is another asset type which will have it's own namespace
|
56
|
+
# :stylesheets:
|
57
|
+
# :options:
|
58
|
+
# :css_compressor: :sass
|
59
|
+
#
|
60
|
+
# :paths:
|
61
|
+
# - assets/stylesheets
|
62
|
+
# # images can be part of the asset pipeline
|
63
|
+
# :images:
|
64
|
+
# # options can be overridden per type
|
65
|
+
# :options:
|
66
|
+
# :output: images
|
67
|
+
# :paths:
|
68
|
+
# - assets/images
|
69
|
+
# ````
|
70
|
+
class Environment
|
71
|
+
|
72
|
+
# Default {#options}.
|
73
|
+
DEFAULT_OPTIONS = {
|
74
|
+
# all environment's temporary directories will be rooted under here
|
75
|
+
tmp_dir: '/tmp',
|
76
|
+
|
77
|
+
# prepended to the name of the environment's working directory
|
78
|
+
dir_prefix: 'palimpsest_',
|
79
|
+
|
80
|
+
# name of config file to load, relative to environment's working directory
|
81
|
+
config_file: 'palimpsest_config.yml'
|
82
|
+
}
|
83
|
+
|
84
|
+
# @!attribute site
|
85
|
+
# @return site to build the environment with
|
86
|
+
#
|
87
|
+
# @!attribute treeish
|
88
|
+
# @return [String] the reference used to pick the commit to build the environment with
|
89
|
+
#
|
90
|
+
# @!attribute [r] directory
|
91
|
+
# @return [String] the environment's working directory
|
92
|
+
#
|
93
|
+
# @!attribute [r] populated
|
94
|
+
# @return [Boolean] true if the site's repo has been extracted
|
95
|
+
attr_reader :site, :treeish, :directory, :populated
|
96
|
+
|
97
|
+
def initialize site: nil, treeish: 'master', options: {}
|
98
|
+
@populated = false
|
99
|
+
self.options options
|
100
|
+
self.site = site if site
|
101
|
+
self.treeish = treeish
|
102
|
+
end
|
103
|
+
|
104
|
+
# Uses {DEFAULT_OPTIONS} as initial value.
|
105
|
+
# @param options [Hash] merged with current options
|
106
|
+
# @return [Hash] current options
|
107
|
+
def options options={}
|
108
|
+
@options ||= DEFAULT_OPTIONS
|
109
|
+
@options = @options.merge options
|
110
|
+
end
|
111
|
+
|
112
|
+
def site= site
|
113
|
+
raise RuntimeError, "Cannot redefine 'site' once populated" if populated
|
114
|
+
@site = site
|
115
|
+
end
|
116
|
+
|
117
|
+
def treeish= treeish
|
118
|
+
raise RuntimeError, "Cannot redefine 'treeish' once populated" if populated
|
119
|
+
raise TypeError unless treeish.is_a? String
|
120
|
+
@treeish = treeish
|
121
|
+
end
|
122
|
+
|
123
|
+
def directory
|
124
|
+
raise RuntimeError if site.nil?
|
125
|
+
if @directory.nil?
|
126
|
+
@directory = Palimpsest::Utility.make_random_directory options[:tmp_dir], "#{options[:dir_prefix]}#{site.name}_"
|
127
|
+
else
|
128
|
+
@directory
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Removes the environment's working directory.
|
133
|
+
def cleanup
|
134
|
+
FileUtils.remove_entry_secure directory if @directory
|
135
|
+
@directory = nil
|
136
|
+
@populated = false
|
137
|
+
return self
|
138
|
+
end
|
139
|
+
|
140
|
+
# Extracts the site's files from repository to the working directory.
|
141
|
+
def populate from: :repo
|
142
|
+
cleanup if populated
|
143
|
+
raise RuntimeError, "Cannot populate without 'site'" if site.nil?
|
144
|
+
|
145
|
+
case from
|
146
|
+
when :repo
|
147
|
+
raise RuntimeError, "Cannot populate without 'treeish'" if treeish.empty?
|
148
|
+
Palimpsest::Utility.extract_repo site.repo, treeish, directory
|
149
|
+
when :source
|
150
|
+
FileUtils.cp_r Dir["#{site.source}/*"], directory
|
151
|
+
end
|
152
|
+
|
153
|
+
@populated = true
|
154
|
+
return self
|
155
|
+
end
|
156
|
+
|
157
|
+
# @return [Hash] configuration loaded from {#options}`[:config_file]` under {#directory}
|
158
|
+
def config
|
159
|
+
populate unless populated
|
160
|
+
@config = YAML.load_file "#{directory}/#{options[:config_file]}"
|
161
|
+
validate_config if @config
|
162
|
+
end
|
163
|
+
|
164
|
+
# @return [Array<Palimpsest::Assets>] assets with settings and paths loaded from config
|
165
|
+
def assets
|
166
|
+
@assets = []
|
167
|
+
|
168
|
+
config[:assets].each do |type, opt|
|
169
|
+
next if [ :sources ].include? type
|
170
|
+
next if opt[:paths].nil?
|
171
|
+
|
172
|
+
assets = Palimpsest::Assets.new directory: directory, paths: opt[:paths]
|
173
|
+
assets.options config[:assets][:options] unless config[:assets][:options].nil?
|
174
|
+
assets.options opt[:options] unless opt[:options].nil?
|
175
|
+
assets.type = type
|
176
|
+
@assets << assets
|
177
|
+
end unless config[:assets].nil?
|
178
|
+
|
179
|
+
@assets
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [Array] all source files with asset tags
|
183
|
+
def sources_with_assets
|
184
|
+
return [] if config[:assets].nil?
|
185
|
+
return [] if config[:assets][:sources].nil?
|
186
|
+
|
187
|
+
@sources_with_assets = []
|
188
|
+
|
189
|
+
opts = {}
|
190
|
+
[ :src_pre, :src_post ].each do |opt|
|
191
|
+
opts[opt] = config[:assets][:options][opt] unless config[:assets][:options][opt].nil?
|
192
|
+
end unless config[:assets][:options].nil?
|
193
|
+
|
194
|
+
config[:assets][:sources].each do |path|
|
195
|
+
@sources_with_assets << Palimpsest::Assets.find_tags("#{directory}/#{path}", nil, opts)
|
196
|
+
end
|
197
|
+
|
198
|
+
@sources_with_assets.flatten
|
199
|
+
end
|
200
|
+
|
201
|
+
# Finds all assets in {#sources_with_assets} and
|
202
|
+
# generates the assets and updates the sources.
|
203
|
+
def compile_assets
|
204
|
+
sources_with_assets.each do |file|
|
205
|
+
source = File.read file
|
206
|
+
assets.each { |a| a.update_source! source }
|
207
|
+
Palimpsest::Utility.write source, file
|
208
|
+
end
|
209
|
+
return self
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
# Checks the config file for invalid settings.
|
215
|
+
#
|
216
|
+
# - Checks that paths are not absolute or use `../` or `~/`.
|
217
|
+
def validate_config
|
218
|
+
message = 'bad path in config'
|
219
|
+
|
220
|
+
def safe_path?(path) Palimpsest::Utility.safe_path?(path) end
|
221
|
+
|
222
|
+
# Checks the option in the asset key.
|
223
|
+
def validate_asset_options opts
|
224
|
+
opts.each do |k,v|
|
225
|
+
raise RuntimeError, 'bad option in config' if k == :sprockets_options
|
226
|
+
raise RuntimeError, message if k == :output && ! safe_path?(v)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
@config[:assets].each do |k, v|
|
231
|
+
|
232
|
+
# process @config[:assets][:options] then go to the next option
|
233
|
+
if k == :options
|
234
|
+
validate_asset_options v
|
235
|
+
next
|
236
|
+
end unless v.nil?
|
237
|
+
|
238
|
+
# process @config[:assets][:sources] then go to the next option
|
239
|
+
if k == :sources
|
240
|
+
v.each_with_index do |source, i|
|
241
|
+
raise RuntimeError, message unless safe_path? source
|
242
|
+
end
|
243
|
+
next
|
244
|
+
end
|
245
|
+
|
246
|
+
# process each asset type in @config[:assets]
|
247
|
+
v.each do |asset_key, asset_value|
|
248
|
+
# process :options
|
249
|
+
if asset_key == :options
|
250
|
+
validate_asset_options asset_value
|
251
|
+
next
|
252
|
+
end unless asset_value.nil?
|
253
|
+
|
254
|
+
# process each asset path
|
255
|
+
asset_value.each_with_index do |path, i|
|
256
|
+
raise RuntimeError, message unless safe_path? path
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end unless @config[:assets].nil?
|
260
|
+
@config
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|