Go Modules vs Package - go

just starting to learn about Go Modules. I have a question on importing local packages inside the same module. The example I am looking at is this repo:
https://github.com/Azure/azure-service-bus-go
The module is module github.com/Azure/azure-service-bus-go. There is a separate package inside that module, atom (but it's not a module itself).
When files inside the main package import atom, they do it like this: import "github.com/Azure/azure-service-bus-go/atom" -- see queue_manager.go as an example.
What I do not quite understand -- how does GO know to look at the local atom package, as opposed to, say the one on Github? It seems confusing to me that something that is part of the module being modified is referenced by a remote/absolute URI. Is it guaranteed that if I modify the file on local disk and build I'm actually referencing the latest version as opposed to something already pushed?
As a toy exercise I tried to create a module with a non-existent Github URI and it did in fact appear that go mod tidy tried to look that up against Github, even though a local copy did in fact exist

A module is a collection of go packages.
A package is a directory of .go files. Using packages, you organize your
code into reusable units.
We can add a module to go project or upgrade the module version.

The module directive in the go.mod file declares the import-path prefix for all of the packages within that module.
If you are just starting to learn about Go modules, the
Create a Go module tutorial might be a good place to start.

Related

Go, using other packages in the same project

I have the following situation, where I can't use romanNumerals in romanserver, inside a folder in my module directory.
go run romanserver/main.go
romanserver/main.go:13:2: no required module provides package github.com/BuddhiLW/roman/romanNumerals; to add it:
go get github.com/BuddhiLW/roman/romanNumerals
I want to upload the roman project to GitHub containing both romanNumerals and romanserver. Of course, I would like to export variables from one another.
I'm still confused about how that is done in Go.
EDIT: I deleted go.mod in both romanNumerals and romanserver, and now everything is working, just like
Cerise Limón pointed out.

managing hardcoded import paths

In Go, it is common that some packages are versioned. So a program might look like this:
package main
import (
"github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
)
// ... do stuff
Sometimes, I might want to update the version of glfw. Lets imagine GLFW 3.3 bindings come to Go and I want to update from 3.2.
I might have multiple Go files in a project all using glfw. I don't want to go into each of them and update the version of the import by hand. Ideally I wouldn't be copying that long path around, either, and I could define it in one place per project.
Maybe I could write a script to find+replace "github.com/go-gl/glfw/v3.2/glfw"
Maybe I could template the file with Genny
Maybe I could create a symlink inside the root Go path "glfw" -> "github.com/go-gl/glfw/v3.2/glfw", update it when changing version, and just use import "glfw"
but this information then lives "outside" the project, so no-one cloning my project knows what version to use
but this is a global change and I might have multiple projects which want to depend on different versions
Ideally I would be able to do something like this in each source file:
package main
import (
$gl
$glfw
)
And in some project-level dot file, something like:
gl=github.com/go-gl/gl/v3.3-core/gl
glfw=github.com/go-gl/glfw/v3.2/glfw
Or, a command-line argument attached to go build defining constants that could look something like:
go build -Dgl=github.com/go-gl/gl/v3.3-core/gl -Dglfw=github.com/go-gl/glfw/v3.2/glfw
How is everyone else handling this currently?
See github.com/golang/go/wiki/Modules for the recommended way of managing package versions.

Multiple files in same package in Go

I'm writing my first Go code which among other things, sends an email. After finding out that the package net/smtp only supports Plain Auth (but some providers like outlook doesn't support it), I asked for a solution and got pointed out to https://gist.github.com/andelf/5118732.
That code works like a charm, but as it's not something written by myself, I would like to add it in a separate file and just reference it in my main.go.
What's the right approach to have multiple files in the same package? I don't want to create a different package just for that code, first because it's not mine, and secondly, because I think it's an "overkill" approach, isn't it?
I thought that as long as the files are in the same directory, I could have many *.go files, but it seems it's not working out. If I just create a file with the content of that gist, the compiler fails because expected package, found import. If I add something like package auth, then it fails because found packages auth (auth.go) and main (main.go)
So, what's the general practice in this situations? Just create packages for everything?
You can have only one package in a directory, and it looks like you don't need a package for this addition, so you can simply put that in a separate file, and add package main at the top. Having a main package and putting everything under it works up to a point. As things get larger, you have to break it up into self-contained packages.
If your current working directory is in GOPATH, then you can just add new go file with same package name main.
If your current working directory is not in GOPATH, you can still put them in multiple go files and when you run the program, you should use go run *.go instead of just go run main.go.
There are also other options which you can refer Run code with multiple files in the same main package in GoLang for detail.

how to organize GO project packages if it will hosted on different repos (GitHub & SourceForge)

Say I want to create a project and host it on GitHub,I HAVE TO create project struct like this:
src/github.com/user/
myproject/
main.go
util/
fileutil.go
and in the main.go ,I have to write the import as:
import github.com/user/myproject/util/fileutil
AND now I also want to host this project onto SourceForge, should I copy the whole project and modify the path ?? it seems not so good enough. Is there any other way to do that ? What I need is just create my project under src folder, and can be hosted to any repo as I wish, without changing the packages.
If developing an app and not a library
If you don't plan to have other projects "import" your own project (this is, if you are implementing an application and not a library), it might be possible for you to avoid any reference to github.com in your local paths.
Note: this is not the recommended approach, but from my tests it does work, you can compile, run and test your code if you structure it this way.
You can create your project structure as follows:
src/
myproject/
main.go
util/
fileutil.go
Then you can import like this:
import "myproject/util/fileutil"
You can then host the contents of the myproject folder anywhere without changing paths within the project files.
If developing a library
If you are actually developing a library others will be able to import, then it gets more complicated since those projects will actually need a full path to import your project.
You can create a "vanity" import path, like myproject.io/... by using the meta tag like described here:
https://golang.org/cmd/go/#hdr-Remote_import_paths
That way, when the go tool queries your myproject.io/ pages, you should respond with a header like this:
<meta name="go-import" content="myproject.io git https://github.com/user/myproject">
And then change that header you return if you decide to move away from github.
Note that this does not prevent users to import your project directly from github, if you want to avoid that you need to use the technique described in the canonical import path spec:
https://golang.org/doc/go1.4#canonicalimports

Working with digital signatures in Go

I would like to use signatures for a program that I am writing in Go, but I can't figure out the documentation, which is here. In particular, I would like to use the SignPKCS1v15 and VerifyPKCS1v15 functions, but I'm not sure exactly what I have to pass as arguments. I would greatly benefit from some example code of these two functions. Thanks.
Note: The message that I would like to send is a struct that I defined.
I think the src\pkg\crypto\rsa\pkcs1v15_test.go file in the Go source tree should be a good start.
An update striving provide more context… Go source contains many tests for the code in its standard library (and the crypto/rsa package is a part of it), so whenever you have no idea how to use a standard package (or, actually, any other Go package), a good place to start is to look at the tests involving that package as testing code naturally uses the package! Tests are kept in files ending in _test.go, usually have meaningful names and are located in the same directories actual code implementing a particular package is kept.
So in your particular case you could do this:
Download the Go source package of the version matching your compiler (what go version shows) and unpack it somewhere.
Navigate to the directory matching the package of interest. Code for standard Go packages is located in the "pkg" directory under the "src" top-level directory, so if you're interested in the crypto/rsa package, you need the src/pkg/crypto/rsa directory.

Resources