This PR augments gh pr alias set
with the ability to accept -s/--shell
. Shell aliases are executed through $SHELL
and allow executing various commands in composition instead of just rewriting invocations of gh subcommands.
It works like this:
$ gh alias set -s checklist 'gh issue list -l$1 | sed "s/^/- [ ] /" > checklist.md'
- Adding alias for checklist: gh issue list -l$1 | sed "s/^/- [ ] /" > checklist.md
✓ Added alias.
$ gh checklist epic
Showing 2 of 2 issues in cli/cli that match your search
$ cat checklist.md
- [ ] 957 [Tracking issue] Improve GitHub authentication via GitHub CLI enhancement, epic about 4 days ago
- [ ] 939 Alias support phase 2 aliases, epic about 12 days ago
Below is the initial sketch/discussion about this feature:
$ gh alias set igrep '!sh -c "gh issue list -L100 | grep $1"'
$ gh igrep alias
Showing 100 of 206 issues in cli/cli
1128 completions for aliases aliases, enhancement about 18 minutes ago
1045 Share and consume gh aliases enhancement about 9 days ago
941 shell version of `gh alias set` aliases about 3 hours ago
940 Scriptability audit aliases, tech-debt about 9 days ago
939 Alias support phase 2 aliases, epic about 2 hours ago
But the caveats:
! character
Enclosing the expansion in single quotes is necessary. both bash
and zsh
interpret !
as a
special character and it will not make it into gh
, which will lead to potentially confusing errors
for users who forget to use single quotes when using !
style aliases.
Potential alternatives:
- Use a different character. None really felt right to me and just about every special character
means something to shells.
- Have
gh alias set
respect a --external
flag. This is circular because to support this we'd have
to re-enable flag parsing on gh alias set
. In other words, to support --external
, this would
no longer work: gh alias set co pr checkout
.
- Assume an external alias if the expansion does not map to a
gh
command. I don't love this;
losing that bit of validation for non-external aliases seems not worth it.
my opinion: we're not going to do better than !
and requiring single quotes is acceptable.
quote madness
There are a lot of quote characters in gh alias set igrep '!sh -c "gh issue list | grep $1"'
.
The sh -c
in !sh -c "command goes here"
is not needed in all cases. It's only necessary when you
want to compose commands.
For example, this works fine:
$ gh alias set echo '!echo'
$ gh echo hi how are you
hi how are you
But this won't do what you want:
$ gh alias set igrep '!gh issue list | grep $1'
$ gh igrep alias
# (...just runs issue list and discards subsequent |...)
My concern here is that it's cognitively confusing for people who aren't used to scripting in
shells. The sh -c
is probably confusing and the need to put what they actually want to run in
the double quotes when they're already wrapping everything in single quotes could lead users to
frustration.
Potential alternative:
- always wrapping
!
aliases in sh -c "<expansion>"
. I've hacked this together and it seems to
work well; the downside is that users are now stuck invoking their composed commands via sh
.
They might prefer to run things through zsh
or bash
to pick up their own shell aliases (i.e.
aliases they've defined in their shells, not gh aliases). We could expose the shell for external
aliases as a config option with a default of sh
.
That could lead to something like this:
# In ZSH:
$ alias g=grep
$ gh alias set ig '!gh issue list | g $1'
$ gh ig alias
external alias failed: sh: 1: command not found: g
$ gh config set shell zsh
$ gh ig alias
# ... expected output ...
my opinion: I'm really intrigued by always wrapping in a sh -c "<...>"
. I like combining it with the new config setting.
Multiline input
I started experimenting with accepting an --input <filename>
argument with an alias expansion in
it so that alias definitions could be written on multiple lines. This felt kind of bad; I wasn't
sure if suddenly having to worry about newlines in alias expansions was worth it.
Potential paths:
- Continue trying to allow for file input and handling newlines appropriately when setting up
commands.
- Leave as-is and worry about more complex scripting in @mislav's extensions hack day proposal.
my opinion: we can punt on this for now.
If you read this far
I'd love feedback on the above three caveats as well as any other thoughts y'all have about this.
tl;dr:
- is the
!
character ok for signalling to gh
that the user wants an external alias?
- should we wrap all external aliases in
sh -c "<expansion>"
?
- should we worry about multi-line input at this point?