hydra-tutorial 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,135 @@
1
+ class ModsDescMetadata < ActiveFedora::NokogiriDatastream
2
+ # MODS XML constants.
3
+
4
+ MODS_NS = 'http://www.loc.gov/mods/v3'
5
+ MODS_SCHEMA = 'http://www.loc.gov/standards/mods/v3/mods-3-3.xsd'
6
+ MODS_PARAMS = {
7
+ "version" => "3.3",
8
+ "xmlns:xlink" => "http://www.w3.org/1999/xlink",
9
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
10
+ "xmlns" => MODS_NS,
11
+ "xsi:schemaLocation" => "#{MODS_NS} #{MODS_SCHEMA}",
12
+ }
13
+
14
+ # OM terminology.
15
+
16
+ set_terminology do |t|
17
+ t.root :path => 'mods', :xmlns => MODS_NS
18
+ t.originInfo do
19
+ t.dateOther
20
+ end
21
+ t.abstract
22
+ t.titleInfo do
23
+ t.title
24
+ end
25
+
26
+ t.title :ref => [:mods, :titleInfo, :title]
27
+ t.name do
28
+ t.namePart
29
+ t.role do
30
+ t.roleTerm
31
+ end
32
+ end
33
+
34
+ t.relatedItem do
35
+ t.titleInfo do
36
+ t.title
37
+ end
38
+ t.location do
39
+ t.url
40
+ end
41
+ end
42
+
43
+ t.subject do
44
+ t.topic
45
+ end
46
+
47
+ t.preferred_citation :path => 'note', :attributes => { :type => "preferred citation" }
48
+ t.related_citation :path => 'note', :attributes => { :type => "citation/reference" }
49
+
50
+ end
51
+
52
+ # Blocks to pass into Nokogiri::XML::Builder.new()
53
+
54
+ define_template :name do |xml|
55
+ xml.name {
56
+ xml.namePart
57
+ xml.role {
58
+ xml.roleTerm(:authority => "marcrelator", :type => "text")
59
+ }
60
+ }
61
+ end
62
+
63
+ define_template :relatedItem do |xml|
64
+ xml.relatedItem {
65
+ xml.titleInfo {
66
+ xml.title
67
+ }
68
+ xml.location {
69
+ xml.url
70
+ }
71
+ }
72
+ end
73
+
74
+ define_template :related_citation do |xml|
75
+ xml.note(:type => "citation/reference")
76
+ end
77
+
78
+ def self.xml_template
79
+ Nokogiri::XML::Builder.new do |xml|
80
+ xml.mods(MODS_PARAMS) {
81
+ xml.originInfo {
82
+ xml.dateOther
83
+ }
84
+ xml.abstract
85
+ xml.titleInfo {
86
+ xml.title
87
+ }
88
+ xml.name {
89
+ xml.namePart
90
+ xml.role {
91
+ xml.roleTerm
92
+ }
93
+ }
94
+ xml.relatedItem {
95
+ xml.titleInfo {
96
+ xml.title
97
+ }
98
+ xml.location {
99
+ xml.url
100
+ }
101
+ }
102
+ xml.subject {
103
+ xml.topic
104
+ }
105
+ xml.note(:type => "preferred citation")
106
+ xml.note(:type => "citation/reference")
107
+ }
108
+ end.doc
109
+ end
110
+
111
+ def insert_person
112
+ insert_new_node(:name)
113
+ end
114
+
115
+ def insert_related_item
116
+ insert_new_node(:relatedItem)
117
+ end
118
+
119
+ def insert_related_citation
120
+ insert_new_node(:related_citation)
121
+ end
122
+
123
+ def insert_new_node(term)
124
+ add_child_node(ng_xml.root, term)
125
+ end
126
+
127
+ def remove_node(term, index)
128
+ node = self.find_by_terms(term.to_sym => index.to_i).first
129
+ unless node.nil?
130
+ node.remove
131
+ self.dirty = true
132
+ end
133
+ end
134
+
135
+ end
@@ -0,0 +1,34 @@
1
+ class Dataset < ActiveFedora::Base
2
+
3
+ class DatastreamMetadata < ActiveFedora::NokogiriDatastream
4
+
5
+ ##
6
+ # Here's the important part. We're mapping XML into Ruby.
7
+ set_terminology do |t|
8
+ t.root :path => 'root', :xmlns => nil
9
+ t.title
10
+ t.author
11
+ t.url
12
+ t.description
13
+ end
14
+
15
+ def self.xml_template
16
+ Nokogiri::XML::Builder.new do |xml|
17
+ xml.root do
18
+ xml.title
19
+ xml.author
20
+ xml.url
21
+ xml.description
22
+ end
23
+ end.doc
24
+ end
25
+ end
26
+
27
+ has_metadata :name => "descMetadata", :type => DatastreamMetadata
28
+
29
+ delegate :title, :to=>'descMetadata', :unique=>true
30
+ delegate :author, :to=>'descMetadata', :unique=>true
31
+ delegate :url, :to=>'descMetadata', :unique=>true
32
+ delegate :description, :to=>'descMetadata', :unique=>true
33
+
34
+ end
@@ -0,0 +1,24 @@
1
+ class Dataset < OmRecord # OmRecord contains code that lets us pretend this Dataset is a drop-in replacement for the ActiveRecord.
2
+ include OM::XML::Document
3
+
4
+ ##
5
+ # Here's the important part. We're mapping XML into Ruby.
6
+ set_terminology do |t|
7
+ t.root :path => 'root', :xmlns => nil
8
+ t.title
9
+ t.author
10
+ t.url
11
+ t.description
12
+ end
13
+
14
+ def self.xml_template
15
+ Nokogiri::XML::Builder.new do |xml|
16
+ xml.root do
17
+ xml.title
18
+ xml.author
19
+ xml.url
20
+ xml.description
21
+ end
22
+ end.doc
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ development:
2
+ user: fedoraAdmin
3
+ password: fedoraAdmin
4
+ url: http://127.0.0.1:8983/fedora
5
+ test: &TEST
6
+ user: fedoraAdmin
7
+ password: fedoraAdmin
8
+ url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/fedora-test" %>
9
+ production:
10
+ user: fedoraAdmin
11
+ password: fedoraAdmin
12
+ url: http://your.production.server:8080/fedora
13
+ cucumber:
14
+ <<: *TEST
@@ -0,0 +1,63 @@
1
+ class OmRecord
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ ##
6
+ # This stuff is so we can store and retrieve data off the filesystem. Don't worry about it.
7
+ extend ActiveModel::Naming
8
+ include ActiveModel::Conversion
9
+
10
+ attr_writer :file
11
+
12
+ attr_accessor :name
13
+ attr_reader :errors
14
+ end
15
+
16
+ def initialize options={}
17
+
18
+ @errors = ActiveModel::Errors.new(self)
19
+
20
+ self.ng_xml = self.class.xml_template
21
+
22
+ options.each do |k,v|
23
+ send("#{k}=", v)
24
+ end
25
+ end
26
+
27
+ def file
28
+ @file ||= "db/datasets/#{Time.now.to_i}"
29
+ end
30
+
31
+ def id
32
+ File.basename(file)
33
+ end
34
+
35
+ def save
36
+ File.open(file, 'w') { |f| f.puts ng_xml.to_s }
37
+ end
38
+
39
+ def persisted?
40
+ File.exists? file
41
+ end
42
+
43
+ class ClassMethods
44
+ def all
45
+ Dir.glob('db/datasets/*').map do |f|
46
+ Dataset.from_file(f)
47
+ end
48
+ end
49
+
50
+ def find id
51
+ Dataset.from_file("db/datasets/#{id}")
52
+ end
53
+
54
+ def from_file f
55
+ d = Dataset.from_xml(File.read(f))
56
+
57
+ d.file = f
58
+
59
+ d
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,10 @@
1
+ # This is a sample config file that does not have multiple solr instances. You will also need to be sure to
2
+ # edit the fedora.yml file to match the solr URL for active-fedora.
3
+ development:
4
+ url: http://localhost:8983/solr/development
5
+ test: &TEST
6
+ url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/solr/test" %>
7
+ cucumber:
8
+ <<: *TEST
9
+ production:
10
+ url: http://your.production.server:8080/bl_solr/core0
data/tutorial.thor ADDED
@@ -0,0 +1,493 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require 'thor/group'
6
+ require 'rails/generators/actions'
7
+ require 'active_support/core_ext/array/extract_options'
8
+
9
+ $base_templates_path = File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
10
+
11
+ class HydraTutorialApp < Thor::Group
12
+ class_option :quick, :default => false
13
+
14
+ def welcome
15
+ $quick = options[:quick]
16
+ say %Q{
17
+ Welcome to this Hydra tutorial. We're going to go through some steps to
18
+ set up a working Hydra head. We'll build the application gradually, and give you
19
+ opportunities to stop and look around on the way.
20
+ }, Thor::Shell::Color::YELLOW
21
+
22
+ if $quick
23
+ say %Q{
24
+ We'll quickly build the application, give you some Hydra models, and send you on your way.
25
+ }, Thor::Shell::Color::YELLOW
26
+
27
+ else
28
+ say %Q{
29
+ We'll go through this tour slowly, starting by creating a pure Rails application,
30
+ and then introduce Hydra components. If you want to speed things along,
31
+ }, Thor::Shell::Color::YELLOW
32
+
33
+ exit unless yes? %Q{
34
+ If you want to speed things along, you should quit this tutorial (by saying 'no'),
35
+ and run it again with ./tutorial.thor --quick=yes.
36
+
37
+ Do you want to continue at this pace? (y/n) }, Thor::Shell::Color::GREEN
38
+ end
39
+ end
40
+
41
+ include Thor::Actions
42
+ include Rails::Generators::Actions
43
+
44
+ class Prerequisites < Thor::Group
45
+ class_option :quick, :default => false
46
+ include Thor::Actions
47
+ include Rails::Generators::Actions
48
+
49
+ def install_ruby
50
+ return if $quick
51
+ say %Q{
52
+ Obviously, if you can run this tutorial, you have already installed ruby.
53
+ }, Thor::Shell::Color::YELLOW
54
+
55
+
56
+ ruby_executable = run 'which ruby', :capture => true
57
+
58
+ say %Q{
59
+ You are running this using:
60
+ #{ruby_executable}
61
+ }, Thor::Shell::Color::YELLOW
62
+
63
+ if ruby_executable =~ /rvm/ or ruby_executable =~ /rbenv/ or ruby_executable =~ /home/ or ruby_Executable =~ /Users/
64
+ say %Q{
65
+ It looks like you're using rvm/rbenv/etc. (with a gemset?) We'll use this environment to build the application.
66
+ }, Thor::Shell::Color::YELLOW
67
+
68
+ else
69
+
70
+ say %Q{
71
+ We checked, and it looks like you might be using a system-wide ruby. We'd like to
72
+ suggest you use somethng like rvm [1], rbenv [2], etc to manage your ruby projects.
73
+
74
+ [1] http://rvm.io/
75
+ [2] https://github.com/sstephenson/rbenv/
76
+ }, Thor::Shell::Color::RED
77
+
78
+ exit unless yes? %Q{
79
+ You can continue and hope for the best, or go install one of these ruby managers, which may make your life easier.
80
+
81
+ Do you want to continue anyway? (y/n)
82
+ }, Thor::Shell::Color::GREEN
83
+ end
84
+
85
+ end
86
+
87
+ def install_bundler_and_rails
88
+ say %Q{
89
+ We're going to install some prerequisite gems in order to create our skeleton Rails application.
90
+ }, Thor::Shell::Color::YELLOW
91
+ run 'gem install bundler rails'
92
+ end
93
+
94
+ def new_rails_app
95
+ say %Q{
96
+ Now we'll create the application.
97
+ }, Thor::Shell::Color::YELLOW
98
+ run 'rails new hydra_tutorial_app'
99
+ run 'cd hydra_tutorial_app'
100
+
101
+ end
102
+
103
+ def out_of_the_box
104
+ return if $quick
105
+ say %Q{
106
+ Here's a chance to look around. You can see the structure of a Rails application.
107
+ ./app
108
+ ./config
109
+ ./lib
110
+ Gemfile
111
+ }
112
+
113
+ ask %Q{
114
+
115
+ Hit ENTER when you're ready to continue.
116
+ }, Thor::Shell::Color::GREEN
117
+ end
118
+
119
+ # and then clean up some cruft
120
+ def remove_public_index
121
+ say %Q{
122
+ We'll now remove the Rails directions from the application.
123
+ }, Thor::Shell::Color::YELLOW
124
+ inside 'hydra_tutorial_app' do
125
+ remove_file 'public/index.html'
126
+ end
127
+ end
128
+ end
129
+
130
+ class BuildingABasicRailsApp < Thor::Group
131
+ include Thor::Actions
132
+ include Rails::Generators::Actions
133
+
134
+ def self.source_paths
135
+ [File.join($base_templates_path, "building_a_basic_rails_app")]
136
+ end
137
+
138
+ def notes
139
+ say %Q{
140
+ We're going to build an application to track (simplified) datasets and their metadata.
141
+ }, Thor::Shell::Color::YELLOW
142
+ end
143
+
144
+ def as_if_this_was_just_a_rails_applications
145
+ say %Q{
146
+ If we wanted to build a Rails application to do this, we would add some models and controllers.
147
+
148
+ Rails can help "scaffold" the application for us.
149
+ }, Thor::Shell::Color::YELLOW
150
+
151
+ generate 'scaffold', 'dataset', 'title', 'author', 'url', 'description:text'
152
+ rake 'db:migrate'
153
+
154
+ say %Q{
155
+ This created a Dataset model (in ./app/models/dataset.rb), a controller, and some views.
156
+ }, Thor::Shell::Color::YELLOW
157
+
158
+ ask %Q{
159
+ Take a look around. Hit ENTER when you're ready to continue.
160
+ }, Thor::Shell::Color::GREEN
161
+ end
162
+
163
+ def but_maybe_we_want_to_store_our_metadata_as_xml
164
+ say %Q{
165
+ But it turns out a relational database is not a great place to store complex metadata objects,
166
+ with nesting, hierarchy, repetition, etc like we often fine in the digital library world. We'd
167
+ also like to store and manage our data in an exchangeable form rather than a custom-built database.
168
+
169
+ In our world, we often find ourselves dealing with XML-based metadata. Fortunately, we have a gem called 'om' that can help us deal with XML metadata.
170
+ To start using it, we need to add it to our Gemfile.
171
+ }, Thor::Shell::Color::YELLOW
172
+
173
+ gem 'om'
174
+ run 'bundle install'
175
+
176
+ say %Q{
177
+ Now let's adapt our Dataset model to use OM. First we'll add some code that allows us to persist our
178
+ OM Documents on the filesystem (in db/datasets) and then add a simple OM terminology as a drop-in
179
+ replacement for the ActiveRecord scaffold object.
180
+
181
+ }, Thor::Shell::Color::YELLOW
182
+
183
+ run "mkdir db/datasets"
184
+ copy_file "om_record.rb", "app/models/om_record.rb"
185
+
186
+ say %Q{
187
+ Press 'd' to see the difference between the Rails version and the OM version of Dataset.
188
+ }, Thor::Shell::Color::YELLOW
189
+
190
+ copy_file "dataset_simple_om.rb", "app/models/dataset.rb"
191
+
192
+ ask %Q{
193
+ Take a look around.
194
+
195
+ Hit ENTER when you're ready to continue.
196
+ }, Thor::Shell::Color::GREEN
197
+
198
+ end
199
+
200
+
201
+ def stop_using_the_filesystem
202
+ say %Q{
203
+ Storing the documents on the filesystem has worked so far, but what if we wanted to start
204
+ managing whole objects (instead of XML documents), version datastream, keep checksums...
205
+
206
+ We use Fedora [3], and ActiveFedora to work with data in our repository. We also use Solr to
207
+ index and provide searching, faceting, etc for our content. For now, you can just concentrate on
208
+ Fedora. We'll have a section on Solr and discovery interfaces later.
209
+
210
+ [3] http://fedora-commons.org
211
+ }, Thor::Shell::Color::YELLOW
212
+
213
+ say %Q{
214
+ Fedora runs as a java servlet inside a container like Tomcat or Jetty. Hydra provides a bundled
215
+ version of Fedora and Solr for testing and development.
216
+ }, Thor::Shell::Color::YELLOW
217
+
218
+ say %Q{
219
+ We'll download a copy now. It may take awhile.
220
+ }, Thor::Shell::Color::YELLOW
221
+ unless File.exists? '../jetty'
222
+ git :clone => 'git://github.com/projecthydra/hydra-jetty.git ../jetty'
223
+ end
224
+ run 'cp -R ../jetty jetty'
225
+ # run 'rake hydra:jetty:config'
226
+
227
+ say %Q{
228
+ Now we're configure it and start the application.
229
+ }, Thor::Shell::Color::YELLOW
230
+ rake 'hydra:jetty:config'
231
+
232
+ copy_file 'solr.yml', 'config/solr.yml'
233
+ copy_file 'fedora.yml', 'config/fedora.yml'
234
+
235
+ say %Q{
236
+ And we'll use jettywrapper to help start and stop the service.
237
+ }, Thor::Shell::Color::YELLOW
238
+
239
+ gem 'jettywrapper'
240
+ run 'bundle install'
241
+ rake 'jetty:start'
242
+
243
+ say %Q{
244
+ Take a look around. Jetty should be running on port 8983. You can see the Fedora server at
245
+
246
+ http://localhost:8983/fedora/
247
+
248
+ And a Solr index at
249
+
250
+ http://localhost:8983/solr/development/admin/
251
+ }, Thor::Shell::Color::YELLOW
252
+
253
+ ask %Q{
254
+ Hit ENTER when you're ready to continue.
255
+ }, Thor::Shell::Color::GREEN
256
+
257
+ end
258
+
259
+ def convert_our_model_to_activefedora
260
+ say %Q{
261
+ We'll update our Dataset object to use ActiveFedora.
262
+ }, Thor::Shell::Color::YELLOW
263
+
264
+ gem 'active-fedora'
265
+ run 'bundle install'
266
+ copy_file "dataset_af_om.rb", "app/models/dataset.rb"
267
+
268
+ say %Q{
269
+ You should be able to create new dataset objects and see them updated in Fedora.
270
+ }, Thor::Shell::Color::YELLOW
271
+
272
+ ask %Q{
273
+ Hit ENTER when you're ready to continue.
274
+ }, Thor::Shell::Color::GREEN
275
+ end
276
+ end
277
+
278
+ class Application < Thor::Group
279
+ include Thor::Actions
280
+ include Rails::Generators::Actions
281
+
282
+ def self.source_paths
283
+ [File.join($base_templates_path, "application")]
284
+ end
285
+
286
+ # here are some gems that help
287
+ def add_blacklight_and_hydra
288
+ say %Q{
289
+ Eventually, common patterns get packaged up into new gems.
290
+ }, Thor::Shell::Color::YELLOW
291
+
292
+ say %Q{
293
+ We use blacklight to provide a search interface.
294
+ }, Thor::Shell::Color::YELLOW
295
+
296
+ gem 'blacklight'
297
+ run 'bundle install'
298
+ generate 'blacklight', '--devise'
299
+
300
+ say %Q{
301
+ And hydra-head bundles OM, ActiveFedora, etc for us. It also includes things like
302
+ gated discovery and permissions (through hydra-access-controls).
303
+ }, Thor::Shell::Color::YELLOW
304
+
305
+ gem 'hydra-head', "~> 4.1"
306
+ run 'bundle install'
307
+ generate 'hydra:head', 'User'
308
+ end
309
+
310
+ def rake_db_migrate
311
+ rake 'db:migrate'
312
+ rake 'db:test:prepare'
313
+ end
314
+
315
+ def install_hydra_jetty
316
+ if $quick # if we were in quick mode, we skipped this step from before..
317
+ say %Q{
318
+ Fedora runs as a java servlet inside a container like Tomcat or Jetty. Hydra provides a bundled
319
+ version of Fedora and Solr for testing and development.
320
+ }, Thor::Shell::Color::YELLOW
321
+
322
+ say %Q{
323
+ We'll download a copy now. It may take awhile.
324
+ }, Thor::Shell::Color::YELLOW
325
+
326
+ unless File.exists? '../jetty'
327
+ git :clone => 'git://github.com/projecthydra/hydra-jetty.git ../jetty'
328
+ end
329
+ run 'cp -R ../jetty jetty'
330
+
331
+ rake 'hydra:jetty:config'
332
+
333
+ gem 'jettywrapper'
334
+ run 'bundle install'
335
+ rake 'jetty:start'
336
+ else
337
+
338
+ rake 'jetty:stop'
339
+ rake 'hydra:jetty:config'
340
+ rake 'jetty:start'
341
+ end
342
+
343
+ end
344
+
345
+ def fixup_ui
346
+ remove_file 'app/assets/stylesheets/datasets.css.scss'
347
+ remove_file 'app/assets/stylesheets/scaffolds.css.scss'
348
+ end
349
+
350
+ def fixup_datasets
351
+ return if $quick
352
+ say %Q{
353
+ We need to make a couple of tweaks to our Dataset model and controller in order
354
+ to make it a Hydra-compliant object.
355
+
356
+ Because Hydra enforces access controls in the discovery layer (and, by default, no one
357
+ has access), we need to teach our model and controller about the Hydra rightsMetadata model
358
+ and have the controller tell the object who deposited it.
359
+ }, Thor::Shell::Color::YELLOW
360
+
361
+ copy_file "dataset_hydra_om.rb", "app/models/dataset.rb"
362
+
363
+ inject_into_class "app/controllers/datasets_controller.rb", 'DatasetsController' do
364
+ " include Hydra::AssetsControllerHelper\n"
365
+ end
366
+
367
+ insert_into_file "app/controllers/datasets_controller.rb", :after => "@dataset = Dataset.new(params[:dataset])\n" do
368
+ " apply_depositor_metadata(@dataset)\n"
369
+ end
370
+ end
371
+
372
+ def lets_make_a_better_terminology
373
+ say %Q{
374
+ So far, we've been working with a made-up XML schema, however, in the real world, we're probably
375
+ dealing with more complex data in well-known standards like MODS.
376
+
377
+ Now we'll replace our custom schema with a basic MODS schema.
378
+ }, Thor::Shell::Color::YELLOW
379
+ copy_file "mods_desc_metadata.rb", "app/models/mods_desc_metadata.rb"
380
+ copy_file "dataset_hydra_mods_om.rb", "app/models/dataset.rb"
381
+ end
382
+
383
+ end
384
+
385
+ class MakeItNice < Thor::Group
386
+ include Thor::Actions
387
+ include Rails::Generators::Actions
388
+
389
+ def self.source_paths
390
+ [File.join($base_templates_path, "make_it_nice")]
391
+ end
392
+
393
+ # now we want our app to do stuff.. so lets enhance our old models
394
+
395
+ def some_better_views
396
+
397
+ end
398
+
399
+ def file_uploads
400
+
401
+ end
402
+
403
+
404
+ def sprinkle_some_css
405
+
406
+ end
407
+
408
+ end
409
+
410
+ class Tests < Thor::Group
411
+ include Thor::Actions
412
+ include Rails::Generators::Actions
413
+
414
+ # and write some tests
415
+
416
+ end
417
+
418
+ class InitialSteps < Thor::Group
419
+ include Thor::Actions
420
+ include Rails::Generators::Actions
421
+
422
+ # here are some steps you can do to get started
423
+ def create_a_user_account
424
+
425
+ end
426
+
427
+ def explore_the_application
428
+ run 'rails s'
429
+
430
+ end
431
+ end
432
+
433
+
434
+ class Cleanup < Thor::Group
435
+ include Thor::Actions
436
+ include Rails::Generators::Actions
437
+
438
+ # and write some tests
439
+ #
440
+ def stop_jetty
441
+ rake 'jetty:stop'
442
+ end
443
+
444
+ end
445
+
446
+ def prerequisites
447
+ Prerequisites.start
448
+ end
449
+
450
+ def building_a_basic_rails_app
451
+ return if $quick
452
+
453
+ inside 'hydra_tutorial_app' do
454
+ BuildingABasicRailsApp.start
455
+ end
456
+ end
457
+
458
+ def application
459
+ inside 'hydra_tutorial_app' do
460
+ Application.start
461
+ end
462
+ end
463
+
464
+ def make_it_nice
465
+ return if $quick
466
+ inside 'hydra_tutorial_app' do
467
+ MakeItNice.start
468
+ end
469
+ end
470
+
471
+ def tests
472
+ inside 'hydra_tutorial_app' do
473
+ Tests.start
474
+ end
475
+ end
476
+
477
+ def initial_steps
478
+ return if $quick
479
+ inside 'hydra_tutorial_app' do
480
+ InitialSteps.start
481
+ end
482
+ end
483
+
484
+ def cleanup
485
+ yes? "All Done?", Thor::Shell::Color::GREEN
486
+ inside 'hydra_tutorial_app' do
487
+ Cleanup.start
488
+ end
489
+ end
490
+
491
+ end
492
+
493
+ HydraTutorialApp.start