airgun 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjllNGU0ODM3YjNhMDUyNmU0YmMzNGM0NzFiY2UzMDNkZDA5MWM3NA==
5
+ data.tar.gz: !binary |-
6
+ ZWQwYzBmYzNlZTNlNzY5NTIzYjA1YTk0NjMwMmU4NzY1YmNhMjAwMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTEzYWIxYjBmYTBiZWExYjA2ZWI3ZjViYTY3NTlkMzliYzg4ZjdhZDczMGNk
10
+ NDJlNGIxOTU5YzY4OTAxNjY0YTFlZjEzOTcwMzNhMjc1ZDE1MGE1ZjkxODNk
11
+ ZmMwNzQ5ZGI2N2NmZmYyOGMyMzliNDdjNjc5YTRlNThmZDRkYWE=
12
+ data.tar.gz: !binary |-
13
+ MDUyYjVmYTcxZGQ1ZDU1NmJiYmRlNjM4OGZkYzhiYzA5YTA5NTc0ZGI4N2Fj
14
+ OTkyODRiOTk3OGYyM2QyNWY3YmVmYWIxZDZhZDAxYTI3NjlhY2QxMmI5ZmQ5
15
+ YzI0YzIxYTAwMmIxNGMzYjFhMTVmNzkyNTc3NTNkOTlmZTljYTc=
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - rbx-18mode
4
+ - rbx-19mode
5
+ - jruby-18mode
6
+ - jruby-19mode
7
+ - 1.8.7
8
+ - 1.9.2
9
+ - 1.9.3
10
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+ gemspec
3
+
@@ -0,0 +1,7 @@
1
+ Copyright (C) 2013 Peter Bakkum
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # Airgun [![Build Status](https://secure.travis-ci.org/bakks/airgun.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/bakks/airgun.png?travis)][gemnasium]
2
+
3
+ [travis]: http://travis-ci.org/bakks/airgun
4
+ [gemnasium]: https://gemnasium.com/bakks/airgun
5
+
6
+ This gem provides a simple Ruby interface to compress HTML, JS, and CSS, including embedded JS and CSS. This is useful for compressing static web content for size and obfuscation.
7
+
8
+ ```ruby
9
+ require 'airgun'
10
+ puts Airgun::html 'file.htm'
11
+
12
+ args = {
13
+ :outfile => 'compressed.htm',
14
+ :jscompressor => :closure,
15
+ :erb => true,
16
+ :compressjs => true,
17
+ :compresscss => false
18
+ }
19
+ Airgun::html 'file.htm', args
20
+ ```
21
+
22
+ HTML compresson is provided by the [html_compressor](https://github.com/completelynovel/html_compressor) gem after parsing with [Nokogiri](). CSS compression is provided by the [YUI Compressor](http://developer.yahoo.com/yui/compressor/). JS compression is provided by Google's [Closure Compiler](https://developers.google.com/closure/compiler/).
23
+
24
+ ## Documentation
25
+
26
+ __Airgun::html__ file, args
27
+
28
+ By default this method returns the compressed HTML as a string.
29
+
30
+ Possible arguments:
31
+
32
+ * :outfile - Write the compressor's output to this file.
33
+ * :exclude - Exclude the CSS and JS linked in the HTML page that match one of the filenames in this list.
34
+ * :jscompressor - Either :closure or :yui, defaults to :closure.
35
+ * :fragment - Either true or false. Don't parse with Nokogiri prior to compression, this disables JS and CSS compression.
36
+ * :erb - Either true or false. Run the files through ERB before compression.
37
+ * :compressjs - Either true or false, defaults to true.
38
+ * :compresscss - Either true or false, defaults to true.
39
+
40
+ __Airgun::js__ file, args
41
+
42
+ By default this method returns the compressed JS as a string.
43
+
44
+ Possible arguments:
45
+
46
+ * :compressor - Either :closure or :yui, defaults to :closure.
47
+ * :outfile - Write the compressor's output to this file.
48
+ * :erb - Run the file through ERB prior to compression
49
+
50
+ __Airgun::css__ file, args
51
+
52
+ By default this method returns the compressed CSS as a string.
53
+
54
+ Possible arguments:
55
+
56
+ * :outfile - Write the compressor's output to this file.
57
+ * :erb - Run the file through ERB prior to compression
58
+
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../lib/airgun", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.add_runtime_dependency 'nokogiri'
6
+ gem.add_runtime_dependency 'yui-compressor'
7
+ gem.add_runtime_dependency 'closure-compiler'
8
+ gem.add_runtime_dependency 'html_compressor'
9
+ gem.add_development_dependency 'rspec'
10
+ gem.add_development_dependency 'mocha'
11
+ gem.add_development_dependency 'autotest-standalone'
12
+
13
+ gem.authors = ["Peter Bakkum"]
14
+ gem.bindir = 'bin'
15
+ gem.description = %q{A simple interface to compress HTML, JS, and CSS, includig embedded JS and CSS, using several technologies, including the YUI Compressor and the Google Closure Compiler.}
16
+ gem.email = ['pbb7c@virginia.edu']
17
+ gem.executables = ['airgun']
18
+ gem.extra_rdoc_files = ['LICENSE.md', 'README.md']
19
+ gem.files = Dir['LICENSE.md', 'README.md', 'airgun.gemspec', 'Gemfile', '.rspec', '.travis.yml', 'spec/**/*', 'lib/**/*', 'bin/*']
20
+ gem.homepage = 'http://github.com/bakks/airgun'
21
+ gem.name = 'airgun'
22
+ gem.rdoc_options = ["--charset=UTF-8"]
23
+ gem.require_paths = ['lib']
24
+ gem.required_rubygems_version = Gem::Requirement.new(">= 1.3.6")
25
+ gem.summary = %q{An interface to compress HTML and embedded JS and CSS}
26
+ gem.test_files = Dir['spec/**/*']
27
+ gem.version = Airgun::VERSION
28
+ gem.license = 'MIT'
29
+ end
30
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require 'airgun'
6
+ require 'pp'
7
+
8
+ p = Trollop::Parser.new do
9
+ version "airgun #{Airgun::VERSION}"
10
+ banner <<-EOS
11
+ Airgun is a compressor for HTML and embedded/linked CSS and Javascript
12
+
13
+ Usage:
14
+ airgun [options] <filename>...
15
+
16
+ Example:
17
+ airgun -o compressed.htm file.htm
18
+
19
+ EOS
20
+
21
+ opt :outfile, "Write the compressor's output to this file", :default => 'airgun.out', :short => 'o'
22
+ opt :path, 'Path for dependencies', :type => String, :short => 'p'
23
+ opt :jscompressor, "Either closure or yui", :default => 'closure'
24
+ opt :fragment, "Don't parse with Nokogiri prior to compression, this disables JS and CSS compression", :default => false
25
+ opt :erb, "Run the files through ERB before compression", :default => false
26
+ opt :compressjs, "Run JS compression", :default => true
27
+ opt :compresscss, "Run CSS compression", :default => true
28
+ end
29
+
30
+ opts = Trollop::with_standard_exception_handling p do
31
+ raise Trollop::HelpNeeded if ARGV.empty?
32
+ p.parse ARGV
33
+ end
34
+
35
+ file = ARGV[0]
36
+ opts[:jscompressor] = opts[:jscompressor].to_sym
37
+
38
+ Airgun::html file, opts
39
+
@@ -0,0 +1,189 @@
1
+ require 'nokogiri'
2
+ require 'yui/compressor'
3
+ require 'closure-compiler'
4
+ require 'html_compressor'
5
+ require 'erb'
6
+
7
+ module Airgun
8
+ VERSION = "0.1.0"
9
+
10
+ def self.load file
11
+ File.open(file, 'r') { |f| f.read }
12
+ end
13
+
14
+ def self.path source, target, arg = {}
15
+ unless arg[:target]
16
+ arg[:target] = target[0] == '/' ? target : File.join(Dir.pwd, target)
17
+ end
18
+ unless arg[:htmlmatcher]
19
+ arg[:htmlmatcher] = /.*\.(htm|html)/
20
+ end
21
+ arg[:path] = Dir.pwd unless arg[:path]
22
+ arg[:exclude] = [] unless arg[:exclude]
23
+
24
+ Dir[File.join(source, '*')].each do |f|
25
+ if f =~ arg[:htmlmatcher]
26
+ arg = {
27
+ :exclude => arg[:exclude],
28
+ :path => arg[:path],
29
+ :outfile => File.join(arg[:target], f)
30
+ }
31
+
32
+ Airgun::html f, arg
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ def self.html htmlfile, arg = {}
39
+ arg[:outfile] = nil unless arg[:outfile]
40
+ arg[:exclude] = [] unless arg[:exclude]
41
+ arg[:jscompressor] = :closure unless arg[:jscompressor]
42
+ arg[:fragment] = false unless arg[:fragment]
43
+ arg[:erb] = false unless arg[:erb]
44
+ arg[:compressjs] = true unless arg[:compressjs]
45
+ arg[:compresscss] = true unless arg[:compresscss]
46
+ arg[:path] = File.join(Dir.pwd, File.dirname(htmlfile)) unless arg[:path]
47
+
48
+ html = File.open(htmlfile, 'r') { |f| f.read }
49
+
50
+ html = ERB.new(html).result(binding) if arg[:erb]
51
+
52
+ doc = html
53
+
54
+ unless arg[:fragment]
55
+ doc = Nokogiri::HTML(html)
56
+ a = {
57
+ :exclude => arg[:exclude],
58
+ :path => arg[:path]
59
+ }
60
+
61
+ Airgun::css doc, a if arg[:compresscss]
62
+
63
+ a[:compressor] = arg[:jscompressor]
64
+ Airgun::js doc, a if arg[:compresscss]
65
+ end
66
+
67
+ s = doc.to_s
68
+ s = HtmlCompressor::HtmlCompressor.new.compress(s)
69
+
70
+ if arg[:outfile]
71
+ File.open(arg[:outfile], 'w') { |f| f.write(s) }
72
+ end
73
+
74
+ s
75
+ end
76
+
77
+ def self.include? arr, str
78
+ arr.any? do |x|
79
+ if x.is_a? String
80
+ r = (str == x)
81
+ elsif x.is_a? Regexp
82
+ r = (str =~ x)
83
+ else raise "cant check #{x}"
84
+ end
85
+ r
86
+ end
87
+ end
88
+
89
+ def self.css doc, arg = {}
90
+ arg[:exclude] = [] unless arg[:exclude]
91
+ arg[:path] = '' unless arg[:path]
92
+ arg[:erb] = false unless arg[:erb]
93
+
94
+ if doc.kind_of? Nokogiri::XML::Node
95
+ c = YUI::CssCompressor.new
96
+ files = []
97
+
98
+ doc.xpath("//link[@rel='stylesheet']").each do |node|
99
+ next unless node['href']
100
+ if include? arg[:exclude], node['href']
101
+ puts "excluding #{node['href']}"
102
+ node.remove
103
+ next
104
+ end
105
+ files << node['href']
106
+
107
+ puts "expanding #{node['href']}"
108
+ css = c.compress(File.open(File.join(arg[:path], node['href'])))
109
+ n = Nokogiri::XML::Node.new('style', doc)
110
+ n.content = css
111
+ node.add_next_sibling n
112
+ node.remove
113
+ end
114
+
115
+ doc.xpath("//style").each do |node|
116
+ node.content = c.compress(node.content)
117
+ end
118
+ else
119
+ c = YUI::CssCompressor.new
120
+ s = File.open(doc, 'r') { |f| f.read }
121
+ s = ERB.new(s).result(binding) if arg[:erb]
122
+ s = c.compress(s)
123
+
124
+ if arg[:outfile]
125
+ File.open(arg[:outfile], 'w') { |f| f.write(s) }
126
+ end
127
+
128
+ return s
129
+ end
130
+ end
131
+
132
+ def self.js doc, arg = {}
133
+ arg[:compressor] = :closure unless arg[:compressor]
134
+ arg[:exclude] = [] unless arg[:exclude]
135
+ arg[:path] = '' unless arg[:path]
136
+ arg[:erb] = false unless arg[:erb]
137
+
138
+ if doc.kind_of? Nokogiri::XML::Node
139
+ c = nil
140
+
141
+ if arg[:compressor] == :closure
142
+ c = Closure::Compiler.new :language_in => 'ECMASCRIPT5'
143
+ elsif arg[:compressor] == :yui
144
+ c = YUI::JavaScriptCompressor.new
145
+ else
146
+ raise ':compressor should be set to either :closure (default) or :yui'
147
+ end
148
+
149
+ doc.xpath('//script').each do |node|
150
+ if include? arg[:exclude], node['src']
151
+ puts "excluding #{node['src']}"
152
+ node.remove
153
+ next
154
+ end
155
+
156
+ if node['src']
157
+ puts "expanding #{node['src']}"
158
+ js = c.compress(File.open(File.join(arg[:path], node['src'])))
159
+ node.remove_attribute 'src'
160
+ node.content = js
161
+ else
162
+ node.content = c.compress(node.text)
163
+ end
164
+ end
165
+ else
166
+ c = nil
167
+
168
+ if arg[:compressor] == :closure
169
+ c = Closure::Compiler.new :language_in => 'ECMASCRIPT5'
170
+ elsif arg[:compressor] == :yui
171
+ c = YUI::JavaScriptCompressor.new
172
+ else
173
+ raise 'compressor setting is bad'
174
+ end
175
+
176
+ s = File.open(doc, 'r') { |f| f.read }
177
+ s = ERB.new(s).result(binding) if arg[:erb]
178
+ s = c.compress(s)
179
+
180
+ if arg[:outfile]
181
+ File.open(arg[:outfile], 'w') { |f| f.write(s) }
182
+ end
183
+
184
+ return s
185
+ end
186
+ end
187
+
188
+ end
189
+
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rubygems'
4
+ require 'rspec'
5
+ require 'mocha'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :mocha
9
+ config.fail_fast = true
10
+ end
11
+
12
+
@@ -0,0 +1,81 @@
1
+ require 'helper'
2
+ require 'airgun'
3
+
4
+ describe Airgun do
5
+
6
+ it 'should handle basic html compression' do
7
+ r = Airgun::html 'spec/resources/test1.htm'
8
+ r.should_not == nil
9
+ r.include?('16').should == false
10
+ end
11
+
12
+ it 'should run erb' do
13
+ a = {
14
+ :erb => true
15
+ }
16
+ r = Airgun::html 'spec/resources/test1.htm', a
17
+ r.include?('64').should == true
18
+ end
19
+
20
+ it 'should handle embedded and linked css compression' do
21
+ a = {
22
+ :erb => true
23
+ }
24
+ r = Airgun::html 'spec/resources/test2.htm', a
25
+ r.include?('64').should == true
26
+ r.include?('#one').should == true
27
+ r.include?('#four').should == true
28
+ end
29
+
30
+ it 'should handle embedded js and linked js with Closure' do
31
+ a = {
32
+ :erb => true,
33
+ :compressor => :closure
34
+ }
35
+ r = Airgun::html 'spec/resources/test3.htm', a
36
+ r.include?('64').should == true
37
+ r.include?('alert("one")').should == true
38
+ r.include?('alert("two")').should == true
39
+ end
40
+
41
+ it 'should handle embedded and linked js with YUI' do
42
+ a = {
43
+ :erb => false,
44
+ :compressor => :yui
45
+ }
46
+ r = Airgun::html 'spec/resources/test3.htm', a
47
+ r.include?('64').should == false
48
+ r.include?('alert("one")').should == true
49
+ r.include?('alert("two")').should == true
50
+ end
51
+
52
+ it 'should handle direct css with file write' do
53
+ fname = '/tmp/compressed.css'
54
+ File.delete fname if File.exist? fname
55
+
56
+ a = {
57
+ :outfile => fname
58
+ }
59
+
60
+ Airgun::css 'spec/resources/css/test2.css', a
61
+
62
+ content = File.open(fname) { |f| f.read }
63
+ content.include?('#four').should == true
64
+ end
65
+
66
+ it 'should handle direct js with file write' do
67
+ fname = '/tmp/compressed.js'
68
+ File.delete fname if File.exist? fname
69
+
70
+ a = {
71
+ :outfile => fname
72
+ }
73
+
74
+ Airgun::js 'spec/resources/js/test3.js', a
75
+
76
+ content = File.open(fname) { |f| f.read }
77
+ content.include?('alert("two")').should == true
78
+ end
79
+
80
+ end
81
+
@@ -0,0 +1,9 @@
1
+ #four {
2
+ color: #000;
3
+ }
4
+ .five {
5
+ background-color: #ccc;
6
+ }
7
+ a .six {
8
+ font-family: 'Arial', sans-serif;
9
+ }
@@ -0,0 +1,2 @@
1
+ if(10 * 10 == 100)
2
+ alert('two')
@@ -0,0 +1,13 @@
1
+ <!doctype HTML>
2
+ <html>
3
+ <head>
4
+ <title>Test Page</title>
5
+ </head>
6
+ <body>
7
+ hello world
8
+ <br/>
9
+ this is a test for a very simple html page with no js or css
10
+ <br/>
11
+ <%= (8 * 8).to_s %>
12
+ </body>
13
+ </html>
@@ -0,0 +1,25 @@
1
+ <!doctype HTML>
2
+ <html>
3
+ <head>
4
+ <title>Test Page</title>
5
+ <style>
6
+ #one {
7
+ color: #000;
8
+ }
9
+ .two {
10
+ background-color: #ccc;
11
+ }
12
+ a .three {
13
+ font-family: 'Arial', sans-serif;
14
+ }
15
+ </style>
16
+ <link rel="stylesheet" href="/css/test2.css"/>
17
+ </head>
18
+ <body>
19
+ hello world
20
+ <br/>
21
+ this is a test for a very simple html page with css
22
+ <br/>
23
+ <%= (8 * 8).to_s %>
24
+ </body>
25
+ </html>
@@ -0,0 +1,18 @@
1
+ <!doctype HTML>
2
+ <html>
3
+ <head>
4
+ <title>Test Page</title>
5
+ <script type="text/javascript">
6
+ if(true)
7
+ alert('one');
8
+ </script>
9
+ <script type="text/javascript" src="js/test3.js"></script>
10
+ </head>
11
+ <body>
12
+ hello world
13
+ <br/>
14
+ this is a test for a very simple html page with js
15
+ <br/>
16
+ <%= (8 * 8).to_s %>
17
+ </body>
18
+ </html>
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: airgun
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Peter Bakkum
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yui-compressor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: closure-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: html_compressor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mocha
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: autotest-standalone
99
+ requirement: !ruby/object:Gem::Requirement
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
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A simple interface to compress HTML, JS, and CSS, includig embedded JS
112
+ and CSS, using several technologies, including the YUI Compressor and the Google
113
+ Closure Compiler.
114
+ email:
115
+ - pbb7c@virginia.edu
116
+ executables:
117
+ - airgun
118
+ extensions: []
119
+ extra_rdoc_files:
120
+ - LICENSE.md
121
+ - README.md
122
+ files:
123
+ - LICENSE.md
124
+ - README.md
125
+ - airgun.gemspec
126
+ - Gemfile
127
+ - .rspec
128
+ - .travis.yml
129
+ - spec/helper.rb
130
+ - spec/lib/airgun_spec.rb
131
+ - spec/resources/css/test2.css
132
+ - spec/resources/js/test3.js
133
+ - spec/resources/test1.htm
134
+ - spec/resources/test2.htm
135
+ - spec/resources/test3.htm
136
+ - lib/airgun.rb
137
+ - bin/airgun
138
+ homepage: http://github.com/bakks/airgun
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options:
144
+ - --charset=UTF-8
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: 1.3.6
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.0.3
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: An interface to compress HTML and embedded JS and CSS
163
+ test_files:
164
+ - spec/helper.rb
165
+ - spec/lib/airgun_spec.rb
166
+ - spec/resources/css/test2.css
167
+ - spec/resources/js/test3.js
168
+ - spec/resources/test1.htm
169
+ - spec/resources/test2.htm
170
+ - spec/resources/test3.htm
171
+ has_rdoc: