coyote 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest CHANGED
@@ -1,8 +1,23 @@
1
1
  Manifest
2
+ README.md
2
3
  Rakefile
3
4
  bin/coyote
4
5
  config/coyote.yaml
5
6
  lib/coyote.rb
6
- lib/coyote/builder.rb
7
+ lib/coyote/closure_compiler.rb
8
+ lib/coyote/config_reader.rb
9
+ lib/coyote/fs_listener.rb
10
+ lib/coyote/fs_listeners/darwin.rb
11
+ lib/coyote/fs_listeners/linux.rb
12
+ lib/coyote/fs_listeners/polling.rb
13
+ lib/coyote/fs_listeners/windows.rb
7
14
  lib/coyote/generator.rb
8
15
  lib/coyote/output.rb
16
+ test/javascript/application.js
17
+ test/javascript/application/controller.js
18
+ test/javascript/application/interface.js
19
+ test/javascript/init.js
20
+ test/javascript/jquery/jquery.js
21
+ test/javascript/jquery/plugins/jquery.cookie.js
22
+ test/javascript/jquery/plugins/jquery.cycle.all.min.js
23
+ test/javascript/jquery/plugins/jquery.query.js
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ COYOTE
2
+ =============
3
+
4
+ An intelligent command-line tool for combining and compressing JavaScript files.
5
+
6
+ Coyote selectively concatenates your JS files, combining them into a single file with the option of running the output through the Google Closure Compiler before save. Coyote automatically observes your directories and source files for changes and will recompile and save on the fly for easy development.
7
+
8
+
9
+ Installation
10
+ ------
11
+ $ gem install coyote
12
+
13
+ Usage
14
+ ------
15
+
16
+ **Configuration**
17
+
18
+ $ cd myproject/scripts
19
+ $ coyote generate
20
+
21
+ *This will create the configuration file at coyote.yaml and will find any .js files and automatically add them to the input parameter. Open coyote.yaml and modify the input and output configurations to meet your needs. Coyote will combine the input files in the order you define.*
22
+
23
+ **Running Coyote**
24
+
25
+ $ coyote
26
+
27
+ **Building without watching**
28
+
29
+ $ coyote build
30
+
31
+ **Input wildcards**
32
+
33
+ You can wildcard your input parameters to find files.
34
+
35
+ - **/*.js # recursively find all files with the extension '.js'
36
+ - /jquery/plugins/*.js # find all .js files in the directory
37
+
38
+
39
+ **Dependency discovery**
40
+
41
+ If your JavaScript files depend on other files or libraries to run, you can define those dependencies so Coyote will include them in the compiled output before the files that require them.
42
+
43
+ // require /jquery/jquery.js
44
+
45
+ or simply
46
+
47
+ // require jquery
48
+
49
+ Dependencies are relative to the top level of your directory, likely where your coyote.yaml config file is located.
50
+
51
+
52
+ Options
53
+ -------
54
+ **Forced compression**
55
+
56
+ $ coyote -c
57
+
58
+ or
59
+
60
+ $ coyote build -c
61
+
62
+ Plan
63
+ ----
64
+
65
+ - Global configuration for logging
66
+ - Support for Growl notifications
67
+ - Configuration options for level of compression
68
+
69
+
70
+ License
71
+ -------
72
+
73
+ Copyright (C) 2011 by Imulus
74
+
75
+ Permission is hereby granted, free of charge, to any person obtaining a copy
76
+ of this software and associated documentation files (the "Software"), to deal
77
+ in the Software without restriction, including without limitation the rights
78
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79
+ copies of the Software, and to permit persons to whom the Software is
80
+ furnished to do so, subject to the following conditions:
81
+
82
+ The above copyright notice and this permission notice shall be included in
83
+ all copies or substantial portions of the Software.
84
+
85
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
86
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
87
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
88
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
89
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
90
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
91
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -2,13 +2,13 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('coyote', '0.2.5') do |p|
6
- p.description = "A flexible command-line tool for combining and compressing JS files"
7
- p.summary = "Coyote is a command-line tool for combining and compressing JS files. It uses YAML for configuration and the Google Closure Compiler to compilation and compression."
8
- p.url = "http://github.com/caseyohara/coyote"
9
- p.author = "Casey O'Hara"
5
+ Echoe.new('coyote', '0.2.6') do |p|
6
+ p.description = "An intelligent command-line tool for combining and compressing JavaScript files."
7
+ p.summary = "Coyote selectively concatenates your JS files, combining them into a single file with the option of running the output through the Google Closure Compiler. Coyote automatically observes your directories and source files for changes and will recompile and save on the fly for easy development."
8
+ p.url = "http://github.com/imulus/coyote"
9
+ p.author = "Imulus"
10
10
  p.email = "casey.ohara@imulus.com"
11
- p.ignore_pattern = ["tmp/*", "script/*"]
12
- p.development_dependencies = ["closure-compiler >=1.1.1", "term-ansicolor >=1.0.5"]
13
- p.runtime_dependencies = ["closure-compiler >=1.1.1", "term-ansicolor >=1.0.5"]
11
+ p.ignore_pattern = ["tmp/*", "script/*", "test/*"]
12
+ p.development_dependencies = ["term-ansicolor >=1.0.5"]
13
+ p.runtime_dependencies = ["term-ansicolor >=1.0.5"]
14
14
  end
data/bin/coyote CHANGED
@@ -1,33 +1,63 @@
1
1
  #!/usr/bin/env ruby
2
-
2
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
3
3
  require 'fileutils'
4
4
  require 'rubygems'
5
- require 'closure-compiler'
6
5
  require 'optparse'
7
- require File.expand_path(File.dirname(__FILE__) + "/../lib/coyote")
8
- require "coyote/builder"
9
- require "coyote/generator"
10
- require "coyote/output"
11
-
6
+ require 'coyote'
12
7
 
13
- options = {}
8
+ @options = {}
14
9
  OptionParser.new do |opts|
15
- opts.on("-f", "--force", "Force") do |f|
16
- options[:force] = f
10
+ opts.on("-f", "--force", "Force") do |o|
11
+ @options[:force] = o
17
12
  end
18
- opts.on("-c", "--compress", "Compress") do |c|
19
- options[:compress] = c
13
+
14
+ opts.on("-c", "--compress", "Compress") do |o|
15
+ @options[:compress] = o
20
16
  end
21
17
  end.parse!
22
18
 
19
+ def config_file_reader(rebuild = false)
20
+ if nil == @reader or rebuild
21
+ @reader = Coyote::ConfigReader.new(@options)
22
+ @reader.find_input_files
23
+ end
24
+
25
+ return @reader
26
+ end
27
+
28
+ def coyote_the_sources
29
+
30
+ reader = config_file_reader
31
+
32
+ output = Coyote::Output.new(reader.output_file, reader.should_compress?)
33
+ output.add_files(reader.input_files)
34
+ output.save
35
+ end
23
36
 
24
37
  case ARGV.first
25
38
  when 'generate'
26
- Coyote::Generator.new(options).generate
39
+ Coyote::Generator.new(@options).generate
27
40
  when 'build'
28
- Coyote::Builder.new(options).build
41
+ coyote_the_sources
29
42
  else
30
- Coyote::Builder.new(options).build
31
- end
32
-
43
+
44
+ coyote_the_sources
45
+
46
+ listener = Coyote::FSListener.select_and_init
47
+
48
+ listener.on_change do |files|
49
+ if files.include?(Coyote::CONFIG_FILENAME)
50
+ print "Config file changed. Reading it in.\n".yellow
51
+ config_file_reader(true) #rebuild the sources of the config file
52
+ coyote_the_sources
53
+ else
54
+ #see if any of the files in the config file changed
55
+ changed_watched_files = config_file_reader.input_files & files
56
+ if changed_watched_files.length > 0
57
+ coyote_the_sources
58
+ end
59
+ end
60
+ end
33
61
 
62
+ listener.start
63
+ end
data/config/coyote.yaml CHANGED
@@ -1,22 +1,2 @@
1
- # Example usages:
2
-
3
- # Explicitly defining individual files to join
4
- application:
5
- compress: true
6
- output: application.js
7
- input:
8
- - application/Application.Data.js
9
- - application/Application.Controller.js
10
- - application/Application.Interface.js
11
-
12
- # Recursively searching and adding
13
- application_classes:
14
- compress: false
15
- output: application.classes.js
16
- input: application/**/*.class.js
17
-
18
- # Adding by extension
19
- jquery:
20
- compress: true
21
- output: jquery.plugins.js
22
- input: jquery/plugins/*.js
1
+ output: scripts.js
2
+ input:
data/coyote.gemspec CHANGED
@@ -2,42 +2,36 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{coyote}
5
- s.version = "0.2.5"
5
+ s.version = "0.2.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Casey O'Hara"]
9
- s.date = %q{2011-05-02}
8
+ s.authors = ["Imulus"]
9
+ s.date = %q{2011-05-20}
10
10
  s.default_executable = %q{coyote}
11
- s.description = %q{A flexible command-line tool for combining and compressing JS files}
11
+ s.description = %q{An intelligent command-line tool for combining and compressing JavaScript files.}
12
12
  s.email = %q{casey.ohara@imulus.com}
13
13
  s.executables = ["coyote"]
14
- s.extra_rdoc_files = ["bin/coyote", "lib/coyote.rb", "lib/coyote/builder.rb", "lib/coyote/generator.rb", "lib/coyote/output.rb"]
15
- s.files = ["Manifest", "Rakefile", "bin/coyote", "config/coyote.yaml", "lib/coyote.rb", "lib/coyote/builder.rb", "lib/coyote/generator.rb", "lib/coyote/output.rb", "coyote.gemspec"]
16
- s.homepage = %q{http://github.com/caseyohara/coyote}
17
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Coyote"]
14
+ s.extra_rdoc_files = ["README.md", "bin/coyote", "lib/coyote.rb", "lib/coyote/closure_compiler.rb", "lib/coyote/config_reader.rb", "lib/coyote/fs_listener.rb", "lib/coyote/fs_listeners/darwin.rb", "lib/coyote/fs_listeners/linux.rb", "lib/coyote/fs_listeners/polling.rb", "lib/coyote/fs_listeners/windows.rb", "lib/coyote/generator.rb", "lib/coyote/output.rb"]
15
+ s.files = ["Manifest", "README.md", "Rakefile", "bin/coyote", "config/coyote.yaml", "lib/coyote.rb", "lib/coyote/closure_compiler.rb", "lib/coyote/config_reader.rb", "lib/coyote/fs_listener.rb", "lib/coyote/fs_listeners/darwin.rb", "lib/coyote/fs_listeners/linux.rb", "lib/coyote/fs_listeners/polling.rb", "lib/coyote/fs_listeners/windows.rb", "lib/coyote/generator.rb", "lib/coyote/output.rb", "test/javascript/application.js", "test/javascript/application/controller.js", "test/javascript/application/interface.js", "test/javascript/init.js", "test/javascript/jquery/jquery.js", "test/javascript/jquery/plugins/jquery.cookie.js", "test/javascript/jquery/plugins/jquery.cycle.all.min.js", "test/javascript/jquery/plugins/jquery.query.js", "coyote.gemspec"]
16
+ s.homepage = %q{http://github.com/imulus/coyote}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Coyote", "--main", "README.md"]
18
18
  s.require_paths = ["lib"]
19
19
  s.rubyforge_project = %q{coyote}
20
20
  s.rubygems_version = %q{1.6.2}
21
- s.summary = %q{Coyote is a command-line tool for combining and compressing JS files. It uses YAML for configuration and the Google Closure Compiler to compilation and compression.}
21
+ s.summary = %q{Coyote selectively concatenates your JS files, combining them into a single file with the option of running the output through the Google Closure Compiler. Coyote automatically observes your directories and source files for changes and will recompile and save on the fly for easy development.}
22
22
 
23
23
  if s.respond_to? :specification_version then
24
24
  s.specification_version = 3
25
25
 
26
26
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
- s.add_runtime_dependency(%q<closure-compiler>, [">= 1.1.1"])
28
27
  s.add_runtime_dependency(%q<term-ansicolor>, [">= 1.0.5"])
29
- s.add_development_dependency(%q<closure-compiler>, [">= 1.1.1"])
30
28
  s.add_development_dependency(%q<term-ansicolor>, [">= 1.0.5"])
31
29
  else
32
- s.add_dependency(%q<closure-compiler>, [">= 1.1.1"])
33
30
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.5"])
34
- s.add_dependency(%q<closure-compiler>, [">= 1.1.1"])
35
31
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.5"])
36
32
  end
37
33
  else
38
- s.add_dependency(%q<closure-compiler>, [">= 1.1.1"])
39
34
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.5"])
40
- s.add_dependency(%q<closure-compiler>, [">= 1.1.1"])
41
35
  s.add_dependency(%q<term-ansicolor>, [">= 1.0.5"])
42
36
  end
43
37
  end
data/lib/coyote.rb CHANGED
@@ -1,9 +1,15 @@
1
1
  require 'yaml'
2
2
  require 'term/ansicolor'
3
+ require 'coyote/config_reader'
4
+ require 'coyote/fs_listener'
5
+ require 'coyote/generator'
6
+ require 'coyote/output'
7
+ require 'coyote/closure_compiler'
8
+
3
9
  include Term::ANSIColor
4
10
 
5
11
  module Coyote
6
- VERSION = "0.2.5"
12
+ VERSION = "0.2.6"
7
13
  ROOT_PATH = Dir.pwd
8
14
  CONFIG_PATH = File.expand_path(File.dirname(__FILE__) + "/../config")
9
15
  CONFIG_FILENAME = "coyote.yaml"
@@ -0,0 +1,56 @@
1
+ require 'net/http'
2
+
3
+ module Coyote
4
+ class ClosureCompiler
5
+
6
+ def initialize
7
+ @request = Net::HTTP::Post.new('/compile', 'Content-type' => 'application/x-www-form-urlencoded')
8
+ end
9
+
10
+ def compile(content)
11
+ @content = content
12
+ params = {
13
+ 'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
14
+ 'output_format' => 'xml',
15
+ 'output_info' => 'compiled_code',
16
+ 'js_code' => @content
17
+ }
18
+
19
+ @request.set_form_data(params)
20
+ begin
21
+ res = Net::HTTP.new('closure-compiler.appspot.com', 80).start {|http| http.request(@request) }
22
+ case res
23
+ when Net::HTTPSuccess
24
+ #puts res.body
25
+ @doc = REXML::Document.new(res.body)
26
+ end
27
+ rescue REXML::ParseException => msg
28
+ print "Failed: #{msg}\n".red
29
+ rescue
30
+ #these should be caught by external checking
31
+ end
32
+
33
+ self
34
+ end
35
+
36
+ def success?
37
+ @doc && @doc.root && @doc.root.elements['serverErrors'].nil?
38
+ end
39
+
40
+ def errors
41
+ unless @doc
42
+ nil
43
+ else
44
+ @doc.root.elements["serverErrors"]
45
+ end
46
+ end
47
+
48
+ def compiled_code
49
+ @doc.root.elements['compiledCode'].text
50
+ end
51
+
52
+ def file_too_big?
53
+ @doc && @doc.root && @doc.root.elements["serverErrors/error[@code='8']"] != nil
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,88 @@
1
+ module Coyote
2
+ class ConfigReader
3
+
4
+ attr_accessor :config, :options, :input_files
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ @config = get_config_or_screw_off
9
+ @input_files = []
10
+ end
11
+
12
+ def output_file
13
+ return @config['output']
14
+ end
15
+
16
+ def should_compress?
17
+ return @config['compress'] || options[:compress]
18
+ end
19
+
20
+ def find_input_files
21
+ @input_files = []
22
+ @config['input'].each { |input| add_input input }
23
+ end
24
+
25
+
26
+ def add_input(input)
27
+ if input.class == Array
28
+ input.each do |input|
29
+ find_and_add_files input
30
+ end
31
+ elsif input.class == String and @config['output'] != input
32
+ find_and_add_files input
33
+ end
34
+ end
35
+
36
+
37
+ def find_and_add_files(input)
38
+ Dir.glob(input).each do |file|
39
+ required = find_requires file
40
+ required.each do |requirement|
41
+ find_and_add_files "**/#{requirement}.js"
42
+ end
43
+ if ! @input_files.include? file
44
+ @input_files.push file
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ def find_requires(input_file)
51
+ required = []
52
+ File.open(input_file) do |file|
53
+ file = file.read
54
+ pattern = Regexp.new(/(\/\/.*)(require )(.*)$/x)
55
+ matches = file.scan(pattern)
56
+ matches.each do |match|
57
+ required.push match.last.strip.to_s.gsub(/\.js/, '').gsub(/(\"|\')/, '')
58
+ end
59
+ end
60
+ #puts required
61
+ return required
62
+ end
63
+
64
+
65
+ def get_config_or_screw_off
66
+ if File.exists?(Coyote::CONFIG_FILENAME)
67
+ begin
68
+ config = YAML.load(File.open(Coyote::CONFIG_FILENAME))
69
+ if config.class == Hash && ! config.empty?
70
+ return config
71
+ else
72
+ print "Coyote configuration exists but has not been defined yet. Configure it in #{Coyote::CONFIG_FILENAME}\n".red
73
+ exit(0)
74
+ end
75
+ rescue ArgumentError => e
76
+ print "Could not parse YAML: #{e.message}\n".red
77
+ exit
78
+ end
79
+ else
80
+ print "Could not find a Coyote configuration file in this directory. Use 'coyote generate' to create one.\n".red
81
+ exit
82
+ end
83
+ end
84
+
85
+
86
+
87
+ end
88
+ end