bunch 0.2.2 → 1.0.0pre1

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.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -6
  3. data/Gemfile +3 -1
  4. data/Guardfile +5 -0
  5. data/LICENSE.txt +22 -0
  6. data/Rakefile +7 -12
  7. data/bin/bunch +2 -5
  8. data/bunch.gemspec +30 -23
  9. data/lib/bunch.rb +37 -81
  10. data/lib/bunch/cli.rb +40 -74
  11. data/lib/bunch/combiner.rb +121 -0
  12. data/lib/bunch/compiler.rb +52 -0
  13. data/lib/bunch/compilers/coffee_script.rb +23 -0
  14. data/lib/bunch/compilers/ejs.rb +28 -0
  15. data/lib/bunch/compilers/jade.rb +28 -0
  16. data/lib/bunch/compilers/jst.rb +38 -0
  17. data/lib/bunch/compilers/null.rb +19 -0
  18. data/lib/bunch/compilers/sass.rb +55 -0
  19. data/lib/bunch/content_hash.rb +37 -0
  20. data/lib/bunch/css_minifier.rb +121 -0
  21. data/lib/bunch/file.rb +18 -0
  22. data/lib/bunch/file_cache.rb +159 -0
  23. data/lib/bunch/file_tree.rb +153 -0
  24. data/lib/bunch/ignorer.rb +38 -0
  25. data/lib/bunch/js_minifier.rb +38 -0
  26. data/lib/bunch/middleware.rb +16 -67
  27. data/lib/bunch/pipeline.rb +30 -0
  28. data/lib/bunch/server.rb +56 -0
  29. data/lib/bunch/simple_cache.rb +36 -0
  30. data/lib/bunch/tree_merge.rb +29 -0
  31. data/lib/bunch/version.rb +3 -1
  32. data/spec/bunch/cli_spec.rb +85 -0
  33. data/spec/bunch/combiner_spec.rb +107 -0
  34. data/spec/bunch/compiler_spec.rb +73 -0
  35. data/spec/bunch/compilers/coffee_script_spec.rb +23 -0
  36. data/spec/bunch/compilers/ejs_spec.rb +27 -0
  37. data/spec/bunch/compilers/jade_spec.rb +28 -0
  38. data/spec/bunch/compilers/sass_spec.rb +120 -0
  39. data/spec/bunch/css_minifier_spec.rb +31 -0
  40. data/spec/bunch/file_cache_spec.rb +151 -0
  41. data/spec/bunch/file_tree_spec.rb +127 -0
  42. data/spec/bunch/ignorer_spec.rb +26 -0
  43. data/spec/bunch/js_minifier_spec.rb +35 -0
  44. data/spec/bunch/middleware_spec.rb +41 -0
  45. data/spec/bunch/pipeline_spec.rb +31 -0
  46. data/spec/bunch/server_spec.rb +90 -0
  47. data/spec/bunch/simple_cache_spec.rb +55 -0
  48. data/spec/bunch/tree_merge_spec.rb +30 -0
  49. data/spec/bunch_spec.rb +6 -0
  50. data/spec/example_tree/directory/_combine +2 -0
  51. data/{example/js/test1.js → spec/example_tree/directory/file1} +0 -0
  52. data/{example/js/test2/test2a.js → spec/example_tree/directory/file2} +0 -0
  53. data/{example/js/test2/test2c.js → spec/example_tree/file3} +0 -0
  54. data/spec/spec_helper.rb +38 -0
  55. metadata +224 -102
  56. data/.yardopts +0 -1
  57. data/README.md +0 -4
  58. data/config.ru +0 -6
  59. data/example/config.ru +0 -6
  60. data/example/css/test1.css +0 -1
  61. data/example/css/test2/test2a.scss +0 -1
  62. data/example/css/test2/test2b.css +0 -1
  63. data/example/js/.bunchignore +0 -1
  64. data/example/js/test2/_.yml +0 -2
  65. data/example/js/test2/foo.js +0 -1
  66. data/example/js/test2/test2b.js +0 -1
  67. data/example/js/test3/test3a.js +0 -1
  68. data/example/js/test3/test3b/_.yml +0 -1
  69. data/example/js/test3/test3b/test3bi.js +0 -1
  70. data/example/js/test3/test3b/test3bii.js +0 -1
  71. data/example/js/test4/_.yml +0 -1
  72. data/example/js/test4/test4a.js +0 -1
  73. data/example/js/test4/test4b.coffee +0 -1
  74. data/example/js/test4/test4c.coffee +0 -1
  75. data/example/js/test5/test5a.jst.ejs +0 -1
  76. data/lib/bunch/abstract_node.rb +0 -25
  77. data/lib/bunch/cache.rb +0 -40
  78. data/lib/bunch/coffee_node.rb +0 -39
  79. data/lib/bunch/directory_node.rb +0 -82
  80. data/lib/bunch/ejs_node.rb +0 -50
  81. data/lib/bunch/file_node.rb +0 -25
  82. data/lib/bunch/jade_node.rb +0 -50
  83. data/lib/bunch/null_node.rb +0 -11
  84. data/lib/bunch/rack.rb +0 -38
  85. data/lib/bunch/sass_node.rb +0 -39
  86. data/test/middleware_test.rb +0 -26
  87. data/test/rack_test.rb +0 -93
  88. data/test/test_helper.rb +0 -21
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: efebcfd36e823c3ec86e0442561e0dae5b269992
4
+ data.tar.gz: a5e89ce41f38db3a0b6b1bb0b93ac19f4778ad6c
5
+ SHA512:
6
+ metadata.gz: 3f66c4238a91ea23234ff00fa0b3dadfaa6a304f6e5c144e10d3388cda68a45228edf3e280ed932a5f66804ae4760541d80fe4cc8c35986efca9ee1165a906f6
7
+ data.tar.gz: 37d71071cd267674130898cd31856e47d788e26ebf765ddba3e34c888fdd040d6bfd0b5122bb9c8ba04f8e0ba6ef5a59cc3967755d221d02abc8c18f2d375481
data/.gitignore CHANGED
@@ -1,10 +1,19 @@
1
1
  *.gem
2
+ *.rbc
2
3
  .bundle
4
+ .config
5
+ .yardoc
3
6
  Gemfile.lock
4
- pkg/*
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
5
18
  .sass-cache
6
- .yardoc
7
- doc/*
8
- *.sublime-workspace
9
- *.sublime-project
10
- *.DS_Store
19
+ .bunch-cache
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rb-fsevent'
2
4
 
3
5
  # Specify your gem's dependencies in bunch.gemspec
4
6
  gemspec
@@ -0,0 +1,5 @@
1
+ guard 'minitest' do
2
+ watch(%r|^spec/(.*)_spec\.rb|)
3
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
4
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
5
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Academia.edu
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.
data/Rakefile CHANGED
@@ -1,18 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
2
3
 
3
- begin
4
- require 'yard'
5
- YARD::Rake::YardocTask.new
6
- rescue LoadError
4
+ Rake::TestTask.new do |t|
5
+ t.libs.concat %w(bunch spec)
6
+ t.pattern = "spec/**/*_spec.rb"
7
7
  end
8
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
9
+ task :pry do
10
+ system "pry -Ilib -rbunch"
16
11
  end
17
12
 
18
- task :default => :test
13
+ task :default => [:test]
data/bin/bunch CHANGED
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift File.expand_path('../../lib', __FILE__)
4
- require 'bunch'
5
- require 'bunch/cli'
6
-
7
- Bunch::CLI.process!
3
+ require "bunch"
4
+ Bunch::CLI.run!(ARGV)
@@ -1,31 +1,38 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
4
  require 'bunch/version'
4
5
 
5
- Gem::Specification.new do |s|
6
- s.name = 'bunch'
7
- s.version = Bunch::VERSION
8
- s.authors = ['Ryan Fitzgerald']
9
- s.email = ['rfitz@academia.edu']
10
- s.homepage = ''
11
- s.summary = %q{Directory-structure-based asset bundling.}
12
- s.description = %q{Directory-structure-based asset bundling.}
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "bunch"
8
+ gem.version = Bunch::VERSION
9
+ gem.authors = ["Ryan Fitzgerald"]
10
+ gem.email = ["rwfitzge@gmail.com"]
11
+ gem.summary = %q{Directory-structure-based asset bundling.}
12
+ gem.description = gem.summary
13
+ gem.homepage = "https://github.com/academia-edu/bunch"
13
14
 
14
- s.rubyforge_project = 'bunch'
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
15
19
 
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
+ gem.add_dependency "mime-types", "~> 1.16"
20
21
 
21
- s.add_runtime_dependency 'mime-types'
22
+ gem.add_development_dependency "yard", "~> 0.8.3"
23
+ gem.add_development_dependency "minitest", "~> 4.3.3"
24
+ gem.add_development_dependency "mocha", "~> 0.13.1"
25
+ gem.add_development_dependency "rdiscount"
26
+ gem.add_development_dependency "rake"
27
+ gem.add_development_dependency "guard"
28
+ gem.add_development_dependency "guard-minitest"
29
+ gem.add_development_dependency "pry"
30
+ gem.add_development_dependency "simplecov"
31
+ gem.add_development_dependency "rack"
22
32
 
23
- s.add_development_dependency 'yard'
24
- s.add_development_dependency 'rdiscount'
25
- s.add_development_dependency 'shoulda-context'
26
- s.add_development_dependency 'mocha'
27
-
28
- s.add_development_dependency 'coffee-script'
29
- s.add_development_dependency 'sass'
30
- s.add_development_dependency 'ejs'
33
+ gem.add_development_dependency "coffee-script"
34
+ gem.add_development_dependency "sass"
35
+ gem.add_development_dependency "ejs"
36
+ gem.add_development_dependency "ruby-jade"
37
+ gem.add_development_dependency "uglifier"
31
38
  end
@@ -1,94 +1,50 @@
1
- require 'fileutils'
2
- require 'optparse'
3
- require 'pathname'
4
- require 'yaml'
5
-
6
- require 'mime/types'
7
-
8
- begin
9
- require 'v8'
10
- rescue LoadError
11
- $stderr.puts "WARNING: 'gem install therubyracer' for much faster CoffeeScript compilation."
1
+ # encoding: utf-8
2
+
3
+ require "bunch/version"
4
+ require "bunch/cli"
5
+ require "bunch/combiner"
6
+ require "bunch/compiler"
7
+ require "bunch/content_hash"
8
+ require "bunch/css_minifier"
9
+ require "bunch/file"
10
+ require "bunch/file_cache"
11
+ require "bunch/file_tree"
12
+ require "bunch/ignorer"
13
+ require "bunch/js_minifier"
14
+ require "bunch/middleware"
15
+ require "bunch/server"
16
+ require "bunch/simple_cache"
17
+ require "bunch/pipeline"
18
+ require "bunch/tree_merge"
19
+
20
+ Dir.glob(File.expand_path("../bunch/compilers/*.rb", __FILE__)) do |compiler|
21
+ require compiler
12
22
  end
13
23
 
14
- require 'bunch/version'
15
- require 'bunch/rack'
16
- require 'bunch/middleware'
17
- require 'bunch/cache'
18
-
19
- require 'bunch/abstract_node'
20
- require 'bunch/directory_node'
21
- require 'bunch/file_node'
22
- require 'bunch/coffee_node'
23
- require 'bunch/sass_node'
24
- require 'bunch/null_node'
25
- require 'bunch/ejs_node'
26
- require 'bunch/jade_node'
27
-
28
24
  module Bunch
29
- class CompileError < StandardError
30
- def initialize(exception, filename)
31
- @exception = exception
32
- @filename = filename
33
- end
34
-
35
- def message
36
- "#{@filename}: #{@exception.message}"
25
+ def self.load_default_config_if_possible
26
+ if ::File.exist?("config/bunch.rb")
27
+ load "config/bunch.rb"
37
28
  end
38
29
  end
39
- end
40
-
41
- class << Bunch
42
- IGNORED_PATTERNS = []
43
30
 
44
- def load_ignores(path='.')
45
- fn = File.join(path, '.bunchignore')
46
- if File.exist?(fn)
47
- IGNORED_PATTERNS.concat File.readlines(fn).map { |f| Regexp.new(f.chomp) }
48
- IGNORED_PATTERNS.uniq!
31
+ def self.load_config_files(config_files)
32
+ config_files.each do |config_file|
33
+ load config_file
49
34
  end
50
35
  end
51
36
 
52
- def content_for(path, options = {})
53
- tree_for(normalized_path(path), options).content
37
+ Pipeline.define :development do |config|
38
+ [Ignorer,
39
+ SimpleCache(Compiler),
40
+ Combiner]
54
41
  end
55
42
 
56
- def tree_for(path, options)
57
- node = case
58
- when IGNORED_PATTERNS.any? { |p| File.basename(path) =~ p }
59
- Bunch::NullNode.new(path)
60
- when File.directory?(path)
61
- Bunch::DirectoryNode.new(path)
62
- when path =~ /\.coffee$/
63
- Bunch::CoffeeNode.new(path)
64
- when path =~ /\.s(a|c)ss$/
65
- Bunch::SassNode.new(path)
66
- when path =~ /\.ejs$/
67
- Bunch::EJSNode.new(path)
68
- when path =~ /\.jade/
69
- Bunch::JadeNode.new(path)
70
- else
71
- Bunch::FileNode.new(path)
72
- end
73
- node.options = options
74
- node
43
+ Pipeline.define :production do |config|
44
+ [Ignorer,
45
+ SimpleCache(Compiler),
46
+ Combiner,
47
+ FileCache(JsMinifier, config[:root]),
48
+ FileCache(CssMinifier, config[:root])]
75
49
  end
76
-
77
- protected
78
- def normalized_path(path)
79
- case
80
- when File.exist?(path)
81
- path
82
- when File.exist?(chopped_path = path.sub(%r(\.[^.]*$), ''))
83
- chopped_path
84
- when File.basename(path).start_with?('all.') && File.exist?(dir_path = File.dirname(path))
85
- dir_path
86
- when (path_w_different_extension = Dir["#{chopped_path}.*"].first)
87
- path_w_different_extension
88
- else
89
- raise Errno::ENOENT, path.to_s
90
- end
91
- end
92
50
  end
93
-
94
- Bunch.load_ignores
@@ -1,103 +1,69 @@
1
+ # encoding: UTF-8
2
+
3
+ require "optparse"
4
+
1
5
  module Bunch
2
6
  class CLI
3
- def initialize(input, output, opts)
4
- @input = Pathname.new(input)
5
- @output = output ? Pathname.new(output) : nil
6
- @opts = opts
7
-
8
- if @opts[:server]
9
- run_server
10
- else
11
- generate_files
12
- end
7
+ def self.run!(args)
8
+ new(args).run!
13
9
  end
14
10
 
15
- def run_server
16
- require 'rack'
17
- ::Rack::Handler::WEBrick.run(Bunch::Rack.new(@input), :Port => 3001)
18
- rescue LoadError
19
- $stderr.puts "ERROR: 'gem install rack' to run Bunch in server mode."
20
- exit 1
11
+ def initialize(args, out = $stdout)
12
+ @args, @out = args, out
21
13
  end
22
14
 
23
- def generate_files
24
- Bunch.load_ignores(@input)
25
- tree = Bunch.tree_for(@input.to_s, @opts.merge(:root => @input.to_s))
15
+ def run!
16
+ config = parse_options
26
17
 
27
- if @output
28
- FileUtils.mkdir_p(@output.to_s)
29
- end
30
-
31
- if @opts[:all]
32
- if @output
33
- tree.write_to_file(@output.join('all'))
34
- else
35
- puts tree.content
36
- end
37
- end
38
-
39
- if @opts[:individual]
40
- tree.children.each do |child|
41
- child.write_to_dir(@output)
42
- end
18
+ if config && config[:root] && config[:output_path]
19
+ pipeline = Pipeline.for_environment config
20
+ in_tree = FileTree.from_path config[:root]
21
+ out_tree = pipeline.process in_tree
22
+ out_tree.write_to_path config[:output_path]
43
23
  end
44
24
  end
45
- end
46
25
 
47
- class << CLI
48
- def process!
49
- CLI.new(*parse_opts)
50
- rescue => e
51
- if ENV['BUNCH_DEBUG']
52
- raise
53
- else
54
- $stderr.puts "ERROR: #{e.message}"
55
- exit 1
56
- end
57
- end
26
+ private
58
27
 
59
- def parse_opts
60
- options = {:individual => true}
28
+ def parse_options
29
+ config = { environment: "production", config_files: [] }
61
30
 
62
31
  opts = OptionParser.new do |opts|
63
- opts.banner = 'Usage: bunch [options] INPUT_PATH [OUTPUT_PATH]'
64
-
65
- opts.on '-s', '--server', 'Instead of creating files, use WEBrick to serve files from INPUT_PATH.' do
66
- options[:server] = true
67
- end
68
-
69
- opts.on '-i', '--[no-]individual', 'Create one output file for each file or directory in the input path (default).' do |i|
70
- options[:individual] = i
71
- end
32
+ opts.banner = "Usage: bunch [options] INPUT_PATH OUTPUT_PATH"
72
33
 
73
- opts.on '-a', '--all', 'Create an all.[extension] file combining all inputs.' do
74
- options[:all] = true
34
+ opts.on "-e", "--env [ENV]",
35
+ "Specify environment (default: \"production\")" do |env|
36
+ config[:environment] = env.strip
75
37
  end
76
38
 
77
- opts.on '-r', '--recurse', 'Recursively generate one output file for every input file and directory.' do
78
- options[:recurse] = true
39
+ opts.on "-c", "--config [FILE]",
40
+ "File to load (default: \"config/bunch.rb\")" do |f|
41
+ config[:config_files] << f.strip
79
42
  end
80
43
 
81
- opts.on_tail '-h', '--help', 'Show this message.' do
82
- puts opts
83
- exit
44
+ opts.on_tail "-h", "--help", "Show this message" do
45
+ @out.puts opts
46
+ return
84
47
  end
85
48
  end
86
49
 
87
- opts.parse!
50
+ opts.parse!(@args)
88
51
 
89
- if ARGV.count < 1
90
- raise "Must give an input path.\n\n#{opts}"
52
+ if @args.count != 2
53
+ raise "Must provide input and output paths!"
91
54
  end
92
55
 
93
- if ARGV.count < 2 && options[:individual] && !options[:server]
94
- raise "Must give an output path unless --no-individual or --server is provided."
56
+ if config[:config_files].any?
57
+ Bunch.load_config_files(config[:config_files])
58
+ else
59
+ Bunch.load_default_config_if_possible
95
60
  end
96
61
 
97
- input = ARGV.shift
98
- output = ARGV.shift
99
-
100
- [input, output, options]
62
+ config[:root], config[:output_path] = @args
63
+ config
64
+ rescue StandardError, LoadError => e
65
+ @out.puts "Error: #{e.message}\n\n"
66
+ @out.puts opts if opts
101
67
  end
102
68
  end
103
69
  end