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 +5 -19
- data/bin/coyote +16 -75
- data/config/coyote-usage.txt +16 -0
- data/config/coyote.yaml +1 -1
- data/coyote.gemspec +4 -4
- data/lib/coyote.rb +75 -7
- data/lib/coyote/configuration.rb +89 -0
- data/lib/coyote/coy_file.rb +64 -0
- data/lib/coyote/generator.rb +13 -13
- data/lib/coyote/output.rb +2 -7
- metadata +21 -36
- data/lib/coyote/config_reader.rb +0 -92
- data/lib/coyote/hooks.rb +0 -18
- data/test/coffeescript/coyote.yaml +0 -9
- data/test/coffeescript/lib/animals.js +0 -46
- data/test/coffeescript/src/animal.coffee +0 -5
- data/test/coffeescript/src/horse.coffee +0 -5
- data/test/coffeescript/src/init.coffee +0 -5
- data/test/coffeescript/src/snake.coffee +0 -4
- data/test/javascript/application.js +0 -3
- data/test/javascript/application/controller.js +0 -6
- data/test/javascript/application/interface.js +0 -8
- data/test/javascript/coyote.yaml +0 -10
- data/test/javascript/init.js +0 -7
- data/test/javascript/jquery/jquery.js +0 -16
- data/test/javascript/jquery/plugins/jquery.cookie.js +0 -91
- data/test/javascript/jquery/plugins/jquery.cycle.all.min.js +0 -24
- data/test/javascript/jquery/plugins/jquery.query.js +0 -227
- data/test/javascript/scripts.js +0 -401
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/
|
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
|
-
|
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("-
|
11
|
-
@options[
|
12
|
+
opts.on("-c", "--compress", "Compress") do |option|
|
13
|
+
@options['compress'] = option
|
12
14
|
end
|
13
|
-
|
14
|
-
|
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 '
|
66
|
-
|
22
|
+
when 'new'
|
23
|
+
Coyote::generate
|
67
24
|
when 'build'
|
68
|
-
|
69
|
-
|
70
|
-
|
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:
|
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.
|
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-
|
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/
|
14
|
-
s.files = [%q{
|
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/
|
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
|
15
|
-
VERSION
|
16
|
-
ROOT_PATH
|
17
|
-
CONFIG_PATH
|
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
|
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
|
+
|