sprockets 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprockets might be problematic. Click here for more details.
- data/LICENSE +21 -0
- data/README.md +356 -0
- data/lib/sprockets.rb +26 -37
- data/lib/sprockets/asset.rb +212 -0
- data/lib/sprockets/asset_attributes.rb +158 -0
- data/lib/sprockets/base.rb +163 -0
- data/lib/sprockets/bundled_asset.rb +258 -0
- data/lib/sprockets/cache/file_store.rb +41 -0
- data/lib/sprockets/caching.rb +123 -0
- data/lib/sprockets/charset_normalizer.rb +41 -0
- data/lib/sprockets/context.rb +217 -0
- data/lib/sprockets/digest.rb +67 -0
- data/lib/sprockets/directive_processor.rb +380 -0
- data/lib/sprockets/eco_template.rb +38 -0
- data/lib/sprockets/ejs_template.rb +37 -0
- data/lib/sprockets/engines.rb +98 -0
- data/lib/sprockets/environment.rb +81 -40
- data/lib/sprockets/errors.rb +17 -0
- data/lib/sprockets/index.rb +79 -0
- data/lib/sprockets/jst_processor.rb +26 -0
- data/lib/sprockets/mime.rb +38 -0
- data/lib/sprockets/processing.rb +280 -0
- data/lib/sprockets/processor.rb +32 -0
- data/lib/sprockets/safety_colons.rb +28 -0
- data/lib/sprockets/server.rb +272 -0
- data/lib/sprockets/static_asset.rb +86 -0
- data/lib/sprockets/trail.rb +114 -0
- data/lib/sprockets/utils.rb +67 -0
- data/lib/sprockets/version.rb +1 -7
- metadata +212 -64
- data/Rakefile +0 -19
- data/bin/sprocketize +0 -54
- data/ext/nph-sprockets.cgi +0 -127
- data/lib/sprockets/concatenation.rb +0 -36
- data/lib/sprockets/error.rb +0 -5
- data/lib/sprockets/pathname.rb +0 -37
- data/lib/sprockets/preprocessor.rb +0 -91
- data/lib/sprockets/secretary.rb +0 -106
- data/lib/sprockets/source_file.rb +0 -54
- data/lib/sprockets/source_line.rb +0 -82
- data/test/fixtures/assets/images/script_with_assets/one.png +0 -1
- data/test/fixtures/assets/images/script_with_assets/two.png +0 -1
- data/test/fixtures/assets/stylesheets/script_with_assets.css +0 -1
- data/test/fixtures/constants.yml +0 -1
- data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_ignored_when_strip_comments_is_false.js +0 -8
- data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_removed_by_default.js +0 -2
- data/test/fixtures/multiline_comments_should_be_removed_by_default.js +0 -4
- data/test/fixtures/requiring_a_file_after_it_has_already_been_required_should_do_nothing.js +0 -5
- data/test/fixtures/requiring_a_file_that_does_not_exist_should_raise_an_error.js +0 -1
- data/test/fixtures/requiring_a_single_file_should_replace_the_require_comment_with_the_file_contents.js +0 -3
- data/test/fixtures/requiring_the_current_file_should_do_nothing.js +0 -1
- data/test/fixtures/src/constants.yml +0 -3
- data/test/fixtures/src/foo.js +0 -1
- data/test/fixtures/src/foo/bar.js +0 -4
- data/test/fixtures/src/foo/foo.js +0 -1
- data/test/fixtures/src/script_with_assets.js +0 -3
- data/test/test_concatenation.rb +0 -28
- data/test/test_environment.rb +0 -64
- data/test/test_helper.rb +0 -55
- data/test/test_pathname.rb +0 -43
- data/test/test_preprocessor.rb +0 -107
- data/test/test_secretary.rb +0 -83
- data/test/test_source_file.rb +0 -34
- data/test/test_source_line.rb +0 -89
data/ext/nph-sprockets.cgi
DELETED
@@ -1,127 +0,0 @@
|
|
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
|
@@ -1,36 +0,0 @@
|
|
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
|
data/lib/sprockets/error.rb
DELETED
data/lib/sprockets/pathname.rb
DELETED
@@ -1,37 +0,0 @@
|
|
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
|
@@ -1,91 +0,0 @@
|
|
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
|
-
File.join(File.dirname(location), File.basename(location, ".js") + ".js")
|
79
|
-
end
|
80
|
-
|
81
|
-
def asset_path_from(source_line)
|
82
|
-
source_line.source_file.find(source_line.provide, :directory)
|
83
|
-
end
|
84
|
-
|
85
|
-
def raise_load_error_for(source_line)
|
86
|
-
kind = kind_of_require_from(source_line).to_s.tr("_", " ")
|
87
|
-
file = File.split(location_from(source_line)).last
|
88
|
-
raise LoadError, "can't find file for #{kind} `#{file}' (#{source_line.inspect})"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
data/lib/sprockets/secretary.rb
DELETED
@@ -1,106 +0,0 @@
|
|
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
|
-
relative_file_paths_beneath(asset_path).each do |filename|
|
84
|
-
source, destination = File.join(asset_path, filename), File.join(asset_root, File.dirname(filename))
|
85
|
-
if !File.directory?(source)
|
86
|
-
FileUtils.mkdir_p(destination)
|
87
|
-
FileUtils.cp(source, destination)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def relative_file_paths_beneath(path)
|
93
|
-
Dir[File.join(path, "**", "*")].map do |filename|
|
94
|
-
File.join(*path_pieces(filename)[path_pieces(path).length..-1])
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def asset_root
|
99
|
-
from_root(@options[:asset_root])
|
100
|
-
end
|
101
|
-
|
102
|
-
def path_pieces(path)
|
103
|
-
path.split(File::SEPARATOR)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module Sprockets
|
2
|
-
class SourceFile
|
3
|
-
attr_reader :environment, :pathname
|
4
|
-
|
5
|
-
def initialize(environment, pathname)
|
6
|
-
@environment = environment
|
7
|
-
@pathname = pathname
|
8
|
-
end
|
9
|
-
|
10
|
-
def source_lines
|
11
|
-
@lines ||= begin
|
12
|
-
lines = []
|
13
|
-
|
14
|
-
comments = []
|
15
|
-
File.open(pathname.absolute_location) do |file|
|
16
|
-
file.each do |line|
|
17
|
-
lines << line = SourceLine.new(self, line, file.lineno)
|
18
|
-
|
19
|
-
if line.begins_pdoc_comment? || comments.any?
|
20
|
-
comments << line
|
21
|
-
end
|
22
|
-
|
23
|
-
if line.ends_multiline_comment?
|
24
|
-
if line.ends_pdoc_comment?
|
25
|
-
comments.each { |l| l.comment! }
|
26
|
-
end
|
27
|
-
comments.clear
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
lines
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def each_source_line(&block)
|
37
|
-
source_lines.each(&block)
|
38
|
-
end
|
39
|
-
|
40
|
-
def find(location, kind = :file)
|
41
|
-
pathname.parent_pathname.find(location, kind)
|
42
|
-
end
|
43
|
-
|
44
|
-
def ==(source_file)
|
45
|
-
pathname == source_file.pathname
|
46
|
-
end
|
47
|
-
|
48
|
-
def mtime
|
49
|
-
File.mtime(pathname.absolute_location)
|
50
|
-
rescue Errno::ENOENT
|
51
|
-
Time.now
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|