nibjs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +45 -0
  4. data/LICENCE.js +7 -0
  5. data/LICENCE.md +22 -0
  6. data/Manifest.txt +16 -0
  7. data/README.md +64 -0
  8. data/Rakefile +53 -0
  9. data/bin/nibjs +4 -0
  10. data/lib/nibjs/loader.rb +2 -0
  11. data/lib/nibjs/main.rb +288 -0
  12. data/lib/nibjs/version.rb +14 -0
  13. data/lib/nibjs.rb +9 -0
  14. data/nibjs.gemspec +194 -0
  15. data/nibjs.noespec +41 -0
  16. data/src/nibjs.coffee +124 -0
  17. data/tasks/debug_mail.rake +78 -0
  18. data/tasks/debug_mail.txt +13 -0
  19. data/tasks/dist.rake +14 -0
  20. data/tasks/gem.rake +68 -0
  21. data/tasks/test.rake +72 -0
  22. data/tasks/yard.rake +51 -0
  23. data/test/command/header.js +1 -0
  24. data/test/command/nibjs_spec.rb +52 -0
  25. data/test/command/run.rb +3 -0
  26. data/test/command/sc_coffee_1.exp +31 -0
  27. data/test/command/sc_coffee_2.exp +26 -0
  28. data/test/command/sc_coffee_3.exp +25 -0
  29. data/test/command/sc_coffee_4.exp +26 -0
  30. data/test/command/sc_coffee_5.exp +24 -0
  31. data/test/command/sc_common_0.exp +31 -0
  32. data/test/command/sc_common_1.exp +31 -0
  33. data/test/command/sc_common_2.exp +32 -0
  34. data/test/command/sc_common_3.exp +32 -0
  35. data/test/command/sc_common_4.exp +1 -0
  36. data/test/command/sc_common_5.exp +1 -0
  37. data/test/command/scenarios.rb +73 -0
  38. data/test/fixture.coffee/app.coffee +6 -0
  39. data/test/fixture.coffee/dependent.coffee +8 -0
  40. data/test/fixture.coffee/index.coffee +3 -0
  41. data/test/fixture.js/app.js +9 -0
  42. data/test/fixture.js/dependent.js +10 -0
  43. data/test/fixture.js/index.js +3 -0
  44. data/test/fixture.min.js +28 -0
  45. data/test/integration/index.html +42 -0
  46. data/test/integration/integration_test.coffee +29 -0
  47. data/test/integration/integration_test.js +34 -0
  48. data/test/integration/integration_test.rb +37 -0
  49. data/test/integration/jquery-1.4.4.min.js +167 -0
  50. data/test/jasmine/nibjs_spec.coffee +31 -0
  51. data/test/jasmine/run.coffee +14 -0
  52. data/test/nibjs.js +74 -0
  53. metadata +325 -0
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # 1.0.0 / 2011-02-22
2
+
3
+ * Enhancements
4
+
5
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org'
2
+ gemspec :name => "nibjs"
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nibjs (1.0.0)
5
+ bundler (~> 1.0)
6
+ quickl (~> 0.2.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ bluecloth (2.0.10)
12
+ diff-lcs (1.1.2)
13
+ quickl (0.2.0)
14
+ rack (1.2.1)
15
+ rake (0.8.7)
16
+ rcov (0.9.9)
17
+ rspec (2.4.0)
18
+ rspec-core (~> 2.4.0)
19
+ rspec-expectations (~> 2.4.0)
20
+ rspec-mocks (~> 2.4.0)
21
+ rspec-core (2.4.0)
22
+ rspec-expectations (2.4.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.4.0)
25
+ sinatra (1.1.2)
26
+ rack (~> 1.1)
27
+ tilt (~> 1.2)
28
+ tilt (1.2.2)
29
+ wlang (0.10.1)
30
+ yard (0.6.4)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ bluecloth (~> 2.0.9)
37
+ bundler (~> 1.0)
38
+ nibjs!
39
+ quickl (~> 0.2.0)
40
+ rake (~> 0.8.7)
41
+ rcov (~> 0.9)
42
+ rspec (~> 2.4.0)
43
+ sinatra (> 0)
44
+ wlang (~> 0.10.1)
45
+ yard (~> 0.6.4)
data/LICENCE.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * nib.js - [Java/Coffee]script application packager from node.js conventions
3
+ *
4
+ * Copyright 2011, Bernard Lambeau
5
+ * Released under the MIT License
6
+ * http://github.com/blambeau/nib.js
7
+ */
data/LICENCE.md ADDED
@@ -0,0 +1,22 @@
1
+ # The MIT Licence
2
+
3
+ Copyright (c) 2011 - Bernard Lambeau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,16 @@
1
+ bin/**/*
2
+ CHANGELOG.md
3
+ dist
4
+ Gemfile
5
+ Gemfile.lock
6
+ lib/**/*
7
+ LICENCE.js
8
+ LICENCE.md
9
+ Manifest.txt
10
+ nibjs.gemspec
11
+ nibjs.noespec
12
+ Rakefile
13
+ README.md
14
+ src/**/*
15
+ tasks/**/*
16
+ test/**/*
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # NibJS
2
+
3
+ nib.js - Package and embed node.js or coffeescript libraries in the browser
4
+
5
+ nib.js is a NibJS javascript library allowing to maintain javascript/coffeescript projects
6
+ ala 'node.js' (modules, exports, require) while also targetting a web browser as execution
7
+ platform. It contains a simple packager command (nibjs) that will convert your sources to a
8
+ single and minified .js file to be embedded in the browser. Node.js's exports and require
9
+ are correctly bounded.
10
+
11
+ ## Getting started
12
+
13
+ gem install nibjs
14
+ nibjs --help
15
+
16
+ ## How to use it
17
+
18
+ Let assume that your project has the structure below.
19
+
20
+ mylib/
21
+ dist/
22
+ src/
23
+ foo.[js,coffee] # exports.Foo = ...
24
+ bar.[js,coffee] # require('./foo')
25
+ index.[js,coffee] # exports.X = ...
26
+ spec/
27
+ foo_spec.[js,coffee]
28
+ bar_spec.[js,coffee]
29
+ package.json
30
+
31
+ ### EXAMPLE 1 (embedded javascript):
32
+
33
+ In a shell:
34
+
35
+ # if the sources are .js
36
+ nibjs --libname=mylib --output=mylib.js src
37
+
38
+ # if the sources are .coffee
39
+ nibjs --coffee --libname=mylib --output=mylib.js src
40
+
41
+ In the browser:
42
+
43
+ <script src="js/nibjs.js" type="text/javascript">
44
+ <script src="js/mylib.js" type="text/javascript">
45
+ <script>
46
+ var mylib = NibJS.require('mylib')
47
+ </script>
48
+
49
+ ### EXAMPLE 2 (embedded coffeescript):
50
+
51
+ In a shell:
52
+
53
+ nibjs --coffee --no-coffee-compile --libname=mylib --output=mylib.coffee src
54
+
55
+ In the browser:
56
+
57
+ <script src="js/coffee-script.js" type="text/javascript">
58
+ <script src="js/nibjs.js" type="text/javascript">
59
+ <script src="js/mylib.coffee" type="text/coffeescript">
60
+ <script>
61
+ /* But be warned of coffeescript's issue 1054
62
+ https://github.com/jashkenas/coffee-script/issues/#issue/1054 */
63
+ var mylib = NibJS.require('mylib')
64
+ </script>
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ begin
2
+ gem "bundler", "~> 1.0"
3
+ require "bundler/setup"
4
+ rescue LoadError => ex
5
+ puts ex.message
6
+ abort "Bundler failed to load, (did you run 'gem install bundler' ?)"
7
+ end
8
+
9
+ # Runs a command, returns result on STDOUT. If the exit status was no 0,
10
+ # a RuntimeError is raised.
11
+ def shell_safe_exec(cmd)
12
+ puts cmd
13
+ unless system(cmd)
14
+ raise RuntimeError, "Error while executing #{cmd}"
15
+ end
16
+ $?
17
+ end
18
+
19
+ def _(path)
20
+ File.join(File.dirname(__FILE__), path)
21
+ end
22
+
23
+ def dist(target)
24
+ shell_safe_exec("cat src/nibjs.coffee | coffee --bare --compile --stdio > #{target}")
25
+ code = ""
26
+ code += File.read("LICENCE.js")
27
+ code += "(function(exports){\n"
28
+ code += File.read(target).gsub(/^/m, " ")
29
+ code += "}).call(this, this)"
30
+ File.open(target, "w"){|io| io << code}
31
+ end
32
+
33
+ def nibjs(*args)
34
+ nibjs = _('bin/nibjs')
35
+ shell_safe_exec "#{nibjs} #{args.flatten.join(' ')}"
36
+ end
37
+
38
+ # Dynamically load the gem spec
39
+ $gemspec_file = File.expand_path('../nibjs.gemspec', __FILE__)
40
+ $gemspec = Kernel.eval(File.read($gemspec_file))
41
+
42
+ # We run tests by default
43
+ task :default => :test
44
+
45
+ #
46
+ # Install all tasks found in tasks folder
47
+ #
48
+ # See .rake files there for complete documentation.
49
+ #
50
+ Dir["tasks/*.rake"].each do |taskfile|
51
+ instance_eval File.read(taskfile), taskfile
52
+ end
53
+
data/bin/nibjs ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby -rrubygems
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+ require "nibjs"
4
+ NibJS::Main.run(ARGV)
@@ -0,0 +1,2 @@
1
+ require "bundler"
2
+ require "quickl"
data/lib/nibjs/main.rb ADDED
@@ -0,0 +1,288 @@
1
+ require 'nibjs'
2
+ module NibJS
3
+ #
4
+ # nibjs - Package and embed node.js/coffeescript application in your browser
5
+ #
6
+ # SYNOPSIS
7
+ # #{program_name} [--help] [--version] [FOLDER]
8
+ #
9
+ # OPTIONS
10
+ # #{summarized_options}
11
+ #
12
+ # DESCRIPTION
13
+ # This command packages a complete javascript/coffeescript as a single .js file
14
+ # to be embedded in the browser. Basically, it defines Node.js's exports and
15
+ # require to work nicely. For this, we expect a project structure that respect
16
+ # Node.js's package conventions (exports, require, index):
17
+ #
18
+ # mylib/
19
+ # dist/
20
+ # src/
21
+ # foo.[js,coffee] # exports.Foo = ...
22
+ # bar.[js,coffee] # require('./foo')
23
+ # index.[js,coffee] # exports.X = ...
24
+ # spec/
25
+ # foo_spec.[js,coffee]
26
+ # bar_spec.[js,coffee]
27
+ #
28
+ # EXAMPLE 1 (embedded javascript):
29
+ #
30
+ # In a shell:
31
+ #
32
+ # # if the sources are .js
33
+ # nibjs --libname=mylib --output=mylib.js src
34
+ #
35
+ # # if the sources are .coffee
36
+ # nibjs --coffee --libname=mylib --output=mylib.js src
37
+ #
38
+ # In the browser:
39
+ #
40
+ # <script src="js/coffee-script.js" type="text/javascript">
41
+ # <script src="js/nibjs.js" type="text/javascript">
42
+ # <script src="js/mylib.js" type="text/javascript">
43
+ # <script>
44
+ # var mylib = NibJS.require('mylib')
45
+ # </script>
46
+ #
47
+ # EXAMPLE 2 (embedded coffeescript):
48
+ #
49
+ # In a shell:
50
+ #
51
+ # nibjs --coffee --no-coffee-compile --libname=mylib --output=mylib.coffee src
52
+ #
53
+ # In the browser:
54
+ #
55
+ # <script src="js/nibjs.js" type="text/javascript">
56
+ # <script src="js/mylib.coffee" type="text/coffeescript">
57
+ # <script>
58
+ # /* But be warned of coffeescript's issue 1054
59
+ # https://github.com/jashkenas/coffee-script/issues/#issue/1054 */
60
+ # var mylib = NibJS.require('mylib')
61
+ # </script>
62
+ #
63
+ class Main < Quickl::Command(__FILE__, __LINE__)
64
+
65
+ # Name of the library which is packaged
66
+ attr_accessor :libname
67
+
68
+ # Look for .coffee files
69
+ attr_accessor :coffee
70
+
71
+ # Compile .coffee files
72
+ attr_accessor :coffee_compile
73
+
74
+ # Join the sources instead of treating them separately
75
+ attr_accessor :join
76
+
77
+ # Invoke ugligyjs on result
78
+ attr_accessor :uglify
79
+
80
+ # Add 'libname = NibJS.require(libname)' at end of script
81
+ attr_accessor :autorequire
82
+
83
+ # Path to a licencing file to add as header
84
+ attr_accessor :header
85
+
86
+ # IO or filename where to output result
87
+ attr_accessor :output
88
+
89
+ def initialize
90
+ @output = STDOUT
91
+ end
92
+
93
+ # Install options
94
+ options do |opt|
95
+ @libname = nil
96
+ opt.on("--libname=X", "Specify the main library name") do |value|
97
+ @libname = value
98
+ end
99
+ @autorequire = false
100
+ opt.on('-a','--autorequire', "Add 'libname = NibJS.require(libname)' at end of script") do
101
+ @autorequire = true
102
+ end
103
+ @coffee = false
104
+ opt.on("-c", "--coffee", "Look for .coffee instead of .js files (requires coffee)") do
105
+ @coffee = true
106
+ end
107
+ @coffee_compile = true
108
+ opt.on("--[no-]coffee-compile", "Compile .coffee sources to javascript (requires coffee)") do |value|
109
+ @coffee_compile = value
110
+ end
111
+ @join = false
112
+ opt.on('-j', '--join', "Join the sources instead of treating them separately") do |value|
113
+ @join = true
114
+ end
115
+ @uglify = false
116
+ opt.on('-u', '--[no-]uglify', "Invoke ugligyjs on result (requires uglifyjs)") do |value|
117
+ @uglify = value
118
+ end
119
+ opt.separator('')
120
+ @header = nil
121
+ opt.on("--header=FILE", "Add a (licencing) header from a file") do |value|
122
+ @header = value
123
+ end
124
+ #@output = STDOUT
125
+ opt.on("-o", "--output=FILE", "Output in a specific file") do |value|
126
+ @output = value
127
+ end
128
+ opt.on_tail("--help", "Show help") do
129
+ raise Quickl::Help
130
+ end
131
+ opt.on_tail("--version", "Show version") do
132
+ raise Quickl::Exit, "#{program_name} #{NibJS::VERSION} (c) 2011, Bernard Lambeau"
133
+ end
134
+ end
135
+
136
+ ### In coffee
137
+
138
+ def with_coffee_registration(file)
139
+ code = ""
140
+ code += "nibjs.register '#{file}', (exports, require)->\n"
141
+ code += yield.strip.gsub(/^/m, ' ') + "\n"
142
+ code += "\n"
143
+ end
144
+
145
+ def with_coffee_define(package)
146
+ code = ""
147
+ code += "NibJS.define '#{package}', (nibjs)->\n"
148
+ code += yield.strip.gsub(/^/m, ' ') + "\n"
149
+ code += "\n"
150
+ code += " nibjs.require './index'\n"
151
+ end
152
+
153
+ ### In javascript
154
+
155
+ def with_js_registration(file)
156
+ code = ""
157
+ code += "nibjs.register('#{file}', function(exports, require) {\n"
158
+ code += yield.strip.gsub(/^/m, ' ') + "\n"
159
+ code += "});\n"
160
+ end
161
+
162
+ def with_js_define(package)
163
+ code = ""
164
+ code += "NibJS.define('#{package}', function(nibjs) {\n"
165
+ code += yield.strip.gsub(/^/m, ' ') + "\n"
166
+ code += " return nibjs.require('./index');\n"
167
+ code += "});\n"
168
+ end
169
+
170
+ ###
171
+
172
+ # Runs a command, returns result on STDOUT. If the exit status was no 0,
173
+ # a RuntimeError is raised.
174
+ def safe_run(cmd)
175
+ res = `#{cmd}`
176
+ unless $?.exitstatus == 0
177
+ raise RuntimeError, "Error while executing #{cmd}"
178
+ end
179
+ res
180
+ end
181
+
182
+ def with_temp_file(content)
183
+ require "tempfile"
184
+ file = Tempfile.new('nibjs')
185
+ file << content
186
+ file.close
187
+ res = yield(file)
188
+ file.unlink
189
+ res
190
+ end
191
+
192
+ ###
193
+
194
+ def file2require(root_folder, file)
195
+ root_folder, file = File.expand_path(root_folder), File.expand_path(file)
196
+ stripped = file[(1+root_folder.size)..-1]
197
+ stripped =~ /(.*)\.(js|coffee)$/
198
+ "./#{$1}"
199
+ end
200
+
201
+ ###
202
+
203
+ def collect_on_files(folder)
204
+ files = if coffee
205
+ Dir["#{folder}/**/*.coffee"]
206
+ else
207
+ Dir["#{folder}/**/*.js"]
208
+ end
209
+ if join
210
+ files.sort!
211
+ content = files.collect{|f| File.read(f)}.join("\n")
212
+ [ with_temp_file(content){|f| yield(f.path, './index')} ]
213
+ else
214
+ files.collect{|f| yield(f, file2require(folder, f))}
215
+ end
216
+ end
217
+
218
+ def compile_coffee_source(code)
219
+ with_temp_file(code){|f|
220
+ safe_run("cat #{f.path} | coffee --compile --stdio --bare")
221
+ }
222
+ end
223
+
224
+ def compile(folder)
225
+ folder = File.expand_path(folder)
226
+ self.libname ||= File.basename(folder)
227
+ if self.libname =~ /(.*)\.\w/
228
+ self.libname = $1
229
+ end
230
+
231
+ code = if coffee
232
+ code = with_coffee_define(libname){
233
+ collect_on_files(folder){|filepath, reqname|
234
+ with_coffee_registration(reqname){ File.read(filepath) }
235
+ }.join
236
+ }
237
+ if coffee_compile
238
+ compile_coffee_source(code)
239
+ else
240
+ code
241
+ end
242
+ else
243
+ with_js_define(libname){
244
+ collect_on_files(folder){|filepath, reqname|
245
+ with_js_registration(reqname){ File.read(filepath) }
246
+ }.join
247
+ }
248
+ end
249
+
250
+ # Add the autorequire line if requested
251
+ if autorequire
252
+ if (!coffee || coffee_compile)
253
+ code += "var #{libname} = NibJS.require('#{libname}');\n"
254
+ else
255
+ code += "#{libname} = NibJS.require '#{libname}'\n"
256
+ end
257
+ end
258
+
259
+ if header
260
+ code = File.read(header) + "\n" + code
261
+ end
262
+
263
+ # Uglify result now
264
+ if uglify
265
+ code = with_temp_file(code){|f| safe_run("uglifyjs #{f.path}") }
266
+ end
267
+
268
+ code
269
+ end
270
+
271
+ def with_output
272
+ if String === output
273
+ File.open(output, 'w'){|io| yield(io) }
274
+ else
275
+ yield(output)
276
+ end
277
+ end
278
+
279
+ def execute(args)
280
+ if args.size == 1
281
+ with_output{|io| io << compile(args[0]) }
282
+ else
283
+ raise Quickl::Help
284
+ end
285
+ end
286
+
287
+ end # class Main
288
+ end # module NibJS
@@ -0,0 +1,14 @@
1
+ module NibJS
2
+ module Version
3
+
4
+ MAJOR = 1
5
+ MINOR = 0
6
+ TINY = 0
7
+
8
+ def self.to_s
9
+ [ MAJOR, MINOR, TINY ].join('.')
10
+ end
11
+
12
+ end
13
+ VERSION = Version.to_s
14
+ end
data/lib/nibjs.rb ADDED
@@ -0,0 +1,9 @@
1
+ #
2
+ # nib.js - Package and embed node.js or coffeescript libraries in the browser
3
+ #
4
+ module NibJS
5
+
6
+ end # module NibJS
7
+ require "nibjs/version"
8
+ require "nibjs/loader"
9
+ require "nibjs/main"