jsc 0.1.2 → 0.1.3

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.
@@ -1,3 +1,14 @@
1
+ == 0.1.3 / 2009-12-14
2
+
3
+ BUG fix: now show every error in a file, not just the first
4
+ Exception handling for:
5
+ * file to check not found
6
+ * Name or service not known (SocketError)
7
+
8
+ == 0.1.2 / 2009-12-12
9
+
10
+ fix in --help option for jsc command when installed as gem
11
+
1
12
  == 0.1.0 / 2009-12-12
2
13
 
3
14
  * First gem release
@@ -47,9 +47,7 @@ Compile a piece of code, check for errors:
47
47
 
48
48
  ruby bin/jsc -e "function("
49
49
 
50
- <b>NOTE</b>: the library is a single file, so you can include it and just call the JSCompiler.compile(file_name, operations, compilation_level) function everywhere in your code. Check the plugins dir for samples or snippets.
51
-
52
- <b>UPDATE 20091212</b>: bin file plugins/bin/google_closure_compiler not working at the moment due to changes in project name and structure
50
+ <b>NOTE</b>: the library is a single file, so you can include it and just call one of the JSCompiler.compile* functions everywhere in your code.
53
51
 
54
52
  == EMACS SNIPPETS
55
53
 
@@ -67,7 +65,7 @@ Now, select the code to compile and run:
67
65
 
68
66
  == REQUIREMENTS:
69
67
 
70
- jsc require the {bones}[http://gemcutter.org/gems/bones] gem.
68
+ jsc requires the {bones}[http://gemcutter.org/gems/bones] gem.
71
69
 
72
70
  == INSTALL:
73
71
 
data/Rakefile CHANGED
@@ -31,7 +31,7 @@ Bones {
31
31
  authors 'sub'
32
32
  email 'fitzkarraldo@gmail.com'
33
33
  url 'http://github.com/sub/jsc'
34
- version '0.1.2'
34
+ version '0.1.3'
35
35
  summary 'Simple Ruby API to Google Closure Compiler Web service'
36
36
  }
37
37
 
data/bin/jsc CHANGED
@@ -82,10 +82,5 @@ unless ARGV.length > 0 or file
82
82
  exit 0
83
83
  end
84
84
 
85
- code = ARGV.shift
86
-
87
- if file
88
- puts JSCompiler.compile_file(file_path, output_info, level)
89
- else
90
- puts JSCompiler.compile(code, output_info, level)
91
- end
85
+ arg = file_path.blank? ? ARGV.shift : file_path
86
+ puts JSCompiler.compile(arg, file, output_info, level)
@@ -0,0 +1 @@
1
+ function hello(a){return; alert(\"Hello, \"+a)}hello(\"New user\")
@@ -0,0 +1,169 @@
1
+ require 'rubygems' # include RubyGems
2
+ gem 'activesupport' # load ActiveSupport
3
+ require 'activesupport' # include ActiveSupport
4
+ require 'active_support/core_ext/integer/inflections'
5
+
6
+ require 'json'
7
+ require 'net/http'
8
+
9
+ module JSCompiler
10
+
11
+ # CONFIGURE this with the relative path to your javascript
12
+ # folder (typically public/javascripts in a RAILS APP)
13
+ # NO MORE NEEDED
14
+ #JAVASCRIPTS_DIR = "js/"
15
+
16
+ # Link to Google Closure Compiler service
17
+ GOOGLE_SERVICE_ADDRESS = "http://closure-compiler.appspot.com/compile"
18
+ # Default output_info parameter
19
+ DEFAULT_SERVICE = "compiled_code"
20
+ # Default compilation_level parameter
21
+ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
22
+
23
+ class << self
24
+
25
+ # Creates the <em>JSON</em> hash for the request and returns the hash to send along with the request
26
+ #
27
+ # Accepted parameters:
28
+ # * <b>code</b>: json_code parameter
29
+ # * <b>level</b>: compilation_level parameter
30
+ def create_json_request(code)
31
+ parameters = {
32
+ "code" => code,
33
+ "level" => @level,
34
+ "format" => "json",
35
+ "info" => @op
36
+ }
37
+ end
38
+
39
+ # Sends the JSON request <em>data</em> hash to Google service and returns its response
40
+ #
41
+ def post_to_cc(data)
42
+ post_args = {
43
+ 'js_code' => data["code"],
44
+ 'compilation_level' => data["level"],
45
+ 'output_format' => data["format"],
46
+ 'output_info' => data["info"]
47
+ }
48
+ # send the request
49
+ resp, data = Net::HTTP.post_form(URI.parse(GOOGLE_SERVICE_ADDRESS), post_args)
50
+ end
51
+
52
+ # Reads the <em>file_name</em> file and calls compile method on it
53
+ #
54
+ # Accepted parameters:
55
+ # * <b>file_name</b>: absolute path to file
56
+ # * <b>op</b>: output_info parameter
57
+ # * <b>level</b>: compilation_level parameter
58
+ def compile_file(file_name, op, level)
59
+ # javascript_code = read_file(JAVASCRIPTS_DIR + file_name)
60
+ # resp, data = post_to_cc(create_json_request(javascript_code, op, level))
61
+ # parse_json_output(data, op)
62
+
63
+ javascript_code = read_file(file_name)
64
+ compile(javascript_code, op, level)
65
+ end
66
+
67
+ # Compiles <em>javascript_code</em> code and returns parsed output
68
+ #
69
+ # Accepted parameters:
70
+ # * <b>req</b>: the code to compile
71
+ # * <b>op</b>: output_info parameter
72
+ # * <b>level</b>: compilation_level parameter
73
+ def compile(req, is_file, op, level)
74
+ @op = op.blank? ? DEFAULT_SERVICE : op
75
+ @level = level.blank? ? DEFAULT_LEVEL : level
76
+
77
+ js_code = is_file ? read_file(qualcosa) : qualcosa
78
+ resp, data = post_to_cc(create_json_request(js_code))
79
+ parse_json_output(data)
80
+ end
81
+
82
+ # Calls compile method for every file in <em>dir</em> directory
83
+ #
84
+ # Accepted parameters:
85
+ # * <b>dir</b>: the directory
86
+ # * <b>op</b>: output_info parameter
87
+ # * <b>level</b>: compilation_level parameter
88
+ def compile_dir(dir, op, level)
89
+ out = String.new
90
+ Dir.entries(dir).each do |file|
91
+ if File.extname(file) == ".js"
92
+ out << "Statistics for file #{file}...\n"
93
+ out << compile_file(file, op, level) + "\n***************\n"
94
+ end
95
+ end
96
+ return out
97
+ end
98
+
99
+ # Parses and returns JSON server <em>response</em>
100
+ #
101
+ # Accepted parameters:
102
+ # * <b>response</b>: the server response
103
+ def parse_json_output(response)
104
+ out = String.new
105
+ parsed_response = JSON.parse(response, :max_nesting => false)
106
+ #p response
107
+
108
+ if parsed_response.has_key?("serverErrors")
109
+ result = parsed_response['serverErrors']
110
+ return "Server Error: #{result[0]['error']} - Error Code: #{result[0]['code']}"
111
+ end
112
+
113
+ case @op
114
+ when "compiled_code"
115
+ out = parsed_response['compiledCode']
116
+ when "statistics"
117
+ result = parsed_response['statistics']
118
+ out = create_statistics_output(result)
119
+ else "errors"
120
+ #case for errors or warnings
121
+ begin
122
+ result = parsed_response[@op]
123
+ unless result.nil?
124
+ result.each do |message|
125
+ out = "#{message['type']}: " + message[@op.singularize] + " at line #{message['lineno']} character #{message['charno']}\n"
126
+ out << message['line'] unless message['line'].nil?
127
+ return out
128
+ end
129
+ else
130
+ return "No #{@op}"
131
+ end
132
+ rescue
133
+ out = "Error parsing JSON output...Check your output"
134
+ end
135
+ end
136
+ end
137
+
138
+ # Reads file and returns its content
139
+ #
140
+ # Accepted parameters:
141
+ # * <b>file_name</b>: the absolute path to the file
142
+ def read_file(file_name)
143
+ begin
144
+ # content = File.open(JAVASCRIPTS_DIR + file_name).read
145
+ content = File.open(file_name).read
146
+ return content, true
147
+ rescue
148
+ out = "ERROR reading #{file_name} file"
149
+ return out, false
150
+ end
151
+ end
152
+
153
+ # Parses and returns the <em>result</em> JSON server response
154
+ #
155
+ # Accepted parameters:
156
+ # * <b>result</b>: the already parsed JSON server response
157
+ def create_statistics_output(result)
158
+ size_improvement = result['originalSize'] - result['compressedSize']
159
+ size_gzip_improvement = result['originalGzipSize'] - result['compressedGzipSize']
160
+ rate_improvement = (size_improvement * 100)/result['originalSize']
161
+ rate_gzip_improvement = (size_gzip_improvement * 100)/result['originalGzipSize']
162
+ out = "Original Size: #{result['originalSize']} bytes (#{result['originalGzipSize']} bytes gzipped) \n"
163
+ out << "Compiled Size: #{result['compressedSize']} bytes (#{result['compressedGzipSize']} bytes gzipped) \n"
164
+ out << "\t Saved #{rate_improvement}% off the original size (#{rate_gzip_improvement}% off the gzipped size)"
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -6,13 +6,6 @@ require 'active_support/core_ext/integer/inflections'
6
6
  require 'json'
7
7
  require 'net/http'
8
8
 
9
- module JSCompiler
10
-
11
- # CONFIGURE this with the relative path to your javascript
12
- # folder (typically public/javascripts in a RAILS APP)
13
- # NO MORE NEEDED
14
- #JAVASCRIPTS_DIR = "js/"
15
-
16
9
  # Link to Google Closure Compiler service
17
10
  GOOGLE_SERVICE_ADDRESS = "http://closure-compiler.appspot.com/compile"
18
11
  # Default output_info parameter
@@ -20,6 +13,8 @@ DEFAULT_SERVICE = "compiled_code"
20
13
  # Default compilation_level parameter
21
14
  DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
22
15
 
16
+ module JSCompiler
17
+
23
18
  class << self
24
19
 
25
20
  # Creates the <em>JSON</em> hash for the request and returns the hash to send along with the request
@@ -49,32 +44,36 @@ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
49
44
  resp, data = Net::HTTP.post_form(URI.parse(GOOGLE_SERVICE_ADDRESS), post_args)
50
45
  end
51
46
 
52
- # Reads the <em>file_name</em> file and calls compile method on it
47
+ # Compiles a file or a piece of code and returns parsed output
53
48
  #
54
49
  # Accepted parameters:
55
- # * <b>file_name</b>: absolute path to file
50
+ # * <b>arg</b>: the code or the file path to compile
51
+ # * <b>is_file</b>: 0 => arg is code
52
+ # 1 => arg is a file path
56
53
  # * <b>op</b>: output_info parameter
57
54
  # * <b>level</b>: compilation_level parameter
58
- def compile_file(file_name, op, level)
59
- # javascript_code = read_file(JAVASCRIPTS_DIR + file_name)
60
- # resp, data = post_to_cc(create_json_request(javascript_code, op, level))
61
- # parse_json_output(data, op)
62
-
63
- javascript_code = read_file(file_name)
64
- compile(javascript_code, op, level)
65
- end
66
-
67
- # Compiles <em>javascript_code</em> code and returns parsed output
68
- #
69
- # Accepted parameters:
70
- # * <b>javascript_code</b>: the code to compile
71
- # * <b>op</b>: output_info parameter
72
- # * <b>level</b>: compilation_level parameter
73
- def compile(javascript_code, op, level)
55
+ def compile(arg, is_file, op, level)
74
56
  @op = op.blank? ? DEFAULT_SERVICE : op
75
57
  @level = level.blank? ? DEFAULT_LEVEL : level
58
+ value = true
59
+
60
+ if is_file
61
+ js_code, value = read_file(arg)
62
+ else
63
+ js_code = arg
64
+ end
65
+ # js_code = is_file ? read_file(arg) : arg
66
+
67
+ unless value
68
+ return "Error reading file #{arg}"
69
+ end
70
+
71
+ begin
72
+ resp, data = post_to_cc(create_json_request(js_code))
73
+ rescue
74
+ return "Error calling the service...try again later"
75
+ end
76
76
 
77
- resp, data = post_to_cc(create_json_request(javascript_code))
78
77
  parse_json_output(data)
79
78
  end
80
79
 
@@ -89,7 +88,7 @@ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
89
88
  Dir.entries(dir).each do |file|
90
89
  if File.extname(file) == ".js"
91
90
  out << "Statistics for file #{file}...\n"
92
- out << compile_file(file, op, level) + "\n***************\n"
91
+ out << compile(file, true, op, level) + "\n***************\n"
93
92
  end
94
93
  end
95
94
  return out
@@ -102,7 +101,6 @@ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
102
101
  def parse_json_output(response)
103
102
  out = String.new
104
103
  parsed_response = JSON.parse(response, :max_nesting => false)
105
- #p response
106
104
 
107
105
  if parsed_response.has_key?("serverErrors")
108
106
  result = parsed_response['serverErrors']
@@ -121,10 +119,10 @@ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
121
119
  result = parsed_response[@op]
122
120
  unless result.nil?
123
121
  result.each do |message|
124
- out = "#{message['type']}: " + message[@op.singularize] + " at line #{message['lineno']} character #{message['charno']}\n"
125
- out << message['line'] unless message['line'].nil?
126
- return out
122
+ out << "#{message['type']}: " + message[@op.singularize] + " at line #{message['lineno']} character #{message['charno']}\n"
123
+ out << message['line'] + "\n" unless message['line'].nil?
127
124
  end
125
+ return out
128
126
  else
129
127
  return "No #{@op}"
130
128
  end
@@ -140,7 +138,6 @@ DEFAULT_LEVEL = "SIMPLE_OPTIMIZATIONS"
140
138
  # * <b>file_name</b>: the absolute path to the file
141
139
  def read_file(file_name)
142
140
  begin
143
- # content = File.open(JAVASCRIPTS_DIR + file_name).read
144
141
  content = File.open(file_name).read
145
142
  return content, true
146
143
  rescue
@@ -1,15 +1,36 @@
1
1
 
2
2
  require File.join(File.dirname(__FILE__), %w[spec_helper])
3
3
 
4
+ COMPILE_CODE = <<-EOU
5
+ function hello(name) {
6
+ alert('Hello, ' + name)
7
+ }
8
+ hello('New user');
9
+ EOU
10
+
11
+ ERROR_CODE = <<-EOU
12
+ functiont hello(name) {
13
+ alert('Hello, ' + name)
14
+ }
15
+ hello('New user');
16
+ EOU
17
+
18
+ WARNING_CODE = <<-EOU
19
+ function hello(name) {
20
+ return;
21
+ alert('Hello, ' + name)
22
+ }
23
+ hello('New user');
24
+ EOU
25
+
4
26
  describe JSCompiler do
5
27
 
6
28
  describe 'Use the web service through API' do
7
-
29
+
8
30
  describe 'Put all keys in the request' do
9
31
 
10
32
  before do
11
- code = "function hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
12
- @request = JSCompiler.create_json_request(code)
33
+ @request = JSCompiler.create_json_request(COMPILE_CODE)
13
34
  @request['level'] = "SIMPLE_OPTIMIZATIONS"
14
35
  @request['info'] = "compiled_code"
15
36
  end
@@ -37,8 +58,7 @@ describe JSCompiler do
37
58
 
38
59
  describe 'create a JSON compile-code request (default request)' do
39
60
  before do
40
- code = "function hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
41
- @request = JSCompiler.create_json_request(code)
61
+ @request = JSCompiler.create_json_request(COMPILE_CODE)
42
62
  @request['level'] = "SIMPLE_OPTIMIZATIONS"
43
63
  @request['info'] = "compiled_code"
44
64
  end
@@ -62,8 +82,7 @@ describe JSCompiler do
62
82
 
63
83
  describe 'compile code and get compiled code' do
64
84
  before do
65
- code = "function hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
66
- @resp = JSCompiler.compile(code, "compiled_code", "SIMPLE_OPTIMIZATIONS")
85
+ @resp = JSCompiler.compile(COMPILE_CODE, false, "compiled_code", "SIMPLE_OPTIMIZATIONS")
67
86
  end
68
87
 
69
88
  it 'should receive the compiled code' do
@@ -73,30 +92,28 @@ describe JSCompiler do
73
92
 
74
93
  describe 'compile code and find errors' do
75
94
  before do
76
- code = "functiont hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
77
- @resp = JSCompiler.compile(code, "errors", "SIMPLE_OPTIMIZATIONS")
95
+ @resp = JSCompiler.compile(ERROR_CODE, false, "errors", "SIMPLE_OPTIMIZATIONS")
78
96
  end
79
97
 
80
98
  it 'should return the result string' do
81
99
  @resp.should match(/at line/)
82
100
  end
83
101
  end
84
-
102
+
85
103
  describe 'compile code and find warnings' do
86
104
  before do
87
- code = "function hello(a){return; alert(\"Hello, \"+a)}hello(\"New user\");"
88
- @resp = JSCompiler.compile(code, "warnings", "SIMPLE_OPTIMIZATIONS")
105
+ @resp = JSCompiler.compile(WARNING_CODE, false, "warnings", "SIMPLE_OPTIMIZATIONS")
106
+ puts @resp
89
107
  end
90
108
 
91
109
  it 'should return the result string' do
92
110
  @resp.should match(/at line/)
93
111
  end
94
112
  end
95
-
113
+
96
114
  describe 'compile code and obtain statistics' do
97
115
  before do
98
- code = "function hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
99
- @resp = JSCompiler.compile(code, "statistics", "SIMPLE_OPTIMIZATIONS")
116
+ @resp = JSCompiler.compile(COMPILE_CODE, false, "statistics", "SIMPLE_OPTIMIZATIONS")
100
117
  end
101
118
 
102
119
  it 'should return the result string' do
@@ -109,12 +126,18 @@ describe JSCompiler do
109
126
  before do
110
127
  #test file
111
128
  @file_name = 'js/compiled_code.js'
129
+ @file_not_found = 'js/not_found.js'
112
130
  end
113
131
 
114
132
  it 'should return the code without errors' do
115
133
  result, value = JSCompiler.read_file(@file_name)
116
134
  value.should be_true
117
135
  end
136
+
137
+ it 'should return error if file not found' do
138
+ result, value = JSCompiler.read_file(@file_not_found)
139
+ result.should match(/ERROR reading /)
140
+ end
118
141
  end
119
142
 
120
143
  describe 'compile a whole directory' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - sub
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-12 00:00:00 +01:00
12
+ date: 2009-12-14 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -25,28 +25,31 @@ dependencies:
25
25
  description: Simple Ruby API to Google Closure Compiler Web service.
26
26
  email: fitzkarraldo@gmail.com
27
27
  executables:
28
+ - "#jsc#"
28
29
  - jsc
29
30
  extensions: []
30
31
 
31
32
  extra_rdoc_files:
32
33
  - History.txt
33
34
  - README.rdoc
35
+ - bin/#jsc#
34
36
  - bin/jsc
35
37
  files:
36
- - .bnsignore
37
38
  - .gitignore
38
39
  - History.txt
39
40
  - README.rdoc
40
41
  - Rakefile
42
+ - bin/#jsc#
41
43
  - bin/jsc
42
44
  - js/compiled_code.js
43
45
  - js/errors.js
46
+ - js/temp.js
44
47
  - js/warnings.js
45
48
  - lib/jsc.rb
49
+ - lib/jsc/clo2.rb
46
50
  - lib/jsc/closure_compiler.rb
47
- - plugins/bin/google_closure_compiler
48
51
  - plugins/jsc.el
49
- - spec/jsc.rb
52
+ - spec/jsc_spec.rb
50
53
  - spec/spec_helper.rb
51
54
  - spec/wip_spec.rb
52
55
  - tasks/jsc.rake
data/.bnsignore DELETED
@@ -1,18 +0,0 @@
1
- # The list of files that should be ignored by Mr Bones.
2
- # Lines that start with '#' are comments.
3
- #
4
- # A .gitignore file can be used instead by setting it as the ignore
5
- # file in your Rakefile:
6
- #
7
- # Bones {
8
- # ignore_file '.gitignore'
9
- # }
10
- #
11
- # For a project with a C extension, the following would be a good set of
12
- # exclude patterns (uncomment them if you want to use them):
13
- # *.[oa]
14
- # *~
15
- announcement.txt
16
- coverage
17
- doc
18
- pkg
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(
4
- File.join(File.dirname(__FILE__), %w[.. .. lib google_closure_compiler]))
5
-
6
- # Give me errors!
7
- puts ClosureCompiler.compile_file("test_errors.js", "errors")
8
- puts "**************\n"
9
-
10
- # Read file and compile it!
11
-
12
- # function passing it the relative path of the file
13
- code_to_compile, result = ClosureCompiler.read_file('test.js')
14
- if result
15
- compiled_code = ClosureCompiler.compile(code_to_compile, "compiled_code")
16
- unless compiled_code.nil?
17
- puts compiled_code
18
- end
19
- else
20
- puts "ERROR reading file\n"
21
- end
22
- puts "**************\n"
23
-
24
- # Give me statistics!
25
- code_to_compile = "function hello(a){alert(\"Hello, \"+a)}hello(\"New user\");"
26
- puts ClosureCompiler.compile(code_to_compile, "statistics")
27
- puts "**************\n"
28
-
29
- # Compile a whole directory
30
- js_dir = "js" # relative path to js directory
31
- puts "Compiling a WHOLE directory...\n"
32
- puts ClosureCompiler.compile_dir(js_dir, "statistics")
33
- puts "**************\n"
34
-
35
- # Execute every check on the file
36
- puts ClosureCompiler.compile_file("js/compiled_code.js", "compiled_code")
37
- puts "*******************"
38
- puts ClosureCompiler.compile_file("js/compiled_code.js", "warnings")
39
- puts "*******************"
40
- puts ClosureCompiler.compile_file("js/compiled_code.js", "errors")
41
- puts "*******************"
42
- puts ClosureCompiler.compile_file("js/compiled_code.js", "statistics")