diff options
| author | Michael Matloob <matloob@golang.org> | 2022-02-07 15:41:02 -0500 |
|---|---|---|
| committer | Michael Matloob <michaelmatloob@gmail.com> | 2022-03-01 19:33:14 +0000 |
| commit | d10dfbe3247130f0b352df7063d4da084c4a9059 (patch) | |
| tree | 2d7face7719baae4e37754a8059c63b1afadaa46 /_content/doc/tutorial/workspaces.md | |
| parent | c18706c44380f56baeff04967eb1ead68ea42e5d (diff) | |
| download | go-x-website-d10dfbe3247130f0b352df7063d4da084c4a9059.tar.xz | |
_content/doc/tutorial: add a tutorial for workspaces
Change-Id: I0686121523da9b22666cfbad54821527ac5b8feb
Reviewed-on: https://go-review.googlesource.com/c/website/+/383854
Trust: Michael Matloob <michaelmatloob@gmail.com>
Trust: Bryan Mills <bcmills@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Diffstat (limited to '_content/doc/tutorial/workspaces.md')
| -rw-r--r-- | _content/doc/tutorial/workspaces.md | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/_content/doc/tutorial/workspaces.md b/_content/doc/tutorial/workspaces.md new file mode 100644 index 00000000..a3452499 --- /dev/null +++ b/_content/doc/tutorial/workspaces.md @@ -0,0 +1,276 @@ +<!--{ + "Title": "Tutorial: Getting started with multi-module workspaces" +}--> + +This tutorial introduces the basics of multi-module workspaces in Go. +With multi-module workspaces, you can tell the Go command that you're +writing code in multiple modules at the same time and easily build and +run code in those modules. + +In this tutorial, you'll create two modules in a shared multi-module +workspace, make changes across those modules, and see the results +of those changes in a build. + +<!-- TODO TOC --> + +**Note:** For other tutorials, see [Tutorials](/doc/tutorial/index.html). + +## Prerequisites + +* **An installation of Go 1.18 or later.** +* **A tool to edit your code.** Any text editor you have will work fine. +* **A command terminal.** Go works well using any terminal on Linux and Mac, + and on PowerShell or cmd in Windows. + +This tutorial requires go1.18 or later. Make sure you've installed Go at Go 1.18 or later using the +links at [go.dev/dl](https://go.dev/dl). + +## Create a module for your code {#create_folder} + +To begin, create a module for the code you’ll write. + +1. Open a command prompt and change to your home directory. + + On Linux or Mac: + + ``` + $ cd + ``` + + On Windows: + + ``` + C:\> cd %HOMEPATH% + ``` + + The rest of the tutorial will show a $ as the prompt. The commands you use + will work on Windows too. + +2. From the command prompt, create a directory for your code called workspace. + + ``` + $ mkdir workspace + $ cd workspace + ``` + +3. Initialize the module + + Our example will create a new module `hello` that will depend on the golang.org/x/example module. + + Create the hello module: + + ``` + $ mkdir hello + $ cd hello + $ go mod init example.com/hello + go: creating new go.mod: module example.com/hello + ``` + + Add a dependency on the golang.org/x/example module by using `go get`. + + ``` + $ go get golang.org/x/example + ``` + + Create hello.go in the hello directory with the following contents: + + ``` + package main + + import ( + "fmt" + + "golang.org/x/example/stringutil" + ) + + func main() { + fmt.Println(stringutil.Reverse("Hello")) + } + ``` + + Now, run the hello program: + + ``` + $ go run example.com/hello + olleH + ``` + +## Create the workspace + +In this step, we'll create a `go.work` file to specify a workspace with the module. + +#### Initialize the workspace + +In the `workspace` directory, run: + + ``` + $ go work init ./hello + ``` + +The `go work init` command tells `go` to create a `go.work` file +for a workspace containing the modules in the `./hello` +directory. + +The `go` command produces a `go.work` file that looks like this: + + ``` + go 1.18 + + use ./hello + ``` + +The `go.work` file has similar syntax to `go.mod`. + +The `go` directive tells Go which version of Go the file should be +interpreted with. It's similar to the `go` directive in the `go.mod` +file. + +The `use` directive tells Go that the module in the `hello` +directory should be main modules when doing a build. + +So in any subdirectory of `workspace` the module will be active. + +#### Run the program in the workspace directory + +In the `workspace` directory, run: + + ``` + $ go run example.com/hello + olleH + ``` + +The Go command includes all the modules in the workspace as main modules. This allows us +to refer to a package in the module, even outside the module. Running the `go run` command +outside the module or the workspace would result in an error because the `go` command +wouldn't know which modules to use. + +Next, we'll add a local copy of the `golang.org/x/example` module to the workspace. We'll then +add a new function to the `stringutil` package that we can use instead of `Reverse`. + +## Download and modify the `golang.org/x/example` module + + In this step, we'll download a copy of the Git repo containing the `golang.org/x/example` module, + add it to the workspace, and then add a new function to it that we will use from the hello program. + +1. Clone the repository + + From the workspace directory, run the `git` command to clone the repository: + + ``` + $ git clone https://go.googlesource.com/example + Cloning into 'example'... + remote: Total 165 (delta 27), reused 165 (delta 27) + Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done. + Resolving deltas: 100% (27/27), done. + ``` + +2. Add the module to the workspace + + ``` + $ go work use ./example + ``` + + The `go work use` command adds a new module to the go.work file. It will now look like this: + + ``` + go 1.18 + + use ( + ./hello + ./example + ) + ``` + + The module now includes both the `example.com/hello` module and the `golang.org/x/example module. + + This will allow us to use the new code we will write in our copy of the `stringutil` module + instead of the version of the module in the module cache that we downloaded with the `go get` command. + +3. Add the new function. + + We'll add a new function to uppercase a string to the `golang.org/x/example/stringutil` package. + + Add a new folder to the `workspace/example/stringutil` directory containing the following contents: + + ``` + package stringutil + + import "unicode" + + // ToUpper uppercases all the runes in its argument string. + func ToUpper(s string) string { + r := []rune(s) + for i := range r { + r[i] = unicode.ToUpper(r[i]) + } + return string(r) + } + ``` + +4. Modify the hello program to use the function. + + Modify the contents of `workspace/hello/hello.go` to contain the following contents: + + ``` + package main + + import ( + "fmt" + + "golang.org/x/example/stringutil" + ) + + func main() { + fmt.Println(stringutil.ToUpper("Hello")) + } + ``` + +#### Run the code in the workspace + + From the workspace directory, run + + ``` + $ go run example/hello + HELLO + ``` + + The Go command finds the `example.com/hello` module specified in the + command line in the `hello` directory specified by the `go.work` + file, and similarly resolves the `golang.org/x/example` import using + the `go.work` file. + + `go.work` can be used instead of adding [`replace`](https://go.dev/ref/mod#go-mod-file-replace) + directives to work across multiple modules. + + Since the two modules are in the same workspace it's easy + to make a change in one module and use it in another. + +#### Future step + + Now, to properly release these modules we'd need to make a release of the `golang.org/x/example` + module, for example at `v0.1.0`. This is usually done by tagging a commit on the module's version + control repository. See the + [module release workflow documentation](https://go.dev/doc/modules/release-workflow) + for more details. Once the release is done, we can increase the requirement on the + `golang.org/x/example` module in `hello/go.mod`: + + ``` + cd hello + go get example.com/dep@v0.1.0 + ``` + + That way, the `go` command can properly resolve the modules outside the workspace. + +## Learn more about workspaces + + The `go` command has a couple of subcommands for working with workspaces in addition to `go work init` which + we saw earlier in the tutorial: + + - `go work use [-r] [dir]` adds a `use` directive to the `go.work` file for `dir`, + if it exists, and removes the `use` directory if the argument directory doesn't exist. The `-r` + flag examines subdirectories of `dir` recursively. + - `go work edit` edits the `go.work` file similarly to `go mod edit` + - `go work sync` syncs dependencies from the workspace's build list into each of the workspace modules. + + See [Workspaces](https://go.dev/ref/mod#workspaces) in the Go Modules Reference for more detail on + workspaces and `go.work` files. |
