jax 1.0.1 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/.gitmodules +3 -0
  2. data/.travis.yml +32 -0
  3. data/CHANGELOG +126 -0
  4. data/README.md +1 -1
  5. data/Rakefile +125 -19
  6. data/bin/jax +1 -1
  7. data/builtin/{shaders → app/shaders}/basic/common.ejs +0 -0
  8. data/builtin/{shaders → app/shaders}/basic/fragment.ejs +0 -0
  9. data/builtin/{shaders → app/shaders}/basic/vertex.ejs +0 -0
  10. data/builtin/{shaders → app/shaders}/depthmap/common.ejs +0 -0
  11. data/builtin/{shaders → app/shaders}/depthmap/fragment.ejs +0 -0
  12. data/builtin/{shaders → app/shaders}/depthmap/material.js +0 -0
  13. data/builtin/{shaders → app/shaders}/depthmap/vertex.ejs +0 -0
  14. data/builtin/{shaders → app/shaders}/fog/common.ejs +0 -0
  15. data/builtin/{shaders → app/shaders}/fog/fragment.ejs +0 -0
  16. data/builtin/{shaders → app/shaders}/fog/manifest.yml +0 -0
  17. data/builtin/{shaders → app/shaders}/fog/material.js +0 -0
  18. data/builtin/{shaders → app/shaders}/fog/vertex.ejs +0 -0
  19. data/builtin/{shaders → app/shaders}/functions/depth_map.ejs +0 -0
  20. data/builtin/{shaders → app/shaders}/functions/lights.ejs +0 -0
  21. data/builtin/{shaders → app/shaders}/functions/noise.ejs +0 -0
  22. data/builtin/{shaders → app/shaders}/lighting/common.ejs +0 -0
  23. data/builtin/{shaders → app/shaders}/lighting/fragment.ejs +0 -0
  24. data/builtin/{shaders → app/shaders}/lighting/manifest.yml +0 -0
  25. data/builtin/{shaders → app/shaders}/lighting/material.js +0 -0
  26. data/builtin/{shaders → app/shaders}/lighting/vertex.ejs +0 -0
  27. data/builtin/{shaders → app/shaders}/normal_map/common.ejs +0 -0
  28. data/builtin/{shaders → app/shaders}/normal_map/fragment.ejs +0 -0
  29. data/builtin/{shaders → app/shaders}/normal_map/manifest.yml +0 -0
  30. data/builtin/{shaders → app/shaders}/normal_map/material.js +0 -0
  31. data/builtin/{shaders → app/shaders}/normal_map/vertex.ejs +0 -0
  32. data/builtin/{shaders → app/shaders}/paraboloid/common.ejs +0 -0
  33. data/builtin/{shaders → app/shaders}/paraboloid/fragment.ejs +0 -0
  34. data/builtin/{shaders → app/shaders}/paraboloid/manifest.yml +0 -0
  35. data/builtin/{shaders → app/shaders}/paraboloid/material.js +0 -0
  36. data/builtin/{shaders → app/shaders}/paraboloid/vertex.ejs +0 -0
  37. data/builtin/{shaders → app/shaders}/picking/common.ejs +0 -0
  38. data/builtin/{shaders → app/shaders}/picking/fragment.ejs +0 -0
  39. data/builtin/{shaders → app/shaders}/picking/material.js +0 -0
  40. data/builtin/{shaders → app/shaders}/picking/vertex.ejs +0 -0
  41. data/builtin/{shaders → app/shaders}/shadow_map/common.ejs +0 -0
  42. data/builtin/{shaders → app/shaders}/shadow_map/fragment.ejs +0 -0
  43. data/builtin/{shaders → app/shaders}/shadow_map/manifest.yml +0 -0
  44. data/builtin/{shaders → app/shaders}/shadow_map/material.js +0 -0
  45. data/builtin/{shaders → app/shaders}/shadow_map/vertex.ejs +0 -0
  46. data/builtin/{shaders → app/shaders}/texture/common.ejs +0 -0
  47. data/builtin/{shaders → app/shaders}/texture/fragment.ejs +0 -0
  48. data/builtin/{shaders → app/shaders}/texture/manifest.yml +0 -0
  49. data/builtin/{shaders → app/shaders}/texture/material.js +0 -0
  50. data/builtin/{shaders → app/shaders}/texture/vertex.ejs +0 -0
  51. data/jax.gems +1 -1
  52. data/jax.gemspec +9 -7
  53. data/lib/jax.rb +23 -9
  54. data/lib/jax/application.rb +118 -60
  55. data/lib/jax/application/builtin.rb +12 -0
  56. data/lib/jax/application/builtin/configurable.rb +5 -0
  57. data/lib/jax/application/builtin/configuration.rb +5 -0
  58. data/lib/jax/application/configurable.rb +19 -0
  59. data/lib/jax/application/configuration.rb +46 -13
  60. data/lib/jax/application/railties.rb +26 -0
  61. data/lib/jax/core_ext/kernel.rb +7 -0
  62. data/lib/jax/engine.rb +64 -0
  63. data/lib/jax/engine/configurable.rb +19 -0
  64. data/lib/jax/engine/configuration.rb +49 -0
  65. data/lib/jax/generators/app.rb +3 -2
  66. data/lib/jax/generators/app/app_generator.rb +9 -2
  67. data/lib/jax/generators/app/templates/config/environment.rb.tt +5 -0
  68. data/lib/jax/generators/app/templates/public/index.html.tt +26 -0
  69. data/lib/jax/generators/app/templates/public/javascripts/jax.js +8726 -1
  70. data/lib/jax/generators/app/templates/public/stylesheets/%file_name%.css.tt +11 -0
  71. data/lib/jax/generators/app/templates/public/webgl_not_supported.html +1 -1
  72. data/lib/jax/generators/app/templates/spec/javascripts/support/jasmine.yml +1 -0
  73. data/lib/jax/generators/app/templates/spec/javascripts/support/spec_helpers/jax_spec_environment_helper.js +13 -5
  74. data/lib/jax/generators/app/templates/spec/javascripts/support/spec_helpers/jax_spec_helper.js +6 -10
  75. data/lib/jax/generators/commands.rb +168 -42
  76. data/lib/jax/generators/controller/controller_generator.rb +9 -2
  77. data/lib/jax/generators/interactions.rb +56 -0
  78. data/lib/jax/generators/light_source/light_source_generator.rb +1 -2
  79. data/lib/jax/generators/material/material_generator.rb +1 -2
  80. data/lib/jax/generators/model/model_generator.rb +1 -3
  81. data/lib/jax/generators/packager/package_generator.rb +32 -0
  82. data/lib/jax/generators/plugin/USAGE +4 -0
  83. data/lib/jax/generators/plugin/all.rb +113 -0
  84. data/lib/jax/generators/plugin/credentials.rb +108 -0
  85. data/lib/jax/generators/plugin/plugin_generator.rb +72 -0
  86. data/lib/jax/generators/plugin/plugin_manager.rb +254 -0
  87. data/lib/jax/generators/plugin/templates/new_plugin/app/controllers/.empty_directory +0 -0
  88. data/lib/jax/generators/plugin/templates/new_plugin/app/helpers/.empty_directory +0 -0
  89. data/lib/jax/generators/plugin/templates/new_plugin/app/models/.empty_directory +0 -0
  90. data/lib/jax/generators/plugin/templates/new_plugin/app/resources/.empty_directory +0 -0
  91. data/lib/jax/generators/plugin/templates/new_plugin/app/views/.empty_directory +0 -0
  92. data/lib/jax/generators/plugin/templates/new_plugin/config/routes.rb +3 -0
  93. data/lib/jax/generators/plugin/templates/new_plugin/init.rb +1 -0
  94. data/lib/jax/generators/plugin/templates/new_plugin/install.rb +2 -0
  95. data/lib/jax/generators/plugin/templates/new_plugin/public/.empty_directory +0 -0
  96. data/lib/jax/generators/plugin/templates/new_plugin/spec/.empty_directory +0 -0
  97. data/lib/jax/generators/plugin/templates/new_plugin/uninstall.rb +2 -0
  98. data/lib/jax/generators/script_jax_loader.rb +17 -0
  99. data/lib/jax/generators/shader/shader_generator.rb +2 -3
  100. data/lib/jax/monkeypatch/jasmine/config.rb +25 -1
  101. data/lib/jax/monkeypatch/jasmine/server.rb +1 -1
  102. data/lib/jax/packager.rb +12 -11
  103. data/lib/jax/packager/sprockets_template.rb +15 -6
  104. data/lib/jax/plugin.rb +49 -0
  105. data/lib/jax/plugin/manifest.rb +71 -0
  106. data/lib/jax/resource_compiler.rb +24 -14
  107. data/lib/jax/routes.rb +1 -0
  108. data/lib/jax/shader.rb +16 -1
  109. data/lib/jax/tasks/rake.rb +1 -1
  110. data/lib/jax/version.rb +3 -3
  111. data/spec/benchmark.htm +93 -0
  112. data/spec/fixtures/web/plugins/404.http +39 -0
  113. data/spec/fixtures/web/plugins/all.xml +106 -0
  114. data/spec/fixtures/web/plugins/author/create_account.xml.http +20 -0
  115. data/spec/fixtures/web/plugins/author/create_new_plugin.xml.http +27 -0
  116. data/spec/fixtures/web/plugins/author/login_existing_account.xml.http +19 -0
  117. data/spec/fixtures/web/plugins/author/login_not_found.xml.http +14 -0
  118. data/spec/fixtures/web/plugins/author/login_password_invalid.xml.http +12 -0
  119. data/spec/fixtures/web/plugins/clouds.xml +51 -0
  120. data/spec/fixtures/web/plugins/example.tgz.http +0 -0
  121. data/spec/fixtures/web/plugins/example.tgz.http.old +0 -0
  122. data/spec/fixtures/web/plugins/none.http +13 -0
  123. data/spec/fixtures/web/plugins/vert.xml +68 -0
  124. data/spec/fixtures/web/plugins/vertex-blob.xml +37 -0
  125. data/spec/fixtures/web/plugins/vertex-height-map.xml +44 -0
  126. data/spec/generators/app_generator_test.rb +42 -0
  127. data/spec/generators/controller_generator_test.rb +47 -0
  128. data/spec/generators/light_generator_test.rb +37 -0
  129. data/spec/generators/material_generator_test.rb +22 -0
  130. data/spec/generators/model_generator_test.rb +26 -0
  131. data/spec/generators/plugin_generator_test.rb +114 -0
  132. data/spec/generators/plugin_manager/push_test.rb +59 -0
  133. data/spec/generators/plugin_manager_test.rb +192 -0
  134. data/spec/generators/shader_generator_test.rb +38 -0
  135. data/spec/lib/jax/application_test.rb +18 -0
  136. data/spec/lib/jax/generators/plugin/credentials_test.rb +72 -0
  137. data/spec/lib/jax/packager_test.rb +87 -0
  138. data/spec/lib/jax/plugin_test.rb +27 -0
  139. data/spec/lib/jax/reloading_test.rb +23 -0
  140. data/spec/lib/jax/routes_test.rb +28 -0
  141. data/spec/lib/jax/shader_test.rb +29 -0
  142. data/spec/lib/jax/tasks/jax_rake_test.rb +85 -0
  143. data/spec/support/bases/generator_test_case.rb +108 -0
  144. data/spec/support/bases/isolated_test_case.rb +148 -0
  145. data/spec/support/fixtures_helper.rb +21 -0
  146. data/spec/support/spec_shell.rb +14 -1
  147. data/spec/test_app.rb +3 -0
  148. data/spec/test_helper.rb +55 -0
  149. metadata +200 -92
  150. data/spec/generators/app_generator_spec.rb +0 -47
  151. data/spec/generators/controller_generator_spec.rb +0 -68
  152. data/spec/generators/light_generator_spec.rb +0 -51
  153. data/spec/generators/material_generator_spec.rb +0 -35
  154. data/spec/generators/model_generator_spec.rb +0 -43
  155. data/spec/lib/jax/routes_spec.rb +0 -24
  156. data/spec/lib/jax/shader_spec.rb +0 -57
  157. data/spec/lib/jax/tasks/jax_rake_spec.rb +0 -92
  158. data/spec/spec_helper.rb +0 -11
@@ -0,0 +1,11 @@
1
+ #nav {
2
+ position:absolute;
3
+ top: 0px;
4
+ left: 0px;
5
+ background-color: #fff;
6
+ z-index:100; /* for chrome */
7
+ }
8
+
9
+ body {
10
+ margin: 0;
11
+ }
@@ -7,7 +7,7 @@
7
7
 
8
8
  <p>
9
9
  Unfortunately, WebGL appears to be unavailable! Please verify that you have the latest release of a WebGL-compatible
10
- browser such as <a href="http://www.firefox.com">FireFox 4.0</a> or <a href="http://chrome.google.com">Chrome 11</a>.
10
+ browser such as <a href="http://www.firefox.com">FireFox</a> or <a href="http://chrome.google.com">Chrome</a>.
11
11
  </p>
12
12
 
13
13
  <p>
@@ -17,6 +17,7 @@ src_files:
17
17
  - app/**/*.js
18
18
  - tmp/**/*.js
19
19
  - public/javascripts/**/*.js
20
+ - lib/**/*.js
20
21
 
21
22
  # stylesheets
22
23
  #
@@ -11,23 +11,31 @@ function setupJaxTestEnvironment() {
11
11
  return trivialReporter.specFilter(spec);
12
12
  };
13
13
 
14
+ setupJaxSpecContext();
15
+
16
+ jasmineEnv.execute();
17
+ }
18
+
19
+ function setupJaxSpecContext() {
14
20
  /*
15
21
  Create a canvas element and add it to the document.
16
22
  There's nothing special about this element.
17
23
  */
18
24
  var canvas = document.createElement("canvas");
25
+ canvas.setAttribute("width", 600);
26
+ canvas.setAttribute("height", 400);
19
27
  canvas.setAttribute("id", "spec-canvas");
20
28
  canvas.style.display = "none";
21
29
  document.body.appendChild(canvas);
22
30
 
23
31
  beforeEach(function() {
24
- window.SPEC_CONTEXT = new Jax.Context(canvas);
32
+ Jax.getGlobal().SPEC_CONTEXT = new Jax.Context(canvas);
25
33
  });
26
34
 
27
35
  afterEach(function() {
28
- SPEC_CONTEXT.dispose();
36
+ Jax.getGlobal().SPEC_CONTEXT.dispose();
29
37
  })
30
-
31
-
32
- jasmineEnv.execute();
33
38
  }
39
+
40
+ if (typeof(global) != 'undefined')
41
+ global.setupJaxSpecContext = setupJaxSpecContext;
@@ -157,39 +157,35 @@ beforeEach(function() {
157
157
  this.actual = "model";
158
158
  var original_render = model.render;
159
159
 
160
- var context = new Jax.Context('canvas-element');
161
- context.world.addObject(model);
162
- context.world.addLightSource(new Jax.Scene.LightSource({type:Jax.DIRECTIONAL_LIGHT}));
160
+ SPEC_CONTEXT.world.addObject(model);
161
+ SPEC_CONTEXT.world.addLightSource(new Jax.Scene.LightSource({type:Jax.DIRECTIONAL_LIGHT}));
163
162
 
164
163
  var illuminated = false;
165
164
  model.render = function() {
166
- if (context.current_pass == Jax.Scene.ILLUMINATION_PASS)
165
+ if (SPEC_CONTEXT.current_pass == Jax.Scene.ILLUMINATION_PASS)
167
166
  illuminated = true;
168
167
  };
169
168
 
170
169
  spyOn(model, 'render').andCallThrough();
171
- context.world.render();
170
+ SPEC_CONTEXT.world.render();
172
171
 
173
172
  var called = model.render.callCount;
174
173
  if (!model.render.callCount) result = false; // fail-safe
175
- context.dispose();
176
174
 
177
175
  model.render = original_render;
178
176
  return called && illuminated;
179
177
  },
180
178
 
181
179
  toBeRendered: function() {
182
- var context = new Jax.Context('canvas-element');
183
180
  var model = this.actual;
184
181
  var original_render = model.render;
185
- context.world.addObject(model);
182
+ SPEC_CONTEXT.world.addObject(model);
186
183
 
187
184
  this.actual = 'model';
188
185
  spyOn(model, 'render');
189
- context.world.render();
186
+ SPEC_CONTEXT.world.render();
190
187
  expect(model.render).toHaveBeenCalled();
191
188
 
192
- context.dispose();
193
189
  model.render = original_render;
194
190
  },
195
191
 
@@ -3,92 +3,218 @@
3
3
  require 'thor'
4
4
  require 'thor/group'
5
5
  require File.expand_path('../../jax', File.dirname(__FILE__))
6
+ require File.expand_path('interactions', File.dirname(__FILE__))
6
7
 
7
8
  module Jax
8
9
  module Generators
9
- class Command < Thor::Group
10
- class << self
11
- def inherited(base)
12
- base.base_path = File.dirname(caller.first.gsub(/:.*$/, ''))
10
+ class Error < Thor::Error
11
+ end
12
+
13
+ module Usage
14
+ module ClassMethods
15
+ def start(given_args=ARGV, config={})
16
+ if (given_args.length == 0)
17
+ puts usage
18
+ else
19
+ super
20
+ end
13
21
  end
14
-
22
+
23
+ def usage
24
+ usage = ERB.new(File.read(File.expand_path("USAGE", base_path)), nil, '-')
25
+ usage.result(binding)
26
+ end
27
+
15
28
  def base_path
16
29
  @base_path || raise("Jax Command base path was not found")
17
30
  end
18
-
31
+
19
32
  def base_path=(path)
20
33
  @base_path = path
21
34
  end
22
-
23
- def usage
24
- usage = ERB.new(File.read(File.expand_path("USAGE", base_path)), nil, '-')
25
- usage.result(binding)
35
+ end
36
+
37
+ class << self
38
+ def extended(base)
39
+ base.send :extend, ClassMethods
40
+ base.base_path = File.dirname(caller.first.gsub(/:.*$/, ''))
26
41
  end
27
-
28
- def start(given_args=ARGV, config={})
29
- if (given_args.length == 0)
30
- puts usage
31
- else
32
- super
42
+
43
+ def included(base)
44
+ base.send :extend, ClassMethods
45
+ base.base_path = File.dirname(caller.first.gsub(/:.*$/, ''))
46
+ end
47
+ end
48
+ end
49
+
50
+ class Command < Thor::Group
51
+ include Thor::Actions
52
+ include Jax::Generators::Usage
53
+
54
+ no_tasks do
55
+ def exit(message = "")
56
+ raise Jax::Generators::Error, message
57
+ end
58
+ end
59
+
60
+ def self.inherited(base)
61
+ base.base_path = File.dirname(caller.first.gsub(/:.*$/, ''))
62
+ base.instance_eval do
63
+ def self.source_root
64
+ File.join(base_path, "templates")
33
65
  end
34
66
  end
35
67
  end
36
68
  end
37
69
 
38
- autoload :Controller, File.join(File.dirname(__FILE__), "controller/controller_generator")
39
- autoload :Model, File.join(File.dirname(__FILE__), "model/model_generator")
40
- autoload :LightSource,File.join(File.dirname(__FILE__), "light_source/light_source_generator")
41
- autoload :Material, File.join(File.dirname(__FILE__), "material/material_generator")
42
- autoload :Shader, File.join(File.dirname(__FILE__), "shader/shader_generator")
70
+ # Generators extending PluggableCommand will produce code in either a Jax
71
+ # application proper, or in a plugin within the app.
72
+ class PluggableCommand < Command
73
+ def check_plugin_destination
74
+ if ENV['JAX_CWD'] && cwd = File.expand_path('.', ENV['JAX_CWD'])
75
+ if cwd =~ /^#{Regexp::escape File.join(Jax.root, "vendor/plugins/", "")}(.*?)(\/|$)/
76
+ self.destination_root = Jax.root.join("vendor", "plugins", $1)
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ autoload :Controller, "jax/generators/controller/controller_generator"
83
+ autoload :Model, "jax/generators/model/model_generator"
84
+ autoload :LightSource, "jax/generators/light_source/light_source_generator"
85
+ autoload :Material, "jax/generators/material/material_generator"
86
+ autoload :Shader, "jax/generators/shader/shader_generator"
87
+ autoload :Plugin, "jax/generators/plugin/all"
88
+ autoload :Packager, "jax/generators/packager/package_generator"
43
89
  end
44
90
  end
45
91
 
46
92
  class JaxGeneratorInvoker < Thor
93
+ include Thor::Actions
94
+
47
95
  def self.basename
48
96
  "jax generate"
49
97
  end
50
98
 
51
- desc "controller", "generates a new controller"
99
+ desc "controller NAME", "generates a new controller"
52
100
  def controller(*args)
53
- Jax::Generators::Controller::ControllerGenerator.start(args)
101
+ Jax::Generators::Controller::ControllerGenerator.start(ARGV[1..-1])
54
102
  end
55
103
 
56
- desc "model", "generates a new model"
104
+ desc "model NAME", "generates a new model"
57
105
  def model(*args)
58
- Jax::Generators::Model::ModelGenerator.start(args)
106
+ Jax::Generators::Model::ModelGenerator.start(args, :behavior => behavior)
59
107
  end
60
108
 
61
- desc "light", "generates a new light source"
109
+ desc "light NAME TYPE", "generates a new light source"
62
110
  def light(*args)
63
- Jax::Generators::LightSource::LightSourceGenerator.start(args)
111
+ Jax::Generators::LightSource::LightSourceGenerator.start(args, :behavior => behavior)
64
112
  end
65
113
 
66
- desc "material", "generates a new material"
114
+ desc "material NAME", "generates a new material"
67
115
  def material(*args)
68
116
  args = ARGV.dup
69
- 2.times { args.shift }
70
- Jax::Generators::Material::MaterialGenerator.start(args)
117
+ args.shift
118
+ Jax::Generators::Material::MaterialGenerator.start(args, :behavior => behavior)
71
119
  end
72
120
 
73
- desc "scaffold", "generates a controller, model and material, all with the same name"
74
- def scaffold(*name)
75
- name = name.shift || []
76
- Jax::Generators::Controller::ControllerGenerator.start([name, 'index'])
77
- Jax::Generators::Model::ModelGenerator.start([name])
78
- Jax::Generators::Material::MaterialGenerator.start([name])
121
+ desc "scaffold NAME", "generates a controller, model and material, all with the same name"
122
+ def scaffold(name)
123
+ Jax::Generators::Controller::ControllerGenerator.start([name, 'index'], :behavior => behavior)
124
+ Jax::Generators::Model::ModelGenerator.start([name], :behavior => behavior)
125
+ Jax::Generators::Material::MaterialGenerator.start([name], :behavior => behavior)
79
126
  end
80
127
 
81
- desc "shader", "generates a new custom shader"
128
+ desc "shader NAME", "generates a new custom shader"
82
129
  def shader(*name)
83
- Jax::Generators::Shader::ShaderGenerator.start(name)
130
+ Jax::Generators::Shader::ShaderGenerator.start(name, :behavior => behavior)
131
+ end
132
+
133
+ desc "plugin NAME", "generates a new plugin"
134
+ def plugin(*args)
135
+ Jax::Generators::Plugin::PluginGenerator.start(ARGV[1..-1], :behavior => behavior)
84
136
  end
85
137
  end
86
138
 
87
- class JaxGenerator < Thor
88
- desc "generate", "generates a controller, model, light source, material or shader"
89
- def generate(*args)
90
- JaxGeneratorInvoker.start(args)
139
+ class JaxGenerator
140
+ attr_reader :args
141
+
142
+ COMMANDS = {
143
+ "generate" => "Generate new code",
144
+ "destroy" => "Undo code generated with \"generate\"",
145
+ "plugin" => "Install a plugin",
146
+ "package" => "Package the app for production"
147
+ } unless defined?(COMMANDS)
148
+ ALIASES = { "g" => "generate" } unless defined?(ALIASES)
149
+
150
+ def initialize(args)
151
+ @args = args
152
+
153
+ show_usage and return unless command
154
+ if respond_to? command then send command
155
+ else invalid command
156
+ end
91
157
  rescue ArgumentError
92
158
  puts $!.message
93
159
  end
160
+
161
+ def package
162
+ Jax::Generators::Packager::PackageGenerator.start
163
+ end
164
+
165
+ def generate
166
+ JaxGeneratorInvoker.start
167
+ end
168
+
169
+ def destroy
170
+ JaxGeneratorInvoker.start(ARGV, :behavior => :revoke)
171
+ end
172
+
173
+ def plugin
174
+ Jax::Generators::Plugin::PluginManager.start
175
+ end
176
+
177
+ def command
178
+ @command ||= begin
179
+ command = args.shift
180
+ command = ALIASES[command] || command
181
+ end
182
+ end
183
+
184
+ def invalid(command)
185
+ puts "Invalid command."
186
+ puts
187
+ show_usage
188
+ end
189
+
190
+ def show_usage
191
+ puts <<-end_banner
192
+ Usage: jax COMMAND [ARGS]
193
+
194
+ The following commands are available:
195
+ #{command_list.join("\n ")}
196
+
197
+ All commands can be run with -h for more information.
198
+ end_banner
199
+ end
200
+
201
+ def command_list
202
+ COMMANDS.keys.collect { |command| "#{command.ljust(13)}#{description_for command}"}
203
+ end
204
+
205
+ def description_for(command)
206
+ if i = ALIASES.values.index(command)
207
+ COMMANDS[command] + " (shortcut alias: \"#{ALIASES.keys[i]}\")"
208
+ else
209
+ COMMANDS[command]
210
+ end
211
+ end
212
+
213
+ class << self
214
+ # this gets called by script/jax from within a jax app
215
+ def start
216
+ new ARGV
217
+ end
218
+ end
94
219
  end
220
+
@@ -3,10 +3,10 @@ require 'active_support/core_ext'
3
3
  module Jax
4
4
  module Generators
5
5
  module Controller
6
- class ControllerGenerator < Jax::Generators::Command
7
- include Thor::Actions
6
+ class ControllerGenerator < Jax::Generators::PluggableCommand
8
7
  argument :controller_name
9
8
  attr_reader :actions, :action_name
9
+ class_option :root, :default => false, :type => :boolean
10
10
 
11
11
  def self.source_root
12
12
  File.expand_path("templates", File.dirname(__FILE__))
@@ -15,6 +15,7 @@ module Jax
15
15
  def initialize(args=[], options={}, config={})
16
16
  super
17
17
  @actions = args[1..-1].collect { |c| c.underscore }
18
+ @actions = ['index'] if @actions.empty?
18
19
  @controller_name = controller_name.underscore
19
20
  end
20
21
 
@@ -44,6 +45,12 @@ module Jax
44
45
  :after => /\.routes\.map do$/
45
46
  end
46
47
  end
48
+
49
+ def root_route
50
+ if options[:root]
51
+ insert_into_file "config/routes.rb", " root '#{controller_name}'\n", :before => /^end\s*\Z/
52
+ end
53
+ end
47
54
 
48
55
  protected
49
56
  def file_name
@@ -0,0 +1,56 @@
1
+ module Jax
2
+ module Generators
3
+ module Interactions
4
+ def prompt_yn(message, options = {})
5
+ yn = ask(message).downcase[0]
6
+ throw :aborted, "Aborted by user." if yn != ?y
7
+ end
8
+
9
+ def menu(items, options = {})
10
+ min = 1
11
+ if options[:allow_all]
12
+ say_option 0, "All candidates"
13
+ min = 0
14
+ end
15
+
16
+ items.each_with_index do |item, index|
17
+ say_option index+1, item
18
+ end
19
+ which = menu_choice(:min => min, :max => items.length)
20
+
21
+ if which == -1
22
+ items.each_with_index { |item, index| yield item, index }
23
+ else
24
+ yield items[which], which
25
+ end
26
+ end
27
+
28
+ def menu_choice(*args)
29
+ options = args.extract_options!
30
+ caption, addl_caption = *args
31
+ caption = "Please select an option, or press ctrl+c to cancel >" unless caption
32
+
33
+ which = ask("#{addl_caption}#{caption}")
34
+ sel = which.to_i
35
+ # if sel.to_s != which then which is non-numeric
36
+ if sel.to_s != which || options[:min] && sel < options[:min] || options[:max] && sel > options[:max]
37
+ menu_choice(caption, "Invalid choice. ")
38
+ else
39
+ sel - 1
40
+ end
41
+ end
42
+
43
+ def say_option(which, caption)
44
+ say "\t#{which}\t: #{caption}"
45
+ end
46
+
47
+ def overwrite(path)
48
+ path = path.to_s
49
+ if File.exist? path
50
+ prompt_yn "Path '#{path}' already exists! Delete it?"
51
+ FileUtils.rm_rf path
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end