coyote 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
+