sprockets 2.1.0 → 2.2.3

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.

checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: be373494a4e64c06e55a9ad11e2c9efae09f1492
4
+ data.tar.gz: b683ce4b0ed64e683ea98d0b5af268bdeca3f584
5
+ SHA512:
6
+ metadata.gz: fa430704b4ef87304b8a128cb83fbb64c66e24d0bdae3d9e9e343bbebd56bf8823f65cba4a0ad1eb33204308c814910ebdd9c2b570c33fbbf89a2fadd2383b33
7
+ data.tar.gz: 785eb7a9f36afa38e6f010a573240768a9620ed216f4b20614835ffe9564d258a0e5340c9e8dbf3b538e8b960d9f7fd22342581b5e597dbbfc4e892bac7f7d3a
data/README.md CHANGED
@@ -354,9 +354,26 @@ submit a pull request.
354
354
 
355
355
  ## Version History ##
356
356
 
357
+ **2.2.0** (Unreleased)
358
+
359
+ * Added `sprockets` command line utility.
360
+ * Added rake/sprocketstask.
361
+ * Added json manifest log of compiled assets.
362
+ * Added `stub` directive that allows you to exclude files from the bundle.
363
+ * Added per environment external encoding (Environment#default_external_encoding). Defaults to UTF-8. Fixes issues where LANG is not set correctly and Rubys default external is set to ASCII.
364
+
365
+ **2.1.2** (November 20, 2011)
366
+
367
+ * Disabled If-Modified-Since server checks. Fixes some browser caching issues when serving the asset body only. If-None-Match caching is sufficent.
368
+
369
+ **2.1.1** (November 18, 2011)
370
+
371
+ * Fix windows absolute path check bug.
372
+
357
373
  **2.1.0** (November 11, 2011)
358
374
 
359
- * Preserve directive whitespace.
375
+ * Directive comment lines are now turned into empty lines instead of removed. This way line numbers in
376
+ CoffeeScript syntax errors are correct.
360
377
  * Performance and caching bug fixes.
361
378
 
362
379
  **2.0.3** (October 17, 2011)
data/bin/sprockets ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sprockets'
4
+ require 'optparse'
5
+ require 'shellwords'
6
+
7
+ unless ARGV.delete("--noenv")
8
+ if File.exist?(path = "./.sprocketsrc")
9
+ rcflags = Shellwords.split(File.read(path))
10
+ ARGV.unshift(*rcflags)
11
+ end
12
+ end
13
+
14
+ filenames = []
15
+ environment = Sprockets::Environment.new(Dir.pwd)
16
+ manifest = nil
17
+
18
+ (ENV['SPROCKETS_PATH'] || "").split(File::PATH_SEPARATOR).each do |path|
19
+ environment.append_path path
20
+ end
21
+
22
+ OptionParser.new do |opts|
23
+ opts.summary_width = 28
24
+ opts.banner = "Usage: sprockets [options] filename [filename ...]"
25
+
26
+ def opts.show_usage
27
+ puts self
28
+ exit 1
29
+ end
30
+
31
+ opts.on("-r", "--require LIBRARY", "Require the LIBRARY before doing anything") do |lib|
32
+ require lib
33
+ end
34
+
35
+ opts.on("-I DIRECTORY", "--include=DIRECTORY", "Adds the directory to the Sprockets load path") do |directory|
36
+ environment.append_path directory
37
+ end
38
+
39
+ opts.on("-o DIRECTORY", "--output=DIRECTORY", "Copy provided assets into DIRECTORY") do |directory|
40
+ manifest = Sprockets::Manifest.new(environment, directory)
41
+ end
42
+
43
+ opts.on("--noenv", "Disables .sprocketsrc file") do
44
+ end
45
+
46
+ opts.on_tail("-h", "--help", "Shows this help message") do
47
+ opts.show_usage
48
+ end
49
+
50
+ opts.on_tail("-v", "--version", "Shows version") do
51
+ puts Sprockets::VERSION
52
+ exit
53
+ end
54
+
55
+ opts.show_usage if ARGV.empty?
56
+
57
+ begin
58
+ opts.order(ARGV) do |filename|
59
+ filenames << File.expand_path(filename)
60
+ end
61
+ rescue OptionParser::ParseError => e
62
+ opts.warn e.message
63
+ opts.show_usage
64
+ end
65
+ end
66
+
67
+ if environment.paths.empty?
68
+ warn "No load paths given"
69
+ warn "Usage: sprockets -Ijavascripts/ filename"
70
+ exit 1
71
+ end
72
+
73
+ if manifest
74
+ manifest.compile(filenames)
75
+ elsif filenames.length == 1
76
+ puts environment.find_asset(filenames.first).to_s
77
+ else
78
+ warn "Only one file can be compiled to stdout at a time"
79
+ exit 1
80
+ end
@@ -0,0 +1,140 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ require 'sprockets'
5
+ require 'logger'
6
+
7
+ module Rake
8
+ # Simple Sprockets compilation Rake task macro.
9
+ #
10
+ # Rake::SprocketsTask.new do |t|
11
+ # t.environment = Sprockets::Environment.new
12
+ # t.output = "./public/assets"
13
+ # t.assets = %w( application.js application.css )
14
+ # end
15
+ #
16
+ class SprocketsTask < Rake::TaskLib
17
+ # Name of the task. Defaults to "assets".
18
+ #
19
+ # The name will also be used to suffix the clean and clobber
20
+ # tasks, "clean_assets" and "clobber_assets".
21
+ attr_accessor :name
22
+
23
+ # `Environment` instance used for finding assets.
24
+ #
25
+ # You'll most likely want to reassign `environment` to your own.
26
+ #
27
+ # Rake::SprocketsTask.new do |t|
28
+ # t.environment = Foo::Assets
29
+ # end
30
+ #
31
+ def environment
32
+ if !@environment.is_a?(Sprockets::Base) && @environment.respond_to?(:call)
33
+ @environment = @environment.call
34
+ else
35
+ @environment
36
+ end
37
+ end
38
+ attr_writer :environment
39
+
40
+ # Directory to write compiled assets too. As well as the manifest file.
41
+ #
42
+ # t.output = "./public/assets"
43
+ #
44
+ attr_accessor :output
45
+
46
+ # Array of asset logical paths to compile.
47
+ #
48
+ # t.assets = %w( application.js jquery.js application.css )
49
+ #
50
+ attr_accessor :assets
51
+
52
+ # Number of old assets to keep.
53
+ attr_accessor :keep
54
+
55
+ # Logger to use during rake tasks. Defaults to using stderr.
56
+ #
57
+ # t.logger = Logger.new($stdout)
58
+ #
59
+ attr_accessor :logger
60
+
61
+ # Returns logger level Integer.
62
+ def log_level
63
+ @logger.level
64
+ end
65
+
66
+ # Set logger level with constant or symbol.
67
+ #
68
+ # t.log_level = Logger::INFO
69
+ # t.log_level = :debug
70
+ #
71
+ def log_level=(level)
72
+ if level.is_a?(Integer)
73
+ @logger.level = level
74
+ else
75
+ @logger.level = Logger.const_get(level.to_s.upcase)
76
+ end
77
+ end
78
+
79
+ def initialize(name = :assets)
80
+ @name = name
81
+ @environment = lambda { Sprockets::Environment.new(Dir.pwd) }
82
+ @logger = Logger.new($stderr)
83
+ @logger.level = Logger::INFO
84
+ @keep = 2
85
+
86
+ yield self if block_given?
87
+
88
+ define
89
+ end
90
+
91
+ # Define tasks
92
+ def define
93
+ desc name == :assets ? "Compile assets" : "Compile #{name} assets"
94
+ task name do
95
+ with_logger do
96
+ manifest.compile(assets)
97
+ end
98
+ end
99
+
100
+ desc name == :assets ? "Remove all assets" : "Remove all #{name} assets"
101
+ task "clobber_#{name}" do
102
+ with_logger do
103
+ manifest.clobber
104
+ end
105
+ end
106
+
107
+ task :clobber => ["clobber_#{name}"]
108
+
109
+ desc name == :assets ? "Clean old assets" : "Clean old #{name} assets"
110
+ task "clean_#{name}" do
111
+ with_logger do
112
+ manifest.clean(keep)
113
+ end
114
+ end
115
+
116
+ task :clean => ["clean_#{name}"]
117
+ end
118
+
119
+ private
120
+ # Returns cached indexed environment
121
+ def index
122
+ @index ||= environment.index
123
+ end
124
+
125
+ # Returns manifest for tasks
126
+ def manifest
127
+ @manifest ||= Sprockets::Manifest.new(index, output)
128
+ end
129
+
130
+ # Sub out environment logger with our rake task logger that
131
+ # writes to stderr.
132
+ def with_logger
133
+ old_logger = index.logger
134
+ index.logger = @logger
135
+ yield
136
+ ensure
137
+ index.logger = old_logger
138
+ end
139
+ end
140
+ end
data/lib/sprockets.rb CHANGED
@@ -6,6 +6,7 @@ module Sprockets
6
6
  autoload :Engines, "sprockets/engines"
7
7
  autoload :Environment, "sprockets/environment"
8
8
  autoload :Index, "sprockets/index"
9
+ autoload :Manifest, "sprockets/manifest"
9
10
 
10
11
  # Assets
11
12
  autoload :Asset, "sprockets/asset"
@@ -138,6 +138,8 @@ module Sprockets
138
138
  # Gzip contents if filename has '.gz'
139
139
  options[:compress] ||= File.extname(filename) == '.gz'
140
140
 
141
+ FileUtils.mkdir_p File.dirname(filename)
142
+
141
143
  File.open("#{filename}+", 'wb') do |f|
142
144
  if options[:compress]
143
145
  # Run contents through `Zlib`
@@ -103,6 +103,12 @@ module Sprockets
103
103
  raise NotImplementedError
104
104
  end
105
105
 
106
+ if defined? Encoding.default_external
107
+ # Define `default_external_encoding` accessor on 1.9.
108
+ # Defaults to UTF-8.
109
+ attr_accessor :default_external_encoding
110
+ end
111
+
106
112
  # Works like `Dir.entries`.
107
113
  #
108
114
  # Subclasses may cache this method.
@@ -149,7 +155,7 @@ module Sprockets
149
155
  logical_path = path
150
156
  pathname = Pathname.new(path)
151
157
 
152
- if pathname.to_s =~ /^\//
158
+ if pathname.absolute?
153
159
  return unless stat(pathname)
154
160
  logical_path = attributes_for(pathname).logical_path
155
161
  else
@@ -204,13 +210,15 @@ module Sprockets
204
210
  nil
205
211
  end
206
212
 
207
- def each_logical_path
208
- return to_enum(__method__) unless block_given?
213
+ def each_logical_path(*args)
214
+ return to_enum(__method__, *args) unless block_given?
215
+ filters = args.flatten
209
216
  files = {}
210
217
  each_file do |filename|
211
- logical_path = attributes_for(filename).logical_path
212
- yield logical_path unless files[logical_path]
213
- files[logical_path] = true
218
+ if logical_path = logical_path_for_filename(filename, filters)
219
+ yield logical_path unless files[logical_path]
220
+ files[logical_path] = true
221
+ end
214
222
  end
215
223
  nil
216
224
  end
@@ -263,5 +271,37 @@ module Sprockets
263
271
  ensure
264
272
  Thread.current[:sprockets_circular_calls] = nil if reset
265
273
  end
274
+
275
+ def logical_path_for_filename(filename, filters)
276
+ logical_path = attributes_for(filename).logical_path.to_s
277
+
278
+ if matches_filter(filters, logical_path)
279
+ return logical_path
280
+ end
281
+
282
+ # If filename is an index file, retest with alias
283
+ if File.basename(logical_path)[/[^\.]+/, 0] == 'index'
284
+ path = logical_path.sub(/\/index\./, '.')
285
+ if matches_filter(filters, path)
286
+ return path
287
+ end
288
+ end
289
+
290
+ nil
291
+ end
292
+
293
+ def matches_filter(filters, filename)
294
+ return true if filters.empty?
295
+
296
+ filters.any? do |filter|
297
+ if filter.is_a?(Regexp)
298
+ filter.match(filename)
299
+ elsif filter.respond_to?(:call)
300
+ filter.call(filename)
301
+ else
302
+ File.fnmatch(filter.to_s, filename)
303
+ end
304
+ end
305
+ end
266
306
  end
267
307
  end
@@ -6,14 +6,11 @@ module Sprockets
6
6
  module Cache
7
7
  # A simple file system cache store.
8
8
  #
9
- # environment.cache = Sprockets::Cache::FileStore.new("tmp/sprockets")
9
+ # environment.cache = Sprockets::Cache::FileStore.new("/tmp")
10
10
  #
11
11
  class FileStore
12
12
  def initialize(root)
13
13
  @root = Pathname.new(root)
14
-
15
- # Ensure directory exists
16
- FileUtils.mkdir_p @root
17
14
  end
18
15
 
19
16
  # Lookup value in cache
@@ -24,6 +21,9 @@ module Sprockets
24
21
 
25
22
  # Save value to cache
26
23
  def []=(key, value)
24
+ # Ensure directory exists
25
+ FileUtils.mkdir_p @root.join(key).dirname
26
+
27
27
  @root.join(key).open('w') { |f| Marshal.dump(value, f)}
28
28
  value
29
29
  end
@@ -11,7 +11,7 @@ module Sprockets
11
11
  # helpers by injecting them into `Environment#context_class`. Do not
12
12
  # mix them into `Context` directly.
13
13
  #
14
- # environment.instance_eval do
14
+ # environment.context_class.class_eval do
15
15
  # include MyHelper
16
16
  # def asset_url; end
17
17
  # end
@@ -22,7 +22,8 @@ module Sprockets
22
22
  # assets. See `DirectiveProcessor` for an example of this.
23
23
  class Context
24
24
  attr_reader :environment, :pathname
25
- attr_reader :_required_paths, :_dependency_paths, :_dependency_assets
25
+ attr_reader :_required_paths, :_stubbed_assets
26
+ attr_reader :_dependency_paths, :_dependency_assets
26
27
  attr_writer :__LINE__
27
28
 
28
29
  def initialize(environment, logical_path, pathname)
@@ -32,6 +33,7 @@ module Sprockets
32
33
  @__LINE__ = nil
33
34
 
34
35
  @_required_paths = []
36
+ @_stubbed_assets = Set.new
35
37
  @_dependency_paths = Set.new
36
38
  @_dependency_assets = Set.new([pathname.to_s])
37
39
  end
@@ -78,7 +80,7 @@ module Sprockets
78
80
  pathname = Pathname.new(path)
79
81
  attributes = environment.attributes_for(pathname)
80
82
 
81
- if pathname.to_s =~ /^\//
83
+ if pathname.absolute?
82
84
  pathname
83
85
 
84
86
  elsif content_type = options[:content_type]
@@ -143,6 +145,14 @@ module Sprockets
143
145
  nil
144
146
  end
145
147
 
148
+ # `stub_asset` blacklists `path` from being included in the bundle.
149
+ # `path` must be an asset which may or may not already be included
150
+ # in the bundle.
151
+ def stub_asset(path)
152
+ @_stubbed_assets << resolve(path, :content_type => :self).to_s
153
+ nil
154
+ end
155
+
146
156
  # Tests if target path is able to be safely required into the
147
157
  # current concatenation.
148
158
  def asset_requirable?(path)
@@ -168,7 +178,13 @@ module Sprockets
168
178
  if options[:data]
169
179
  result = options[:data]
170
180
  else
171
- result = Sprockets::Utils.read_unicode(pathname)
181
+ if environment.respond_to?(:default_external_encoding)
182
+ mime_type = environment.mime_types(pathname.extname)
183
+ encoding = environment.encoding_for_mime_type(mime_type)
184
+ result = Sprockets::Utils.read_unicode(pathname, encoding)
185
+ else
186
+ result = Sprockets::Utils.read_unicode(pathname)
187
+ end
172
188
  end
173
189
 
174
190
  processors.each do |processor|