I am working on building a web framework in Go. I have the code locally and would like to use that repo in another module to test that everything works without having to create tags and/or push things to remote repos. I have followed the official docs on how to do this, as well as a number of posts elsewhere. However nothing seems to work. What am I doing incorrectly?
Package live here locally:
../goworkspace/src/github.com/garrettlove8/goserve
Import from other module:
...
import (
"fmt"
"io"
"net/http"
"github.com/garrettlove8/goserve" // I have tried "goserve" and "../goserve"
)
...
go.mod:
...
require github.com/garrettlove8/goserve v0.1.17
No matter what I do it doesn't seem to work as desired
Update
Code and error combos:
// main.go
import (
"fmt"
"io"
"net/http"
"goserve"
)
Run go mod tidy
// go.mod becomes
require github.com/garrettlove8/goserve v0.1.17 // indirect
Error:
goserve: package goserve is not in GOROOT (/usr/local/go/src/goserve)
Manually changing go mod to this (which I don't to have to do):
require github.com/garrettlove8/goserve
Run go mod tidy
Error:
usage: require module/path v1.2.3
When you want to use a local module instead of a remote one, you can achieve that with the replace directive.
In your case, add this to your go.mod file:
replace github.com/garrettlove8/goserve => ../goworkspace/src/github.com/garrettlove8/goserve
Related
I'm new with Go and I'm trying to build an API, but I'm having some problems at importing functions located at another local package.
My folder structure looks like the following:
├── app.go //at package "main"
└── middleware
├── authentication.go // package "middleware"
I'm trying to import the functions inside the authentication.go file like that:
package main
import (
"fmt"
"log"
"net/http"
"./middleware" //Also tried "middleware"
)
Thinking that's an import problem because if I move the functions to the same package and folder, it works fine.
The func I'm trying to use also starts with caps, so there shouldn't be a problem importing it:
func AuthMiddleware(next http.Handler) http.Handler {
//...
}
What's wrong with my code? Also, what's the best way to import a local package without having to write the whole path?
I'm using Go 1.15.2, and checked all related S.O posts, but none looks to solve my problem.
EDIT :
Whenever you use a function located at another package, you have to refer first to the package. I was trying to call my function as AuthMiddleware(parameters) but the right way to call it was middleware.AuthMiddleware(parameters).
Don't use dot import paths like this, it is not recommended. Use the relative path for your go src dir (which can be local only, it doesn't have to be online) and it'll work fine.
So something like
import "me.com/api/middleware"
Then to avoid stutter perhaps:
middleware.Auth()
There is two way to call function from another package
You can use package or alias to call function
With package name
package main
import (
"./middleware"
)
middleware.Auth();
With alias
package main
import (
mid "./middleware"
)
mid.Auth();
You can import whole package by using . , after that you do not need to use alias or package name to call function. You can use call function directly with function name
package main
import (
. "./middleware"
)
Auth();
I'm trying to import a subdirectory I have in my project to my main file, but for some reason I get this error:
could not import ./service (no package for import ./service)
This is how I import:
import (
"os"
"service"
)
I also tried "service/app"
"./service/app"
"./service" nothing works, always the same error.
I'm trying to use the app.go file
This is the file structure:
Project Directory
-- main.go
-- service (directory)
-- app.go (file)
I tried to restart VS Code, tried to use go install/update tools, nothing works.
Also, this is my main func:
func main() {
a := &service.App()
a.Initialize(
os.Getenv("APP_DB_USERNAME"),
os.Getenv("APP_DB_PASSWORD"),
os.Getenv("APP_DB_NAME"),
)
a.Run(":8010")
}
&service.App() does not show a problem, but when I remove the "service" import, it does say
undeclared name: service
So I don't understand what the problem is.
This error sometime show on the "os" import too, I don't know why.
Golang doesn't support relative imports.
In modules, there finally is a name for the subdirectory. If the parent directory says "module m" then the subdirectory is imported as "m/subdir", no longer "./subdir".
So, in your case you should import service package as your_module_name/service.
This question already has answers here:
Relative imports in Go
(6 answers)
Closed 3 years ago.
I'm really new to Go and I'm trying to import a local file in the main.go.
This is how the project is structured:
-project_name(dir)
--src(dir)
---main.go
---auth(dir)
----signup.go
I'm trying to use a function I wrote in signup.go in main.go.
This is how I tried to import the signup.go in main.go:
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
auth "./auth"
)
and use it like that:
myRouter.HandleFunc("/signup", auth.signupUser).Methods("POST")
I also tried copying the relative auth dir and write it in the import but I still get an error undefined: auth go
I tried looking for answers but I can't see what I'm doing differently from the answers I saw.
Relative imports are not recommended in Go.
If project_name is inside your GOPATH, like $GOPATH/github.com/john/project_name, you can import auth like this:
import "github.com/john/project_name/src/auth"
If you are using Go modules, then instead of github.com/john/project_name, use whatever name is inside your go.mod. If you are not using Go modules but would like to, you can do go mod init github.com/john/project_name whilst inside the project_name folder, and then that folder will be used as a base.
Note that signupUser has to actually be SignupUser to be exported (and therefore useable).
Intro
I'm trying to import my EventController.go to my main.go file.
Directory:
├───Controllers
│ └───Event
│ └───EventController.go
├───Models
├───Routes
│
└ Main.go
Problem:
import (
"log"
"net/http"
_ "/Controllers/Event/EventController.go" //problem here
)
error : cannot import absolute path
I read some documentation but the thing is I see that I'm doing it correctly, though i learnt about $GOPATH but I want to use the local directory thing.
What am I doing wrong and what's this error about
NOTE: I want add that I'm using windows as os
Thank you.
There are a few issues:
Packages are imported, not files (as noted in other answers)
File absolute import paths are not valid as the error states. An application can use file relative import paths (the path starts with "./") or a path relative to the Go workspace. See the go command doc for info on the syntax. Import paths relative to the Go workspace are the preferred form.
It is idiomatic to use lowercase names for packages (and their corresponding directories). The camel case names in the question are workable, but it's better to go with the flow.
The document How to Write Go Code is a nice tutorial on how to do this.
Here's how to reorganize the code given the above. This assumes that main.go is in a package with import path "myapp". Change this import path to whatever you want.
-- main.go --
package main
import (
"log"
_ "myapp/controllers/event"
)
func main() {
log.Println("hello from main")
}
-- go.mod --
module myapp
-- controllers/event/eventController.go --
package event
import "log"
func init() {
log.Println("hello from controllers/event")
}
Run this example on the Go playground.
You cannot import a file. You can import a package. So, lets say your main is the package "github.com/mypackage", then you should import "github.com/mypackage/Controllers/Event".
Go supports package level import. You can import a package by adding it to the import statement at the beginning of the file.
In your case, you should do something like this-
import (
"log"
"net/http"
"Controllers/Event/EventController"
)
Also, you should remove first "/" from the file name
_ /Controllers/Event/EventController.go" //problem here
because your Controllers folder is at the same level as Main.go file. You should always give relative path in the import statements.
In this way, you can use any file which is listed under EventController folder.
Ok so this question has been asked before and I believe I have looked through all of them to and tested the answers but I will explain how each one doesn't match my case. I might have missed the answer in one of those but I read each one and attempted to see if it could fit my case
How to import local packages in go? I believe my imports follow the structure of the answer
Go build: "Cannot find package" (even though GOPATH is set) I'm not sure if this one is fully pertinent but I don't think it's the same error.
Golang - Why can't I import local package in GOPATH/src/project but can in home directory? My import path isn't relative so this question isn't pertinent.
My error is simple:
cannot find package "api/handlers" in any of:
C:\Go\src\api\handlers (from $GOROOT)
C:\Projects\Go\src\api\handlers (from $GOPATH)`
My project structure is as follows:
src
|
--api
|
-- index.go
-- repo.go
|
github.com
|
main.go
Environment variables:
$GOPATH : C:\Projects\Go
$GOROOT : C:\Go\
index and repo.go both have the same package name, imports, and just an empty function:
package handlers
import (
"net/http"
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
}
My main.go:
package main
import (
"fmt"
"log"
"net/http"
"api/handlers"
)
func main() {
http.HandleFunc("/api/index", handlers.indexHandler)
http.HandleFunc("/api/repo", handlers.repoHandler)
log.Fatal(http.ListenAndServer("localhost:8080", nil))
}
What's happening is that import api/handlers is looking for the folder handlers in the folder api, and then looking in the contents for the package name. Add a handlers folder inside api and move index.go and repo.go into that folder. Or just change the package name to api in those files and just do import api.
About your comment:
cannot refer to unexported name handlers.indexHandler
In order for you to be able to use function indexHandler from your main package, you should rename it to IndexHandler. In go, for things to be able to be accessed by other packages, the name needs to start with a capital letter.