Conversation
There was a problem hiding this comment.
I like the general approach taken here, but there are many edge cases that I feel should be addressed before shipping.
An idea: should we print information about alias expansion when DEBUG is active? This seems to me like a good use of debug mode; e.g.
$ DEBUG=1 gh pl foo
[pl foo] -> [pr list foo]
(...rest of output)Additionally, I think that we should prevent recording and expanding an alias of the same name as a built-in CLI command. This is primarily for two reasons:
-
Ease of debugging user problem reports: someone could report to us an error they are getting with
gh pr createand we could spend time going back and forth with that user until we find out that the user hasprconfigured among their aliases that expands to something unexpected. -
Allowing our future commands to override people's aliases: it's possible that it would get popular that CLI users would share an alias named
openwithin our community, but if ship a top-level command namedopenin a future release, we probably want our command to take precedence over the alias. Otherwise, our release notes are advertisinggh openbehavior that some users would not be getting because they have an active alias (and they might have forgotten about it).
command/alias.go
Outdated
| // TODO HACK: even when inside of a single-quoted string, cobra was noticing and parsing any flags | ||
| // used in an alias expansion string argument. Since this command needs no flags, I disabled their | ||
| // parsing. If we ever want to add flags to alias set we'll have to figure this out. I haven't | ||
| // checked if this is fixed in a new cobra. |
There was a problem hiding this comment.
Cobra will only ever try to parse arguments as flags if an argument begins with a -- or -. With default Cobra config, this will work:
gh alias set pc 'pr create --assignee mona'i.e. Cobra will not try to parse flags within the pr create --assignee mona. However, the quote-free version will fail:
gh alias set pc pr create --assignee monaThis is because all "words" are now passed as distinct arguments to alias set and one of them looks like a flag. To enable this use, I think that DisableFlagParsing is a good approach, but you are right that we will have to revisit this should we ever want to enable flags specifically for alias set.
There was a problem hiding this comment.
gh alias set pc 'pr create --assignee mona' is exactly what didn't work, hence my saying "even when inside of a single-quoted string" and saying it seemed like a bug.
I understand how argument passing works :)
There was a problem hiding this comment.
gh alias set pc 'pr create --assignee mona'is exactly what didn't work
I only brought up my points because I have first tried to reproduce this with DisableFlagParsing: false, but was not able to.
There was a problem hiding this comment.
I had trouble reproducing this too. It might be that you’re trying to use the --author flag on pr list but it surprisingly doesn’t exist. I tried out these alias for issues and they worked:
ghd alias set foo ‘issue list —author=“probablycorey”’
ghd alias set foo2 ‘issue list —author=probablycorey’
There was a problem hiding this comment.
the error is from alias set; not pr list. i get the same result with issue list:
I thought it was possibly something weird about my shell but I'm getting the same behavior in bash and zsh.
I noticed that your paste, corey, isn't using actual single quotes but rather the ‘ character. I tried that but it still fails for me; I wonder, however, if that character is treated different on macos?
There was a problem hiding this comment.
@vilmibm I'm stumped. I cannot reproduce this when I remove the DisableFlagParsing workaround:
$ gh alias set ix 'issue list --author=vilmibm'
- Adding alias for ix: issue list --author=vilmibm
✓ Added alias.
$ gh alias set ix 'issue list --author="vilmibm"'
- Adding alias for ix: issue list --author="vilmibm"
✓ Changed alias ix from issue list --author=vilmibm to issue list --author="vilmibm"
$ gh ix
Showing 11 of 11 issues in cli/cli that match your search
#990 gh alias delete (aliases, enhancement) about 6 days ago
...There was a problem hiding this comment.
🤷 i have no further ideas. it is concretely broken for me. i think we should leave flag parsing disabled until we have a reason to worry about it; i'll amend my comment to mention the weird by-platform behavior.
There was a problem hiding this comment.
@vilmibm I can see that you are running ghd instead of gh. Could you check in your ghd script that you are forwading the arguments with "$@" and not via $@ or $*?
internal/config/config_type.go
Outdated
|
|
||
| func (c *fileConfig) parseAliasConfig(aliasesEntry *yaml.Node) (*AliasConfig, error) { | ||
| if aliasesEntry.Kind != yaml.MappingNode { | ||
| return nil, errors.New("expected aliases to be a map") |
There was a problem hiding this comment.
Could we also interpret a YAML null essentially as an empty mapping?
When experimenting with aliases, I've manually deleted alias entries in my config file, resulting in only this:
aliases:the current alias-parsing code now aborts because aliases is not a map, but I think we should be permissive about this and interpret null as an empty map.
There was a problem hiding this comment.
oops yeah, good catch. that shouldn't explode a config parsing.
probablycorey
left a comment
There was a problem hiding this comment.
This is great! I can't wait to use it for real!
An idea: should we print information about alias expansion when DEBUG is active? This seems to me like a good use of debug mode; e.g.
I really like this idea. I ran into a situation where I couldn’t figure out why an alias wouldn’t work and this would have helped!
One thing that surprised me: If I try to change an alias I got “alias foo already exists” I was expecting it to say something like “alias foo was ghd xyz but is now god abc
command/alias.go
Outdated
| // TODO HACK: even when inside of a single-quoted string, cobra was noticing and parsing any flags | ||
| // used in an alias expansion string argument. Since this command needs no flags, I disabled their | ||
| // parsing. If we ever want to add flags to alias set we'll have to figure this out. I haven't | ||
| // checked if this is fixed in a new cobra. |
There was a problem hiding this comment.
I had trouble reproducing this too. It might be that you’re trying to use the --author flag on pr list but it surprisingly doesn’t exist. I tried out these alias for issues and they worked:
ghd alias set foo ‘issue list —author=“probablycorey”’
ghd alias set foo2 ‘issue list —author=probablycorey’
command/alias.go
Outdated
| } | ||
|
|
||
| if !validCommand(expansion) { | ||
| return fmt.Errorf("could not create alias: %s does not correspond to a gh command", utils.Bold(expansion)) |
There was a problem hiding this comment.
I like the "error on valid command" idea. I think @vilmibm's idea of warning on import would be an acceptable fix for the potential import problem.
command/alias.go
Outdated
| func validCommand(expansion string) bool { | ||
| split, _ := shlex.Split(expansion) | ||
| cmd, _, err := RootCmd.Traverse(split) | ||
| return err == nil && cmd != RootCmd | ||
| } |
There was a problem hiding this comment.
This is easier than I thought it would be!
|
I've caught up on all the feedback. Update: I moved that code into |
mislav
left a comment
There was a problem hiding this comment.
Getting really close! I already love the functionality in this branch; works great for me ✨
My last remaining requests are related to tightening safety around how we pass arguments around so that single arguments that contain spaces do not accidentally get intepreted as multiple arguments due to shellsplitting.
command/alias.go
Outdated
| // TODO HACK: even when inside of a single-quoted string, cobra was noticing and parsing any flags | ||
| // used in an alias expansion string argument. Since this command needs no flags, I disabled their | ||
| // parsing. If we ever want to add flags to alias set we'll have to figure this out. I haven't | ||
| // checked if this is fixed in a new cobra. |
There was a problem hiding this comment.
@vilmibm I'm stumped. I cannot reproduce this when I remove the DisableFlagParsing workaround:
$ gh alias set ix 'issue list --author=vilmibm'
- Adding alias for ix: issue list --author=vilmibm
✓ Added alias.
$ gh alias set ix 'issue list --author="vilmibm"'
- Adding alias for ix: issue list --author="vilmibm"
✓ Changed alias ix from issue list --author=vilmibm to issue list --author="vilmibm"
$ gh ix
Showing 11 of 11 issues in cli/cli that match your search
#990 gh alias delete (aliases, enhancement) about 6 days ago
...|
@mislav caught up once more. |
mislav
left a comment
There was a problem hiding this comment.
One tiny edge case; otherwise everything looks great! Thank you for the hard work
command/alias.go
Outdated
| return args[0] | ||
| } | ||
|
|
||
| return strings.Join(args, " ") |
There was a problem hiding this comment.
I'm finding that this is still an issue. Repro:
$ gh config set editor 'path with spaces' # works
$ gh alias set c config set editor 'path with spaces'
$ gh c
#=> error: "accepts 2 arg(s), received 4"this is because 'path with spaces' stopped being treated as a single argument when serialized into config:
aliases:
c: config set editor path with spaces|
nevermind, i'm tired and this is fully PEBCAC. My @mislav
|
|
@vilmibm are the aliases stored in a file somewhere? would be awesome if somehow |
|
@DanyC97 aliases are stored in the config.yml file; we have no plans to read them from gitconfig but we're actively removing the auth stuff from the gh config file so that people can start committing their gh config alongside other dotfiles. |


This PR adds
gh alias set.what this PR does
$1)aliasessection to our config which is created on first use ofalias setwhat this PR doesn't do
gh alias set#941 )considerations
I did two things I'm nervous about in this PR.
main.goto initialize aContext, check the config, and rewriteargvif an alias is found.alias set. I encountered what I think is a bug where cobra would treat flags inside of single quoted strings as something it should parse (egalias set il 'issue list --label="bug"'). Disabling flag processing for this command fixed the problem but if we ever wantalias setto accept flags we'll need to revisit this.I'm open to feedback on those things.
demo
(right click view image to make more legible)
todotodidalias set(though it might be fine to ship initially)closes #938