Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go compatibility #82

Closed
iamnoah opened this issue Jun 24, 2021 · 4 comments
Closed

Go compatibility #82

iamnoah opened this issue Jun 24, 2021 · 4 comments

Comments

@iamnoah
Copy link

iamnoah commented Jun 24, 2021

I struggled to get Go private modules working and wanted to share my workaround in case it's helpful or the changes can be incorporated. Basically the default .gitconfig generated when using commented keys doesn't seem to work with go get and related commands.

The tl;dr is I need the config to go from this:

[url "git@d5ec..:my-org/my-repo.git"]
	insteadOf = https://github.com/my-org/my-repo.git
        ...

to

[url "ssh://git@d5ec.../my-org/my-repo"]
	insteadOf = https://github.com/my-org/my-repo
	...

The key differences being:

  • urls do not end with .git
  • url needs to be ssh:// formatted. i.e., first : -> /, and the scheme.

The reason for this seems to be that go interacts with git by specifying the origin as https://github.com/my-org/my-repo, which works, but won't match the longer (arguably more correct) URL you've put in the config. e.g., internally go is doing git remote add origin -- https://github.com/my-org/my-repo without a trailing slash or .git.

I'm currently working around this with this sed script:

          sed -i.bak -re '
          s|(insteadOf.*https://.*)\.git$|\1|g
          s|\[url "(git@[^:]*]?):(.*?)\.git"\]$|[url "ssh://\1/\2"]|g' ~/.gitconfig

NOTE: For anyone else trying to get this working, you will also need GOPRIVATE=github.com/my-org/* as an environment variable.

@mpdude
Copy link
Member

mpdude commented Jun 24, 2021

Thank you for raising this issue! First, let me say that I have no experience with go at all.

I have tried to find some documentation on how go finds and loads private modules and I came across this https://golang.org/ref/mod#vcs-find:

If the module path has a VCS qualifier (one of .bzr, .fossil, .git, .hg, .svn) at the end of a path component, the go command will use everything up to that path qualifier as the repository URL. For example, for the module example.com/foo.git/bar, the go command downloads the repository at example.com/foo.git using git, expecting to find the module in the bar subdirectory. The go command will guess the protocol to use based on the protocols supported by the version control tool.

Also, a bit further down, it says:

repo-url is the repository's URL. If the URL does not include a scheme (either because the module path has a VCS qualifier or because the tag lacks a scheme), the go command will try each protocol supported by the version control system. For example, with Git, the go command will try https:// then git+ssh://. Insecure protocols (like http:// and git://) may only be used if the module path is matched by the GOINSECURE environment variable.

This makes me wonder if you could specify your module slightly different, including the .git extension, to make it work without the extra configuration?

@iamnoah
Copy link
Author

iamnoah commented Jun 24, 2021

I honestly am not entirely sure what that is referring to, but including the scheme is not valid in go.mod. I can't go get ssh://.. without getting go get: malformed module path

There are some hardcoded assumptions in the go tooling about the github.com namespace that cause it to default to git over https. I could be wrong and there is an easier workaround, but the only solution I have seen is to use insteadOf gitconfig to rewrite the URL.

@mpdude
Copy link
Member

mpdude commented Jun 24, 2021

ssh-agent/index.js

Lines 53 to 68 in 5f066a3

const parts = key.match(/\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/i);
if (!parts) {
console.log(`Comment for key '${key}' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.`);
return;
}
const sha256 = crypto.createHash('sha256').update(key).digest('hex');
const ownerAndRepo = parts[1].replace(/\.git$/, '');
fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
child_process.execSync(`git config --global --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);

Doesn't that generate the insteadOf = config value without a trailing .git as you suggested?

@iamnoah
Copy link
Author

iamnoah commented Jun 24, 2021

@mpdude my apologies, I seem to have been running against v0.5.0. The URL format in v0.5.3 seems to resolve everything for me without modifications. Thanks!

@iamnoah iamnoah closed this as completed Jun 24, 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

No branches or pull requests

2 participants