Skip to content

Commit ec1f42d

Browse files
committed
(MODULES-11816) Refactor CLAUDE.md to avoid duplicating authoritative sources
Address review feedback from @bastelfreak: drop content that duplicates existing single-sources-of-truth (OS list, dependency versions, lint disabled-checks, custom type/provider enumeration, spec subdirectory listing). Replace with an explicit "Authoritative sources" table that points readers at the real file for each piece of information. Keeps the non-discoverable content: three-layer architecture, the default-vs-versioned package-name branch in params.pp, the include_examples convention, and how the CI matrix is actually built.
1 parent 1f43031 commit ec1f42d

1 file changed

Lines changed: 32 additions & 54 deletions

File tree

CLAUDE.md

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,74 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## Module overview
66

7-
`puppetlabs-postgresql` manages PostgreSQL packages, services, databases, roles, grants, and `pg_hba.conf` / `pg_ident.conf` rules across RHEL-family, Debian-family, SLES, Arch, Gentoo, FreeBSD, and OpenBSD. The Puppet Forge entry point is `class { 'postgresql::server': }`, but every consumer is expected to declare `postgresql::globals` first (see Architecture).
7+
`puppetlabs-postgresql` manages PostgreSQL packages, services, databases, roles, grants, and `pg_hba.conf` / `pg_ident.conf` rules. Entry point is `class { 'postgresql::server': }`, but every consumer is expected to declare `postgresql::globals` first (see Architecture). Supported OSes, Puppet version range, and module dependencies are declared in `metadata.json` — treat that as the single source of truth.
88

99
## Architecture
1010

11-
The module has a three-layer composition that you must understand before changing anything in `manifests/`:
11+
The module has a three-layer composition that must be understood before changing anything in `manifests/`:
1212

1313
1. **`manifests/globals.pp`** — sole source of truth for version + OS detection. Resolves `$default_version` from `$facts['os']['family']`, `$facts['os']['name']`, and `$facts['os']['release']['major']` (a nested selector hash, ~70 lines). Also resolves `$default_postgis_version`. Optionally configures the PGDG yum/apt repo via `postgresql::repo`, or enables `postgresql::dnfmodule` on EL8+/Fedora. **Must be included before `postgresql::server`**`postgresql::server` reads `$postgresql::globals::default_version` to decide package names. Adding a new OS or version means editing the selector here.
1414

1515
2. **`manifests/params.pp`** — translates the resolved version into package/service/path names per OS. Has a critical branch: if `$version == $default_version` (and not Amazon Linux), it uses unversioned package names (`postgresql`, `postgresql-server`) from the OS base repo; otherwise it constructs versioned names (`postgresql16-server`) for the PGDG repo. Changing default version mappings without understanding this branch will break either base-repo or PGDG installs.
1616

17-
3. **`manifests/server.pp` + `manifests/server/`** — the user-facing API. `server.pp` orchestrates `install``initdb``config``service``reload`. The defined types under `manifests/server/` (`db.pp`, `role.pp`, `grant.pp`, `database_grant.pp`, `default_privileges.pp`, `extension.pp`, `pg_hba_rule.pp`, `schema.pp`, `tablespace.pp`, `table_grant.pp`, etc.) are the public interface — each one ultimately fires a `postgresql_psql` custom resource.
17+
3. **`manifests/server.pp` + `manifests/server/`** — the user-facing API. `server.pp` orchestrates `install``initdb``config``service``reload`. The defined types under `manifests/server/` are the public interface — each one ultimately fires a `postgresql_psql` custom resource (see `lib/puppet/type/postgresql_psql.rb`).
1818

1919
**Multi-instance support** (`manifests/server_instance.pp` + `manifests/server/instance/`) is opt-in and currently tested only on RHEL 8 / CentOS Stream 8 — see the warning at `manifests/server_instance.pp:39`. Treat changes there as RHEL-8-specific unless explicitly broadening scope.
2020

21-
**Hiera-driven OS defaults**: `hiera.yaml` is keyed by `os.name`/`os.family` + `os.release.major`. Per-OS YAML lives in `data/os/<Family>/<major>.yaml` and `data/os/<Name>.yaml`. Add new-OS defaults here rather than hard-coding them in `params.pp` when possible.
21+
**Custom types and providers** live in `lib/puppet/{type,provider}/`. The workhorse is `postgresql_psql`, which runs idempotent SQL via the `unless`/`onlyif` query pattern — every `server::*` defined type funnels through it. The manifests are mostly orchestration; the actual work happens in these Ruby files.
2222

23-
**Custom types and providers** (`lib/puppet/`) — these are the actual workhorses; the manifests just wire them:
24-
- `postgresql_psql` (type + provider in `lib/puppet/type/postgresql_psql.rb` and `lib/puppet/provider/postgresql_psql/ruby.rb`): runs idempotent SQL via the `unless`/`onlyif` query pattern. Every `server::*` defined type funnels through this.
25-
- `postgresql_conf`: manages `postgresql.conf` entries as resources.
26-
- `postgresql_conn_validator`: connectivity check; backed by `lib/puppet/util/postgresql_validator.rb`.
27-
- `postgresql_replication_slot`: replication slot management.
28-
- Functions in `lib/puppet/functions/`: `postgresql_password` (md5/scram-sha-256 hashing), `postgresql_escape` (dollar-quoting), plus the `postgresql::` namespace.
29-
- Puppet type aliases in `types/`: `pg_hba_rule`, `pg_hba_rules`, `pg_password_encryption`, etc. — used as parameter types in the manifests.
23+
**Hiera-driven OS defaults**: `hiera.yaml` is keyed by `os.name`/`os.family` + `os.release.major`. Per-OS YAML lives in `data/os/<Family>/<major>.yaml` and `data/os/<Name>.yaml`. Add new-OS defaults here rather than hard-coding them in `params.pp` when possible.
3024

3125
## Common commands
3226

33-
All commands assume `bundle install --path=vendor` has been run.
27+
Assume `bundle install --path=vendor` has been run.
3428

35-
**Validation (run before pushing):**
3629
```sh
37-
bundle exec rake validate # puppet syntax + lint + metadata-json-lint
38-
bundle exec rake lint # puppet-lint only
39-
bundle exec rake rubocop # Ruby style for lib/ and spec/
40-
```
41-
42-
**Unit tests:**
43-
```sh
44-
bundle exec rake spec # full unit suite (rspec-puppet + lib specs)
45-
bundle exec rake parallel_spec # same, parallelized — preferred for full runs
30+
bundle exec rake validate # puppet syntax + lint + metadata-json-lint (run before pushing)
31+
bundle exec rake parallel_spec # full unit suite, parallelized — preferred over `rake spec` for full runs
4632
bundle exec rspec spec/classes/globals_spec.rb # one file
4733
bundle exec rspec spec/classes/globals_spec.rb -e "RedHat 8" # one example
48-
```
49-
50-
`rake spec` automatically runs `spec_prep` first, which clones the fixture modules listed in `.fixtures.yml` into `spec/fixtures/modules/`. If fixtures get stale after dependency changes, run `bundle exec rake spec_clean && bundle exec rake spec_prep`.
5134

52-
**Acceptance tests (Litmus, run against a real container/VM):**
53-
```sh
5435
bundle exec rake 'litmus:provision[docker,litmusimage/almalinux:9]'
5536
bundle exec rake 'litmus:install_agent'
5637
bundle exec rake 'litmus:install_module'
5738
bundle exec rake 'litmus:acceptance:parallel'
5839
bundle exec rake 'litmus:tear_down'
59-
```
6040

61-
A single acceptance spec, against an already-provisioned target listed in `spec/fixtures/litmus_inventory.yaml`:
62-
```sh
63-
bundle exec rspec spec/acceptance/server_spec.rb
41+
bundle exec rake strings:generate:reference # regenerate REFERENCE.md after editing puppet-strings annotations
6442
```
6543

66-
**Reference docs:** `REFERENCE.md` is generated from puppet-strings annotations on classes/defines/types. Regenerate with `bundle exec rake strings:generate:reference` after editing parameter documentation.
67-
68-
## Spec layout conventions
44+
`rake spec` automatically runs `spec_prep` first, cloning the fixture modules listed in `.fixtures.yml` into `spec/fixtures/modules/`. If fixtures get stale after dependency changes, run `bundle exec rake spec_clean && bundle exec rake spec_prep`.
6945

70-
- `spec/classes/``rspec-puppet` catalog tests for classes in `manifests/`.
71-
- `spec/defines/``rspec-puppet` for defined types.
72-
- `spec/functions/` — function tests.
73-
- `spec/type_aliases/` — tests for Puppet type aliases in `types/`.
74-
- `spec/unit/{type,provider,puppet}/` — pure Ruby tests for `lib/puppet/`.
75-
- `spec/acceptance/` — Litmus tests; run on provisioned hosts, NOT in unit runs.
46+
## Spec conventions
7647

77-
`spec/spec_helper_local.rb` defines `shared_context` blocks for OSes (`'RedHat 8'`, `'Debian 11'`, etc.) backed by `rspec-puppet-facts`. When adding tests for a new OS, prefer adding a `shared_context` here over inlining fact hashes. Use `include_examples 'RedHat 8'` (note: `include_examples`, not `include_context` — that's the project convention).
48+
`spec/spec_helper_local.rb` defines `shared_context` blocks for OSes (`'RedHat 8'`, `'Debian 11'`, etc.) backed by `rspec-puppet-facts`. When adding tests for a new OS, prefer adding a `shared_context` here over inlining fact hashes. Use `include_examples 'RedHat 8'` note: `include_examples`, **not** `include_context`. That's the project convention and tests written with the wrong helper will silently behave differently.
7849

79-
## Lint and style customizations
50+
## Lint and CI
8051

81-
`.puppet-lint.rc` and the `Rakefile` disable: `80chars`, `140chars`, `class_inherits_from_params_class`, `autoloader_layout`, `documentation`, `single_quote_string_with_variables`, `anchor_resource`, `params_empty_string_assignment`, `relative`. `fail_on_warnings` is **on** — any new puppet-lint warning will fail CI. The lint ignores `types/**/*.pp` (Puppet type aliases use a different syntax that puppet-lint doesn't grok well).
52+
Lint configuration lives in `.puppet-lint.rc` and the `Rakefile`. `fail_on_warnings` is **on** — any new puppet-lint warning will fail CI. The `types/**/*.pp` directory is excluded from lint (Puppet type aliases use syntax that puppet-lint doesn't grok well). RuboCop exceptions are tracked in `.rubocop_todo.yml` — prefer fixing offenses over adding to the todo list.
8253

83-
RuboCop config lives in `.rubocop.yml` with overrides for puppet-module style. Existing exceptions are tracked in `.rubocop_todo.yml` — prefer fixing offenses over adding to the todo list.
54+
`.github/workflows/{ci,nightly}.yml` are thin shims that call reusable workflows from `puppetlabs/cat-github-actions`. The acceptance matrix is built by `matrix_from_metadata_v3`, which reads `metadata.json`'s `operatingsystem_support` **and** cross-references the platform catalog in `puppetlabs/puppet_litmus/exe/matrix.json`. **Adding an OS/version to `metadata.json` does NOT automatically produce a CI job**`puppet_litmus`'s matrix.json must also have a Docker image or provision-service entry for that platform. This is the most common cause of "I added the OS but no job appeared".
8455

85-
## CI
86-
87-
`.github/workflows/ci.yml` and `nightly.yml` are thin shims that call reusable workflows from `puppetlabs/cat-github-actions`:
88-
- `module_ci.yml` runs `rake validate` and `rake parallel_spec`.
89-
- `module_acceptance.yml` runs Litmus against a matrix built by `matrix_from_metadata_v3`, which reads `metadata.json`'s `operatingsystem_support` and cross-references the platform catalog in `puppetlabs/puppet_litmus/exe/matrix.json`. **Adding an OS/version to `metadata.json` does NOT automatically produce a CI job**`puppet_litmus`'s matrix.json must also have a Docker image or provision-service entry for that platform.
90-
91-
## Conventions when committing
56+
## Commit and branch conventions
9257

9358
- Branch names follow `<module-id>-<short-change-related-name>`, where `<module-id>` is the Jira ticket key (e.g. `MODULES-11816-add-claude-md`, `MODULES-12345-fix-el10-default-version`). Keep the trailing slug short, kebab-cased, and descriptive of the change. For test-PR runs of community PRs, the convention used here is `<module-id>-pr<upstream-pr-number>` (e.g. `MODULES-11807-pr1650`).
9459
- Commit messages and PR titles start with `(MODULES-XXXX)` — the Jira automation uses this to link commits back to tickets.
9560
- When cherry-picking community PRs, squash to one commit and add a `Co-authored-by:` trailer for the original contributor.
9661

97-
## Dependency boundaries
98-
99-
`metadata.json` declares the supported Puppet (`>= 8.0.0 < 9.0.0`) and module-dependency ranges. The hard runtime dependencies are `puppetlabs/stdlib`, `puppetlabs/apt`, `puppet/systemd`, `puppetlabs/concat`. Don't introduce new module dependencies without an explicit Jira ticket — they propagate to every consumer.
62+
## Authoritative sources (do not duplicate here)
63+
64+
When you need any of these, read the file directly — the lists drift fast and a copy here would lie:
65+
66+
| What | Authoritative file |
67+
|---|---|
68+
| Supported operating systems and versions | `metadata.json``operatingsystem_support` |
69+
| Puppet version range, module dependencies | `metadata.json``requirements`, `dependencies` |
70+
| Class, defined-type, and parameter docs | `REFERENCE.md` (regenerate with `rake strings:generate:reference`) |
71+
| Lint configuration | `.puppet-lint.rc`, `Rakefile` |
72+
| Custom types and providers | `lib/puppet/type/`, `lib/puppet/provider/` |
73+
| Puppet type aliases | `types/` |
74+
| OS-specific Hiera defaults | `data/os/` |
75+
| Fixture-module pins for unit tests | `.fixtures.yml` |
76+
| CI workflow definitions | `.github/workflows/`, `puppetlabs/cat-github-actions` |
77+
| CI platform catalog | `puppetlabs/puppet_litmus/exe/matrix.json` |

0 commit comments

Comments
 (0)