Build constraints exclude all the Go files - go

I'm newbie to go and I've created a file and init a mod inside of it by typing:
go mod init github.com/AnmarDc/e-commerce
After that, I made a folder called controllers which will contain all the controllers of my operations on my site and then tried to import it into my routes folder, but that didn't work.
I kept getting the following error:
Build constraints exclude all the Go files in 'C:/Users/engan/Go/src/Projects/eCommerce/controllers'
I thought it was about GoPath, or GoRoot, but I found it out it's because GoLand itself, but I have no idea how to fix it, as I can see everything seems reasonable to me.
GoEnv attached.

Oh, it looks like there's some issue in building constraints, I just imported the following code in my routers:
//go:build (linux && 386) || (darwin && !cgo)
and it worked perfectly.
Reference:
Constraints

Related

How do I stop the auto importing of imported item in go outside of my project?

I have my projects that have many packages which import each other and import outside packages. When I make a change to one of my low lever packages, and then push it to git it is fine and works in that section. When I go get it for use in another project that was working perfectly I now get this go get this error:
module declares its path as: github.com/xdg-go/scram
but was required as: github.com/xdg/scram
None of my code uses either of those directly. It looks like it automatically updated some lower external packages and broke things the used to then old import.
How do I either find out the package that is importing the wrong name or stop all auto-updates?
The go.mod file at github.com/xdg/scram declares itself as github.com/xdg-go/scram:
module github.com/xdg-go/scram
go 1.11
require (
github.com/xdg-go/stringprep v1.0.2
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
)
The go.mod file should be updated to reflect the correct import path.
Unfortunately if this module is for you an indirect dependency, the best fix possible is to update whatever project you import that is directly importing it.
When that is not an option, a solution to this error is to clone the problematic repository locally and use the replace directive in your go.mod file:
module mymodule
replace github.com/xdg/stringprep => ../strprep
go 1.16.2
require (
github.com/divjotarora/mgo v0.0.0-20190308170442-1d451d2a3149
)
where ../strprep is where the code of the required module exists in your local machine, relative to the go.mod file of your project.
The downside of this of course is that you have to replicate this palliative fix wherever you plan to go get your modules.
Note also:
divjotarora/mgo is just a random example of a project that imports one of those packages using their old import path.
I'm using xdg/stringprep as an example because I can't find modules that import xdg/scram instead, but apparently it suffers from the same issue
Beside, you can use:
go mod why <package> to find out why a certain package is listed as a dependency of your project
go mod graph to show the full dependency graph. The output is in <package> <requirement> format

Understanding How to Build Go Source

I am confused about how to layout my Go project and then how to build it. I am reasonably new to Go and believe there was a time <1.13 where the GOPATH was important. I am using 1.14, so I believe I do not have to care about that and GOPATH is not set. I do not (for the moment) host my code on GitHub (which is something various articles assume). I have read a number of things, but it all leaves me more confused:
https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies
https://www.wolfe.id.au/2020/03/10/starting-a-go-project/
https://talks.golang.org/2014/organizeio.slide#1
I have laid out my project according to this: https://github.com/golang-standards/project-layout. (Except this project seems to use a Makefile. I do not want to write a Makefile. I believe this should all work without a Makefile. I really do not want to write a Makefile.)
Here is the structure:
/src
/cmd
main.go
/internal
helper.go
go.mod
go.mod looks like this:
module mycompany/mymodule
go 1.14
service.go looks as follows
package main // this has to be called 'main'
import (
"mycompany/mymodule/internal/helper"
)
func main () {
helper.greet("Jenny")
}
So, if I am in /src and I run build cmd/service.go I get
cmd/service.go:4:2: package mycompany/mymodule/internal/helper is not in GOROOT (/usr/local/Cellar/go/1.14.5/libexec/src/mycompany/mymodule/internal/helper)
Do I have to compile helper.go first? Manually? Surely not. go build surely should be able to build my entire project, right? Including all the dependencies. Could someone please tell me what I am missing?
When you run go build without specifying file path, it will look for the main function inside any .go files at current directory to start. It doesn't build entire project. But it wouldn't be a problem in this case.
You're importing wrong package. The package name to import must be mycompany/mymodule/internal not mycompany/mymodule/internal/helper.
And to invoke a function inside another package, it must be exposed to outside.
So you have to declare the function greet() as Greet()

VS Code throwing error 'No package for import' but code compiles and runs fine

As a work requirement learning gRPC through an online course.
I have a project defined in folder greet (outside of GOPATH) with three packages called:
greet_client
greet_server
greetpb
In the go.mod file at the root of my project, I've specified the following:
module example.com/myuser/myproject
go 1.14
The code in greet_server/server.go makes a reference to greetpb.
I'm referencing it like the following:
I'm able to run server.go successfully.
It returns the expected the result:
My question is on the red squiggly lines VSCode throws saying it could not import greetpb:
Here's how package greetpb is defined (it's an auto generated file):
How can I get rid of this warning message?
Is it something I've not setup properly?
Update:
When I try to ctrl+click to view the module greetpb on the file server.go, I note that it's pointing to the url pkg.go.dev.
How can I make the program to do a "local" lookup?
Why would you use example.com? You don't have your package defined there.
Initialize go modules first i.e.
go mod init github.com/$USER/$REPO
Go mod vendor
go mod tidy && go mod vendor
That's it.

golang modules and local packages

I'm trying to understand how to organize my golang project using go1.11 modules. I tried several options, but none of them worked.
I have some code in the main package under the application folder and a local package that the main package uses.
$GOPATH
+ src
+ application/
+ main/
+ main.go
+ otherFileUnderMainPackage.go
+ aLocalPackage/
+ someCode.go
+ someCode_test.go
+ someMoreCode.go
+ someMoreCode_test.go
Files in the main package, imports ../aLocalPackage. When I compile by go build main/*.go it's working.
Then, I ran go mod init application: V.0.9.9 and got the go.mod file, but the build always fails. I always get error about not finding the local package: build application:V0.9.9/main: cannot find module for path _/.../src/application/aLocalPackage. I also tried to place the local package right under src/, place it under main/ etc. but none of these methods worked for me.
What is the way to use modules and local packages?
Thanks.
Relative import paths are not supported in module mode. You will need to update your import statements to use a full (absolute) import path.
You should also choose a module name other than application. Your module path should generally begin with a URL prefix that you control — either your own domain name, or a unique path such as github.com/$USER/$REPO.
I had some problems working with local packages myself.
There are two tricks to make it work:
you run "go build" in the package directory
This compiles the package and places it in the build cache.
This link about code organisation in go explains more.
You can identify where the cache is using:
>go env GOCACHE
/home/<user>/.cache/go-build
Import using a path relative to the project
I puzzled loads over what the correct import path was and finally discovered that go doc or go list will tell you.
>go doc
package docs // import "tools/src/hello/docs"
>go list
tools/src/hello/docs
For example. I have a hello world API project and was using swaggo to generate documentation which it does in a docs sub-directory.
To use it I add an import:
_ "tools/src/hello/docs"
For my case the _ is important as docs is not used directly but we its init() function to be invoked.
Now in hello/main.go I can add "tools/src/hello/docs" and it will import the correct package.
The path is relative to the location of go.mod if you have one.
I have tools/ here as I have a go.mod declaring "modules tools".
Modules are a different kettle of fish - see https://github.com/golang/go/wiki/Modules.
Recent versions of go (1.11 and later) can create a go.mod file which you may use to fix the version of a module that is used and avoid go's crazy default behaviour of just downloading the latest version of any package you import.
I have written a blogpost on how to start your first Go project using modules.
https://marcofranssen.nl/start-on-your-first-golang-project/
In general it boils down to just create a new folder somewhere on your system (doesn't have to be in GOPATH).
mkdir my-project
cd my-project
go mod init github.com/you-user/my-project
This will create the go.mod file. Now you can simply create your project layout and start building whatever you like.
Maybe one of my other blogs can inspire you a bit more on how to do things.
https://marcofranssen.nl/categories/software-development/golang/

"undefined" function declared in another file?

I'm trying to write a basic go program that calls a function on a different file, but a part of the same package. However, it returns:
undefined: NewEmployee
Here is the source code:
main.go:
package main
func main() {
emp := NewEmployee()
}
employee.go:
package main
type Employee struct {
name string
age int
}
func NewEmployee() *Employee {
p := &Employee{}
return p
}
func PrintEmployee (p *Employee) {
return "Hello world!"
}
Please read "How to Write Go Code".
Use go build or go install within the package directory, or supply an import path for the package. Do not use file arguments for build or install.
While you can use file arguments for go run, you should build a package instead, usually with go run ., though you should almost always use go install, or go build.
I just had the same problem in GoLand (which is Intellij IDEA for Go) and worked out a solution. You need to change the Run kind from File to Package or Directory. You can choose this from a drop-down if you go into Run/Edit Configurations.
Eg: for package ~/go/src/a_package, use a Package path of a_package and a Directory of ~/go/src/a_package and Run kind of Package or Directory.
If you're using go run, do go run *.go. It will automatically find all go files in the current working directory, compile and then run your main function.
You can try one of the following:
Method 1:
Assume that your project name is MyProject
Go to your path, run go build
It will create an executable file as your project name ("MyProject")
Then run the executable using ./MyProject
You can do both steps at once by typing go build && ./MyProject. Go files of the package main are compiled to an executable.
Method 2:
Just run go run *.go. It won't create any executable but it runs.
go run . will run all of your files. The entry point is the function main() which has to be unique to the main package.
Another option is to build the binary with go build and run it.
If you want to call a function from another go file and you are using Goland, then find the option 'Edit configuration' from the Run menu and change the run kind from File to Directory. It clears all the errors and allows you to call functions from other go files.
you should use go modules now, if you are not following How to write go code
With go module you don't have to put the code in the $GOPATH/src. it can live in any other location as well.
You can move the code to different directory like /employee, To make it work Just under employee directory initialise the go module
go mod init example.com/employee
I ran into the same issue with Go11, just wanted to share how I did solve it for helping others just in case they run into the same issue.
I had my Go project outside $GOPATH, so I had to turned on GO111MODULE=on without this option turned on, it will give you this issue; even if you you try to build or test the whole package or directory it won't be solved without GO111MODULE=on
While this doesn't directly address the OP's specific issue, I thought I'd chime in with the solution to my "undefined" error: the file with the undefined method had a build constraint (build tag).
More specifically, I accidentally included a build constraint to remove testing files from my deployed application binary in a utility function file used by my deployed binary. So in the OP's example - if employee.go had a build constraints their go build command would need to include a -tags flag matching the constraint in in order to have the file included.
For more info read this blog post:
https://dave.cheney.net/tag/build-constraints
Took a while to drill down my own MRE for this, so hopefully it will help others, despite being brief:
This can also occur if your functions / structs are defined in a file that has import "C", which will be silently ignored if CGO_ENABLED=0 is in your go environment, leading to you staring at a two file package that somehow is unable to share between themselves.
In GoLand,
right click a directory
GoLand will give you the option for build it and run it
it will also create a run configuration draft for you
you can save with an option of the upper right dropdown
If you right clic a file, it shows you commands to run, debug, test that file.
If you right clic a directory, it will be the same for that "package", expecting a main.go file inside the directory
I had a nasty import "C" in one of my go files.
If your source folder is structured /go/src/blog (assuming the name of your source folder is blog).
cd /go/src/blog ... (cd inside the folder that has your package)
go install
blog
That should run all of your files at the same time, instead of you having to list the files manually or "bashing" a method on the command line.
Off topic but still :-)
Before:
func NewEmployee() *Employee {
p := &Employee{}
return p
}
After:
func NewEmployee() *Employee {
return &Employee{}
}
No need to create a new variable. Just return.

Resources