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.

Files changed (64) hide show
  1. data/LICENSE +21 -0
  2. data/README.md +356 -0
  3. data/lib/sprockets.rb +26 -37
  4. data/lib/sprockets/asset.rb +212 -0
  5. data/lib/sprockets/asset_attributes.rb +158 -0
  6. data/lib/sprockets/base.rb +163 -0
  7. data/lib/sprockets/bundled_asset.rb +258 -0
  8. data/lib/sprockets/cache/file_store.rb +41 -0
  9. data/lib/sprockets/caching.rb +123 -0
  10. data/lib/sprockets/charset_normalizer.rb +41 -0
  11. data/lib/sprockets/context.rb +217 -0
  12. data/lib/sprockets/digest.rb +67 -0
  13. data/lib/sprockets/directive_processor.rb +380 -0
  14. data/lib/sprockets/eco_template.rb +38 -0
  15. data/lib/sprockets/ejs_template.rb +37 -0
  16. data/lib/sprockets/engines.rb +98 -0
  17. data/lib/sprockets/environment.rb +81 -40
  18. data/lib/sprockets/errors.rb +17 -0
  19. data/lib/sprockets/index.rb +79 -0
  20. data/lib/sprockets/jst_processor.rb +26 -0
  21. data/lib/sprockets/mime.rb +38 -0
  22. data/lib/sprockets/processing.rb +280 -0
  23. data/lib/sprockets/processor.rb +32 -0
  24. data/lib/sprockets/safety_colons.rb +28 -0
  25. data/lib/sprockets/server.rb +272 -0
  26. data/lib/sprockets/static_asset.rb +86 -0
  27. data/lib/sprockets/trail.rb +114 -0
  28. data/lib/sprockets/utils.rb +67 -0
  29. data/lib/sprockets/version.rb +1 -7
  30. metadata +212 -64
  31. data/Rakefile +0 -19
  32. data/bin/sprocketize +0 -54
  33. data/ext/nph-sprockets.cgi +0 -127
  34. data/lib/sprockets/concatenation.rb +0 -36
  35. data/lib/sprockets/error.rb +0 -5
  36. data/lib/sprockets/pathname.rb +0 -37
  37. data/lib/sprockets/preprocessor.rb +0 -91
  38. data/lib/sprockets/secretary.rb +0 -106
  39. data/lib/sprockets/source_file.rb +0 -54
  40. data/lib/sprockets/source_line.rb +0 -82
  41. data/test/fixtures/assets/images/script_with_assets/one.png +0 -1
  42. data/test/fixtures/assets/images/script_with_assets/two.png +0 -1
  43. data/test/fixtures/assets/stylesheets/script_with_assets.css +0 -1
  44. data/test/fixtures/constants.yml +0 -1
  45. data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_ignored_when_strip_comments_is_false.js +0 -8
  46. data/test/fixtures/double_slash_comments_that_are_not_requires_should_be_removed_by_default.js +0 -2
  47. data/test/fixtures/multiline_comments_should_be_removed_by_default.js +0 -4
  48. data/test/fixtures/requiring_a_file_after_it_has_already_been_required_should_do_nothing.js +0 -5
  49. data/test/fixtures/requiring_a_file_that_does_not_exist_should_raise_an_error.js +0 -1
  50. data/test/fixtures/requiring_a_single_file_should_replace_the_require_comment_with_the_file_contents.js +0 -3
  51. data/test/fixtures/requiring_the_current_file_should_do_nothing.js +0 -1
  52. data/test/fixtures/src/constants.yml +0 -3
  53. data/test/fixtures/src/foo.js +0 -1
  54. data/test/fixtures/src/foo/bar.js +0 -4
  55. data/test/fixtures/src/foo/foo.js +0 -1
  56. data/test/fixtures/src/script_with_assets.js +0 -3
  57. data/test/test_concatenation.rb +0 -28
  58. data/test/test_environment.rb +0 -64
  59. data/test/test_helper.rb +0 -55
  60. data/test/test_pathname.rb +0 -43
  61. data/test/test_preprocessor.rb +0 -107
  62. data/test/test_secretary.rb +0 -83
  63. data/test/test_source_file.rb +0 -34
  64. data/test/test_source_line.rb +0 -89
@@ -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
@@ -1,5 +0,0 @@
1
- module Sprockets
2
- class Error < ::StandardError; end
3
- class LoadError < Error; end
4
- class UndefinedConstantError < Error; end
5
- end
@@ -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
@@ -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