stitch-rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/examples/.DS_Store +0 -0
- data/examples/app/controllers/controller.coffee +1 -0
- data/examples/compile.rb +5 -0
- data/examples/lib/jquery.js +1 -0
- data/lib/stitch.rb +9 -0
- data/lib/stitch/compiler.rb +47 -0
- data/lib/stitch/compilers/coffeescript.rb +16 -0
- data/lib/stitch/compilers/javascript.rb +9 -0
- data/lib/stitch/package.rb +93 -0
- data/lib/stitch/server.rb +11 -0
- data/lib/stitch/source.rb +52 -0
- data/lib/stitch/version.rb +3 -0
- data/stitch.gemspec +18 -0
- metadata +74 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Alex MacCaw (info@eribium.org)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Stitch
|
2
|
+
|
3
|
+
This is a port of Sam Stephenson's [Stich](https://github.com/sstephenson/stitch) to Ruby. Stitch allows you to:
|
4
|
+
|
5
|
+
> Develop and test your JavaScript applications as CommonJS modules in Node.js. Then __Stitch__ them together to run in the browser.
|
6
|
+
|
7
|
+
In other words, this is a [CommonJS](http://dailyjs.com/2010/10/18/modules/) JavaScript package management solution. It's terribly simple, bundling up all your applications JavaScript files without intelligently resolving dependencies. However, unless your application is very modular, it turns out thats all you need.
|
8
|
+
|
9
|
+
##Usage
|
10
|
+
|
11
|
+
Install the gem, or add it to your Gemfile:
|
12
|
+
|
13
|
+
gem 'stitch-rb'
|
14
|
+
|
15
|
+
You can compile your application like this:
|
16
|
+
|
17
|
+
Stitch::Package.new(:paths => ["app"], :dependencies => ["lib/jquery.js"]).compile
|
18
|
+
|
19
|
+
It returns a JavaScript file that you can serve to your users, or write to disk and cache.
|
20
|
+
|
21
|
+
You should give `Stitch::Package` an array of `:paths`, the relative directories your JavaScript application is served from. You can also specify an array of `:dependencies`, JavaScript files which will be concatenated without being wrapped in CommonJS modules.
|
22
|
+
|
23
|
+
##Rails & Rack
|
24
|
+
|
25
|
+
Stitch includes a basic Rack server, for example this is how you'd use it with Rails 3 routes:
|
26
|
+
|
27
|
+
match '/application.js' => Stitch::Server.new(:paths => ["app/assets/javascripts"])
|
28
|
+
|
29
|
+
##Adding compilers
|
30
|
+
|
31
|
+
Compilers need to inherit from `Stitch::Compiler`. They're very simple, for example:
|
32
|
+
|
33
|
+
class jQueryTmplCompiler < Stitch::Compiler
|
34
|
+
# List of supported extensions
|
35
|
+
extensions :tmpl
|
36
|
+
|
37
|
+
# A compile method which takes a file path,
|
38
|
+
# and returns a compiled string
|
39
|
+
def compile(path)
|
40
|
+
content = File.read(path)
|
41
|
+
%{
|
42
|
+
var template = jQuery.template(#{content.to_json});
|
43
|
+
module.exports = (function(data){ return jQuery.tmpl(template, data); });
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/examples/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
someCoffeeScript = true
|
data/examples/compile.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
// A dependency
|
data/lib/stitch.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Stitch
|
2
|
+
class Compiler
|
3
|
+
class << self
|
4
|
+
def compilers
|
5
|
+
@compilers ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
def inherited(child)
|
9
|
+
Compiler.compilers.unshift(child)
|
10
|
+
end
|
11
|
+
|
12
|
+
def for_extension(extension)
|
13
|
+
extension.gsub!(/^\./, "")
|
14
|
+
Compiler.compilers.select(&:enabled?).find do |item|
|
15
|
+
item.extensions.include?(extension)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Child methods
|
20
|
+
|
21
|
+
def extensions(*exts)
|
22
|
+
@extensions ||= []
|
23
|
+
@extensions |= exts.map(&:to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
def enabled(value)
|
27
|
+
@enabled = value
|
28
|
+
end
|
29
|
+
|
30
|
+
def enabled?
|
31
|
+
@enabled != false
|
32
|
+
end
|
33
|
+
|
34
|
+
def compile(*args)
|
35
|
+
self.new.compile(*args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def compile(filename)
|
40
|
+
raise "Re-implement"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Require default compilers
|
46
|
+
require "stitch/compilers/javascript"
|
47
|
+
require "stitch/compilers/coffeescript"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Stitch
|
2
|
+
class CoffeeScriptCompiler < Compiler
|
3
|
+
extensions :cs, :coffee
|
4
|
+
|
5
|
+
enabled begin
|
6
|
+
require "coffee-script"
|
7
|
+
rescue LoadError
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def compile(filename)
|
12
|
+
source = File.read(filename)
|
13
|
+
CoffeeScript.compile(source)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Stitch
|
2
|
+
class Package
|
3
|
+
DEFAULTS = {
|
4
|
+
:identifier => "require",
|
5
|
+
:paths => ["lib"],
|
6
|
+
:dependencies => []
|
7
|
+
}
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
options = DEFAULTS.merge(options)
|
11
|
+
|
12
|
+
@identifier = options[:identifier]
|
13
|
+
@paths = options[:paths]
|
14
|
+
@dependencies = options[:dependencies]
|
15
|
+
end
|
16
|
+
|
17
|
+
def compile
|
18
|
+
[compile_dependencies, compile_sources].join("\n")
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def compile_dependencies
|
23
|
+
@dependencies.map {|path| File.read(path) }.join("\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
def compile_sources
|
27
|
+
sources = @paths.map {|path|
|
28
|
+
Source.from_path(path)
|
29
|
+
}.flatten
|
30
|
+
|
31
|
+
result = <<-EOF
|
32
|
+
(function(/*! Stitch !*/) {
|
33
|
+
if (!this.#{@identifier}) {
|
34
|
+
var modules = {}, cache = {}, require = function(name, root) {
|
35
|
+
var module = cache[name], path = expand(root, name), fn;
|
36
|
+
if (module) {
|
37
|
+
return module;
|
38
|
+
} else if (fn = modules[path] || modules[path = expand(path, './index')]) {
|
39
|
+
module = {id: name, exports: {}};
|
40
|
+
try {
|
41
|
+
cache[name] = module.exports;
|
42
|
+
fn(module.exports, function(name) {
|
43
|
+
return require(name, dirname(path));
|
44
|
+
}, module);
|
45
|
+
return cache[name] = module.exports;
|
46
|
+
} catch (err) {
|
47
|
+
delete cache[name];
|
48
|
+
throw err;
|
49
|
+
}
|
50
|
+
} else {
|
51
|
+
throw 'module \\'' + name + '\\' not found';
|
52
|
+
}
|
53
|
+
}, expand = function(root, name) {
|
54
|
+
var results = [], parts, part;
|
55
|
+
if (/^\\.\\.?(\\/|$)/.test(name)) {
|
56
|
+
parts = [root, name].join('/').split('/');
|
57
|
+
} else {
|
58
|
+
parts = name.split('/');
|
59
|
+
}
|
60
|
+
for (var i = 0, length = parts.length; i < length; i++) {
|
61
|
+
part = parts[i];
|
62
|
+
if (part == '..') {
|
63
|
+
results.pop();
|
64
|
+
} else if (part != '.' && part != '') {
|
65
|
+
results.push(part);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
return results.join('/');
|
69
|
+
}, dirname = function(path) {
|
70
|
+
return path.split('/').slice(0, -1).join('/');
|
71
|
+
};
|
72
|
+
this.#{@identifier} = function(name) {
|
73
|
+
return require(name, '');
|
74
|
+
}
|
75
|
+
this.#{@identifier}.define = function(bundle) {
|
76
|
+
for (var key in bundle)
|
77
|
+
modules[key] = bundle[key];
|
78
|
+
};
|
79
|
+
}
|
80
|
+
return this.#{@identifier}.define;
|
81
|
+
}).call(this)({
|
82
|
+
EOF
|
83
|
+
|
84
|
+
sources.each_with_index do |source, i|
|
85
|
+
result += i == 0 ? "" : ", "
|
86
|
+
result += source.name.to_json
|
87
|
+
result += ": function(exports, require, module) {#{source.compile}}"
|
88
|
+
end
|
89
|
+
|
90
|
+
result += "});\n"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module Stitch
|
4
|
+
class Source
|
5
|
+
class << self
|
6
|
+
def from_path(root, path = nil, result = [])
|
7
|
+
path ||= root
|
8
|
+
path = Pathname.new(path)
|
9
|
+
|
10
|
+
if path.directory?
|
11
|
+
path.children.each do |child|
|
12
|
+
from_path(root, child, result)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
source = self.new(root, path)
|
16
|
+
result << source if source.valid?
|
17
|
+
end
|
18
|
+
result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :root, :path
|
23
|
+
|
24
|
+
def initialize(root, path)
|
25
|
+
@root = Pathname.new(root)
|
26
|
+
@path = Pathname.new(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
name = path.relative_path_from(root)
|
31
|
+
name = name.dirname + name.basename(".*")
|
32
|
+
name.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def ext
|
36
|
+
path.extname
|
37
|
+
end
|
38
|
+
|
39
|
+
def compile
|
40
|
+
compiler.compile(path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid?
|
44
|
+
!!compiler
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
def compiler
|
49
|
+
Compiler.for_extension(ext)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/stitch.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "stitch/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "stitch-rb"
|
7
|
+
s.version = Stitch::VERSION
|
8
|
+
s.authors = ["Alex MacCaw"]
|
9
|
+
s.email = ["maccman@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Stitch ported to Ruby}
|
12
|
+
s.description = %q{A JavaScript package manager}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stitch-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alex MacCaw
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-06-29 00:00:00 -06:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: A JavaScript package manager
|
18
|
+
email:
|
19
|
+
- maccman@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- Gemfile
|
29
|
+
- LICENSE
|
30
|
+
- README.md
|
31
|
+
- Rakefile
|
32
|
+
- examples/.DS_Store
|
33
|
+
- examples/app/controllers/controller.coffee
|
34
|
+
- examples/compile.rb
|
35
|
+
- examples/lib/jquery.js
|
36
|
+
- lib/stitch.rb
|
37
|
+
- lib/stitch/compiler.rb
|
38
|
+
- lib/stitch/compilers/coffeescript.rb
|
39
|
+
- lib/stitch/compilers/javascript.rb
|
40
|
+
- lib/stitch/package.rb
|
41
|
+
- lib/stitch/server.rb
|
42
|
+
- lib/stitch/source.rb
|
43
|
+
- lib/stitch/version.rb
|
44
|
+
- stitch.gemspec
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: ""
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.6.0
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Stitch ported to Ruby
|
73
|
+
test_files: []
|
74
|
+
|