amiel-sprockets 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +26 -0
- data/ext/nph-sprockets.cgi +127 -0
- data/lib/sprockets.rb +42 -0
- data/lib/sprockets/concatenation.rb +36 -0
- data/lib/sprockets/environment.rb +52 -0
- data/lib/sprockets/error.rb +5 -0
- data/lib/sprockets/pathname.rb +37 -0
- data/lib/sprockets/preprocessor.rb +92 -0
- data/lib/sprockets/secretary.rb +110 -0
- data/lib/sprockets/source_file.rb +54 -0
- data/lib/sprockets/source_line.rb +86 -0
- data/lib/sprockets/version.rb +9 -0
- data/test/fixtures/assets/images/script_with_assets/one.png +1 -0
- data/test/fixtures/assets/images/script_with_assets/two.png +1 -0
- data/test/fixtures/assets/stylesheets/script_with_assets.css +1 -0
- data/test/fixtures/constants.yml +1 -0
- data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_ignored_when_strip_comments_is_false.js +8 -0
- data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_removed_by_default.js +2 -0
- data/test/fixtures/multiline_comments_should_be_removed_by_default.js +4 -0
- data/test/fixtures/requiring_a_file_after_it_has_already_been_required_should_do_nothing.js +5 -0
- data/test/fixtures/requiring_a_file_that_does_not_exist_should_raise_an_error.js +1 -0
- data/test/fixtures/requiring_a_file_with_css_style_comments_should_replace_the_require_comment_with_file_contents.css +4 -0
- data/test/fixtures/requiring_a_single_file_should_replace_the_require_comment_with_the_file_contents.js +3 -0
- data/test/fixtures/requiring_the_current_file_should_do_nothing.js +1 -0
- data/test/fixtures/src/constants.yml +3 -0
- data/test/fixtures/src/foo.css +1 -0
- data/test/fixtures/src/foo.js +1 -0
- data/test/fixtures/src/foo/bar.js +4 -0
- data/test/fixtures/src/foo/foo.js +1 -0
- data/test/fixtures/src/script_with_assets.js +3 -0
- data/test/test_concatenation.rb +28 -0
- data/test/test_environment.rb +64 -0
- data/test/test_helper.rb +55 -0
- data/test/test_pathname.rb +43 -0
- data/test/test_preprocessor.rb +116 -0
- data/test/test_secretary.rb +83 -0
- data/test/test_source_file.rb +34 -0
- data/test/test_source_line.rb +89 -0
- metadata +50 -4
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake/testtask"
|
3
|
+
require "rake/gempackagetask"
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << "test"
|
9
|
+
t.test_files = FileList["test/test_*.rb"]
|
10
|
+
t.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
Rake::GemPackageTask.new(eval(IO.read(File.join(File.dirname(__FILE__), "sprockets.gemspec")))) do |pkg|
|
14
|
+
require File.join(File.dirname(__FILE__), "lib", "sprockets", "version")
|
15
|
+
raise "Error: Sprockets::Version doesn't match gemspec" if Sprockets::Version::STRING != pkg.version.to_s
|
16
|
+
|
17
|
+
pkg.need_zip = true
|
18
|
+
pkg.need_tar = true
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :manifest do
|
22
|
+
task :generate do
|
23
|
+
files = Dir["Rakefile", "bin/**/*", "lib/**/*", "test/**/*", "ext/**/*"]
|
24
|
+
File.open("MANIFEST.txt", "w"){|f| f.puts *files }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This is a simple CGI wrapper around Sprockets.
|
4
|
+
#
|
5
|
+
# Copy it into a directory on your site with CGI enabled. When invoked, the
|
6
|
+
# script will search its directory and parent directories for a YAML file named
|
7
|
+
# "config/sprockets.yml" in order to load configuration information.
|
8
|
+
#
|
9
|
+
# If you set the environment variable "sprockets_generate_output_file" to
|
10
|
+
# "true" the concatenation will be cached to disk. Use it in conjunction with
|
11
|
+
# URL rewriting to cache your Sprockets output on the first request.
|
12
|
+
#
|
13
|
+
# Assuming a site layout like this:
|
14
|
+
#
|
15
|
+
# mysite/
|
16
|
+
# config/
|
17
|
+
# sprockets.yml
|
18
|
+
# javascripts/
|
19
|
+
# mysite.js
|
20
|
+
# ...
|
21
|
+
# public/
|
22
|
+
# index.html
|
23
|
+
# nph-sprockets.cgi (this file)
|
24
|
+
# vendor/
|
25
|
+
# sprockets/
|
26
|
+
# prototype/ -> ...
|
27
|
+
# scriptaculous/ -> ...
|
28
|
+
#
|
29
|
+
# mysite/config/sprockets.yml might look like this:
|
30
|
+
#
|
31
|
+
# :load_path:
|
32
|
+
# - javascripts
|
33
|
+
# - vendor/sprockets/*/src
|
34
|
+
# :source_files:
|
35
|
+
# - javascripts/mysite.js
|
36
|
+
# - javascripts/*.js
|
37
|
+
# :output_file: public/sprockets.js
|
38
|
+
#
|
39
|
+
# The <script> tag in mysite/public/index.html could look like this:
|
40
|
+
#
|
41
|
+
# <script type="text/javascript" src="/sprockets.js"></script>
|
42
|
+
#
|
43
|
+
# And you might have the following Apache configuration:
|
44
|
+
#
|
45
|
+
# <VirtualHost ...>
|
46
|
+
# ServerName mysite.example.org
|
47
|
+
# DocumentRoot "/path/to/mysite/public"
|
48
|
+
#
|
49
|
+
# <Directory "/path/to/mysite/public">
|
50
|
+
# Options +ExecCGI +FollowSymLinks
|
51
|
+
# AddHandler cgi-script .cgi
|
52
|
+
#
|
53
|
+
# RewriteEngine on
|
54
|
+
# RewriteCond /sprockets.js !-f
|
55
|
+
# RewriteRule ^sprockets\.js /nph-sprockets.cgi [P,L]
|
56
|
+
# </Directory>
|
57
|
+
# </VirtualHost>
|
58
|
+
#
|
59
|
+
# All requests to /sprockets.js will transparently proxy /nph-sprockets.cgi if
|
60
|
+
# mysite/public/sprockets.js does not exist. In production, you can add
|
61
|
+
#
|
62
|
+
# SetEnv sprockets_generate_output_file true
|
63
|
+
#
|
64
|
+
# to your Apache configuration and mysites/public/sprockets.js will be cached
|
65
|
+
# on the first request to /sprockets.js.
|
66
|
+
|
67
|
+
require "yaml"
|
68
|
+
require "fileutils"
|
69
|
+
|
70
|
+
def respond_with(options = {})
|
71
|
+
options = { :code => 200, :content => "", :type => "text/plain" }.merge(options)
|
72
|
+
print "HTTP/1.0 #{options[:code]}\r\n"
|
73
|
+
print "Content-Type: #{options[:type]}\r\n"
|
74
|
+
print "Content-Length: #{options[:content].length}\r\n"
|
75
|
+
print "\r\n#{options[:content]}"
|
76
|
+
$stdout.flush
|
77
|
+
exit!
|
78
|
+
end
|
79
|
+
|
80
|
+
def search_upwards_for(filename)
|
81
|
+
pwd = original_pwd = Dir.pwd
|
82
|
+
loop do
|
83
|
+
return File.expand_path(filename) if File.file?(filename)
|
84
|
+
Dir.chdir("..")
|
85
|
+
respond_with(:code => 500, :content => "couldn't find config/sprockets.yml") if Dir.pwd == pwd
|
86
|
+
pwd = Dir.pwd
|
87
|
+
end
|
88
|
+
ensure
|
89
|
+
Dir.chdir(original_pwd)
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_output_file?
|
93
|
+
(ENV["REDIRECT_sprockets_generate_output_file"] || ENV["sprockets_generate_output_file"]) =~ /true/i
|
94
|
+
end
|
95
|
+
|
96
|
+
configuration_file = search_upwards_for("config/sprockets.yml")
|
97
|
+
sprockets_root = File.dirname(File.dirname(configuration_file))
|
98
|
+
configuration = YAML.load(IO.read(configuration_file))
|
99
|
+
|
100
|
+
begin
|
101
|
+
if File.directory?(sprockets_dir = File.join(sprockets_root, "vendor/gems/sprockets/lib"))
|
102
|
+
$:.unshift sprockets_dir
|
103
|
+
elsif File.directory?(sprockets_dir = File.join(sprockets_root, "vendor/sprockets/lib"))
|
104
|
+
$:.unshift sprockets_dir
|
105
|
+
else
|
106
|
+
require "rubygems"
|
107
|
+
end
|
108
|
+
|
109
|
+
require "sprockets"
|
110
|
+
|
111
|
+
rescue Exception => e
|
112
|
+
respond_with(:code => 500, :content => "couldn't find sprockets: #{e}")
|
113
|
+
end
|
114
|
+
|
115
|
+
begin
|
116
|
+
secretary = Sprockets::Secretary.new(
|
117
|
+
:root => sprockets_root,
|
118
|
+
:load_path => configuration[:load_path],
|
119
|
+
:source_files => configuration[:source_files]
|
120
|
+
)
|
121
|
+
|
122
|
+
secretary.concatenation.save_to(File.join(sprockets_root, configuration[:output_file])) if generate_output_file?
|
123
|
+
respond_with(:content => secretary.concatenation.to_s, :type => "text/javascript")
|
124
|
+
|
125
|
+
rescue Exception => e
|
126
|
+
respond_with(:code => 500, :content => "couldn't generate concatenated javascript: #{e}")
|
127
|
+
end
|
data/lib/sprockets.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module Sprockets
|
7
|
+
class << self
|
8
|
+
def running_on_windows?
|
9
|
+
RUBY_PLATFORM =~ /(win|w)32$/
|
10
|
+
end
|
11
|
+
|
12
|
+
def absolute?(location)
|
13
|
+
same_when_expanded?(location) || platform_absolute_path?(location)
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def same_when_expanded?(location)
|
18
|
+
location[0, 1] == File.expand_path(location)[0, 1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def platform_absolute_path?(location)
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
if Sprockets.running_on_windows?
|
26
|
+
def platform_absolute_path?(location)
|
27
|
+
location[0, 1] == File::SEPARATOR && File.expand_path(location) =~ /[A-Za-z]:[\/\\]/
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require "sprockets/version"
|
34
|
+
require "sprockets/error"
|
35
|
+
require "sprockets/environment"
|
36
|
+
require "sprockets/pathname"
|
37
|
+
require "sprockets/source_line"
|
38
|
+
require "sprockets/source_file"
|
39
|
+
require "sprockets/concatenation"
|
40
|
+
require "sprockets/preprocessor"
|
41
|
+
require "sprockets/secretary"
|
42
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Sprockets
|
2
|
+
class Concatenation
|
3
|
+
attr_reader :source_lines
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@source_lines = []
|
7
|
+
@source_file_mtimes = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def record(source_line)
|
11
|
+
source_lines << source_line
|
12
|
+
record_mtime_for(source_line.source_file)
|
13
|
+
source_line
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
source_lines.join
|
18
|
+
end
|
19
|
+
|
20
|
+
def mtime
|
21
|
+
@source_file_mtimes.values.max
|
22
|
+
end
|
23
|
+
|
24
|
+
def save_to(filename)
|
25
|
+
timestamp = mtime
|
26
|
+
File.open(filename, "w") { |file| file.write(to_s) }
|
27
|
+
File.utime(timestamp, timestamp, filename)
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def record_mtime_for(source_file)
|
33
|
+
@source_file_mtimes[source_file] ||= source_file.mtime
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Sprockets
|
2
|
+
class Environment
|
3
|
+
attr_reader :root, :load_path
|
4
|
+
|
5
|
+
def initialize(root, load_path = [])
|
6
|
+
@load_path = [@root = Pathname.new(self, root)]
|
7
|
+
|
8
|
+
load_path.reverse_each do |location|
|
9
|
+
register_load_location(location)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def pathname_from(location)
|
14
|
+
Pathname.new(self, absolute_location_from(location))
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_load_location(location)
|
18
|
+
pathname = pathname_from(location)
|
19
|
+
load_path.delete(pathname)
|
20
|
+
load_path.unshift(pathname)
|
21
|
+
location
|
22
|
+
end
|
23
|
+
|
24
|
+
def find(location)
|
25
|
+
if Sprockets.absolute?(location) && File.exists?(location)
|
26
|
+
pathname_from(location)
|
27
|
+
else
|
28
|
+
find_all(location).first
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def constants(reload = false)
|
33
|
+
@constants = nil if reload
|
34
|
+
@constants ||= find_all("constants.yml").inject({}) do |constants, pathname|
|
35
|
+
contents = YAML.load(pathname.contents) rescue nil
|
36
|
+
contents = {} unless contents.is_a?(Hash)
|
37
|
+
constants.merge(contents)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
def absolute_location_from(location)
|
43
|
+
location = location.to_s
|
44
|
+
location = File.join(root.absolute_location, location) unless Sprockets.absolute?(location)
|
45
|
+
File.expand_path(location)
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_all(location)
|
49
|
+
load_path.map { |pathname| pathname.find(location) }.compact
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Sprockets
|
2
|
+
class Pathname
|
3
|
+
attr_reader :environment, :absolute_location
|
4
|
+
|
5
|
+
def initialize(environment, absolute_location)
|
6
|
+
@environment = environment
|
7
|
+
@absolute_location = File.expand_path(absolute_location)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns a Pathname for the location relative to this pathname's absolute location.
|
11
|
+
def find(location, kind = :file)
|
12
|
+
location = File.join(absolute_location, location)
|
13
|
+
File.send("#{kind}?", location) ? Pathname.new(environment, location) : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def parent_pathname
|
17
|
+
Pathname.new(environment, File.dirname(absolute_location))
|
18
|
+
end
|
19
|
+
|
20
|
+
def source_file
|
21
|
+
SourceFile.new(environment, self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def contents
|
25
|
+
IO.read(absolute_location)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(pathname)
|
29
|
+
environment == pathname.environment &&
|
30
|
+
absolute_location == pathname.absolute_location
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
absolute_location
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Sprockets
|
2
|
+
class Preprocessor
|
3
|
+
attr_reader :environment, :concatenation, :source_files, :asset_paths
|
4
|
+
|
5
|
+
def initialize(environment, options = {})
|
6
|
+
@environment = environment
|
7
|
+
@concatenation = Concatenation.new
|
8
|
+
@source_files = []
|
9
|
+
@asset_paths = []
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def require(source_file)
|
14
|
+
return if source_files.include?(source_file)
|
15
|
+
source_files << source_file
|
16
|
+
|
17
|
+
source_file.each_source_line do |source_line|
|
18
|
+
if source_line.require?
|
19
|
+
require_from_source_line(source_line)
|
20
|
+
elsif source_line.provide?
|
21
|
+
provide_from_source_line(source_line)
|
22
|
+
else
|
23
|
+
record_source_line(source_line)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def provide(asset_path)
|
29
|
+
return if !asset_path || asset_paths.include?(asset_path)
|
30
|
+
asset_paths << asset_path
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
attr_reader :options
|
35
|
+
|
36
|
+
def require_from_source_line(source_line)
|
37
|
+
require pathname_from(source_line).source_file
|
38
|
+
end
|
39
|
+
|
40
|
+
def provide_from_source_line(source_line)
|
41
|
+
provide asset_path_from(source_line)
|
42
|
+
end
|
43
|
+
|
44
|
+
def record_source_line(source_line)
|
45
|
+
unless source_line.comment? && strip_comments?
|
46
|
+
concatenation.record(source_line)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def strip_comments?
|
51
|
+
options[:strip_comments] != false
|
52
|
+
end
|
53
|
+
|
54
|
+
def pathname_from(source_line)
|
55
|
+
pathname = send(pathname_finder_from(source_line), source_line)
|
56
|
+
raise_load_error_for(source_line) unless pathname
|
57
|
+
pathname
|
58
|
+
end
|
59
|
+
|
60
|
+
def pathname_for_require_from(source_line)
|
61
|
+
environment.find(location_from(source_line))
|
62
|
+
end
|
63
|
+
|
64
|
+
def pathname_for_relative_require_from(source_line)
|
65
|
+
source_line.source_file.find(location_from(source_line))
|
66
|
+
end
|
67
|
+
|
68
|
+
def pathname_finder_from(source_line)
|
69
|
+
"pathname_for_#{kind_of_require_from(source_line)}_from"
|
70
|
+
end
|
71
|
+
|
72
|
+
def kind_of_require_from(source_line)
|
73
|
+
source_line.require[/^(.)/, 1] == '"' ? :relative_require : :require
|
74
|
+
end
|
75
|
+
|
76
|
+
def location_from(source_line)
|
77
|
+
location = source_line.require[/^.(.*).$/, 1]
|
78
|
+
ext = File.extname source_line.source_file.pathname.to_s
|
79
|
+
File.join(File.dirname(location), File.basename(location, ext) + ext)
|
80
|
+
end
|
81
|
+
|
82
|
+
def asset_path_from(source_line)
|
83
|
+
source_line.source_file.find(source_line.provide, :exists)
|
84
|
+
end
|
85
|
+
|
86
|
+
def raise_load_error_for(source_line)
|
87
|
+
kind = kind_of_require_from(source_line).to_s.tr("_", " ")
|
88
|
+
file = File.split(location_from(source_line)).last
|
89
|
+
raise LoadError, "can't find file for #{kind} `#{file}' (#{source_line.inspect})"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Sprockets
|
2
|
+
class Secretary
|
3
|
+
DEFAULT_OPTIONS = {
|
4
|
+
:root => ".",
|
5
|
+
:load_path => [],
|
6
|
+
:source_files => [],
|
7
|
+
:expand_paths => true
|
8
|
+
}
|
9
|
+
|
10
|
+
attr_reader :environment, :preprocessor
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
reset!(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset!(options = @options)
|
17
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
18
|
+
@environment = Sprockets::Environment.new(@options[:root])
|
19
|
+
@preprocessor = Sprockets::Preprocessor.new(@environment)
|
20
|
+
|
21
|
+
add_load_locations(@options[:load_path])
|
22
|
+
add_source_files(@options[:source_files])
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_load_location(load_location, options = {})
|
26
|
+
add_load_locations([load_location], options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_load_locations(load_locations, options = {})
|
30
|
+
expand_paths(load_locations, options).each do |load_location|
|
31
|
+
environment.register_load_location(load_location)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_source_file(source_file, options = {})
|
36
|
+
add_source_files([source_file], options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_source_files(source_files, options = {})
|
40
|
+
expand_paths(source_files, options).each do |source_file|
|
41
|
+
if pathname = environment.find(source_file)
|
42
|
+
preprocessor.require(pathname.source_file)
|
43
|
+
else
|
44
|
+
raise Sprockets::LoadError, "no such file `#{source_file}'"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def concatenation
|
50
|
+
preprocessor.concatenation
|
51
|
+
end
|
52
|
+
|
53
|
+
def install_assets
|
54
|
+
if @options[:asset_root]
|
55
|
+
preprocessor.asset_paths.each do |asset_path|
|
56
|
+
copy_assets_from(asset_path.absolute_location)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def source_last_modified
|
62
|
+
preprocessor.source_files.map { |s| s.mtime }.max
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
def expand_paths(paths, options = {})
|
67
|
+
if options.has_key?(:expand_paths) ? options[:expand_paths] : @options[:expand_paths]
|
68
|
+
paths.map { |path| Dir[from_root(path)].sort }.flatten.compact
|
69
|
+
else
|
70
|
+
paths.map { |path| from_root(path) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def from_root(path)
|
75
|
+
if Sprockets.absolute?(path)
|
76
|
+
path
|
77
|
+
else
|
78
|
+
File.join(@options[:root], path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def copy_assets_from(asset_path)
|
83
|
+
if File.directory?(asset_path)
|
84
|
+
relative_file_paths_beneath(asset_path).each do |filename|
|
85
|
+
source, destination = File.join(asset_path, filename), File.join(asset_root, File.dirname(filename))
|
86
|
+
if !File.directory?(source)
|
87
|
+
FileUtils.mkdir_p(destination)
|
88
|
+
FileUtils.cp(source, destination)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
else
|
92
|
+
FileUtils.cp(asset_path, asset_root)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def relative_file_paths_beneath(path)
|
97
|
+
Dir[File.join(path, "**", "*")].map do |filename|
|
98
|
+
File.join(*path_pieces(filename)[path_pieces(path).length..-1])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def asset_root
|
103
|
+
from_root(@options[:asset_root])
|
104
|
+
end
|
105
|
+
|
106
|
+
def path_pieces(path)
|
107
|
+
path.split(File::SEPARATOR)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|