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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b52de470428f2cecb91388721b140a88d6cdb0a1e0ea7b3ce07b0b855e17fbaa
4
- data.tar.gz: 5a6147ac698f2820027e493bd8bdee96c13f39867dd50f6b472a495f5f01b829
3
+ metadata.gz: 753f6373a24773431ad2987bd84b7d8609f4a9bedb32dff5a59264bc37c68081
4
+ data.tar.gz: bc6e8b3d5657bc82bebc1c1913a591e1b7bcb7545f8620d7b4b92704e4735558
5
5
  SHA512:
6
- metadata.gz: 52374b36988c76209702afb27c59e32ac95e05c53ca805914257264bb3eaae31ee06fa3329faae3a6da5c25742d31e136f470a22cf1897cdbd9a17caad010f97
7
- data.tar.gz: 75083924ea8bdc22bf39d5dbea930da5ec5eb37d736107b43037e235d40a4430b0ae963a24133b9789631135de83b51cdfb1afd82515c4d2f0c69ddb43bb30a2
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
- `collection_actions` is scanned even though no generator creates files there yet, since a
235
- hand-written one could already exist and go unreported otherwise. Reports missing/broken
236
- action-file markers (`RailsAdmin::Config::Actions.add_action`, `http_methods`never
237
- fixable), a missing companion view/JS/SCSS or one present but missing its own marker (a
238
- *missing* companion is fixable for `root_action`/`member_action`, by delegating straight to
239
- that generator's own template rendering never for `collection_action`, which has no
240
- generator to delegate to; an *existing* companion missing a marker is never fixable, same
241
- reasoning as Models), a missing `after_initialize.rb` require line (fixable, all three
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. a `collection_action` companion, still shows up
252
- after `--fix`). The task exits non-zero whenever any violation remains, zero otherwise, so it's
253
- usable as a CI gate either with or without `--fix`.
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] && $stdin.tty? && $stdout.tty?
118
+ !options[:non_interactive] && Thecore::Generators::TtyDetection.real_tty?
118
119
  end
119
120
 
120
121
  def concern_path_for(target_class_name)