stitch-rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in stitch.gemspec
4
+ gemspec
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.
@@ -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
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
Binary file
@@ -0,0 +1 @@
1
+ someCoffeeScript = true
@@ -0,0 +1,5 @@
1
+ $: << File.join(File.dirname(__FILE__), *%w[.. lib])
2
+
3
+ require "stitch"
4
+
5
+ puts Stitch::Package.new(:paths => ["app"], :dependencies => ["lib/jquery.js"]).compile
@@ -0,0 +1 @@
1
+ // A dependency
@@ -0,0 +1,9 @@
1
+ require "json"
2
+ require "stitch/version"
3
+
4
+ module Stitch
5
+ autoload :Compiler, "stitch/compiler"
6
+ autoload :Package, "stitch/package"
7
+ autoload :Source, "stitch/source"
8
+ autoload :Server, "stitch/server"
9
+ end
@@ -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,9 @@
1
+ module Stitch
2
+ class JavaScriptCompiler < Compiler
3
+ extensions :js
4
+
5
+ def compile(filename)
6
+ File.read(filename)
7
+ end
8
+ end
9
+ 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,11 @@
1
+ module Stitch
2
+ class Server
3
+ def initialize(options = {})
4
+ @package = Package.new(options)
5
+ end
6
+
7
+ def call(env)
8
+ [200, {"Content-Type" => "text/javascript"}, [@package.compile]]
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,3 @@
1
+ module Stitch
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
+