jekyll-minibundle 1.0.0 → 1.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YmU4ZTUwM2ZlNTlhNGI1OGFjMTg4OGRhNDEyNWYwOWUyYjI1OWUwMQ==
5
+ data.tar.gz: !binary |-
6
+ ZDdiN2RjN2JiMDY3Yjc4ODA4MTI2YTA5YWVlY2RkMzM3NGFhOTMzYg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MGFiYmJhNGY1MTRhOTRiYWYxM2FkOWQxYmE5YzU0ZGM5NjMwMTkxNDRlY2Q0
10
+ MWQxZmIwZTY5NWY5YTg5ZGIzYjkyMjlkNzk4Yjg1NTNlN2QzMzA5ZjU3NDZl
11
+ OTcwODM2ZjU3YjQ1NGFjNmRlYzcyNDU0NDg5Y2I4YTQ2YWZiYmE=
12
+ data.tar.gz: !binary |-
13
+ ZWZjNmNlZmMxZTQ3MmFkNGY0YzExYmY1NGFjM2VmZjVkMzFiZjQxMTY1ODNi
14
+ OWVhODdjNTIzM2E5NjRkMDNjMDA4Njc1NjI4MmVjOTZjMjlkNjVlZWJhZWIx
15
+ MWE3YzVmZThlMmQ0YzIxODgxZmFiZmQ2ODg4NzQ2M2Q0YmE4M2E=
@@ -1,17 +1,25 @@
1
- ### 1.0.0 / 2013-02-15
1
+ # 1.1.0 / 2013-02-27
2
+
3
+ * `ministamp` tag omits fingerprint in development mode
4
+ * Clarify documentation
5
+ * Comply with (Gemnasium) conventions for changelogs (@tmatilai)
6
+ * Bug fix: do not bundle assets when nonrelated files change
7
+ * Bug fix: do not bundle assets twice upon startup
8
+
9
+ # 1.0.0 / 2013-02-15
2
10
 
3
11
  * Add development mode, where `minibundle` block will copy each asset
4
12
  as-is to the destination directory
5
13
  * Clarify documentation
6
14
  * Increase test coverage
7
15
 
8
- ### 0.2.0 / 2012-12-15
16
+ # 0.2.0 / 2012-12-15
9
17
 
10
18
  * Escape the values of custom attributes given in `minibundle` block
11
19
  * Add semicolons between each JavaScript asset in bundling
12
20
  * Show error in page output if asset bundling command failed
13
21
 
14
- ### 0.1.0 / 2012-12-07
22
+ # 0.1.0 / 2012-12-07
15
23
 
16
24
  * Add `ministamp` tag and `minibundle` block for Jekyll
17
25
  * First release
File without changes
data/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # Jekyll Minibundle plugin
2
+
3
+ A minimalistic plugin for bundling assets to
4
+ [Jekyll](https://github.com/mojombo/jekyll)'s site generation
5
+ directory.
6
+
7
+ In addition to the plugin itself, you need a minification tool
8
+ supporting standard unix input and output. There are no gem
9
+ dependencies at runtime.
10
+
11
+ Tested with Ruby MRI 1.9.3. Ruby 1.8 is *not* supported.
12
+
13
+ [![Build Status](https://secure.travis-ci.org/tkareine/jekyll-minibundle.png)](http://travis-ci.org/tkareine/jekyll-minibundle)
14
+
15
+ # Features
16
+
17
+ There are two features: asset fingerprinting with MD5 digest over the
18
+ contents of the asset, and asset bundling combined with the first
19
+ feature.
20
+
21
+ Asset bundling consists of concatenation and minification. The plugin
22
+ implements concatenation and leaves up to you to choose the
23
+ minification tool. [UglifyJS2](https://github.com/mishoo/UglifyJS2) is
24
+ a good and fast minifier. The plugin connects to the minifier with
25
+ standard unix pipe, feeding asset file contents to it in desired order
26
+ via standard input, and reads the result from standard output.
27
+
28
+ Why is this good? Well, a fingerprint in asset's path is the
29
+ [recommended way](https://developers.google.com/speed/docs/best-practices/caching)
30
+ to handle caching of static resources, because you can allow caching
31
+ the asset forever. Calculating MD5 digest over the contents of the
32
+ asset is fast and the resulting digest is reasonably unique to be
33
+ generated automatically.
34
+
35
+ Asset bundling is good for reducing the number of requests to the
36
+ backend upon page load. The minification of stylesheets and JavaScript
37
+ sources makes asset sizes smaller and thus faster to load over
38
+ network.
39
+
40
+ # Usage
41
+
42
+ The plugin is shipped as a
43
+ [RubyGem](https://rubygems.org/gems/jekyll-minibundle):
44
+
45
+ ``` bash
46
+ $ gem install jekyll-minibundle
47
+ ```
48
+
49
+ Add file `_plugins/minibundle.rb` to your Jekyll site project with
50
+ this line:
51
+
52
+ ``` ruby
53
+ require 'jekyll/minibundle'
54
+ ```
55
+
56
+ ## Asset fingerprinting
57
+
58
+ Asset fingerprinting is intended to be used together with
59
+ [Compass](http://compass-style.org/) and other similar asset
60
+ generation tools that have their own configuration for input sources.
61
+
62
+ Configure Compass to take inputs from `_assets/styles/*.scss` and to
63
+ put output to `_tmp/site.css`. Use `ministamp` tag to copy the
64
+ processed style asset to the generated site:
65
+
66
+ ``` html
67
+ <link href="{% ministamp _tmp/site.css assets/site.css %}" rel="stylesheet" media="screen, projection">
68
+ ```
69
+
70
+ Output, containing the MD5 digest of the file in the filename:
71
+
72
+ ``` html
73
+ <link href="assets/site-390be921ee0eff063817bb5ef2954300.css" rel="stylesheet" media="screen, projection">
74
+ ```
75
+
76
+ This feature does not require any external tools.
77
+
78
+ ## Asset bundling
79
+
80
+ This is a straightforward way to bundle assets with any minification
81
+ tool that supports reading input from STDIN and writing the output to
82
+ STDOUT. You write the configuration for input sources directly into
83
+ the content file where you want the markup tag for the bundle file to
84
+ appear. The outcome will be a markup tag containing the path to the
85
+ bundle file, and the generated site will have the bundle file in that
86
+ path. The MD5 digest of the file will be included in the filename.
87
+
88
+ Place `minibundle` block with configuration into your content file
89
+ where you want the generated markup to appear. For example, to bundle
90
+ a set of JavaScript sources:
91
+
92
+ ``` text
93
+ {% minibundle js %}
94
+ source_dir: _assets/scripts
95
+ destination_path: assets/site
96
+ assets:
97
+ - dependency
98
+ - app
99
+ attributes:
100
+ id: my-scripts
101
+ {% endminibundle %}
102
+ ```
103
+
104
+ Then, specify the command for launching your favorite minifier in
105
+ `$JEKYLL_MINIBUNDLE_CMD_JS` environment variable. For example, when
106
+ launching Jekyll:
107
+
108
+ ``` bash
109
+ $ JEKYLL_MINIBUNDLE_CMD_JS='./node_modules/.bin/uglifyjs --' jekyll
110
+ ```
111
+
112
+ You can pass custom attributes to the generated markup with
113
+ `attributes` map in the configuration.
114
+
115
+ Output in the content file:
116
+
117
+ ``` html
118
+ <script src="assets/site-8e764372a0dbd296033cb2a416f064b5.js" type="text/javascript" id="my-scripts"></script>
119
+ ```
120
+
121
+ For bundling CSS assets, you use `css` as the argument to `minibundle` block:
122
+
123
+ ``` text
124
+ {% minibundle css %}
125
+ source_dir: _assets/styles
126
+ destination_path: assets/site
127
+ assets:
128
+ - reset
129
+ - common
130
+ attributes:
131
+ media: screen
132
+ {% endminibundle %}
133
+ ```
134
+
135
+ And then specify the command for launching bundling in
136
+ `$JEKYLL_MINIBUNDLE_CMD_CSS` environment variable.
137
+
138
+ ## Development mode
139
+
140
+ The plugin has one more trick in its sleeves. If you set environment
141
+ variable `JEKYLL_MINIBUNDLE_MODE` to `development`, then the plugin
142
+ will copy asset files as is to the destination directory (using
143
+ `destination_path` as directory for `minibundle` block), and omit
144
+ fingerprinting. This is useful in development workflow, where you need
145
+ the filenames and line numbers of the original asset sources.
146
+
147
+ ``` bash
148
+ $ JEKYLL_MINIBUNDLE_MODE=development jekyll --auto --server
149
+ ```
150
+
151
+ # Example site
152
+
153
+ See the contents of `test/fixture/site` directory.
154
+
155
+ # License
156
+
157
+ MIT. See `LICENSE.txt`.
data/RELEASING.txt ADDED
@@ -0,0 +1,11 @@
1
+ In order to release, do
2
+
3
+ $EDITOR lib/jekyll/minibundle/version.rb # update version number
4
+ $EDITOR CHANGELOG.md # describe a summary of changes since last release
5
+ git diff # review the changes
6
+ rake gem:build # check that tests pass
7
+ git add -p
8
+ git commit -m 'Release <version>'
9
+ git tag <version>
10
+ git push --tags origin master
11
+ gem push jekyll-minibundle-<version>.gem
data/Rakefile CHANGED
@@ -38,7 +38,7 @@ task :test do
38
38
  tests = Dir['test/**/*_test.rb'].
39
39
  map { |file| %r{^test/(.+)\.rb$}.match(file)[1] }.
40
40
  shelljoin
41
- test_cmd = %{bundle exec ruby -e 'ARGV.each { |f| require f }' #{tests}}
41
+ test_cmd = %{ruby -e 'ARGV.each { |f| require f }' #{tests}}
42
42
  sh(get_minibundle_env('RUBYLIB' => 'lib:test'), test_cmd)
43
43
  end
44
44
 
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib/jekyll/minibundle/version'))
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'jekyll-minibundle'
5
+ s.version = Jekyll::Minibundle::VERSION
6
+ s.summary = 'A minimalistic asset bundling plugin for Jekyll'
7
+ s.authors = ['Tuomas Kareinen']
8
+ s.email = 'tkareine@gmail.com'
9
+ s.homepage = 'https://github.com/tkareine/jekyll-minibundle'
10
+ s.licenses = %w{MIT}
11
+
12
+ s.description = <<-END
13
+ A minimalistic asset bundling plugin for Jekyll, requiring only your
14
+ bundling tool of choice (no other dependencies, not even other gems).
15
+ Provides asset bundling and filename stamping with MD5 digest.
16
+ END
17
+
18
+ s.files = %w{
19
+ CHANGELOG.md
20
+ LICENSE.txt
21
+ README.md
22
+ RELEASING.txt
23
+ Rakefile
24
+ jekyll-minibundle.gemspec
25
+ lib/jekyll/minibundle/asset_bundle.rb
26
+ lib/jekyll/minibundle/asset_file_operations.rb
27
+ lib/jekyll/minibundle/asset_file_paths.rb
28
+ lib/jekyll/minibundle/asset_stamp.rb
29
+ lib/jekyll/minibundle/asset_tag_markup.rb
30
+ lib/jekyll/minibundle/bundle_file.rb
31
+ lib/jekyll/minibundle/development_file.rb
32
+ lib/jekyll/minibundle/development_file_collection.rb
33
+ lib/jekyll/minibundle/environment.rb
34
+ lib/jekyll/minibundle/mini_bundle_block.rb
35
+ lib/jekyll/minibundle/mini_stamp_tag.rb
36
+ lib/jekyll/minibundle/stamp_file.rb
37
+ lib/jekyll/minibundle/version.rb
38
+ lib/jekyll/minibundle.rb
39
+ }
40
+
41
+ s.test_files = %w{
42
+ test/fixture/site/_assets/scripts/app.js
43
+ test/fixture/site/_assets/scripts/dependency.js
44
+ test/fixture/site/_assets/styles/common.css
45
+ test/fixture/site/_assets/styles/reset.css
46
+ test/fixture/site/_bin/remove_comments
47
+ test/fixture/site/_bin/with_count
48
+ test/fixture/site/_plugins/minibundle.rb
49
+ test/fixture/site/_tmp/site.css
50
+ test/fixture/site/index.html
51
+ test/integration/minibundle_development_mode_test.rb
52
+ test/integration/minibundle_production_mode_test.rb
53
+ test/integration/ministamp_test.rb
54
+ test/support/fixture_config.rb
55
+ test/support/test_case.rb
56
+ test/unit/asset_bundle_test.rb
57
+ test/unit/asset_tag_markup_test.rb
58
+ test/unit/bundle_file_test.rb
59
+ test/unit/stamp_file_test.rb
60
+ }
61
+
62
+ s.add_development_dependency 'jekyll', '~> 0.12.0'
63
+ s.add_development_dependency 'minitest', '~> 4.6.0'
64
+ s.add_development_dependency 'nokogiri', '~> 1.5.6'
65
+ s.add_development_dependency 'rake', '~> 10.0.2'
66
+
67
+ s.required_ruby_version = '>= 1.9.3'
68
+
69
+ s.rdoc_options << '--line-numbers' << '--title' << s.name << '--exclude' << 'test'
70
+ end
@@ -1,4 +1,5 @@
1
1
  require 'tempfile'
2
+ require 'jekyll/minibundle/environment'
2
3
 
3
4
  module Jekyll::Minibundle
4
5
  class AssetBundle
@@ -27,10 +28,7 @@ module Jekyll::Minibundle
27
28
  private
28
29
 
29
30
  def bundling_cmd
30
- key = "JEKYLL_MINIBUNDLE_CMD_#{@type.upcase}"
31
- cmd = ENV[key]
32
- raise "You need to set bundling command in $#{key}" if !cmd
33
- cmd
31
+ Environment.command_for @type
34
32
  end
35
33
 
36
34
  def pipe_bundling_to_temp_file(cmd)
@@ -4,12 +4,12 @@ module Jekyll::Minibundle
4
4
  asset_source_path
5
5
  end
6
6
 
7
- def asset_path
7
+ def asset_destination_path
8
8
  File.join asset_destination_dir, asset_destination_basename
9
9
  end
10
10
 
11
11
  def destination(site_destination_dir)
12
- File.join site_destination_dir, asset_destination_dir, asset_destination_basename
12
+ File.join site_destination_dir, asset_destination_path
13
13
  end
14
14
 
15
15
  def destination_exists?(site_destination_dir)
@@ -7,72 +7,88 @@ module Jekyll::Minibundle
7
7
  class BundleFile
8
8
  include AssetFileOperations
9
9
 
10
- @@mtimes = {}
10
+ def self.clear_cache
11
+ @@mtimes = {}
12
+ @@writes_after_mtime_updates = Hash.new false
13
+ @@asset_bundles = {}
14
+ end
15
+
16
+ clear_cache
11
17
 
12
18
  def initialize(config)
13
19
  @type = config['type']
14
20
  @site_source_dir = config['site_dir']
15
21
  asset_source_dir = File.join @site_source_dir, config['source_dir']
16
22
  @assets = config['assets'].map { |asset_path| File.join asset_source_dir, "#{asset_path}.#{@type}" }
17
- @asset_destination_path = config['destination_path']
23
+ @destination_path = config['destination_path']
18
24
  @attributes = config['attributes']
19
25
  end
20
26
 
27
+ def markup
28
+ # we must rebundle here, if at all, in order to make sure the
29
+ # markup and generated file have the same fingerprint
30
+ rebundle_assets if modified?
31
+ AssetTagMarkup.make_markup @type, asset_destination_path, @attributes
32
+ end
33
+
21
34
  def path
22
35
  asset_bundle.path
23
36
  end
24
37
 
25
- def asset_path
26
- "#{@asset_destination_path}-#{asset_stamp}.#{@type}"
38
+ def asset_destination_path
39
+ "#{@destination_path}-#{asset_stamp}.#{@type}"
27
40
  end
28
41
 
29
42
  def destination(site_destination_dir)
30
- File.join site_destination_dir, asset_path
43
+ File.join site_destination_dir, asset_destination_path
31
44
  end
32
45
 
33
46
  def mtime
34
- @assets.max { |f| File.stat(f).mtime.to_i }
47
+ @assets.map { |f| File.stat(f).mtime.to_i }.max
35
48
  end
36
49
 
37
50
  def modified?
38
- @@mtimes[path] != mtime
51
+ @@mtimes[asset_destination_canonical_path] != mtime
39
52
  end
40
53
 
41
- def write(site_destination_dir)
42
- is_modified = modified?
43
-
44
- rebundle_assets if is_modified
54
+ def destination_written_after_mtime_update?
55
+ @@writes_after_mtime_updates[asset_destination_canonical_path]
56
+ end
45
57
 
46
- if File.exists?(destination(site_destination_dir)) && !is_modified
58
+ def write(site_destination_dir)
59
+ if File.exists?(destination(site_destination_dir)) && destination_written_after_mtime_update?
47
60
  false
48
61
  else
49
- update_mtime
50
62
  write_destination site_destination_dir
63
+ @@writes_after_mtime_updates[asset_destination_canonical_path] = true
51
64
  true
52
65
  end
53
66
  end
54
67
 
55
- def markup
56
- AssetTagMarkup.make_markup @type, asset_path, @attributes
57
- end
58
-
59
68
  private
60
69
 
70
+ def asset_destination_canonical_path
71
+ "#{@destination_path}.#{@type}"
72
+ end
73
+
61
74
  def asset_stamp
62
- @asset_stamp ||= AssetStamp.from_file(path)
75
+ @asset_stamp ||= AssetStamp.from_file path
63
76
  end
64
77
 
65
78
  def asset_bundle
66
- @asset_bundle ||= AssetBundle.new(@type, @assets, @site_source_dir).make_bundle
79
+ @@asset_bundles[asset_destination_canonical_path] ||= AssetBundle.new(@type, @assets, @site_source_dir)
67
80
  end
68
81
 
69
82
  def rebundle_assets
70
83
  @asset_stamp = nil
71
84
  asset_bundle.make_bundle
85
+ update_mtime
72
86
  end
73
87
 
74
88
  def update_mtime
75
- @@mtimes[path] = mtime
89
+ p = asset_destination_canonical_path
90
+ @@mtimes[p] = mtime
91
+ @@writes_after_mtime_updates[p] = false
76
92
  end
77
93
  end
78
94
  end
@@ -24,16 +24,10 @@ module Jekyll::Minibundle
24
24
  if destination_exists?(site_destination_dir) && !modified?
25
25
  false
26
26
  else
27
- update_mtime
27
+ @@mtimes[path] = mtime
28
28
  write_destination site_destination_dir
29
29
  true
30
30
  end
31
31
  end
32
-
33
- private
34
-
35
- def update_mtime
36
- @@mtimes[path] = mtime
37
- end
38
32
  end
39
33
  end