bagger 0.0.1
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/.gitignore +6 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/README.md +37 -0
- data/Rakefile +33 -0
- data/bagger.gemspec +29 -0
- data/lib/bagger/packager.rb +148 -0
- data/lib/bagger/version.rb +3 -0
- data/lib/bagger.rb +9 -0
- data/test/bagger_test.rb +265 -0
- data/test/test_helper.rb +11 -0
- data/tests.watchr +38 -0
- metadata +137 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# bagger
|
2
|
+
|
3
|
+
A framework agnostic packaging solution to speed up client side
|
4
|
+
rendering by using the following techniques:
|
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
|
10
|
+
* Rewrite urls in css files with the versioned file name
|
11
|
+
* Bundle up the assets as a zip file
|
12
|
+
|
13
|
+
## Similar projects
|
14
|
+
|
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/)
|
18
|
+
|
19
|
+
## Roadmap
|
20
|
+
|
21
|
+
### Version 0.0.1 (Minimal Viable Product)
|
22
|
+
|
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
|
34
|
+
|
35
|
+
## Tests
|
36
|
+
|
37
|
+
check the build status on [travis.ci](http://travis-ci.org/wooga/bagger)
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
task :default => ['test:units']
|
6
|
+
|
7
|
+
def rubies
|
8
|
+
require 'yaml'
|
9
|
+
rubies = YAML.load_file('.travis.yml')['rvm']
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace :test do
|
13
|
+
Rake::TestTask.new(:units) do |t|
|
14
|
+
t.libs << "test"
|
15
|
+
t.test_files = FileList['test/*_test.rb']
|
16
|
+
|
17
|
+
t.verbose = true
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'run test suite with all ruby versions'
|
21
|
+
task :multi_ruby do
|
22
|
+
rubies.each do |ruby_version|
|
23
|
+
puts `rvm use #{ruby_version} && rake`
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'run bundle install for all rubies'
|
29
|
+
task :prepare_rubies do
|
30
|
+
rubies.each do |ruby_version|
|
31
|
+
puts `rvm use #{ruby_version} && gem install bundler && bundle`
|
32
|
+
end
|
33
|
+
end
|
data/bagger.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "bagger/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "bagger"
|
7
|
+
s.version = Bagger::VERSION
|
8
|
+
s.authors = ["Patrick Huesler"]
|
9
|
+
s.email = ["patrick.huesler@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = "Asset packaging for the rest of us"
|
12
|
+
s.description = "A framework agnostic packaging solution for your assets: version files, combine them, minify them and create a manifest"
|
13
|
+
|
14
|
+
s.rubyforge_project = "bagger"
|
15
|
+
|
16
|
+
s.add_dependency "json"
|
17
|
+
s.add_dependency "addressable"
|
18
|
+
s.add_dependency "uglifier"
|
19
|
+
s.add_dependency "rainpress"
|
20
|
+
|
21
|
+
s.add_development_dependency "rake"
|
22
|
+
s.add_development_dependency "shoulda-context"
|
23
|
+
s.add_development_dependency "mocha"
|
24
|
+
|
25
|
+
s.files = `git ls-files`.split("\n")
|
26
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
27
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'json'
|
3
|
+
require 'digest/md5'
|
4
|
+
require 'addressable/uri'
|
5
|
+
require 'uglifier'
|
6
|
+
require 'rainpress'
|
7
|
+
|
8
|
+
module Bagger
|
9
|
+
class Packager
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
@options = options
|
13
|
+
@manifest_name = 'manifest.json'
|
14
|
+
@stylesheets = (@options[:combine] || {})[:stylesheets] || []
|
15
|
+
@javascripts = (@options[:combine] || {})[:javascripts] || []
|
16
|
+
@source_dir = @options[:source_dir]
|
17
|
+
@target_dir = @options[:target_dir]
|
18
|
+
@stylesheet_path = (@options[:combine] || {})[:stylesheet_path] || 'combined.css'
|
19
|
+
@javascript_path = (@options[:combine] || {})[:javascript_path] || 'combined.js'
|
20
|
+
@path_prefix = @options[:path_prefix] || ''
|
21
|
+
@manifest = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_manifest(path, keep_original = true)
|
25
|
+
content = File.open(File.join(@target_dir, path)) { |f| f.read }
|
26
|
+
extension = File.extname(path)
|
27
|
+
basename = File.basename(path, extension)
|
28
|
+
dirname = File.dirname(path)
|
29
|
+
FileUtils.mkdir_p(File.join(@target_dir, dirname))
|
30
|
+
md5 = Digest::MD5.hexdigest(content)
|
31
|
+
new_file_name = "#{basename}.#{md5}#{extension}"
|
32
|
+
new_file_path = File.join(@target_dir, dirname, new_file_name)
|
33
|
+
File.open(new_file_path, 'w') { |f| f.write content }
|
34
|
+
FileUtils.rm(File.join(@target_dir, path)) unless keep_original
|
35
|
+
manifest_key_path = File.expand_path("/#{dirname}/#{basename}#{extension}")
|
36
|
+
effective_path = File.expand_path(@path_prefix + "/" + File.join(dirname, new_file_name))
|
37
|
+
@manifest[manifest_key_path] = effective_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def manifest_path
|
41
|
+
File.join(@options[:source_dir], @manifest_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def run
|
45
|
+
combine_css
|
46
|
+
combine_js
|
47
|
+
version_files
|
48
|
+
rewrite_urls_in_css
|
49
|
+
compress_css
|
50
|
+
to_manifest(@stylesheet_path, false)
|
51
|
+
compress_js
|
52
|
+
to_manifest(@javascript_path, false)
|
53
|
+
generate_and_version_cache_manifest
|
54
|
+
write_manifest
|
55
|
+
end
|
56
|
+
|
57
|
+
def write_manifest
|
58
|
+
File.open(manifest_path, 'w') do |f|
|
59
|
+
f.write JSON.pretty_generate(@manifest)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def version_files
|
64
|
+
FileUtils.cd(@source_dir) do
|
65
|
+
Dir["**/*"].reject{ |f| f =~ /\.(css|js)$/ }.each do |path|
|
66
|
+
if File.directory? path
|
67
|
+
FileUtils.mkdir_p(File.join(@target_dir, path))
|
68
|
+
next
|
69
|
+
end
|
70
|
+
FileUtils.cp(path, File.join(@target_dir, path))
|
71
|
+
to_manifest(path, false)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def combine_css
|
77
|
+
combine_files(@stylesheets, @stylesheet_path)
|
78
|
+
end
|
79
|
+
|
80
|
+
def rewrite_urls_in_css
|
81
|
+
url_regex = /(^|[{;])(.*?url\(\s*['"]?)(.*?)(['"]?\s*\).*?)([;}]|$)/ui
|
82
|
+
behavior_regex = /behavior:\s*url/ui
|
83
|
+
data_regex = /^\s*data:/ui
|
84
|
+
input = File.open(File.join(@target_dir, @stylesheet_path)){|f| f.read}
|
85
|
+
output = input.gsub(url_regex) do |full_match|
|
86
|
+
pre, url_match, post = ($1 + $2), $3, ($4 + $5)
|
87
|
+
if behavior_regex.match(pre) || data_regex.match(url_match)
|
88
|
+
full_match
|
89
|
+
else
|
90
|
+
path = Addressable::URI.parse("/") + url_match
|
91
|
+
target_url = @manifest[path.to_s]
|
92
|
+
if target_url
|
93
|
+
pre + target_url + post
|
94
|
+
else
|
95
|
+
full_match
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
File.open(File.join(@target_dir, @stylesheet_path), 'w') do |f|
|
100
|
+
f.write output
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def compress_css
|
105
|
+
css = File.open(File.join(@target_dir, @stylesheet_path)){|f| f.read}
|
106
|
+
compressed = Rainpress.compress(css)
|
107
|
+
File.open(File.join(@target_dir, @stylesheet_path), 'w') do |f|
|
108
|
+
f.write compressed
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def combine_js
|
113
|
+
combine_files(@javascripts, @javascript_path)
|
114
|
+
end
|
115
|
+
|
116
|
+
def compress_js
|
117
|
+
javascript = File.open(File.join(@target_dir, @javascript_path)){|f| f.read}
|
118
|
+
compressed = Uglifier.compile(javascript)
|
119
|
+
File.open(File.join(@target_dir, @javascript_path), 'w'){|f| f.write compressed}
|
120
|
+
end
|
121
|
+
|
122
|
+
def generate_and_version_cache_manifest
|
123
|
+
File.open(File.join(@target_dir, 'cache.manifest'), 'w') do |f|
|
124
|
+
f.puts 'CACHE MANIFEST'
|
125
|
+
f.puts ''
|
126
|
+
f.puts '# Explicitely cached entries'
|
127
|
+
f.puts @manifest.values.join("\n")
|
128
|
+
f.puts ''
|
129
|
+
f.puts 'NETWORK:'
|
130
|
+
f.puts '*'
|
131
|
+
end
|
132
|
+
to_manifest('cache.manifest')
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def combine_files(files, path)
|
138
|
+
output = ''
|
139
|
+
FileUtils.mkdir_p(File.join(@target_dir, File.dirname(path)))
|
140
|
+
target_path = File.join(@target_dir, path)
|
141
|
+
files.each do |file|
|
142
|
+
output << File.open(File.join(@source_dir, file)) { |f| f.read }
|
143
|
+
output << "\n"
|
144
|
+
end
|
145
|
+
File.open(target_path, "w") { |f| f.write(output) }
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
data/lib/bagger.rb
ADDED
data/test/bagger_test.rb
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class BaggerTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@source_dir = Dir.mktmpdir
|
8
|
+
@target_dir = Dir.mktmpdir
|
9
|
+
Uglifier.stubs(:compile).returns('//minfied js');
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
FileUtils.remove_entry_secure @source_dir
|
14
|
+
FileUtils.remove_entry_secure @target_dir
|
15
|
+
end
|
16
|
+
|
17
|
+
def write_file(path, content)
|
18
|
+
File.open(path, 'w') do |f|
|
19
|
+
f.write content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_options
|
24
|
+
{
|
25
|
+
:source_dir => @source_dir,
|
26
|
+
:target_dir => @target_dir,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def manifest
|
31
|
+
path = File.join(@source_dir, 'manifest.json')
|
32
|
+
json = File.open(path){|f| f.read}
|
33
|
+
JSON.parse(json)
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'manifest' do
|
37
|
+
should 'generate one' do
|
38
|
+
Bagger.bagit!(default_options)
|
39
|
+
assert File.exists?(File.join(@source_dir, 'manifest.json')), 'manifest was not created'
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'version files with md5' do
|
43
|
+
test_content = 'testcontent'
|
44
|
+
write_file(File.join(@source_dir, 'test.txt'), test_content)
|
45
|
+
Bagger.bagit!(default_options)
|
46
|
+
md5 = Digest::MD5.hexdigest(test_content)
|
47
|
+
assert_equal md5, manifest['/test.txt'].split('.')[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'copy over the versioned files' do
|
51
|
+
test_content = 'testcontent'
|
52
|
+
write_file(File.join(@source_dir, 'test.txt'), test_content)
|
53
|
+
Bagger.bagit!(default_options)
|
54
|
+
assert File.exists?(File.join(@target_dir, manifest['/test.txt']))
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'support a path prefix' do
|
58
|
+
test_content = 'testcontent'
|
59
|
+
write_file(File.join(@source_dir, 'test.txt'), test_content)
|
60
|
+
Bagger.bagit!(default_options.merge(:path_prefix => '/path_prefix'))
|
61
|
+
assert_match /\/path_prefix\/test\..*\.txt/, manifest['/test.txt']
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'html 5 cache manifest' do
|
66
|
+
should 'generate one' do
|
67
|
+
Bagger.bagit!(default_options)
|
68
|
+
expected_path = File.join(@target_dir, 'cache.manifest')
|
69
|
+
assert File.exists?(expected_path), 'cache manifest not found'
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'add the cache manifest to the manifest' do
|
73
|
+
Bagger.bagit!(default_options)
|
74
|
+
assert_match /\/cache\..*\.manifest/, manifest['/cache.manifest']
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'create a versioned cache manifest' do
|
78
|
+
Bagger.bagit!(default_options)
|
79
|
+
expected_path = File.join(@target_dir, manifest['/cache.manifest'])
|
80
|
+
assert File.exists?(expected_path), 'versioned cache manifest not found'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'css files' do
|
85
|
+
setup do
|
86
|
+
@config = {
|
87
|
+
:stylesheets => [],
|
88
|
+
:stylesheet_path => 'css/combined.css'
|
89
|
+
}
|
90
|
+
@css_dir = File.join(@source_dir, 'css')
|
91
|
+
FileUtils.mkdir_p(@css_dir)
|
92
|
+
%w(one two).each do |file|
|
93
|
+
write_file(
|
94
|
+
File.join(@css_dir, "#{file}.css"),
|
95
|
+
".#{file}{}"
|
96
|
+
)
|
97
|
+
@config[:stylesheets] << "css/#{file}.css"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'add it to the manifest' do
|
102
|
+
Bagger.bagit!(
|
103
|
+
:source_dir => @source_dir,
|
104
|
+
:target_dir => @target_dir,
|
105
|
+
:combine => @config
|
106
|
+
)
|
107
|
+
|
108
|
+
assert manifest['/css/combined.css']
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'combine it' do
|
112
|
+
Bagger.bagit!(
|
113
|
+
:source_dir => @source_dir,
|
114
|
+
:target_dir => @target_dir,
|
115
|
+
:combine => @config
|
116
|
+
)
|
117
|
+
expected_file_path = File.join(@target_dir, manifest['/css/combined.css'])
|
118
|
+
assert File.exists?(expected_file_path), 'combined css not found'
|
119
|
+
end
|
120
|
+
|
121
|
+
should 'only copy over the generate files' do
|
122
|
+
Bagger.bagit!(
|
123
|
+
:source_dir => @source_dir,
|
124
|
+
:target_dir => @target_dir,
|
125
|
+
:combine => @config
|
126
|
+
)
|
127
|
+
assert !File.exists?(File.join(@target_dir, 'css', 'one.css'))
|
128
|
+
end
|
129
|
+
|
130
|
+
should 'compress it' do
|
131
|
+
Rainpress.stubs(:compress).returns('//super minified css');
|
132
|
+
Bagger.bagit!(
|
133
|
+
:source_dir => @source_dir,
|
134
|
+
:target_dir => @target_dir,
|
135
|
+
:combine => @config
|
136
|
+
)
|
137
|
+
expected_file_path = File.join(@target_dir, manifest['/css/combined.css'])
|
138
|
+
compressed_content = File.open(expected_file_path){|f| f.read}
|
139
|
+
assert_equal '//super minified css', compressed_content , 'combined css not found'
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'url rewriting' do
|
143
|
+
setup do
|
144
|
+
css = <<-EOF
|
145
|
+
#documentRootBasedUrl {
|
146
|
+
background: url("/images/root.png") top center;
|
147
|
+
}
|
148
|
+
#relativeUrl {
|
149
|
+
background: url("../images/relative.png") top center;
|
150
|
+
}
|
151
|
+
#absoluteUrl {
|
152
|
+
background: url('http://localhost/absolute.png') top center;
|
153
|
+
}
|
154
|
+
EOF
|
155
|
+
write_file(File.join(@css_dir, "urled.css"), css)
|
156
|
+
@config[:stylesheets] << 'css/urled.css'
|
157
|
+
FileUtils.mkdir_p(File.join(@source_dir, 'images'))
|
158
|
+
%w(root relative absolute).each do |type|
|
159
|
+
FileUtils.touch(File.join(@source_dir, 'images', "#{type}.png"))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
should 'rewrite document root based urls' do
|
164
|
+
Bagger.bagit!(
|
165
|
+
:source_dir => @source_dir,
|
166
|
+
:target_dir => @target_dir,
|
167
|
+
:combine => @config
|
168
|
+
)
|
169
|
+
combined_css = File.open(File.join(@target_dir, manifest['/css/combined.css'])){|f| f.read}
|
170
|
+
assert combined_css.include?(manifest['/images/root.png'])
|
171
|
+
end
|
172
|
+
|
173
|
+
should 'rewrite relative (anchored by the css file) urls to absolute paths' do
|
174
|
+
Bagger.bagit!(
|
175
|
+
:source_dir => @source_dir,
|
176
|
+
:target_dir => @target_dir,
|
177
|
+
:combine => @config
|
178
|
+
)
|
179
|
+
combined_css = File.open(File.join(@target_dir, manifest['/css/combined.css'])){|f| f.read}
|
180
|
+
assert combined_css.include?(manifest['/images/relative.png'])
|
181
|
+
end
|
182
|
+
|
183
|
+
should 'not rewrite absolute urls' do
|
184
|
+
Bagger.bagit!(
|
185
|
+
:source_dir => @source_dir,
|
186
|
+
:target_dir => @target_dir,
|
187
|
+
:combine => @config
|
188
|
+
)
|
189
|
+
combined_css = File.open(File.join(@target_dir, manifest['/css/combined.css'])){|f| f.read}
|
190
|
+
assert combined_css.include?('http://localhost/absolute.png')
|
191
|
+
end
|
192
|
+
|
193
|
+
should 'support a path prefix' do
|
194
|
+
Bagger.bagit!(
|
195
|
+
:source_dir => @source_dir,
|
196
|
+
:target_dir => @target_dir,
|
197
|
+
:path_prefix => '/path_prefix',
|
198
|
+
:combine => @config
|
199
|
+
)
|
200
|
+
combined_css_path = manifest['/css/combined.css'].gsub(/path_prefix/,'')
|
201
|
+
combined_css = File.open(File.join(@target_dir, combined_css_path)){|f| f.read}
|
202
|
+
assert_match /\/path_prefix\/images\/relative\..*\.png/, combined_css
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'combine javascript' do
|
208
|
+
setup do
|
209
|
+
@config = {
|
210
|
+
:javascripts => [],
|
211
|
+
:javascript_path => 'js/combined.js'
|
212
|
+
}
|
213
|
+
@js_dir = File.join(@source_dir, 'js')
|
214
|
+
FileUtils.mkdir_p(@js_dir)
|
215
|
+
%w(one two).each do |file|
|
216
|
+
write_file(
|
217
|
+
File.join(@js_dir, "#{file}.js"),
|
218
|
+
"var #{file} = 1;"
|
219
|
+
)
|
220
|
+
@config[:javascripts] << "js/#{file}.js"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
should 'add it to the manifest' do
|
225
|
+
Bagger.bagit!(
|
226
|
+
:source_dir => @source_dir,
|
227
|
+
:target_dir => @target_dir,
|
228
|
+
:combine => @config
|
229
|
+
)
|
230
|
+
assert manifest['/js/combined.js']
|
231
|
+
end
|
232
|
+
|
233
|
+
should 'combine it' do
|
234
|
+
Bagger.bagit!(
|
235
|
+
:source_dir => @source_dir,
|
236
|
+
:target_dir => @target_dir,
|
237
|
+
:combine => @config
|
238
|
+
)
|
239
|
+
expected_file_path = File.join(@target_dir, manifest['/js/combined.js'])
|
240
|
+
assert File.exists?(expected_file_path), 'combined js not found'
|
241
|
+
end
|
242
|
+
|
243
|
+
should 'only copy over the generate files' do
|
244
|
+
Bagger.bagit!(
|
245
|
+
:source_dir => @source_dir,
|
246
|
+
:target_dir => @target_dir,
|
247
|
+
:combine => @config
|
248
|
+
)
|
249
|
+
assert !File.exists?(File.join(@target_dir, 'js', 'one.js'))
|
250
|
+
end
|
251
|
+
|
252
|
+
should 'compress the javascript' do
|
253
|
+
expected_path = File.join(@target_dir, 'js', 'combined.js')
|
254
|
+
Uglifier.expects(:compile).returns('//minified javascript')
|
255
|
+
|
256
|
+
Bagger.bagit!(
|
257
|
+
:source_dir => @source_dir,
|
258
|
+
:target_dir => @target_dir,
|
259
|
+
:combine => @config
|
260
|
+
)
|
261
|
+
expected_file_path = File.join(@target_dir, manifest['/js/combined.js'])
|
262
|
+
assert_equal '//minified javascript', File.open(expected_file_path){|f| f.read}
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift( File.join( File.dirname(__FILE__), "..", "lib") )
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha'
|
6
|
+
require 'shoulda-context'
|
7
|
+
require 'bagger'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
TEST_TEMP_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp'))
|
11
|
+
|
data/tests.watchr
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Run me with:
|
2
|
+
# $ watchr specs.watchr
|
3
|
+
|
4
|
+
# --------------------------------------------------
|
5
|
+
# Rules
|
6
|
+
# --------------------------------------------------
|
7
|
+
watch( '^test.*/test_.*\.rb' ) { |m| ruby m[0] }
|
8
|
+
watch( '^lib/(.*)\.rb' ) { |m| ruby "test/#{m[1]}_test.rb" }
|
9
|
+
watch( '^test/test_helper\.rb' ) { ruby tests }
|
10
|
+
watch( '^test/bagger_test\.rb' ) { ruby tests }
|
11
|
+
watch( '^lib/bagger\.rb' ) { ruby tests }
|
12
|
+
|
13
|
+
|
14
|
+
# --------------------------------------------------
|
15
|
+
# Signal Handling
|
16
|
+
# --------------------------------------------------
|
17
|
+
Signal.trap('QUIT') { ruby tests } # Ctrl-\
|
18
|
+
Signal.trap('INT' ) { abort("\n") } # Ctrl-C
|
19
|
+
|
20
|
+
# --------------------------------------------------
|
21
|
+
# Helpers
|
22
|
+
# --------------------------------------------------
|
23
|
+
def ruby(*paths)
|
24
|
+
run "ruby #{gem_opt} -I.:lib:test -e'%w( #{paths.flatten.join(' ')} ).each {|p| require p }'"
|
25
|
+
end
|
26
|
+
|
27
|
+
def tests
|
28
|
+
Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
def run( cmd )
|
32
|
+
puts cmd
|
33
|
+
system cmd
|
34
|
+
end
|
35
|
+
|
36
|
+
def gem_opt
|
37
|
+
defined?(Gem) ? "-rubygems" : ""
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bagger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Patrick Huesler
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &70307486940240 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70307486940240
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: addressable
|
27
|
+
requirement: &70307486939720 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70307486939720
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: uglifier
|
38
|
+
requirement: &70307486939180 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70307486939180
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rainpress
|
49
|
+
requirement: &70307486938540 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70307486938540
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rake
|
60
|
+
requirement: &70307486938000 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70307486938000
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: shoulda-context
|
71
|
+
requirement: &70307486937460 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70307486937460
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: mocha
|
82
|
+
requirement: &70307486936940 !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: *70307486936940
|
91
|
+
description: ! 'A framework agnostic packaging solution for your assets: version files,
|
92
|
+
combine them, minify them and create a manifest'
|
93
|
+
email:
|
94
|
+
- patrick.huesler@gmail.com
|
95
|
+
executables: []
|
96
|
+
extensions: []
|
97
|
+
extra_rdoc_files: []
|
98
|
+
files:
|
99
|
+
- .gitignore
|
100
|
+
- .travis.yml
|
101
|
+
- Gemfile
|
102
|
+
- README.md
|
103
|
+
- Rakefile
|
104
|
+
- bagger.gemspec
|
105
|
+
- lib/bagger.rb
|
106
|
+
- lib/bagger/packager.rb
|
107
|
+
- lib/bagger/version.rb
|
108
|
+
- test/bagger_test.rb
|
109
|
+
- test/test_helper.rb
|
110
|
+
- tests.watchr
|
111
|
+
homepage: ''
|
112
|
+
licenses: []
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project: bagger
|
131
|
+
rubygems_version: 1.8.6
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: Asset packaging for the rest of us
|
135
|
+
test_files:
|
136
|
+
- test/bagger_test.rb
|
137
|
+
- test/test_helper.rb
|