bunch 0.0.6 → 0.0.7

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 CHANGED
@@ -3,3 +3,5 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  .sass-cache
6
+ .yardoc
7
+ doc/*
@@ -0,0 +1 @@
1
+ --markup markdown --private
@@ -0,0 +1,4 @@
1
+ Bunch: (Almost) configuration-free asset bundling.
2
+ ==================================================
3
+
4
+ <img src="http://i.imgur.com/QqufL.png">
data/Rakefile CHANGED
@@ -1 +1,18 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'yard'
5
+ YARD::Rake::YardocTask.new
6
+ rescue LoadError
7
+ end
8
+
9
+ require 'rake/testtask'
10
+
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task :default => :test
@@ -1,23 +1,26 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "bunch/version"
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'bunch/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = "bunch"
6
+ s.name = 'bunch'
7
7
  s.version = Bunch::VERSION
8
- s.authors = ["Ryan Fitzgerald"]
9
- s.email = ["rfitz@academia.edu"]
10
- s.homepage = ""
8
+ s.authors = ['Ryan Fitzgerald']
9
+ s.email = ['rfitz@academia.edu']
10
+ s.homepage = ''
11
11
  s.summary = %q{Directory-structure-based asset bundling.}
12
12
  s.description = %q{Directory-structure-based asset bundling.}
13
13
 
14
- s.rubyforge_project = "bunch"
14
+ s.rubyforge_project = 'bunch'
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib"]
19
+ s.require_paths = ['lib']
20
20
 
21
- s.add_runtime_dependency "mime-types"
22
- s.add_runtime_dependency "slop"
21
+ s.add_runtime_dependency 'mime-types'
22
+ s.add_runtime_dependency 'slop'
23
+
24
+ s.add_development_dependency 'yard'
25
+ s.add_development_dependency 'rdiscount'
23
26
  end
@@ -14,7 +14,9 @@ end
14
14
  require 'bunch/version'
15
15
  require 'bunch/rack'
16
16
  require 'bunch/middleware'
17
- require 'bunch/caching'
17
+ require 'bunch/cache'
18
+
19
+ require 'bunch/abstract_node'
18
20
  require 'bunch/directory_node'
19
21
  require 'bunch/file_node'
20
22
  require 'bunch/coffee_node'
@@ -41,7 +43,7 @@ class << Bunch
41
43
  end
42
44
  end
43
45
 
44
- private
46
+ protected
45
47
  def normalized_path(path)
46
48
  case
47
49
  when File.exist?(path)
@@ -57,14 +59,3 @@ class << Bunch
57
59
  end
58
60
  end
59
61
  end
60
-
61
- #class Module
62
- # def benchmark(meth)
63
- # alias_method "#{meth}_old", meth
64
- # define_method meth do |*args, &blk|
65
- # t = Time.now
66
- # send "#{meth}_old", *args, &blk
67
- # STDERR.puts "Called #{meth} in #{Time.now - t}."
68
- # end
69
- # end
70
- #end
@@ -0,0 +1,23 @@
1
+ module Bunch
2
+ class AbstractNode
3
+ def content
4
+ raise NotImplementedError
5
+ end
6
+ alias name content
7
+ alias target_extension content
8
+
9
+ def write_to_dir(dir)
10
+ write_to_file(File.join(dir, name))
11
+ end
12
+
13
+ def write_to_file(fn)
14
+ out_file = "#{fn}#{target_extension}"
15
+ File.open(out_file, 'w') { |f| f.write(content) }
16
+ end
17
+
18
+ protected
19
+ def fetch(fn, &blk)
20
+ Cache.fetch(fn, &blk)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module Bunch
2
+ module Cache
3
+ end
4
+
5
+ class << Cache
6
+ def initialize
7
+ @cache = Hash.new { |h, k| h[k] = {} }
8
+ end
9
+
10
+ def stored?(fn)
11
+ @cache.keys.include?(fn)
12
+ end
13
+
14
+ def read(fn)
15
+ @cache[fn][:content]
16
+ end
17
+
18
+ def mtime(fn)
19
+ @cache[fn][:mtime]
20
+ end
21
+
22
+ def write(fn, mtime, content)
23
+ @cache[fn] = {:mtime => mtime, :content => content}
24
+ end
25
+
26
+ def fetch(fn, &blk)
27
+ current_mtime = File.mtime(fn)
28
+
29
+ if stored?(fn) && mtime(fn) == current_mtime
30
+ read(fn)
31
+ else
32
+ content = blk.call
33
+ write(fn, current_mtime, content)
34
+ content
35
+ end
36
+ end
37
+ end
38
+
39
+ Cache.initialize
40
+ end
@@ -5,10 +5,6 @@ module Bunch
5
5
  @output = output ? Pathname.new(output) : nil
6
6
  @opts = opts
7
7
 
8
- if @opts[:profile]
9
- require 'profile'
10
- end
11
-
12
8
  if @opts[:server]
13
9
  run_server
14
10
  else
@@ -33,7 +29,7 @@ module Bunch
33
29
 
34
30
  if @opts[:all]
35
31
  if @output
36
- write("all.#{tree.target_extension}", tree.content)
32
+ tree.write_to_file(@output.join('all'))
37
33
  else
38
34
  puts tree.content
39
35
  end
@@ -41,15 +37,10 @@ module Bunch
41
37
 
42
38
  if @opts[:individual]
43
39
  tree.children.each do |child|
44
- write("#{child.name}.#{child.target_extension}", child.content)
40
+ child.write_to_dir(@output)
45
41
  end
46
42
  end
47
43
  end
48
-
49
- private
50
- def write(fn, content)
51
- File.open(@output.join(fn), 'w') { |f| f.write(content) }
52
- end
53
44
  end
54
45
 
55
46
  class << CLI
@@ -60,7 +51,6 @@ module Bunch
60
51
  on :s, :server, 'Instead of creating files, use WEBrick to serve files from INPUT_PATH'
61
52
  on :i, :individual, 'Create one output file for each file or directory in the input path (default)', :default => true
62
53
  on :a, :all, 'Create an all.[extension] file combining all inputs'
63
- on :p, :profile
64
54
  on :h, :help, 'Show this message' do
65
55
  puts self
66
56
  exit
@@ -1,7 +1,5 @@
1
1
  module Bunch
2
- class CoffeeNode
3
- include Caching
4
-
2
+ class CoffeeNode < FileNode
5
3
  def initialize(fn)
6
4
  unless defined?(@@coffee_required)
7
5
  require 'coffee-script'
@@ -21,11 +19,7 @@ module Bunch
21
19
  end
22
20
 
23
21
  def target_extension
24
- 'js'
25
- end
26
-
27
- def inspect
28
- @filename.inspect
22
+ '.js'
29
23
  end
30
24
  end
31
25
  end
@@ -1,5 +1,5 @@
1
1
  module Bunch
2
- class DirectoryNode
2
+ class DirectoryNode < AbstractNode
3
3
  attr_reader :root
4
4
 
5
5
  def initialize(fn)
@@ -30,8 +30,10 @@ module Bunch
30
30
  exts = children.map(&:target_extension).compact.uniq
31
31
  if exts.count == 1
32
32
  exts.first
33
+ elsif exts.count > 1
34
+ raise "Directory #{name} contains non-homogeneous nodes: #{exts.inspect}"
33
35
  else
34
- raise "Directory contains non-homogeneous nodes: #{exts.inspect}"
36
+ nil
35
37
  end
36
38
  end
37
39
  end
@@ -44,6 +46,11 @@ module Bunch
44
46
  File.basename(@root)
45
47
  end
46
48
 
49
+ def write_to_file(dir)
50
+ return if filenames.count == 0
51
+ super
52
+ end
53
+
47
54
  def inspect
48
55
  "#<DirectoryNode @root=#{@root.inspect} @children=#{children.inspect}>"
49
56
  end
@@ -1,15 +1,16 @@
1
1
  module Bunch
2
- class FileNode
3
- attr_reader :name, :target_extension
2
+ class FileNode < AbstractNode
3
+ attr_accessor :name, :target_extension
4
4
 
5
5
  def initialize(fn)
6
6
  @filename = fn
7
7
 
8
- if fn =~ %r(\.([^.]*)$)
8
+ if fn =~ /\.[^.]*$/
9
9
  @name = File.basename($`)
10
- @target_extension = $1
10
+ @target_extension = $&
11
11
  else
12
12
  @name = File.basename(@filename)
13
+ @target_extension = nil
13
14
  end
14
15
  end
15
16
 
@@ -33,9 +33,47 @@ module Bunch
33
33
  end
34
34
  end
35
35
 
36
- private
36
+ protected
37
37
  def root_regexp
38
38
  Regexp.new("^#{Regexp.quote(@root_url).gsub('/', '/+')}(.*)")
39
39
  end
40
40
  end
41
+
42
+ class << Middleware
43
+ # Binds an instance of `Bunch::Middleware` in front of any instance
44
+ # of the given middleware class. Whenever `klass` is instantiated,
45
+ # any calls to `klass#call` will first pass through the single
46
+ # instance of `Middleware` created by this method.
47
+ #
48
+ # You can compose any number of `Middleware` instances in front
49
+ # of the same class.
50
+ #
51
+ # In practice, the purpose of this is to allow Bunch to take
52
+ # precedence over `Rails::Rack::Static` in a Rails 2 context.
53
+ # Since the server's instance of `Rails::Rack::Static` isn't part of
54
+ # the `ActionController` stack, it isn't possible to use
55
+ # Rails' normal middleware tools to insert Bunch in front of it,
56
+ # which means any files in `public` would be served preferentially.
57
+ #
58
+ # @param [Class] klass Any Rack middleware class.
59
+ # @param [Hash] options The options that would normally be passed to
60
+ # `Bunch::Middleware#initialize`.
61
+ #
62
+ # @example
63
+ # if Rails.env.development?
64
+ # Bunch::Middleware.insert_before Rails::Rack::Static,
65
+ # root_url: '/javascripts', path: 'app/scripts', no_cache: true
66
+ # end
67
+ def insert_before(klass, options={})
68
+ instance = new(nil, options)
69
+
70
+ klass.class_eval do
71
+ unbound_call = instance_method(:call)
72
+ define_method(:call) do |env|
73
+ instance.app = unbound_call.bind(self)
74
+ instance.call(env)
75
+ end
76
+ end
77
+ end
78
+ end
41
79
  end
@@ -20,11 +20,6 @@ module Bunch
20
20
  [500, headers('text/plain'), [error_log(e)]]
21
21
  end
22
22
 
23
- private
24
- def headers(mime_type)
25
- @headers.merge('Content-Type' => mime_type.to_s)
26
- end
27
-
28
23
  private
29
24
  def content_for(path)
30
25
  Bunch.content_for(path)
@@ -1,19 +1,23 @@
1
1
  module Bunch
2
- class SassNode
3
- include Caching
4
-
2
+ class SassNode < FileNode
5
3
  def initialize(fn)
6
4
  unless defined?(@@sass_required)
7
5
  require 'sass'
8
6
  @@sass_required = true
9
7
  end
8
+
9
+ unless defined?(@@sass_style)
10
+ @@sass_style = ENV['SASS_STYLE'] || 'nested'
11
+ puts @@sass_style.inspect
12
+ end
13
+
10
14
  @filename = fn
11
15
  rescue LoadError
12
16
  raise "'gem install sass' to compile .sass and .scss files."
13
17
  end
14
18
 
15
19
  def content
16
- @content ||= fetch(@filename) { Sass::Engine.for_file(@filename, {}).render }
20
+ @content ||= fetch(@filename) { Sass::Engine.for_file(@filename, :style => @@sass_style.to_sym).render }
17
21
  end
18
22
 
19
23
  def name
@@ -21,11 +25,7 @@ module Bunch
21
25
  end
22
26
 
23
27
  def target_extension
24
- 'css'
25
- end
26
-
27
- def inspect
28
- @filename.inspect
28
+ '.css'
29
29
  end
30
30
  end
31
31
  end
@@ -1,3 +1,3 @@
1
1
  module Bunch
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class RackTest < Test::Unit::TestCase
4
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'bunch'
4
+ require 'test/unit'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bunch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
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: 2012-01-03 00:00:00.000000000 Z
12
+ date: 2012-01-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mime-types
16
- requirement: &70177706384580 !ruby/object:Gem::Requirement
16
+ requirement: &70318786120460 !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: *70177706384580
24
+ version_requirements: *70318786120460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: slop
27
- requirement: &70177706384160 !ruby/object:Gem::Requirement
27
+ requirement: &70318786100960 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,29 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70177706384160
35
+ version_requirements: *70318786100960
36
+ - !ruby/object:Gem::Dependency
37
+ name: yard
38
+ requirement: &70318786099000 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70318786099000
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdiscount
49
+ requirement: &70318786097560 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70318786097560
36
58
  description: Directory-structure-based asset bundling.
37
59
  email:
38
60
  - rfitz@academia.edu
@@ -42,7 +64,9 @@ extensions: []
42
64
  extra_rdoc_files: []
43
65
  files:
44
66
  - .gitignore
67
+ - .yardopts
45
68
  - Gemfile
69
+ - README.md
46
70
  - Rakefile
47
71
  - bin/bunch
48
72
  - bunch.gemspec
@@ -65,7 +89,8 @@ files:
65
89
  - example/js/test4/test4b.coffee
66
90
  - example/js/test4/test4c.coffee
67
91
  - lib/bunch.rb
68
- - lib/bunch/caching.rb
92
+ - lib/bunch/abstract_node.rb
93
+ - lib/bunch/cache.rb
69
94
  - lib/bunch/cli.rb
70
95
  - lib/bunch/coffee_node.rb
71
96
  - lib/bunch/directory_node.rb
@@ -74,6 +99,8 @@ files:
74
99
  - lib/bunch/rack.rb
75
100
  - lib/bunch/sass_node.rb
76
101
  - lib/bunch/version.rb
102
+ - test/rack_test.rb
103
+ - test/test_helper.rb
77
104
  homepage: ''
78
105
  licenses: []
79
106
  post_install_message:
@@ -98,5 +125,7 @@ rubygems_version: 1.8.10
98
125
  signing_key:
99
126
  specification_version: 3
100
127
  summary: Directory-structure-based asset bundling.
101
- test_files: []
128
+ test_files:
129
+ - test/rack_test.rb
130
+ - test/test_helper.rb
102
131
  has_rdoc:
@@ -1,42 +0,0 @@
1
- module Bunch
2
- module Caching
3
- class << self
4
- def initialize_cache
5
- @cache = Hash.new { |h, k| h[k] = {} }
6
- end
7
-
8
- def stored?(fn)
9
- @cache.keys.include?(fn)
10
- end
11
-
12
- def read(fn)
13
- @cache[fn][:content]
14
- end
15
-
16
- def mtime(fn)
17
- @cache[fn][:mtime]
18
- end
19
-
20
- def write(fn, mtime, content)
21
- @cache[fn] = {:mtime => mtime, :content => content}
22
- end
23
-
24
- def fetch(fn, &blk)
25
- current_mtime = File.mtime(fn)
26
-
27
- if stored?(fn) && mtime(fn) == current_mtime
28
- read(fn)
29
- else
30
- content = blk.call
31
- write(fn, current_mtime, content)
32
- content
33
- end
34
- end
35
- end
36
- initialize_cache
37
-
38
- def fetch(filename, &blk)
39
- Bunch::Caching.fetch(filename, &blk)
40
- end
41
- end
42
- end