jekyll-assets 0.1.0

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 (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