gumbo 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.
@@ -0,0 +1,19 @@
1
+ *.swp
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ examples/**/public
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.3@gumbo --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gumbo.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Paul Barry
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ # Gumbo
2
+
3
+ Gumbo is a standalone asset packager for creating HTML files that link to a single CSS and single JS file, which includes an MD5 in the file name to make the asset package files cacheable for indefinite amounts of time.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'gumbo'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install gumbo
18
+
19
+ ## Usage
20
+
21
+ To see an example of how this works, look at `examples/todo`. To build the assets, in that directory, run:
22
+
23
+ $ gumbo
24
+
25
+ To make changes and have them automatically built, you can install `guard-shell` and run:
26
+
27
+ $ guard
28
+
29
+ The way is works is that you put your assets in the `assets` directory. In the `assets` directory, there is a `packages.yml` file that looks like:
30
+
31
+ js:
32
+ todo:
33
+ - todo.coffee
34
+ - templates/todo.eco
35
+
36
+ css:
37
+ todo:
38
+ - reset.css
39
+ - style.css
40
+
41
+ What this means is that there is one js package called todo and one css package called todo. When the assets are built, they will be put into a directory called `public` along side `assets`.
42
+
43
+ Static HTML files can be generated from dynamic content using the [Liquid][liquid] templating language. In this example, the names of the asset packages with an MD5 timestamp of the contents are included in the resulting HTML file that is created in the `public` directory.
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
52
+
53
+ [liquid]: http://liquidmarkup.org/
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ * non-css, non-js
2
+ * liquid rendering
3
+ * write the asset_manifest.json to the public dir
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "gumbo"
4
+
5
+ Gumbo::CLI.run(ARGV)
@@ -0,0 +1,3 @@
1
+ body {
2
+ margin: 10px auto;
3
+ }
@@ -0,0 +1,3 @@
1
+ p {
2
+ padding: 10px 0;
3
+ }
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>Gumbo</title>
4
+ <script type="text/javascript" src="{% asset_package "application.js" %}"></script>
5
+ </head>
6
+ <body>
7
+ <h1>Gumbo</h1>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ bar = -> "bar!"
@@ -0,0 +1 @@
1
+ foo = -> "foo"
@@ -0,0 +1 @@
1
+ <h1><%= @title %></h1>
@@ -0,0 +1,13 @@
1
+ js:
2
+ application:
3
+ - foo.coffee
4
+ - bar.coffee
5
+
6
+ fancy:
7
+ - foo.coffee
8
+ - templates/home.eco
9
+
10
+ css:
11
+ application:
12
+ - bar.css
13
+ - foo.css
@@ -0,0 +1,5 @@
1
+ guard :shell do
2
+ watch /assets\/.*/ do
3
+ `../../bin/gumbo`
4
+ end
5
+ end
@@ -0,0 +1,48 @@
1
+ /* http://meyerweb.com/eric/tools/css/reset/
2
+ v2.0 | 20110126
3
+ License: none (public domain)
4
+ */
5
+
6
+ html, body, div, span, applet, object, iframe,
7
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8
+ a, abbr, acronym, address, big, cite, code,
9
+ del, dfn, em, img, ins, kbd, q, s, samp,
10
+ small, strike, strong, sub, sup, tt, var,
11
+ b, u, i, center,
12
+ dl, dt, dd, ol, ul, li,
13
+ fieldset, form, label, legend,
14
+ table, caption, tbody, tfoot, thead, tr, th, td,
15
+ article, aside, canvas, details, embed,
16
+ figure, figcaption, footer, header, hgroup,
17
+ menu, nav, output, ruby, section, summary,
18
+ time, mark, audio, video {
19
+ margin: 0;
20
+ padding: 0;
21
+ border: 0;
22
+ font-size: 100%;
23
+ font: inherit;
24
+ vertical-align: baseline;
25
+ }
26
+ /* HTML5 display-role reset for older browsers */
27
+ article, aside, details, figcaption, figure,
28
+ footer, header, hgroup, menu, nav, section {
29
+ display: block;
30
+ }
31
+ body {
32
+ line-height: 1;
33
+ }
34
+ ol, ul {
35
+ list-style: none;
36
+ }
37
+ blockquote, q {
38
+ quotes: none;
39
+ }
40
+ blockquote:before, blockquote:after,
41
+ q:before, q:after {
42
+ content: '';
43
+ content: none;
44
+ }
45
+ table {
46
+ border-collapse: collapse;
47
+ border-spacing: 0;
48
+ }
@@ -0,0 +1,7 @@
1
+ body {
2
+ margin: 25px auto;
3
+ }
4
+
5
+ #container {
6
+ width: 800px;
7
+ }
@@ -0,0 +1,20 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Todo</title>
5
+ <link rel="stylesheet" type="text/css" href="{% asset_package todo.css %}" />
6
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>
7
+ <script type="text/javascript" src="{% asset_package todo.js %}"></script>
8
+ </head>
9
+ <body>
10
+ <div id="container">
11
+ <h1>Todo</h1>
12
+ <form id="add-todo">
13
+ <label for="todo">Todo</label>
14
+ <input id="todo" type="text" name="todo" size="50"/>
15
+ <button type="submit">Add</button>
16
+ </form>
17
+ <ul id="todos"></ul>
18
+ </div>
19
+ </body>
20
+ </html>
@@ -0,0 +1 @@
1
+ <li><%= @name %></li>
@@ -0,0 +1,7 @@
1
+ $ =>
2
+ $('#add-todo').submit (e) ->
3
+ e.preventDefault()
4
+ e.stopPropagation()
5
+ $('#todos').append(JST["templates/todo"](name: $('#todo').val()))
6
+ false
7
+
@@ -0,0 +1,9 @@
1
+ js:
2
+ todo:
3
+ - todo.coffee
4
+ - templates/todo.eco
5
+
6
+ css:
7
+ todo:
8
+ - reset.css
9
+ - style.css
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.authors = ["Paul Barry"]
4
+ gem.email = ["mail@paulbarry.com"]
5
+ gem.description = %q{A standalone asset packager}
6
+ gem.summary = %q{A standalone asset packager}
7
+ gem.homepage = "http://github.com/pjb3/gumbo"
8
+
9
+ gem.files = `git ls-files`.split($\)
10
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
11
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
12
+ gem.name = "gumbo"
13
+ gem.require_paths = ["lib"]
14
+ gem.version = "0.0.1"
15
+
16
+ gem.add_runtime_dependency "coffee-script", "~> 2.2.0"
17
+ gem.add_runtime_dependency "cssmin"
18
+ gem.add_runtime_dependency "eco"
19
+ gem.add_runtime_dependency "liquid", "~> 2.4.1"
20
+ gem.add_runtime_dependency "uglifier"
21
+ end
@@ -0,0 +1,13 @@
1
+ require "gumbo/logger"
2
+ require "gumbo/asset_builder"
3
+ require "gumbo/asset_file"
4
+ require "gumbo/asset_package"
5
+ require "gumbo/package_file"
6
+ require "gumbo/java_script_file"
7
+ require "gumbo/style_sheet_file"
8
+ require "gumbo/compile_to_java_script_file"
9
+ require "gumbo/coffee_script_file"
10
+ require "gumbo/eco_file"
11
+ require "gumbo/template_file"
12
+ require "gumbo/liquid_file"
13
+ require "gumbo/cli"
@@ -0,0 +1,169 @@
1
+ require 'fileutils'
2
+ require 'json'
3
+ require 'set'
4
+ require 'time'
5
+ require 'yaml'
6
+
7
+ module Gumbo
8
+ class AssetBuilder
9
+ DEFAULT_SOURCE_DIR = "assets"
10
+ DEFAULT_OUTPUT_DIR = "public"
11
+ DEFAULT_PACKAGES_FILE = "packages.yml"
12
+ DEFAULT_MANIFEST_FILE = "packages.json"
13
+
14
+ attr_accessor :source_dir, :output_dir, :packages_file, :manifest_file, :clean
15
+
16
+ def self.build(attrs={})
17
+ new(attrs).build
18
+ end
19
+
20
+ def initialize(attrs={})
21
+ self.clean = !!attrs[:clean]
22
+ self.source_dir = attrs.fetch(:source_dir, DEFAULT_SOURCE_DIR)
23
+ self.output_dir = attrs.fetch(:output_dir, DEFAULT_OUTPUT_DIR)
24
+ self.packages_file = File.join(source_dir, attrs.fetch(:packages_file, DEFAULT_PACKAGES_FILE))
25
+ self.manifest_file = File.join(output_dir, attrs.fetch(:manifest_file, DEFAULT_MANIFEST_FILE))
26
+ end
27
+
28
+ def build
29
+ clean_output_dir if clean
30
+ create_output_dir
31
+ build_package_files
32
+ build_packages
33
+ build_non_package_files
34
+ end
35
+
36
+ protected
37
+
38
+ def clean_output_dir
39
+ FileUtils.rm_r(output_dir) if File.exists?(output_dir)
40
+ end
41
+
42
+ def create_output_dir
43
+ FileUtils.mkdir_p(output_dir)
44
+ end
45
+
46
+ def build_package_files
47
+ file_packages.each do |file, packages|
48
+ package_files << file.source_file
49
+ if file.should_be_rebuilt?
50
+ file.build
51
+ packages.each{|p| packages_to_rebuild << p }
52
+ end
53
+ end
54
+ end
55
+
56
+ def build_packages
57
+ unless packages_to_rebuild.empty?
58
+ packages_to_rebuild.each do |package|
59
+ package.build
60
+ asset_packages[package.type] ||= {}
61
+ asset_packages[package.type][package.name] = package.file_name
62
+ end
63
+
64
+ new_manifest = File.exists?(manifest_file)
65
+ open(manifest_file, "w") do |f|
66
+ f << JSON.pretty_generate(asset_packages)
67
+ logger.info "#{new_manifest ? 'Created' : 'Updated'} #{manifest_file}"
68
+ end
69
+ end
70
+ end
71
+
72
+ def build_non_package_files
73
+ Dir["#{source_dir}/**/*"].each do |file|
74
+ unless File.directory?(file) || file == packages_file || package_files.include?(file)
75
+ asset_file = AssetFile.for(
76
+ :name => file.sub(/^#{source_dir}\//, ''),
77
+ :source_dir => source_dir,
78
+ :output_dir => output_dir,
79
+ :context => {
80
+ "asset_packages" => asset_packages
81
+ })
82
+ if !packages_to_rebuild.empty? || asset_file.should_be_rebuilt?
83
+ asset_file.build
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ # A Set of AssetPackage objects which need to be rebuilt
90
+ def packages_to_rebuild
91
+ @packages_to_rebuild ||= Set.new
92
+ end
93
+
94
+ # A Set of file names of all files that are part of at least one package
95
+ def package_files
96
+ @package_files ||= Set.new
97
+ end
98
+
99
+ # A Hash of package types to Hashes of package names to package file
100
+ # Example:
101
+ # {
102
+ # "js" => {
103
+ # "foo" => "foo-cff07015305f5bc4ffc30a216a676df2.js"
104
+ # }
105
+ # }
106
+ def asset_packages
107
+ @asset_packages ||= if File.exists?(manifest_file)
108
+ parse_file(manifest_file)
109
+ else
110
+ {}
111
+ end
112
+ end
113
+
114
+ # The definition of which files are in each package
115
+ # as parsed from the packages_file
116
+ def package_definitions
117
+ @package_definitions ||= parse_file(packages_file)
118
+ end
119
+
120
+ # Given a package_type and package_name, this will return
121
+ # the AssetPackage object representing those values,
122
+ # returning the same object on successive calls for the same
123
+ # package_type and package_name
124
+ def get_package_for(output_dir, package_type, package_name)
125
+ @packages ||= {}
126
+ @packages[package_type] ||= {}
127
+ @packages[package_type][package_name] ||= AssetPackage.new(
128
+ :output_dir => output_dir,
129
+ :type => package_type,
130
+ :name => package_name)
131
+ end
132
+
133
+ # A Hash of AssetFile to an Array of AssetPackage objects,
134
+ # representing the AssetPackages that an AssetFile belongs to
135
+ def file_packages
136
+ @file_packages ||= package_definitions.inject({}) do |file_packages, (package_type, package_definitions)|
137
+ package_definitions.each do |package_name, file_names|
138
+ package = get_package_for(output_dir, package_type, package_name)
139
+ file_names.each do |file_name|
140
+ file = PackageFile.for(
141
+ :source_dir => source_dir,
142
+ :output_dir => output_dir,
143
+ :type => package_type,
144
+ :name => file_name)
145
+ file_packages[file] ||= []
146
+ file_packages[file] << package
147
+ package.files << file
148
+ end
149
+ end
150
+ file_packages
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ def logger
157
+ Gumbo.logger
158
+ end
159
+
160
+ def parse_file(file)
161
+ case File.extname(file)
162
+ when '.yml', '.yaml' then YAML.load_file(file)
163
+ when '.json' then JSON.parse(File.read(file))
164
+ else raise "Unknown file type: #{file}"
165
+ end
166
+ end
167
+
168
+ end
169
+ end
@@ -0,0 +1,70 @@
1
+ require 'fileutils'
2
+
3
+ module Gumbo
4
+ class AssetFile
5
+ attr_accessor :source_dir, :output_dir, :name, :context
6
+ include FileUtils
7
+
8
+ def self.for(attrs={})
9
+ class_for(attrs[:name]).new(attrs)
10
+ end
11
+
12
+ def self.ext(*args)
13
+ @@extension_class_map ||= {}
14
+ if args.size == 1
15
+ @ext = args.first
16
+ @@extension_class_map[@ext] = self
17
+ end
18
+ @ext
19
+ end
20
+
21
+ def self.class_for(name)
22
+ @@extension_class_map[File.extname(name)] || self
23
+ end
24
+
25
+ def initialize(attrs={})
26
+ attrs.each do |k,v|
27
+ send("#{k}=", v)
28
+ end
29
+ end
30
+
31
+ def source_file
32
+ @source_file ||= File.join(source_dir, name)
33
+ end
34
+
35
+ def output_file
36
+ @output_file ||= File.join(output_dir, name)
37
+ end
38
+
39
+ def build
40
+ logger.info "#{source_file} -> #{output_file}"
41
+ mkdir_p File.dirname(output_file)
42
+ cp source_file, output_file
43
+ end
44
+
45
+ def replace_ext(path, ext)
46
+ parts = path.split('.')
47
+ parts.pop
48
+ parts << ext
49
+ parts.join('.')
50
+ end
51
+
52
+ def should_be_rebuilt?
53
+ !File.exists?(output_file) || File.mtime(source_file) > File.mtime(output_file)
54
+ end
55
+
56
+ def eql?(o)
57
+ o.is_a?(self.class) &&
58
+ o.name == name
59
+ end
60
+ alias == eql?
61
+
62
+ def hash
63
+ name.hash
64
+ end
65
+
66
+ def logger
67
+ Gumbo.logger
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,71 @@
1
+ require 'digest/md5'
2
+ require 'cssmin'
3
+ require 'uglifier'
4
+
5
+ module Gumbo
6
+ class AssetPackage
7
+ attr_accessor :output_dir, :type, :name, :files, :digest
8
+
9
+ def initialize(attrs={})
10
+ attrs.each do |k,v|
11
+ send("#{k}=", v)
12
+ end
13
+ end
14
+
15
+ def files
16
+ @files ||= Set.new
17
+ end
18
+
19
+ def file_name
20
+ @file_name ||= "#{name}-#{digest}.#{type}"
21
+ end
22
+
23
+ def output_file
24
+ @output_file ||= File.join(output_dir, file_name)
25
+ end
26
+
27
+ def build
28
+ out = ""
29
+ files.each do |file|
30
+ out << File.read(file.output_file)
31
+ out << "\n"
32
+ end
33
+
34
+ out = compress(out)
35
+
36
+ self.digest = Digest::MD5.hexdigest(out)
37
+
38
+ open(output_file, 'w') do |f|
39
+ f << out
40
+ end
41
+
42
+ logger.info "Created package #{output_file}"
43
+ end
44
+
45
+ def compress(out)
46
+ case type
47
+ when 'css'
48
+ CSSMin.minify(out)
49
+ when 'js'
50
+ Uglifier.compile(out, :mangle => true)
51
+ else
52
+ raise "Unknown package type '#{type}'"
53
+ end
54
+ end
55
+
56
+ def eql?(o)
57
+ o.is_a?(self.class) &&
58
+ o.type == type &&
59
+ o.name == name
60
+ end
61
+ alias == eql?
62
+
63
+ def hash
64
+ type.hash ^ name.hash
65
+ end
66
+
67
+ def logger
68
+ Gumbo.logger
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,49 @@
1
+ require 'optparse'
2
+
3
+ module Gumbo
4
+ class CLI
5
+
6
+ attr_accessor :options
7
+
8
+ def self.run(args)
9
+ new(args).run
10
+ end
11
+
12
+ def initialize(args)
13
+ @options = {}
14
+
15
+ OptionParser.new do |opts|
16
+ opts.banner = "Usage: gumbo [options]"
17
+
18
+ opts.on("-c", "--clean", "Delete the output directory before running") do |v|
19
+ @options[:clean] = v
20
+ end
21
+
22
+ opts.on("-h", "--help", "Display this message") do |h|
23
+ puts opts
24
+ exit
25
+ end
26
+
27
+ opts.on("-s", "--source-dir [SOURCE_DIR]", "the source directory, defaults to '#{Gumbo::AssetBuilder::DEFAULT_SOURCE_DIR}'") do |v|
28
+ @options[:source_dir] = v
29
+ end
30
+
31
+ opts.on("-o", "--output-dir [OUTPUT_DIR]", "the output directory, defaults to '#{Gumbo::AssetBuilder::DEFAULT_OUTPUT_DIR}'") do |v|
32
+ @options[:output_dir] = v
33
+ end
34
+
35
+ opts.on("-p", "--packages-file [PACKAGES_FILE]", "the packages file, relative to the source directory, defaults to '#{Gumbo::AssetBuilder::DEFAULT_PACKAGES_FILE}'") do |v|
36
+ @options[:packages_file] = v
37
+ end
38
+
39
+ opts.on("-m", "--manifest-file [MANIFEST_FILE]", "the manifest file, relative to the output directory, defaults to '#{Gumbo::AssetBuilder::DEFAULT_MANIFEST_FILE}'") do |v|
40
+ @options[:manifest_file] = v
41
+ end
42
+ end.parse(args)
43
+ end
44
+
45
+ def run
46
+ Gumbo::AssetBuilder.build(@options)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ require 'coffee_script'
2
+
3
+ module Gumbo
4
+ class CoffeeScriptFile < CompileToJavaScriptFile
5
+ ext ".coffee"
6
+ compiler CoffeeScript
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ module Gumbo
2
+ class CompileToJavaScriptFile < PackageFile
3
+ def output_file
4
+ @output_file ||= replace_ext(super, "js")
5
+ end
6
+
7
+ def build
8
+ logger.info "#{source_file} -> #{output_file}"
9
+ mkdir_p File.dirname(output_file)
10
+ open(output_file, 'w') do |out|
11
+ out << compile(File.read(source_file))
12
+ end
13
+ end
14
+
15
+ def compile(src)
16
+ self.class.compile(src)
17
+ end
18
+
19
+ def self.compile(src)
20
+ if compiler
21
+ compiler.compile(src)
22
+ else
23
+ raise "no compiler set for #{name}"
24
+ end
25
+ end
26
+
27
+ def self.compiler(*args)
28
+ if args.empty?
29
+ @compiler
30
+ else
31
+ @compiler = args.first
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ require 'eco'
2
+
3
+ module Gumbo
4
+ class EcoFile < CompileToJavaScriptFile
5
+ ext ".eco"
6
+
7
+ def compile(src)
8
+ "this.JST || (this.JST = {}); this.JST['#{name.sub(/.eco$/,'')}'] = #{Eco.compile(src)};"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module Gumbo
2
+ class JavaScriptFile < PackageFile
3
+ ext ".js"
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require 'liquid'
2
+
3
+ module Gumbo
4
+ class LiquidFile < TemplateFile
5
+ ext ".liquid"
6
+
7
+ def parse(src)
8
+ @template = Liquid::Template.parse(src)
9
+ end
10
+
11
+ def render(context)
12
+ @template.render(context)
13
+ end
14
+
15
+ class AssetPackageTag < Liquid::Tag
16
+ def initialize(tag_name, file_name, tokens)
17
+ super
18
+ @file_name = file_name
19
+ end
20
+
21
+ def render(context)
22
+ parts = @file_name.split('.')
23
+ ext = parts.pop.strip
24
+ name = parts.join('.')
25
+ context["asset_packages"][ext][name]
26
+ end
27
+ end
28
+
29
+ Liquid::Template.register_tag("asset_package", AssetPackageTag)
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ require 'logger'
2
+
3
+ module Gumbo
4
+ def self.logger
5
+ @logger ||= begin
6
+ logger = Logger.new(STDOUT)
7
+ logger.formatter = proc do |severity, datetime, progname, msg|
8
+ "#{msg}\n"
9
+ end
10
+ logger
11
+ end
12
+ end
13
+
14
+ def self.logger=(logger)
15
+ @logger = logger
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Gumbo
2
+ class PackageFile < AssetFile
3
+ attr_accessor :type
4
+
5
+ def source_file
6
+ @source_file ||= File.join(source_dir, type, name)
7
+ end
8
+
9
+ def output_file
10
+ @output_file ||= File.join(output_dir, type, name)
11
+ end
12
+
13
+ def eql?(o)
14
+ super && o.type == type
15
+ end
16
+ alias == eql?
17
+
18
+ def hash
19
+ super ^ type.hash
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module Gumbo
2
+ class StyleSheetFile < PackageFile
3
+ ext ".css"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ module Gumbo
2
+ class TemplateFile < AssetFile
3
+
4
+ def output_file
5
+ @output_file ||= super.sub(/\.liquid$/,'')
6
+ end
7
+
8
+ def build
9
+ logger.info "#{source_file} -> #{output_file}"
10
+ mkdir_p File.dirname(output_file)
11
+ open(output_file, 'w') do |out|
12
+ parse(File.read(source_file))
13
+ out << render(context)
14
+ end
15
+ end
16
+
17
+ def parse(src)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def render(context)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gumbo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Barry
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: coffee-script
16
+ requirement: &70252106829220 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70252106829220
25
+ - !ruby/object:Gem::Dependency
26
+ name: cssmin
27
+ requirement: &70252106828820 !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: *70252106828820
36
+ - !ruby/object:Gem::Dependency
37
+ name: eco
38
+ requirement: &70252106828360 !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: *70252106828360
47
+ - !ruby/object:Gem::Dependency
48
+ name: liquid
49
+ requirement: &70252106827860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.4.1
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70252106827860
58
+ - !ruby/object:Gem::Dependency
59
+ name: uglifier
60
+ requirement: &70252106827440 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70252106827440
69
+ description: A standalone asset packager
70
+ email:
71
+ - mail@paulbarry.com
72
+ executables:
73
+ - gumbo
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .rvmrc
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.md
82
+ - Rakefile
83
+ - TODO
84
+ - bin/gumbo
85
+ - examples/multiple/assets/css/bar.css
86
+ - examples/multiple/assets/css/foo.css
87
+ - examples/multiple/assets/index.html.liquid
88
+ - examples/multiple/assets/js/bar.coffee
89
+ - examples/multiple/assets/js/foo.coffee
90
+ - examples/multiple/assets/js/templates/home.eco
91
+ - examples/multiple/assets/packages.yml
92
+ - examples/todo/Guardfile
93
+ - examples/todo/assets/css/reset.css
94
+ - examples/todo/assets/css/style.css
95
+ - examples/todo/assets/index.html.liquid
96
+ - examples/todo/assets/js/templates/todo.eco
97
+ - examples/todo/assets/js/todo.coffee
98
+ - examples/todo/assets/packages.yml
99
+ - gumbo.gemspec
100
+ - lib/gumbo.rb
101
+ - lib/gumbo/asset_builder.rb
102
+ - lib/gumbo/asset_file.rb
103
+ - lib/gumbo/asset_package.rb
104
+ - lib/gumbo/cli.rb
105
+ - lib/gumbo/coffee_script_file.rb
106
+ - lib/gumbo/compile_to_java_script_file.rb
107
+ - lib/gumbo/eco_file.rb
108
+ - lib/gumbo/java_script_file.rb
109
+ - lib/gumbo/liquid_file.rb
110
+ - lib/gumbo/logger.rb
111
+ - lib/gumbo/package_file.rb
112
+ - lib/gumbo/style_sheet_file.rb
113
+ - lib/gumbo/template_file.rb
114
+ homepage: http://github.com/pjb3/gumbo
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.17
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: A standalone asset packager
138
+ test_files: []