From a6e55562392686f17395fe4d60a3f7e6530fbeeb Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Tue, 28 Apr 2026 01:45:38 +0200 Subject: [PATCH 1/3] docs(README): document four per-plan-type --services slugs + add example 8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #138. The four per-plan-type Savings Plans `--services` flag values from PR #123 (`savings-plans-{compute,ec2instance,sagemaker,database}`) plus the `savingsplans` / `sp` fan-out aliases were never documented in the README because the docs commit was deferred over markdownlint table-style errors. Changes: - Expanded the `-s, --services` flag-table row to spell out the per-RI services, the four per-plan-type SP slugs, and the fan-out aliases. - Updated examples 6 and 7 to use the per-plan-type slugs directly (`savings-plans-database`, `savings-plans-compute,...-ec2instance`) instead of `savingsplans --include-sp-types Database`. - Added example 8 demonstrating the `savingsplans` fan-out alias and a callout that explicit per-plan-type slugs are preferred when scope matters. Disabled MD060 (table-column-style) in `.markdownlint.yaml`. The README mixes tables of wildly different widths — small flag/value pairs and long descriptive rows. Forcing a single style across all of them either crams long-text rows into ugly compact form or pads tiny tables with mountains of trailing whitespace. Both are worse than the inconsistency the rule was trying to flag, and the rule was the only thing blocking PR #123's docs commit. Aligned a few tables on the way through (`Execution Control`, `Filtering`, `Authentication`) into the wider style; left the others in their existing compact form. `pre-commit run markdownlint --files README.md` clean. --- README.md | 79 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index ac42b32dc..05b6cac4f 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ go install github.com/LeanerCloud/CUDly/cmd@latest | Flag | Description | Default | |------|-------------|---------| -| `-s, --services` | Comma-separated service list (rds,elasticache,ec2,opensearch,redshift,memorydb,savingsplans) | rds | +| `-s, --services` | Comma-separated service list. Per-RI services: `rds`, `elasticache`, `ec2`, `opensearch`, `redshift`, `memorydb`. Per-plan-type Savings Plans: `savings-plans-compute`, `savings-plans-ec2instance`, `savings-plans-sagemaker`, `savings-plans-database`. Fan-out aliases: `savingsplans` and `sp` expand to all four SP plan types. | rds | | `--all-services` | Process all supported services | false | ### Purchase Configuration @@ -161,28 +161,28 @@ go install github.com/LeanerCloud/CUDly/cmd@latest ### Execution Control -| Flag | Description | Default | -|------|-------------|---------| -| `--purchase` | Execute actual purchases (dry-run by default) | false | -| `--yes` | Skip confirmation prompts | false | -| `-i, --input-csv` | Input CSV file with recommendations | - | -| `-o, --output` | Output CSV file path | auto-generated | +| Flag | Description | Default | +| ----------------- | --------------------------------------------- | -------------- | +| `--purchase` | Execute actual purchases (dry-run by default) | false | +| `--yes` | Skip confirmation prompts | false | +| `-i, --input-csv` | Input CSV file with recommendations | - | +| `-o, --output` | Output CSV file path | auto-generated | ### Filtering -| Flag | Description | -|------|-------------| -| `--include-regions` | Only include these regions | -| `--exclude-regions` | Exclude these regions | -| `--include-instance-types` | Only include these instance types | -| `--exclude-instance-types` | Exclude these instance types | -| `--include-engines` | Only include these database engines | -| `--exclude-engines` | Exclude these database engines | -| `--include-accounts` | Only include these account names | -| `--exclude-accounts` | Exclude these account names | -| `--include-extended-support` | Include instances on extended support engine versions (see below) | -| `--include-sp-types` | Only include these Savings Plan types (Compute, EC2Instance, SageMaker, Database) | -| `--exclude-sp-types` | Exclude these Savings Plan types | +| Flag | Description | +| ---------------------------- | --------------------------------------------------------------------------------- | +| `--include-regions` | Only include these regions | +| `--exclude-regions` | Exclude these regions | +| `--include-instance-types` | Only include these instance types | +| `--exclude-instance-types` | Exclude these instance types | +| `--include-engines` | Only include these database engines | +| `--exclude-engines` | Exclude these database engines | +| `--include-accounts` | Only include these account names | +| `--exclude-accounts` | Exclude these account names | +| `--include-extended-support` | Include instances on extended support engine versions (see below) | +| `--include-sp-types` | Only include these Savings Plan types (Compute, EC2Instance, SageMaker, Database) | +| `--exclude-sp-types` | Exclude these Savings Plan types | ### Extended Support Filtering @@ -210,9 +210,9 @@ For example, if you purchase 5 db.r6g.large RIs and run CUDly again within 24 ho ### Authentication -| Flag | Description | -|------|-------------| -| `--profile` | AWS profile to use | +| Flag | Description | +| ---------------------- | ---------------------------------------- | +| `--profile` | AWS profile to use | | `--validation-profile` | AWS profile for instance type validation | ## Usage Examples @@ -283,28 +283,43 @@ Only process specific regions with instance limits: ### Example 6: Database Savings Plans Only ```bash -# Get only Database Savings Plans recommendations -./cudly --services savingsplans \ - --include-sp-types Database \ +# Get only Database Savings Plans recommendations using the per-plan-type slug +./cudly --services savings-plans-database \ --term 1 \ --coverage 80 ``` -### Example 7: Exclude SageMaker Savings Plans +### Example 7: Compute + EC2 Instance Savings Plans ```bash -# Get all Savings Plans except SageMaker +# Pick exactly the SP plan-types you want by listing per-plan-type slugs +./cudly --services savings-plans-compute,savings-plans-ec2instance \ + --term 3 \ + --coverage 80 +``` + +### Example 8: All Savings Plans via Fan-out Alias + +```bash +# `savingsplans` (and `sp`) is shorthand that fans out to every SP +# plan type — equivalent to listing all four per-plan-type slugs. ./cudly --services savingsplans \ - --exclude-sp-types SageMaker \ - --term 3 + --term 3 \ + --coverage 80 ``` +> **Per-plan-type vs alias**: prefer the explicit per-plan-type slugs +> (`savings-plans-compute`, `savings-plans-ec2instance`, +> `savings-plans-sagemaker`, `savings-plans-database`) when you want +> precise scope. Use the `savingsplans` / `sp` alias only when you +> intentionally want all four SP plan types together. + ## Coverage Percentage The coverage percentage controls what portion of recommendations to act on: | Coverage | Description | Use Case | -|----------|-------------|----------| +| -------- | ----------- | -------- | | 100% | All recommended instances | Maximum savings, stable workloads | | 75% | Three-quarters of recommendations | Balanced approach | | 50% | Half of recommendations | Conservative adoption | @@ -623,7 +638,7 @@ go test ./providers/aws/... ### Project Structure | Directory | Purpose | -|-----------|---------| +| --------- | ------- | | `cmd/` | CLI implementation, flag parsing, orchestration | | `pkg/common/` | Cloud-agnostic types (Provider, Service, Commitment) | | `pkg/provider/` | Provider interface, registry, factory | From 4fc74f031a85f2c5652c0e527d0634f01966f0c3 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Tue, 19 May 2026 17:11:39 +0200 Subject: [PATCH 2/3] docs(README): add `savings-plans` to SP fan-out aliases cmd/main.go:180 accepts three fan-out aliases (`savingsplans`, `savings-plans`, `sp`) that expand to all four per-plan-type SP slugs. The README listed only two of them (`savingsplans` and `sp`), so users following the docs would not discover the hyphenated alias even though the CLI accepts it. Updates: - README.md L108 (`-s, --services` table row): add `savings-plans` to the fan-out alias list so the table matches parseServices in cmd/main.go. - README.md L263 (Example 8 comment): mention `savings-plans` alongside `savingsplans` and `sp` in the "shorthand" prose. - README.md L273 ("per-plan-type vs alias" callout): update the alias enumeration to list all three forms. Closes the CodeRabbit actionable on PR #169 (Line 108: hyphenated fan-out alias missing from the documented alias set). --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05b6cac4f..8e12fd3b5 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ go install github.com/LeanerCloud/CUDly/cmd@latest | Flag | Description | Default | |------|-------------|---------| -| `-s, --services` | Comma-separated service list. Per-RI services: `rds`, `elasticache`, `ec2`, `opensearch`, `redshift`, `memorydb`. Per-plan-type Savings Plans: `savings-plans-compute`, `savings-plans-ec2instance`, `savings-plans-sagemaker`, `savings-plans-database`. Fan-out aliases: `savingsplans` and `sp` expand to all four SP plan types. | rds | +| `-s, --services` | Comma-separated service list. Per-RI services: `rds`, `elasticache`, `ec2`, `opensearch`, `redshift`, `memorydb`. Per-plan-type Savings Plans: `savings-plans-compute`, `savings-plans-ec2instance`, `savings-plans-sagemaker`, `savings-plans-database`. Fan-out aliases: `savingsplans`, `savings-plans`, and `sp` expand to all four SP plan types. | rds | | `--all-services` | Process all supported services | false | ### Purchase Configuration @@ -301,7 +301,7 @@ Only process specific regions with instance limits: ### Example 8: All Savings Plans via Fan-out Alias ```bash -# `savingsplans` (and `sp`) is shorthand that fans out to every SP +# `savingsplans` (and `savings-plans`, `sp`) is shorthand that fans out to every SP # plan type — equivalent to listing all four per-plan-type slugs. ./cudly --services savingsplans \ --term 3 \ @@ -311,7 +311,7 @@ Only process specific regions with instance limits: > **Per-plan-type vs alias**: prefer the explicit per-plan-type slugs > (`savings-plans-compute`, `savings-plans-ec2instance`, > `savings-plans-sagemaker`, `savings-plans-database`) when you want -> precise scope. Use the `savingsplans` / `sp` alias only when you +> precise scope. Use the `savingsplans` / `savings-plans` / `sp` alias only when you > intentionally want all four SP plan types together. ## Coverage Percentage From 722cd1f66938c74f55646f318320ca3db1c3db58 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 19 Jun 2026 17:30:37 +0200 Subject: [PATCH 3/3] docs(README): replace em-dash in example 8 SP alias comment Replace U+2014 em-dash with double hyphen in the bash code-block comment added in the per-plan-type slug documentation, keeping prose style consistent with the rest of the file. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e12fd3b5..7a02819fb 100644 --- a/README.md +++ b/README.md @@ -302,7 +302,7 @@ Only process specific regions with instance limits: ```bash # `savingsplans` (and `savings-plans`, `sp`) is shorthand that fans out to every SP -# plan type — equivalent to listing all four per-plan-type slugs. +# plan type -- equivalent to listing all four per-plan-type slugs. ./cudly --services savingsplans \ --term 3 \ --coverage 80