Use functions of other files is other directories Golang [closed] - go

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I want to use a method that is in a folder called "controllers" inside my main method, but it turns out that when I start the program it says that the function is not found or defined, I tried following the package guide in the Golang documentation but with the Go build and Go install this did not work, I would like to know only how to use files that are inside other folders to be able to have more order, here the codes and my file tree, first: UserController.go, here is the funcionLoadRecordsFromFile()... (Repeat... i tried using the go build and go install from the documentation but dont work...)
package main
import (
"net/http"
"log"
)
func LoadRecordsFromFile(w http.ResponseWriter, r *http.Request) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(10 << 20)
}
Here is my main.Go were i want to use the function LoadRecordsFromFile() from UserController.go
package main
import (
"net/http"
"github.com/go-chi/chi"
"log"
)
func main() {
r := chi.NewRouter()
r.Post("/loadUsers", func(w http.ResponseWriter, r *http.Request) {
LoadRecordsFromFile(w,r)
})
log.Print("Server started in port 3000")
http.ListenAndServe(":3000", r)
}
The archives are...
-GolangProject
-Main.go
-controllers
--UserController.go

You need to make some changes in your code.
At first, you need to change your package name in your UserController.go. Lets just use controllers as package.
package controllers
import (
"net/http"
"log"
)
func LoadRecordsFromFile(w http.ResponseWriter, r *http.Request) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(10 << 20)
}
Then your Main.go needs some changes.
package main
import (
"net/http"
"github.com/go-chi/chi"
"log"
"github.com/Giovanni2414/Truora/controllers"
)
func main() {
r := chi.NewRouter()
r.Post("/loadUsers", func(w http.ResponseWriter, r *http.Request) {
controllers.LoadRecordsFromFile(w,r)
})
log.Print("Server started in port 3000")
http.ListenAndServe(":3000", r)
}
These changes are enough I think.
Some notes:
Only your main file should have package main.
Normally we define package name after our current folder (but it can be different). All the files under same folder must have same package name.
When you use a function that is under a different package, you should import the desired package before you can use that function.
Your imported path should be like this: <project-module-name>/<folder1>/<folder2>/../<final-folder>.
Finally, you should call that function like the following:
package_name.MyFunction()

Related

Serve static file from within a group with Gin

I want to server static file by mapping /fs to filesys in the disk. I can server static file like this:
r := gin.New()
r.Use(static.Serve("/fs", static.LocalFile("./filesys", false)))
// followed by other routes definition such as R.GET()
I also want to guard access by using a authentication middleware, without affecting other routes. I imagine it's something I need to do with Gin's group like this:
r := gin.New()
g := r.Group("/fs")
{ // what is the purpose of this parenthesis BTW?
g.Use(authMiddleWare)
g.Use(static.Serve("/fs", static.LocalFile(fileUploadDir, false)))
}
However, I can't get it to work. It is not routed in. If I do additional g.GET afterward, the path came out to be wrong.
How to go about this?
Hi I checked this issue has been open for 3 years on git with no solution for 3 years and the static package seems not being maintained anymore
This is an alternate solution that might help you
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
grp := r.Group("/static")
{
grp.StaticFS("", http.Dir("/your_directory"))
}
r.Run()
}

GO Lang Web Application- Auto Compile and Reload [duplicate]

This question already has answers here:
Go Auto-Recompile and Reload Server on file change
(12 answers)
Closed 2 years ago.
Created basic web app and it is running on localhost:8080, I have to restart the server on each file change.
File changes take affect Ctrl +c (terminate program)and run again go program go run hello.go.
We do not want to terminate program of each file changes. If we do any changes and refresh browser new change take affect like PHP language
EX
First Program
package main
import (
"fmt"
"net/http"
)
func helloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
Second Program
package main
import (
"fmt"
"net/http"
)
func helloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Happy Coding")
}
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
Anyone have a solution to this?
You have to understand that Go & PHP are not the same at all. Go is a statically-typed, COMPILED language -- where PHP is a dynamically-typed, INTERPRETED language.
So using some special third party solution like the one mentioned in the comment above by #AyushGupta is probably your best bet. What you described in your question is the workflow when building services with Go. You compile a binary, run it & repeat when you make changes.

modifying imported functions in go

I could override the builtin print() function's behavior by defining another print() in scope, as in https://play.golang.org/p/Y2ly31oXU67
Is it possible in go to alter the behavior on-the-fly of an imported function, say fmt.Println()?
If you want to 'alter' a builtin function, look at the very fine monkey patch utility https://github.com/bouk/monkey (And pay attention to the warnings, it's only really useful in test functions, and I for one reject any prod code that imports that package)
Import a different package with name "fmt" and implement whatever functions you need in that package. Here's an example:
File go.mod:
module test
File main.go
package main
import (
"test/fmt"
)
func main() {
fmt.Println("Hello, playground")
}
File fmt/fmt.go:
package fmt
import (
"fmt"
"log"
)
func Println(format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
log.Printf(msg)
}
Run it on the playground.
The code in this answer does not modify the imported function as asked in the question.

My main.go file cannot see other files

I need some help understanding what is wrong with my file layout in a simple web application.
$GOPATH/src/example.com/myweb
I then have 2 files:
$GOPATH/src/example.com/myweb/main.go
$GOPATH/src/example.com/myweb/api.go
Both files have:
package main
The api.go file looks like:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type API struct {
URI string
Token string
Secret string
client *http.Client
}
...
My main.go file looks like:
package main
import (
"github.com/gorilla/mux"
"html/template"
"net/http"
)
var (
templates = template.Must(template.ParseFiles("views/home.html", "views/history.html", "views/incident.html"))
api = API{
URI: "http://localhost:3000",
Token: "abc",
Secret: "123",
}
)
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
..
..
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
..
..
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
r.PathPrefix("/assets/").Handler(
http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))))
http.ListenAndServe(":9000", r)
}
In the code I excluded, I basically use structs that are defined in my api.go file, and I get this error when doing:
go run main.go
# command-line-arguments
./main.go:16: undefined: API
./main.go:23: undefined: User
What exactly am I doing wrong here?
I tried changing the package name in api.go to myweb but that didn't help.
Am I suppose to use the package name myweb? Is just 1 file suppose to have main?
You're compiling only the main.go file. You should use:
go run main.go api.go
Or:
go run *.go
If you're writing a complex application, you might add everything to packages in subdirectories and have a single main.go file. For instance, etcd has an etcdmain subdirectory/package along with other subdirectories/packages. Something like:
/alarm
/auth
/cmd
/etcdmain
...
And the main.go file is simply:
package main
import "github.com/coreos/etcd/etcdmain"
func main() {
etcdmain.Main()
}
You are using golang workspace project, which is good for the structure for your application and it also standardize.
When we use the golang workspace, you can not run single go file. You need to call go build / go install.
Install
go install example.com/myweb
The command above will compile your main package on example.com/myweb. And the myweb executable binary will be placed on the GOPATH/bin. And you can run it manually.
Build
go build example.com/myweb
The command is similar to go install but the binary executable file will be placed on the current directory when you call the command, instead of on GOPATH/bin (unless your current directory is GOPATH/bin).
For more information please check this link.

Go: embed static files in binary

This might be a very amateur question. I'm trying to embed static files into binary, ie. html. How do I do that with https://github.com/jteeuwen/go-bindata?
So I can access an asset with this https://github.com/jteeuwen/go-bindata#accessing-an-asset, but what do I do with "data", and how to do I parse files, execute template, and serve them in the directory?
I couldn't find any examples online, and will appreciate some help!
5/6 years later, this should be easier with Go 1.16 (Q1 2021), which adds support for embedded files (issue/proposal 41191 )
It will be permitted to use //go:embed naming a single file to initialize a plain string or []byte variable:
//go:embed gopher.png
var gopherPNG []byte
The import is required to flag the file as containing //go:embed lines and needing processing.
Goimports (and gopls etc) can be taught this rule and automatically add the import in any file with a //go:embed as needed.
That sparked a debate on issue 42328 about how to avoid surprising inclusion of "hidden" files when using //go:embed
This as resolved in CL 275092 and commit 37588ff
Decision to exclude files matching .* and _* from embedded directory results when embedding an entire directory tree.
See src/embed/internal/embedtest/embed_test.go
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
Note: with CL 281492, cmd/go passes embedcfg to gccgo if supported.
See also (Jan. 2021) issue 43854 "opt-in for //go:embed to not ignore files and empty dirs".
Given a directory structure like so:
example/
main.go
data/hi.html
example/main.go
package main
import (
"html/template"
"log"
"net/http"
"os"
)
var tmpl *template.Template
func init() {
data, err := Asset("data/hi.html")
if err != nil {
log.Fatal(err)
}
tmpl = template.Must(template.New("tmpl").Parse(string(data)))
}
func main() {
// print to stdout
tmpl.Execute(os.Stdout, map[string]string{"Name": "James"})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
tmpl.Execute(w, map[string]string{"Name": "James"})
})
log.Fatal(http.ListenAndServe(":8000", nil))
}
example/data/hi.html
<h1>Hi, {{.Name}}</h1>
run like so:
go-bindata data && go build && ./example
Console Output:
<h1>Hi, James</h1>
HTTP output:
Hi, James

Resources