osc_machete_rails 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +76 -0
- data/LICENSE.txt +22 -0
- data/README.md +14 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/osc_machete_rails/application.js +13 -0
- data/app/assets/stylesheets/osc_machete_rails/application.css +13 -0
- data/app/controllers/osc_machete_rails/application_controller.rb +4 -0
- data/app/helpers/osc_machete_rails/application_helper.rb +4 -0
- data/app/views/layouts/osc_machete_rails/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/generators/active_record/job_model_generator.rb +13 -0
- data/lib/generators/active_record/orm_helpers.rb +6 -0
- data/lib/generators/active_record/templates/job_model.rb +17 -0
- data/lib/generators/active_record/templates/migration.rb +19 -0
- data/lib/generators/active_record/templates/module.rb +7 -0
- data/lib/generators/active_record/templates/workflow_model.rb +34 -0
- data/lib/generators/active_record/workflow_model_generator.rb +30 -0
- data/lib/generators/osc_machete_rails/USAGE +36 -0
- data/lib/generators/osc_machete_rails/erb/erb_generator.rb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/_form.html.erb +21 -0
- data/lib/generators/osc_machete_rails/erb/templates/edit.html.erb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/index.html.erb +41 -0
- data/lib/generators/osc_machete_rails/erb/templates/new.html.erb +5 -0
- data/lib/generators/osc_machete_rails/erb/templates/show.html.erb +13 -0
- data/lib/generators/osc_machete_rails/job_helpers.rb +10 -0
- data/lib/generators/osc_machete_rails/job_model/USAGE +28 -0
- data/lib/generators/osc_machete_rails/job_model/job_model_generator.rb +13 -0
- data/lib/generators/osc_machete_rails/resource_route/USAGE +3 -0
- data/lib/generators/osc_machete_rails/resource_route/resource_route_generator.rb +57 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/USAGE +17 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/scaffold_controller_generator.rb +24 -0
- data/lib/generators/osc_machete_rails/scaffold_controller/templates/controller.rb +120 -0
- data/lib/generators/osc_machete_rails/scaffold_generator.rb +35 -0
- data/lib/generators/osc_machete_rails/workflow_model/USAGE +38 -0
- data/lib/generators/osc_machete_rails/workflow_model/workflow_model_generator.rb +12 -0
- data/lib/generators/osc_machete_rails/workflow_template/USAGE +19 -0
- data/lib/generators/osc_machete_rails/workflow_template/templates/main.sh.mustache +18 -0
- data/lib/generators/osc_machete_rails/workflow_template/workflow_template_generator.rb +9 -0
- data/lib/osc_machete_rails/engine.rb +24 -0
- data/lib/osc_machete_rails/helper.rb +25 -0
- data/lib/osc_machete_rails/statusable.rb +199 -0
- data/lib/osc_machete_rails/version.rb +3 -0
- data/lib/osc_machete_rails/workflow.rb +249 -0
- data/lib/osc_machete_rails.rb +12 -0
- data/lib/tasks/osc_machete_rails_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/javascripts/simulations.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/simulations.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/simulations_controller.rb +103 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/simulations_helper.rb +2 -0
- data/test/dummy/app/models/simulation.rb +26 -0
- data/test/dummy/app/models/simulation_job.rb +15 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/simulations/_form.html.erb +15 -0
- data/test/dummy/app/views/simulations/edit.html.erb +5 -0
- data/test/dummy/app/views/simulations/index.html.erb +35 -0
- data/test/dummy/app/views/simulations/new.html.erb +5 -0
- data/test/dummy/app/views/simulations/show.html.erb +16 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +11 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20151230193910_create_simulations.rb +11 -0
- data/test/dummy/db/migrate/20151230193911_create_simulation_jobs.rb +15 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/jobs/simulation/main.sh.mustache +17 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +31198 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0ff4cb4a6c217771a1336b307c51cf4e +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/57261b7c75c19be33229517e39e47528 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9e1e594361ba2561e5f6011db99503bb +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/dc292ec300d07016ebcc2de4806208c3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/integration/error_handling_test.rb +166 -0
- data/test/integration/statusable_update_status_test.rb +47 -0
- data/test/models/simulation_test.rb +4 -0
- data/test/osc_machete_rails_test.rb +7 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/statusable_test.rb +124 -0
- metadata +320 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8fd50095c5fcd06e3563aaaed87004a06c9e76aa
|
4
|
+
data.tar.gz: c0b622235dee4361de6467d929f352d875905c24
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38d903278baf2add66f71037dbb192b15a65b75b019eb2f9ba080e2a110cb9d014d0b1c59aa0231ef048a0277211f919da9643b2763cf9994d0cbf63ac6477fc
|
7
|
+
data.tar.gz: 84231e28bb943ea11a0cbde8ca6325c0ac89ed6b0ec882ce7b5be6e3150a7a4591adf4a7a6a204e019eaf327449547a3d54ffea1b110ba53106f3a1f1a3f6b0b
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
5
|
+
|
6
|
+
## [Unreleased]
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
|
10
|
+
- remove `AwesimRails` as a dependency
|
11
|
+
|
12
|
+
## [1.1.0] - 2016-03-03
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
|
16
|
+
- fix precompiling assets when a database is not available (which almost always happens when you go to share an app)
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- status_label view helper now accepts a second optional argument specifying the tag that wraps the label (defaults to span)
|
21
|
+
- status_label view helper now adds the class `status_label` to the labels for easier customization of the labels
|
22
|
+
|
23
|
+
## [1.0.1] - 2016-02-19
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Fix module used so Statusable.update_status_of_all_active_jobs is called on each request
|
28
|
+
|
29
|
+
## 1.0.0 - 2016-02-03
|
30
|
+
|
31
|
+
This release notes changes from existing files pulled out of osc-machete gem and
|
32
|
+
added features and fixed defects that this gem introduces.
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- `update_status!` on the `Job` models (models that include `OscMacheteRails::Statusable`) is called at beginning of each request instead of in the `after_find` hook, so you no longer need to preload to trigger the update (a big hangup we had earlier for each new developer)
|
37
|
+
- even if you did preload for the `Job` models, superfluous sql calls were being made for each model - this was eliminated
|
38
|
+
- with the latest version of torque new status values were causing problems with status display on simulations. Introducing the Status value object fixed this problem
|
39
|
+
- proper error handling avoided various odd behavior that resulted if job submission failed
|
40
|
+
|
41
|
+
### Added
|
42
|
+
|
43
|
+
- Rails generators to scaffold a workflow
|
44
|
+
- status_label helper to replace the one previously manually added or generated by Rails application template (this one handles Status values appropriately)
|
45
|
+
- Initialization option: change OscMacheteRails.update_status_of_all_active_jobs_on_each_request to false if you want to disable the update of all active jobs on each request
|
46
|
+
- workflow.rb: before_destroy we stop all of the jobs and if that succeeds we delete the staged directory if "staged_dir" exists on model that has a workflow
|
47
|
+
- statusable.rb: Added Statusable#stop to allow qdel-ing the job. This could be used to implement a stop feature if you wanted to stop a simulation but keep from deleting the files it had created so far.
|
48
|
+
|
49
|
+
|
50
|
+
### Changed
|
51
|
+
|
52
|
+
workflow.rb (from v0.6.3 of osc-machete to latest osc_machete_rails)
|
53
|
+
|
54
|
+
- in module OscMacheteRails instead of OSC::Machete::SimpleJob
|
55
|
+
- handle errors when submitting jobs, logging the error and setting it on the model#errors object
|
56
|
+
- if submitting a job fails, we delete the staged directory that was created during submission
|
57
|
+
|
58
|
+
statusable.rb (from v0.6.3 of osc-machete to latest osc_machete_rails)
|
59
|
+
|
60
|
+
- in module OscMacheteRails instead of OSC::Machete::SimpleJob
|
61
|
+
- models that include Statutable no longer are updated via after_find hook. instead a new class method "update_status_of_all_active_jobs" is called to call `Statusable#update_status!` on each instance that is in an active state (running, queued, etc.). this is called at the beginning of each request via a before_action hook on the application controller.
|
62
|
+
- update_status! handles PBS::Error's when checking the status, logs an error in the log and then leaves the model untouched
|
63
|
+
- Statusable#status returns OSC::Machete::Status object instead of a character
|
64
|
+
- Statusable#status= can accept a character, nil or an OSC::Machete::Status
|
65
|
+
- Statusable#job= lets you set the attributes of an OSC::Machete::Job object to the Statusable model. Backwards compatibility supports saving the attributes script_name, job_path, and pbsid. New models produced by the generators use a job_cache column that stores a hash, and script, pbsid, and host are saved here instead.
|
66
|
+
- setters `script_name=` and `job_path=` do not exist on models that are generated using the generators (models that have a job_cache column)
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
### Removed
|
71
|
+
|
72
|
+
|
73
|
+
[Unreleased]: https://github.com/AweSim-OSC/osc_machete_rails/compare/v1.1.0...master
|
74
|
+
[1.1.0]: https://github.com/AweSim-OSC/osc_machete_rails/compare/v1.0.1...v1.1.0
|
75
|
+
[1.0.1]: https://github.com/AweSim-OSC/osc_machete_rails/compare/v1.0.0...v1.0.1
|
76
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015-2016 Ohio Supercomputer Center
|
2
|
+
|
3
|
+
MIT License
|
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/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'OscMacheteRails'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>OscMacheteRails</title>
|
5
|
+
<%= stylesheet_link_tag "osc_machete_rails/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "osc_machete_rails/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/active_record/model/model_generator'
|
2
|
+
require 'generators/active_record/orm_helpers'
|
3
|
+
|
4
|
+
class ActiveRecord::JobModelGenerator < ActiveRecord::Generators::ModelGenerator
|
5
|
+
include ActiveRecord::OrmHelpers
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
# overrides original ModelGenerator#create_model_file to make a job_model instead of a model
|
9
|
+
# since we are inheriting from ModelGenerator, we get the tests and all the other good stuff
|
10
|
+
def create_model_file
|
11
|
+
template 'job_model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
class <%= class_name %> < <%= parent_class_name.classify %>
|
3
|
+
include OscMacheteRails::Statusable
|
4
|
+
|
5
|
+
<% attributes.select(&:reference?).each do |attribute| -%>
|
6
|
+
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
7
|
+
<% end -%>
|
8
|
+
<% if attributes.any?(&:password_digest?) -%>
|
9
|
+
has_secure_password
|
10
|
+
<% end -%>
|
11
|
+
|
12
|
+
# Determine if the results are valid
|
13
|
+
# def results_valid?
|
14
|
+
# # CODE GOES HERE
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
<% end -%>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
|
+
<% attributes.each do |attribute| -%>
|
5
|
+
<% if attribute.password_digest? -%>
|
6
|
+
t.string :password_digest<%= attribute.inject_options %>
|
7
|
+
<% else -%>
|
8
|
+
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
9
|
+
<% end -%>
|
10
|
+
<% end -%>
|
11
|
+
<% if options[:timestamps] %>
|
12
|
+
t.timestamps
|
13
|
+
<% end -%>
|
14
|
+
end
|
15
|
+
<% attributes_with_index.each do |attribute| -%>
|
16
|
+
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
17
|
+
<% end -%>
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
class <%= class_name %> < <%= parent_class_name.classify %>
|
3
|
+
has_many :<%= job.plural_name %>, dependent: :destroy
|
4
|
+
has_machete_workflow_of :<%= job.plural_name %>
|
5
|
+
|
6
|
+
<% attributes.select(&:reference?).each do |attribute| -%>
|
7
|
+
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
8
|
+
<% end -%>
|
9
|
+
<% if attributes.any?(&:password_digest?) -%>
|
10
|
+
has_secure_password
|
11
|
+
<% end -%>
|
12
|
+
|
13
|
+
# Name that defines the template/target dirs
|
14
|
+
def staging_template_name
|
15
|
+
"<%= file_name %>"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Define tasks to do after staging template directory typically copy over
|
19
|
+
# uploaded files here
|
20
|
+
# def after_stage(staged_dir)
|
21
|
+
# # CODE HERE
|
22
|
+
# end
|
23
|
+
|
24
|
+
# Build an array of Machete jobs that are then submitted to the batch server
|
25
|
+
def build_jobs(staged_dir, job_list = [])
|
26
|
+
job_list << OSC::Machete::Job.new(script: staged_dir.join("main.sh"))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Make copy of workflow
|
30
|
+
def copy
|
31
|
+
self.dup
|
32
|
+
end
|
33
|
+
end
|
34
|
+
<% end -%>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rails/generators/active_record/model/model_generator'
|
2
|
+
require 'generators/active_record/orm_helpers'
|
3
|
+
require 'generators/osc_machete_rails/job_helpers'
|
4
|
+
|
5
|
+
class ActiveRecord::WorkflowModelGenerator < ActiveRecord::Generators::ModelGenerator
|
6
|
+
include ActiveRecord::OrmHelpers
|
7
|
+
include OscMacheteRails::JobHelpers
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
# add a new attribute to the generator
|
11
|
+
# the workflow needs to know what the job model is
|
12
|
+
# to render the template properly
|
13
|
+
attr_reader :job
|
14
|
+
|
15
|
+
# jobs is a new attribute type, like "references", so we can let the user specify the corresponding
|
16
|
+
# job model. This attribute is used in the workflow_model.rb template file. i.e.
|
17
|
+
#
|
18
|
+
# rails g osc_machete_rails:workflow_model Container name:string container_job:jobs
|
19
|
+
#
|
20
|
+
def initialize(args, *options)
|
21
|
+
@job = parse_job!(args)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
# overrides original ModelGenerator#create_model_file to make a workflow_model instead of a model
|
26
|
+
# since we are inheriting from ModelGenerator, we get the tests and all the other good stuff
|
27
|
+
def create_model_file
|
28
|
+
template 'workflow_model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Description:
|
2
|
+
Scaffolds an entire workflow, from models and migrations to controller and
|
3
|
+
views, along with a full test suite. The resource is ready to use as a
|
4
|
+
starting point for your Workflow.
|
5
|
+
|
6
|
+
Pass the name of the workflow (in singular form), either CamelCased or
|
7
|
+
under_scored, as the first argument, and an optional list of attribute
|
8
|
+
pairs.
|
9
|
+
|
10
|
+
Attributes are field arguments specifying the model's attributes. You can
|
11
|
+
optionally pass the type and an index to each field. For instance:
|
12
|
+
"title body:text tracking_id:integer:uniq" will generate a title field of
|
13
|
+
string type, a body with text type and a tracking_id as an integer with an
|
14
|
+
unique index. "index" could also be given instead of "uniq" if one desires
|
15
|
+
a non unique index.
|
16
|
+
|
17
|
+
Timestamps are added by default, so you don't have to specify them by hand
|
18
|
+
as 'created_at:datetime updated_at:datetime'.
|
19
|
+
|
20
|
+
You don't have to think up every attribute up front, but it helps to
|
21
|
+
sketch out a few so you can start working with the resource immediately.
|
22
|
+
|
23
|
+
For example, 'osc_machete_rails:scaffold container name pressure:decimal'
|
24
|
+
gives you a workflow model with those two attributes, a workflow template,
|
25
|
+
a job model, a controller that handles the
|
26
|
+
create/show/update/destroy/submit/copy, forms to create and edit your
|
27
|
+
posts, and an index that lists them all, as well as a resources :containers
|
28
|
+
declaration in config/routes.rb.
|
29
|
+
|
30
|
+
If you want to remove all the generated files, run
|
31
|
+
'rails destroy osc_machete_rails:scaffold WorkflowName'.
|
32
|
+
|
33
|
+
Examples:
|
34
|
+
`rails generate osc_machete_rails:scaffold structure`
|
35
|
+
`rails generate osc_machete_rails:scaffold fan name comments:text centrifugal:boolean`
|
36
|
+
`rails generate osc_machete_rails:scaffold heatsink material temperature:decimal`
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%%# Uses rails_bootstrap_form gem. API at: https://github.com/bootstrap-ruby/rails-bootstrap-forms %>
|
2
|
+
<%%= bootstrap_form_for(<%= singular_table_name %>) do |f| %>
|
3
|
+
<%%= f.alert_message "Please fix the errors below." %>
|
4
|
+
|
5
|
+
<% attributes.each do |attribute| -%>
|
6
|
+
<% if attribute.password_digest? -%>
|
7
|
+
<%%= f.password_field :password %>
|
8
|
+
<%%= f.password_field :password_confirmation %>
|
9
|
+
<% else -%>
|
10
|
+
<%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %>
|
11
|
+
<% end -%>
|
12
|
+
<% end -%>
|
13
|
+
|
14
|
+
<%%= f.submit 'Save', class: 'btn btn-primary' %>
|
15
|
+
<%%= f.button 'Reset', type: :reset, class: 'btn btn-default' %>
|
16
|
+
|
17
|
+
<hr>
|
18
|
+
|
19
|
+
<%%= link_to 'Back', <%= index_helper %>_path, class: 'btn btn-default' %>
|
20
|
+
<%%= link_to 'Show', <%= singular_table_name %>, class: 'btn btn-primary' unless <%= singular_table_name %>.new_record? %>
|
21
|
+
<%% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h2>Listing <%= plural_table_name.titleize %></h2>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<table class="table data-table">
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th>#</th>
|
9
|
+
<th>Status</th>
|
10
|
+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
11
|
+
<th><%= attribute.human_name %></th>
|
12
|
+
<% end -%>
|
13
|
+
<th class="no-sort"></th>
|
14
|
+
<th class="no-sort"></th>
|
15
|
+
<th class="no-sort"></th>
|
16
|
+
<th class="no-sort"></th>
|
17
|
+
<th class="no-sort"></th>
|
18
|
+
</tr>
|
19
|
+
</thead>
|
20
|
+
|
21
|
+
<tbody>
|
22
|
+
<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
|
23
|
+
<tr>
|
24
|
+
<td><%%= <%= singular_table_name %>.id %></td>
|
25
|
+
<td><%%= status_label(<%= singular_table_name %>) %></td>
|
26
|
+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
27
|
+
<td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
|
28
|
+
<% end -%>
|
29
|
+
<td><%%= link_to 'Submit', submit_<%= singular_table_name %>_path(<%= singular_table_name %>), method: :put, class: 'btn btn-success btn-sm' unless <%= singular_table_name %>.submitted? %></td>
|
30
|
+
<td><%%= link_to 'Show', <%= singular_table_name %>, class: 'btn btn-primary btn-sm' %></td>
|
31
|
+
<td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>), class: 'btn btn-default btn-sm' unless <%= singular_table_name %>.submitted? %></td>
|
32
|
+
<td><%%= link_to 'Copy', copy_<%= singular_table_name %>_path(<%= singular_table_name %>), method: :put, class: 'btn btn-default btn-sm' %></td>
|
33
|
+
<td><%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, class: 'btn btn-danger btn-sm', data: { confirm: 'Are you sure?' } %></td>
|
34
|
+
</tr>
|
35
|
+
<%% end %>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
|
39
|
+
<br>
|
40
|
+
|
41
|
+
<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_table_name %>_path %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h2>Showing <%= singular_table_name.titleize %></h2>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
6
|
+
<p>
|
7
|
+
<strong><%= attribute.human_name %>:</strong>
|
8
|
+
<%%= @<%= singular_table_name %>.<%= attribute.name %> %>
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<% end -%>
|
12
|
+
<%%= link_to 'Back', <%= index_helper %>_path, class: 'btn btn-default' %>
|
13
|
+
<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>), class: 'btn btn-default' %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a new job model. Pass the model name, either CamelCased or
|
3
|
+
under_scored, and an optional list of attribute pairs as arguments.
|
4
|
+
|
5
|
+
Attribute pairs are field:type arguments specifying the
|
6
|
+
model's attributes. Timestamps are added by default, so you don't have to
|
7
|
+
specify them by hand as 'created_at:datetime updated_at:datetime'.
|
8
|
+
|
9
|
+
You don't have to think up every attribute up front, but it helps to
|
10
|
+
sketch out a few so you can start working with the model immediately.
|
11
|
+
|
12
|
+
This generator invokes your configured ORM and test framework, which
|
13
|
+
defaults to ActiveRecord and TestUnit.
|
14
|
+
|
15
|
+
Available field types:
|
16
|
+
|
17
|
+
For more information see:
|
18
|
+
|
19
|
+
`rails generate model --help`
|
20
|
+
|
21
|
+
Example:
|
22
|
+
`rails generate osc_machete_rails:job_model ThingJob thing:references`
|
23
|
+
|
24
|
+
For ActiveRecord and TestUnit it creates:
|
25
|
+
Model: app/models/thing_job.rb
|
26
|
+
Test: test/models/thing_job_test.rb
|
27
|
+
Fixtures: test/fixtures/thing_jobs.yml
|
28
|
+
Migration: db/migrate/XXX_create_thing_jobs.rb
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class OscMacheteRails::JobModelGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path("../templates", __FILE__)
|
3
|
+
|
4
|
+
def initialize(args, *options)
|
5
|
+
args |= %w(status:string)
|
6
|
+
args |= %w(job_cache:text)
|
7
|
+
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
|
12
|
+
hook_for :orm, required: true
|
13
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class OscMacheteRails::ResourceRouteGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
|
4
|
+
# Properly nests namespaces passed into a generator
|
5
|
+
#
|
6
|
+
# $ rails generate osc_machete_rails:workflow_route admin/users/products
|
7
|
+
#
|
8
|
+
# should give you
|
9
|
+
#
|
10
|
+
# namespace :admin do
|
11
|
+
# namespace :users
|
12
|
+
# resources :products do
|
13
|
+
# member do
|
14
|
+
# put 'submit'
|
15
|
+
# put 'copy'
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
def add_workflow_route
|
21
|
+
return if options[:actions].present?
|
22
|
+
|
23
|
+
# iterates over all namespaces and opens up blocks
|
24
|
+
regular_class_path.each_with_index do |namespace, index|
|
25
|
+
write("namespace :#{namespace} do", index + 1)
|
26
|
+
end
|
27
|
+
|
28
|
+
# inserts the primary resource
|
29
|
+
write("resources :#{file_name.pluralize} do", route_length + 1)
|
30
|
+
write("member do", route_length + 2)
|
31
|
+
write("put 'submit'", route_length + 3)
|
32
|
+
write("put 'copy'", route_length + 3)
|
33
|
+
write("end", route_length + 2)
|
34
|
+
write("end", route_length + 1)
|
35
|
+
|
36
|
+
# ends blocks
|
37
|
+
regular_class_path.each_index do |index|
|
38
|
+
write("end", route_length - index)
|
39
|
+
end
|
40
|
+
|
41
|
+
# route prepends two spaces onto the front of the string that is passed, this corrects that
|
42
|
+
route route_string[2..-1]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def route_string
|
47
|
+
@route_string ||= ""
|
48
|
+
end
|
49
|
+
|
50
|
+
def write(str, indent)
|
51
|
+
route_string << "#{" " * indent}#{str}\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
def route_length
|
55
|
+
regular_class_path.length
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a scaffolded controller, its seven RESTful actions + two Workflow
|
3
|
+
actions and related views. Pass the model name, either CamelCased or
|
4
|
+
under_scored. The controller name is retrieved as a pluralized version of
|
5
|
+
the model name.
|
6
|
+
|
7
|
+
This generates a controller class in app/controllers and invokes helper,
|
8
|
+
template engine and test framework generators.
|
9
|
+
|
10
|
+
Example:
|
11
|
+
`rails generate osc_machete_rails:scaffold_controller Thing`
|
12
|
+
|
13
|
+
Thing controller with URLs like /thing/submit.
|
14
|
+
Controller: app/controllers/things_controller.rb
|
15
|
+
Test: test/controllers/things_controller_test.rb
|
16
|
+
Views: app/views/things/index.html.erb [...]
|
17
|
+
Helper: app/helpers/things_helper.rb
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
|
2
|
+
require 'generators/osc_machete_rails/job_helpers'
|
3
|
+
|
4
|
+
class OscMacheteRails::ScaffoldControllerGenerator < Rails::Generators::ScaffoldControllerGenerator
|
5
|
+
include OscMacheteRails::JobHelpers
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
# attribute to know what the job model is - see comments on active_record/workflow_model_generator.rb
|
9
|
+
attr_reader :job
|
10
|
+
|
11
|
+
def initialize(args, *options)
|
12
|
+
@job = parse_job!(args)
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
# override ScaffoldControllerGenerator
|
18
|
+
# by recalling hook_for, the erb_generator will be searched for under OscMacheteRails
|
19
|
+
# (idiosyncracy of Thor)
|
20
|
+
#
|
21
|
+
# the default template engine is erb, so we provide specific erb_generator.rb and its templates
|
22
|
+
# see lib/generators/osc_machete_rails/erb for details
|
23
|
+
hook_for :template_engine
|
24
|
+
end
|