Skip to content

Update iCalendar generation tool: add output suffix option#3647

Open
sanmaxdev wants to merge 7 commits into
vacanza:devfrom
sanmaxdev:fix/ics-output-suffix
Open

Update iCalendar generation tool: add output suffix option#3647
sanmaxdev wants to merge 7 commits into
vacanza:devfrom
sanmaxdev:fix/ics-output-suffix

Conversation

@sanmaxdev

@sanmaxdev sanmaxdev commented Jun 23, 2026

Copy link
Copy Markdown

Proposed change

Adds --output-suffix to holidays-ics so users can keep the generated smart filename base and append their own suffix without manually reconstructing the whole --output value.

Closes #3645.

Implementation details:

  • Adds a mutually exclusive --output-suffix option alongside -o/--output.
  • Keeps the existing default .ics behavior when no output option is passed.
  • Appends the suffix exactly as provided, without automatically adding .ics.
  • Supports suffix values that start with -, matching the issue example: --output-suffix -MYNOTE.ics.
  • Documents the new option in the holidays-ics examples.
  • Adds focused tests for generated suffix filenames, no implicit extension, mutual exclusion, and dash-prefixed suffix parsing.

Type of change

  • New country/market holidays support (thank you!)
  • Supported country/market holidays update (calendar discrepancy fix, localization)
  • Existing code/documentation/test/process quality improvement (best practice, cleanup, refactoring, optimization)
  • Dependency update (version deprecation/pin/upgrade)
  • Bugfix (non-breaking change which fixes an issue)
  • Breaking change (a code change causing existing functionality to break)
  • New feature (new holidays functionality in general)

Checklist

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds --output-suffix support to holidays-ics, including argument normalization, suffix-aware output filename construction, test coverage for parsing and filename behavior, and updated documentation examples.

Changes

--output-suffix CLI feature

Layer / File(s) Summary
CLI option, normalization, and output path
holidays/generate_ics.py
Adds --output-suffix to the CLI, normalizes space-separated suffix tokens that start with -, and uses the parsed suffix when building the generated output filename.
Tests for normalization and filename behavior
tests/test_generate_ics.py
Adds coverage for normalize_output_suffix_args and for filename generation with --output-suffix, including extension handling, mutual exclusion with --output, and missing-value cases.
Documentation update for --output-suffix
docs/examples.md
Updates the holidays-ics tool description and examples to mention --output-suffix and show a suffix-based filename example.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs

  • vacanza/holidays#3593: Introduced the IcsGenerator CLI that this PR extends with --output-suffix parsing and filename logic.

Suggested labels: script, test, doc

Suggested reviewers: KJhellico, PPsyrius

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement #3645 by adding --output-suffix, preserving smart naming, and matching the requested filename behavior.
Out of Scope Changes check ✅ Passed The diff stays within the requested feature scope, covering CLI logic, docs, and tests only.
Title check ✅ Passed The title clearly matches the main change: adding an output suffix option to iCalendar generation.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new output suffix option and related updates.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Confidence score: 3/5

  • In holidays/generate_ics.py, the --output-suffix normalization can treat following CLI flags as suffix text, which can silently drop valid options and produce incorrect output/behavior for users running the command. Tighten parsing so --output-suffix only consumes its intended value (and add a CLI regression test for adjacent flags) before merging.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread holidays/generate_ics.py
@sanmaxdev sanmaxdev force-pushed the fix/ics-output-suffix branch from 570537c to b4331ed Compare June 23, 2026 07:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_generate_ics.py`:
- Around line 470-474: The test method
test_filename_output_and_suffix_are_mutually_exclusive has two nested with
statements that can be combined into a single with statement for cleaner code.
Combine the self.argv context manager and self.assertRaises context manager into
one with statement by separating them with a comma on the same line, then dedent
the IcsGenerator() call to align with the combined with statement.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 60edb8d5-d1f5-4a27-8c3b-558c1d9686ec

📥 Commits

Reviewing files that changed from the base of the PR and between 570537c and b4331ed.

📒 Files selected for processing (3)
  • docs/examples.md
  • holidays/generate_ics.py
  • tests/test_generate_ics.py

Comment thread tests/test_generate_ics.py Outdated
@sanmaxdev sanmaxdev force-pushed the fix/ics-output-suffix branch from b4331ed to 1352035 Compare June 23, 2026 07:46
@sanmaxdev

sanmaxdev commented Jun 23, 2026

Copy link
Copy Markdown
Author

Follow-up pushed after review:

  • Tightened --output-suffix normalization so it only rewrites single-dash suffix values (for example -MYNOTE.ics) and does not consume double-dash options such as --list-categories.
  • Added regression coverage for normal suffix values, dash-prefixed suffix values, --output-suffix=<value>, missing suffix values, and double-dash options after --output-suffix.
  • Applied the CodeRabbit nested-with cleanup.

Re-validated locally:

  • uv run ruff format holidays/generate_ics.py tests/test_generate_ics.py
  • uv run ruff check holidays/generate_ics.py tests/test_generate_ics.py
  • uv run pytest tests/test_generate_ics.py -q --cov=holidays.generate_ics --cov-report=term-missing --cov-fail-under=100 -> 40 passed, 100% coverage
  • uv run python -m holidays.generate_ics CH --subdiv ZH --years 2020 --output-suffix -MYNOTE.ics
  • make test before the review follow-up -> 7314 passed, 4 skipped, 100% coverage
  • make doc
  • git diff --check

@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (382e718) to head (c7c1a10).

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #3647   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          318       318           
  Lines        19167     19183   +16     
  Branches      2457      2459    +2     
=========================================
+ Hits         19167     19183   +16     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI review requested due to automatic review settings July 1, 2026 17:05
@sanmaxdev

Copy link
Copy Markdown
Author

Pushed a small follow-up for the --output-suffix boundary cases.

Validation:

  • uv run --group tests python -m pytest tests/test_generate_ics.py -q -k 'output_suffix'
  • uv run --group tests python -m compileall holidays/generate_ics.py tests/test_generate_ics.py
  • uv run --group tests ruff check holidays/generate_ics.py tests/test_generate_ics.py
  • git diff --check

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_generate_ics.py`:
- Around line 477-486: The two new tests in
test_output_suffix_does_not_consume_long_options and
test_output_suffix_missing_value_uses_argparse_error should follow the existing
SIM117 style by combining the nested argv and assertRaises context managers into
a single with block. Update the IcsGenerator test cases to use one combined
context manager statement, matching the already-fixed pattern in the same test
class, while keeping the unittest-style assertRaises convention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f1c99f8e-9548-42fa-81f7-b793c83ea3a8

📥 Commits

Reviewing files that changed from the base of the PR and between 1352035 and 700d4fe.

📒 Files selected for processing (1)
  • tests/test_generate_ics.py

Comment thread tests/test_generate_ics.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new --output-suffix CLI option to holidays-ics (implemented in holidays.generate_ics.IcsGenerator) to let users keep the smart generated filename base and append a custom suffix (including values that start with -) without reconstructing --output.

Changes:

  • Add --output-suffix as a mutually exclusive alternative to -o/--output, plus argv normalization to support dash-prefixed suffix values.
  • Update filename generation to append the provided suffix exactly (or default to .ics when no suffix is provided).
  • Add tests and documentation examples covering suffix behavior, mutual exclusion, and parsing edge cases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
holidays/generate_ics.py Adds --output-suffix, normalizes argv to support --prefixed values, and updates output filename composition.
tests/test_generate_ics.py Adds unit tests for suffix parsing/normalization and filename generation behavior.
docs/examples.md Documents --output-suffix usage in the holidays-ics examples section.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread holidays/generate_ics.py
Comment on lines +67 to +70
output_group.add_argument(
"--output-suffix",
help="Suffix to append to the generated output filename base (e.g., -MYNOTE.ics)",
)
Comment thread tests/test_generate_ics.py Outdated
Comment thread holidays/generate_ics.py Outdated
Comment thread tests/test_generate_ics.py Outdated
Comment thread tests/test_generate_ics.py Outdated
@KJhellico KJhellico changed the title feat: add ICS output suffix option Update iCalendar generation tool: add output suffix option Jul 2, 2026
@sanmaxdev

Copy link
Copy Markdown
Author

Addressed the latest review notes:

  • simplified the suffix fallback
  • removed the two parser-behavior tests

Verification:

  • uv run --group tests python -m pytest tests/test_generate_ics.py -q -k 'output_suffix'
  • uv run --group tests python -m compileall holidays/generate_ics.py tests/test_generate_ics.py
  • uv run --group tests ruff check holidays/generate_ics.py tests/test_generate_ics.py
  • git diff --check

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="holidays/generate_ics.py">

<violation number="1" location="holidays/generate_ics.py:221">
P2: The `or` fallback on the added line overrides an explicitly empty suffix. If a user passes `--output-suffix ''`, `argparse` sets the value to `''` (empty string, not `None`). Because `''` is falsy, `or ".ics"` replaces it, forcing an unwanted extension and ignoring the explicit input. This breaks the stated contract that the suffix is "appended exactly as provided (no implicit .ics added by the code)." The original `is not None` check correctly distinguished between "option omitted" (`None`) and "option given as empty string" (`''`). Restoring `self.args.output_suffix if self.args.output_suffix is not None else ".ics"` preserves both the default behavior and the explicit empty-string edge case.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread holidays/generate_ics.py Outdated
Comment thread tests/test_generate_ics.py Outdated
@sanmaxdev

Copy link
Copy Markdown
Author

Removed the duplicate output suffix test from the latest review.

Verification:

  • uv run --group tests python -m pytest tests/test_generate_ics.py -q -k 'output_suffix'
  • git diff --check

@sanmaxdev

Copy link
Copy Markdown
Author

Pushed a small follow-up for the empty suffix case.

Verification:

  • uv run --group tests python -m pytest tests/test_generate_ics.py -q -k 'output_suffix'
  • uv run --group tests python -m compileall holidays/generate_ics.py tests/test_generate_ics.py
  • uv run --group tests ruff check holidays/generate_ics.py tests/test_generate_ics.py
  • git diff --check

@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--output-suffix flag to modify default output filename ending

3 participants