Go from the beginning - Go modules
There are two interesting use cases with modules:
- Consuming a module, you will most likely use a combination oof core modules and external third party modules
- Creating a module, in some case you will create code that you or someone else will be able to use. For this scenario, you can create a module and upload it to GitHub.
Consume internal files
You might want to split up your app in many different files. Let's say you have the following files:
/app
main.go
/helper
helper.go
-
Create the module like so:
go mod init
-
create the helper directory and helper.go file and give it the following content:
// helper.go package helper import "fmt" func Help() { fmt.Println("This is a helper function") }
Create the main.go file and give it the following content:
package main
import (
"log-tester/helper"
"github.com/softchris/logger"
)
func main() {
logger.Log("hey there")
helper.Help()
}
Note this import "log-tester/helper"
, it ensures the helper
package is in scope.
- Compile and run
go run main.go
Consume an external module
To consume an external module, you need to:
-
Import it, this involves using the
import
instruction and fully qualifying the address to the module's location. - Use it in code, call the code from the module that you mean to use
- Ensure it's downloaded, so your code can be run.
Create a project
Let's create a new project
-
Run
go mod init
:
go mod init hello
Note how go.mod was created with the following content:
module hello go 1.16
Add reference to an external lib
Next, lets create some code that will use the external library:
-
Create the file main.go
package main import ( "fmt" "github.com/softchris/math" )
-
To the same file, add
main()
function and use external function, from package:
func main() { sum += math.Add(1,2) fmt.Println(sum) }
Fetch the lib
Now, we need to resolve the external library.
-
Run
go mod tidy
:
go mod tidy
Your go.mod is updated:
require github.com/softchris/math v0.2.0
There's also go.sum file with the following content:
github.com/softchris/math v0.2.0 h1:88L6PLRBGygS3LY5KGIJhyw9IZturmd2ksU+p13OPa4= github.com/softchris/math v0.2.0/go.mod h1:v8WzhjKC+ipuH+i9IZ0Ta2IArniTP53gc5TgCINCqAo=
This is Go's way of keeping track of how to build the app by referencing to the go module in question.
Run
go run
:
go run main.go
3
Create a module
When you build a module meant for sharing, there's some gotchas:
- you need to create a package
- your package won't be called main
- there's concept of public and private parts of your code
- you can't test it locally
- upload your package to GitHub for wide distribution
Create the code for the module
To create a moodule meant for wider use you need to first initialize a module.
- Create a directory logger for your new package:
mkdir logger
cd logger
- Run
go mod init <address at github>
, for example:
go mod init github.com/softchris/logger
This will create a go.mod file in your directory.
logger/
go.mod
The file looks like so:
module github.com/softchris/logger
go 1.16
It contains the package name and the version of Go it means to use.
- Create a file to host your package code, for example log.go and give it the following content:
package logger
import (
"fmt"
)
var Version string = "1.0"
func Log(mess string) {
fmt.Println("[LOG] " + mess)
}
- Note
package logger
instead ofmain
. - The uppercase variables and methods makes the publicly available. Anything named with lowercase will be private for the package.
Test it locally
You can test your package locally. To do so you need a separate package that you can import your package from.
- Move up a directory:
cd ..
- Create a new directory logger-test:
mkdir logger-test
cd logger-test
- Create a package, it will be used for testing only:
go mod init logger-test
- Create a file main.go and add the following code:
package main
import "github.com/softchris/logger"
func main() {
logger.Log("hey there")
}
At this point, you are consuming the "logger" package but it's pointing to GitHub and your package don't live there yet. However, you can repoint to a local address on your machine, lets do that next.
- Open go.mod and add the following:
require github.com/softchris/logger v0.0.0
replace github.com/softchris/logger => ../logger
Two things are happening here:
-
you are asking for the "logger" package:
require github.com/softchris/logger v0.0.0
-
you are making it point to your local system instead of GitHub
replace github.com/softchris/logger => ../logger
-
Run the package with
go run
:
go run main.go
You should see:
[LOG] hey there
Publish a package
To publish your package, you can put it on GitHub.
- Create a git repo with
git init
:
git init
Create the repo at GitHub.
-
Make you do at least one commit:
git add . git commit -m "first commit"
Do the following do upload your package to GitHub:
git remote add origin https://github.com/softchris/logger.git
git branch -M main
git push -u origin main
- Tag your package with
git tag
:
git tag v0.1.0
git push origin v0.1.0
Now your package has the tag 0.1.0
Test it out
- Go to your project "logger-test":
cd ..
cd logger-test
- Open up go.mod and remove these lines:
require github.com/softchris/logger v0.1.0
replace github.com/softchris/logger => ../logger
- Run
go mod tidy
, this will force Go to go look for the package:
Your go.mod should now contain:
require github.com/softchris/logger v0.1.0
Also, your go.sum should contain:
github.com/softchris/logger v0.1.0 h1:Kqw7t9C3Y7BtHDLTx/KXEqHy5x8EJxrLian742S0di0=
github.com/softchris/logger v0.1.0/go.mod h1:rrzWjMsM3tqjetDBDyezI8mFCjGucF/b5RSAqptKF/M=
- Run the program with
go run
:
go run main.go
You should see:
[LOG] hey there
Summary
Great, you've managed to create a module locally, put it on GitHub and have one of your other Go projects use it.