Skip to content

Add ability to customize separator across Onym strategies via options and constructor#1

Open
SimonBarrettACT wants to merge 5 commits into
Blaspsoft:mainfrom
SimonBarrettACT:feature/custom-separator
Open

Add ability to customize separator across Onym strategies via options and constructor#1
SimonBarrettACT wants to merge 5 commits into
Blaspsoft:mainfrom
SimonBarrettACT:feature/custom-separator

Conversation

@SimonBarrettACT

@SimonBarrettACT SimonBarrettACT commented Apr 13, 2025

Copy link
Copy Markdown

Description

This pull request enhances the Onym package by making the separator used across different strategies fully customizable.

Previously, the timestamp(), date(), and numbered() methods hard-coded the separator (e.g., underscore _) into their generated filenames. There was no way to override it dynamically through options.

This PR introduces:

  • Support for a separator option in all relevant methods (timestamp, date, numbered, and slug).
  • Fallback to a defaultSeparator if no separator is provided in options.
  • The ability to override options and defaultSeparator through the constructor, making the class easier to customize and test.

Example usage:

use Blaspsoft\Onym\Onym;

// Set a custom default separator
$onym = new Onym([], ' ');
$filename = $onym->timestamp('invoice', 'pdf'); // 2024-03-15 invoice.pdf

// Or override per call
$filename = $onym->timestamp('invoice', 'pdf', ['separator' => ' ']); // 2024-03-15 invoice.pdf

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added configurable `default_separator` option allowing custom filename separators across all filename generation strategies.
  * Extended support for Laravel 13, PHP 8.4, PHPUnit 12, and Orchestra Testbench 11.

* **Documentation**
  * Added "Customizing the Default Separator" section with examples and migration guidance for users with existing configurations.

* **Tests**
  * Expanded test coverage for configurable separator behavior across all filename generation strategies.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@deemonic

deemonic commented Apr 13, 2025

Copy link
Copy Markdown
Collaborator

Hi @SimonBarrettACT

Thanks for this addition I can see the value.

I just wanted to acknowledge the request I'll try and look as this and get this merged later today. If not it will be Wednesday as im travelling Monday / Tuesday.

I just wanted to let you know and set some expectation.

Your contribution is appreciated

Have a great day

@SimonBarrettACT

Copy link
Copy Markdown
Author

Would it be possible to merge this please 🙏

- illuminate/support now allows ^13.0
- dev toolchain: testbench ^10|^11, phpunit ^11|^12
- CI matrix exercises Laravel 12/13 on PHP 8.3/8.4
- suite passes on Laravel 13.15 (34 tests)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a configurable default_separator feature to the Onym filename generator. The separator is stored in configuration and passed to the Onym class constructor, then used as a fallback in timestamp(), date(), numbered(), and slug() methods. The PR also updates CI and dependency constraints to validate the feature across PHP 8.3/8.4 and Laravel 12/13 combinations.

Changes

Default Separator Configuration

Layer / File(s) Summary
Configuration schema and Onym interface
config/config.php, src/Onym.php
Configuration array adds default_separator entry (default '_'). Onym constructor now accepts optional defaultSeparator parameter and stores it as a public property, initialized from the provided argument or config value.
Separator fallback logic in generation methods
src/Onym.php
timestamp(), date(), numbered(), and slug() methods now use $options['separator'] when provided, otherwise fall back to $this->defaultSeparator instead of hardcoded separators.
Test coverage for separator configuration
tests/OnymTest.php, tests/TestCase.php
Eight new test methods verify that each generation method applies the default separator when no option override is given and respects separator option overrides. Test environment setup initializes the onym.default_separator configuration.
User-facing documentation of separator customization
README.md
Adds section demonstrating manual Onym construction with custom separator; updates example global configuration to show default_separator key; adds migration note for users with existing published config files.

Multi-Version Testing Infrastructure

Layer / File(s) Summary
Workflow matrix configuration and dependency installation
.github/workflows/main.yml, composer.json
GitHub Actions workflow now tests across PHP 8.3/8.4 and Laravel 12/13 via parameterized matrix with testbench version selection. Workflow steps dynamically require version-specific illuminate/support and orchestra/testbench before running composer update. Composer constraints widened to allow illuminate/support ^13.0, orchestra/testbench ^10.0 | ^11.0, and phpunit/phpunit ^11.0 | ^12.0.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A separator blooms in config's spring,
no hardcoded underscores left to sting!
Each method now respects the chosen way,
timestamp, date, and slug all have their say.
Tests dance across PHP versions bright,
while rabbit crafts the fallback right! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding customizable separator functionality via options and constructor parameters across multiple Onym strategies.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Onym.php (1)

96-96: ⚠️ Potential issue | 🟠 Major

Pass $useOptions into the slug strategy call

make() calls $this->slug($defaultFilename, $extension) without $useOptions, unlike the other strategies, so custom options (e.g., separator) are ignored when strategy='slug'.

🔧 Proposed fix
-            'slug' => $this->slug($defaultFilename, $extension),
+            'slug' => $this->slug($defaultFilename, $extension, $useOptions),

Add a test that calls make() with strategy='slug' and a custom separator, asserting the produced slug uses that separator.

🤖 Prompt for 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.

In `@src/Onym.php` at line 96, The make() call is invoking
$this->slug($defaultFilename, $extension) without passing $useOptions so custom
slug options (e.g., separator) are ignored; update the call in Onym::make() to
pass $useOptions into the slug strategy ($this->slug($defaultFilename,
$extension, $useOptions)) and ensure Onym::slug accepts and uses that parameter;
add a unit test that calls make() with strategy='slug' and a custom 'separator'
option and asserts the returned slug uses the provided separator.
🧹 Nitpick comments (2)
.github/workflows/main.yml (1)

23-30: ⚡ Quick win

Consider security hardening recommendations from static analysis.

The static analysis tool flagged two security concerns:

  1. Unpinned action references (lines 24, 27): Actions reference tags (@v4, @v2) rather than commit SHAs, which exposes the workflow to supply-chain attacks if tags are moved.
  2. Credential persistence (line 24): The checkout action doesn't set persist-credentials: false, which means GitHub tokens persist in the workspace and could leak through artifacts.

These are security best practices recommended by OpenSSF. However, many projects accept these risks for maintainability since tags are more readable than commit SHAs.

🔒 Proposed hardening changes
       - name: Checkout code
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+        with:
+          persist-credentials: false

       - name: Set up PHP
-        uses: shivammathur/setup-php@v2
+        uses: shivammathur/setup-php@c541c155eee45413f5b09a52d31318011562d79a # v2.31.1
         with:
🤖 Prompt for 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.

In @.github/workflows/main.yml around lines 23 - 30, Update the GitHub Actions
workflow to address the static-analysis security flags: replace the loose action
tags actions/checkout@v4 and shivammathur/setup-php@v2 with pinned commit SHAs
(use the full commit SHA for each action instead of the tag) and add
persist-credentials: false to the checkout step (the actions/checkout usage) so
the GITHUB_TOKEN is not left in the workspace; keep the existing php-version and
extensions inputs when updating the pin.

Source: Linters/SAST tools

tests/OnymTest.php (1)

214-291: 💤 Low value

Consider consistent test naming convention.

The new tests use test_* prefix while existing tests in the file use it_* prefix. For consistency within the test suite, consider renaming to match the established pattern (e.g., it_uses_default_separator_for_timestamp, it_overrides_separator_for_timestamp).

🤖 Prompt for 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.

In `@tests/OnymTest.php` around lines 214 - 291, The test methods use a different
naming convention (test_*) than the rest of the file (it_*); rename the new
methods (test_timestamp_uses_default_separator,
test_timestamp_overrides_separator_in_options, test_date_uses_default_separator,
test_date_overrides_separator_in_options, test_numbered_uses_default_separator,
test_numbered_overrides_separator_in_options, test_slug_uses_default_separator,
test_slug_overrides_separator_in_options) to follow the existing it_* pattern
(e.g., it_uses_default_separator_for_timestamp,
it_overrides_separator_for_timestamp, etc.), keeping the same #[Test] attributes
and test bodies so the assertions and referenced symbols (Onym->timestamp,
Onym->date, Onym->numbered, Onym->slug) remain unchanged.
🤖 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 `@composer.json`:
- Line 19: The composer.json PHP platform constraint currently excludes PHP 8.1;
update the "php" constraint entry (the "php" key in composer.json) to include
^8.1 (e.g., "php": "^8.0|^8.1|^8.2|^8.3|^8.4") if 8.1 is supported, or
alternatively add a short note in project docs (README or composer.json
comments) explaining the intentional exclusion of 8.1 and the reason; modify the
"php" value under the composer.json file or add the documentation accordingly so
the constraint matches the project compatibility decision.

In `@README.md`:
- Around line 274-276: The README example calling $filename =
$onym->timestamp('invoice', 'pdf'); uses the default timestamp format
'Y-m-d_H-i-s' but shows a date-only result; update the example so it matches
reality by either calling $onym->timestamp('invoice', 'pdf', ['format' =>
'Y-m-d']) to produce "2024-03-15|invoice.pdf" or change the expected result to
include the full default timestamp (e.g., "2024-03-15_14-30-00|invoice.pdf");
reference the timestamp() call and the default format 'Y-m-d_H-i-s' when making
the change.

---

Outside diff comments:
In `@src/Onym.php`:
- Line 96: The make() call is invoking $this->slug($defaultFilename, $extension)
without passing $useOptions so custom slug options (e.g., separator) are
ignored; update the call in Onym::make() to pass $useOptions into the slug
strategy ($this->slug($defaultFilename, $extension, $useOptions)) and ensure
Onym::slug accepts and uses that parameter; add a unit test that calls make()
with strategy='slug' and a custom 'separator' option and asserts the returned
slug uses the provided separator.

---

Nitpick comments:
In @.github/workflows/main.yml:
- Around line 23-30: Update the GitHub Actions workflow to address the
static-analysis security flags: replace the loose action tags
actions/checkout@v4 and shivammathur/setup-php@v2 with pinned commit SHAs (use
the full commit SHA for each action instead of the tag) and add
persist-credentials: false to the checkout step (the actions/checkout usage) so
the GITHUB_TOKEN is not left in the workspace; keep the existing php-version and
extensions inputs when updating the pin.

In `@tests/OnymTest.php`:
- Around line 214-291: The test methods use a different naming convention
(test_*) than the rest of the file (it_*); rename the new methods
(test_timestamp_uses_default_separator,
test_timestamp_overrides_separator_in_options, test_date_uses_default_separator,
test_date_overrides_separator_in_options, test_numbered_uses_default_separator,
test_numbered_overrides_separator_in_options, test_slug_uses_default_separator,
test_slug_overrides_separator_in_options) to follow the existing it_* pattern
(e.g., it_uses_default_separator_for_timestamp,
it_overrides_separator_for_timestamp, etc.), keeping the same #[Test] attributes
and test bodies so the assertions and referenced symbols (Onym->timestamp,
Onym->date, Onym->numbered, Onym->slug) remain unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c43112d-a1d5-4b25-b924-542b3ec21b30

📥 Commits

Reviewing files that changed from the base of the PR and between 9405740 and 211741f.

📒 Files selected for processing (7)
  • .github/workflows/main.yml
  • README.md
  • composer.json
  • config/config.php
  • src/Onym.php
  • tests/OnymTest.php
  • tests/TestCase.php

Comment thread composer.json
@@ -17,11 +17,11 @@
],
"require": {
"php": "^8.0|^8.2|^8.3|^8.4",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for PHP 8.1 related comments or documentation

# Check README and docs for PHP version mentions
fd -e md -e txt | xargs rg -i 'php.*8\.1' -C2

# Check for any PHP version related issues or comments in code
rg -i 'php.*8\.1|8\.1.*incompatible|8\.1.*issue' -C2

Repository: Blaspsoft/onym

Length of output: 40


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Show composer.json php constraint with line numbers around it
echo "== composer.json =="
if [ -f composer.json ]; then
  nl -ba composer.json | sed -n '1,120p'
else
  echo "composer.json not found at repo root"
fi

# 2) Search for explicit PHP 8.1 mentions/incompat notes across the repo (excluding vendor)
echo "== rg for PHP 8.1 related mentions =="
rg -n --hidden --glob '!vendor/**' --glob '!node_modules/**' --glob '!storage/**' \
  '(php[^0-9]{0,10}8\.1|8\.1[^0-9]{0,10}(incompatible|not supported|not supported|unsupported)|8\.1.*(incompatible|issue|break|fails|problem|support))' \
  -S || true

# 3) Broad search for "8.1" occurrences to see any context
echo "== rg for literal 8.1 (broad) =="
rg -n --hidden --glob '!vendor/**' --glob '!node_modules/**' \
  '8\.1' -S || true

Repository: Blaspsoft/onym

Length of output: 139


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ls =="
ls -la | head

echo "== composer.json =="
if [ -f composer.json ]; then
  # Print first 120 lines with line numbers via awk
  awk '{printf "%5d\t%s\n", NR, $0}' composer.json | sed -n '1,120p'
else
  echo "composer.json not found at repo root"
fi

echo "== rg for PHP 8.1 related mentions =="
rg -n --hidden --glob '!vendor/**' --glob '!node_modules/**' \
  '(php[^0-9]{0,10}8\.1|8\.1[^0-9]{0,10}(incompatible|not supported|unsupported|not supported|problem|fails|issue)|8\.1.*(incompatible|issue|break|fails|problem|support))' \
  -S || true

echo "== rg for literal 8.1 occurrences (broad) =="
rg -n --hidden --glob '!vendor/**' --glob '!node_modules/**' \
  '8\.1' -S || true

Repository: Blaspsoft/onym

Length of output: 2234


Add ^8.1 back to the PHP constraint (or document why it’s excluded).

composer.json (line 19) sets "php": "^8.0|^8.2|^8.3|^8.4", which excludes PHP 8.1 and prevents installs on that runtime. There are no repo notes/comments indicating PHP 8.1 is incompatible, so please confirm whether to include ^8.1 or document the deliberate exclusion.

🤖 Prompt for 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.

In `@composer.json` at line 19, The composer.json PHP platform constraint
currently excludes PHP 8.1; update the "php" constraint entry (the "php" key in
composer.json) to include ^8.1 (e.g., "php": "^8.0|^8.1|^8.2|^8.3|^8.4") if 8.1
is supported, or alternatively add a short note in project docs (README or
composer.json comments) explaining the intentional exclusion of 8.1 and the
reason; modify the "php" value under the composer.json file or add the
documentation accordingly so the constraint matches the project compatibility
decision.

Comment thread README.md
Comment on lines +274 to +276
$filename = $onym->timestamp('invoice', 'pdf');

// Result: "2024-03-15|invoice.pdf"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct the example output to match the default timestamp format.

The example calls timestamp() without options, so it uses the default format 'Y-m-d_H-i-s' which includes time. The actual result would be "2024-03-15_14-30-00|invoice.pdf", not "2024-03-15|invoice.pdf".

To fix, either:

  1. Pass ['format' => 'Y-m-d'] to produce date-only output, or
  2. Update the expected result to show the full timestamp with time
📝 Proposed fix (option 1: use date-only format)
 // Use the timestamp strategy with the custom separator
-$filename = $onym->timestamp('invoice', 'pdf');
+$filename = $onym->timestamp('invoice', 'pdf', ['format' => 'Y-m-d']);
 
 // Result: "2024-03-15|invoice.pdf"

Or option 2: update the expected result comment:

 // Use the timestamp strategy with the custom separator
 $filename = $onym->timestamp('invoice', 'pdf');
 
-// Result: "2024-03-15|invoice.pdf"
+// Result: "2024-03-15_14-30-00|invoice.pdf"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$filename = $onym->timestamp('invoice', 'pdf');
// Result: "2024-03-15|invoice.pdf"
$filename = $onym->timestamp('invoice', 'pdf', ['format' => 'Y-m-d']);
// Result: "2024-03-15|invoice.pdf"
🤖 Prompt for 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.

In `@README.md` around lines 274 - 276, The README example calling $filename =
$onym->timestamp('invoice', 'pdf'); uses the default timestamp format
'Y-m-d_H-i-s' but shows a date-only result; update the example so it matches
reality by either calling $onym->timestamp('invoice', 'pdf', ['format' =>
'Y-m-d']) to produce "2024-03-15|invoice.pdf" or change the expected result to
include the full default timestamp (e.g., "2024-03-15_14-30-00|invoice.pdf");
reference the timestamp() call and the default format 'Y-m-d_H-i-s' when making
the change.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants