coyote 0.4.2 → 0.5.0

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/Manifest CHANGED
@@ -1,34 +1,20 @@
1
- Manifest
2
1
  README.md
3
2
  Rakefile
4
3
  bin/coyote
5
4
  config/coyote-icon.png
5
+ config/coyote-usage.txt
6
6
  config/coyote.yaml
7
+ coyote.gemspec
7
8
  lib/coyote.rb
8
9
  lib/coyote/closure_compiler.rb
9
- lib/coyote/config_reader.rb
10
+ lib/coyote/configuration.rb
11
+ lib/coyote/coy_file.rb
10
12
  lib/coyote/fs_listener.rb
11
13
  lib/coyote/fs_listeners/darwin.rb
12
14
  lib/coyote/fs_listeners/linux.rb
13
15
  lib/coyote/fs_listeners/polling.rb
14
16
  lib/coyote/fs_listeners/windows.rb
15
17
  lib/coyote/generator.rb
16
- lib/coyote/hooks.rb
17
18
  lib/coyote/notification.rb
18
19
  lib/coyote/output.rb
19
- test/coffeescript/coyote.yaml
20
- test/coffeescript/lib/animals.js
21
- test/coffeescript/src/animal.coffee
22
- test/coffeescript/src/horse.coffee
23
- test/coffeescript/src/init.coffee
24
- test/coffeescript/src/snake.coffee
25
- test/javascript/application.js
26
- test/javascript/application/controller.js
27
- test/javascript/application/interface.js
28
- test/javascript/coyote.yaml
29
- test/javascript/init.js
30
- test/javascript/jquery/jquery.js
31
- test/javascript/jquery/plugins/jquery.cookie.js
32
- test/javascript/jquery/plugins/jquery.cycle.all.min.js
33
- test/javascript/jquery/plugins/jquery.query.js
34
- test/javascript/scripts.js
20
+ Manifest
data/bin/coyote CHANGED
@@ -1,93 +1,34 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
3
4
  require 'fileutils'
4
5
  require 'rubygems'
5
6
  require 'optparse'
6
7
  require 'coyote'
7
8
 
9
+
8
10
  @options = {}
9
11
  OptionParser.new do |opts|
10
- opts.on("-f", "--force", "Force") do |o|
11
- @options[:force] = o
12
+ opts.on("-c", "--compress", "Compress") do |option|
13
+ @options['compress'] = option
12
14
  end
13
-
14
- opts.on("-c", "--compress", "Compress") do |o|
15
- @options[:compress] = o
15
+ opts.on("-v", "--verbose", "Verbose") do |option|
16
+ @options['verbose'] = option
16
17
  end
17
18
  end.parse!
18
19
 
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
- reader = config_file_reader
30
-
31
- output = Coyote::Output.new(reader.output_file, reader.should_compress?, reader.hooks)
32
- output.add_files(reader.input_files)
33
- output.save
34
- end
35
-
36
- def compress
37
- ARGV.shift
38
- if ! ARGV[0]
39
- Coyote::Notification.new "Compress requires an input parameter\n", "failure"
40
- puts "Example: 'coyote compress app.js'"
41
- exit
42
- else
43
- input_output_file = ARGV[0]
44
- temp_file = "#{input_output_file}.tmp"
45
-
46
- output = Coyote::Output.new(temp_file, true, false)
47
- output.add_files([input_output_file])
48
- output.save
49
-
50
- Coyote::Notification.new "Copying temporary file #{temp_file} to #{input_output_file}\n", "warning"
51
- File.open(temp_file, 'r') do |temp|
52
- output_file = File.open(input_output_file, 'w+')
53
- output_file.write(temp.read)
54
- output_file.close
55
- Coyote::Notification.new "Successfully copied temporary file #{temp_file} to #{input_output_file}\n", "success"
56
- end
57
-
58
- File.delete(temp_file)
59
- Coyote::Notification.new "Deleted temporary file #{temp_file}\n", "success"
60
- end
61
- end
62
-
63
20
 
64
21
  case ARGV.first
65
- when 'generate'
66
- Coyote::Generator.new(@options).generate
22
+ when 'new'
23
+ Coyote::generate
67
24
  when 'build'
68
- coyote_the_sources
69
- when 'compress'
70
- compress
25
+ config = Coyote::Configuration.new @options
26
+ config.load_from_yaml!
27
+ Coyote::build config
28
+ when 'watch'
29
+ config = Coyote::Configuration.new @options
30
+ config.load_from_yaml!
31
+ Coyote::watch config
71
32
  else
72
-
73
- coyote_the_sources
74
-
75
- listener = Coyote::FSListener.select_and_init
76
-
77
- listener.on_change do |files|
78
- if files.include?(Coyote::CONFIG_FILENAME)
79
- Coyote::Notification.new "Config file changed. Reading it in.\n", "warning"
80
-
81
- config_file_reader(true) #rebuild the sources of the config file
82
- coyote_the_sources
83
- else
84
- #see if any of the files in the config file changed
85
- changed_watched_files = config_file_reader.input_files & files
86
- if changed_watched_files.length > 0
87
- coyote_the_sources
88
- end
89
- end
90
- end
91
-
92
- listener.start
33
+ Coyote::usage
93
34
  end
@@ -0,0 +1,16 @@
1
+ ------------------------------------------
2
+ Coyote - Command-line Concatenation
3
+ http://github.com/imulus/coyote
4
+ ------------------------------------------
5
+
6
+ Usage : 'coyote Action [Environment] [Options]'
7
+
8
+ == Actions
9
+ build - Execute the compiler
10
+ watch - Starts the Coyote observe mechanism.
11
+ new - Create a Coyote configuration in this directory
12
+
13
+ == Options
14
+ -c | --compress - Use Google Closure Compiler
15
+ -v | --verbose - Verbose CLI logging
16
+
data/config/coyote.yaml CHANGED
@@ -1,2 +1,2 @@
1
- output: scripts.js
1
+ output: coyote.js
2
2
  input:
data/coyote.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{coyote}
5
- s.version = "0.4.2"
5
+ s.version = "0.5.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = [%q{Imulus}]
9
- s.date = %q{2011-07-25}
9
+ s.date = %q{2011-08-21}
10
10
  s.description = %q{An intelligent command-line tool for combining and compressing JavaScript files.}
11
11
  s.email = %q{developer@imulus.com}
12
12
  s.executables = [%q{coyote}]
13
- s.extra_rdoc_files = [%q{README.md}, %q{bin/coyote}, %q{lib/coyote.rb}, %q{lib/coyote/closure_compiler.rb}, %q{lib/coyote/config_reader.rb}, %q{lib/coyote/fs_listener.rb}, %q{lib/coyote/fs_listeners/darwin.rb}, %q{lib/coyote/fs_listeners/linux.rb}, %q{lib/coyote/fs_listeners/polling.rb}, %q{lib/coyote/fs_listeners/windows.rb}, %q{lib/coyote/generator.rb}, %q{lib/coyote/hooks.rb}, %q{lib/coyote/notification.rb}, %q{lib/coyote/output.rb}]
14
- s.files = [%q{Manifest}, %q{README.md}, %q{Rakefile}, %q{bin/coyote}, %q{config/coyote-icon.png}, %q{config/coyote.yaml}, %q{lib/coyote.rb}, %q{lib/coyote/closure_compiler.rb}, %q{lib/coyote/config_reader.rb}, %q{lib/coyote/fs_listener.rb}, %q{lib/coyote/fs_listeners/darwin.rb}, %q{lib/coyote/fs_listeners/linux.rb}, %q{lib/coyote/fs_listeners/polling.rb}, %q{lib/coyote/fs_listeners/windows.rb}, %q{lib/coyote/generator.rb}, %q{lib/coyote/hooks.rb}, %q{lib/coyote/notification.rb}, %q{lib/coyote/output.rb}, %q{test/coffeescript/coyote.yaml}, %q{test/coffeescript/lib/animals.js}, %q{test/coffeescript/src/animal.coffee}, %q{test/coffeescript/src/horse.coffee}, %q{test/coffeescript/src/init.coffee}, %q{test/coffeescript/src/snake.coffee}, %q{test/javascript/application.js}, %q{test/javascript/application/controller.js}, %q{test/javascript/application/interface.js}, %q{test/javascript/coyote.yaml}, %q{test/javascript/init.js}, %q{test/javascript/jquery/jquery.js}, %q{test/javascript/jquery/plugins/jquery.cookie.js}, %q{test/javascript/jquery/plugins/jquery.cycle.all.min.js}, %q{test/javascript/jquery/plugins/jquery.query.js}, %q{test/javascript/scripts.js}, %q{coyote.gemspec}]
13
+ s.extra_rdoc_files = [%q{README.md}, %q{bin/coyote}, %q{lib/coyote.rb}, %q{lib/coyote/closure_compiler.rb}, %q{lib/coyote/configuration.rb}, %q{lib/coyote/coy_file.rb}, %q{lib/coyote/fs_listener.rb}, %q{lib/coyote/fs_listeners/darwin.rb}, %q{lib/coyote/fs_listeners/linux.rb}, %q{lib/coyote/fs_listeners/polling.rb}, %q{lib/coyote/fs_listeners/windows.rb}, %q{lib/coyote/generator.rb}, %q{lib/coyote/notification.rb}, %q{lib/coyote/output.rb}]
14
+ s.files = [%q{README.md}, %q{Rakefile}, %q{bin/coyote}, %q{config/coyote-icon.png}, %q{config/coyote-usage.txt}, %q{config/coyote.yaml}, %q{coyote.gemspec}, %q{lib/coyote.rb}, %q{lib/coyote/closure_compiler.rb}, %q{lib/coyote/configuration.rb}, %q{lib/coyote/coy_file.rb}, %q{lib/coyote/fs_listener.rb}, %q{lib/coyote/fs_listeners/darwin.rb}, %q{lib/coyote/fs_listeners/linux.rb}, %q{lib/coyote/fs_listeners/polling.rb}, %q{lib/coyote/fs_listeners/windows.rb}, %q{lib/coyote/generator.rb}, %q{lib/coyote/notification.rb}, %q{lib/coyote/output.rb}, %q{Manifest}]
15
15
  s.homepage = %q{http://github.com/imulus/coyote}
16
16
  s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Coyote}, %q{--main}, %q{README.md}]
17
17
  s.require_paths = [%q{lib}]
data/lib/coyote.rb CHANGED
@@ -1,20 +1,88 @@
1
1
  require 'yaml'
2
2
  require 'term/ansicolor'
3
- require 'coyote/config_reader'
3
+ require 'coyote/coy_file'
4
+ require 'coyote/configuration'
4
5
  require 'coyote/fs_listener'
5
6
  require 'coyote/generator'
6
7
  require 'coyote/output'
7
8
  require 'coyote/closure_compiler'
8
9
  require 'coyote/notification'
9
- require 'coyote/hooks'
10
10
 
11
11
  include Term::ANSIColor
12
12
 
13
13
  module Coyote
14
- APP_NAME = "Coyote"
15
- VERSION = "0.4.2"
16
- ROOT_PATH = Dir.pwd
17
- CONFIG_PATH = File.expand_path(File.dirname(__FILE__) + "/../config")
14
+ APP_NAME = "Coyote"
15
+ VERSION = "0.5.0"
16
+ ROOT_PATH = Dir.pwd
17
+ CONFIG_PATH = File.expand_path(File.dirname(__FILE__) + "/../config")
18
18
  CONFIG_FILENAME = "coyote.yaml"
19
- CONFIG_ICON = "coyote-icon.png"
19
+ CONFIG_ICON = "coyote-icon.png"
20
+ USAGE_FILENAME = "coyote-usage.txt"
21
+
22
+ module Defaults
23
+ OUTPUT = "coyote.js"
24
+ end
25
+
26
+
27
+ module CoffeeScript
28
+ EXTENSION = ".coffee"
29
+ COMMENT = "#"
30
+ end
31
+
32
+
33
+ module JavaScript
34
+ EXTENSION = ".js"
35
+ COMMENT = "//"
36
+ end
37
+
38
+
39
+ def self.generate
40
+ Coyote::Generator.new.generate
41
+ end
42
+
43
+
44
+ def self.build(config)
45
+ output = Coyote::CoyFile.new config.output
46
+ output.empty!
47
+
48
+ config.inputs.each do |file|
49
+ input = Coyote::CoyFile.new file
50
+ input.compile! if input.coffee?
51
+ output.append input.contents
52
+ print "+ Added #{file}\n" if config.options['verbose']
53
+ end
54
+
55
+ output.compress! if config.should_compress?
56
+ output.save
57
+ Coyote::Notification.new "Saved #{config.output}\n\n", "success"
58
+ end
59
+
60
+
61
+ def self.watch(config)
62
+ self.build config
63
+
64
+ listener = Coyote::FSListener.select_and_init
65
+
66
+ listener.on_change do |files|
67
+ if files.include? config.source
68
+ Coyote::Notification.new "Config file (#{config.source}) changed. Reading it in.\n", "warning"
69
+ config.load_from_yaml! config.source
70
+ self.build config
71
+ else
72
+ changed_watched_files = config.inputs & files
73
+ if changed_watched_files.length > 0
74
+ self.build config
75
+ end
76
+ end
77
+ end
78
+
79
+ listener.start
80
+ end
81
+
82
+
83
+ def self.usage
84
+ file = File.open("#{Coyote::CONFIG_PATH}/#{Coyote::USAGE_FILENAME}", 'r')
85
+ puts file.read
86
+ file.close
87
+ end
20
88
  end
@@ -0,0 +1,89 @@
1
+ module Coyote
2
+ class Configuration
3
+
4
+ attr_accessor :options, :output, :source
5
+ attr_reader :inputs
6
+
7
+ def initialize(options = {})
8
+ @options = options
9
+ @inputs = []
10
+ @output = Coyote::Defaults::OUTPUT
11
+ end
12
+
13
+
14
+ def should_compress?
15
+ @options['compress'] || false
16
+ end
17
+
18
+
19
+ def inputs=(inputs)
20
+ inputs.each { |input| add_input input }
21
+ end
22
+
23
+
24
+ def add_input(input)
25
+ if input.class == Array
26
+ input.each do |input|
27
+ find_and_add_files input
28
+ end
29
+ elsif input.class == String and @output != input
30
+ find_and_add_files input
31
+ end
32
+ end
33
+
34
+
35
+ def load_from_yaml!(yaml_file = Coyote::CONFIG_FILENAME)
36
+ if File.exists?(yaml_file)
37
+ begin
38
+ config = YAML.load(File.open(yaml_file))
39
+ if config.class == Hash && ! config.empty?
40
+ self.inputs = config['input']
41
+ @output = config['output']
42
+ if config['options'] && config['options'].class == Hash
43
+ @options = config['options'].merge(@options)
44
+ end
45
+ @source = yaml_file
46
+ else
47
+ Coyote::Notification.new "Coyote configuration exists but has not been defined yet. Configure it in #{yaml_file}\n", "failure"
48
+ exit(0)
49
+ end
50
+ rescue ArgumentError => e
51
+ Coyote::Notification.new "Could not parse YAML: #{e.message}\n", "failure"
52
+ exit
53
+ end
54
+ else
55
+ Coyote::Notification.new "Could not find a Coyote configuration file #{yaml_file}. Use 'coyote new' to create one.\n", "failure"
56
+ exit
57
+ end
58
+ end
59
+
60
+
61
+
62
+ private
63
+
64
+ def find_and_add_files(input)
65
+ Dir.glob(input).each do |file|
66
+ required = find_requires file
67
+ required.each do |requirement|
68
+ find_and_add_files "**/#{requirement}"
69
+ end
70
+ if ! @inputs.include? file
71
+ @inputs.push file
72
+ end
73
+ end
74
+ end
75
+
76
+
77
+ def find_requires(input_file)
78
+ required = []
79
+ File.open(input_file) do |file|
80
+ file = file.read
81
+ pattern = Regexp.new(/((\/\/|\#)=.*)(require )(.*)$/x)
82
+ matches = file.scan(pattern)
83
+ matches.each { |match| required.push match.last.strip }
84
+ end
85
+ return required
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,64 @@
1
+ module Coyote
2
+ class CoyFile
3
+ attr_accessor :filename, :contents
4
+
5
+ def initialize(filename, contents = "")
6
+ @filename = filename
7
+ if contents.empty? and File.exists? @filename
8
+ @contents = File.open(@filename, 'r').read
9
+ else
10
+ @contents = contents
11
+ end
12
+ end
13
+
14
+ def append(content)
15
+ @contents += "#{content}\n\n"
16
+ end
17
+
18
+ def prepend(content)
19
+ @contents = "#{content}\n\n" + @contents
20
+ end
21
+
22
+ def type
23
+ File.extname @filename
24
+ end
25
+
26
+ def coffee?
27
+ type == Coyote::CoffeeScript::EXTENSION
28
+ end
29
+
30
+ def javascript?
31
+ type == Coyote::JavaScript::EXTENSION
32
+ end
33
+
34
+ def empty!
35
+ @contents = ""
36
+ end
37
+
38
+ def compress!
39
+ Coyote::Notification.new "Compiling #{@filename}...\n", "warning"
40
+ compiler = ClosureCompiler.new.compile(@contents)
41
+ if compiler.success?
42
+ @contents = compiler.compiled_code
43
+ elsif compiler.file_too_big?
44
+ Coyote::Notification.new "Input code too big for API, creating uncompiled file\n", "failure"
45
+ elsif compiler.errors
46
+ Coyote::Notification.new "Google closure API failed to compile, creating uncompiled file\n", "failure"
47
+ Coyote::Notification.new "Errors: \n", "failure"
48
+ Coyote::Notification.new "#{compiler.errors.to_s}\n\n", "failure"
49
+ end
50
+ end
51
+
52
+ def compile!
53
+ @contents = `cat #{@filename} | coffee -scb`
54
+ end
55
+
56
+ def save
57
+ output = File.open @filename, 'w+'
58
+ output.write @contents
59
+ output.close
60
+ end
61
+ end
62
+ end
63
+
64
+