tennpipes-init 3.6.6
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +163 -0
- data/Rakefile +1 -0
- data/bin/tennpipes-init +16 -0
- data/lib/tennpipes-init.rb +73 -0
- data/lib/tennpipes-init/command.rb +18 -0
- data/lib/tennpipes-init/generators/actions.rb +630 -0
- data/lib/tennpipes-init/generators/app.rb +75 -0
- data/lib/tennpipes-init/generators/app/app.rb.tt +72 -0
- data/lib/tennpipes-init/generators/app/app.rb.tt~ +72 -0
- data/lib/tennpipes-init/generators/cli.rb +57 -0
- data/lib/tennpipes-init/generators/component.rb +73 -0
- data/lib/tennpipes-init/generators/components/actions.rb +208 -0
- data/lib/tennpipes-init/generators/components/mocks/mocha.rb +10 -0
- data/lib/tennpipes-init/generators/components/mocks/rr.rb +13 -0
- data/lib/tennpipes-init/generators/components/orms/activerecord.rb +201 -0
- data/lib/tennpipes-init/generators/components/orms/couchrest.rb +55 -0
- data/lib/tennpipes-init/generators/components/orms/datamapper.rb +140 -0
- data/lib/tennpipes-init/generators/components/orms/dynamoid.rb +67 -0
- data/lib/tennpipes-init/generators/components/orms/minirecord.rb +165 -0
- data/lib/tennpipes-init/generators/components/orms/mongoid.rb +113 -0
- data/lib/tennpipes-init/generators/components/orms/mongomapper.rb +43 -0
- data/lib/tennpipes-init/generators/components/orms/mongomatic.rb +84 -0
- data/lib/tennpipes-init/generators/components/orms/ohm.rb +65 -0
- data/lib/tennpipes-init/generators/components/orms/ripple.rb +75 -0
- data/lib/tennpipes-init/generators/components/orms/sequel.rb +99 -0
- data/lib/tennpipes-init/generators/components/renderers/erb.rb +3 -0
- data/lib/tennpipes-init/generators/components/renderers/haml.rb +3 -0
- data/lib/tennpipes-init/generators/components/renderers/liquid.rb +4 -0
- data/lib/tennpipes-init/generators/components/renderers/slim.rb +3 -0
- data/lib/tennpipes-init/generators/components/scripts/dojo.rb +10 -0
- data/lib/tennpipes-init/generators/components/scripts/extcore.rb +10 -0
- data/lib/tennpipes-init/generators/components/scripts/jquery.rb +10 -0
- data/lib/tennpipes-init/generators/components/scripts/mootools.rb +10 -0
- data/lib/tennpipes-init/generators/components/scripts/prototype.rb +12 -0
- data/lib/tennpipes-init/generators/components/scripts/rightjs.rb +10 -0
- data/lib/tennpipes-init/generators/components/stylesheets/compass.rb +39 -0
- data/lib/tennpipes-init/generators/components/stylesheets/compass/application.scss +43 -0
- data/lib/tennpipes-init/generators/components/stylesheets/compass/partials/_base.scss +12 -0
- data/lib/tennpipes-init/generators/components/stylesheets/less.rb +25 -0
- data/lib/tennpipes-init/generators/components/stylesheets/sass.rb +15 -0
- data/lib/tennpipes-init/generators/components/stylesheets/scss.rb +16 -0
- data/lib/tennpipes-init/generators/components/tests/bacon.rb +103 -0
- data/lib/tennpipes-init/generators/components/tests/cucumber.rb +86 -0
- data/lib/tennpipes-init/generators/components/tests/minitest.rb +110 -0
- data/lib/tennpipes-init/generators/components/tests/riot.rb +117 -0
- data/lib/tennpipes-init/generators/components/tests/rspec.rb +111 -0
- data/lib/tennpipes-init/generators/components/tests/shoulda.rb +114 -0
- data/lib/tennpipes-init/generators/components/tests/steak.rb +114 -0
- data/lib/tennpipes-init/generators/controller.rb +77 -0
- data/lib/tennpipes-init/generators/helper.rb +50 -0
- data/lib/tennpipes-init/generators/mailer.rb +52 -0
- data/lib/tennpipes-init/generators/migration.rb +43 -0
- data/lib/tennpipes-init/generators/model.rb +113 -0
- data/lib/tennpipes-init/generators/plugin.rb +67 -0
- data/lib/tennpipes-init/generators/project.rb +160 -0
- data/lib/tennpipes-init/generators/project/config.ru +9 -0
- data/lib/tennpipes-init/generators/project/config/apps.rb.tt +35 -0
- data/lib/tennpipes-init/generators/project/config/boot.rb +49 -0
- data/lib/tennpipes-init/generators/project/public/favicon.ico +0 -0
- data/lib/tennpipes-init/generators/project/public/images/booking.com.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/causes.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/ennkeypee_bg.jpg +0 -0
- data/lib/tennpipes-init/generators/project/public/images/ennkeypee_bluelogo.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/ennkeypee_bluelogo.svg +68 -0
- data/lib/tennpipes-init/generators/project/public/images/ennkeypee_whitelogo.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/ennkeypee_whitelogo.svg +65 -0
- data/lib/tennpipes-init/generators/project/public/images/forever21.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/icons/foundation-icons.eot +0 -0
- data/lib/tennpipes-init/generators/project/public/images/icons/foundation-icons.svg +970 -0
- data/lib/tennpipes-init/generators/project/public/images/icons/foundation-icons.ttf +0 -0
- data/lib/tennpipes-init/generators/project/public/images/icons/foundation-icons.woff +0 -0
- data/lib/tennpipes-init/generators/project/public/images/icons/tennpipes-icons.css +598 -0
- data/lib/tennpipes-init/generators/project/public/images/image1.jpg +0 -0
- data/lib/tennpipes-init/generators/project/public/images/image11.jpg +0 -0
- data/lib/tennpipes-init/generators/project/public/images/image2.jpg +0 -0
- data/lib/tennpipes-init/generators/project/public/images/image3.jpg +0 -0
- data/lib/tennpipes-init/generators/project/public/images/intuit.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/krispykreme.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/README.md +302 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/bower.json +4 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/composer.json +34 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/gulpfile.js +92 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/holder.js +1920 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/holder.min.js +12 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/package.json +46 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/holder.js +1411 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/lib/augment.js +27 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/lib/ondomready.js +155 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/lib/polyfills.js +177 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/scenegraph.js +101 -0
- data/lib/tennpipes-init/generators/project/public/images/placeholders/src/utils.js +129 -0
- data/lib/tennpipes-init/generators/project/public/images/priceline.com.png +0 -0
- data/lib/tennpipes-init/generators/project/public/images/stripe.png +0 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes.min.js +6081 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.abide.js +340 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.accordion.js +67 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.alert.js +43 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.clearing.js +556 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.dropdown.js +448 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.equalizer.js +77 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.interchange.js +354 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.joyride.js +932 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.js +703 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.magellan.js +203 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.offcanvas.js +152 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.orbit.js +476 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.reveal.js +471 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.slider.js +263 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.tab.js +237 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.tooltip.js +307 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/tennpipes/tennpipes.topbar.js +452 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/vendor/fastclick.js +8 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/vendor/jquery.cookie.js +8 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/vendor/jquery.js +26 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/vendor/modernizr.js +8 -0
- data/lib/tennpipes-init/generators/project/public/javascripts/vendor/placeholder.js +2 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/app.css~ +178 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/app1.css~ +177 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/ennkeypee.css +214 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/ennkeypee.css~ +214 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/normalize.css +427 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/tennpipes.css +6201 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/tennpipes.css~ +6201 -0
- data/lib/tennpipes-init/generators/project/public/stylesheets/tennpipes.min.css +1 -0
- data/lib/tennpipes-init/generators/runner.rb +139 -0
- data/lib/tennpipes-init/generators/task.rb +45 -0
- data/lib/tennpipes-init/generators/templates/Gemfile.tt +32 -0
- data/lib/tennpipes-init/generators/templates/Rakefile.tt +8 -0
- data/lib/tennpipes-init/generators/templates/controller.rb.tt +22 -0
- data/lib/tennpipes-init/generators/templates/gem/README.md.tt +29 -0
- data/lib/tennpipes-init/generators/templates/gem/gemspec.tt +19 -0
- data/lib/tennpipes-init/generators/templates/gem/lib/libname.tt +6 -0
- data/lib/tennpipes-init/generators/templates/gem/lib/libname/version.tt +3 -0
- data/lib/tennpipes-init/generators/templates/helper.rb.tt +13 -0
- data/lib/tennpipes-init/generators/templates/initializer.rb.tt +5 -0
- data/lib/tennpipes-init/generators/templates/mailer.rb.tt +54 -0
- data/lib/tennpipes-init/generators/templates/project_bin.tt +14 -0
- data/lib/tennpipes-init/generators/templates/task.rb.tt +7 -0
- data/lib/tennpipes-init/tennpipes-tasks/activerecord.rb +377 -0
- data/lib/tennpipes-init/tennpipes-tasks/database.rb +12 -0
- data/lib/tennpipes-init/tennpipes-tasks/datamapper.rb +94 -0
- data/lib/tennpipes-init/tennpipes-tasks/minirecord.rb +19 -0
- data/lib/tennpipes-init/tennpipes-tasks/mongoid.rb +215 -0
- data/lib/tennpipes-init/tennpipes-tasks/mongomapper.rb +55 -0
- data/lib/tennpipes-init/tennpipes-tasks/sequel.rb +85 -0
- data/lib/tennpipes-init/tennpipes-tasks/sql-helpers.rb +72 -0
- data/test/fixtures/admin_template.rb +7 -0
- data/test/fixtures/example_template.rb +15 -0
- data/test/fixtures/git_template.rb +4 -0
- data/test/fixtures/plugin_template.rb +13 -0
- data/test/fixtures/rake_template.rb +9 -0
- data/test/helper.rb +103 -0
- data/test/test_app_generator.rb +142 -0
- data/test/test_cli.rb +27 -0
- data/test/test_component_generator.rb +98 -0
- data/test/test_controller_generator.rb +272 -0
- data/test/test_generator.rb +13 -0
- data/test/test_helper_generator.rb +133 -0
- data/test/test_mailer_generator.rb +69 -0
- data/test/test_migration_generator.rb +222 -0
- data/test/test_model_generator.rb +553 -0
- data/test/test_plugin_generator.rb +152 -0
- data/test/test_project_generator.rb +757 -0
- data/test/test_task_generator.rb +53 -0
- metadata +285 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: c7ceae2eea5dffe4f6251675777b082af7ff26fd
|
|
4
|
+
data.tar.gz: 30e12698ffc27d64b3e719a0444be4c4e47597aa
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 39f426e683fb4166564fb2297ddbf4a1a93d0fdd4917f1a53a10686fc3c1c89cfd22779aa5561c2a21a4935566761a0be4dc564b1e030f373db0bd091e1f47b5
|
|
7
|
+
data.tar.gz: 2b208aec0720a1ee5d24df9591261882cec35ddd8ae77f5cddc49f37a3ea3aff59e3bedf8227be1f5519307265605cb393d373f0c7ff5122d994436b56aaf281
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2011 Tennpipes
|
|
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.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
= Agnostic Application Generators (tennpipes-init)
|
|
2
|
+
|
|
3
|
+
=== Overview
|
|
4
|
+
|
|
5
|
+
Tennpipes comes preloaded with flexible code generators powered in part by the excellent Thor gem
|
|
6
|
+
(incidentally also used in the Rails 3 generators). These generators are intended to allow for easy code generation
|
|
7
|
+
both in creating new applications and building on existing ones. The generators have been built to be as library agnostic
|
|
8
|
+
as possible, supporting a myriad of test frameworks, js libraries, mocking libraries, etc.
|
|
9
|
+
|
|
10
|
+
See the guide for {Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators] for a
|
|
11
|
+
more in-depth look at the system.
|
|
12
|
+
|
|
13
|
+
=== Project Generator
|
|
14
|
+
|
|
15
|
+
Tennpipes provides generator support for quickly creating new Tennpipes applications. This provides many benefits
|
|
16
|
+
such as constructing the recommended Tennpipes application structure, auto-generating a Gemfile listing
|
|
17
|
+
all starting dependencies and guidelines provided within the generated files to help orient a new user
|
|
18
|
+
to using Tennpipes.
|
|
19
|
+
|
|
20
|
+
One important feature of the generators is that they were built from the ground up to support a wide variety
|
|
21
|
+
of tools, libraries and gems for use within your tennpipes application.
|
|
22
|
+
|
|
23
|
+
The simplest possible command to generate a base application would be:
|
|
24
|
+
|
|
25
|
+
$ tennpipes-init project demo_project
|
|
26
|
+
|
|
27
|
+
This would construct a Tennpipes application DemoApp (which extends from Tennpipes::Application)
|
|
28
|
+
inside the folder 'demo_project' at our current path. Inside the application there would be configuration and
|
|
29
|
+
setup performed for the default components.
|
|
30
|
+
|
|
31
|
+
You can define specific components to be used:
|
|
32
|
+
|
|
33
|
+
$ tennpipes-init project demo_project -t rspec -r haml -m rr -s jquery -d datamapper
|
|
34
|
+
|
|
35
|
+
You can also instruct the generator to skip a certain component to avoid using one at all (or to use your own):
|
|
36
|
+
|
|
37
|
+
$ tennpipes-init project demo_project --test none --renderer none
|
|
38
|
+
|
|
39
|
+
The available components and their default options are listed below:
|
|
40
|
+
|
|
41
|
+
test:: none (default), bacon, shoulda, cucumber, riot, rspec, minitest, steak
|
|
42
|
+
renderer:: slim (default), erb, erubis, liquid, haml
|
|
43
|
+
stylesheet:: none (default), less, compass, sass, scss
|
|
44
|
+
mock:: none (default), mocha, rr
|
|
45
|
+
script:: none (default), jquery, prototype, mootools, rightjs, extcore, dojo
|
|
46
|
+
orm:: none (default), datamapper, mongomapper, mongoid, activerecord, minirecord, sequel, couchrest, ohm, mongomatic, ripple, dynamoid
|
|
47
|
+
|
|
48
|
+
In addition, you can generate projects based on existing templates:
|
|
49
|
+
|
|
50
|
+
$ tennpipes-init project demo_project --template sampleblog
|
|
51
|
+
|
|
52
|
+
To learn more about the project generator, check out the guide to
|
|
53
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
54
|
+
|
|
55
|
+
=== Plugin System
|
|
56
|
+
|
|
57
|
+
Tennpipes provides support for plugins to be executed within your application. For example:
|
|
58
|
+
|
|
59
|
+
$ tennpipes-init plugin hoptoad
|
|
60
|
+
|
|
61
|
+
would install the hoptoad middleware into your application automatically.
|
|
62
|
+
|
|
63
|
+
To learn more about the plugin system, check out the guide to
|
|
64
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
65
|
+
|
|
66
|
+
=== Sub App Generator
|
|
67
|
+
|
|
68
|
+
Unlike other ruby frameworks Tennpipes is principally designed for mounting multiple apps at the same time.
|
|
69
|
+
|
|
70
|
+
First you need to create a project
|
|
71
|
+
|
|
72
|
+
$ tennpipes-init project demo_project
|
|
73
|
+
$ cd demo_project
|
|
74
|
+
|
|
75
|
+
Now you are in demo_project and you can create your apps:
|
|
76
|
+
|
|
77
|
+
$ tennpipes-init app one
|
|
78
|
+
$ tennpipes-init app two
|
|
79
|
+
|
|
80
|
+
By default these apps are mounted under:
|
|
81
|
+
|
|
82
|
+
* /one
|
|
83
|
+
* /two
|
|
84
|
+
|
|
85
|
+
but you can edit config/apps.rb and change it.
|
|
86
|
+
|
|
87
|
+
To learn more about the subapp generator, check out the guide to
|
|
88
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
89
|
+
|
|
90
|
+
=== Model Generator
|
|
91
|
+
|
|
92
|
+
Tennpipes provides generator support for quickly creating new models within your Tennpipes application. Note that
|
|
93
|
+
the models (and migrations) generated are specifically tailored towards the ORM component and testing framework
|
|
94
|
+
chosen during application generation.
|
|
95
|
+
|
|
96
|
+
Very important to note that model generators are intended primarily to work within applications
|
|
97
|
+
created through the Tennpipes application generator and that follow Tennpipes conventions. Using model generators
|
|
98
|
+
within an existing application not generated by Tennpipes will likely not work as expected.
|
|
99
|
+
|
|
100
|
+
Using the model generator is as simple as:
|
|
101
|
+
|
|
102
|
+
$ tennpipes-init model User
|
|
103
|
+
|
|
104
|
+
You can also specify desired fields to be contained within your User model:
|
|
105
|
+
|
|
106
|
+
$ tennpipes-init model User name:string age:integer email:string
|
|
107
|
+
|
|
108
|
+
To learn more about the model generator, check out the guide to
|
|
109
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
110
|
+
|
|
111
|
+
=== Migration Generator
|
|
112
|
+
|
|
113
|
+
Tennpipes provides generator for quickly generating new migrations to change or manipulate the database schema.
|
|
114
|
+
These migrations generated will be tailored towards the ORM chosen when generating the application.
|
|
115
|
+
|
|
116
|
+
Very important to note that migration generators are intended primarily to work within applications
|
|
117
|
+
created through the Tennpipes application generator and that follow Tennpipes conventions. Using migration generators
|
|
118
|
+
within an existing application not generated by Tennpipes will likely not work as expected.
|
|
119
|
+
|
|
120
|
+
Using the migration generator is as simple as:
|
|
121
|
+
|
|
122
|
+
$ tennpipes-init migration AddFieldsToUsers
|
|
123
|
+
$ tennpipes-init migration RemoveFieldsFromUsers
|
|
124
|
+
|
|
125
|
+
To learn more about the migration generator, check out the guide to
|
|
126
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
127
|
+
|
|
128
|
+
=== Controller Generator
|
|
129
|
+
|
|
130
|
+
Tennpipes provides generator support for quickly creating new controllers within your Tennpipes application. Note that
|
|
131
|
+
the controller tests are generated specifically tailored towards the testing framework chosen
|
|
132
|
+
during application generation.
|
|
133
|
+
|
|
134
|
+
Very important to note that controller generators are intended primarily to work within applications
|
|
135
|
+
created through the Tennpipes application generator and that follow Tennpipes conventions.
|
|
136
|
+
|
|
137
|
+
Using the controller generator is as simple as:
|
|
138
|
+
|
|
139
|
+
$ tennpipes-init controller Admin
|
|
140
|
+
|
|
141
|
+
You can also specify desired actions to be added to your controller:
|
|
142
|
+
|
|
143
|
+
$ tennpipes-init controller Admin get:index get:new post:create
|
|
144
|
+
|
|
145
|
+
To learn more about the controller generator, check out the guide to
|
|
146
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
147
|
+
|
|
148
|
+
=== Mailer Generator
|
|
149
|
+
|
|
150
|
+
Tennpipes provides generator support for quickly creating new mailers within your Tennpipes application.
|
|
151
|
+
Very important to note that mailer generators are intended primarily to work within applications
|
|
152
|
+
created through the Tennpipes application generator and that follow Tennpipes conventions.
|
|
153
|
+
|
|
154
|
+
Using the mailer generator is as simple as:
|
|
155
|
+
|
|
156
|
+
$ tennpipes-init mailer UserNotifier
|
|
157
|
+
|
|
158
|
+
To learn more about the mailer generator, check out the guide to
|
|
159
|
+
{Tennpipes Generators}[http://www.tennpipesrb.com/guides/generators].
|
|
160
|
+
|
|
161
|
+
== Copyright
|
|
162
|
+
|
|
163
|
+
Copyright (c) 2011-2013 Tennpipes. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper')
|
data/bin/tennpipes-init
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rubygems' unless defined?(Gem) # Useful only on --dev mode
|
|
3
|
+
require 'bundler/setup' if %w(Gemfile .components).all? { |f| File.exist?(f) }
|
|
4
|
+
|
|
5
|
+
tennpipes_gen_path = File.expand_path('../../lib', __FILE__)
|
|
6
|
+
$:.unshift(tennpipes_gen_path) if File.directory?(tennpipes_gen_path) && !$:.include?(tennpipes_gen_path)
|
|
7
|
+
|
|
8
|
+
# We try to load the vendored tennpipes-base if exist (useful also for --dev mode)
|
|
9
|
+
tennpipes_core_path = File.expand_path('../../../tennpipes-base/lib', __FILE__)
|
|
10
|
+
$:.unshift(tennpipes_core_path) if File.directory?(tennpipes_core_path) && !$:.include?(tennpipes_core_path)
|
|
11
|
+
|
|
12
|
+
require 'tennpipes-init'
|
|
13
|
+
require 'tennpipes-init/generators/cli'
|
|
14
|
+
|
|
15
|
+
# We need our config boot because we need to load registered generators so:
|
|
16
|
+
Tennpipes::Generators::Cli.start(ARGV)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'tennpipes-base/tasks'
|
|
2
|
+
require 'tennpipes-init/command'
|
|
3
|
+
require 'active_support/ordered_hash'
|
|
4
|
+
|
|
5
|
+
module Tennpipes
|
|
6
|
+
##
|
|
7
|
+
# This module it's used for register generators.
|
|
8
|
+
#
|
|
9
|
+
# Can be useful for 3rd party generators:
|
|
10
|
+
#
|
|
11
|
+
# # custom_generator.rb
|
|
12
|
+
# class CustomGenerator < Thor::Group
|
|
13
|
+
# Tennpipes::Generators.add_generator(:custom_generator, self)
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# Now for handle generators in tennpipes you need to add it to into +load_paths+.
|
|
17
|
+
#
|
|
18
|
+
# Tennpipes::Generators.load_paths << "custom_generator.rb"
|
|
19
|
+
#
|
|
20
|
+
module Generators
|
|
21
|
+
# Defines the absolute path to the tennpipes source folder.
|
|
22
|
+
DEV_PATH = File.expand_path("../../", File.dirname(__FILE__))
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
##
|
|
26
|
+
# Store our generators paths.
|
|
27
|
+
#
|
|
28
|
+
def load_paths
|
|
29
|
+
@_files ||= []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Return an ordered list of task with their class.
|
|
34
|
+
#
|
|
35
|
+
def mappings
|
|
36
|
+
@_mappings ||= ActiveSupport::OrderedHash.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Global add a new generator class to +tennpipes-init+.
|
|
41
|
+
#
|
|
42
|
+
# @param [Symbol] name
|
|
43
|
+
# Key name for generator mapping.
|
|
44
|
+
# @param [Class] klass
|
|
45
|
+
# Class of generator.
|
|
46
|
+
#
|
|
47
|
+
# @return [Hash] generator mappings
|
|
48
|
+
#
|
|
49
|
+
# @example
|
|
50
|
+
# Tennpipes::Generators.add_generator(:controller, Controller)
|
|
51
|
+
#
|
|
52
|
+
def add_generator(name, klass)
|
|
53
|
+
mappings[name] = klass
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Load Global Actions and Component Actions then all files in +load_path+.
|
|
58
|
+
#
|
|
59
|
+
def load_components!
|
|
60
|
+
require 'tennpipes-init/generators/actions'
|
|
61
|
+
require 'tennpipes-init/generators/components/actions'
|
|
62
|
+
require 'tennpipes-init/generators/runner'
|
|
63
|
+
load_paths.flatten.each { |file| require file }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Add our generators to Tennpipes::Generators.
|
|
70
|
+
Tennpipes::Generators.load_paths << Dir[File.dirname(__FILE__) + '/tennpipes-init/generators/{project,app,mailer,controller,helper,model,migration,plugin,component,task}.rb']
|
|
71
|
+
|
|
72
|
+
# Add our tasks to tennpipes-base.
|
|
73
|
+
Tennpipes::Tasks.files << Dir[File.dirname(__FILE__) + "/tennpipes-init/tennpipes-tasks/**/*.rb"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'tennpipes-base/command'
|
|
2
|
+
|
|
3
|
+
module Tennpipes
|
|
4
|
+
##
|
|
5
|
+
# This method return the correct location of tennpipes-init bin or
|
|
6
|
+
# exec it using Kernel#system with the given args.
|
|
7
|
+
#
|
|
8
|
+
# @param [Array<String>] args.
|
|
9
|
+
# Splat of arguments to pass to tennpipes-init.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# Tennpipes.bin_gen(:app, name.to_s, "-r=#{destination_root}")
|
|
13
|
+
#
|
|
14
|
+
def self.bin_gen(*args)
|
|
15
|
+
@_tennpipes_gen_bin ||= [Tennpipes.ruby_command, File.expand_path("../../../bin/tennpipes-init", __FILE__)]
|
|
16
|
+
system args.unshift(@_tennpipes_gen_bin).join(" ")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
module Tennpipes
|
|
4
|
+
module Generators
|
|
5
|
+
# Raised when an application does not have a resolved root path.
|
|
6
|
+
class AppRootNotFound < RuntimeError; end
|
|
7
|
+
##
|
|
8
|
+
# Default helper name for use in tiny app skeleton generator.
|
|
9
|
+
#
|
|
10
|
+
DEFAULT_HELPER_NAME = "Helper".freeze
|
|
11
|
+
##
|
|
12
|
+
# Common actions needed to support project and component generation.
|
|
13
|
+
#
|
|
14
|
+
module Actions
|
|
15
|
+
def self.included(base)
|
|
16
|
+
base.extend(ClassMethods)
|
|
17
|
+
end
|
|
18
|
+
##
|
|
19
|
+
# Avoids editing destination file if it does not exist.
|
|
20
|
+
#
|
|
21
|
+
def inject_into_file(destination, *args, &block)
|
|
22
|
+
destination_path = Pathname.new(destination).absolute? ? destination : destination_root(destination)
|
|
23
|
+
return unless File.exist?(destination_path)
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Performs the necessary generator for a given component choice.
|
|
29
|
+
#
|
|
30
|
+
# @param [Symbol] component
|
|
31
|
+
# The type of component module.
|
|
32
|
+
# @param [String] choice
|
|
33
|
+
# The name of the component module choice.
|
|
34
|
+
#
|
|
35
|
+
# @example
|
|
36
|
+
# execute_component_setup(:mock, 'rr')
|
|
37
|
+
#
|
|
38
|
+
def execute_component_setup(component, choice)
|
|
39
|
+
return true && say_status(:skipping, "#{component} component...") if choice.to_s == 'none'
|
|
40
|
+
say_status(:applying, "#{choice} (#{component})...")
|
|
41
|
+
apply_component_for(choice, component)
|
|
42
|
+
send("setup_#{component}") if respond_to?("setup_#{component}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Returns the related module for a given component and option.
|
|
47
|
+
#
|
|
48
|
+
# @param [String] choice
|
|
49
|
+
# The name of the component module.
|
|
50
|
+
# @param [Symbol] component
|
|
51
|
+
# The type of the component module.
|
|
52
|
+
#
|
|
53
|
+
# @example
|
|
54
|
+
# apply_component_for('rr', :mock)
|
|
55
|
+
#
|
|
56
|
+
def apply_component_for(choice, component)
|
|
57
|
+
# I need to override Thor#apply because for unknow reason :verbose => false break tasks.
|
|
58
|
+
path = File.expand_path(File.dirname(__FILE__) + "/components/#{component.to_s.pluralize}/#{choice}.rb")
|
|
59
|
+
say_status :apply, "#{component.to_s.pluralize}/#{choice}"
|
|
60
|
+
shell.padding += 1
|
|
61
|
+
instance_eval(File.read(path))
|
|
62
|
+
shell.padding -= 1
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Includes the component module for the given component and choice.
|
|
67
|
+
# It determines the choice using .components file.
|
|
68
|
+
#
|
|
69
|
+
# @param [Symbol] component
|
|
70
|
+
# The type of component module.
|
|
71
|
+
# @param [String] choice
|
|
72
|
+
# The name of the component module.
|
|
73
|
+
#
|
|
74
|
+
# @example
|
|
75
|
+
# include_component_module_for(:mock)
|
|
76
|
+
# include_component_module_for(:mock, 'rr')
|
|
77
|
+
#
|
|
78
|
+
def include_component_module_for(component, choice=nil)
|
|
79
|
+
choice = fetch_component_choice(component) unless choice
|
|
80
|
+
return false if choice.to_s == 'none'
|
|
81
|
+
apply_component_for(choice, component)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# Returns the component choice stored within the .component file of an application.
|
|
86
|
+
#
|
|
87
|
+
# @param [Symbol] component
|
|
88
|
+
# The type of component module.
|
|
89
|
+
#
|
|
90
|
+
# @return [String] Name of the component module.
|
|
91
|
+
#
|
|
92
|
+
# @example
|
|
93
|
+
# fetch_component_choice(:mock)
|
|
94
|
+
#
|
|
95
|
+
def fetch_component_choice(component)
|
|
96
|
+
retrieve_component_config(destination_root('.components'))[component]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# Set the component choice in the .component file of the application.
|
|
101
|
+
#
|
|
102
|
+
# @param [Symbol] key
|
|
103
|
+
# The type of component module.
|
|
104
|
+
# @param [Symbol] value
|
|
105
|
+
# The name of the component module.
|
|
106
|
+
#
|
|
107
|
+
# @return [Symbol] The name of the component module.
|
|
108
|
+
#
|
|
109
|
+
# @example
|
|
110
|
+
# store_component_choice(:renderer, :haml)
|
|
111
|
+
#
|
|
112
|
+
def store_component_choice(key, value)
|
|
113
|
+
path = destination_root('.components')
|
|
114
|
+
config = retrieve_component_config(path)
|
|
115
|
+
config[key] = value
|
|
116
|
+
create_file(path, :force => true) { config.to_yaml }
|
|
117
|
+
value
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##
|
|
121
|
+
# Loads the component config back into a hash.
|
|
122
|
+
#
|
|
123
|
+
# @param [String] target
|
|
124
|
+
# Path to component config file.
|
|
125
|
+
#
|
|
126
|
+
# @return [Hash] Loaded YAML file.
|
|
127
|
+
#
|
|
128
|
+
# @example
|
|
129
|
+
# retrieve_component_config(...)
|
|
130
|
+
# # => { :mock => 'rr', :test => 'riot', ... }
|
|
131
|
+
#
|
|
132
|
+
def retrieve_component_config(target)
|
|
133
|
+
YAML.load_file(target)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Prompts the user if necessary until a valid choice is returned for the component.
|
|
138
|
+
#
|
|
139
|
+
# @param [Symbol] component
|
|
140
|
+
# The type of component module.
|
|
141
|
+
#
|
|
142
|
+
# @return [String] Name of component if valid, otherwise ask for valid choice.
|
|
143
|
+
#
|
|
144
|
+
# @example
|
|
145
|
+
# resolve_valid_choice(:mock)
|
|
146
|
+
#
|
|
147
|
+
def resolve_valid_choice(component)
|
|
148
|
+
available_string = self.class.available_choices_for(component).join(", ")
|
|
149
|
+
choice = options[component]
|
|
150
|
+
until valid_choice?(component, choice)
|
|
151
|
+
say("Option for --#{component} '#{choice}' is not available.", :red)
|
|
152
|
+
choice = ask("Please enter a valid option for #{component} (#{available_string}):")
|
|
153
|
+
end
|
|
154
|
+
choice
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# Returns true if the option passed is a valid choice for component.
|
|
159
|
+
#
|
|
160
|
+
# @param [Symbol] component
|
|
161
|
+
# The type of component module.
|
|
162
|
+
# @param [String] choice
|
|
163
|
+
# The name of the component module.
|
|
164
|
+
#
|
|
165
|
+
# @return [Boolean] Boolean of whether the choice is valid.
|
|
166
|
+
#
|
|
167
|
+
# @example
|
|
168
|
+
# valid_choice?(:mock, 'rr')
|
|
169
|
+
#
|
|
170
|
+
def valid_choice?(component, choice)
|
|
171
|
+
choice.present? && self.class.available_choices_for(component).include?(choice.to_sym)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
##
|
|
175
|
+
# Creates a component_config file at the destination containing all component options.
|
|
176
|
+
# Content is a YAMLized version of a hash containing component name mapping to chosen value.
|
|
177
|
+
#
|
|
178
|
+
# @param [String] destination
|
|
179
|
+
# The file path to store the component config.
|
|
180
|
+
#
|
|
181
|
+
# @example
|
|
182
|
+
# store_component_config('/foo/bar')
|
|
183
|
+
#
|
|
184
|
+
def store_component_config(destination)
|
|
185
|
+
components = @_components || options
|
|
186
|
+
create_file(destination) do
|
|
187
|
+
self.class.component_types.inject({}) { |result, comp|
|
|
188
|
+
result[comp] = components[comp].to_s; result
|
|
189
|
+
}.to_yaml
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
##
|
|
194
|
+
# Returns the root for this Thor class (also aliased as destination root).
|
|
195
|
+
#
|
|
196
|
+
# @param [Array<String>] paths
|
|
197
|
+
# The relative path from destination root.
|
|
198
|
+
#
|
|
199
|
+
# @return [String] The full path
|
|
200
|
+
#
|
|
201
|
+
# @example
|
|
202
|
+
# destination_root('config/boot.rb')
|
|
203
|
+
#
|
|
204
|
+
def destination_root(*paths)
|
|
205
|
+
File.expand_path(File.join(@destination_stack.last, paths))
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
##
|
|
209
|
+
# Returns true if inside a Tennpipes application.
|
|
210
|
+
#
|
|
211
|
+
def in_app_root?
|
|
212
|
+
File.exist?(destination_root('config/boot.rb'))
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
##
|
|
216
|
+
# Returns true if constant name already exists.
|
|
217
|
+
#
|
|
218
|
+
def already_exists?(name, project_name = nil)
|
|
219
|
+
project_name = project_name ? (Object.const_get(project_name) rescue nil) : nil
|
|
220
|
+
Object.const_defined?(name) || (project_name && project_name.const_defined?(name))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
##
|
|
224
|
+
# Returns the field with an unacceptable name(for symbol) else returns nil.
|
|
225
|
+
#
|
|
226
|
+
# @param [Array<String>] fields
|
|
227
|
+
# Field names for generators.
|
|
228
|
+
#
|
|
229
|
+
# @return [Array<String>] array of invalid fields
|
|
230
|
+
#
|
|
231
|
+
# @example
|
|
232
|
+
# invalid_fields ['foo:bar', 'hello:world']
|
|
233
|
+
#
|
|
234
|
+
def invalid_fields(fields)
|
|
235
|
+
results = fields.select { |field| field.split(":").first =~ /\W/ }
|
|
236
|
+
results.empty? ? nil : results
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
##
|
|
240
|
+
# Apply default field types.
|
|
241
|
+
#
|
|
242
|
+
# @param [Array<String>] fields
|
|
243
|
+
# Field names for generators.
|
|
244
|
+
#
|
|
245
|
+
# @return [Array<String>] fields with default types
|
|
246
|
+
#
|
|
247
|
+
def apply_default_fields(fields)
|
|
248
|
+
fields.map! { |field| field =~ /:/ ? field : "#{field}:string" }
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Returns the namespace for the project.
|
|
252
|
+
#
|
|
253
|
+
# @param [String] app
|
|
254
|
+
# folder name of application.
|
|
255
|
+
#
|
|
256
|
+
# @return [String] namespace for application.
|
|
257
|
+
#
|
|
258
|
+
# @example
|
|
259
|
+
# fetch_project_name
|
|
260
|
+
#
|
|
261
|
+
def fetch_project_name(app='app')
|
|
262
|
+
app_path = destination_root(app, 'app.rb')
|
|
263
|
+
@project_name = fetch_component_choice(:namespace) if @project_name.empty?
|
|
264
|
+
@project_name ||= begin
|
|
265
|
+
say "Autodetecting project namespace using folder name.", :red
|
|
266
|
+
say ""
|
|
267
|
+
detected_namespace = File.basename(destination_root('.')).gsub(/\W/, '_').camelize
|
|
268
|
+
say(<<-WARNING, :red)
|
|
269
|
+
From v0.11.0 on, applications should have a `namespace` setting
|
|
270
|
+
in their .components file. Please include a line like the following
|
|
271
|
+
in your .components file:
|
|
272
|
+
WARNING
|
|
273
|
+
say "\t:namespace: #{detected_namespace}", :yellow
|
|
274
|
+
say ""
|
|
275
|
+
|
|
276
|
+
detected_namespace
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
##
|
|
281
|
+
# Returns the app_name for the application at root.
|
|
282
|
+
#
|
|
283
|
+
# @param [String] app
|
|
284
|
+
# folder name of application.
|
|
285
|
+
#
|
|
286
|
+
# @return [String] class name for application.
|
|
287
|
+
#
|
|
288
|
+
# @example
|
|
289
|
+
# fetch_app_name('subapp')
|
|
290
|
+
#
|
|
291
|
+
def fetch_app_name(app='app')
|
|
292
|
+
app_path = destination_root(app, 'app.rb')
|
|
293
|
+
@app_name ||= File.read(app_path).scan(/class\s(.*?)\s</).flatten[0]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
##
|
|
297
|
+
# Adds all the specified gems into the Gemfile for bundler.
|
|
298
|
+
#
|
|
299
|
+
# @param [Array<String>] gem_names
|
|
300
|
+
# Splat of gems to require in Gemfile.
|
|
301
|
+
# @param [Hash] options
|
|
302
|
+
# The options to pass to gem in Gemfile.
|
|
303
|
+
#
|
|
304
|
+
# @example
|
|
305
|
+
# require_dependencies('active_record')
|
|
306
|
+
# require_dependencies('mocha', 'bacon', :group => 'test')
|
|
307
|
+
# require_dependencies('json', :version => ">=1.2.3")
|
|
308
|
+
#
|
|
309
|
+
def require_dependencies(*gem_names)
|
|
310
|
+
options = gem_names.extract_options!
|
|
311
|
+
gem_names.reverse_each { |lib| insert_into_gemfile(lib, options) }
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
##
|
|
315
|
+
# Inserts a required gem into the Gemfile to add the bundler dependency.
|
|
316
|
+
#
|
|
317
|
+
# @param [String] name
|
|
318
|
+
# Name of gem to insert into Gemfile.
|
|
319
|
+
# @param [Hash] options
|
|
320
|
+
# Options to generate into Gemfile for gem.
|
|
321
|
+
#
|
|
322
|
+
# @example
|
|
323
|
+
# insert_into_gemfile(name)
|
|
324
|
+
# insert_into_gemfile(name, :group => 'test', :require => 'foo')
|
|
325
|
+
# insert_into_gemfile(name, :group => 'test', :version => ">1.2.3")
|
|
326
|
+
#
|
|
327
|
+
def insert_into_gemfile(name, options={})
|
|
328
|
+
after_pattern = options[:group] ? "#{options[:group].to_s.capitalize} requirements\n" : "Component requirements\n"
|
|
329
|
+
version = options.delete(:version)
|
|
330
|
+
gem_options = options.map { |k, v| k.to_s == 'require' && [true,false].include?(v) ? ":#{k} => #{v}" : ":#{k} => '#{v}'" }.join(", ")
|
|
331
|
+
write_option = gem_options.present? ? ", #{gem_options}" : ''
|
|
332
|
+
write_version = version.present? ? ", '#{version}'" : ''
|
|
333
|
+
include_text = "gem '#{name}'" << write_version << write_option << "\n"
|
|
334
|
+
inject_into_file('Gemfile', include_text, :after => after_pattern)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
##
|
|
338
|
+
# Inserts an hook before or after load in our boot.rb.
|
|
339
|
+
#
|
|
340
|
+
# @param [String] include_text
|
|
341
|
+
# Text to include into hooks in boot.rb.
|
|
342
|
+
# @param [Symbol] where
|
|
343
|
+
# method hook to call from Tennpipes, i.e :after_load, :before_load.
|
|
344
|
+
#
|
|
345
|
+
# @example
|
|
346
|
+
# insert_hook("DataMapper.finalize", :after_load)
|
|
347
|
+
#
|
|
348
|
+
def insert_hook(include_text, where)
|
|
349
|
+
inject_into_file('config/boot.rb', " #{include_text}\n", :after => "Tennpipes.#{where} do\n")
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
##
|
|
353
|
+
# Inserts a middleware inside app.rb.
|
|
354
|
+
#
|
|
355
|
+
# @param [String] include_text
|
|
356
|
+
# Text to include into hooks in boot.rb.
|
|
357
|
+
#
|
|
358
|
+
# @example
|
|
359
|
+
# insert_middleware(ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
|
360
|
+
#
|
|
361
|
+
def insert_middleware(include_text, app=nil)
|
|
362
|
+
name = app || (options[:name].present? ? @app_name.downcase : 'app')
|
|
363
|
+
inject_into_file("#{name}/app.rb", " use #{include_text}\n", :after => "Tennpipes::Application\n")
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
##
|
|
367
|
+
# Registers and creates initializer.
|
|
368
|
+
#
|
|
369
|
+
# @param [Symbol] name
|
|
370
|
+
# Name of the initializer.
|
|
371
|
+
# @param [String] data
|
|
372
|
+
# Text to generate into the initializer file.
|
|
373
|
+
#
|
|
374
|
+
# @example
|
|
375
|
+
# initializer(:test, "some stuff here")
|
|
376
|
+
# #=> generates 'lib/test_init.rb'
|
|
377
|
+
#
|
|
378
|
+
def initializer(name, data=nil)
|
|
379
|
+
@_init_name, @_init_data = name, data
|
|
380
|
+
register = data.present? ? " register #{name.to_s.underscore.camelize}Initializer\n" : " register #{name}\n"
|
|
381
|
+
inject_into_file destination_root("/app/app.rb"), register, :after => "Tennpipes::Application\n"
|
|
382
|
+
template "templates/initializer.rb.tt", destination_root("/lib/#{name}_initializer.rb") if data.present?
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
##
|
|
386
|
+
# Creates and inserts middleware.
|
|
387
|
+
# @param [Symbol, String] name
|
|
388
|
+
# Name of the middleware.
|
|
389
|
+
# @param [String] source
|
|
390
|
+
# Text to generate into the middleware file.
|
|
391
|
+
#
|
|
392
|
+
# @example
|
|
393
|
+
# middleware(:hello, "class Hello\nend")
|
|
394
|
+
# #=> generates 'lib/hello_middleware.rb'
|
|
395
|
+
#
|
|
396
|
+
def middleware(name, source)
|
|
397
|
+
create_file destination_root("lib/#{name}_middleware.rb"), source
|
|
398
|
+
insert_middleware name.to_s.underscore.camelize
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
##
|
|
402
|
+
# Insert the regired gem and add in boot.rb custom contribs.
|
|
403
|
+
#
|
|
404
|
+
# @param [String] contrib
|
|
405
|
+
# name of library from tennpipes-contrib
|
|
406
|
+
#
|
|
407
|
+
# @example
|
|
408
|
+
# require_contrib('auto_locale')
|
|
409
|
+
#
|
|
410
|
+
def require_contrib(contrib)
|
|
411
|
+
insert_into_gemfile 'tennpipes-contrib'
|
|
412
|
+
contrib = "require '" + File.join("tennpipes-contrib", contrib) + "'\n"
|
|
413
|
+
inject_into_file destination_root("/config/boot.rb"), contrib, :before => "\nTennpipes.load!"
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
##
|
|
417
|
+
# Return true if our project has test component.
|
|
418
|
+
#
|
|
419
|
+
def test?
|
|
420
|
+
fetch_component_choice(:test).to_s != 'none'
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
##
|
|
424
|
+
# Return true if we have a tiny skeleton.
|
|
425
|
+
#
|
|
426
|
+
def tiny?
|
|
427
|
+
File.exist?(destination_root('app/controllers.rb'))
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
##
|
|
431
|
+
# Run the bundler.
|
|
432
|
+
#
|
|
433
|
+
def run_bundler
|
|
434
|
+
say 'Bundling application dependencies using bundler...', :yellow
|
|
435
|
+
in_root { run 'bundle install' }
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
##
|
|
439
|
+
# Ask something to the user and receives a response.
|
|
440
|
+
#
|
|
441
|
+
# @param [String] statement
|
|
442
|
+
# String of statement to display for input.
|
|
443
|
+
# @param [String] default
|
|
444
|
+
# Default value for input.
|
|
445
|
+
# @param [String] color
|
|
446
|
+
# Name of color to display input.
|
|
447
|
+
#auto_locale
|
|
448
|
+
# @return [String] Input value
|
|
449
|
+
#
|
|
450
|
+
# @example
|
|
451
|
+
# ask("What is your name?")
|
|
452
|
+
# ask("Path for ruby", "/usr/local/bin/ruby") => "Path for ruby (leave blank for /usr/local/bin/ruby):"
|
|
453
|
+
#
|
|
454
|
+
def ask(statement, default=nil, color=nil)
|
|
455
|
+
default_text = default ? " (leave blank for #{default}):" : nil
|
|
456
|
+
say("#{statement}#{default_text} ", color)
|
|
457
|
+
result = $stdin.gets.strip
|
|
458
|
+
result.blank? ? default : result
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
##
|
|
462
|
+
# Raise SystemExit if the app does not exist.
|
|
463
|
+
#
|
|
464
|
+
# @param [String] app
|
|
465
|
+
# Directory name of application.
|
|
466
|
+
#
|
|
467
|
+
# @example
|
|
468
|
+
# check_app_existence 'app'
|
|
469
|
+
#
|
|
470
|
+
def check_app_existence(app)
|
|
471
|
+
unless File.exist?(destination_root(app))
|
|
472
|
+
say
|
|
473
|
+
say "================================================================="
|
|
474
|
+
say "Unable to locate '#{app.underscore.camelize}' application "
|
|
475
|
+
say "================================================================="
|
|
476
|
+
say
|
|
477
|
+
raise SystemExit
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
##
|
|
482
|
+
# Generates standard and tiny applications within a project.
|
|
483
|
+
#
|
|
484
|
+
# @param [String] app
|
|
485
|
+
# Name of application.
|
|
486
|
+
# @param [Boolean] tiny
|
|
487
|
+
# Boolean to generate a tiny structure.
|
|
488
|
+
#
|
|
489
|
+
# @example
|
|
490
|
+
# app_skeleton 'some_app'
|
|
491
|
+
# app_skeleton 'sub_app', true
|
|
492
|
+
#
|
|
493
|
+
def app_skeleton(app, tiny=false)
|
|
494
|
+
directory('app/', destination_root(app))
|
|
495
|
+
if tiny
|
|
496
|
+
template 'templates/controller.rb.tt', destination_root(app, 'controllers.rb')
|
|
497
|
+
@helper_name = DEFAULT_HELPER_NAME
|
|
498
|
+
template 'templates/helper.rb.tt', destination_root(app, 'helpers.rb')
|
|
499
|
+
@short_name = 'notifier'
|
|
500
|
+
template 'templates/mailer.rb.tt', destination_root(app, 'mailers.rb')
|
|
501
|
+
else
|
|
502
|
+
empty_directory destination_root(app, 'controllers')
|
|
503
|
+
empty_directory destination_root(app, 'helpers')
|
|
504
|
+
empty_directory destination_root(app, 'views')
|
|
505
|
+
empty_directory destination_root(app, 'views', 'layouts')
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
##
|
|
510
|
+
# Ensure that project name is valid, else raise an NameError.
|
|
511
|
+
#
|
|
512
|
+
# @param [String] name
|
|
513
|
+
# Name of project.
|
|
514
|
+
#
|
|
515
|
+
# @return [Exception] Exception with error message if not valid.
|
|
516
|
+
#
|
|
517
|
+
# @example
|
|
518
|
+
# valid_constant '1235Stuff'
|
|
519
|
+
# valid_constant '#Abc'
|
|
520
|
+
#
|
|
521
|
+
def valid_constant?(name)
|
|
522
|
+
if name =~ /^\d/
|
|
523
|
+
raise ::NameError, "Project name #{name} cannot start with numbers"
|
|
524
|
+
elsif name =~ /^\W/
|
|
525
|
+
raise ::NameError, "Project name #{name} cannot start with non-word character"
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
##
|
|
530
|
+
# Recognizes the path of application.
|
|
531
|
+
#
|
|
532
|
+
def recognize_path
|
|
533
|
+
options[:app] == '.' ? '/..' : '/../..'
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
##
|
|
537
|
+
# Creates an empty directory with .keep file
|
|
538
|
+
#
|
|
539
|
+
def empty_directory_with_keep_file(destination, config = {})
|
|
540
|
+
empty_directory(destination, config)
|
|
541
|
+
keep_file(destination)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
##
|
|
545
|
+
# Creates an empty .keep file
|
|
546
|
+
#
|
|
547
|
+
def keep_file(destination)
|
|
548
|
+
create_file("#{destination}/.keep")
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# Class methods for Thor generators to support the generators and component choices.
|
|
552
|
+
module ClassMethods
|
|
553
|
+
##
|
|
554
|
+
# Defines a class option to allow a component to be chosen and add to component type list.
|
|
555
|
+
# Also builds the available_choices hash of which component choices are supported.
|
|
556
|
+
#
|
|
557
|
+
# @param [Symbol] name
|
|
558
|
+
# Name of component.
|
|
559
|
+
# @param [String] caption
|
|
560
|
+
# Description of the component.
|
|
561
|
+
# @param [Hash] options
|
|
562
|
+
# Additional parameters for component choice.
|
|
563
|
+
#
|
|
564
|
+
# @example
|
|
565
|
+
# component_option :test, "Testing framework", :aliases => '-t', :choices => [:bacon, :shoulda]
|
|
566
|
+
#
|
|
567
|
+
def component_option(name, caption, options = {})
|
|
568
|
+
(@component_types ||= []) << name # TODO use ordered hash and combine with choices below
|
|
569
|
+
(@available_choices ||= Hash.new)[name] = options[:choices]
|
|
570
|
+
description = "The #{caption} component (#{options[:choices].join(', ')}, none)"
|
|
571
|
+
class_option name, :default => options[:default] || options[:choices].first, :aliases => options[:aliases], :desc => description
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
##
|
|
575
|
+
# Definitions for the available customizable components.
|
|
576
|
+
#
|
|
577
|
+
def defines_component_options(options = {})
|
|
578
|
+
[
|
|
579
|
+
[ :orm, 'database engine', { :aliases => '-d', :default => :none }],
|
|
580
|
+
[ :test, 'testing framework', { :aliases => '-t', :default => :none }],
|
|
581
|
+
[ :mock, 'mocking library', { :aliases => '-m', :default => :none }],
|
|
582
|
+
[ :script, 'javascript library', { :aliases => '-s', :default => :none }],
|
|
583
|
+
[ :renderer, 'template engine', { :aliases => '-e', :default => :none }],
|
|
584
|
+
[ :stylesheet, 'stylesheet engine', { :aliases => '-c', :default => :none }]
|
|
585
|
+
].each do |name, caption, opts|
|
|
586
|
+
opts[:default] = '' if options[:default] == false
|
|
587
|
+
component_option name, caption, opts.merge(:choices => Dir["#{File.dirname(__FILE__)}/components/#{name.to_s.pluralize}/*.rb"].map{|lib| File.basename(lib, '.rb').to_sym})
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
##
|
|
592
|
+
# Tell Tennpipes that for this Thor::Group it is a necessary task to run.
|
|
593
|
+
#
|
|
594
|
+
def require_arguments!
|
|
595
|
+
@require_arguments = true
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
##
|
|
599
|
+
# Return true if we need an arguments for our Thor::Group.
|
|
600
|
+
#
|
|
601
|
+
def require_arguments?
|
|
602
|
+
@require_arguments
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
##
|
|
606
|
+
# Returns the compiled list of component types which can be specified.
|
|
607
|
+
#
|
|
608
|
+
def component_types
|
|
609
|
+
@component_types
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
##
|
|
613
|
+
# Returns the list of available choices for the given component (including none).
|
|
614
|
+
#
|
|
615
|
+
# @param [Symbol] component
|
|
616
|
+
# The type of the component module.
|
|
617
|
+
#
|
|
618
|
+
# @return [Array<Symbol>] Array of component choices.
|
|
619
|
+
#
|
|
620
|
+
# @example
|
|
621
|
+
# available_choices_for :test
|
|
622
|
+
# => [:shoulda, :bacon, :riot, :minitest]
|
|
623
|
+
#
|
|
624
|
+
def available_choices_for(component)
|
|
625
|
+
@available_choices[component] + [:none]
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
end
|