How to go mod get local package? - go

I want go.mod get a folder inside the selfCheck(get package inside selfCheck folder).
selfCheck/encrypt , selfCheck/searchSchool
my screenshots is here
(don't mind vendor file. i'll remove it.)

You don't need to require a folder in the project itself in go.mod files. go.mod is only requireing external packages from other repositories.
I wrote a blogpost on starting with Go that covers this question. https://marcofranssen.nl/start-on-your-first-golang-project
I also wrote a whole bunch more articles on Go https://marcofranssen.nl/categories/golang
In summary what you should do it use the full url of your git repository so other projects can depend on it as a best practice.
e.g.
go mod init github.com/your-user/selfcheck
Once you did that your go.mod file looks like this.
module github.com/your-user/selfcheck
go 1.17
Please note camel casing is not the way you name go packages. Go packages should be all lowercase.
Now if you want to create sub packages as you are asking for you should create folders. e.g. your project could look like this.
$ tree selfcheck
selfcheck
├── go.mod
├── main.go
└── searchschool
└── searchschool.go
1 directory, 3 files
Now to reference code from the searchschool package you can do the following in main.go.
package main
require (
"fmt"
"github.com/your-user/selfcheck/searchschool"
)
func main() {
fmt.Println(searchschool.Excute())
}
Please note all functions have to start with an uppercase to access them outside of the searchschool package. E.g. searchschool/searchschool.go
package searchschool
func Execute() string {
return privateFunc() + "!"
}
func privateFunc() string {
return "Hello World"
}

Related

Golang - package name as double underscore

In my protobuf generated go code, the package is:
package __
What does the double underscore mean, does it means the same as folder name ?
Is there a document for this, I searched but didn't found any. And the code can compile without error.
Yes it means the same directory. Let's look at the following code.
Directory Structure
.
├── go.mod
├── greet
│ └── greet.go
└── main.go
Content in greet.go
package __
import "fmt"
func Hello(name string) {
fmt.Printf("Hello %s\n", name)
}
Content in main.go
package main
import greet "playground/greet"
func main() {
greet.Hello("Eric")
}
Current Directory
$ pwd
/Users/thedatageek/Codes/go-playground
Unfortunately I also couldn't find any docs for go.
But it seems that its kinda good thing. You really don't need to name the package. You just name the directory and the package name would be automatically the same.
Note: This is definitely not the grpc or protobuf thing. It is however a customary that if you have generated proto stub from a proto file and if you add some additional utility file you may put those into a dir and then import it directly via directory name. For example the following github repos
https://github.com/Ash110/gRPC-Logger
https://github.com/dist1ll/cache-prototype
https://github.com/kamensotirov99/int-gateway
https://github.com/rachaelyychen/go-gee
https://github.com/suvvm/ToadOCREngine
https://github.com/denyami/drawing-api

Call function in another files

I don't know how I can use function in another file.
my project architecture:
.
├── main.go
└── src
└── function.go
1 directory, 2 files
main.go
package main
import "src/funcrion"
func main() {
funcrion.Display();
}
function.go
package src
import "fmt";
func Display() {
fmt.Println("Hello World");
}
For start my project I use:
go run main.go
error:
main.go:3:8: cannot find package "src/funcrion" in any of:
/usr/local/opt/go/libexec/src/src/funcrion (from $GOROOT)
/Users/clementbolin/go/src/src/funcrion (from $GOPATH)
In first, I want to resolve this problem. In second time I want to know what is the best option for compile a real project with more 10 files for example, do I need to use Makefile? Or like in Rust go has package manager?
When you do import "src/funcrion" the go compiler will try to search for this in GOPATH and GOROOT, as you see in your error message. It does not try to search in the current folder. Since it doesn't find a package with that name in either GOPATH or GOROOT, it gives you that error.
A good way to reference "the current folder" would be using go modules. On the root of your project do $ go mod init myproject. (replace myproject for a more appropriate name for your project)
After you do that, you can use "myproject" to reference the project folder in package names, like:
package main
import "myprject/src"
func main() {
src.Display();
}
Also note that the import goes only up to the package name and not the file name. So, in your case, you shouldn't do import myproject/src/function just because you have a function.go file inside a src package.
And since your Display function is inside the src package, you refer to it simply with src.Display() after importing the package. No need to specify the name of the file anywhere.
You can read more about go modules here: https://blog.golang.org/using-go-modules
Another tip is to not use src as a package name. In Go, it's common to not have a "src" folder, and as a package name is also not very good. For instance, see the line that reads src.Display(). Instinctively, i would read this as something like "the Display of the source", which has no meaning. But if instead of src you name your package text, that same line would read text.Display() which would read as "display some text", which is more accurate and meaningful to what the function is doing.
I believe the package name is src but I see you are trying to import src\funcrion There is no such package called funcrion.
I think you should just do something like this main.go
package main
import "src"
func main() {
src.Display();
}
or if you would like to call your src package as funcrion, then just import it like below,
import funcrion "src"
And make sure your file structure is as below and inside $GOPATH
Users
└── clementbolin
└── go
└── src
├── main.go
└── src
└── function.go

Are there conventions for Go module names in mono-repos with multiple modules?

In a multi-module repository, should a module name (set via the go.mod module directive) follow the conventions of package naming?
E.g. module github.com/org-name/repo-name/path/to/module-dir
I understand that, whatever the module is named, the packages within the module refer to each other using the module name as prefix. But, from outside the module, there seems to problems if the module name is set to something other than the <host><path-within-repo> pattern. get-ing a package included in the module then gives messages about unrecognized import path.
Is there any cause to name a module differently than <host><path-within-repo> ?
There isn't any hard requirement for referencing modules, although it always good practice to use the domain/repo pattern. So, if you want to reference other modules locally that are not in the GOPATH, you can use the replace directive.
https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
replace also can be used to inform the go tooling of the relative or absolute on->disk location of modules in a multi-module project, such as:
replace example.com/project/foo => ../foo
Let's say we have the following structure:
├── .gitignore
├── pkg1
│   ├── go.mod
│   └── main.go
└── pkg2
├── go.mod
└── utils.go
pkg1/main.go
package main
import (
"fmt"
"local/pkg2"
)
func main() {
fmt.Println(pkg2.Add(1, 2))
}
pkg1/go.mod
module local/pkg1
go 1.12
require local/pkg2 v0.0.0
replace local/pkg2 => ../pkg2
pkg2/utils.go
package pkg2
func Add(a, b int) int {
return a + b
}
pkg2/go.mod
module local/pkg2
go 1.12
Running:
cd pkg1
go run main.go
You get:
3
If you want to be able to go get a module, it should follow the <host>/repo/path/within/repo pattern.
However, I would suggest stepping back and asking if you really do want a multi-module repo. It adds substantial complexity, it is hard to get right, and usually means more work on an on-going basis.
Russ Cox commented in #26664:
For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.
For more details, see "Organize local code in packages using Go modules".

Package naming: error exporting variable

I have a directory structure like this:
Animal/
dog/
chiwawa.go
rabbit.go
Both chiwawa.go and rabbit.go are packaged named: "package animal" at the top of the file. However when I try to use a variable var Food = apple from chiwawa.go in rabbit.go, I get error - undefined: Food.
I don't have any problems when I place chiwawa.go directly under Animal without the dog directory.
Is this intentional in Go? Can I work around this while retaining the package names and directory structure?
How to Write Go Code
Workspaces
The go tool is designed to work with open source code maintained in
public repositories. Although you don't need to publish your code, the
model for how the environment is set up works the same whether you do
or not.
Go code must be kept inside a workspace. A workspace is a directory
hierarchy with three directories at its root:
src contains Go source files organized into packages (one package per directory),
pkg contains package objects, and
bin contains executable commands.
The go tool builds source packages and installs the resulting binaries
to the pkg and bin directories.
The src subdirectory typically contains multiple version control
repositories (such as for Git or Mercurial) that track the development
of one or more source packages.
To give you an idea of how a workspace looks in practice, here's an
example:
bin/
hello # command executable
outyet # command executable
pkg/
linux_amd64/
github.com/golang/example/
stringutil.a # package object
src/
github.com/golang/example/
.git/ # Git repository metadata
hello/
hello.go # command source
outyet/
main.go # command source
main_test.go # test source
stringutil/
reverse.go # package source
reverse_test.go # test source
This workspace contains one repository (example) comprising two
commands (hello and outyet) and one library (stringutil).
A typical workspace would contain many source repositories containing
many packages and commands. Most Go programmers keep all their Go
source code and dependencies in a single workspace.
For the Go tools, all the Go source files for a Go package should be in the same directory.
It is intentional. Packages in Go are imported using a directory path. So, "animal" and "animal/dog" are two different packages even if you give them the same package name.
To demonstrate this, I wrote the following example set of files:
~/go/src/test/
├── animal
│   ├── animal.go
│   └── dog
│   └── dog.go
└── test.go
animal/animal.go
package animal
type Species string
animal/dog/dog.go
package animal
// In package "animal" importing a package "animal"
import "test/animal"
type Dog struct {
Species animal.Species
Breed string
}
test.go
package main
import (
"fmt"
"test/animal/dog"
)
func main() {
d := animal.Dog{}
fmt.Printf("%#v", d)
}
Notice that dog.go imports the "test/animal" package and references it as "animal".
Furthermore notice that test.go imports "test/animal/dog" to get access to the "Dog" struct type. If it imports, "test/animal", the error (undefined: animal.Dog) is generated.

Break up go project into subfolders

I want to break my project up to subfolders.
I want this code structure:
├── main.go
└── models
└── user.go
Where main.go is:
package main
import (
"fmt"
"./models"
)
func main(){
fmt.Println(User{"new_user"})
}
And user.go is:
package models
type User struct {
Login string
}
But User is not defined in main package and import raise warning "imported and not used".
What am I doing wrong? My project is simple (not such a example but just with few files (controllers and models)) and I want a simple structure.
Maybe I doing it in completely wrong way?
Problem project is here: https://github.com/abonec/go_import_problem
I recently achieved this by using go modules.
Golang introduced preliminary opt-in support for modules as of go v1.11.1 which is intended to completely remove the, frankly, absurd $GOPATH necessity. Not only can you now have versioned dependencies in any normal directory such as ~/development, but you can basically have something that looks like namespaces and sub-directories. You can enable this feature by invoking the go command with the following environment variable: GO111MODULE=on.
Go v1.11.3 expects to enable modules by default and is slated for August 2019.
Here is an example directory structure (that you might find typically in some other languages).
~/Dev/my-app
├── src/
│ ├── one/
│ │ ├── two/
│ │ │ └── two.go
│ │ └── one.go
│ └── zero.go
├── go.mod
└── app.go
The application is called my-app, which will be the module name for app.go. We define this once in go.mod and then each of all the other go files in subdirectories will automatically be importable as if they were namespaced.
Given the above, two.go, assuming it contains a function named Two, will be importable in app.go by using my-app/src/one/two.
Here's what you need to do to achieve this:
go.mod
module my-app
two.go
package two
func Two() string {
return "I'm totally not supposed to be using go modules for this"
}
app.go
package main
import "my-app/src/one/two"
func main() {
two.Two()
}
If you were to place another file within two/, then you would simply use two.TheNewFunc() as long as you made TheNewFunc() available within the new file.
I created a very simple GitHub repo which you can check out as a demonstration.
Your import should be an absolute one:
import "github.com/abonec/go_import_problem/models"
If you don't want to export your project to an external referential, you can do a:
import "go_import_problem/models"
(That is: "the name of your project folder accessible by GOPATH/your package")
See "How to use custom packages in golang?".
And you would use:
models.User
As mentioned in Effective Go:
The importer of a package will use the name to refer to its contents, so exported names in the package can use that fact to avoid stutter.
(Don't use the import . notation, which can simplify tests that must run outside the package they are testing, but should otherwise be avoided.)
kostix adds in the comments:
to reiterate, names of Go packages are always absolute (that is, there's no relative package names, neither with ./ nor with ../ or anything like that) but that names are "anchored" to one of the so-called workspaces listed in $GOPATH.
When Go searches for a package, it looks through workspaces and tries to find a package in each of them, in order.
The search is not recursive.
And no, there's no requirement to encode URLs in package paths -- unless you want to make your package public.
You need to qualify items in in a package by its package name
So
fmt.Println(models.User{"new_user"})
Breaking up a single project into subfolders is not the recommended way of structuring a go project, which is why there is basically no good way to do what you want.
If the project is really large, and too unwieldy to make a single package, consider splitting it into several totally distinct packages, rather than special sub-directory packages. This has the advantage of forcing you to think cleanly about your internal APIs.
The packages are referenced in code in relation to your "go/src" folder
└── go
└── src
└── myAwesomeProject
├── main.go
└── models
└── user.go
So in main.go
package main
import (
"fmt"
"myAwesomeProject/models"
)
Similarly packages can reference each other using the same convention.
You should use your imported objects by it's imported names. For example if you
import "./models"
with struct User you should use it as
models.User

Resources