coffee-script 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.md +28 -5
  2. data/lib/coffee_script.rb +116 -42
  3. metadata +39 -12
data/README.md CHANGED
@@ -1,15 +1,38 @@
1
1
  Ruby CoffeeScript
2
2
  =================
3
3
 
4
- Ruby CoffeeScript is a thin wrapper around the `coffee` binary.
4
+ Ruby CoffeeScript is a bridge to the official CoffeeScript compiler.
5
+
6
+ CoffeeScript.compile File.read("script.coffee")
7
+
8
+
9
+ Installation
10
+ ------------
11
+
12
+ gem install coffee-script
13
+
14
+ *This compiler lib has replaced the original CoffeeScript compiler that was written in Ruby*
5
15
 
6
- CoffeeScript.compile File.open("script.coffee")
7
16
 
8
17
  Dependencies
9
18
  ------------
10
19
 
11
- This is **not** the CoffeeScript parser. This means you need to install `node` and `coffee`.
20
+ The compiler depends on the `coffee-script-source` gem which is updated any time a new version of CoffeeScript is released. The gem's version number is sync'd up with the javascript release. This way you can build against different versions of CoffeeScript from this compiler.
21
+
22
+ You can also use this lib with unreleased versions of CoffeeScript:
23
+
24
+ export COFFEESCRIPT_SOURCE_PATH=/path/to/coffee-script/extras/coffee-script.js
25
+
26
+ The json library is also required but is not explicity stated as a gem dependency. If you're on 1.8 you'll need to install the json or json_pure gem. Its already included in 1.9.
27
+
28
+
29
+ Engines
30
+ -------
31
+
32
+ The `coffee-script` lib will automatically choose the best JavaScript engine for your platform. The currently implemented engines are:
33
+
34
+ * **Node.js**. If the `node` binary is available in $PATH, it will be used to invoke the CoffeeScript compiler.
12
35
 
13
- If your `coffee` binary is in a weird location, you can specify the path by hand.
36
+ * **JavaScript Core**. If you're on OS X and don't have Node.js installed, the lib will fall back to the built-in JavaScript Core binary, `jsc`. This way you don't need any additional dependencies.
14
37
 
15
- CoffeeScript.coffee_bin = "/usr/local/bin/coffee"
38
+ * **V8**. Shelling out to Node.js may be too slow for your production environment. In this case, install `therubyracer` gem, which provides a fast bridge between Ruby and V8.
data/lib/coffee_script.rb CHANGED
@@ -1,64 +1,138 @@
1
+ require 'json'
2
+ require 'tempfile'
3
+
4
+ require 'coffee_script/source'
5
+
1
6
  module CoffeeScript
2
- class << self
3
- def locate_coffee_bin
4
- out = `which coffee`
5
- if $?.success?
6
- out.chomp
7
- else
8
- raise LoadError, "could not find `coffee` in PATH"
9
- end
7
+ module Source
8
+ def self.path
9
+ @path ||= ENV['COFFEESCRIPT_SOURCE_PATH'] || bundled_path
10
10
  end
11
11
 
12
- def coffee_bin
13
- @@coffee_bin ||= locate_coffee_bin
12
+ def self.path=(path)
13
+ @contents = @version = @bare_option = nil
14
+ @path = path
14
15
  end
15
16
 
16
- def coffee_bin=(path)
17
- @@coffee_bin = path
17
+ def self.contents
18
+ @contents ||= File.read(path)
18
19
  end
19
20
 
20
- def version
21
- `#{coffee_bin} --version`[/(\d|\.)+/]
21
+ def self.version
22
+ @version ||= contents[/CoffeeScript Compiler v([\d.]+)/, 1]
22
23
  end
23
24
 
24
- # Compile a script (String or IO) to JavaScript.
25
- def compile(script, options = {})
26
- args = "-sp"
25
+ def self.bare_option
26
+ @bare_option ||= contents.match(/noWrap/) ? 'noWrap' : 'bare'
27
+ end
28
+ end
27
29
 
28
- if options[:wrap] == false ||
29
- options.key?(:bare) ||
30
- options.key?(:no_wrap)
31
- args += " --#{no_wrap_flag}"
32
- end
30
+ module Engines
31
+ module JavaScriptCore
32
+ BIN = "/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc"
33
33
 
34
- execute_coffee(script, args)
35
- end
34
+ class << self
35
+ def supported?
36
+ File.exist?(BIN)
37
+ end
38
+
39
+ def compile(script, options = {})
40
+ options = options[:bare] ? "{#{Source.bare_option} : true}" : "{}"
36
41
 
37
- # Evaluate a script (String or IO) and return the stdout.
38
- # Note: the first argument will be process.argv[3], the second
39
- # process.argv[4], etc.
40
- def evaluate(script, *args)
41
- execute_coffee(script, "-s #{args.join(' ')}")
42
+ f = Tempfile.open("coffee.js")
43
+ f.puts "load(#{Source.path.to_json});"
44
+ f.puts "print(CoffeeScript.compile(#{script.to_json}, #{options}));"
45
+ f.close
46
+
47
+ out = `#{BIN} #{f.path}`
48
+ $?.success? ? out.chomp : nil
49
+ ensure
50
+ f.close! if f
51
+ end
52
+ end
42
53
  end
43
54
 
44
- private
45
- def execute_coffee(script, args)
46
- command = "#{coffee_bin} #{args}"
47
- script = script.read if script.respond_to?(:read)
55
+ module Node
56
+ class << self
57
+ def supported?
58
+ `which node`
59
+ $?.success?
60
+ end
61
+
62
+ def compile(script, options = {})
63
+ options = options[:bare] ? "{#{Source.bare_option} : true}" : "{}"
64
+
65
+ f = Tempfile.open("coffee.js")
66
+ f.puts Source.contents
67
+ f.puts "console.log(this.CoffeeScript.compile(#{script.to_json}, #{options}));"
68
+ f.close
48
69
 
49
- IO.popen(command, "w+") do |f|
50
- f << script
51
- f.close_write
52
- f.read
70
+ out = `node #{f.path}`
71
+ $?.success? ? out.chomp : nil
72
+ ensure
73
+ f.close! if f
53
74
  end
54
75
  end
76
+ end
77
+
78
+ module V8
79
+ class << self
80
+ def supported?
81
+ require 'v8'
82
+ true
83
+ rescue LoadError
84
+ false
85
+ end
55
86
 
56
- def no_wrap_flag
57
- if `#{coffee_bin} --help`.lines.grep(/--no-wrap/).any?
58
- 'no-wrap'
59
- else
60
- 'bare'
87
+ def compile(script, options = {})
88
+ coffee_module['compile'].call(script, Source.bare_option => options[:bare])
61
89
  end
90
+
91
+ private
92
+ def coffee_module
93
+ @coffee_module ||= build_coffee_module
94
+ end
95
+
96
+ def build_coffee_module
97
+ context = ::V8::Context.new
98
+ context.eval(Source.contents)
99
+ context['CoffeeScript']
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ class << self
106
+ def engine
107
+ @engine ||= nil
108
+ end
109
+
110
+ def engine=(engine)
111
+ @engine = engine
112
+ end
113
+
114
+ def version
115
+ Source.version
116
+ end
117
+
118
+ # Compile a script (String or IO) to JavaScript.
119
+ def compile(script, options = {})
120
+ script = script.read if script.respond_to?(:read)
121
+
122
+ if options.key?(:bare)
123
+ elsif options.key?(:no_wrap)
124
+ options[:bare] = options[:no_wrap]
125
+ else
126
+ options[:bare] = false
62
127
  end
128
+
129
+ engine.compile(script, options)
130
+ end
63
131
  end
132
+
133
+ self.engine ||= [
134
+ Engines::V8,
135
+ Engines::Node,
136
+ Engines::JavaScriptCore
137
+ ].detect(&:supported?)
64
138
  end
metadata CHANGED
@@ -1,26 +1,54 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coffee-script
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
- - 1
8
- - 1
7
+ - 2
9
8
  - 0
10
- version: 1.1.0
9
+ - 0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Ashkenas
14
14
  - Joshua Peek
15
+ - Sam Stephenson
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2010-10-29 00:00:00 -05:00
20
+ date: 2010-11-12 00:00:00 -06:00
20
21
  default_executable:
21
- dependencies: []
22
-
23
- description: " Ruby CoffeeScript is a thin wrapper around the coffee binary.\n"
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: coffee-script-source
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: therubyracer
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ description: " Ruby CoffeeScript is a bridge to the JS CoffeeScript compiler.\n"
24
52
  email: josh@joshpeek.com
25
53
  executables: []
26
54
 
@@ -60,13 +88,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
88
  segments:
61
89
  - 0
62
90
  version: "0"
63
- requirements:
64
- - node
65
- - coffee-script
91
+ requirements: []
92
+
66
93
  rubyforge_project: coffee-script
67
94
  rubygems_version: 1.3.7
68
95
  signing_key:
69
96
  specification_version: 3
70
- summary: Ruby CoffeeScript wrapper
97
+ summary: Ruby CoffeeScript Compiler
71
98
  test_files: []
72
99