rails_engine_toolkit 0.6.3
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/.github/workflows/ci.yml +54 -0
- data/.github/workflows/release.yml +22 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +83 -0
- data/Rakefile +7 -0
- data/docs/ARCHITECTURE.md +18 -0
- data/docs/COMPATIBILITY.md +18 -0
- data/docs/CONTRIBUTING.md +26 -0
- data/docs/END_TO_END.md +26 -0
- data/docs/PUBLISHING.md +24 -0
- data/docs/RELEASE.md +32 -0
- data/docs/RELEASE_CHECKLIST.md +49 -0
- data/docs/TESTING.md +21 -0
- data/exe/engine-toolkit +6 -0
- data/lib/rails_engine_toolkit/actions/delete_engine_migration.rb +46 -0
- data/lib/rails_engine_toolkit/actions/init.rb +54 -0
- data/lib/rails_engine_toolkit/actions/install_engine_migrations.rb +83 -0
- data/lib/rails_engine_toolkit/actions/new_engine.rb +127 -0
- data/lib/rails_engine_toolkit/actions/new_engine_migration.rb +30 -0
- data/lib/rails_engine_toolkit/actions/new_engine_model.rb +30 -0
- data/lib/rails_engine_toolkit/actions/remove_engine.rb +78 -0
- data/lib/rails_engine_toolkit/actions/uninstall_engine_migrations.rb +79 -0
- data/lib/rails_engine_toolkit/actions/update_engine_readme.rb +60 -0
- data/lib/rails_engine_toolkit/cli.rb +110 -0
- data/lib/rails_engine_toolkit/config.rb +98 -0
- data/lib/rails_engine_toolkit/errors.rb +7 -0
- data/lib/rails_engine_toolkit/file_editor.rb +40 -0
- data/lib/rails_engine_toolkit/generators/install/install_generator.rb +67 -0
- data/lib/rails_engine_toolkit/project.rb +71 -0
- data/lib/rails_engine_toolkit/railtie.rb +9 -0
- data/lib/rails_engine_toolkit/route_inspector.rb +44 -0
- data/lib/rails_engine_toolkit/routes_rewriter.rb +63 -0
- data/lib/rails_engine_toolkit/templates/engine_readme.erb +37 -0
- data/lib/rails_engine_toolkit/templates/engine_toolkit_yml.erb +35 -0
- data/lib/rails_engine_toolkit/templates/gemspec.erb +25 -0
- data/lib/rails_engine_toolkit/templates/license.erb +3 -0
- data/lib/rails_engine_toolkit/templates.rb +12 -0
- data/lib/rails_engine_toolkit/utils.rb +56 -0
- data/lib/rails_engine_toolkit/version.rb +5 -0
- data/lib/rails_engine_toolkit.rb +33 -0
- data/rails_engine_toolkit.gemspec +31 -0
- data/spec/rails_engine_toolkit/cli_spec.rb +11 -0
- data/spec/rails_engine_toolkit/config_spec.rb +52 -0
- data/spec/rails_engine_toolkit/file_editor_spec.rb +26 -0
- data/spec/rails_engine_toolkit/install_engine_migrations_spec.rb +36 -0
- data/spec/rails_engine_toolkit/install_generator_spec.rb +26 -0
- data/spec/rails_engine_toolkit/new_engine_integration_spec.rb +59 -0
- data/spec/rails_engine_toolkit/new_engine_spec.rb +54 -0
- data/spec/rails_engine_toolkit/project_spec.rb +19 -0
- data/spec/rails_engine_toolkit/remove_engine_integration_spec.rb +40 -0
- data/spec/rails_engine_toolkit/remove_engine_spec.rb +72 -0
- data/spec/rails_engine_toolkit/route_inspector_spec.rb +20 -0
- data/spec/rails_engine_toolkit/routes_rewriter_spec.rb +36 -0
- data/spec/rails_engine_toolkit/uninstall_engine_migrations_spec.rb +35 -0
- data/spec/rails_engine_toolkit/update_engine_readme_spec.rb +32 -0
- data/spec/spec_helper.rb +30 -0
- data/test/fixtures/host_app/Gemfile +5 -0
- data/test/fixtures/host_app/config/application.rb +11 -0
- data/test/fixtures/host_app/config/boot.rb +3 -0
- data/test/fixtures/host_app/config/environment.rb +3 -0
- data/test/fixtures/host_app/config/routes.rb +2 -0
- metadata +140 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2daf757686e083799345227ffbacbb0fe9d53915f764a82320049f23202aab1f
|
|
4
|
+
data.tar.gz: d0e663fa492f7f6f2992cd0b2f9ad7ec6e80c1c772baf385f4537410461b407e
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b03b80e939f4e62b57471509c80241b4e7ca2157f8db29a6c7ae8b38e79df651633839bd50135546234418076b9d89f3e1c4de17a58b490372b54a81a440915c
|
|
7
|
+
data.tar.gz: c537ed36c0a79ac052eadeb992f38ddb5fcb526d5f057f855708feeee988b30188e704ed95f7a59318fd5742ec70e03b995d4230ac13b899092e8c9ef461e183
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
rspec:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false
|
|
12
|
+
matrix:
|
|
13
|
+
ruby: ["3.2", "3.3"]
|
|
14
|
+
rails: ["8.1.2"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- run: bundle install
|
|
22
|
+
- run: bundle exec rspec
|
|
23
|
+
- run: bundle exec rubocop
|
|
24
|
+
|
|
25
|
+
host-app-smoke:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
strategy:
|
|
28
|
+
fail-fast: false
|
|
29
|
+
matrix:
|
|
30
|
+
ruby: ["3.2", "3.3"]
|
|
31
|
+
rails: ["8.1.2"]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: ruby/setup-ruby@v1
|
|
35
|
+
with:
|
|
36
|
+
ruby-version: ${{ matrix.ruby }}
|
|
37
|
+
- run: gem install rails -v ${{ matrix.rails }}
|
|
38
|
+
- run: bundle install
|
|
39
|
+
- run: |
|
|
40
|
+
cp -R test/fixtures/host_app /tmp/host_app
|
|
41
|
+
cd /tmp/host_app
|
|
42
|
+
bundle config set local.rails_engine_toolkit "$GITHUB_WORKSPACE"
|
|
43
|
+
bundle install
|
|
44
|
+
bundle exec rails generate engine_toolkit:install <<'EOF'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
EOF
|
|
52
|
+
bundle exec engine-toolkit new_engine auth <<'EOF'
|
|
53
|
+
|
|
54
|
+
EOF
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: "3.3"
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
- run: gem build rails_engine_toolkit.gemspec
|
|
20
|
+
- run: gem push *.gem
|
|
21
|
+
env:
|
|
22
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Rails Engine Toolkit
|
|
2
|
+
|
|
3
|
+
Reusable tooling for Rails projects that use internal engines.
|
|
4
|
+
|
|
5
|
+
## What this gem provides
|
|
6
|
+
|
|
7
|
+
- `rails generate engine_toolkit:install`
|
|
8
|
+
- `engine-toolkit init`
|
|
9
|
+
- `engine-toolkit new_engine ENGINE_NAME`
|
|
10
|
+
- `engine-toolkit new_engine_model ENGINE_NAME MODEL_NAME [ATTRS...]`
|
|
11
|
+
- `engine-toolkit new_engine_migration ENGINE_NAME MIGRATION_NAME [ATTRS...]`
|
|
12
|
+
- `engine-toolkit install_engine_migrations ENGINE_NAME`
|
|
13
|
+
- `engine-toolkit uninstall_engine_migrations ENGINE_NAME`
|
|
14
|
+
- `engine-toolkit delete_engine_migration ENGINE_NAME PATTERN`
|
|
15
|
+
- `engine-toolkit update_engine_readme ENGINE_NAME`
|
|
16
|
+
- `engine-toolkit remove_engine ENGINE_NAME`
|
|
17
|
+
|
|
18
|
+
## What is new in v6.3
|
|
19
|
+
|
|
20
|
+
- RuboCop cleanup and sane project-level RuboCop configuration
|
|
21
|
+
- action classes split into smaller private helpers where useful
|
|
22
|
+
- long lines and unused arguments fixed
|
|
23
|
+
- packaging polish for a cleaner public repository
|
|
24
|
+
|
|
25
|
+
## Installation in a host Rails app
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
gem "rails_engine_toolkit"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bundle install
|
|
35
|
+
bin/rails generate engine_toolkit:install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The install generator creates:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
config/engine_toolkit.yml
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
and prints:
|
|
45
|
+
|
|
46
|
+
- the generated default configuration
|
|
47
|
+
- the full path of the file you should edit
|
|
48
|
+
|
|
49
|
+
## CLI usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bundle exec engine-toolkit new_engine auth
|
|
53
|
+
bundle exec engine-toolkit new_engine_model auth credential email:string
|
|
54
|
+
bundle exec engine-toolkit new_engine_migration auth CreateCredentials
|
|
55
|
+
bundle exec engine-toolkit install_engine_migrations auth
|
|
56
|
+
bundle exec engine-toolkit uninstall_engine_migrations auth
|
|
57
|
+
bundle exec engine-toolkit update_engine_readme auth
|
|
58
|
+
bundle exec engine-toolkit delete_engine_migration auth create_credentials
|
|
59
|
+
bundle exec engine-toolkit remove_engine auth
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bundle install
|
|
66
|
+
bundle exec rspec
|
|
67
|
+
bundle exec rubocop
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Publishing to RubyGems
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
gem build rails_engine_toolkit.gemspec
|
|
74
|
+
gem push rails_engine_toolkit-0.6.3.gem
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
After it is published, consumers can install it with:
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
gem "rails_engine_toolkit"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
without `github:` or `path:`.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Main components
|
|
4
|
+
|
|
5
|
+
- `CLI`: command entrypoint powered by Thor
|
|
6
|
+
- `Project`: host app path and mutation helper
|
|
7
|
+
- `Config`: validated project configuration loader
|
|
8
|
+
- `FileEditor`: small safe file mutation helpers
|
|
9
|
+
- `Templates`: ERB renderer for generated content
|
|
10
|
+
- `Actions::*`: business operations
|
|
11
|
+
|
|
12
|
+
## Rails integration
|
|
13
|
+
|
|
14
|
+
The gem ships a Railtie and a generator:
|
|
15
|
+
|
|
16
|
+
- `rails generate engine_toolkit:install`
|
|
17
|
+
|
|
18
|
+
That keeps the install experience close to tools such as `rspec:install`. The install generator creates the configuration file and prints a summary plus the exact path to edit.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Compatibility strategy
|
|
2
|
+
|
|
3
|
+
## Rails support
|
|
4
|
+
|
|
5
|
+
The gem is intended to support Rails 8.1.x first.
|
|
6
|
+
|
|
7
|
+
## Verification approach
|
|
8
|
+
|
|
9
|
+
Compatibility is checked at four levels:
|
|
10
|
+
|
|
11
|
+
1. unit specs
|
|
12
|
+
2. integration-style specs on temporary directories
|
|
13
|
+
3. install generator smoke test in a dummy host app fixture
|
|
14
|
+
4. CI matrix across supported Ruby and Rails versions
|
|
15
|
+
|
|
16
|
+
## Important limitation
|
|
17
|
+
|
|
18
|
+
A true dynamic matrix that creates full temporary Rails apps at runtime is possible, but is best executed in CI rather than lightweight local scaffolding environments.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Local setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bundle install
|
|
7
|
+
bundle exec rspec
|
|
8
|
+
bundle exec rubocop
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Main principles
|
|
12
|
+
|
|
13
|
+
- keep project mutations explicit
|
|
14
|
+
- prefer small action classes
|
|
15
|
+
- keep route handling readable and testable
|
|
16
|
+
- avoid hidden side effects during install and engine generation
|
|
17
|
+
- prefer configuration over hardcoded project metadata
|
|
18
|
+
|
|
19
|
+
## Test expectations
|
|
20
|
+
|
|
21
|
+
Before opening a pull request, run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle exec rspec
|
|
25
|
+
bundle exec rubocop
|
|
26
|
+
```
|
data/docs/END_TO_END.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# End-to-end smoke test
|
|
2
|
+
|
|
3
|
+
A lightweight host app fixture is included under `test/fixtures/host_app`.
|
|
4
|
+
|
|
5
|
+
## Typical smoke workflow
|
|
6
|
+
|
|
7
|
+
From a temporary Rails app or the fixture app:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bundle install
|
|
11
|
+
bin/rails generate engine_toolkit:install
|
|
12
|
+
bundle exec engine-toolkit new_engine auth
|
|
13
|
+
bundle exec engine-toolkit new_engine_model auth credential email:string
|
|
14
|
+
bundle exec engine-toolkit install_engine_migrations auth
|
|
15
|
+
bin/rails db:migrate
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Migration uninstall note
|
|
19
|
+
|
|
20
|
+
If you later run:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bundle exec engine-toolkit uninstall_engine_migrations auth
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
the toolkit removes copied files from `db/migrate`, but it does **not** rollback the database automatically. Run your down/rollback flow manually first if needed.
|
data/docs/PUBLISHING.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Publishing
|
|
2
|
+
|
|
3
|
+
## Publish to RubyGems
|
|
4
|
+
|
|
5
|
+
Create an account on RubyGems.org, then:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
gem build rails_engine_toolkit.gemspec
|
|
9
|
+
gem push rails_engine_toolkit-0.6.2.gem
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Consumers can then use:
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
gem "rails_engine_toolkit"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
instead of `github:` or `path:`.
|
|
19
|
+
|
|
20
|
+
## Trusted publishing
|
|
21
|
+
|
|
22
|
+
You can also set up GitHub Actions with trusted publishing so that releases push automatically after tagging.
|
|
23
|
+
|
|
24
|
+
See the RubyGems publishing guide and trusted publishing guide.
|
data/docs/RELEASE.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Release workflow
|
|
2
|
+
|
|
3
|
+
## Local release
|
|
4
|
+
|
|
5
|
+
1. Update `lib/rails_engine_toolkit/version.rb`
|
|
6
|
+
2. Commit your changes
|
|
7
|
+
3. Tag the release
|
|
8
|
+
4. Build and push the gem
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
gem build rails_engine_toolkit.gemspec
|
|
12
|
+
gem push rails_engine_toolkit-0.3.0.gem
|
|
13
|
+
git tag v0.3.0
|
|
14
|
+
git push origin v0.3.0
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## GitHub Actions release
|
|
18
|
+
|
|
19
|
+
This repository includes a RubyGems release workflow template.
|
|
20
|
+
|
|
21
|
+
### Required secret
|
|
22
|
+
|
|
23
|
+
- `RUBYGEMS_API_KEY`
|
|
24
|
+
|
|
25
|
+
### Trigger
|
|
26
|
+
|
|
27
|
+
Push a version tag such as:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git tag v0.3.0
|
|
31
|
+
git push origin v0.3.0
|
|
32
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Release checklist
|
|
2
|
+
|
|
3
|
+
## Before releasing
|
|
4
|
+
|
|
5
|
+
- Run the test suite:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bundle exec rspec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- Run the linter:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bundle exec rubocop
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Verify the gem builds:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
gem build rails_engine_toolkit.gemspec
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- Review:
|
|
24
|
+
- `README.md`
|
|
25
|
+
- `docs/PUBLISHING.md`
|
|
26
|
+
- `docs/RELEASE.md`
|
|
27
|
+
- `lib/rails_engine_toolkit/version.rb`
|
|
28
|
+
|
|
29
|
+
## Release steps
|
|
30
|
+
|
|
31
|
+
1. Bump the version in `lib/rails_engine_toolkit/version.rb`
|
|
32
|
+
2. Commit the changes
|
|
33
|
+
3. Tag the release
|
|
34
|
+
4. Push the tag
|
|
35
|
+
5. Publish the gem manually or through GitHub Actions
|
|
36
|
+
|
|
37
|
+
## Manual publish
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
gem build rails_engine_toolkit.gemspec
|
|
41
|
+
gem push rails_engine_toolkit-0.6.2.gem
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Tag example
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git tag v0.6.2
|
|
48
|
+
git push origin v0.6.2
|
|
49
|
+
```
|
data/docs/TESTING.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Testing strategy
|
|
2
|
+
|
|
3
|
+
## Layers
|
|
4
|
+
|
|
5
|
+
The test suite is split into four layers:
|
|
6
|
+
|
|
7
|
+
1. focused specs for utility classes and file mutation helpers
|
|
8
|
+
2. action specs that exercise CLI-facing workflows on temporary directories
|
|
9
|
+
3. integration-style specs for route insertion, removal, and migration installation/uninstallation
|
|
10
|
+
4. host-app smoke checks through CI using a Rails 8.1 fixture app
|
|
11
|
+
|
|
12
|
+
## Main scenarios covered
|
|
13
|
+
|
|
14
|
+
- install generator creates configuration and prints summary
|
|
15
|
+
- broken engine references in Gemfile are detected and can be removed
|
|
16
|
+
- route mounts are inspected with parser-assisted detection
|
|
17
|
+
- route mounts are inserted once and removed across multiple mount syntaxes
|
|
18
|
+
- engine README owned tables are updated from engine migrations
|
|
19
|
+
- engine migration files can be installed into the host app one engine at a time
|
|
20
|
+
- copied root migrations can be uninstalled with explicit confirmation
|
|
21
|
+
- engine removal cleans routes, Gemfile, and engine directory
|
data/exe/engine-toolkit
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsEngineToolkit
|
|
4
|
+
module Actions
|
|
5
|
+
class DeleteEngineMigration
|
|
6
|
+
def initialize(argv, stdin:, stdout:, root:, stderr: nil)
|
|
7
|
+
@engine_name = argv[0]
|
|
8
|
+
@pattern = argv[1]
|
|
9
|
+
@stdin = stdin
|
|
10
|
+
@stdout = stdout
|
|
11
|
+
@stderr = stderr
|
|
12
|
+
@root = Pathname(root)
|
|
13
|
+
@project = Project.new(@root)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
@project.validate_root!
|
|
18
|
+
validate_args!
|
|
19
|
+
|
|
20
|
+
migrations_dir = @project.engine_path(@engine_name).join('db/migrate')
|
|
21
|
+
raise ValidationError, "Migrations path does not exist: #{migrations_dir}" unless migrations_dir.directory?
|
|
22
|
+
|
|
23
|
+
matches = migrations_dir.glob("*#{@pattern}*.rb").sort
|
|
24
|
+
raise ValidationError, "No migrations found matching '#{@pattern}'." if matches.empty?
|
|
25
|
+
|
|
26
|
+
confirmed = Utils.ask(
|
|
27
|
+
"Type '#{@engine_name}' to confirm deletion",
|
|
28
|
+
input: @stdin,
|
|
29
|
+
output: @stdout
|
|
30
|
+
)
|
|
31
|
+
raise ValidationError, 'Operation aborted.' unless confirmed == @engine_name
|
|
32
|
+
|
|
33
|
+
matches.each(&:delete)
|
|
34
|
+
UpdateEngineReadme.new([@engine_name], stdin: @stdin, stdout: @stdout, stderr: nil, root: @root).call
|
|
35
|
+
@stdout.puts("Deleted #{matches.size} migration(s)")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def validate_args!
|
|
41
|
+
raise ValidationError, 'Engine name is required.' if @engine_name.to_s.empty?
|
|
42
|
+
raise ValidationError, 'Migration match pattern is required.' if @pattern.to_s.empty?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsEngineToolkit
|
|
4
|
+
module Actions
|
|
5
|
+
class Init
|
|
6
|
+
def initialize(_argv, stdin:, stdout:, root:, stderr: nil)
|
|
7
|
+
@stdin = stdin
|
|
8
|
+
@stdout = stdout
|
|
9
|
+
@stderr = stderr
|
|
10
|
+
@root = Pathname(root)
|
|
11
|
+
@project = Project.new(@root)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
@project.validate_root!
|
|
16
|
+
answers = prompt_values
|
|
17
|
+
|
|
18
|
+
FileUtils.mkdir_p(@project.config_file.dirname)
|
|
19
|
+
@project.config_file.write(
|
|
20
|
+
Templates.render('engine_toolkit_yml', answers)
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
@stdout.puts("Created #{@project.config_file}")
|
|
24
|
+
@stdout.puts('Edit this file to customize the toolkit for your project:')
|
|
25
|
+
@stdout.puts(" #{@project.config_file}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def prompt_values
|
|
31
|
+
slug_default = Utils.repo_slug_from_path(@root)
|
|
32
|
+
name_default = Utils.humanize_slug(slug_default)
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
project_slug: Utils.ask('Project slug', default: slug_default, input: @stdin, output: @stdout),
|
|
36
|
+
project_name: Utils.ask('Project name', default: name_default, input: @stdin, output: @stdout),
|
|
37
|
+
project_url: Utils.ask('Project URL', default: Utils.git_remote_url.to_s, input: @stdin, output: @stdout),
|
|
38
|
+
author_name: Utils.ask('Author name', default: Utils.git_config('user.name').to_s, input: @stdin,
|
|
39
|
+
output: @stdout),
|
|
40
|
+
author_email: Utils.ask('Author email', default: Utils.git_config('user.email').to_s, input: @stdin,
|
|
41
|
+
output: @stdout),
|
|
42
|
+
database: Utils.ask('Default database adapter', default: 'postgresql', input: @stdin, output: @stdout),
|
|
43
|
+
api_only: Utils.ask_yes_no('Use API-only engines by default?', default: true, input: @stdin, output: @stdout),
|
|
44
|
+
skip_asset_pipeline: Utils.ask_yes_no('Skip asset pipeline by default?', default: true, input: @stdin,
|
|
45
|
+
output: @stdout),
|
|
46
|
+
mount_routes: Utils.ask_yes_no('Mount engine routes automatically?', default: true, input: @stdin,
|
|
47
|
+
output: @stdout),
|
|
48
|
+
create_ddd_structure: Utils.ask_yes_no('Create DDD folders by default?', default: true, input: @stdin,
|
|
49
|
+
output: @stdout)
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsEngineToolkit
|
|
4
|
+
module Actions
|
|
5
|
+
class InstallEngineMigrations
|
|
6
|
+
def initialize(argv, stdout:, root:, stdin: nil, stderr: nil)
|
|
7
|
+
@engine_name = argv[0]
|
|
8
|
+
@stdout = stdout
|
|
9
|
+
@stdin = stdin
|
|
10
|
+
@stderr = stderr
|
|
11
|
+
@root = Pathname(root)
|
|
12
|
+
@project = Project.new(@root)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call
|
|
16
|
+
@project.validate_root!
|
|
17
|
+
validate_args!
|
|
18
|
+
|
|
19
|
+
migrations_dir = engine_migrations_dir
|
|
20
|
+
FileUtils.mkdir_p(@project.root_migrations_dir)
|
|
21
|
+
|
|
22
|
+
copied = migrations_to_copy(migrations_dir).map do |source_file|
|
|
23
|
+
copy_migration(source_file)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
report_result(copied)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def validate_args!
|
|
32
|
+
raise ValidationError, 'Engine name is required.' if @engine_name.to_s.empty?
|
|
33
|
+
raise ValidationError, 'Engine name must be snake_case.' unless Utils.snake_case?(@engine_name)
|
|
34
|
+
|
|
35
|
+
engine_path = @project.engine_path(@engine_name)
|
|
36
|
+
raise ValidationError, "Engine does not exist: #{engine_path}" unless engine_path.directory?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def engine_migrations_dir
|
|
40
|
+
migrations_dir = @project.engine_path(@engine_name).join('db/migrate')
|
|
41
|
+
unless migrations_dir.directory?
|
|
42
|
+
raise ValidationError,
|
|
43
|
+
"Engine migrations directory not found: #{migrations_dir}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
migrations_dir
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def migrations_to_copy(migrations_dir)
|
|
50
|
+
existing = @project.root_migrations_dir.glob('*.rb').map do |file|
|
|
51
|
+
file.basename.to_s.sub(/^\d+_/, '')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
migrations_dir.glob('*.rb').sort.reject do |file|
|
|
55
|
+
existing.include?(file.basename.to_s.sub(/^\d+_/, ''))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def copy_migration(source_file)
|
|
60
|
+
basename_without_version = source_file.basename.to_s.sub(/^\d+_/, '')
|
|
61
|
+
destination = @project.root_migrations_dir.join("#{next_timestamp}_#{basename_without_version}")
|
|
62
|
+
FileEditor.copy_file(source_file, destination)
|
|
63
|
+
destination
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def report_result(copied)
|
|
67
|
+
if copied.empty?
|
|
68
|
+
@stdout.puts("No new migrations to install for engine '#{@engine_name}'.")
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@stdout.puts("Installed #{copied.size} migration(s) for engine '#{@engine_name}':")
|
|
73
|
+
copied.each { |file| @stdout.puts(" #{file.relative_path_from(@root)}") }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def next_timestamp
|
|
77
|
+
@counter ||= 0
|
|
78
|
+
@counter += 1
|
|
79
|
+
(Time.now.utc + @counter).strftime('%Y%m%d%H%M%S')
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|