should src folder be created in golang go1.17 - go

I am starting off with golang according to some document it mentions $GOPATH default should have bin pkg src directories.
When a I do go get github.com/astaxie/beedb there no src folder created and the source goes and sits in $GOPATH/pkg//mod/github.com/astaxie/beedb#v0.0.0-20141221130223-1732292dfde4/
according to documentation the it should be in src folder
I am using golang go1.17. Has something changed in newer versions or am I refering old doc.

you don't need to create src folder under $GOPATH
With Go modules, Go projects are no longer confined to $GOPATH
Don't confuse the project level /src directory with the /src directory Go used to use for its workspaces, but please note
"Since Go 1.14, module support is considered ready for production use, and all users are encouraged to migrate to modules from other dependency management systems "
please check below links
https://github.com/golang/go/wiki/Modules

There is no need to manually create the sub-folders in $GOPATH. When you run go get, go will handle everything for you. So if there is no src folder, you can just leave it.
The src folder was basically for package management before Go Modules (enabled by default since go 1.13). You don't really need this now.

Related

How to use an alternate go.mod file for local development?

Currently I am working on an API which uses Serverless Framework with Go.
I'm using the Serverless-offline plugin for local testing.
This API depends on a few other repositories (which I also maintain), which I import using the go.mod file.
However I am having a hard time refining my developer workflow.
Currently, if I want to make changes in a repository which this API depends upon, I have to alter the projects go.mod to include replace directives for the purpose of testing, but then I'm having to manually change it back for deployment to production.
Basically I'm looking for a way to include replace directives, which only get applied during local development. How has everyone else dealt with this problem?
Bonus question: Is there any way to run Serverless offline in docker? I'm finding that serverless-offline running on the bare metal is causing inconsistencies between different developers environments.
You can run go commands with an alternate go.mod file with the -modfile option:
From Build commands:
The -modfile=file.mod flag instructs the go command to read (and
possibly write) an alternate file instead of go.mod in the module root
directory. The file’s name must end with .mod. A file named go.mod
must still be present in order to determine the module root directory,
but it is not accessed. When -modfile is specified, an alternate
go.sum file is also used: its path is derived from the -modfile flag
by trimming the .mod extension and appending .sum.
Create a local.go.mod file with the necessary replace directive for development and build, for example, with:
go build -modfile=local.go.mod ./...

Building Go module without main file

I have a small module that contains some shared code. The module looks like the following :
Shared
├── go.mod
├── go.sum
├── logging
│ └── logger.go
└── db-utils
├── db.go
If I'll try to build the Shared module from inside the directory I'm getting an error that no go file available under this module.
bash-3.2$ go build .
no Go files in /Users/xxxx/go/src/Shared
Is there a way to build a Go module that only has packages inside and doesn't have a main.go file? The motivation here is to use those packages in other go modules that can't access the internet or private repo in order to retrieve the packages.
The go command stores downloaded modules in the module cache as source code, not compiled object files. go build rebuilds the object files on demand and stores them in a separate build cache.
If you want to distribute a non-public module for use with other modules, you have a few options:
You can publish the module to a private repository — typically accessed with credentials stored in a .netrc file — and use the GOPRIVATE environment variable to tell the go command not to try to fetch it from the public proxy and checksum servers.
You can provide a private GOPROXY server or directory containing the source code, and use the GOPROXY environment variable to instruct the go command to use that proxy.
You can publish the source code as a directory tree and use a replace directive in the consumer's go.mod file to slot it into the module graph.
If you only needed to build files in either the logging or db-utils directory, then you could executing the following from the root directory Shared:
go build <INSERT_MODULE_NAME_FROM_GO_MOD>/logging
go build <INSERT_MODULE_NAME_FROM_GO_MOD>/db-utils
I'm not certain if those commands will work if one of the files has a dependency on a file from the other directory.
Another command that will probably build the entire project is this:
go build ./...
Is there a way to build a go module that only has packages inside and doesn't have a main.go file?
No. The input for the build process is a package, not a module. Note how it says [packages] in the CLI documentation of go build.
When building a package leads to multiple packages being compiled, that is merely a consequence of direct and indirect import statements coming from .go-files located in the package you are building.
Note that Go does not support compiling packages to binaries to distribute closed-source libraries or such. This was not always the case, though. See #28152 and Binary-Only packages. The closest which exists to supporting that are plugins, but they are a work in progress and require resolution of symbols at runtime.

How to use modules replace functionality in cloud functions

I have a google cloud function that is a subdirectory in a repository. It uses the "Directory with source code" option in the settings menu. I keep getting this error on deploy:
Deployment failure:
Build failed: go: parsing /utils/pubsub/go.mod: open /utils/pubsub/go.mod: no such file or directory
go: error loading module requirements
I'm assuming that GCF does not upload the entire directory to the instance, but instead only the folder? This breaks the replace functionality of Go modules. Is there something I am doing wrong?
Link to the repo: https://github.com/FreekingDean/jeffbotgo/tree/5d735cc/slackevent
I work at Google and on this product.
Only the directory where you run gcloud is uploaded. There is no staging step beyond zipping the current directory and uploading it.
Notably, modules are preferred by the builder over vendor. If there is a go.mod, modules will be used. When you upload your function, it only includes the directory with your function at the root, not any directories one level up. So, when there is a go.mod and you have a replace directive pointing one level up, it will not work.
The solution for now with this layout is to vendor and not upload the go.mod/go.sum files. When using gcloud, you can create a .gcloudignore file to do this for you. See https://cloud.google.com/functions/docs/concepts/go-runtime#specifying_dependencies for more detail. Alternatively, modify your project to include any necessary helper packages in subdirectories.
I had the same issue today.
When reading thru the documentation for the 8th time i came across a warning box bellow the "Vendor directory" headline.
Warning: If your project has both a go.mod file and a vendor directory
at the root of your project, the vendor directory will be ignored
during deployment. You must use a .gcloudignore file to ignore the
go.mod file in order to ensure that your vendor directory is used
during deployment.
So basically once i added a .gcloudignore file with go.mod (will add go.sum as well) everything worked. So i guess if you have a go.mod file the cloud function will try to fetch dependencies instead of using the ones uploaded in the vendor folder.
I'm just guessing here tough.

'is not within a known GOPATH/src' error on dep init

When I run dep init in project folder, the error occurs:
init failed: unable to detect the containing GOPATH: D:\projects\foo is not within a known GOPATH/src
My projects are located on another drive and not %GOPATH%/src (i.e. %USERPROFILE%\go\src).
It's a known error but it's unclear what is the solution.
How can I use dep without moving Go projects to %GOPATH%/src?
Go makes this choice so that there is nothing like a CLASSPATH (ie: Java) to deal with. You specify a $GOPATH that has a consistent src tree inside of it. If your repo makes references to particular git commits (rather than the ones checked out into $GOPATH/src/github.com/$githubUser/$githubProjectName), then those will be in the ./vendor directory of your project.
If you have a different Go project that uses a completely different set of checkouts, due to versioning issues, then you can have multiple $GOPATH values to deal with that.
How can I use dep without moving Go projects to %GOPATH%/src?
Not at all.
Go projects require that your project is within its path..
So first do a
$ go env
to find out where that is. Lets say it says /home/turgut/go
move the project that you downloaded that needs the dep to:
/home/turgut/go/src/myproject
then cd /home/turgut/go/src/myproject
and try the
dep ensure
command now.
what does go env command say your GOPATH is? Set GOPATH for your environment as per this doc
Follow steps here https://deployer.org/docs/7.x/installation
you can use this command vendor/bin/dep init instead of dep init

Move main out of the repository root in go

I am creating a project in go. Since there is already a lot of things at the root of the repository of the project (doc, README.md...), I want all the source code to go in a folder src, and all the test code in a folder named test :
\go
\src
\github.com
\user
\my_project
\src
main.go
some_func.go
\test
test_main.go
test_some_func.go
\doc
README.md
But I have two issues :
The build command is not working while I am in the my_project folder. I have to go in the my_project/src to successfully run build. I want to do it from the my_project folder. How to inforce go to understand that the source for my_project is in the src code ?
Then the executable produced by the go install command is named src. How to change the name of that executable ?
I want all the source code to go in a folder src, and all the test code in a folder named test :
Go has a way that it organizes source code. Do not fight this. It is how the system works. Organize your code the way Go wants you to. Do not try to force Go to work the way you have learned working in some other language. Every language has its own ways of doing things. None of them are "correct." Like Java, Go has very specific ideas of what you're supposed to do. Do it that way. (This isn't an argument about whether Go is "right" or Go is "wrong." Go is Go, and it does things in the Go way.)
In particular, you should not create another "src" directory. There is already a "src" directory at the top of the "go" tree. If you create another, redundant, "src" directory, then the package name for your project is "github.com/user/my_project/src" which is likely not what you want.
To make the executable be named what you want, put it in a directory named what you want (probably "my_project"). Put test files with the files they test. This is how go works.
So your tree should look like:
\go
\src
\github.com
\user
\my_project
main.go
some_func.go
main_test.go
some_func_test.go
\doc
README.md
Attempts to do something other than this is going to blow up over and over again, and questions of "how do I make the build system do this other thing" will continually return "put your code in the way the build system expects."
For details on what Go expects, and how you should organize your code, see GOPATH environment variable in the Command Go documentation. Once you've built your system this way for a while, you will start to see where you can deviate from it (like creating other directories for test utilities, but not test cases). Don't start deviating until you've tried it the standard Go way.

Resources