Skip to content

Add alias and forget commands for user-defined package aliases#23

Open
TitasGailius wants to merge 2 commits into
2.xfrom
feat/aliases-v2
Open

Add alias and forget commands for user-defined package aliases#23
TitasGailius wants to merge 2 commits into
2.xfrom
feat/aliases-v2

Conversation

@TitasGailius

Copy link
Copy Markdown

Creating aliases

Added cpx alias [package] [name] to let users create their own shortcut for a package (e.g. cpx alias laravel/pint pint), prompting interactively via Laravel Prompts for whichever argument is omitted.

Screen Recording 2026-07-01 at 15 00 28

Listing aliases

cpx aliases now also lists user-defined aliases under a "Your aliases" section alongside the built-in ones.

bettershot_1782907426111

Deleting aliases

Added cpx forget [name] to remove a saved alias, with a select prompt listing existing aliases when the name is omitted.

Screen Recording 2026-07-01 at 15 01 49

Other

  • Alias names that collide with a real registered command (list, clean, etc.) are rejected, since they'd never be reachable.
  • User aliases are stored in ~/.cpx/aliases.json and take priority over the built-in aliases at dispatch time, so a user can override e.g. pint to point elsewhere.

Comment thread src/Commands/AliasCommand.php
name: 'forget',
description: 'Remove a user-defined alias',
)]
class ForgetCommand extends Command

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think here we should display not only the alias, but also what the alias stands for, because users can even have different aliases for the same package. for example pest3 and pest4 for the versions.

@TitasGailius TitasGailius Jul 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is a great idea. Now it displays the full package name under the highlighted alias.


$json = json_decode((string) file_get_contents($file), true);

return new self(array_map(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A malformed ~/.cpx/aliases.json (invalid JSON, non-array root, or one bad value) throws and breaks every cpx command, including cpx forget, which is how a user would fix it. Let's mirror the is_array() guard already used in Application::resolveVersion(), bail to an empty state otherwise, and skip individual unparseable entries.

return $this;
}

public function save(): void

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this could take advantage of some things I created for this PR:
#22, check the Filesystem class

$this->addArgument('name', InputArgument::OPTIONAL, 'The alias name to run the package as, e.g. "cpx <name>"');
}

protected function execute(InputInterface $input, OutputInterface $output): int

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we display a warning/confirmation when user is overriding an existing alias?

try {
$package = $this->resolvePackage($input);
$name = $this->resolveName($input, $package);
} catch (InvalidArgumentException|NonInteractiveValidationException $e) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The two commands handle errors differently: AliasCommand catches InvalidArgumentException|NonInteractiveValidationException while ForgetCommand catches only the latter, and package vs name validation take two different shapes here. Let's align the catch sets and route both args through a validate*() method so the pattern reads the same.

@imliam

imliam commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

This looks like it covers the primary use case when a binary matches the package/vendor name clearly, do you think there's appetite for another question/parameter for packages that have multiple binaries when it isn't entirely clear? For example:

"The package vimeo/psalm has multiple binaries, which would you like to alias to?"

  • [psalm]
  • psalter
  • psalm-refactor
  • psalm-review

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.

3 participants