spade 0.0.6 → 0.0.7

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.
@@ -24,7 +24,7 @@ require 'thor'
24
24
  require 'v8'
25
25
 
26
26
  module Spade
27
- SPADE_DIR = '.spade'
27
+ SPADE_DIR = '.spade' # Would be nice to share this with node.js loader
28
28
 
29
29
  # find the current path with a package.json or .packages or cur_path
30
30
  def self.discover_root(cur_path)
@@ -6,7 +6,6 @@
6
6
 
7
7
  module Spade
8
8
  BOOT_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'));
9
- BUILTIN_PACKAGES = File.join File.dirname(BOOT_PATH), 'packages'
10
9
 
11
10
  module Bundle
12
11
  class << self
@@ -24,48 +23,44 @@ module Spade
24
23
 
25
24
  installed = []
26
25
 
26
+ # Do this to get the Gem.dir right
27
+ env = Spade::Environment.new
27
28
 
28
- #TODO: Clean up duplication here
29
+ # In reverse order of precedence
30
+ package_dirs = [File.join(env.spade_dir, 'gems')]
31
+ package_dirs += %w[vendor/cache vendor/packages packages].map{|p| File.join(rootdir, p.split('/')) }
29
32
 
30
- Dir.glob(File.join(BUILTIN_PACKAGES, '*')).each do |path|
31
- next unless File.exists? File.join(path, 'package.json')
33
+ for package_dir in package_dirs
34
+ Dir.glob(File.join(package_dir, '*')).each do |path|
35
+ json_file = File.join(path, 'package.json')
36
+ next unless File.exists?(json_file)
32
37
 
33
- next if installed.include? path
34
- installed << path
38
+ # How would this happen?
39
+ next if installed.include? path
40
+ installed << path
35
41
 
36
- new_path = File.join(spade_path, 'packages', File.basename(path))
37
- FileUtils.ln_s path, new_path, :force => true
38
- puts "Installing built-in package #{File.basename(path)}" if verbose
39
- end
42
+ json = JSON.load File.read(json_file)
43
+ package_name = json['name']
44
+ package_version = json['version']
40
45
 
41
- # Do this to get the Gem.dir right
42
- env = Spade::Environment.new
43
- Dir.glob(File.join(env.spade_dir, 'gems', '*')).each do |path|
44
- package_def = File.join(path, 'package.json')
45
- next unless File.exists?(package_def)
46
-
47
- next if installed.include? path
48
- installed << path
49
-
50
- json = JSON.load File.read(package_def)
51
- package_name = json['name']
52
- new_path = File.join(spade_path, 'packages', package_name)
53
- FileUtils.ln_s path, new_path, :force => true
54
- puts "Installing system package #{File.basename(path)}" if verbose
55
- end
46
+ local = path.index(rootdir) == 0
56
47
 
48
+ # Use relative paths if embedded
49
+ old_path = if local
50
+ # Figure out how many levels deep the spade_path is in the project
51
+ levels = spade_path.sub(rootdir, '').split(File::SEPARATOR).reject{|p| p.empty? }.count
52
+ # Build relative path
53
+ File.join(['..'] * levels, path.sub(rootdir, ''))
54
+ else
55
+ path
56
+ end
57
57
 
58
- Dir.glob(File.join(rootdir, 'packages', '*')).each do |path|
59
- next unless File.exists? File.join(path, 'package.json')
58
+ new_path = File.join(spade_path, 'packages', package_name)
60
59
 
61
- next if installed.include? path
62
- installed << path
60
+ FileUtils.ln_s old_path, new_path, :force => true
63
61
 
64
- package_name = File.basename(path)
65
- old_path = File.join('..','..','packages', package_name)
66
- new_path = File.join(spade_path, 'packages', File.basename(path))
67
- FileUtils.ln_s old_path, new_path, :force => true
68
- puts "Installing local package #{File.basename(path)}" if verbose
62
+ puts "Installing #{local ? "local" : "remote"} package #{package_name}" if verbose
63
+ end
69
64
  end
70
65
 
71
66
  File.open(File.join(rootdir, 'spade-boot.js'), 'w+') do |fp|
@@ -8,6 +8,7 @@ module Spade
8
8
  module CLI
9
9
  require 'spade/cli/owner'
10
10
  require 'spade/cli/base'
11
+ require 'spade/cli/project_generator'
11
12
 
12
13
  LOGIN_MESSAGE = "Please login first with `spade login`."
13
14
  end
@@ -1,5 +1,8 @@
1
1
  module Spade::CLI
2
2
  class Base < Thor
3
+ include Thor::Actions
4
+
5
+ source_root File.expand_path('../../templates', __FILE__)
3
6
 
4
7
  desc "owner", "Manage users for a package"
5
8
  subcommand "owner", Owner
@@ -228,6 +231,12 @@ module Spade::CLI
228
231
  print_specs(packages, index)
229
232
  end
230
233
 
234
+ desc "new [NAME]", "Generate a new project skeleton"
235
+ def new(name)
236
+ ProjectGenerator.new(self,
237
+ name, File.expand_path(name)).run
238
+ end
239
+
231
240
  desc "build", "Build a spade package from a package.json"
232
241
  def build
233
242
  local = Spade::Local.new
@@ -0,0 +1,58 @@
1
+ module Spade::CLI
2
+ class ProjectGenerator
3
+ include Thor::Actions
4
+
5
+ source_root File.expand_path('../../templates/project', __FILE__)
6
+
7
+ attr_reader :name
8
+
9
+ def initialize(thor, name, root)
10
+ @thor, @name, @root = thor, name, root
11
+
12
+ self.destination_root = root
13
+ end
14
+
15
+ def run
16
+ empty_directory '.'
17
+ FileUtils.cd(destination_root)
18
+
19
+ template "LICENSE"
20
+ template "README.md"
21
+ template "project.json"
22
+
23
+ empty_directory "lib"
24
+ empty_directory "tests"
25
+
26
+ inside "lib" do
27
+ template "main.js"
28
+ end
29
+
30
+ inside "tests" do
31
+ template "main-test.js"
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def app_const
38
+ name.gsub(/\W|-/, '_').squeeze('_').gsub(/(?:^|_)(.)/) { $1.upcase }
39
+ end
40
+
41
+ def current_year
42
+ Time.now.year
43
+ end
44
+
45
+ def source_paths
46
+ [File.expand_path('../../templates/project', __FILE__)] +
47
+ @thor.source_paths
48
+ end
49
+
50
+ def respond_to?(*args)
51
+ super || @thor.respond_to?(*args)
52
+ end
53
+
54
+ def method_missing(name, *args, &blk)
55
+ @thor.send(name, *args, &blk)
56
+ end
57
+ end
58
+ end
@@ -10,7 +10,7 @@ require 'spade/compiler'
10
10
  require 'spade/console'
11
11
  require 'spade/reactor'
12
12
 
13
- TIKIJS_PATH = File.expand_path File.join(File.dirname(__FILE__), '..', 'spade.js')
13
+ SPADEJS_PATH = File.expand_path File.join(File.dirname(__FILE__), '..', 'spade.js')
14
14
 
15
15
  module Spade
16
16
 
@@ -86,7 +86,7 @@ module Spade
86
86
  ctx['ARGV'] = opts[:argv] || ARGV
87
87
 
88
88
  # Load spade and patch in compiler and loader plugins
89
- ctx.load(TIKIJS_PATH)
89
+ ctx.load(SPADEJS_PATH)
90
90
  ctx['rubyLoader'] = Loader.new(self)
91
91
  ctx['rubyCompiler'] = Compiler.new(self)
92
92
 
@@ -178,11 +178,6 @@ module Spade
178
178
  @packages unless @packages.nil?
179
179
  @packages = {}
180
180
 
181
- # add global packages in spade project
182
- # globals = File.expand_path(File.join(__FILE__, '..', '..', '..', 'packages'))
183
- # package_paths = Dir.glob File.join(globals,'*')
184
- # package_paths.each { |path| add_package(path) }
185
-
186
181
  # Do this to get the Gem.dir right
187
182
  env = Spade::Environment.new
188
183
 
@@ -1,17 +1,10 @@
1
1
  module Spade
2
2
  class Local < Repository
3
3
  def uninstall(package)
4
- index = Gem::SourceIndex.from_gems_in(env.spade_dir("specifications"))
5
- index.refresh!
6
- specs = index.find_name package
7
-
8
- if specs.first
9
- uninstaller = Gem::Uninstaller.new(package, :ignore => true)
10
- uninstaller.uninstall_gem(specs.first, specs)
11
- true
12
- else
13
- false
14
- end
4
+ Gem::Uninstaller.new(package).uninstall
5
+ true
6
+ rescue Gem::InstallError
7
+ false
15
8
  end
16
9
 
17
10
  def pack(path)
@@ -57,6 +57,7 @@ module Spade
57
57
  [500, {}, error]
58
58
  end
59
59
  else
60
+ env['PATH_INFO'] == '/index.html' if env['PATH_INFO'] == '/'
60
61
  @app.call(env)
61
62
  end
62
63
  end
@@ -0,0 +1,19 @@
1
+ Copyright (c) <%= current_year %> YOUR NAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,21 @@
1
+ # <%= name %>
2
+
3
+ ### Description:
4
+
5
+ FIX (describe your package)
6
+
7
+ ### Features / Problems:
8
+
9
+ * FIX (list of features or problems)
10
+
11
+ ### Synopsis:
12
+
13
+ FIX (code sample of usage)
14
+
15
+ ### Requirements:
16
+
17
+ * FIX (list of requirements)
18
+
19
+ ### Install:
20
+
21
+ * FIX (describe how to install)
@@ -0,0 +1,9 @@
1
+ <%= app_const %> = {
2
+
3
+ // TODO: Write amazing code...
4
+ replaceMe: function() {
5
+ return "OMG you're so awesome!!!";
6
+ }
7
+ }
8
+
9
+ return <%= app_const %>;
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "<%= name %>",
3
+ "description": "DESCRIPTION HERE",
4
+ "summary": "SUMMARY HERE",
5
+ "keywords": ["javascript"],
6
+ "author": "YOUR NAME HERE",
7
+ "homepage": "URL",
8
+ "version": "0.0.1",
9
+ "licenses": [{
10
+ "type": "MIT",
11
+ "url": "http://www.opensource.org/licenses/mit-license.php"
12
+ }],
13
+
14
+ "engines": ["browser", "all"],
15
+
16
+ "directories": {
17
+ "lib": "./lib",
18
+ "test": "./tests"
19
+ },
20
+
21
+ "main": "./lib/main",
22
+
23
+ "bin": {
24
+ "cot": "./bin/cot"
25
+ },
26
+
27
+ "dependencies": {
28
+ "ivory": "= 0.0.1",
29
+ "optparse": "= 1.0.1"
30
+ }
31
+ }
@@ -0,0 +1,8 @@
1
+ Ct.module('<%= app_const %> tests');
2
+
3
+ // TODO: Write real tests
4
+ Ct.test('truth', function(t){
5
+ t.ok(true, 'should be true');
6
+ });
7
+
8
+ Ct.run();
@@ -1,3 +1,3 @@
1
1
  module Spade
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spade",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "CommonJS Microkernel for Browser and Command Line",
5
5
 
6
6
  "maintainers": [
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe "spade new" do
4
+ it "should be speced"
5
+ end
@@ -9,37 +9,37 @@ var Ct = require('core-test/sync'),
9
9
 
10
10
  // ..........................................................
11
11
  // BASIC REQUIRE
12
- //
12
+ //
13
13
 
14
14
  Ct.module('spade: basic require');
15
15
 
16
16
  Ct.setup(function(t) {
17
- t.spade = new Spade();
17
+ t.spade = new Spade();
18
18
  });
19
19
 
20
- Ct.teardown(function(t) {
20
+ Ct.teardown(function(t) {
21
21
  delete t.spade;
22
22
  });
23
23
 
24
24
 
25
25
  Ct.test('register then require a module', function(t) {
26
26
  var spade = t.spade;
27
-
28
- spade.register('foo/bar', function(require, exports) {
27
+
28
+ spade.register('foo/bar', function(require, exports) {
29
29
  exports.foo = 'bar';
30
30
  });
31
-
31
+
32
32
  var exp = spade.require('foo/bar');
33
- t.equal(exp.foo, 'bar', 'exports.foo == bar - means require succeeded');
33
+ t.equal(exp.foo, 'bar', 'exports.foo == bar - means require succeeded');
34
34
  });
35
35
 
36
36
  Ct.test('register a string factory then require', function(t) {
37
37
  var spade = t.spade;
38
-
38
+
39
39
  spade.register('foo/bar', "exports.foo = 'bar';");
40
-
40
+
41
41
  var exp = spade.require('foo/bar');
42
- t.equal(exp.foo, 'bar', 'exports.foo == bar - means require succeeded');
42
+ t.equal(exp.foo, 'bar', 'exports.foo == bar - means require succeeded');
43
43
  });
44
44
 
45
45
  Ct.test('require a non-existant module will throw an exception', function(t) {
@@ -56,3 +56,62 @@ Ct.test('require a module that was just registered symbolically. This is for co
56
56
  });
57
57
 
58
58
  Ct.test('require system installed packages');
59
+
60
+
61
+ // ..........................................................
62
+ // BASIC REQUIRE
63
+ //
64
+
65
+ Ct.module('spade: extension require');
66
+
67
+ Ct.setup(function(t) {
68
+ t.spade = new Spade();
69
+
70
+ t.spade.register('foo', {
71
+ 'plugin:formats': {
72
+ 'css': 'foo/format',
73
+ 'txt': 'foo/format'
74
+ }
75
+ });
76
+ t.spade.register('foo/format', "exports.compileFormat = function(code){ return code; };");
77
+ t.spade.register('foo/bar', "exports.foo = 'bar.js';", { format: 'js' });
78
+ t.spade.register('foo/bar', "exports.foo = 'bar.css';", { format: 'css' });
79
+ });
80
+
81
+ Ct.teardown(function(t) {
82
+ delete t.spade;
83
+ });
84
+
85
+
86
+ Ct.test('valid extension', function(t) {
87
+ var exp = t.spade.require('foo/bar.js');
88
+ t.equal(exp.foo, 'bar.js', 'exports.foo == bar.js - means require succeeded');
89
+ });
90
+
91
+ Ct.test('same name different extensions', function(t){
92
+ var spade = t.spade,
93
+ jsExp = spade.require('foo/bar.js'),
94
+ cssExp = spade.require('foo/bar.css');
95
+
96
+ t.equal(jsExp.foo, 'bar.js', 'exports.foo == bar.js - means require succeeded');
97
+ t.equal(cssExp.foo, 'bar.css', 'exports.foo == bar.css - means require succeeded');
98
+ });
99
+
100
+ Ct.test("don't load file for different extension", function(t){
101
+ t.throws(function(){ t.spade.require('foo/bar.txt'); }, Error, 'adfaff');
102
+ });
103
+
104
+ Ct.test("defaults to js", function(t){
105
+ var exp = t.spade.require('foo/bar');
106
+ t.equal(exp.foo, 'bar.js', 'exports.foo == bar.js - means required js as default');
107
+ });
108
+
109
+ Ct.test("defaults to first registered if no js", function(t){
110
+ var spade = t.spade;
111
+
112
+ spade.register('foo/baz', "exports.foo = 'baz.css';", { format: 'css' });
113
+ spade.register('foo/baz', "exports.foo = 'baz.txt';", { format: 'txt' });
114
+
115
+ var exp = spade.require('foo/baz');
116
+ t.equal(exp.foo, 'baz.css', 'exports.foo == baz.css - means required last registered');
117
+ });