What does this command do 'GOFLAGS=-mod=mod'? - go

I am trying to make a Taskfile.yml file for building go application, but I can't quite understand the need of "GOFLAGS=-mod=mod" command before go build main.go.
reference: https://dev.to/aurelievache/learning-go-by-examples-part-3-create-a-cli-app-in-go-1h43

So there are two things here
GOFLAGS
this is nothing but an environment variable(if you don't understand what an environment variable is, think of it like a value that can be accessed by any process in your current environment. These values are maintained by the OS).
So this GOFLAGS variable has a space separated list of flags that will automatically be passed to the appropriate go commands.
The flag we are setting here is mod, this flag is applicable to the go build command and may not be applicable to other go commands.
If you are curious how go does this, refer to this change request
Since we are mentioning this as part of the command, this environment variable is temporarily set and is not actually exported.
what does setting -mod=mod flag, actually do during go build?
The -mod flag controls whether go.mod may be automatically updated and whether the vendor directory is used.
-mod=mod tells the go command to ignore the vendor directory and to automatically update go.mod, for example, when an imported package is not provided by any known module.
Refer this.
Therefore
GOFLAGS="-mod=mod" go build main.go
is equivalent to
go build -mod=mod main.go

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 ./...

What does OMIT mean in a Go build constraint?

I found // +build OMIT in this page https://blog.golang.org/context/server/server.go
I know what a build constraint is.
OMIT isn't
a GOOS or GOARCH value
a compiler name
cgo
a term for each Go major release as go1.12
any additional tags given by the -tags flag
Does it literally mean "omit something here" as // +build ignore keeps a file from being considered for the build ?
The source file is ignored when the the build tag OMIT is not specified. It works the same way as ignore. The OMIT and ignore tags have no special meaning to the build tools.
The file is included in the blog post using the present package .code command. The .code command ignores source file lines ending with OMIT.
In summary, two things are going on. The build constraint is used to ignore the file. The tag OMIT is used instead of the more common ignore so that the build constraint does not appear in the blog post.
The program is run using go run server.go. The go run command ignores build constraints.

'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

Set Go variable with ldflags conflicts with vendor folder

I'm currently developing a small Go app and I want to set a specific variable (like Version, GitCommit, BuildID...etc.) at build or runtime (with go build or go run) by using the -ldflags option.
Because in my company we have several projects with the same base, I decided to extract the code with these variables in a separate "info" module which could be imported in every project.
Here's my problem, say I'm running the app like this:
go run -ldflags "-X git.mycompany.com/utils/info.Version=1.0.0" app.go
This works well, and the variable is set correctly even though the variable is not part of the "main" app but in a dependency.
Then I decided to deploy the app so I used the new dep tool to generate the vendor folder.
Therefore, the "info" dependency is now in: vendor/git.mycompany.com/utils/info
Now when I run the same command as above, the said variable (Version) is not set anymore.
Am I missing something here ?
As soon as I delete the vendor folder, everything works fine again. It's like this vendor folder is conflicting with the -ldflags option or something.
Thanks in advance!
We had exactly the same problem, after lots of research we stumbled upon the solution in a comment to GitHub issue: cmd/link: -X doesn't work for vendored packages.
Solution: the full path name, relative to $GOPATH should be specified.
It works when developing git.mycompany.com/utils/info because the full path is correct.
It doesn't work for vendored dependencies because the full path from $GOPATH would be like git.mycompany.com/name-of/package/vendor/git.mycompany.com/utils/info.Version=1.0.0
Unfortunately, no documentation seem to be present about this ( for further info look at the issue ) but as Dave Cheney points out in a comment:
this is a side effect of the language way vendoring is implemented

On `go build` creating cgo headerfile

Short of it is in the title... I'm trying to have the headerfile that cgo already creates cgo_export.h - but sticks in the working directory - created in a static location that I can reliably access (as working directories can and should change). Directly using cgo provides for a -headerfile option, but I see no such option within the build options of go build, nor a way of passing options to cgo from go build.
Besides using a second run of cgo(or some script to grab the header each time from the working directory) is there any way to produce the header file with go build

Resources