thecore_generators 3.6.0 → 3.11.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.
- checksums.yaml +4 -4
- data/README.md +166 -14
- data/lib/generators/thecore/association_wiring.rb +2 -1
- data/lib/generators/thecore/atom/atom_generator.rb +481 -0
- data/lib/generators/thecore/atom/templates/abilities.rb.tt +16 -0
- data/lib/generators/thecore/atom/templates/seeds.rb.tt +1 -0
- data/lib/generators/thecore/collection_action/collection_action_generator.rb +64 -0
- data/lib/generators/thecore/collection_action/templates/action.html.erb.tt +13 -0
- data/lib/generators/thecore/collection_action/templates/action.js.tt +42 -0
- data/lib/generators/thecore/collection_action/templates/action.rb.tt +33 -0
- data/lib/generators/thecore/collection_action/templates/action.scss.tt +38 -0
- data/lib/generators/thecore/sample_fetcher.rb +68 -0
- data/lib/generators/thecore/tty_detection.rb +19 -0
- data/lib/templates/app_template.rb +220 -0
- data/lib/thecore_generators/check_practices.rb +20 -14
- data/lib/thecore_generators/version.rb +1 -1
- metadata +12 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 753f6373a24773431ad2987bd84b7d8609f4a9bedb32dff5a59264bc37c68081
|
|
4
|
+
data.tar.gz: bc6e8b3d5657bc82bebc1c1913a591e1b7bcb7545f8620d7b4b92704e4735558
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5f315cbe3496bca9a6f8ac33c1af880aba847704d1bda5f313dbfecae44cae8e2d66e6548a3e1eabd473921ec36bfddd0f96fae2dc7f509386a3f31059a53f3
|
|
7
|
+
data.tar.gz: 435300740a43124c459e8688e3a3957693b0fd435e664ee07f52b824b30260d90b4a5d4c70e669157df65a5c1c52acd5a056c69fcf2af1d2ec6e59edf8e9030e
|
data/README.md
CHANGED
|
@@ -22,6 +22,25 @@ transparently apply thecore's scaffolding conventions — no new command vocabul
|
|
|
22
22
|
(check_practices + Root/Member Action generators) is complete** as of this release: `rails
|
|
23
23
|
generate thecore:root_action`, `rails generate thecore:member_action`, and `rails
|
|
24
24
|
thecore:check_practices` (Scaffold Files + Models + Actions, `--fix` included) all ship.
|
|
25
|
+
**Phase 3's App application template** (porting `createApp.js`) is complete as of this release —
|
|
26
|
+
both the core (`lib/templates/app_template.rb`: Rails app + Gemfile stack + vendor placeholders,
|
|
27
|
+
thecore_generators#17) and devcontainer/CI/CLAUDE.md asset fetching from the thecore repo's own
|
|
28
|
+
samples (thecore_generators#18) have shipped. See
|
|
29
|
+
[ADR 0005](https://github.com/gabrieletassoni/thecore/blob/release/3/docs/adr/0005-app-template-scoped-to-rails-new-m-assets-sourced-from-thecore-samples.md)
|
|
30
|
+
in the thecore repo for the full design. **The Collection Action generator** (`rails generate
|
|
31
|
+
thecore:collection_action`, thecore_generators#21) is also complete as of this release — see
|
|
32
|
+
[ADR 0006](https://github.com/gabrieletassoni/thecore/blob/master/docs/adr/0006-atom-generator-dual-ci-manual-submodule-wiring-collection-action-reuses-existing-infra.md)
|
|
33
|
+
in the thecore repo (`master`, thecore's actual default branch — unlike this gem's own
|
|
34
|
+
`release/3`; the ADR 0001-0005 links above predate that distinction being double-checked; note
|
|
35
|
+
that as of this gem's 3.11.0 release the ADR 0006 commit exists only in a local `thecore`
|
|
36
|
+
checkout, not yet pushed to `origin/master` — same class of operational sequencing issue
|
|
37
|
+
`CLAUDE.md` documents for the App template's samples fetch). **`thecore:atom`**
|
|
38
|
+
(`rails generate thecore:atom NAME`, thecore_generators#20/#22) is feature-complete as of this
|
|
39
|
+
release, including its `CLAUDE.md` fetch from thecore's own `samples/ATOM_CLAUDE.md` — but that
|
|
40
|
+
fetch shares the exact same not-yet-pushed caveat as ADR 0006/the App template's own samples
|
|
41
|
+
fetch above: it 404s against the real default GitHub URL until `thecore`'s `master` actually
|
|
42
|
+
carries the commit that added `samples/ATOM_CLAUDE.md`. Phase 4's one remaining piece is
|
|
43
|
+
documenting both new generators in the thecore repo's `GUIDE.md`/`WALKTHROUGH.md` (thecore#19).
|
|
25
44
|
|
|
26
45
|
### What `rails generate model`/`rails generate migration` do now
|
|
27
46
|
|
|
@@ -200,6 +219,92 @@ templates exactly:
|
|
|
200
219
|
XHR `GET` here vs. `fetch` there), and the view adds a `form_with(..., method: :patch)` for
|
|
201
220
|
the PATCH half of the example.
|
|
202
221
|
|
|
222
|
+
### `rails generate thecore:atom NAME`
|
|
223
|
+
|
|
224
|
+
A Ruby port of `thecore_code_extension`'s `createATOM.js` — produces a complete, working ATOM
|
|
225
|
+
(a Rails engine, the Thecore unit of modular functionality) from a terminal, no VS Code
|
|
226
|
+
required:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
rails generate thecore:atom tcp_debugger
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Unlike every other generator in this gem, `thecore:atom` takes **no `--atom=NAME` option** —
|
|
233
|
+
creating a *new* ATOM only ever makes sense from a host app's own root, so it doesn't include
|
|
234
|
+
`Thecore::Generators::AtomAware` at all. It fails fast with a clear error if `vendor/submodules/`
|
|
235
|
+
doesn't exist yet in the current app, if `NAME` isn't a valid gem name (lowercase letters,
|
|
236
|
+
digits, underscores, hyphens, starting with a letter), or if `vendor/submodules/<NAME>` already
|
|
237
|
+
exists — the last one matters because `rails plugin new`'s own `-f` (force) flag would otherwise
|
|
238
|
+
silently overwrite an existing ATOM with the same name.
|
|
239
|
+
|
|
240
|
+
It prompts (interactively, or via `--summary=`/`--description=`/`--author=`/`--email=`/`--url=`
|
|
241
|
+
with `--non-interactive`) for the same five fields `createATOM.js` always has, then:
|
|
242
|
+
|
|
243
|
+
- Shells to `rails plugin new <path> -fG --skip-gemfile-entry --skip-hotwire --full` (via
|
|
244
|
+
`bundle exec`, for robust gem resolution regardless of environment), producing the standard
|
|
245
|
+
Rails engine skeleton.
|
|
246
|
+
- Asks (`yes?`-style, default yes; `--skip-api-admin-deps` in non-interactive mode) whether to
|
|
247
|
+
add `model_driven_api`/`thecore_ui_rails_admin` as dependencies — at this gem's own ADR 0001
|
|
248
|
+
floor (`~> 3.9`/`~> 3.8`), not `createATOM.js`'s stale `~> 3.1`/`~> 3.2`. Declining adds
|
|
249
|
+
neither; the Scaffold Files/directories below are created either way.
|
|
250
|
+
- Creates the same Scaffold Files/directories `createATOM.js` always has: `db/migrate`, the
|
|
251
|
+
API/RailsAdmin concern directories, `config/initializers`, `config/locales`,
|
|
252
|
+
`lib/root_actions`/`member_actions`/`collection_actions`, JS/CSS asset directories, the
|
|
253
|
+
RailsAdmin main view directory, `.github/workflows` — plus `after_initialize.rb`/`assets.rb`/
|
|
254
|
+
`abilities.rb`, `db/seeds.rb`, and `en.yml`/`it.yml` locale files, all with the same skeleton
|
|
255
|
+
content `createATOM.js` already produces.
|
|
256
|
+
- Generates **both** `.github/workflows/gempush.yml` and `.gitlab-ci.yml` unconditionally — no
|
|
257
|
+
hosting-profile prompt (see ADR 0006 for why: which git host a developer pushes to is a
|
|
258
|
+
per-developer choice this ecosystem already treats as generic). `gempush.yml`'s two
|
|
259
|
+
long-standing bugs are fixed here (a broken `awk` pipeline computing the version string; a
|
|
260
|
+
`version_exists` check referenced in `if:` conditions but never actually set, so the
|
|
261
|
+
tag/publish steps have never run for any ATOM generated this way). The gemspec's
|
|
262
|
+
`allowed_push_host` stays hardcoded to `https://rubygems.org`.
|
|
263
|
+
- Rewrites the gemspec's authors/email/homepage/summary/description/metadata fields via targeted
|
|
264
|
+
in-memory substitutions (not `createATOM.js`'s own blind full-file line rewrite, which —
|
|
265
|
+
verified directly against a current `rails plugin new --full` gemspec — silently drops the
|
|
266
|
+
gem's own `rails` dependency when adding the two Thecore ones; this appends instead of
|
|
267
|
+
replacing).
|
|
268
|
+
- `git init`s the new ATOM directory with one initial commit, then **logs** (never runs) the
|
|
269
|
+
exact follow-up commands to create a remote and `git submodule add` it into the host app —
|
|
270
|
+
worded generically, no GitHub/GitLab assumption (ADR 0006: automating a remote-repo-creating,
|
|
271
|
+
credential-dependent step isn't something this generator does on your behalf).
|
|
272
|
+
- Adds `gem "<name>", path: "vendor/submodules/<name>"` to the host app's own `Gemfile` (via
|
|
273
|
+
Thor's own `gem` action) — skipped, with a warning, if the Gemfile already declares a gem with
|
|
274
|
+
that name (the same real collision the `vendor/submodules/<NAME>` guard above protects against,
|
|
275
|
+
one layer up: a duplicate entry for the same gem breaks the next `bundle install`). Does
|
|
276
|
+
**not** run `bundle install` — same as every other generator in this gem that touches a
|
|
277
|
+
Gemfile.
|
|
278
|
+
- Fetches a `CLAUDE.md` skeleton from `thecore`'s own `samples/ATOM_CLAUDE.md` and writes it as
|
|
279
|
+
the new ATOM's `CLAUDE.md`, via `Thecore::Generators::SampleFetcher` — a shared module using
|
|
280
|
+
the exact same `THECORE_SAMPLES_SOURCE` override mechanism the App template's own asset fetch
|
|
281
|
+
already established (`ENV["THECORE_SAMPLES_SOURCE"]`, defaulting to `thecore`'s `master`
|
|
282
|
+
branch; http(s) fetched over the network, anything else read as a local directory; fails fast
|
|
283
|
+
with a clear message naming the file/source/error on failure). Like the App template's own
|
|
284
|
+
`CLAUDE.md`/`.gitlab-ci.yml` fetches, this 404s against the real default URL until `thecore`'s
|
|
285
|
+
`master` actually carries the commit that added `samples/ATOM_CLAUDE.md` — see the caveat
|
|
286
|
+
above.
|
|
287
|
+
|
|
288
|
+
### `rails generate thecore:collection_action NAME`
|
|
289
|
+
|
|
290
|
+
The third sibling to `thecore:root_action`/`thecore:member_action` — structurally identical
|
|
291
|
+
(same shared `AtomAware`/`CompanionFiles`/`ActionCompanion` modules, same file layout, same
|
|
292
|
+
`--atom=NAME`/idempotent-re-run behavior). Unlike Root/Member, there's no
|
|
293
|
+
`addCollectionAction.js` this ports — `checkPractices.js` audited `collection_actions` but
|
|
294
|
+
nothing ever generated them, so this is new, not a port:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
rails generate thecore:collection_action my_action
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Its own `templates/action.rb.tt` mirrors Root Action's simplicity — `add_action "my_action",
|
|
301
|
+
:base, :collection do ... end`, a minimal GET/JSON example with an `ActivityLogChannel`
|
|
302
|
+
broadcast — rather than the more complex, hand-written `save_filters.rb`/`load_filters.rb`
|
|
303
|
+
pattern already living in `thecore_ui_rails_admin`: a generator's starter template exists to be
|
|
304
|
+
customized from a simple base, not to demonstrate every RailsAdmin `:collection` feature. A
|
|
305
|
+
collection action operates against a model's whole index (all records), as distinct from a
|
|
306
|
+
member action (one record) or a root action (global, no model scope at all).
|
|
307
|
+
|
|
203
308
|
### `rails thecore:check_practices`
|
|
204
309
|
|
|
205
310
|
A Ruby port of `thecore_code_extension`'s `checkPractices.js` — audits **Scaffold Files**
|
|
@@ -230,17 +335,15 @@ Flags combine freely, e.g. `rails thecore:check_practices -- --atom=my_atom --fi
|
|
|
230
335
|
`cattr_accessor :json_attrs` for `Api::`, `rails_admin do` for `RailsAdmin::`). Not fixable —
|
|
231
336
|
regenerating over an existing, hand-edited concern could clobber real customization.
|
|
232
337
|
- **Actions** — scans `root_actions`, `member_actions`, and `collection_actions` (in `lib/` for
|
|
233
|
-
an ATOM, `config/` for the host app), with the same rules for all three
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
*
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
kinds), and a missing locale entry checked against **every** `*.yml` already present in the
|
|
243
|
-
locales directory, not just `en`/`it` (fixable, all three kinds).
|
|
338
|
+
an ATOM, `config/` for the host app), with the same rules for all three. Reports
|
|
339
|
+
missing/broken action-file markers (`RailsAdmin::Config::Actions.add_action`, `http_methods`
|
|
340
|
+
— never fixable), a missing companion view/JS/SCSS or one present but missing its own marker
|
|
341
|
+
(a *missing* companion is fixable for all three kinds — `root_action`/`member_action`/
|
|
342
|
+
`collection_action` — by delegating straight to that kind's own generator's template
|
|
343
|
+
rendering; an *existing* companion missing a marker is never fixable, same reasoning as
|
|
344
|
+
Models), a missing `after_initialize.rb` require line (fixable, all three kinds), and a
|
|
345
|
+
missing locale entry checked against **every** `*.yml` already present in the locales
|
|
346
|
+
directory, not just `en`/`it` (fixable, all three kinds).
|
|
244
347
|
|
|
245
348
|
Default output is human-readable text grouped by file; `--json` emits
|
|
246
349
|
`{ "violations": [{ "file", "line", "message", "severity", "fixable", "code" }] }` — `code` is
|
|
@@ -248,9 +351,58 @@ a stable identifier (e.g. `missing_after_initialize`, `orphan_api_include`,
|
|
|
248
351
|
`missing_companion_view`) a future consumer can filter on without depending on `message` text.
|
|
249
352
|
`--fix` applies every fixable violation in one pass with no confirmation of its own — whoever
|
|
250
353
|
passes it has already decided — then re-scans and reports/exits based on whatever violations
|
|
251
|
-
remain (so a violation this run can't fix, e.g.
|
|
252
|
-
after `--fix`). The task exits
|
|
253
|
-
usable as a CI gate either
|
|
354
|
+
remain (so a violation this run can't fix, e.g. an action file's own broken
|
|
355
|
+
`RailsAdmin::Config::Actions.add_action` marker, still shows up after `--fix`). The task exits
|
|
356
|
+
non-zero whenever any violation remains, zero otherwise, so it's usable as a CI gate either
|
|
357
|
+
with or without `--fix`.
|
|
358
|
+
|
|
359
|
+
### Application Template (`rails new -m`) (thecore_generators#17/#18)
|
|
360
|
+
|
|
361
|
+
A Ruby port of `thecore_code_extension`'s `createApp.js`, as a genuine Rails application
|
|
362
|
+
template rather than a `thecore:*` generator — its entry point is `rails new -m`, not `rails
|
|
363
|
+
generate`:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
rails new myapp --database=postgresql --asset-pipeline=sprockets \
|
|
367
|
+
-m https://raw.githubusercontent.com/gabrieletassoni/thecore_generators/release/3/lib/templates/app_template.rb
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Run inside a devcontainer already created by the "Setup Devcontainer" VS Code command — a
|
|
371
|
+
bootstrap step this template doesn't invoke or modify itself (that command's own code is
|
|
372
|
+
untouched), even though the template's own devcontainer-asset fetch below does overwrite the
|
|
373
|
+
files that bootstrap step created, by design. See
|
|
374
|
+
[ADR 0005](https://github.com/gabrieletassoni/thecore/blob/release/3/docs/adr/0005-app-template-scoped-to-rails-new-m-assets-sourced-from-thecore-samples.md)
|
|
375
|
+
for the full design and why the two stay separate).
|
|
376
|
+
|
|
377
|
+
- **Core Gemfile stack, active** — `devise`, `cancancan`, `rails_admin`, `sassc-rails`,
|
|
378
|
+
`model_driven_api` (`~> 3.9`), `thecore_ui_rails_admin` (`~> 3.8` — both meeting ADR 0001's
|
|
379
|
+
`DefaultModuleRegistry` floor), `rails-erd` (`:development`). `thecore_generators` itself is
|
|
380
|
+
added too, `group: :development` — so the generated app can immediately use every
|
|
381
|
+
generator/task documented above without a manual Gemfile edit first.
|
|
382
|
+
- **The rest of the generic Thecore ecosystem, commented out** — `thecore_auth_commons`,
|
|
383
|
+
`thecore_settings`, `thecore_print_commons`, `thecore_background_jobs`, `thecore_ui_commons`,
|
|
384
|
+
`thecore_tcp_debug`, `thecore_download_documents`, `thecore_dataentry_commons`,
|
|
385
|
+
`thecore_connectors`, each with a one-line purpose comment — discoverable but off by default,
|
|
386
|
+
the same "commented but documented" philosophy ADR 0005 applies to the devcontainer's `gh`/
|
|
387
|
+
`glab` CLI mounts below.
|
|
388
|
+
- **`vendor/submodules/`/`vendor/external/`** — created empty (a `.keep` file each), not
|
|
389
|
+
pre-wired with any submodule or gem. Per ADR 0005 these are developer-convenience clone
|
|
390
|
+
locations, not template content.
|
|
391
|
+
- **Devcontainer/CI/CLAUDE.md**, fetched from the `thecore` repo's own `samples/` (single source
|
|
392
|
+
of truth, not duplicated here) and written unconditionally, overwriting whatever the bootstrap
|
|
393
|
+
"Setup Devcontainer" step created: `.devcontainer/*` (base image, plugin mounts, `gh`/`glab`
|
|
394
|
+
CLI config mounts commented out by default), `.gitlab-ci.yml` (build/test/lint/deploy, no
|
|
395
|
+
customer-specific paths), and `CLAUDE.md` (universal sections only, project-specific sections
|
|
396
|
+
left as TODO placeholders). The fetch location is one overridable point,
|
|
397
|
+
`ENV["THECORE_SAMPLES_SOURCE"]`, defaulting to the raw GitHub URL for `thecore`'s `samples/`
|
|
398
|
+
on `master` (`thecore`'s actual default branch).
|
|
399
|
+
- **The standard installer chain** (`devise:install`, `rails_admin:install`, `active_storage:
|
|
400
|
+
install`, `action_text:install`, `action_mailbox:install`, `cancan:ability`, `erd:install`,
|
|
401
|
+
each preceded by the necessary `bundle install`) is genuinely optional, gated behind an
|
|
402
|
+
interactive prompt (`yes?`, wrapped in `after_bundle` so it only ever runs once the gems
|
|
403
|
+
above are actually bundled) — a developer bootstrapping without network access can decline
|
|
404
|
+
and run these by hand later. There is no non-interactive/unattended flag for this in the
|
|
405
|
+
current version (tracked as a future improvement, not silently missing).
|
|
254
406
|
|
|
255
407
|
## Installation
|
|
256
408
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "generators/thecore/workspace_context"
|
|
2
|
+
require "generators/thecore/tty_detection"
|
|
2
3
|
|
|
3
4
|
module Thecore
|
|
4
5
|
module Generators
|
|
@@ -114,7 +115,7 @@ module Thecore
|
|
|
114
115
|
# includer was explicitly told not to prompt via --non-interactive) -
|
|
115
116
|
# default straight to has_many, per ADR 0003.
|
|
116
117
|
def interactive_association_prompt?
|
|
117
|
-
!options[:non_interactive] &&
|
|
118
|
+
!options[:non_interactive] && Thecore::Generators::TtyDetection.real_tty?
|
|
118
119
|
end
|
|
119
120
|
|
|
120
121
|
def concern_path_for(target_class_name)
|