glebtv-compass-rails 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +22 -0
  4. data/CHANGELOG.md +71 -0
  5. data/Gemfile +17 -0
  6. data/LICENSE +22 -0
  7. data/README.md +97 -0
  8. data/Rakefile +25 -0
  9. data/gemfiles/rails31.gemfile +18 -0
  10. data/gemfiles/rails32.gemfile +18 -0
  11. data/gemfiles/rails40.gemfile +18 -0
  12. data/gemfiles/rails42.gemfile +18 -0
  13. data/glebtv-compass-rails.gemspec +21 -0
  14. data/lib/compass-rails.rb +107 -0
  15. data/lib/compass-rails/configuration.rb +77 -0
  16. data/lib/compass-rails/patches.rb +33 -0
  17. data/lib/compass-rails/patches/compass.rb +12 -0
  18. data/lib/compass-rails/patches/importer.rb +24 -0
  19. data/lib/compass-rails/patches/sass_importer.rb +90 -0
  20. data/lib/compass-rails/patches/sprite_importer.rb +30 -0
  21. data/lib/compass-rails/patches/static_compiler.rb +12 -0
  22. data/lib/compass-rails/railtie.rb +51 -0
  23. data/lib/compass-rails/version.rb +5 -0
  24. data/lib/glebtv-compass-rails.rb +1 -0
  25. data/test/compass_rails_spec.rb +39 -0
  26. data/test/fixtures/.gitkeep +0 -0
  27. data/test/fixtures/assets/images/letters/a.png +0 -0
  28. data/test/fixtures/assets/images/letters/b.png +0 -0
  29. data/test/fixtures/assets/images/numbers/sprite-1.png +0 -0
  30. data/test/fixtures/assets/images/numbers/sprite-2.png +0 -0
  31. data/test/fixtures/assets/stylesheets/application.css.scss +23 -0
  32. data/test/fixtures/assets/stylesheets/partials/_partial_1.scss +3 -0
  33. data/test/fixtures/assets/stylesheets/partials/_partial_2.scss +3 -0
  34. data/test/helpers/command_helper.rb +105 -0
  35. data/test/helpers/debug_helper.rb +12 -0
  36. data/test/helpers/file_helper.rb +38 -0
  37. data/test/helpers/rails_helper.rb +53 -0
  38. data/test/helpers/rails_project.rb +76 -0
  39. data/test/test_helper.rb +20 -0
  40. metadata +128 -0
@@ -0,0 +1,77 @@
1
+ module CompassRails
2
+ module Configuration
3
+ def default_images_dir
4
+ File.join("app", "assets", "images")
5
+ end
6
+
7
+ def default_fonts_dir
8
+ File.join("app", "assets", "fonts")
9
+ end
10
+
11
+ def default_javascripts_dir
12
+ File.join("app", "assets", "javascripts")
13
+ end
14
+
15
+ def default_css_dir
16
+ File.join('public', CompassRails.prefix)
17
+ end
18
+
19
+ def default_http_path
20
+ File.join(CompassRails.prefix)
21
+ end
22
+
23
+ def default_http_images_path
24
+ "#{top_level.http_path}"
25
+ end
26
+
27
+ def default_http_javascripts_path
28
+ "#{top_level.http_path}"
29
+ end
30
+
31
+ def default_http_fonts_path
32
+ "#{top_level.http_path}"
33
+ end
34
+
35
+ def default_http_stylesheets_path
36
+ "#{top_level.http_path}"
37
+ end
38
+
39
+ def default_preferred_syntax
40
+ ::Rails.application.config.sass.preferred_syntax rescue nil
41
+ end
42
+
43
+ def default_sprite_load_path
44
+ CompassRails.sprockets.paths
45
+ end
46
+
47
+ def project_type_without_default
48
+ :rails
49
+ end
50
+
51
+ def default_sass_dir
52
+ File.join("app", "assets", "stylesheets")
53
+ end
54
+
55
+ def default_http_generated_images_path
56
+ # Relies on the fact that this will be loaded after the "normal"
57
+ # defaults, so that method_missing finds http_root_relative
58
+ http_root_relative "images"
59
+ end
60
+
61
+ def default_extensions_dir
62
+ File.join("vendor", "plugins", "compass_extensions")
63
+ end
64
+
65
+ def default_cache_dir
66
+ File.join("tmp", "sass-cache")
67
+ end
68
+
69
+ def default_project_path
70
+ Rails.root
71
+ end
72
+
73
+ def default_environment
74
+ Rails.env
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,33 @@
1
+ require 'compass-rails/patches/compass'
2
+ require 'compass-rails/patches/sass_importer'
3
+ require 'compass-rails/patches/sprite_importer'
4
+
5
+ Compass::Core::SassExtensions::Functions::Urls::GeneratedImageUrl.module_eval do
6
+ def generated_image_url(path, cache_buster = Sass::Script::Bool.new(false))
7
+ cachebust_generated_images(path)
8
+ asset_url(path)
9
+ end
10
+
11
+ def cachebust_generated_images(path)
12
+ generated_images_dir = Compass.configuration.generated_images_dir
13
+ generated_images_dir = Rails.root.join(generated_images_dir)
14
+
15
+ sprockets_env = options[:sprockets][:environment]
16
+ sprockets_entries = sprockets_env.instance_variable_get(:@entries) || {}
17
+ sprockets_stats = sprockets_env.instance_variable_get(:@stats) || {}
18
+
19
+ if sprockets_entries.key?(generated_images_dir.to_s)
20
+ path = path.value
21
+ dir = File.dirname(path)
22
+
23
+ # Delete the entries (directories) which cache the files/dirs in a directory
24
+ entry = generated_images_dir.join(dir).to_s
25
+ sprockets_entries.delete(entry)
26
+
27
+ # Delete the stats (file/dir info) which cache the what kind of file/dir each image is
28
+ stat = generated_images_dir.join(path).to_s
29
+ sprockets_stats.delete(stat)
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,12 @@
1
+ Compass::Core::SassExtensions::Functions::ImageSize.class_eval do
2
+ private
3
+
4
+ def image_path_for_size(image_file)
5
+ begin
6
+ file = ::Rails.application.assets.find_asset(image_file)
7
+ return file.filename
8
+ rescue ::Sprockets::FileOutsidePaths
9
+ return super(image_file)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ require 'compass/compiler'
2
+ module Compass
3
+ class Compiler
4
+ attr_accessor :sass_options
5
+ STYLESHEET = /stylesheet/
6
+ def sass_options
7
+ @sass_options[:custom] ||= {}
8
+ @sass_options[:custom] = {:resolver => ::Sass::Rails::Resolver.new(CompassRails.context)}
9
+ @sass_options[:load_paths] ||= []
10
+ unless @sass_options[:load_paths].any? {|k| k.is_a?(::Sass::Rails::Importer) }
11
+ ::Rails.application.assets.paths.each do |path|
12
+ next unless path.to_s =~ STYLESHEET
13
+ Dir["#{path}/**/*"].each do |pathname|
14
+ # args are: sprockets environment, the logical_path ex. 'stylesheets', and the full path name for the render
15
+ context = ::CompassRails.context.new(::Rails.application.assets, File.basename(path), Pathname.new(pathname))
16
+ @sass_options[:load_paths] << ::Sass::Rails::Importer.new(context)
17
+ end
18
+ end
19
+ end
20
+ @sass_options
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,90 @@
1
+ klass = if defined?(Sass::Rails::SassTemplate)
2
+ Sass::Rails::SassTemplate
3
+ else
4
+ Sprockets::SassTemplate
5
+ end
6
+
7
+ klass.class_eval do
8
+ def evaluate(context, locals, &block)
9
+ # Use custom importer that knows about Sprockets Caching
10
+ cache_store = Sprockets::SassProcessor::CacheStore.new(sprockets_cache_store, context.environment)
11
+
12
+ paths = context.environment.paths.map { |path| CompassRails::SpriteImporter.new(path) }
13
+ paths += context.environment.paths.map { |path| sass_importer(context, path) }
14
+ paths += ::Rails.application.config.sass.load_paths
15
+
16
+ options = CompassRails.sass_config.merge( {
17
+ :filename => eval_file,
18
+ :line => line,
19
+ :syntax => syntax,
20
+ :cache_store => cache_store,
21
+ :importer => sass_importer(context, context.pathname),
22
+ :load_paths => paths,
23
+ :sprockets => {
24
+ :context => context,
25
+ :environment => context.environment
26
+ }
27
+ })
28
+
29
+ engine = ::Sass::Engine.new(data, options)
30
+
31
+ engine.dependencies.map do |dependency|
32
+ filename = dependency.options[:filename]
33
+ if filename.include?('*') # Handle sprite globs
34
+ image_path = Rails.root.join(Compass.configuration.images_dir).to_s
35
+ Dir[File.join(image_path, filename)].each do |f|
36
+ context.depend_on(f)
37
+ end
38
+ else
39
+ context.depend_on(filename)
40
+ end
41
+ end
42
+
43
+ engine.render
44
+ rescue ::Sass::SyntaxError => e
45
+ # Annotates exception message with parse line number
46
+ context.__LINE__ = e.sass_backtrace.first[:line]
47
+ raise e
48
+ end
49
+
50
+ private
51
+
52
+ def sass_importer_artiy
53
+ @sass_importer_artiy ||= sass_importer_class.instance_method(:initialize).arity
54
+ end
55
+
56
+ def sass_importer(context, path)
57
+ case sass_importer_artiy.abs
58
+ when 1
59
+ sass_importer_class.new(path)
60
+ else
61
+ sass_importer_class.new(context, path)
62
+ end
63
+ end
64
+
65
+ # if using haml-rails, self.class.parent = Haml::Filters (which doesn't have an implementation)
66
+ def sass_importer_class
67
+ @sass_importer_class ||= if defined?(self.class.parent::SassImporter)
68
+ self.class.parent::SassImporter
69
+ elsif defined?(Sass::Rails::SassTemplate)
70
+ Sass::Rails::SassImporter
71
+ else
72
+ Sprockets::SassImporter
73
+ end
74
+ end
75
+
76
+ def sprockets_cache_store
77
+ cache = case Rails.application.config.assets.cache_store
78
+ when :null_store
79
+ Sprockets::Cache::NullStore.new
80
+ when :memory_store, :mem_cache_store
81
+ Sprockets::Cache::MemoryStore.new
82
+ else
83
+ tmpd = Rails.root.join("tmp/compass").to_s
84
+ FileUtils.mkdir(tmpd) unless File.directory?(tmpd)
85
+ Sprockets::Cache::FileStore.new(tmpd)
86
+ end
87
+
88
+ Sprockets::Cache.new(cache, Rails.logger)
89
+ end
90
+ end
@@ -0,0 +1,30 @@
1
+ require 'sprockets'
2
+ require 'compass/sprite_importer'
3
+
4
+ module CompassRails
5
+ class SpriteImporter < Compass::SpriteImporter
6
+ attr_reader :root
7
+
8
+ def initialize(root)
9
+ @root = root
10
+ end
11
+
12
+ def find(uri, options)
13
+ if old = super(uri, options)
14
+ context = options[:sprockets][:context]
15
+ files = self.class.files(uri)
16
+ files.each do |file|
17
+ relative_path = Pathname.new(file).relative_path_from(Pathname.new(root))
18
+ begin
19
+ pathname = context.resolve(relative_path.to_s)
20
+ context.depend_on_asset(pathname)
21
+ rescue Sprockets::FileNotFound
22
+
23
+ end
24
+ end
25
+ end
26
+
27
+ old
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ require 'sprockets/static_compiler'
2
+ module Sprockets
3
+ class StaticCompiler
4
+ cattr_accessor :generated_sprites
5
+ self.generated_sprites = {}
6
+ def write_manifest_with_sprites(manifest)
7
+ write_manifest_without_sprites(manifest.merge(self.class.generated_sprites))
8
+ end
9
+ alias_method_chain :write_manifest, :sprites
10
+ end
11
+ end
12
+
@@ -0,0 +1,51 @@
1
+ module CompassRails
2
+ class Railtie < Rails::Railtie
3
+
4
+ initializer "compass.initialize_rails", :group => :all do |app|
5
+ require 'compass'
6
+ Compass.discover_extensions!
7
+ CompassRails.configure_rails!(app)
8
+ end
9
+
10
+ config.compass = begin
11
+ @compass ||= begin
12
+ data = if (config_file = Compass.detect_configuration_file) && (config_data = Compass.configuration_for(config_file))
13
+ config_data
14
+ else
15
+ Compass::Configuration::Data.new("rails_config")
16
+ end
17
+ data.project_type = :rails # Forcing this makes sure all the rails defaults will be loaded.
18
+ Compass.add_configuration(:rails)
19
+ Compass.add_configuration(data)
20
+ Compass.configuration.on_sprite_saved do |filename|
21
+ if Rails.application.config.assets.digest && # if digesting is enabled
22
+ caller.grep(%r{/sprockets/rails/task.rb}).any? && #OMG HAX - check if we're being precompiled
23
+ Compass.configuration.generated_images_path[Compass.configuration.images_path.to_s]
24
+ # if the generated images path is not in the assets images directory, we don't have to do these backflips
25
+
26
+ # Clear entries in Hike::Index for this sprite's directory.
27
+ # This makes sure the asset can be found by find_assets
28
+ index = Rails.application.assets.index
29
+ index.instance_variable_get(:@entries).delete(File.dirname(filename))
30
+ index.instance_variable_get(:@stats).delete(filename)
31
+
32
+ pathname = Pathname.new(filename)
33
+ logical_path = pathname.relative_path_from(Pathname.new(Compass.configuration.images_path))
34
+ asset = Rails.application.assets.find_asset(logical_path)
35
+ target = File.join(Rails.public_path, Rails.application.config.assets.prefix, asset.digest_path)
36
+
37
+ # Adds the asset to the manifest file.
38
+ manifest = ActionView::Base.assets_manifest
39
+ manifest.assets[logical_path.to_s] = asset.digest_path
40
+
41
+ # Adds the fingerprinted asset to the public directory
42
+ FileUtils.mkdir_p File.dirname(target)
43
+ asset.write_to target
44
+ end
45
+ end
46
+ data
47
+ end
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,5 @@
1
+ module CompassRails
2
+ unless defined?(::CompassRails::VERSION)
3
+ VERSION = "2.0.4"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require 'compass-rails'
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ describe CompassRails do
4
+ include CompassRails::Test::RailsHelpers
5
+
6
+ it "compiles a basic compass stylesheet" do
7
+ within_rails_app('test_railtie') do |project|
8
+ project.setup_asset_fixtures!
9
+
10
+ assert project.boots?
11
+
12
+ project.precompile!
13
+
14
+ project.compiled_stylesheet 'public/assets/application*.css' do |css|
15
+ refute css.empty?
16
+ assert_match 'body container', css
17
+ assert_match "-webkit-linear-gradient", css
18
+ assert_match "-moz-border-radius", css
19
+ assert_match '.numbers-sprite-1', css
20
+ assert_match '.numbers-sprite-2', css
21
+ assert_match '.letters-a', css
22
+ assert_match '.letters-a', css
23
+ end
24
+ end
25
+ end
26
+
27
+ it "supports rails config arguments" do
28
+ within_rails_app('test_railtie') do |project|
29
+ assert_equal "scss", project.rails_property("sass.preferred_syntax")
30
+ assert_equal "public/assets", project.rails_property("compass.css_dir")
31
+
32
+ project.set_rails('sass.preferred_syntax', :sass)
33
+ project.set_rails('compass.css_dir', "public/stylesheets")
34
+
35
+ assert_equal "sass", project.rails_property("sass.preferred_syntax")
36
+ assert_equal "public/stylesheets", project.rails_property("compass.css_dir")
37
+ end
38
+ end unless ENV['DEBUG_COMPILE']
39
+ end
File without changes
@@ -0,0 +1,23 @@
1
+ // Import Compass
2
+ @import "compass";
3
+
4
+ // Glob import SCSS partials
5
+ @import "partials/*";
6
+
7
+ // Import Sprites
8
+ @import "letters/*.png";
9
+ @include all-letters-sprites;
10
+
11
+ // Inline Sprites
12
+ $numbers-inline: true;
13
+ @import "numbers/sprite-*.png";
14
+ @include all-numbers-sprites;
15
+
16
+ // Try out some compass stuff
17
+ body{
18
+ @include background-image(linear-gradient(white, #aaaaaa));
19
+
20
+ container{
21
+ @include border-radius(4px, 4px);
22
+ }
23
+ }
@@ -0,0 +1,3 @@
1
+ .partial1 {
2
+ display: none;
3
+ }
@@ -0,0 +1,3 @@
1
+ .partial2{
2
+ display: block;
3
+ }
@@ -0,0 +1,105 @@
1
+ require 'appraisal'
2
+ require 'appraisal/command'
3
+ module Kernal
4
+ module Captures
5
+ def capture_output
6
+ buffer = []
7
+ real_stdout, $stdout = $stdout, StringIO.new
8
+ buffer << yield
9
+ buffer << $stdout.string
10
+ return buffer.join
11
+ ensure
12
+ $stdout = real_stdout
13
+ end
14
+
15
+ def capture_all_output
16
+ capture_output do
17
+ capture_warning do
18
+ yield
19
+ end
20
+ end
21
+ end
22
+
23
+
24
+ def capture_warning
25
+ buffer = []
26
+ real_stderr, $stderr = $stderr, StringIO.new
27
+ buffer << yield
28
+ buffer << $stderr.string
29
+ return buffer.join
30
+ ensure
31
+ $stderr = real_stderr
32
+ end
33
+ end
34
+ end
35
+
36
+ include Kernal::Captures
37
+
38
+ module CompassRails
39
+ module Test
40
+ module CommandHelper
41
+ include DebugHelper
42
+ GEMFILES_DIR = Pathname.new(ROOT_PATH).join('gemfiles')
43
+ BUNDLER_COMMAND = 'bundle'
44
+
45
+ def run_command(command, gemfile=nil)
46
+ debug "Running: #{command} with gemfile: #{gemfile}"
47
+ capture_all_output { CompassRails::Test::CommandRunner.new(command, gemfile).run }
48
+ end
49
+
50
+ def bundle(gemfile=nil)
51
+ run_command(BUNDLER_COMMAND, gemfile)
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+
58
+ # Executes commands with a clean environment
59
+ class CompassRails::Test::CommandRunner
60
+ BUNDLER_ENV_VARS = %w(RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE).freeze
61
+
62
+ def self.from_args(gemfile)
63
+ command = ([$0] + ARGV.slice(1, ARGV.size)).join(' ')
64
+ new(command, gemfile)
65
+ end
66
+
67
+ def initialize(command, gemfile = nil)
68
+ @original_env = {}
69
+ @gemfile = gemfile
70
+ if command =~ /^bundle/
71
+ @command = command
72
+ else
73
+ @command = "bundle exec #{command}"
74
+ end
75
+ end
76
+
77
+ def run
78
+ with_clean_env { %x{#{@command}} }
79
+ end
80
+
81
+ def exec
82
+ with_clean_env { Kernel.exec(@command) }
83
+ end
84
+
85
+ private
86
+
87
+ def with_clean_env
88
+ unset_bundler_env_vars
89
+ ENV['BUNDLE_GEMFILE'] = @gemfile
90
+ yield
91
+ ensure
92
+ restore_env
93
+ end
94
+
95
+ def unset_bundler_env_vars
96
+ BUNDLER_ENV_VARS.each do |key|
97
+ @original_env[key] = ENV[key]
98
+ ENV[key] = nil
99
+ end
100
+ end
101
+
102
+ def restore_env
103
+ @original_env.each { |key, value| ENV[key] = value }
104
+ end
105
+ end