Go Dependency Error in SAM application when building with AWS Toolkit - go

I have a SAM application that has several endpoints (with their own module) and a seperate module in the same project that has helper functions, services etc.
When building the project with sam build, which should build and deploy all endpoints at once, it causes an error in the build process. The dependencies are definitely included in all related go.mod/go.sum files.
Here's the error:
Running GoModulesBuilder:Build
Build Failed
Error: GoModulesBuilder:Build - Builder Failed: ..\..\service\matchService.go:10:2: missing go.sum entry for module providing package github.com/aws/aws-sdk-go/aws (imported by testmodule/service); to add:
go get testmodule/service#v1.0.0
..\..\service\matchService.go:11:2: missing go.sum entry for module providing package github.com/aws/aws-sdk-go/aws/session (imported by testmodule/service); to add: go get testmodule/service#v1.0.0
If I execute sam build in the endpoint folder directly it works flawless however!
This is the basic folder structure of the project:
/api/matches/endpoint-a/main.go
/api/matches/endpoint-a/go.mod <- requires matchService of "testmodule" which lies in /, also requires aws-sdk-go indirectly
/api/matches/endpoint-a/go.sum
/services/matchService
/go.mod <- requires github.com/aws/aws-sdk-go/aws
/go.sum
/template.yaml <- includest AWS::Serverless::Function for endpoint-a

Related

Import module located in sub folder in Goland IDE

How can I get Goland to lint my go.mod correctly and not report "missing dependency" errors for a module I am maintaining in a sub directory of my main project?
I'm trying to follow the pattern in hashicorp's vault project where I maintain an api module in a sub folder (that can be imported by others without dragging in all deps used by my main project.) Just like in vault, I reference the api module by url in my main project's go.mod and override it with a replace pointing to the relative path location.
module github.com/hashicorp/vault
go 1.16
replace github.com/hashicorp/vault/api => ./api
// ...
require (
// ...
github.com/hashicorp/vault/api v1.0.5-0.20210210214158-405eced08457
// ...
)
All this works as expected from a build perspective (and dependency resolution within the source code), however Goland is highlighting both the import statement and the replace statement in my main project's go.mod in red (the error is "missing dependency"). The red lightbulb suggests I "Sync Dependencies" which i have tried, but after a "Finished Successfully" message, the error remains.
I am using Goland 2020.3.5 and go 1.16.3. My project is outside of my GOPATH and I have go modules enabled in the Goland settings menu.
Just to reiterate, everything builds correctly, however the linting for my go.mod acts like there is a missing dependency error.
Upgrading to the latest version of Goland (2021.1.3) solved the issue.
Thanks #s0xzwasd !

Google Cloud Function using internal private function

Project looks something like this
project
- internal
- package
code.go
- cmd
- function
main.go
In cmd/function, the go.mod looks like this:
module github.com/private/repo/cmd/function
go 1.13
require (
github.com/private/repo/internal/package v0.0.0-00010101000000-000000000000
)
replace github.com/private/repo/internal/package => ../../internal/package
Which works fine locally, however, when deploying as a Cloud Function, it doesn't work, as Cloud Function only contains the "cmd/function" directory.
Instead, I try to copy the module into the project directory and the replace.
project
- cmd
- function
main.go
- internal
- package
code.go
replace github.com/private/repo/internal/package => ./internal/package
But this replace seems to be ignored as the Cloud Function deploy build still tries to download this package.
Next, I try using go mod vendor instead, and ignore the go.mod and go.sum files. This seems to do the trick, but not fully, since removing the go.mod, I can't use the internal package anymore.
use of internal package function/vendor/github.com/private/repo/internal/package not allowed
Not sure how I would go about and solve this and still being able to use the internal package name.
Edit:
Added a repository showing the error and a simple fix by not using the internal keyword in the library name. https://github.com/lobbin/gcloud-function-error
Thank you for reporting this issue.
I filed a Feature Request for this improvement [1].
I suggest you to star the FR to give it more visibility and every time there is an update you will be notified through your email.
Please note there is no ETA for this request at this moment.
[1]. https://issuetracker.google.com/184141587

golang module name change causes local tests to fail

I have a fork of someone's code. Their module name is formatted like so:
module github.com/foo/bar/v3
I've made some changes locally and have updated the local go.mod to be v4 instead of v3 but this now causes the running of the tests locally to fail (see below, I've genericized the output).
Note: the go.sum at this point is empty.
$ go test -v
go: finding module for package github.com/foo/bar/v3
go: found github.com/foo/bar/v3 in github.com/foo/bar/v3 v3.0.0
# github.com/foo/bar/v4_test [github.com/foo/bar/v4.test]
./some_test.go:232:19: x.Y undefined (type *package.Example has no field or method Y)
FAIL github.com/foo/bar/v4 [build failed]
I'm not sure why it's trying to locate the actual v3 version of the package, and thus updating the go.sum to include it?
I can see from the test file that this package uses a different package name (e.g. package foo_test) so it doesn't rely on the exported data structures to exist when writing their test code. So maybe that's why this happens? it sees the reference to x.Y and then goes to lookup x in github.
But then I'm not sure why the test would run fine when I was using the v3 reference in the go.mod file?
Any ideas on what's happening here and what the right process should be for bumping a go module when you're working on a forked project?
Thanks.
If you change your module name in go.mod file, you have to replace all your import path with the updated module name.
As you replaced your module github.com/foo/bar/v3 with github.com/foo/bar/v4, you must find and replace all your reference of github.com/foo/bar/v3 with github.com/foo/bar/v4 throughout the whole project.
Then your $ go test -v should run properly.

People can't use my v2+ semantic versioning release using gomodules

I am maintaining a company go library which uses Semantic Versioning for releases. I switched to go modules for dependency management within the library and created a new release after v2+. I used the first strategy documented here which involves modifying the go.mod file and import paths.
Now when people use the go get command (in a repo that is also using go modules) an error appears:
invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v3
Is anyone familiar with this issue?
To make things simpler I created a similar and simple example:
I have repo (github.com/Graphmasters/testing-gomod-versioning) with three files (not including .gitignore). These files are:
methods/method.go
package methods
func Method() {
println("Method")
}
main.go
package main
import (
"github.com/Graphmasters/testing-gomod-versioning/v3/methods"
)
func main() {
methods.Method()
}
go.mod
module github.com/Graphmasters/testing-gomod-versioning/v3
go 1.13
In the repo I created a release with the tag v3.0.0 based on the branch with this code.
The aforementioned error is encountered when the following command is run in a repo that is using go modules:
go get "github.com/Graphmasters/testing-gomod-versioning#v3.0.0"
The module name must be github.com/Graphmasters/testing-gomod-versioning/v3 or github.com/Graphmasters/testing-gomod-versioning.v3 and not github.com/Graphmasters/testing-gomod-versioning
Users should be able to do github.com/Graphmasters/testing-gomod-versioning/v3#v3.0.0 instead of github.com/Graphmasters/testing-gomod-versioning#v3.0.0
Example: You can check the mod file of the following v3 package - https://search.gocenter.io/gotest.tools~2Fv3/info?version=v3.0.0

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/

Resources