bagger 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -3,4 +3,5 @@ rvm:
3
3
  - 1.9.3
4
4
  - 1.8.7
5
5
  - ree
6
- - rbx-head
6
+ - rbx-2.0
7
+ - jruby
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 client side
4
- rendering by using the following techniques:
3
+ A framework agnostic packaging solution to speed up loading times
4
+ on the client side by using the following techniques:
5
5
 
6
- * Generating versioned assets to maximize cache efficiency
7
- * Combine, minify and lint javascript and css files to reduce bandwidth
8
- * Zip assets to further reduce bandwidth consumption
9
- * Generating a file manifest to lookup an asset's location
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
- ## Similar projects
12
+ ## Features already implemented in version 0.0.1
14
13
 
15
- * [jammit](https://github.com/documentcloud/jammit)
16
- * [Rails 3 asset pipeline](http://blog.nodeta.com/2011/06/14/rails-3-1-asset-pipeline-in-the-real-world/)
17
- * [assets.io](http://www.assets.io/)
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
- ## Roadmap
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
- ### Version 0.0.1 (Minimal Viable Product)
83
+ CACHE MANIFEST
22
84
 
23
- * Versioned assets
24
- * Manifest files
25
- * Combine javascript
26
- * Combine css
27
- * Rewrite css urls
28
- * CLI binary
29
- * Solid test suite
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
+ }
@@ -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.open(File.join(@target_dir, 'cache.manifest'), 'w') do |f|
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('cache.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
@@ -1,3 +1,3 @@
1
1
  module Bagger
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/bagger.rb CHANGED
@@ -3,6 +3,8 @@ require 'json'
3
3
  require "bagger/packager"
4
4
 
5
5
  module Bagger
6
+ class ValidationError < RuntimeError ; end
7
+
6
8
  def self.bagit!(options)
7
9
  Bagger::Packager.new(options).run
8
10
  end
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 'compress the javascript' do
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.1
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-09 00:00:00.000000000 Z
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: &70307486940240 !ruby/object:Gem::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: *70307486940240
24
+ version_requirements: *70299848703020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: addressable
27
- requirement: &70307486939720 !ruby/object:Gem::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: *70307486939720
35
+ version_requirements: *70299848702420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: uglifier
38
- requirement: &70307486939180 !ruby/object:Gem::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: *70307486939180
46
+ version_requirements: *70299848701860
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rainpress
49
- requirement: &70307486938540 !ruby/object:Gem::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: *70307486938540
57
+ version_requirements: *70299848701260
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &70307486938000 !ruby/object:Gem::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: *70307486938000
68
+ version_requirements: *70299848700760
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: shoulda-context
71
- requirement: &70307486937460 !ruby/object:Gem::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: *70307486937460
79
+ version_requirements: *70299848700240
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: mocha
82
- requirement: &70307486936940 !ruby/object:Gem::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: *70307486936940
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