bagger 0.0.1 → 0.0.2
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.
- data/.travis.yml +2 -1
- data/CHANGELOG.md +21 -0
- data/README.md +88 -24
- data/ROADMAP.md +35 -0
- data/lib/bagger/packager.rb +16 -8
- data/lib/bagger/version.rb +1 -1
- data/lib/bagger.rb +2 -0
- data/test/bagger_test.rb +27 -1
- metadata +18 -16
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## v 0.0.2
|
4
|
+
|
5
|
+
* Make file and cache manifest path configurable
|
6
|
+
* Validate that the source directory actually exists
|
7
|
+
|
8
|
+
## v 0.0.1
|
9
|
+
|
10
|
+
* Combines javascript
|
11
|
+
* Minfies javascript with [UglifyJS](https://github.com/mishoo/UglifyJS)
|
12
|
+
* Combines stylesheets
|
13
|
+
* Rewrites urls in stylesheets
|
14
|
+
* Minfies stylesheets with [rainpress](https://rubygems.org/gems/rainpress)
|
15
|
+
* Generates versioned file names e.g /images/logo.19db9a16e2b73017c575570de577d103.png
|
16
|
+
* Generates a manifest file in JSON
|
17
|
+
* Generates an HTML 5 cache manifest
|
18
|
+
|
19
|
+
### Known issues
|
20
|
+
|
21
|
+
* Paths for manifest and html 5 cache manifest are hardcoded to TARGET_DIR/manifest.json and TARGET_DIR/cache.manifest
|
data/README.md
CHANGED
@@ -1,37 +1,101 @@
|
|
1
1
|
# bagger
|
2
2
|
|
3
|
-
A framework agnostic packaging solution to speed up
|
4
|
-
|
3
|
+
A framework agnostic packaging solution to speed up loading times
|
4
|
+
on the client side by using the following techniques:
|
5
5
|
|
6
|
-
*
|
7
|
-
* Combine
|
8
|
-
*
|
9
|
-
*
|
6
|
+
* Generate versioned assets to maximize cache efficiency
|
7
|
+
* Combine and minify javascript and css files to reduce bandwidth
|
8
|
+
* Generate a file manifest to lookup an asset's location
|
9
|
+
* Generate an HTML 5 cache manifest
|
10
10
|
* Rewrite urls in css files with the versioned file name
|
11
|
-
* Bundle up the assets as a zip file
|
12
11
|
|
13
|
-
##
|
12
|
+
## Features already implemented in version 0.0.1
|
14
13
|
|
15
|
-
*
|
16
|
-
*
|
17
|
-
*
|
14
|
+
* Combines javascript
|
15
|
+
* Minfies javascript with [UglifyJS](https://github.com/mishoo/UglifyJS)
|
16
|
+
* Combines stylesheets
|
17
|
+
* Rewrites urls in stylesheets
|
18
|
+
* Minfies stylesheets with [rainpress](https://rubygems.org/gems/rainpress)
|
19
|
+
* Generates versioned file names e.g /images/logo.19db9a16e2b73017c575570de577d103.png
|
20
|
+
* Generates a manifest file in JSON
|
21
|
+
* Generates an HTML 5 cache manifest
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
gem install bagger
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
require 'bagger'
|
29
|
+
require 'fileutils'
|
30
|
+
|
31
|
+
# define source and target directories
|
32
|
+
target_dir = "/tmp/bundled_assets"
|
33
|
+
source_dir = "/applications/my_app/public"
|
34
|
+
|
35
|
+
# customize paths for file and cache manifest
|
36
|
+
manifest_path = File.join(target_dir, 'file_manifest.json') #defaults
|
37
|
+
to manifest.json
|
38
|
+
|
39
|
+
cache_manifest_path = 'cache/cache.manifest' # defaults to
|
40
|
+
cache.manifest
|
41
|
+
|
42
|
+
# list the stylesheets and javascripts to be combined
|
43
|
+
# and minified. The order is important, because otherwhise
|
44
|
+
# the behavior of the stylesheets and javascripts might change
|
45
|
+
stylesheets = ["css/style.css", "css/reset.css"]
|
46
|
+
javascripts = ["js/app.js", "js/utils.js"]
|
47
|
+
|
48
|
+
# make sure the target directory exists
|
49
|
+
FileUtils.mkdir_p target_dir
|
50
|
+
|
51
|
+
# define the options hash
|
52
|
+
options = {
|
53
|
+
:source_dir => target_dir,
|
54
|
+
:target_dir => source_dir,
|
55
|
+
:manifest_path => manifest_path,
|
56
|
+
:cache_manifest_path => cache_manifest_path,
|
57
|
+
:combine => {
|
58
|
+
:stylesheets => stylesheets,
|
59
|
+
:stylesheet_path => 'css/all.css',
|
60
|
+
:javascripts => javascripts,
|
61
|
+
:javascript_path => 'js/combined.js'
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
# run it
|
66
|
+
Bagger::bagit!(options)
|
67
|
+
|
68
|
+
# TODO: at this point, the paths for the manifest and html 5 cache manifest
|
69
|
+
# are hardcoded.
|
70
|
+
manifest_path = File.join(target_dir, 'manifest.json')
|
71
|
+
cache_manifest_path = File.join(target_dir, 'cache.json')
|
72
|
+
|
73
|
+
## Manifest layout
|
18
74
|
|
19
|
-
|
75
|
+
{
|
76
|
+
"/css/all.css" : "/css/all.19db9a16e2b73017c575570de577d103.css",
|
77
|
+
"/js/combined.js" : "/js/combined.19db9a16e2b73017c575570de577d103.js",
|
78
|
+
"/images/logo.png" : "/images/logo.19db9a16e2b73017c575570de577d103.png"
|
79
|
+
}
|
80
|
+
|
81
|
+
## HTML 5 cache manifest
|
20
82
|
|
21
|
-
|
83
|
+
CACHE MANIFEST
|
22
84
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
*
|
30
|
-
* Support for the following Ruby versions (MRI 1.8.7, 1.9.2, REE 1.8.7)
|
31
|
-
* Pass all tests on travisci.org
|
32
|
-
* Examples on how to integrate it into the development workflow using
|
33
|
-
tools like watch or supervisor
|
85
|
+
# Explicitely cached entries
|
86
|
+
/css/all.19db9a16e2b73017c575570de577d103.css
|
87
|
+
/js/combined.19db9a16e2b73017c575570de577d103.js
|
88
|
+
/images/logo.19db9a16e2b73017c575570de577d103.png
|
89
|
+
|
90
|
+
NETWORK:
|
91
|
+
*
|
34
92
|
|
35
93
|
## Tests
|
36
94
|
|
37
95
|
check the build status on [travis.ci](http://travis-ci.org/wooga/bagger)
|
96
|
+
|
97
|
+
## Similar projects
|
98
|
+
|
99
|
+
* [jammit](https://github.com/documentcloud/jammit)
|
100
|
+
* [Rails 3 asset pipeline](http://blog.nodeta.com/2011/06/14/rails-3-1-asset-pipeline-in-the-real-world/)
|
101
|
+
* [assets.io](http://www.assets.io/)
|
data/ROADMAP.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# ROADMAP
|
2
|
+
|
3
|
+
## v 0.0.1
|
4
|
+
|
5
|
+
* Combines javascript
|
6
|
+
* Minfies javascript with [UglifyJS](https://github.com/mishoo/UglifyJS)
|
7
|
+
* Combines stylesheets
|
8
|
+
* Rewrites urls in stylesheets
|
9
|
+
* Minfies stylesheets with [rainpress](https://rubygems.org/gems/rainpress)
|
10
|
+
* Generates versioned file names e.g /images/logo.19db9a16e2b73017c575570de577d103.png
|
11
|
+
* Generates a manifest file in JSON
|
12
|
+
* Generates an HTML 5 cache manifest
|
13
|
+
|
14
|
+
## v 0.0.2
|
15
|
+
|
16
|
+
* allow to specify the the paths for cache.manifest and manifest.json
|
17
|
+
* better validation
|
18
|
+
|
19
|
+
## v 0.1.0
|
20
|
+
|
21
|
+
* generate custom manifest files e.g with support for file size
|
22
|
+
|
23
|
+
{
|
24
|
+
'/myfile.txt' => {
|
25
|
+
:path => '/myfile.19db9a16e2b73017c575570de577d103.txt'
|
26
|
+
:size => '391'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
* support for packages. e.g
|
31
|
+
|
32
|
+
:stylesheets => {
|
33
|
+
:common => ['main.css', 'fonts.css'],
|
34
|
+
:dialogs => ['modal.css', 'info_box.css']
|
35
|
+
}
|
data/lib/bagger/packager.rb
CHANGED
@@ -10,11 +10,12 @@ module Bagger
|
|
10
10
|
|
11
11
|
def initialize(options)
|
12
12
|
@options = options
|
13
|
-
@manifest_name = 'manifest.json'
|
14
13
|
@stylesheets = (@options[:combine] || {})[:stylesheets] || []
|
15
14
|
@javascripts = (@options[:combine] || {})[:javascripts] || []
|
16
15
|
@source_dir = @options[:source_dir]
|
17
16
|
@target_dir = @options[:target_dir]
|
17
|
+
@manifest_path = @options[:manifest_path] || File.join(@source_dir, 'manifest.json')
|
18
|
+
@cache_manifest_path = @options[:cache_manifest_path] || 'cache.manifest'
|
18
19
|
@stylesheet_path = (@options[:combine] || {})[:stylesheet_path] || 'combined.css'
|
19
20
|
@javascript_path = (@options[:combine] || {})[:javascript_path] || 'combined.js'
|
20
21
|
@path_prefix = @options[:path_prefix] || ''
|
@@ -37,11 +38,8 @@ module Bagger
|
|
37
38
|
@manifest[manifest_key_path] = effective_path
|
38
39
|
end
|
39
40
|
|
40
|
-
def manifest_path
|
41
|
-
File.join(@options[:source_dir], @manifest_name)
|
42
|
-
end
|
43
|
-
|
44
41
|
def run
|
42
|
+
validate
|
45
43
|
combine_css
|
46
44
|
combine_js
|
47
45
|
version_files
|
@@ -55,7 +53,7 @@ module Bagger
|
|
55
53
|
end
|
56
54
|
|
57
55
|
def write_manifest
|
58
|
-
File.open(manifest_path, 'w') do |f|
|
56
|
+
File.open(@manifest_path, 'w') do |f|
|
59
57
|
f.write JSON.pretty_generate(@manifest)
|
60
58
|
end
|
61
59
|
end
|
@@ -120,7 +118,9 @@ module Bagger
|
|
120
118
|
end
|
121
119
|
|
122
120
|
def generate_and_version_cache_manifest
|
123
|
-
File.
|
121
|
+
path = File.join(@target_dir, @cache_manifest_path)
|
122
|
+
FileUtils.mkdir_p(File.dirname(path))
|
123
|
+
File.open(path, 'w') do |f|
|
124
124
|
f.puts 'CACHE MANIFEST'
|
125
125
|
f.puts ''
|
126
126
|
f.puts '# Explicitely cached entries'
|
@@ -129,7 +129,7 @@ module Bagger
|
|
129
129
|
f.puts 'NETWORK:'
|
130
130
|
f.puts '*'
|
131
131
|
end
|
132
|
-
to_manifest(
|
132
|
+
to_manifest(@cache_manifest_path)
|
133
133
|
end
|
134
134
|
|
135
135
|
private
|
@@ -144,5 +144,13 @@ module Bagger
|
|
144
144
|
end
|
145
145
|
File.open(target_path, "w") { |f| f.write(output) }
|
146
146
|
end
|
147
|
+
|
148
|
+
def validate
|
149
|
+
raise_error "Source directory does not exist: #{@source_dir}" unless File.exists?(@source_dir)
|
150
|
+
end
|
151
|
+
|
152
|
+
def raise_error(message)
|
153
|
+
raise ValidationError.new(message)
|
154
|
+
end
|
147
155
|
end
|
148
156
|
end
|
data/lib/bagger/version.rb
CHANGED
data/lib/bagger.rb
CHANGED
data/test/bagger_test.rb
CHANGED
@@ -33,12 +33,25 @@ class BaggerTest < Test::Unit::TestCase
|
|
33
33
|
JSON.parse(json)
|
34
34
|
end
|
35
35
|
|
36
|
+
context 'validations' do
|
37
|
+
should 'verify the source directory exists' do
|
38
|
+
assert_raise(Bagger::ValidationError) do
|
39
|
+
Bagger.bagit!(default_options.merge(:source_dir => '/do/not/exist'))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
36
44
|
context 'manifest' do
|
37
45
|
should 'generate one' do
|
38
46
|
Bagger.bagit!(default_options)
|
39
47
|
assert File.exists?(File.join(@source_dir, 'manifest.json')), 'manifest was not created'
|
40
48
|
end
|
41
49
|
|
50
|
+
should 'not add the manifest itself to the manfiest' do
|
51
|
+
Bagger.bagit!(default_options)
|
52
|
+
assert !manifest['/manifest.json']
|
53
|
+
end
|
54
|
+
|
42
55
|
should 'version files with md5' do
|
43
56
|
test_content = 'testcontent'
|
44
57
|
write_file(File.join(@source_dir, 'test.txt'), test_content)
|
@@ -60,6 +73,12 @@ class BaggerTest < Test::Unit::TestCase
|
|
60
73
|
Bagger.bagit!(default_options.merge(:path_prefix => '/path_prefix'))
|
61
74
|
assert_match /\/path_prefix\/test\..*\.txt/, manifest['/test.txt']
|
62
75
|
end
|
76
|
+
|
77
|
+
should 'allow to specify the path' do
|
78
|
+
manifest_path = File.join(@target_dir, 'custom.manifest')
|
79
|
+
Bagger.bagit!(default_options.merge(:manifest_path => manifest_path))
|
80
|
+
assert File.exists?(manifest_path), 'custom manifest path not found'
|
81
|
+
end
|
63
82
|
end
|
64
83
|
|
65
84
|
context 'html 5 cache manifest' do
|
@@ -79,6 +98,13 @@ class BaggerTest < Test::Unit::TestCase
|
|
79
98
|
expected_path = File.join(@target_dir, manifest['/cache.manifest'])
|
80
99
|
assert File.exists?(expected_path), 'versioned cache manifest not found'
|
81
100
|
end
|
101
|
+
|
102
|
+
should 'allow to specify the path' do
|
103
|
+
manifest_path = 'cache/cache.manifest'
|
104
|
+
Bagger.bagit!(default_options.merge(:cache_manifest_path => manifest_path))
|
105
|
+
expected_path = File.join(@target_dir, manifest_path)
|
106
|
+
assert File.exists?(expected_path), 'custom cache manifest path not found'
|
107
|
+
end
|
82
108
|
end
|
83
109
|
|
84
110
|
context 'css files' do
|
@@ -249,7 +275,7 @@ class BaggerTest < Test::Unit::TestCase
|
|
249
275
|
assert !File.exists?(File.join(@target_dir, 'js', 'one.js'))
|
250
276
|
end
|
251
277
|
|
252
|
-
should '
|
278
|
+
should 'minify the javascript' do
|
253
279
|
expected_path = File.join(@target_dir, 'js', 'combined.js')
|
254
280
|
Uglifier.expects(:compile).returns('//minified javascript')
|
255
281
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-08-
|
12
|
+
date: 2011-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &70299848703020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70299848703020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: addressable
|
27
|
-
requirement: &
|
27
|
+
requirement: &70299848702420 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70299848702420
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: uglifier
|
38
|
-
requirement: &
|
38
|
+
requirement: &70299848701860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70299848701860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rainpress
|
49
|
-
requirement: &
|
49
|
+
requirement: &70299848701260 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70299848701260
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
requirement: &
|
60
|
+
requirement: &70299848700760 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70299848700760
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: shoulda-context
|
71
|
-
requirement: &
|
71
|
+
requirement: &70299848700240 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70299848700240
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: mocha
|
82
|
-
requirement: &
|
82
|
+
requirement: &70299848699640 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70299848699640
|
91
91
|
description: ! 'A framework agnostic packaging solution for your assets: version files,
|
92
92
|
combine them, minify them and create a manifest'
|
93
93
|
email:
|
@@ -98,8 +98,10 @@ extra_rdoc_files: []
|
|
98
98
|
files:
|
99
99
|
- .gitignore
|
100
100
|
- .travis.yml
|
101
|
+
- CHANGELOG.md
|
101
102
|
- Gemfile
|
102
103
|
- README.md
|
104
|
+
- ROADMAP.md
|
103
105
|
- Rakefile
|
104
106
|
- bagger.gemspec
|
105
107
|
- lib/bagger.rb
|