malformed module path ... missing dot in first path element - go

I have a project with 2 different executables, each having it's own dependencies plus a shared dependency on the root, something like this:
Root
|->server
| |-> main.go
| |-> someOtherFiles.go
| |-> go.mod
| |-> go.sum
|->validator
| |-> main.go
| |-> someOtherFiles.go
| |-> go.mod
| |-> go.sum
|->utils
| |-> someOtherFiles.go
|->config
| |-> someOtherFiles.go
|-> go.mod
|-> go.sum
My root's go.mod is like this
module prex-kyc
go 1.13
require ({requiredDependencies})
And my validator's go.mod is like this (server's is analogue)
module validator
go 1.13
require (
prex-kyc v0.0.0-00010101000000-000000000000
{otherRequiredDependencies}
)
replace prex-kyc => ../
And in both validator's and server's main.go I do an import like this:
import (
"prex-kyc/utils"
{someOtherImports}
)
When I try to build either one of the projects i get this error: build validator: cannot load prex-kyc/config: malformed module path "prex-kyc/config": missing dot in first path element
I know there's nothing wrong with the code because it can be compiled in someone else's environment.
I have tried building using go versions 1.12 and 1.13 and both windows 10 and Debian Linux.

[SOLVED]
The issue was that i was importing utils like this:
import("prex-kyc/utils")
But actually there was no package utils inside module prex-kyc, (only directory utils) and every .go files in that directory had a different package name. By changing each one of them to "package utils" the issue was solved.
The error "missing dot in first path element" was really misleading though

Related

Issue with developing a multi-module Go workspace

My folder structure looks something like this... (say my git repo name is demorepo)
demorepo
|--directory1
|-- (no go.mod at this level)
|--module1
|--package1 --------->--------------->--------------------->----|
|--go.mod (github.com/demorepo/directory1/module1) |
|--go.sum |
|--module2 |
|--module3 |
|--directory2 |
|-- (no go.mod at this level) |
|--newmodule ------<------------<------------------<----------------|
Now, I want to use a function defined in "package1" in my "newmodule"
When I hit
go get <repo_address>/directort1/module1/package1 at "new_module"
it says ....
github.com/<repo>#upgrade found (v0.0.0-20211215055943-92e412ad4a12), but does not contain package github.com/<repo>/directory1/module1/package1
There is a proposal for a Go Workspace File for Go 1.18 which should simplify this task.
Meanwhile, you can use the replace directive in your go.mod file to refer to a module located on a local filesystem.
demorepo/directory1/module1/go.mod:
module github.com/<repo>/directory1/module1
demorepo/directory2/newmodule/go.mod:
module github.com/<repo>/directory2/newmodule
replace github.com/<repo>/directory1/module1 => ../../directory1/module1
Now you can import github.com/<repo>/directory1/module1/package1 in newmodule normally and it'll refer to the local module1.
You might not want the replace directive in the go.mod file itself, and instead make a copy of it e.g. go.mod.local and use it when building your project: go build -modfile go.mod.local . (can also add *.local to .gitignore).
Approach :
If you want to use module1 inside newModule then you should make one new repo for module1 put your logic there push it in github. please make sure you should use appropriate version for the library.
import it as a library and it will work.
Also refer the official docs of module dependency and also check root level dependency.
Official docs : https://go.dev/blog/using-go-modules

Local packages and directory structure

This is the directory structure for my Go project:
my_project
|
main.go
- my_package
|
- my_package.go
On main.go this works ok:
import (
"my_package/my_package"
)
But when I create a new folder "examples" to test some new functionalities of the package, tha main.go cannot import the package as expected:
my_project
|
main.go
- my_package
|
- my_package.go
- examples
|
- main.go
importing package from parent directory:
import (
"../my_package/my_package"
)
Trying running examples/main.go does not work:
cd examples
go run main.go
build _/mypath/my_project/my_package: cannot find module for path _/mypath/my_project/my_package
Shouldn't I import local packages from parent directories?
Is it always compulsory to have the package modules on subfolders of main.go?
Is there any simple and clear way to organize main/test/debug go programs w/ shared dependencies on local packages?
I've read on golang modules and local packages that maybe I should use abosulte paths for importing packages, but I don't like that option because this is a code meant to be uloaded to a repository, so absolute paths wouldn't work on other implementations.
The way to proceed according to stackoverflow masters (and it works perfectly well indeed) is to import a fake repository and then replace it with a local redirection as stated on How to use a module that is outside of "GOPATH" in another module?
In main.go:
import (
my_package "my_fake_repository/myself/my_project/my_package"
)
In go.mod:
require my_fake_repository/myself/my_project/my_package v0.0.0
replace my_fake_repository/myself/my_project/my_package => ../my_package
It works! Thx a lot!

How to work with multiple repositories of same project root in a workspace?

I want to work on multiple repositories of the same project in a single project directory. How do I go about doing this effectively? Are there any build/project management tool to go about doing this?
For example, consider the workspace project structure:
/ProjectWorkspace/
|-> build/(build artifacts of Application, ApplicationInterface, ForkedExternalDependency)
|-> logs/
|-> src/
|-> Application/
| |-> src/com.example.*
| |-> tst/com.example.*
| |-> gradle-build-scripts
| |-> .git/
|
|-> ApplicationInterface/
| |-> src/com.example.*
| |-> tst/com.example.*
| |-> ant-build-scripts
| |-> .git/
|
|-> ForkedExternalDependency/
|-> src/
|-> some-other-build-scripts
|-> .git/
Few things to note:
Application depends on ApplicationInterface
Application, ApplicationInterface depend on ForkedExternalDependency
Application, ApplicationInterface, ForkedExternalDependency depend on several external dependencies and share a few of them
All directories under /ProjectWorkspace/src/ are respective individual repositories/packages with their own version control and build-scripts
Rest of the files & directories not within /ProjectWorkspace/src/ are local workspace files and not maintained.
Project in IDE ( here IntelliJ IDEA CE ) is expected to be rooted at /ProjectWorkspace
If any of the package is checked out locally, I want to use them, else depend on remote release. ( ex: if ApplicationInterface package is available in /ProjectWorkspace/src I want Application to use it. If it isn't available locally in workspace, I want to Application to use dependency from remote-repository. )
From the tags I assume you have a Java project.
You should build it either with Maven or Gradle (Ant is outdated). Maven has a very good project structure, but you need to stick with it, not invent your own one.
If you need maximal flexibility, take Gradle. But have a look at Maven as well -- their idea to structure the project may be better than yours.

How can I use a sub-packages with Go on Google Cloud Functions?

I'd like to use a helper package from Go Cloud Function. The package has some helper logic that can be shared between multiple functions. But, what is the right way to structure the packages so they all work? The package should be in the same project - not published and public as a completely separate package.
I work at Google. The goal for this question is to proactively answer common questions and help developers starting off with Go on GCF.
You can use subpackages with Go modules. Go modules are Go's new dependency management solution - they let you work outside of GOPATH and let you manage the exact versions of each dependency you have.
Modules also let you define a group of Go packages with the same import path prefix. When you're writing a function, this lets you import other packages in your module.
The function you're deploying needs to be at the root of your module.
Here is an example file structure and how packages would be imported:
.
├── cmd
│ └── main.go # Useful for testing. Can import and setup your function.
├── function.go # Can import example.com/foo/helperpackage
├── function_test.go
├── go.mod # module example.com/foo
└── helperpackage
└── helper.go
This setup has your function in function.go and tested by function_test.go. They are in a module named example.com/foo. helperpackage can be imported by function.go using example.com/foo/helperpackage.
This also has a cmd directory, which may be helpful for local testing. You can import example.com/foo and start an HTTP server which registers your function as an HTTP handler. For example:
package main
import (
"log"
"net/http"
"example.com/foo"
)
func main() {
http.Handle("/HelloHTTP", foo.HelloHTTP)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Note: You could use a vendor directory to achieve the same result. But, all of the packages your function imports would need to be in the vendor directory (with the full import path), which works, but is cumbersome to maintain. It's uncommon to copy sub-packages into your vendor directory, so I wouldn't recommend this.
We also ran into this issue. The go.mod approach provided by #TylerBui-Palsulich (https://stackoverflow.com/a/54255486/2307346) didn't work as we also had to download dependencies from a private repository.
From the Google documentation:
If your function's dependencies are hosted in a repository that is not publicly accessible, you must use a vendor directory to fetch your dependencies before deploying your function
(https://cloud.google.com/functions/docs/writing/specifying-dependencies-go#using_a_vendor_directory)
Given the following package structure:
cloudfunctions.go
sharedpackage
-> shared.go
go.mod
In our go.mod file we defined the following namespace: module some/namespace
The cloudfunctions.go file has the following package definition and imports
package foobar
import (
"bitbucket.org/some/private/dependency"
"some/namespace/sharedpackage"
)
Because of the private dependency we cannot use the go.mod file. Instead we provide a vendor directory.
Warning: If you have both a go.mod file and a vendor directory at the root of your project, the contents of the vendor directory will be ignored when your function is built in the cloud. To ensure that your vendor directory is used, you must exclude the go.mod file from your project's source code prior to deployment. If you are using the gcloud command-line tool, you can ensure that go.mod is not uploaded by using .gcloudignore.
(https://cloud.google.com/functions/docs/writing/specifying-dependencies-go#using_a_vendor_directory)
gcloud deploy will ignore the vendor directory if it finds go.mod, we fix this with a .gloudignore file with the following content:
go.mod
go.sum
At the end we have the following file structure:
cloudfunctions.go
sharedpackage
-> shared.go
go.mod
vendor
.gcloudignore
The last step, Fixing the cannot find package error
When running the deploy step you will still run into an error similar to:
(gcloud.functions.deploy) OperationError: code=3, message=Build failed: /tmp/sgb/gopath/src/serverlessapp/vendor/some/namespace/cloud_functions.go:5:2: cannot find package "some/namespace/sharedpackage" in any of:...
This is because the go.mod file, containing the module name, is ignored. now the Go compiler no longer knows that some/namespace/sharedpackage refers to the local sharedpackage directory.
We managed to get it working by changing the module name to match the package name:
Change module name in go.mod to module foobar
Change the imports in cloudfunctions.go to: "foobar/sharedpackage":
package foobar
import (
"bitbucket.org/some/private/dependency"
"foobar/sharedpackage"
)
Now the Go compiler is able to detect that foobar/sharedpackage is a subpackage of the foobar package.

Some tips with Go and Gogland

Hi all. I'm very new with Go and Gogland. I have a project
I choose "Run kind" as Package - to run not only main file but a project. Why it cannot find main package??
How to import util.myprinter package to main.go to use it??
Please, help me
First, the general structure of your Go workspace seems to be wrong. You need to make it look more like this:
D:
|-- go_projects
| |-- bin
| |-- pkg
| |-- src
| | |-- FirstSteps
| | | |-- main.go
| | | +-- util
| | | +-- myprinter.go
| | |-- SecondProject
| | |-- ThirdProject
...
Second your import statement seems to be empty, I have no idea how GoLand works but if you want to use whatever is in your myprinter.go file, you will need to import the util package, assuming that the myprinter.go file declares its package as util at the top.
// FirstSteps/main.go
package main
import (
"FirstSteps/util"
)
func main() {
util.MyPrinterFunc()
}
And of course to be able to use anything from util there first must be something...
// FirstSteps/util/myprinter.go
package util
func MyPrinterFunc() {
// do stuff...
}
Edit: I'm sorry, I didn't actually answer your question initially. You're getting the error Cannot find package 'main' because of the wrong workspace setup I already mentioned. The Package path tells GoLand where the package you want to run is relative to the $GOPATH/src directory. So after you've setup your wrokspace correctly, you should set the Package path to FirstSteps since that package's absolute path will be $GOPATH/src/FirstSteps. If, later, you want to run the util package you would specify Package path as FirstSteps/util for GoLand to be able to find it.

Resources