katapult 0.2.0 → 0.3.0

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.
Files changed (143) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +9 -0
  5. data/README.md +122 -94
  6. data/Rakefile +13 -0
  7. data/bin/katapult +59 -25
  8. data/features/application_model.feature +55 -0
  9. data/features/authenticate.feature +88 -62
  10. data/features/basics.feature +64 -402
  11. data/features/binary.feature +56 -42
  12. data/features/configuration.feature +4 -4
  13. data/features/model.feature +21 -30
  14. data/features/navigation.feature +35 -48
  15. data/features/step_definitions/aruba_steps.rb +3 -0
  16. data/features/step_definitions/katapult_steps.rb +307 -8
  17. data/features/step_definitions/rails_steps.rb +74 -14
  18. data/features/step_definitions/test_steps.rb +5 -5
  19. data/features/step_definitions/version_steps.rb +22 -0
  20. data/features/support/env.rb +11 -3
  21. data/features/{wui.feature → web_ui.feature} +175 -148
  22. data/katapult.gemspec +8 -13
  23. data/lib/generators/katapult/app_model/app_model_generator.rb +12 -0
  24. data/lib/generators/katapult/app_model/templates/lib/katapult/application_model.rb +40 -0
  25. data/lib/generators/katapult/basics/basics_generator.rb +186 -51
  26. data/lib/generators/katapult/basics/templates/.browserslistrc +1 -0
  27. data/lib/generators/katapult/basics/templates/.gitignore +20 -21
  28. data/lib/generators/katapult/basics/templates/.rspec_parallel +3 -0
  29. data/lib/generators/katapult/basics/templates/Capfile +5 -1
  30. data/lib/generators/katapult/basics/templates/Gemfile +23 -34
  31. data/lib/generators/katapult/basics/templates/Guardfile +0 -12
  32. data/lib/generators/katapult/basics/templates/app/controllers/errors_controller.rb +9 -0
  33. data/lib/generators/katapult/basics/templates/app/helpers/unpoly_helper.rb +13 -0
  34. data/lib/generators/katapult/{haml → basics}/templates/app/views/layouts/_flashes.html.haml +1 -1
  35. data/lib/generators/katapult/basics/templates/app/views/layouts/_menu_bar.html.haml.tt +12 -0
  36. data/lib/generators/katapult/basics/templates/app/views/layouts/application.html.haml.tt +25 -0
  37. data/lib/generators/katapult/basics/templates/app/webpack/assets/images/.keep +0 -0
  38. data/lib/generators/katapult/basics/templates/app/webpack/assets/index.js +16 -0
  39. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/application.js +0 -0
  40. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/bootstrap.js +12 -0
  41. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/compilers/.keep +0 -0
  42. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/content_link.js +17 -0
  43. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/modal_link.js +17 -0
  44. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/unpoly.js +9 -0
  45. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_definitions.sass +25 -0
  46. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_environment.sass +2 -0
  47. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_mixins.sass +3 -0
  48. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/blocks/.keep +0 -0
  49. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/custom_bootstrap.sass +50 -0
  50. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/.keep +0 -0
  51. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/bootstrap/navbar.sass +83 -0
  52. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/theme.sass +11 -0
  53. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/unpoly.sass +2 -0
  54. data/lib/generators/katapult/basics/templates/app/webpack/packs/application.js +13 -0
  55. data/lib/generators/katapult/basics/templates/config/database.sample.yml +1 -1
  56. data/lib/generators/katapult/basics/templates/config/deploy.rb +3 -4
  57. data/lib/generators/katapult/basics/templates/config/environments/staging.rb +5 -0
  58. data/lib/generators/katapult/basics/templates/config/initializers/better_errors.rb +23 -0
  59. data/lib/generators/katapult/basics/templates/config/initializers/exception_notification.rb.tt +1 -1
  60. data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +1 -1
  61. data/lib/generators/katapult/basics/templates/config/webpack/loaders/unpoly.js +4 -0
  62. data/lib/generators/katapult/basics/templates/features/support/capybara_screenshot.rb +7 -0
  63. data/lib/generators/katapult/basics/templates/features/support/factory_bot.rb +1 -0
  64. data/lib/generators/katapult/basics/templates/features/support/paths.rb +7 -2
  65. data/lib/generators/katapult/basics/templates/features/support/rspec_doubles.rb +1 -0
  66. data/lib/generators/katapult/basics/templates/features/support/selectors.rb +3 -3
  67. data/lib/generators/katapult/basics/templates/features/support/selenium.rb +13 -0
  68. data/lib/generators/katapult/basics/templates/features/support/{env-custom.rb → spreewald.rb} +0 -0
  69. data/lib/generators/katapult/basics/templates/features/support/webpacker.rb +35 -0
  70. data/lib/generators/katapult/basics/templates/lib/ext/action_view/form_for_with_development_errors.rb +31 -31
  71. data/lib/generators/katapult/basics/templates/lib/ext/active_record/find_by_anything.rb +4 -3
  72. data/lib/generators/katapult/basics/templates/public/robots.txt +5 -0
  73. data/lib/generators/katapult/basics/templates/spec/assets/sample.pdf +0 -0
  74. data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +1 -1
  75. data/lib/generators/katapult/basics/templates/spec/support/database_cleaner.rb +20 -0
  76. data/lib/generators/katapult/basics/templates/spec/support/factory_bot.rb +3 -0
  77. data/lib/generators/katapult/basics/templates/spec/support/fixture_file.rb +6 -0
  78. data/lib/generators/katapult/basics/templates/spec/support/postgresql_sequences.rb +15 -0
  79. data/lib/generators/katapult/basics/templates/spec/support/timecop.rb +3 -0
  80. data/lib/generators/katapult/clearance/clearance_generator.rb +14 -2
  81. data/lib/generators/katapult/clearance/templates/app/views/layouts/_current_user.html.haml +11 -0
  82. data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +10 -4
  83. data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +12 -12
  84. data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -11
  85. data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +16 -15
  86. data/lib/generators/katapult/clearance/templates/features/authentication.feature +3 -3
  87. data/lib/generators/katapult/cucumber_features/templates/feature.feature +1 -1
  88. data/lib/generators/katapult/model_specs/templates/model_spec.rb +3 -5
  89. data/lib/generators/katapult/navigation/navigation_generator.rb +7 -1
  90. data/lib/generators/katapult/navigation/templates/app/views/layouts/_navigation.html.haml +15 -0
  91. data/lib/generators/katapult/transform/transform_generator.rb +12 -17
  92. data/lib/generators/katapult/views/templates/_form.html.haml +48 -0
  93. data/lib/generators/katapult/views/templates/app/helpers/table_helper.rb +14 -0
  94. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/action_bar.sass +22 -0
  95. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/title.sass +11 -0
  96. data/lib/generators/katapult/views/templates/custom_action.html.haml +5 -0
  97. data/lib/generators/katapult/views/templates/edit.html.haml +4 -0
  98. data/lib/generators/katapult/views/templates/index.html.haml +26 -0
  99. data/lib/generators/katapult/{haml → views}/templates/new.html.haml +1 -1
  100. data/lib/generators/katapult/views/templates/show.html.haml +39 -0
  101. data/lib/generators/katapult/{haml/haml_generator.rb → views/views_generator.rb} +19 -25
  102. data/lib/generators/katapult/{w_u_i → web_ui}/templates/_route.rb +3 -3
  103. data/lib/generators/katapult/{w_u_i → web_ui}/templates/controller.rb +21 -23
  104. data/lib/generators/katapult/{w_u_i/w_u_i_generator.rb → web_ui/web_ui_generator.rb} +7 -12
  105. data/lib/katapult/action.rb +1 -1
  106. data/lib/katapult/application_model.rb +8 -8
  107. data/lib/katapult/binary_util.rb +48 -10
  108. data/lib/katapult/generator.rb +2 -10
  109. data/lib/katapult/generator_goodies.rb +23 -0
  110. data/lib/katapult/navigation.rb +10 -5
  111. data/lib/katapult/parser.rb +15 -8
  112. data/lib/katapult/version.rb +5 -1
  113. data/lib/katapult/{wui.rb → web_ui.rb} +19 -4
  114. data/lib/katapult.rb +0 -5
  115. data/script/console +5 -2
  116. data/script/kta +8 -0
  117. data/script/update +80 -0
  118. data/spec/action_spec.rb +0 -1
  119. data/spec/attribute_spec.rb +0 -1
  120. data/spec/element_spec.rb +0 -1
  121. data/spec/model_spec.rb +0 -1
  122. data/spec/parser_spec.rb +26 -0
  123. data/spec/util_spec.rb +0 -1
  124. data/spec/{wui_spec.rb → web_ui_spec.rb} +24 -12
  125. metadata +86 -124
  126. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_all.sass +0 -4
  127. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_items.sass +0 -11
  128. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_layout.sass +0 -26
  129. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_navigation.sass +0 -11
  130. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_tools.sass +0 -12
  131. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application.sass +0 -6
  132. data/lib/generators/katapult/basics/templates/config/spring.rb +0 -3
  133. data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +0 -1
  134. data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +0 -3
  135. data/lib/generators/katapult/haml/templates/_form.html.haml +0 -38
  136. data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +0 -33
  137. data/lib/generators/katapult/haml/templates/custom_action.html.haml +0 -5
  138. data/lib/generators/katapult/haml/templates/edit.html.haml +0 -4
  139. data/lib/generators/katapult/haml/templates/index.html.haml +0 -29
  140. data/lib/generators/katapult/haml/templates/show.html.haml +0 -39
  141. data/lib/generators/katapult/install/install_generator.rb +0 -14
  142. data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +0 -20
  143. data/lib/generators/katapult/navigation/templates/app/models/navigation.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a3cdc0f0b264fd596277340707b91532b302b8d2
4
- data.tar.gz: 92f80d989c103b65434d22d9d33c0eb273f2dd40
2
+ SHA256:
3
+ metadata.gz: ddcf0832f9fb8d7597253465296fe0726761e1bd2d3088d741e4bedf51e05cf7
4
+ data.tar.gz: 293a4ba645e9710e1392707ae59df834e9d14cbd841920e919d02d3d0db02e73
5
5
  SHA512:
6
- metadata.gz: 708499a49443d9384eb273369a0e81bf2f6578e0520a9bc460abeefdc2c8c97ff5d310407e391ac80fc8517791c0c12f89652d60a3ff42b7d0228b9466130871
7
- data.tar.gz: d122fd0af16935458dd2b06867fa86b5d545a74b8a2fb2f746c49cd61cada320b333426282a627cb5f41340b14dade12795724496a80c2404af42dfa76d0bd0f
6
+ metadata.gz: 2ead2ca1d7f9bbee69ad9bdac6e5043c513e23deffa6f73119b3b4145206d56f7cf3537067d7116b39d04b0e7c07f795eb839600dedd14f9e22d6bc501e8f33e
7
+ data.tar.gz: cd2336671a2317373433ff47a3568e35073757c21ff2972d1a8d3004830c764adcc7c422e55b34966255952516760eee329a0468687159adf78c5aa2c46551f3
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
+ --require spec_helper
1
2
  --color
2
3
  --format progress
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 2.5.0
data/Gemfile CHANGED
@@ -2,3 +2,12 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in katapult.gemspec
4
4
  gemspec
5
+
6
+ gem 'bundler', '~> 1.5'
7
+ gem 'rake'
8
+ gem 'pry'
9
+
10
+ # Test
11
+ gem 'aruba', '~> 0.10'
12
+ gem 'guard-cucumber'
13
+ gem 'rspec', '~> 3.4'
data/README.md CHANGED
@@ -5,15 +5,25 @@
5
5
 
6
6
  `Katapult` is a kickstart generator for Rails applications. It creates new Rails
7
7
  applications with [lots of pre-configuration](https://github.com/makandra/katapult/blob/master/lib/generators/katapult/basics/basics_generator.rb)
8
- and offers ([makandra-flavored](https://leanpub.com/growing-rails)) code
9
- generation from an application model.
10
- These two features significally speed up the initial phase of a Rails project by
11
- doing in minutes what took you weeks. After modeling your application, which
12
- typically takes about an hour, you can instantly start implementing the meat of
13
- your application.
8
+ and offers [makandra-flavored](https://leanpub.com/growing-rails) code
9
+ generation from an application model. These two features significally speed up
10
+ the initial phase of a Rails project by doing in minutes what otherwise would
11
+ cost you weeks.
12
+ After modeling your application, which typically takes about an hour, you can
13
+ instantly start implementing the meat of your application.
14
14
 
15
- `Katapult` will only support current versions of Ruby and Rails, currently
16
- Rails 4.2 and Ruby 2.3.
15
+ `Katapult` only supports a single Ruby and Rails version, currently it's Rails
16
+ 5.1.4 and Ruby 2.5.0.
17
+
18
+
19
+ ## Prerequisites
20
+
21
+ Katapult uses *PostgreSQL* as database, so you'll need to install that upfront.
22
+ Also, it drops the asset pipeline in favor of *Webpacker*, so you'll need Node
23
+ and Yarn (see <https://makandracards.com/makandra/47477>).
24
+
25
+ Also, it requires the *Bundler* and *Rake* Ruby gems, which are probably already
26
+ installed on your system.
17
27
 
18
28
 
19
29
  ## Installation
@@ -28,14 +38,14 @@ in your Gemfile.
28
38
 
29
39
  ## Usage
30
40
 
31
- `Katapult` does two separate things:
41
+ `katapult` does two distinct things for you:
32
42
 
33
43
  1. It creates a new Rails application, set up with many standard gems, snippets,
34
- useful configuration, databases, testing libraries etc. See the [BasicsGenerator](https://github.com/makandra/katapult/blob/master/lib/generators/katapult/basics/basics_generator.rb) for details.
35
- 2. It generates code from an application model, i.e. creates files for models,
36
- views, controllers, routes, stylesheets; see the
44
+ useful configuration, databases, testing libraries etc.
45
+ 2. It generates code from an application model, i.e. it creates models and
46
+ views, controllers, styles etc.
37
47
 
38
- You may use both or only one of them.
48
+ You may use both or only one of them. Read on for details.
39
49
 
40
50
 
41
51
  ## 1) Creating a new Rails application
@@ -44,58 +54,44 @@ Run the following command:
44
54
 
45
55
  katapult new $APPLICATION_NAME
46
56
 
47
- This will:
48
-
49
- - create a new Rails application
50
- - install common Gems
51
- - set up a `database.yml` file (for PostgreSQL)
52
- - create basic styles
53
- - install RSpec and Cucumber to the application
54
- - install Capistrano
55
- - create `lib/katapult/application_model.rb` (needed for step 2)
56
-
57
- See the [BasicsGenerator](https://github.com/makandra/katapult/blob/master/lib/generators/katapult/basics/basics_generator.rb)
58
- for details: Its methods are executed one-by-one and their names are a
59
- description of what it does.
60
-
61
- ### Alternative: Using Katapult in existing Rails applications
62
- `katapult` expects a clean application (that it would usually generate itself).
57
+ This will create a new Rails application and prepare it in more than 20 steps.
58
+ Read the [BasicsGenerator](https://github.com/makandra/katapult/blob/master/lib/generators/katapult/basics/basics_generator.rb)
59
+ for details: Its methods are executed one-by-one, while the method names are a
60
+ description of what they do.
61
+
62
+ ### Alternative: Using Katapult in an existing Rails application
63
+ `katapult` expects a fresh application (which it would usually generate itself).
63
64
  If you have an existing Rails application, you *may* use `katapult`, but be
64
65
  warned: it is not designed to respect existing files, although it will usually
65
- ask before overwriting anything.
66
+ ask before overwriting something.
66
67
 
67
- After adding it to the Gemfile (see above), run any of the following generators:
68
+ After adding it to the Gemfile, run the basics generator manually:
68
69
 
69
- rails generate katapult:basics # Prepare the app with useful defaults
70
- rails generate katapult:install # Create application model file
71
- rails generate katapult:transform lib/katapult/application_model.rb
70
+ bin/rails generate katapult:basics
72
71
 
73
72
 
74
73
  ## 2) Generating code from an application model
75
74
 
76
- > If you only want to use the code generation feature of `katapult`, but did not
77
- > run `katapult new ...`, you need to add `katapult` to your Gemfile now and
78
- > install it with `rails generate katapult:install`. See above.
75
+ After running `katapult new`, you will find a default application model in
76
+ `lib/katapult/application_model.rb`. It contains a full example of `katapult`'s
77
+ features that you should replace with _your_ application model.
79
78
 
80
- After installation, you will find a file `lib/katapult/application_model.rb`
81
- where you will define the properties of your application. You're free to create
82
- more than one application model, however, you'll need to specify their location
83
- when running the transform.
84
-
85
- Inside the application model, use `katapult`'s simple DSL (domain specific
86
- language) to express yourself. When you are done developing the model, transform
87
- it into code with:
79
+ When you are done, transform the model using:
88
80
 
89
81
  katapult fire [path/to/application_model]
90
82
 
83
+ The path is optional and only needs to be specified when you've renamed the
84
+ application model file. Note that you may well use separate model files for
85
+ separate runs.
86
+
91
87
  See an overview of the DSL below. The respective sections hold examples of what
92
88
  options are available to each element. For details, dive into
93
89
  `lib/generators/katapult` where all generators are stored. The method names
94
- inside a generator tell what it does.
90
+ of a generator tell what it does.
95
91
 
96
92
  ### Generic DSL syntax example
97
- The DSL consists of _elements_, e.g. `Model` or `WUI` (Web User Interface). Each
98
- `katapult` element has the same syntax, taking a name, options, and a block:
93
+ The DSL consists of _elements_, e.g. `Model` or `WebUI`. Each `katapult` element
94
+ has the following syntax, taking a name, options, and a block:
99
95
 
100
96
  element_type 'name', options: 'example' do |element|
101
97
  element.some_method
@@ -140,47 +136,51 @@ Defined on Model. Takes a name and options:
140
136
  model.attr :avoid, type: :plain_json # PostgreSQL "json"
141
137
 
142
138
 
143
- ### WUI (Web User Interface)
139
+ ### WebUI
144
140
  Takes a name, options and a block:
145
141
 
146
- wui 'Customer', model: 'User' do |wui|
147
- # wui.crud, see Action element
148
- end
142
+ web_ui 'Customer', model: 'User' do |web_ui|
143
+ web_ui.crud # Create all the standard rails actions
149
144
 
150
- # Inferred model name: 'Customer'
151
- wui 'Customer' do |wui|
152
- # wui.crud, see Action element
145
+ # web_ui.action :custom etc, see Action element
153
146
  end
154
147
 
148
+ # Short syntax with inferred model name 'User'
149
+ web_ui 'User', &:crud
155
150
 
156
- #### Action
157
- Defined on WUI. Takes a name and options:
158
151
 
159
- # Create all the standard rails actions
160
- wui.crud
152
+ #### Action
153
+ Defined on WebUI. Takes a name and options:
161
154
 
162
155
  # Select single Rails actions
163
- wui.action :index
164
- wui.action :show
165
- wui.action :create # also creates :new
166
- wui.action :update # also creates :edit
167
- wui.action :destroy
156
+ web_ui.action :index
157
+ web_ui.action :show
158
+ web_ui.action :create # also creates :new
159
+ web_ui.action :update # also creates :edit
160
+ web_ui.action :destroy
168
161
 
169
162
  # Add custom actions
170
- wui.action :custom_action, method: :post, scope: :member
171
- wui.action :other_action, method: :get, scope: :collection
163
+ web_ui.action :custom_action, method: :post, scope: :member
164
+ web_ui.action :other_action, method: :get, scope: :collection
172
165
 
166
+ ### Crud
167
+ This is a shortcut for creating a model together with a WebUI with CRUD actions.
168
+
169
+ crud 'Customer' do |customer|
170
+ customer.attr :name
171
+ end
172
+
173
173
 
174
174
  ### Navigation
175
- Takes a name, will generate a navigation with links to the index pages of all
176
- WUIs.
175
+ No arguments, will generate a main menu with links to the index pages of all
176
+ WebUIs.
177
177
 
178
- navigation :main
178
+ navigation
179
179
 
180
180
 
181
181
  ### Authenticate
182
- Takes the name of the user model (currently only `User` (case-insensitive) is
183
- supported) and an email address. Generates authentication with [Clearance](https://github.com/thoughtbot/clearance).
182
+ Takes the name of the user model (currently only `User` is supported) and an
183
+ email address. Generates authentication with [Clearance](https://github.com/thoughtbot/clearance).
184
184
 
185
185
  authenticate 'User', system_email: 'system@example.com'
186
186
 
@@ -190,43 +190,71 @@ requests.
190
190
 
191
191
  ## Development
192
192
 
193
- ### Basic information
193
+ ### Getting started + continuing development
194
194
  `Katapult` is tested with [RSpec](http://rspec.info/) and
195
195
  [Cucumber](https://cucumber.io/) + [Aruba](https://github.com/cucumber/aruba)
196
196
  ([API-Doc](http://www.rubydoc.info/github/cucumber/aruba/master/)).
197
197
 
198
- It caches a pristine Rails application inside its `tmp/` directory to
199
- speed up test runs. Keep this in mind, as it may lead to caching issues when
200
- switching Ruby versions or installing a new version of the Rails gem.
198
+ For its full-stack integration tests, `katapult` requires a PostgreSQL account.
199
+ Create a dedicated account on your local PostgreSQL server:
201
200
 
202
- Since `katapult` has full-stack integration tests, it requires a PostgreSQL
203
- account. Create a dedicated account on your local PostgreSQL server:
204
-
205
- $> sudo -iu postgres
206
- postgres $> psql
201
+ $> sudo -u postgres psql
207
202
  postgres=# CREATE ROLE katapult WITH createdb LOGIN;
208
203
 
209
- ### Continuing development
210
- When you continue development on `katapult`, remove its `tmp/` directory first.
211
- It contains cached data that might lead to confusion.
204
+ Whenever you start working on `katapult`, you should run `script/update`, which
205
+ will guide you through a quick update process.
206
+
207
+ ### Suggested workflow
208
+ When adding a feature to `katapult`, it will usually take you some time to
209
+ figure out how exactly the generated code should look like. You'll be switching
210
+ between `katapult`'s tests, its generators and the generated code.
211
+
212
+ Here's a the suggested process:
213
+
214
+ 1) Run a scenario (create one if needed)
215
+ 2) Tag that scenario with @no-clobber. This will leave the generated test app
216
+ untouched in subsequent test runs.
217
+ 3) Make a commit inside the generated test application, so you'll have a clean
218
+ working directory: `script/kta git add --all && script/kta git commit -m 'x'`
219
+ 4) Modify the test app as needed. Boot a development server with
220
+ `script/kta rails s` if you like.
221
+ 5) Re-run the @no-clobber scenario (modify it as needed) until test and test app
222
+ meet the expectations.
223
+ 6) Now look at the git diff in the test app and model everything with katapult's
224
+ generators.
225
+ 7) Remove the @no-clobber tag and run the scenario normally to see if it's still
226
+ green. Remember to stop the development server first.
212
227
 
213
228
  ### Debugging
214
229
  Add the `@announce-output` tag to `katapult` features in order to have any output
215
- logged to your terminal.
230
+ logged to your terminal. Note that each step will print all output to date, so
231
+ you will see things multiple times.
232
+
233
+ To precisely debug errors occurring _inside_ the generated application, use
234
+ `script/kta`. You could also just cd to the test app directory, but since it is
235
+ destroyed between test runs, you'd need to `cd ../../aruba/katapult_test_app`
236
+ after each test.
216
237
 
217
- To precisely debug errors occurring _inside_ the generated application, you may
218
- cd to `tmp/aruba/katapult_test_app`. Run the failing command manually.
238
+ When fixing issues in the generated app, make a commit in the app first. When
239
+ you've fixed it, the diff will show you what you need to port back to katapult.
219
240
 
220
- Note that after running a katapult feature, you need to call
221
- `cd ../../aruba/katapult_test_app` inside the generated app terminal. This is
222
- required because the `tmp/aruba` directory is being wiped before each scenario.
241
+ ### Typical issues
242
+ Be sure to check this list when you encounter strange issues during development.
223
243
 
224
- ### Typical errors
244
+ - Spring was running in a directory that does not exist any more. This will
245
+ screw subsequent spring invocations. Run `ps aux | grep spring` and `kill`
246
+ suspect processes.
247
+ - An outdated Rails application in `tmp/cached_*`
225
248
  - Timeout error because of a script waiting for user input
226
- - Executing (bash) commands in the test application without resetting the
227
- katapult gem's Bundler settings. Wrap into `Bundler.with_clean_env { }`.
228
- - Spring running inside the test application encumbers parallel_tests
229
- - An outdated Rails application in `tmp/cached_test_app`
249
+
250
+ ### Fast tests
251
+ Generating basics and transforming the application model take quite some time
252
+ (about 20s), because it boots the Rails application, resolves Yarn dependencies
253
+ and migrates databases. To speed that up, `katapult` tests cache prepared Rails
254
+ applications in tmp/.
255
+
256
+ When debugging test suite speed, `bundle exec cucumber --format usage` is your
257
+ friend.
230
258
 
231
259
 
232
260
  ## Credits
data/Rakefile CHANGED
@@ -12,3 +12,16 @@ Cucumber::Rake::Task.new(:features) do |t|
12
12
  end
13
13
 
14
14
  RSpec::Core::RakeTask.new(:spec)
15
+
16
+ task :update_readme do
17
+ require_relative 'lib/katapult/version'
18
+ readme_path = 'README.md'
19
+ readme = File.read readme_path
20
+
21
+ # Using \s+ to support line breaks
22
+ readme.sub! /(currently\s+it's\s+Rails\s+)[\d\.]+/, "\\1#{Katapult::RAILS_VERSION}"
23
+ readme.sub! /(and\s+Ruby\s+)[\d\.]+\d/, "\\1#{Katapult::RUBY_VERSION}"
24
+ File.open readme_path, 'w' do |f|
25
+ f.write readme
26
+ end
27
+ end
data/bin/katapult CHANGED
@@ -2,47 +2,76 @@
2
2
 
3
3
  # This script simplifies the usage of `katapult` by grouping relevant actions
4
4
  # that the user else had to perform manually.
5
- # See bottom for USAGE.
6
5
 
6
+ usage = 'Usage: katapult new APP_NAME | fire [path/to/model] | version'
7
+
8
+ require_relative '../lib/katapult/version'
7
9
  require_relative '../lib/katapult/binary_util'
8
10
  util = Katapult::BinaryUtil
9
11
 
10
- case (transform_command = ARGV.shift)
12
+ require 'optparse'
13
+ options = {}
14
+ OptionParser.new do |opts|
15
+ opts.on '-u', '--db-user USER', 'Database user name' do |name|
16
+ options[:dbuser] = name
17
+ end
18
+ opts.on '-p', '--db-password PASS', 'Database password' do |password|
19
+ options[:dbpass] = password
20
+ end
21
+ opts.on '-v', '--verbose', 'Verbose output' do |verbose|
22
+ options[:verbose] = verbose
23
+ end
24
+ end.parse!
25
+
26
+ # Check Ruby version ###########################################################
27
+ supported_ruby = Katapult::RUBY_VERSION
28
+ current_ruby = `ruby -v`.chomp # Long version string à la "ruby 2.5.0p0 ..."
29
+
30
+ current_ruby.include?(supported_ruby) or util.fail <<-MSG
31
+ Ruby version error
32
+
33
+ Your current Ruby (#{current_ruby})
34
+ is not supported by this version of katapult.
35
+ Please switch to Ruby #{supported_ruby} and run again.
36
+ MSG
37
+
38
+
39
+ case ARGV.shift
11
40
  when 'new'
12
- interactive = !ARGV.delete('--non-interactive')
13
- app_name = ARGV.shift
14
- basics_command = 'bundle exec rails generate katapult:basics'
41
+ app_name = ARGV.shift || util.ask('Please enter the application name:')
42
+ app_name = util.snake_case(app_name)
43
+ puts "Normalized application name: #{app_name}" if options[:verbose]
15
44
 
16
- if interactive
17
- util.puts 'Please enter your database user: '
18
- basics_command << ' --db-user ' << gets.chomp
45
+ # Any options that haven't be passed via command line should be asked for
46
+ options[:dbuser] ||= util.ask 'Please enter the database user:'
47
+ options[:dbpass] ||= util.ask 'Please enter the database password:'
19
48
 
20
- util.puts 'Please enter your database password: '
21
- basics_command << ' --db-password ' << gets.chomp
22
- end
49
+ basics_command = 'bundle exec rails generate katapult:basics'
50
+ basics_command << ' --db-user ' << options[:dbuser]
51
+ basics_command << ' --db-password ' << options[:dbpass]
23
52
 
24
- util.puts 'Creating new Rails application ...'
53
+ util.pink "Creating new Rails application in #{app_name} ..."
25
54
  util.create_rails_app app_name
26
-
27
55
  Dir.chdir app_name
28
56
 
29
- util.puts 'Initializing git repository ...'
57
+ util.pink 'Initializing git repository ...'
30
58
  util.run 'git init --quiet'
31
59
  util.git_commit "rails new #{ app_name }", '--quiet'
32
60
 
33
- util.puts 'Installing katapult ...'
61
+ util.pink 'Installing katapult ...'
34
62
  File.open('Gemfile', 'a') do |file|
35
63
  file.puts "gem 'katapult'#{ ENV['KATAPULT_GEMFILE_OPTIONS'] }, group: :development"
36
64
  end
37
65
  util.run 'bundle install --quiet'
38
- util.run 'bundle exec rails generate katapult:install'
39
- util.git_commit 'rails generate katapult:install', '--quiet'
66
+ util.run 'bundle exec rails generate katapult:app_model'
67
+ util.git_commit 'rails generate katapult:app_model', '--quiet'
40
68
 
41
- util.puts 'Generating katapult basics ...'
69
+ util.pink 'Generating katapult basics ...'
42
70
  util.run basics_command
71
+ # Do not use `basics_command` as commit message, as it contains the password!
43
72
  util.git_commit 'rails generate katapult:basics', '--quiet'
44
73
 
45
- util.puts <<-INSTRUCTIONS
74
+ util.pink <<-INSTRUCTIONS
46
75
  Application initialization done.
47
76
 
48
77
  Next step: Model your application in lib/katapult/application_model.rb and
@@ -53,20 +82,25 @@ when 'fire'
53
82
  app_model_path = ARGV.shift || 'lib/katapult/application_model.rb'
54
83
  transform_command = 'bin/rails generate katapult:transform ' + app_model_path
55
84
 
56
- util.puts 'Loading katapult ...'
85
+ util.pink 'Loading katapult ...'
57
86
  util.run transform_command
87
+
88
+ util.pink 'Committing result ...'
58
89
  util.git_commit transform_command
59
90
 
60
- util.puts <<-INSTRUCTIONS
91
+ util.pink <<-INSTRUCTIONS
61
92
  Model transformation done.
62
93
 
63
94
  Now boot up your development server (e.g. with `rails server`) and try your
64
95
  kickstarted application in the browser!
65
96
  INSTRUCTIONS
66
97
 
98
+ when 'version'
99
+ puts <<-VERSION
100
+ Katapult #{Katapult::VERSION}
101
+ Generating a Rails #{Katapult::RAILS_VERSION} app on Ruby #{Katapult::RUBY_VERSION}.
102
+ VERSION
103
+
67
104
  else
68
- puts <<-USAGE
69
- Usage: katapult [new APP_NAME | fire [path/to/model] ]
70
- Suppress database credentials prompt with `--non-interactive`
71
- USAGE
105
+ puts usage
72
106
  end
@@ -0,0 +1,55 @@
1
+ #@announce-output
2
+ Feature: The application model prepared by Katapult
3
+
4
+ Scenario: Generating the application model template
5
+ Given a new Rails application with Katapult basics installed
6
+
7
+ When I generate the application model
8
+ Then the file "lib/katapult/application_model.rb" should contain:
9
+ """
10
+ # Define a model + generate views with CRUD actions
11
+ # Since this generates the first web UI with an index action, the products list
12
+ # will become the home page of the generated app
13
+ crud 'product' do |product|
14
+ # The first attribute of each model is taken as a human identifier/label
15
+ product.attr :title # Default type "string"
16
+
17
+ # The order of attributes is respected when generating the form for that model
18
+ product.attr :price, type: :money
19
+ product.attr :mode, assignable_values: %w[public private]
20
+ product.attr :provider, type: :url
21
+ product.attr :import_data, type: :json
22
+ end
23
+
24
+ # Define a model
25
+ model 'user' do |user|
26
+ user.attr :email # Type "email" derived from attribute name
27
+
28
+ user.attr :name
29
+ user.attr :last_visit, type: :datetime
30
+ user.attr :locked, type: :flag, default: false
31
+ end
32
+
33
+ # Add a web user interface for the 'user' model
34
+ web_ui 'user' do |web_ui|
35
+ # All CRUD actions: index, show, new, create, edit, update, destroy
36
+ web_ui.crud
37
+
38
+ # Custom action
39
+ web_ui.action :lock, scope: :member, method: :post
40
+ end
41
+
42
+ # Have a main menu
43
+ navigation
44
+
45
+ # Add authentication
46
+ authenticate 'user', system_email: 'system@example.com'
47
+
48
+ """
49
+
50
+ When I successfully transform the application model including migrations
51
+ And I run cucumber
52
+ Then the features should pass
53
+
54
+ When I run rspec
55
+ Then the specs should pass