Skip to content

Commit cb44b01

Browse files
fix: keep trailing hyphens and dots in normalized feature names
Trimming them changed identifiers like "TEST-", which were valid and unchanged before, breaking the promise that existing instances stay reachable. Reject empty and relative path segments explicitly instead, which is what the trim was actually guarding against.
1 parent f17e1d4 commit cb44b01

2 files changed

Lines changed: 9 additions & 4 deletions

File tree

docs/FEATURE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ The `--feature=` value may be a full branch name. Path separators are replaced b
6666

6767
Names that already consist of letters, digits, `_`, `-` and `.` are used unchanged, so existing instances and their databases stay reachable. Since the branch prefix is kept, `feature/TEST-01` and `bugfix/TEST-01` remain two separate instances. The same normalization is applied by `feature:cleanup` when it compares remote git branches with the deployed instances.
6868

69+
A `--feature=` value that yields no usable name is rejected instead of falling back to the base instance, which the feature scaffolding would otherwise overwrite. That covers values without any allowed character as well as `.` and `..`.
70+
71+
> Because the separator is replaced rather than encoded, `feature/TEST-01` and a branch literally named `feature-TEST-01` map to the same instance. Do not use both spellings for different branches in one project.
72+
6973
The recipe already wires this task into the deploy flow, together with a `feature:init` before `deploy:info`. That ordering matters: `deploy:info` resolves `{{release_name}}` and deployer caches the result for the rest of the run, so the feature instance has to be known before it runs. Do not hook `feature:setup` any earlier yourself.
7074

7175
> Upgrading: if your `deploy.php` carries a `before('deploy:info', 'feature:init')` (or an equivalent `feature:setup` hook) as a workaround for that ordering, remove it — the recipe registers it now and the hook would otherwise run twice.

src/Utility/FeatureUtility.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ final class FeatureUtility
1919
* databases reachable.
2020
*
2121
* @throws \InvalidArgumentException if a non-blank identifier normalizes to an empty
22-
* name, which would silently address the base instance
22+
* name or to a relative path segment, either of which
23+
* would silently address the base instance
2324
*/
2425
public static function normalize(?string $feature): string
2526
{
@@ -31,11 +32,11 @@ public static function normalize(?string $feature): string
3132

3233
$normalized = str_replace(['/', '\\'], '-', $feature);
3334
$normalized = (string) preg_replace('/[^A-Za-z0-9_\-.]/', '', $normalized);
34-
$normalized = trim($normalized, '-.');
3535

36-
if ('' === $normalized) {
36+
// "" would resolve to the base instance, "." and ".." to it or its parent
37+
if ('' === trim($normalized, '.')) {
3738
throw new \InvalidArgumentException(
38-
sprintf('The feature name "%s" contains no usable characters.', $feature)
39+
sprintf('The feature name "%s" does not yield a usable instance name.', $feature)
3940
);
4041
}
4142

0 commit comments

Comments
 (0)