Skip to content

Confirm name change before creating a repo with special characters#4562

Merged
mislav merged 12 commits intocli:trunkfrom
bchadwic:special-characters
Nov 18, 2021
Merged

Confirm name change before creating a repo with special characters#4562
mislav merged 12 commits intocli:trunkfrom
bchadwic:special-characters

Conversation

@bchadwic
Copy link
Contributor

Submitting a draft to close #4558

This feature asks for confirmation if the name typed in for a new repo will be different from what will end up on the GH backend.

Example:
passing name as an arg

$ gh repo create C#
? Visibility Public
? Would you like to add a .gitignore? No
? Would you like to add a license? No
? Your new repository will be created as C-. Continue? No
Discarding...

interactive prompt

$ gh repo create
? Repository name C#
? Repository description 
? Visibility Public
? Your new repository will be created as C-. Continue? No
Discarding...

one liner

$ gh repo create -y --private C#
? Your new repository will be created as C-. Continue? No
Discarding...

possible bug? As a user, -y means Skip the confirmation prompt, however, why force something you didn't mean in the first place? Input needed.

@bchadwic bchadwic requested a review from a team as a code owner October 19, 2021 05:32
@bchadwic bchadwic requested review from mislav and removed request for a team October 19, 2021 05:32
Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

Thanks for this! I have an important request of having this logic work only in interactive mode.

Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

Oops, I wanted to "Request Changes" instead 😅

@bchadwic
Copy link
Contributor Author

@mislav

Hopefully this is a little better :)
I agree with all the points made above, so the changes made reflect that.

I'm not sure how I feel about this though:

$ gh repo create C#
? Visibility Public
? Would you like to add a .gitignore? No
? Would you like to add a license? No
? This will create the "C-" repository on GitHub. Continue? Yes
? This will add an "origin" git remote to your local repository. Continue? No
Discarding...
$ gh repo create C
? Visibility Public
? Would you like to add a .gitignore? No
? Would you like to add a license? No
? This will add an "origin" git remote to your local repository. Continue? No
Discarding...

Could the two confirmations at the end be combined? I suppose the first confirmation only shows if the name will be normalized, so not a big deal but it still seems kind of painful to confirm twice.

Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

Almost there!

alreadyDashed = true
}
func normalizeRepoName(name string) string {
re := regexp.MustCompile(`[^a-zA-Z0-9-._]+`)
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. Since - has special meaning inside [...] in regular expressions, a literal - inside of [] should always be at the very end, just before the closing ].
  2. Instead of a-zA-Z0-9_ you could use \w which is equivalent.
  3. Since this regular expression is static, you can declare it on the package level instead of in the function: var invalidRepoNameCharacters = regexp.MustCompile(...)

}
func normalizeRepoName(name string) string {
re := regexp.MustCompile(`[^a-zA-Z0-9-._]+`)
if normalizedRepoName := strings.TrimSuffix(re.ReplaceAllString(name, "-"), ".git"); normalizedRepoName != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no need for this if, I think. Just return the result of TrimSuffix and regexp replacement.

Name string
LocalName string
RemoteName string
Name string
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't look like the Name field is used in the tests, so you can remove it

if inLocalRepo {
if normalizedRepoName != repoName {
var confirmNormalizedName bool
err := survey.AskOne(&survey.Confirm{
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that I see how this adds an additional prompt to the inLocalRepo case:

This will create the "OWNER/REPO" repository on GitHub. Continue?  Yes
This will add an "origin" git remote to your local repository. Continue?

I wonder whether we could just fold this into a single prompt:

This will create "OWNER/REPO" on GitHub and add it as the "origin" git remote. Continue?

What do you think?

Copy link
Contributor Author

@bchadwic bchadwic Oct 20, 2021

Choose a reason for hiding this comment

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

Agreed, I think the confirm prompt should contain the new repo name regardless of inLocalRepo or if the name was normalized.

I removed the inLocalRepo parameter from confirmSubmit for this reason, was that safe to assume?

@mislav mislav changed the title closes #4558, produce a confirmation before creating a repo with special characters Confirm name change before creating a repo with special characters Oct 20, 2021
return normalizedRepoName
}
return "-"
return strings.TrimSuffix(regexp.MustCompile(`[^\w.-]+`).ReplaceAllString(name, "-"), ".git")
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks great now. I love how much simpler it has become 😄 Just had a thought: could you add a comment to this function explaining that this intends to match the logic by which GitHub the platform also normalize repo names?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mislav

Thanks! I've been sharpening up on my regex skills because of this repo haha

I have a humble suggestion. Since I've been creating repos with the new feature, I tend to cross check and confirm that what I typed in is the same as what will be normalized in the confirm prompt every time.

Something that I like about the website, is that I can quickly know without cross checking, if my name will be changed thanks to the nifty color system.

Green -> what I typed in is the same as what will appear on the server
Yellow -> something in my repo name will be normalized
Red -> empty string (currently if .git is inputted, gh repo create will try to make a repo with an empty string as the name)

Could we do a colorizing system (Green / Yellow) for just the name so users can just confirm using the color? If this crowds the code or seems unnecessary I understand. Also if the name is an empty string, should we still call the API knowing that it will fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For example, without color this might be a pain. For accessibility we could also adapt the text the web site uses. Maybe I'm getting ahead of myself on this one though.

warning

good

Copy link
Contributor

Choose a reason for hiding this comment

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

The color switching for this isn't a bad idea, but I think it would be overkill for this feature right now. Let's hold off for now and see whether we feel it's actually necessary in the future.

@bchadwic
Copy link
Contributor Author

Sorry for the hold up! I think I have it close to being ready. I added the conditional statement back in for inLocalRepo

This is what it looks like now in use

$ gh repo create example!
? This will create the "example-" repository on GitHub. Continue? No

# after creating a local .git

$ gh repo create
? Repository name (example!)
? This will create "example-" on GitHub and add it as the "origin" git remote. Continue? No

We plan a larger refactoring around this aspect of repo create functionality, but until then, it would be best to keep the original behavior.

Gotcha! I'll keep an eye on this one :)

normalizedRepoName := normalizeRepoName(repoName)
if inLocalRepo {
promptString = `This will add an "origin" git remote to your local repository. Continue?`
promptString = fmt.Sprintf(`This will create "%s" on GitHub and add it as the "origin" git remote. Continue?`, normalizedRepoName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the OWNER/REPO format in this prompt rather than just REPO since the else branch in this code also uses the OWNER/REPO format for the repository in the prompt. Rule of thumb is: repositories should always be displayed in OWNER/REPO format to reduce ambiguity.


// normalizeRepoName takes in the repo name the user inputted and normalizes it using the same logic as GitHub (GitHub.com/new)
func normalizeRepoName(repoName string) string {
return strings.TrimSuffix(regexp.MustCompile(`[^\w.-]+`).ReplaceAllString(repoName, "-"), ".git")
Copy link
Contributor

Choose a reason for hiding this comment

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

Underscore _ is also an allowed character

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://regex101.com/r/Sl6WtS/1
https://pkg.go.dev/regexp/syntax

I think \w includes _? I added _ to the regex just to be sure, but I supplied a test golang regex link above as well as the docs.

Comment on lines +630 to +633
targetRepo := normalizeRepoName(repoName)
if repoOwner != "" {
targetRepo = fmt.Sprintf("%s/%s", repoOwner, targetRepo)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the targetRepo assignment outside of the if inLocalRepo statement. Is this what you meant above about HOST/REPO?

Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

Thank you; this looks good! I've resolved conflicts with the base branch and I love how minimal we brought the diff down to 😄

@mislav mislav enabled auto-merge (squash) November 18, 2021 13:21
@mislav mislav merged commit 6cc7712 into cli:trunk Nov 18, 2021
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.

gh repo create doesn't acknowledge special characters in repo names

3 participants