jekyll-assets 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +2 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +6 -0
  6. data/LICENSE +22 -0
  7. data/README.md +120 -0
  8. data/Rakefile +9 -0
  9. data/jekyll-assets.gemspec +27 -0
  10. data/lib/jekyll-assets.rb +1 -0
  11. data/lib/jekyll/assets_plugin.rb +16 -0
  12. data/lib/jekyll/assets_plugin/asset_file.rb +45 -0
  13. data/lib/jekyll/assets_plugin/configuration.rb +98 -0
  14. data/lib/jekyll/assets_plugin/generator.rb +26 -0
  15. data/lib/jekyll/assets_plugin/logging.rb +10 -0
  16. data/lib/jekyll/assets_plugin/site_patch.rb +56 -0
  17. data/lib/jekyll/assets_plugin/tag.rb +104 -0
  18. data/lib/jekyll/assets_plugin/version.rb +5 -0
  19. data/spec/fixtures/.gitignore +1 -0
  20. data/spec/fixtures/_assets/app.css.erb +5 -0
  21. data/spec/fixtures/_assets/app.js +1 -0
  22. data/spec/fixtures/_assets/noise.png +0 -0
  23. data/spec/fixtures/_assets/vapor.css +1 -0
  24. data/spec/fixtures/_assets/vapor.js +1 -0
  25. data/spec/fixtures/_config.yml +2 -0
  26. data/spec/fixtures/_layouts/default.html +9 -0
  27. data/spec/fixtures/_posts/2012-10-19-hello-world.md +6 -0
  28. data/spec/fixtures/index.html +0 -0
  29. data/spec/lib/jekyll/assets_plugin/asset_file_spec.rb +12 -0
  30. data/spec/lib/jekyll/assets_plugin/configuration_spec.rb +84 -0
  31. data/spec/lib/jekyll/assets_plugin/generator_spec.rb +12 -0
  32. data/spec/lib/jekyll/assets_plugin/logging_spec.rb +17 -0
  33. data/spec/lib/jekyll/assets_plugin/site_patch_spec.rb +47 -0
  34. data/spec/lib/jekyll/assets_plugin/tag_spec.rb +81 -0
  35. data/spec/spec_helper.rb +31 -0
  36. data/spec/support/fixtures_path.rb +12 -0
  37. metadata +203 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require ./lib/jekyll-assets --color --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ language: ruby
2
+ rvm: [ 1.9.3 ]
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jekyll-assets.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Aleksey V Zapparov (http://ixti.net/)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # Jekyll::AssetsPlugin
2
+
3
+ Jekyll plugin, that adds Rails-alike assets pipelines.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'jekyll-assets'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install jekyll-assets
19
+
20
+
21
+ ## Usage
22
+
23
+ Add this line to your sites `_plugins/ext.rb`:
24
+
25
+ require 'jekyll-assets'
26
+
27
+ Put your assets under following paths:
28
+
29
+ - `_assets/javascripts`
30
+ - `_assets/stylesheets`
31
+ - `_assets/images`
32
+
33
+ Name your "main" asset files `app.js` and `app.css` and use liquid tags:
34
+
35
+ - `{% javascript app %}` to output `<script>` tag for `app.js`
36
+ - `{% stylesheet app %}` to output `<link>` tag for `app.css`
37
+ - `{% asset_path logo.jpg %}` to output URL for `logo.jpg`
38
+
39
+ In order to use these tags, assets must be "bundled". By default only `app.js`,
40
+ `app.css`, and all files with extensions `.jpg`, `.png` or `.gif` are bundled.
41
+ You can change this by tuning up you `_config.yml` (see below).
42
+
43
+
44
+ ## Configuration
45
+
46
+ You can fine-tune configuration by editing your `_config.yml`:
47
+
48
+ assets:
49
+ #
50
+ # Pathname of the destination of generated (bundled) assets relative
51
+ # to the destination of the root.
52
+ #
53
+ dirname: assets
54
+ #
55
+ # Pathnames where to find assets relative to the root of the site.
56
+ #
57
+ sources:
58
+ - _assets/javascripts
59
+ - _assets/stylesheets
60
+ - _assets/images
61
+ #
62
+ # Array of filenames or filename patterns that needs to be generated for
63
+ # the generated site. You can use `*` and `**` wildcards in patterns:
64
+ #
65
+ # 'foobar.jpg' will match 'foobar.jpg' only
66
+ # '*.jpg' will match 'foo.jpg', but not 'foo/bar.jpg'
67
+ # '**.jpg' will match 'foo.jpg', 'foo/bar.jpg', etc.
68
+ #
69
+ bundles:
70
+ - 'app.css'
71
+ - 'app.js'
72
+ - '**.jpg'
73
+ - '**.png'
74
+ - '**.gif'
75
+ #
76
+ # Sets compressors for the specific types of file: `js`, or `css`.
77
+ # No compression by default.
78
+ #
79
+ # Possible variants:
80
+ #
81
+ # css => 'yui', 'sass', nil
82
+ # js => 'yui', 'unglifier', nil
83
+ #
84
+ compress:
85
+ js: ~
86
+ css: ~
87
+
88
+
89
+ ## Contributing
90
+
91
+ 1. Fork it
92
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
93
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
94
+ 4. Push to the branch (`git push origin my-new-feature`)
95
+ 5. Create new Pull Request
96
+
97
+
98
+ ## License
99
+
100
+ Copyright (C) 2012 Aleksey V Zapparov (http://ixti.net/)
101
+
102
+ The MIT License
103
+
104
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
105
+ this software and associated documentation files (the “Software”), to deal in
106
+ the Software without restriction, including without limitation the rights to
107
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
108
+ of the Software, and to permit persons to whom the Software is furnished to do
109
+ so, subject to the following conditions:
110
+
111
+ The above copyright notice and this permission notice shall be included in all
112
+ copies or substantial portions of the Software.
113
+
114
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
115
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
116
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
117
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
118
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
119
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
120
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task :default => :spec
9
+ task :test => :spec
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/jekyll/assets_plugin/version', __FILE__)
3
+
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "jekyll-assets"
7
+ gem.version = Jekyll::AssetsPlugin::VERSION
8
+ gem.homepage = "http://ixti.github.com/jekyll-assets"
9
+ gem.authors = %w{Aleksey V Zapparov}
10
+ gem.email = %w{ixti@member.fsf.org}
11
+ gem.summary = "jekyll-assets-#{Jekyll::AssetsPlugin::VERSION}"
12
+ gem.description = %q{Adds assets pipelines for Jekyll}
13
+
14
+ gem.add_dependency "jekyll"
15
+ gem.add_dependency "sprockets", "~> 2.8"
16
+
17
+ gem.add_development_dependency "rake"
18
+ gem.add_development_dependency "rspec"
19
+ gem.add_development_dependency "guard-rspec"
20
+ gem.add_development_dependency "rb-inotify"
21
+
22
+ gem.files = `git ls-files`.split($\)
23
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
24
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
25
+
26
+ gem.require_paths = ["lib"]
27
+ end
@@ -0,0 +1 @@
1
+ require 'jekyll/assets_plugin'
@@ -0,0 +1,16 @@
1
+ require 'jekyll'
2
+ require 'liquid'
3
+
4
+
5
+ require 'jekyll/assets_plugin/generator'
6
+ require 'jekyll/assets_plugin/site_patch'
7
+ require 'jekyll/assets_plugin/tag'
8
+ require 'jekyll/assets_plugin/version'
9
+
10
+
11
+ Jekyll::Site.send :include, Jekyll::AssetsPlugin::SitePatch
12
+
13
+
14
+ Liquid::Template.register_tag('javascript', Jekyll::AssetsPlugin::Tag)
15
+ Liquid::Template.register_tag('stylesheet', Jekyll::AssetsPlugin::Tag)
16
+ Liquid::Template.register_tag('asset_path', Jekyll::AssetsPlugin::Tag)
@@ -0,0 +1,45 @@
1
+ # stdlib
2
+ require 'set'
3
+
4
+
5
+ module Jekyll
6
+ module AssetsPlugin
7
+ # Represents single asset that can be used as StaticFile for Site
8
+ #
9
+ class AssetFile
10
+ @@mtimes = Hash.new
11
+
12
+ attr_reader :asset
13
+
14
+ def initialize site, asset
15
+ @site, @asset = site, asset
16
+ end
17
+
18
+ def destination dest
19
+ File.join(dest, @site.assets_config.dirname, @asset.digest_path)
20
+ end
21
+
22
+ def path
23
+ @asset.pathname.to_s
24
+ end
25
+
26
+ def mtime
27
+ @asset.mtime.to_i
28
+ end
29
+
30
+ def modified?
31
+ @@mtimes[path] != mtime
32
+ end
33
+
34
+ def write dest
35
+ dest_path = destination dest
36
+
37
+ return false if File.exist?(dest_path) and !modified?
38
+ @@mtimes[path] = mtime
39
+
40
+ @asset.write_to dest_path
41
+ true
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,98 @@
1
+ # stdlib
2
+ require 'ostruct'
3
+
4
+
5
+ module Jekyll
6
+ module AssetsPlugin
7
+ # Plugin configuration class.
8
+ #
9
+ #
10
+ # ##### sources
11
+ #
12
+ # Pathnames where to find assets relative to the root of the site.
13
+ #
14
+ # Default: ['_assets/javascripts', '_assets/stylesheets', '_assets/images']
15
+ #
16
+ #
17
+ # ##### bundles
18
+ #
19
+ # Array of filenames or filename patterns that needs to be generated for the
20
+ # generated site. You can use `*` and `**` wildcards in filename patterns:
21
+ #
22
+ # 'foobar.jpg' will match 'foobar.jpg' only
23
+ # '*.jpg' will match 'foo.jpg', but not 'foo/bar.jpg'
24
+ # '**.jpg' will match 'foo.jpg', 'foo/bar.jpg', etc.
25
+ #
26
+ # Default: ['app.css', 'app.js', '**.jpg', '**.png', '**.gif']
27
+ #
28
+ #
29
+ # ##### compress
30
+ #
31
+ # Sets compressors for the specific types of file: `js`, or `css`.
32
+ #
33
+ # Possible variants:
34
+ #
35
+ # css => 'yui', 'sass', nil
36
+ # js => 'yui', 'unglifier', nil
37
+ #
38
+ # Default: { 'css' => nil, 'js' => nil } (no compression at all)
39
+ #
40
+ #
41
+ # ##### dirname
42
+ #
43
+ # Pathname of the destination of generated (bundled) assets relative to the
44
+ # destination of the root.
45
+ #
46
+ # Default: 'assets'
47
+ #
48
+ class Configuration < OpenStruct
49
+ @@defaults = {
50
+ :dirname => 'assets',
51
+ :sources => %w{_assets/javascripts _assets/stylesheets _assets/images},
52
+ :bundles => %w{app.css app.js **.jpg **.png **.gif},
53
+ :compress => { :css => nil, :js => nil }
54
+ }
55
+
56
+ def initialize config = {}
57
+ super @@defaults.merge(config)
58
+
59
+ self.sources = [ self.sources ] if self.sources.is_a? String
60
+ self.bundles = [ self.bundles ] if self.bundles.is_a? String
61
+
62
+ self.compress = OpenStruct.new(self.compress)
63
+ end
64
+
65
+ # Returns bundles array with pattern strings converted to RegExps
66
+ #
67
+ # 'foobar.jpg' => 'foobar.jpg'
68
+ # '*.png' => /[^\]+\.png/
69
+ # '**.gif' => /.+?\.gif/
70
+ #
71
+ def bundle_filenames
72
+ bundles.map do |pattern|
73
+ if pattern =~ /^\*/
74
+ pattern = pattern.dup
75
+
76
+ pattern.gsub!(/\./, '\\.')
77
+ pattern.sub!(/\*{2}/, '.+?')
78
+ pattern.sub!(/\*{1}/, '[^/]+')
79
+
80
+ pattern = /^#{pattern}$/
81
+ end
82
+
83
+ pattern
84
+ end
85
+ end
86
+
87
+ def js_compressor
88
+ return compress.js.to_sym if compress.js
89
+ false
90
+ end
91
+
92
+ def css_compressor
93
+ return compress.css.to_sym if compress.css
94
+ false
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,26 @@
1
+ # internal
2
+ require 'jekyll/assets_plugin/logging'
3
+ require 'jekyll/assets_plugin/asset_file'
4
+
5
+
6
+ module Jekyll
7
+ module AssetsPlugin
8
+ # Jekyll hook that bundles all files specified in `bundles` config
9
+ #
10
+ class Generator < ::Jekyll::Generator
11
+ include Logging
12
+
13
+ safe false
14
+ priority :low
15
+
16
+ def generate site
17
+ filenames = site.assets_config.bundle_filenames
18
+ site.assets.each_logical_path(filenames).each do |logical_path|
19
+ if asset = site.assets.find_asset(logical_path)
20
+ site.static_files << AssetFile.new(site, asset) if asset
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ module Jekyll
2
+ module AssetsPlugin
3
+ module Logging
4
+ protected
5
+ def log level, message
6
+ puts "[AssetsPlugin] #{level.to_s.upcase} #{message}"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ # 3rd-party
2
+ require 'sprockets'
3
+
4
+
5
+ # internal
6
+ require 'jekyll/assets_plugin/asset_file'
7
+ require 'jekyll/assets_plugin/configuration'
8
+
9
+
10
+ module Jekyll
11
+ module AssetsPlugin
12
+ # Patch that provides #assets and #assets_config to Site
13
+ #
14
+ module SitePatch
15
+ def assets_config
16
+ @assets_config ||= Configuration.new(self.config['assets'] || {})
17
+ end
18
+
19
+ def assets
20
+ unless @assets
21
+ @assets = Sprockets::Environment.new(self.source)
22
+
23
+ assets_config.sources.each(&@assets.method(:append_path))
24
+
25
+ if js_compressor = assets_config.js_compressor
26
+ @assets.js_compressor = js_compressor
27
+ end
28
+
29
+ if css_compressor = assets_config.css_compressor
30
+ @assets.css_compressor = css_compressor
31
+ end
32
+
33
+ @assets.context_class.class_eval <<-RUBY, __FILE__, __LINE__
34
+ def asset_path(path, options = {})
35
+ asset = environment.find_asset path, options
36
+ raise FileNotFound, "couldn't find file '\#{path}'" unless asset
37
+ "/#{assets_config.dirname}/\#{asset.digest_path}".squeeze "/"
38
+ end
39
+ RUBY
40
+ end
41
+
42
+ @assets
43
+ end
44
+
45
+ def has_bundled_asset? asset
46
+ if asset.is_a? String
47
+ asset = assets[asset]
48
+ end
49
+
50
+ !self.static_files.index do |file|
51
+ file.is_a? AssetFile and file.asset == asset
52
+ end.nil?
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,104 @@
1
+ # 3rd-party
2
+ require 'liquid'
3
+
4
+
5
+ # stdlib
6
+ require 'set'
7
+
8
+
9
+ # internal
10
+ require 'jekyll/assets_plugin/logging'
11
+
12
+
13
+ module Jekyll
14
+ module AssetsPlugin
15
+ # Class that implements some useful liquid tags:
16
+ #
17
+ #
18
+ # ##### stylesheet
19
+ #
20
+ # Renders `<link>` tag for a logical path:
21
+ #
22
+ # {% stylesheet foo.css %}
23
+ # # => '<link type="text/css" rel="stylesheet"
24
+ # href="/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.css">
25
+ #
26
+ # You may omit extension so the following will give same result as above:
27
+ #
28
+ # {% stylesheet foo %}
29
+ #
30
+ #
31
+ # ##### javascript
32
+ #
33
+ # Renders `<script>` tag for a logical path:
34
+ #
35
+ # {% javascript foo.js %}
36
+ # # => '<script type="text/javascript"
37
+ # src="/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.js">
38
+ # </script>
39
+ #
40
+ # You may omit extension so the following will give same result as above:
41
+ #
42
+ # {% javascript foo %}
43
+ #
44
+ #
45
+ # ##### asset_path
46
+ #
47
+ # Renders asset path for an asset (useful for images):
48
+ #
49
+ # {% asset_path foo.jpg %}
50
+ # # => '/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.jpg"
51
+ #
52
+ #
53
+ class Tag < Liquid::Tag
54
+ include Logging
55
+
56
+ STYLESHEET = '<link rel="stylesheet" type="text/css" href="%s">'
57
+ JAVASCRIPT = '<script type="text/javascript" src="%s"></script>'
58
+ EXTENSIONS = { 'stylesheet' => '.css', 'javascript' => '.js' }
59
+
60
+ @@errors = Set.new
61
+
62
+ def initialize tag_name, logical_path, tokens
63
+ super
64
+
65
+ @logical_path = logical_path.strip
66
+
67
+ # append auto-guessed extension if needed
68
+ @logical_path << default_extension if File.extname(@logical_path).empty?
69
+ end
70
+
71
+ def default_extension
72
+ EXTENSIONS[@tag_name].to_s
73
+ end
74
+
75
+ def asset_not_found
76
+ if @@errors.add? @logical_path
77
+ log :error, "File not found: #{@logical_path}"
78
+ end
79
+ end
80
+
81
+ def asset_not_bundled
82
+ if @@errors.add? @logical_path
83
+ log :warn, "File was not bundled: #{@logical_path}"
84
+ end
85
+ end
86
+
87
+ def render context
88
+ site = context.registers[:site]
89
+ asset = site.assets[@logical_path]
90
+
91
+ return asset_not_found unless asset
92
+ return asset_not_bundled unless site.has_bundled_asset? asset
93
+
94
+ url = "/#{site.assets_config.dirname}/#{asset.digest_path}".squeeze "/"
95
+
96
+ case @tag_name
97
+ when 'stylesheet' then STYLESHEET % [url]
98
+ when 'javascript' then JAVASCRIPT % [url]
99
+ else url
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module AssetsPlugin
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ _site/
@@ -0,0 +1,5 @@
1
+ /**
2
+ *= require vapor
3
+ */
4
+
5
+ body { background-image: url(<%= image_path 'noise.png' %>) }
@@ -0,0 +1 @@
1
+ //= require vapor
Binary file
@@ -0,0 +1 @@
1
+ /* vapor css framework */
@@ -0,0 +1 @@
1
+ /* vapor js framework */
@@ -0,0 +1,2 @@
1
+ assets:
2
+ sources: [ _assets ]
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>jekyll-assets</title>
4
+ {% stylesheet app %}
5
+ </head>
6
+ <body>
7
+ {{ content }}
8
+ </body>
9
+ </html>
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Jekyll meets assets pipeline
4
+ ---
5
+
6
+ Assets pipelines for Jekyll.
File without changes
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe AssetFile do
6
+ context '#destination' do
7
+ let(:file) { AssetFile.new(@site, @site.assets['app.css']) }
8
+ subject { file.destination @dest.to_s }
9
+ it { should match %r{/app-[0-9a-f]{32}\.css$} }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe Configuration do
6
+ let(:defaults) do
7
+ {
8
+ :dirname => 'assets',
9
+ :sources => %w{_assets/javascripts _assets/stylesheets _assets/images},
10
+ :bundles => %w{app.css app.js **.jpg **.png **.gif}
11
+ }
12
+ end
13
+
14
+ context 'with defaults' do
15
+ let(:config){ Configuration.new }
16
+
17
+ context 'output assets dirname' do
18
+ subject { config.dirname }
19
+ it { should == defaults[:dirname] }
20
+ end
21
+
22
+ context 'sources list' do
23
+ subject { config.sources }
24
+ it { should =~ defaults[:sources] }
25
+ end
26
+
27
+ context 'bundles list' do
28
+ subject { config.bundles }
29
+ it { should =~ defaults[:bundles] }
30
+ end
31
+
32
+ context 'js compressor' do
33
+ subject { config.compress.js }
34
+ it { should be_nil }
35
+ end
36
+
37
+ context 'css compressor' do
38
+ subject { config.compress.css }
39
+ it { should be_nil }
40
+ end
41
+ end
42
+
43
+ it 'should override specified options and leave defaults for missing' do
44
+ config = Configuration.new({
45
+ :sources => %w{abc},
46
+ :compress => { :css => 'sass' }
47
+ })
48
+
49
+ config.dirname.should == 'assets'
50
+ config.sources.should =~ %w{abc}
51
+ config.bundles.should =~ defaults[:bundles]
52
+ config.compress.js.should be_nil
53
+ config.compress.css.should == 'sass'
54
+ end
55
+
56
+ context '#js_compressor' do
57
+ context 'when js compressor is given as "uglify"' do
58
+ let(:config){ Configuration.new(:compress => {:js => 'uglify'}) }
59
+ subject { config.js_compressor }
60
+ it { should be :uglify }
61
+ end
62
+
63
+ context 'otherwise' do
64
+ let(:config){ Configuration.new }
65
+ subject { config.js_compressor }
66
+ it { should be_false }
67
+ end
68
+ end
69
+
70
+ context '#css_compressor' do
71
+ context 'when js compressor is given as "sass"' do
72
+ let(:config){ Configuration.new(:compress => {:css => 'sass'}) }
73
+ subject { config.css_compressor }
74
+ it { should be :sass }
75
+ end
76
+
77
+ context 'otherwise' do
78
+ let(:config){ Configuration.new }
79
+ subject { config.css_compressor }
80
+ it { should be_false }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe Generator do
6
+ it 'should output bundled files only' do
7
+ files = []
8
+ @dest.join('assets').each_child(false, &files.method(:push))
9
+ files.map(&:to_s).should have(3).thing
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe Logging do
6
+ it 'puts strings with [AssetsPlugin] prefix' do
7
+ loggable = Class.new do
8
+ include Logging
9
+ # make sure #log is public
10
+ def log(*args) super; end
11
+ end.new
12
+
13
+ loggable.should_receive(:puts).with(match %r{^\[AssetsPlugin\]})
14
+ loggable.log :info, 'test'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe SitePatch do
6
+ let(:site) do
7
+ Class.new do
8
+ include SitePatch
9
+
10
+ def config
11
+ @config ||= {
12
+ 'bundles' => 'foobar',
13
+ 'assets' => { 'sources' => 'foobar' }
14
+ }
15
+ end
16
+
17
+ def source
18
+ @soure ||= '.'
19
+ end
20
+ end.new
21
+ end
22
+
23
+ context '#assets' do
24
+ subject { site.assets }
25
+ it { should be_an_instance_of Sprockets::Environment }
26
+ end
27
+
28
+ context '#assets_config' do
29
+ subject { site.assets_config }
30
+ it { should be_an_instance_of Configuration }
31
+
32
+ it 'should been populated with `assets` section of config' do
33
+ site.assets_config.bundles.should_not =~ %w{foobar}
34
+ site.assets_config.sources.should =~ %w{foobar}
35
+ end
36
+ end
37
+
38
+ it 'should be included into Jekyll::Site' do
39
+ Jekyll::Site.included_modules.should include SitePatch
40
+ end
41
+
42
+ it 'should respond to #has_bundled_asset?' do
43
+ @site.has_bundled_asset?(@site.assets['app.css']).should be_true
44
+ @site.has_bundled_asset?(@site.assets['normalize.css']).should be_false
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ describe Tag do
6
+ let(:context) { { :registers => { :site => @site } } }
7
+
8
+ def render content
9
+ Liquid::Template.parse(content).render({}, context)
10
+ end
11
+
12
+ context '{% stylesheet <file> %}' do
13
+ let(:tag_re) do
14
+ %r{^#{Tag::STYLESHEET % ['/assets/app-[a-f0-9]{32}\.css']}$}
15
+ end
16
+
17
+ context 'when <file> is bundled' do
18
+ subject { render('{% stylesheet app.css %}') }
19
+ it { should match tag_re }
20
+ end
21
+
22
+ context 'when <file> extension is omited' do
23
+ subject { render('{% stylesheet app %}') }
24
+ it { should match tag_re }
25
+ end
26
+
27
+ context 'when <file> is not found' do
28
+ subject { render('{% stylesheet not-found.css %}') }
29
+ it { should be_empty }
30
+ end
31
+
32
+ context 'when <file> is not bundled' do
33
+ subject { render('{% stylesheet vapor.css %}') }
34
+ it { should be_empty }
35
+ end
36
+ end
37
+
38
+ context '{% javasript <file> %}' do
39
+ let(:tag_re) do
40
+ %r{^#{Tag::JAVASCRIPT % ['/assets/app-[a-f0-9]{32}\.js']}$}
41
+ end
42
+
43
+ context 'when <file> is bundled' do
44
+ subject { render('{% javascript app.js %}') }
45
+ it { should match tag_re }
46
+ end
47
+
48
+ context 'when <file> extension omited' do
49
+ subject { render('{% javascript app %}') }
50
+ it { should match tag_re }
51
+ end
52
+
53
+ context 'when <file> is not found' do
54
+ subject { render('{% javascript not-found.js %}') }
55
+ it { should be_empty }
56
+ end
57
+
58
+ context 'when <file> is not bundled' do
59
+ subject { render('{% javascript vapor.js %}') }
60
+ it { should be_empty }
61
+ end
62
+ end
63
+
64
+ context '{% asset_path <file.ext> %}' do
65
+ context 'when <file> is bundled' do
66
+ subject { render('{% asset_path app.css %}') }
67
+ it { should match(%r{^/assets/app-[a-f0-9]{32}\.css$}) }
68
+ end
69
+
70
+ context 'when <file> is not found' do
71
+ subject { render('{% asset_path not-found.js %}') }
72
+ it { should be_empty }
73
+ end
74
+
75
+ context 'when <file> is not bundled' do
76
+ subject { render('{% asset_path vapor.js %}') }
77
+ it { should be_empty }
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+
3
+
4
+ require 'jekyll'
5
+ require 'liquid'
6
+ require 'sprockets'
7
+
8
+
9
+ # Requires supporting ruby files with custom matchers and macros, etc,
10
+ # in spec/support/ and its subdirectories.
11
+ Dir[File.expand_path('../support', __FILE__) + "/**/*.rb"].each {|f| require f}
12
+
13
+
14
+ RSpec.configure do |config|
15
+ config.include Jekyll::AssetsPlugin::RSpecHelpers
16
+
17
+ config.before(:all) do
18
+ @dest = fixtures_path.join('_site')
19
+ @site = Jekyll::Site.new(Jekyll.configuration({
20
+ 'source' => fixtures_path.to_s,
21
+ 'destination' => @dest.to_s
22
+ }))
23
+
24
+ @dest.rmtree if @dest.exist?
25
+ @site.process
26
+ end
27
+
28
+ config.after(:all) do
29
+ @dest.rmtree if @dest.exist?
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ require 'pathname'
2
+
3
+
4
+ module Jekyll::AssetsPlugin
5
+ module RSpecHelpers
6
+ extend self
7
+
8
+ def fixtures_path
9
+ @fixtures_path ||= Pathname.new(__FILE__).parent.parent.join('fixtures')
10
+ end
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-assets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aleksey
9
+ - V
10
+ - Zapparov
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-10-22 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: jekyll
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: sprockets
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '2.8'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.8'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rspec
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: guard-rspec
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rb-inotify
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Adds assets pipelines for Jekyll
113
+ email:
114
+ - ixti@member.fsf.org
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - .gitignore
120
+ - .rspec
121
+ - .travis.yml
122
+ - Gemfile
123
+ - Guardfile
124
+ - LICENSE
125
+ - README.md
126
+ - Rakefile
127
+ - jekyll-assets.gemspec
128
+ - lib/jekyll-assets.rb
129
+ - lib/jekyll/assets_plugin.rb
130
+ - lib/jekyll/assets_plugin/asset_file.rb
131
+ - lib/jekyll/assets_plugin/configuration.rb
132
+ - lib/jekyll/assets_plugin/generator.rb
133
+ - lib/jekyll/assets_plugin/logging.rb
134
+ - lib/jekyll/assets_plugin/site_patch.rb
135
+ - lib/jekyll/assets_plugin/tag.rb
136
+ - lib/jekyll/assets_plugin/version.rb
137
+ - spec/fixtures/.gitignore
138
+ - spec/fixtures/_assets/app.css.erb
139
+ - spec/fixtures/_assets/app.js
140
+ - spec/fixtures/_assets/noise.png
141
+ - spec/fixtures/_assets/vapor.css
142
+ - spec/fixtures/_assets/vapor.js
143
+ - spec/fixtures/_config.yml
144
+ - spec/fixtures/_layouts/default.html
145
+ - spec/fixtures/_posts/2012-10-19-hello-world.md
146
+ - spec/fixtures/index.html
147
+ - spec/lib/jekyll/assets_plugin/asset_file_spec.rb
148
+ - spec/lib/jekyll/assets_plugin/configuration_spec.rb
149
+ - spec/lib/jekyll/assets_plugin/generator_spec.rb
150
+ - spec/lib/jekyll/assets_plugin/logging_spec.rb
151
+ - spec/lib/jekyll/assets_plugin/site_patch_spec.rb
152
+ - spec/lib/jekyll/assets_plugin/tag_spec.rb
153
+ - spec/spec_helper.rb
154
+ - spec/support/fixtures_path.rb
155
+ homepage: http://ixti.github.com/jekyll-assets
156
+ licenses: []
157
+ post_install_message:
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ segments:
168
+ - 0
169
+ hash: -929384781
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ segments:
177
+ - 0
178
+ hash: -929384781
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 1.8.23
182
+ signing_key:
183
+ specification_version: 3
184
+ summary: jekyll-assets-0.1.0
185
+ test_files:
186
+ - spec/fixtures/.gitignore
187
+ - spec/fixtures/_assets/app.css.erb
188
+ - spec/fixtures/_assets/app.js
189
+ - spec/fixtures/_assets/noise.png
190
+ - spec/fixtures/_assets/vapor.css
191
+ - spec/fixtures/_assets/vapor.js
192
+ - spec/fixtures/_config.yml
193
+ - spec/fixtures/_layouts/default.html
194
+ - spec/fixtures/_posts/2012-10-19-hello-world.md
195
+ - spec/fixtures/index.html
196
+ - spec/lib/jekyll/assets_plugin/asset_file_spec.rb
197
+ - spec/lib/jekyll/assets_plugin/configuration_spec.rb
198
+ - spec/lib/jekyll/assets_plugin/generator_spec.rb
199
+ - spec/lib/jekyll/assets_plugin/logging_spec.rb
200
+ - spec/lib/jekyll/assets_plugin/site_patch_spec.rb
201
+ - spec/lib/jekyll/assets_plugin/tag_spec.rb
202
+ - spec/spec_helper.rb
203
+ - spec/support/fixtures_path.rb