bunch 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,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .sass-cache
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bunch.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'bunch'
5
+ require 'bunch/cli'
6
+
7
+ Bunch::CLI.process!
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bunch/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bunch"
7
+ s.version = Bunch::VERSION
8
+ s.authors = ["Ryan Fitzgerald"]
9
+ s.email = ["rwfitzge@gmail.com"]
10
+ s.homepage = "http://rynftz.gr"
11
+ s.summary = %q{Simple, directory-structure-based asset bundling.}
12
+ s.description = %q{Simple, directory-structure-based asset bundling.}
13
+
14
+ s.rubyforge_project = "bunch"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "mime-types"
22
+ s.add_runtime_dependency "slop"
23
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path('../lib', __FILE__)
2
+ require 'bunch'
3
+
4
+ run Rack::URLMap.new \
5
+ "/stylesheets" => Bunch::Rack.new('example/css'),
6
+ "/javascripts" => Bunch::Rack.new('example/js')
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'bunch'
3
+
4
+ run Rack::URLMap.new \
5
+ "/stylesheets" => Bunch::Rack.new('example/css'),
6
+ "/javascripts" => Bunch::Rack.new('example/js')
@@ -0,0 +1 @@
1
+ body { a: 1; }
@@ -0,0 +1 @@
1
+ body { b: 2; }
@@ -0,0 +1 @@
1
+ body { c: 3; }
@@ -0,0 +1 @@
1
+ 1
@@ -0,0 +1,2 @@
1
+ - test2a
2
+ - test2c
@@ -0,0 +1 @@
1
+ 2
@@ -0,0 +1 @@
1
+ 4
@@ -0,0 +1 @@
1
+ 3
@@ -0,0 +1 @@
1
+ 5
@@ -0,0 +1 @@
1
+ - test3bii
@@ -0,0 +1 @@
1
+ - test4c
@@ -0,0 +1 @@
1
+ 9
@@ -0,0 +1 @@
1
+ 10
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'yaml'
4
+
5
+ require 'mime/types'
6
+ require 'slop'
7
+
8
+ begin
9
+ require 'v8'
10
+ rescue LoadError
11
+ $stderr.puts "WARNING: 'gem install therubyracer' for much faster CoffeeScript compilation."
12
+ end
13
+
14
+ require 'bunch/version'
15
+ require 'bunch/directory_node'
16
+ require 'bunch/file_node'
17
+ require 'bunch/coffee_node'
18
+ require 'bunch/sass_node'
19
+ require 'bunch/rack'
20
+
21
+ module Bunch
22
+ end
23
+
24
+ class << Bunch
25
+ def Tree(fn)
26
+ case
27
+ when File.directory?(fn)
28
+ Bunch::DirectoryNode.new(fn)
29
+ when fn =~ /\.coffee$/
30
+ Bunch::CoffeeNode.new(fn)
31
+ when fn =~ /\.s(a|c)ss$/
32
+ Bunch::SassNode.new(fn)
33
+ else
34
+ Bunch::FileNode.new(fn)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,76 @@
1
+ module Bunch
2
+ class CLI
3
+ def initialize(input, output, opts)
4
+ @input = Pathname.new(input)
5
+ @output = output ? Pathname.new(output) : nil
6
+ @opts = opts
7
+ end
8
+
9
+ def process!
10
+ tree = Bunch::Tree(@input.to_s)
11
+
12
+ if @output
13
+ FileUtils.mkdir_p(@output.to_s)
14
+ end
15
+
16
+ if @opts[:all]
17
+ if @output
18
+ write(@output.join("all.#{tree.target_extension}"), tree.contents)
19
+ else
20
+ puts tree.contents
21
+ end
22
+ end
23
+
24
+ if @opts[:individual]
25
+ tree.children.each do |child|
26
+ write(@output.join("#{child.name}.#{child.target_extension}"), child.contents)
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+ def write(fn, contents)
33
+ File.open(fn, 'w') { |f| f.write(contents) }
34
+ end
35
+ end
36
+
37
+ class << CLI
38
+ def process!
39
+ opts = Slop.parse! do
40
+ banner 'Usage: bunch [options] INPUT_PATH [OUTPUT_PATH]'
41
+
42
+ on :i, :individual, 'Create one output file for each file or directory in the input path (default)', :default => true
43
+ on :a, :all, 'Create an all.[extension] file combining all inputs'
44
+ on :h, :help, 'Show this message' do
45
+ display_help = true
46
+ end
47
+ end
48
+
49
+ if ARGV.count < 1
50
+ $stderr.puts "ERROR: Must give an input path."
51
+ display_help = true
52
+ end
53
+
54
+ if ARGV.count < 2 && opts[:individual]
55
+ $stderr.puts "ERROR: Must give an output path unless --no-individual is provided."
56
+ display_help = true
57
+ end
58
+
59
+ if display_help
60
+ $stderr.puts "\n#{opts}"
61
+ exit
62
+ end
63
+
64
+ input = ARGV.shift
65
+ output = ARGV.shift
66
+
67
+ CLI.new(input, output, opts).process!
68
+ rescue Exception => e
69
+ if ENV['BUNCH_DEBUG']
70
+ raise
71
+ else
72
+ $stderr.puts "ERROR: #{e.message}"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,26 @@
1
+ module Bunch
2
+ class CoffeeNode
3
+ def initialize(fn)
4
+ require 'coffee-script'
5
+ @filename = fn
6
+ rescue LoadError
7
+ $stderr.puts "ERROR: 'gem install coffee-script' to compile .coffee files."
8
+ end
9
+
10
+ def contents
11
+ @contents ||= CoffeeScript.compile(File.read(@filename), :bare => false)
12
+ end
13
+
14
+ def name
15
+ File.basename(@filename, '.coffee')
16
+ end
17
+
18
+ def target_extension
19
+ 'js'
20
+ end
21
+
22
+ def inspect
23
+ @filename.inspect
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module Bunch
2
+ class DirectoryNode
3
+ attr_reader :root
4
+
5
+ def initialize(fn)
6
+ @root = Pathname.new(fn)
7
+ end
8
+
9
+ def filenames
10
+ Dir[@root.join("*")].select { |f| f !~ /_\.yml$/ }
11
+ end
12
+
13
+ def children
14
+ @children ||= begin
15
+ children = filenames.map &Bunch.method(:Tree)
16
+ ordering_file = @root.join('_.yml')
17
+
18
+ if File.exist?(ordering_file)
19
+ ordering = YAML.load_file(ordering_file)
20
+ ordered, unordered = children.partition { |c| ordering.include?(c.name) }
21
+ ordered.sort_by { |c| ordering.index(c.name) } + unordered.sort_by(&:name)
22
+ else
23
+ children.sort_by(&:name)
24
+ end
25
+ end
26
+ end
27
+
28
+ def target_extension
29
+ @target_extension ||= begin
30
+ exts = children.map(&:target_extension).compact.uniq
31
+ if exts.count == 1
32
+ exts.first
33
+ else
34
+ raise "Directory contains non-homogeneous nodes: #{exts.inspect}"
35
+ end
36
+ end
37
+ end
38
+
39
+ def contents
40
+ @contents ||= children.map(&:contents).join
41
+ end
42
+
43
+ def name
44
+ File.basename(@root)
45
+ end
46
+
47
+ def inspect
48
+ "#<Node @root=#{@root.inspect} @children=#{children.inspect}>"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ module Bunch
2
+ class FileNode
3
+ attr_reader :name, :target_extension
4
+
5
+ def initialize(fn)
6
+ @filename = fn
7
+
8
+ if fn =~ %r(\.([^/]*?)$)
9
+ @name = File.basename($`)
10
+ @target_extension = $1
11
+ else
12
+ @name = File.basename(@filename)
13
+ end
14
+ end
15
+
16
+ def contents
17
+ File.read(@filename)
18
+ end
19
+
20
+ def inspect
21
+ @filename.inspect
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ module Bunch
2
+ class Rack
3
+ def initialize(path)
4
+ @root = Pathname.new(path)
5
+ end
6
+
7
+ def call(env)
8
+ path = @root.join(env['PATH_INFO'].sub(/^\//, '')).to_s
9
+ type = MIME::Types.type_for(path).first || 'text/plain'
10
+
11
+ [ 200, { 'Content-Type' => type.to_s }, [ generate(path) ] ]
12
+ rescue => e
13
+ [ 500, { 'Content-Type' => 'text/plain' }, [ error_log(e) ] ]
14
+ end
15
+
16
+ private
17
+ def generate(path)
18
+ if File.exist?(path)
19
+ Bunch::Tree(path).contents
20
+ elsif File.exist?(chopped_path = path.sub(%r(\.[^/]*?$), ''))
21
+ Bunch::Tree(chopped_path).contents
22
+ elsif File.basename(path).start_with?('all.')
23
+ Bunch::Tree(File.dirname(path)).contents
24
+ else
25
+ raise Errno::ENOENT, path
26
+ end
27
+ end
28
+
29
+ def error_log(e)
30
+ "#{e.class}: #{e.message}\n #{e.backtrace.join("\n ")}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Bunch
2
+ class SassNode
3
+ def initialize(fn)
4
+ require 'sass'
5
+ @filename = fn
6
+ rescue LoadError
7
+ $stderr.puts "ERROR: 'gem install sass' to compile .coffee files."
8
+ end
9
+
10
+ def contents
11
+ @contents ||= Sass::Engine.for_file(@filename, {}).render
12
+ end
13
+
14
+ def name
15
+ File.basename(@filename).sub(/\.s(c|a)ss$/, '')
16
+ end
17
+
18
+ def target_extension
19
+ 'css'
20
+ end
21
+
22
+ def inspect
23
+ @filename.inspect
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Bunch
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bunch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Fitzgerald
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mime-types
16
+ requirement: &70324537243860 !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: *70324537243860
25
+ - !ruby/object:Gem::Dependency
26
+ name: slop
27
+ requirement: &70324537243440 !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: *70324537243440
36
+ description: Simple, directory-structure-based asset bundling.
37
+ email:
38
+ - rwfitzge@gmail.com
39
+ executables:
40
+ - bunch
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - Rakefile
47
+ - bin/bunch
48
+ - bunch.gemspec
49
+ - config.ru
50
+ - example/config.ru
51
+ - example/css/test1.css
52
+ - example/css/test2/test2a.scss
53
+ - example/css/test2/test2b.css
54
+ - example/js/test1.js
55
+ - example/js/test2/_.yml
56
+ - example/js/test2/test2a.js
57
+ - example/js/test2/test2b.js
58
+ - example/js/test2/test2c.js
59
+ - example/js/test3/test3a.js
60
+ - example/js/test3/test3b/_.yml
61
+ - example/js/test3/test3b/test3bi.js
62
+ - example/js/test3/test3b/test3bii.js
63
+ - example/js/test4/_.yml
64
+ - example/js/test4/test4a.js
65
+ - example/js/test4/test4b.coffee
66
+ - example/js/test4/test4c.coffee
67
+ - lib/bunch.rb
68
+ - lib/bunch/cli.rb
69
+ - lib/bunch/coffee_node.rb
70
+ - lib/bunch/directory_node.rb
71
+ - lib/bunch/file_node.rb
72
+ - lib/bunch/rack.rb
73
+ - lib/bunch/sass_node.rb
74
+ - lib/bunch/version.rb
75
+ homepage: http://rynftz.gr
76
+ licenses: []
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project: bunch
95
+ rubygems_version: 1.8.10
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Simple, directory-structure-based asset bundling.
99
+ test_files: []
100
+ has_rdoc: