Go Language Modularization: Difference between revisions
(169 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=Internal= | =Internal= | ||
* [[Go_Language#Modularization|Go Language]] | * [[Go_Language#Modularization|Go Language]] | ||
=Overview= | =Overview= | ||
Go modularization builds upon the concepts of package and module. [[Go_Packages#Overview|Packages]] provide a [[Go_Packages#Packages_as_Namespaces|namespace]] for their members, and they are a way to [[Go_Packages#Packages_as_Encapsulation_Mechanism|encapsulate]] code, hide implementation details and only expose features, such as [[Go_Language#Variables|variables]], [[Go_Functions|functions]] or [[Go_Language#Type|type]] definitions that are meant to be publicly consumed. Packages can be published as part of [[Go_Modules#Overview|modules]]. Modules have been introduced in Go 1.11. | |||
=< | =Packages= | ||
{{Internal|Go Packages#Overview|Packages}} | |||
=Modules= | |||
{{Internal|Go Modules#Overview|Modules}} | |||
==Module-Aware or <tt>GOPATH</tt> Mode== | |||
{{External|https://go.dev/ref/mod#mod-commands}} | |||
The compiler must locate packages on the local file system every time it handles an [[Go_Packages#Import_Statement|<code>import</code> statement]]. | |||
The [[Go_Tool#Overview|<tt>go</tt> tool]] has two modes of resolving package dependencies: '''module-aware mode''' or '''GOPATH mode'''. | |||
< | In module-aware mode, the <code>go</code> commands use <code>[[Go_Modules#go.mod|go.mod]]</code> files to find versioned dependencies and typically load packages out of the [[Go_Modules#Module_Cache|module cache]], downloading modules if they are missing. As of Go 1.16, the module-aware mode is enabled by default, regardless of whether <code>[[Go_Modules#go.mod|go.mod]]</code> is present or not. The behavior can be controlled with the <code>[[Go_Environment_Variables#GO111MODULE|GO111MODULE]]</code> environment variable. | ||
In GOPATH mode, <code>go</code> commands use the value of the <code>[[Go_Environment_Variables#GOPATH|GOPATH]]</code> environment variable and vendor directories to resolve packages. | |||
Also see: {{Internal|GoLand#Module-Aware_or_GOPATH_Mode|GoLand Module-Aware or <tt>GOPATH</tt> Mode}}{{Internal|Go_Environment_Variables#GOPATH|<tt>GOPATH</tt>}} | |||
=Project= | |||
{{Internal|Go Project|Project}} | |||
=Repository= | |||
A Go repository typically contains only one [[Go Modules|module]], located in the root of the repository. Repository may contain more than one module. | |||
=Packages, Modules, Projects and Repositories= | |||
Designing your [[Go_Project#Overview|project]], to live in its own repository and host a single module in its root directory will help keep maintenance simpler, particularly over time as you publish new versions. | |||
It is possible to maintain more than one module in a project and repository <font color=darkkhaki>TODO: https://go.dev/doc/modules/managing-source#multiple-module-source</font>. | |||
=<span id='Standard_library'></span>Standard Library= | |||
Go comes with a set of over 100 "built-in" packages, which are available as part of the locally installed Go development environment. | |||
Standard library package documentation is available online here: {{External|https://pkg.go.dev/std}} | |||
The standard library is a good source of code examples, comments and [[Go_Style#Overview|style]] guidance. | |||
The standard library is a good source of code examples, comments and [[Go_Style#Overview|style]]. | |||
Standard library packages: | Standard library packages: | ||
:::{|class="wikitable" style="text-align: left;" | :::{|class="wikitable" style="text-align: left;" | ||
| <font face='menlo' size='-2'><span id='archive'></span>[[Go Package archive|archive]]</font> || <font face='menlo' size='-2'><span id='atomic'></span>[[go Package atomic|atomic]]</font> || <font face='menlo' size='-2'><span id='bytes'></span>[[go Package bytes|bytes]]</font> || <font face='menlo' size='-2'><span id=' | | <font face='menlo' size='-2'><span id='archive'></span>[[Go Package archive|archive]]</font> || <font face='menlo' size='-2'><span id='atomic'></span>[[go Package atomic|atomic]]</font> || <font face='menlo' size='-2'><span id='bytes'></span>[[go Package bytes|bytes]]</font> || <font face='menlo' size='-2'><span id='bufio'></span>[[Go_Package_bufio#Overview|bufio]]</font> || <font face='menlo' size='-2'><span id='container'></span>[[go Package container|container]]</font> || <font face='menlo' size='-2'><span id='context'></span>[[go Package context|context]]</font> || <font face='menlo' size='-2'><span id='database'></span>[[go Package database|database]]</font> | ||
|- | |- | ||
| <font face='menlo' size='-2'><span id=' | | <font face='menlo' size='-2'><span id='encoding'></span>[[go Package encoding|encoding]]</font> || <font face='menlo' size='-2'><span id='json'></span><span id='encoding_json'></span>[[Go Package encoding/json|encoding/json]] || <font face='menlo' size='-2'><span id='errors'></span>[[Go_Language_Error_Handling#The_errors_Package|errors]]</font> || <font face='menlo' size='-2'><span id='filepath'></span>[[File_Paths_and_Names_in_Go#filepath|filepath]]</font> || <font face='menlo' size='-2'><span id='flag'></span>[[go Package flag|flag]]</font> || <font face='menlo' size='-2'><span id='fmt'></span>[[go Package fmt|fmt]]</font> || <font face='menlo' size='-2'><span id='io'></span>[[go Package io|io]]</font> | ||
|- | |- | ||
| <font face='menlo' size='-2'><span id=' | | <font face='menlo' size='-2'><span id='ioutil'></span>[[Go Package ioutil|ioutil]] || <font face='menlo' size='-2'><span id='hash'></span>[[go Package hash|hash]]</font> || <font face='menlo' size='-2'><span id='html'></span>[[go Package html|html]]</font> || <font face='menlo' size='-2'><span id='html_template'></span>[[go Package html/template|html/template]]</font> || <font face='menlo' size='-2'><span id='log'></span>[[go Package log|log]]</font> || <font face='menlo' size='-2'><span id='maps'></span>[[go Package maps|maps]]</font> || <font face='menlo' size='-2'><span id='math'></span>[[go Package math|math]]</font> | ||
|- | |- | ||
| <font face='menlo' size='-2'><span id=' | | <font face='menlo' size='-2'><span id='net'></span>[[Go Package net|net]] || <font face='menlo' size='-2'><span id='net_http'></span>[[Go Package net/http|net/http]] || <font face='menlo' size='-2'><span id='net_url'></span>[[Go Package net/url|net/url]] || <font face='menlo' size='-2'><span id='os'></span>[[Go Package os|os]]</font> || <font face='menlo' size='-2'><span id='path'></span>[[File_Paths_and_Names_in_Go#path|path]]</font> || <font face='menlo' size='-2'><span id='rand'></span>[[Go Package rand|rand]]</font> || <font face='menlo' size='-2'><span id='reflect'></span>[[Go Package reflect|reflect]]</font> | ||
|- | |- | ||
| <font face='menlo' size='-2'><span id=' | | <font face='menlo' size='-2'><span id='regexp'></span> [[go Package regexp|regexp]]</font> || <font face='menlo' size='-2'><span id='runtime'></span>[[go Package runtime|runtime]]</font> || <font face='menlo' size='-2'><span id='runtime_debug'></span>[[go Package runtime/debug|runtime/debug]]</font> || <font face='menlo' size='-2'><span id='slices'></span>[[Go Package slices|slices]]</font> || <font face='menlo' size='-2'><span id='slog'></span>[[Go_Package_slog|slog]]</font> || <font face='menlo' size='-2'><span id='sort'></span>[[Go Package sort|sort]]</font> || <font face='menlo' size='-2'><span id='strings'></span>[[go Package strings|strings]]</font> | ||
|- | |||
| <font face='menlo' size='-2'><span id='strconv'></span>[[Go Package strconv|strconv]]</font> || <font face='menlo' size='-2'><span id='sync'></span>[[Go Package sync|sync]]</font> || <font face='menlo' size='-2'><span id='text-tabwriter'></span>[[go Package text/tabwriter|text/tabwriter]]</font> || <font face='menlo' size='-2'><span id='text-template'></span>[[go Package text/template|text/template]]</font> || <font face='menlo' size='-2'><span id='testing'></span>[[Go Package testing|testing]] || <font face='menlo' size='-2'><span id='time'></span>[[Go Package time|time]]</font> || <font face='menlo' size='-2'><span id='unicode'></span>[[Go Package unicode|unicode]] | |||
|- | |- | ||
|} | |} | ||
=< | =<tt>pkg.go.dev</tt>= | ||
The place to look for published third-party packages is {{External|https://pkg.go.dev}} | |||
=<span id='Workspaces'></span>Workspace= | |||
<font color=darkkhaki>This section needs refactoring after reading: | |||
* Tutorial: Getting started with multi-module workspaces https://go.dev/doc/tutorial/workspaces | |||
* Get familiar with workspaces https://go.dev/blog/get-familiar-with-workspaces | |||
</font> | |||
The workspace is a concept introduced in Go 1.18. A workspace allows organizing the code for a project that has several [[Go_Modules#Overview|modules]] which share a common list of dependencies. The workspace maintains metadata, especially dependency metadata, in a file called <code>go.work</code>. The dependencies declared in this file can span modules and anything declared in <code>go.work</code> will override dependencies in the modules's <code>go.mod</code>. The packages and modules maintained in a workspace are managed with the [[Go_Tool#Overview|<code>go</code> tool]]. | |||
A workspace may contain multiple [[#Project|projects]]. | |||
The standard workspace layout is: | |||
<font size=-2> | |||
. <font color=teal>← GOPATH should point to this directory, it contains src, pkg and bin</font> | |||
│ | |||
├─ src | |||
│ ├─ a | |||
│ │ └─ b | |||
│ │ └─color <font color=teal># "color" package directory, with the "a/b/color" import path</font> | |||
│ │ ├─ colors.go | |||
│ │ ├─ aux.go | |||
│ │ └─ ... | |||
│ │ | |||
│ ├─ weight <font color=teal># "weight" package directory, with the "weight" import path</font> | |||
│ │ ├─ weights.go | |||
< | │ │ ├─ aux.go | ||
│ │ └─ ... | |||
│ │ | |||
│ ├─ novaordis.com | |||
│ │ └─ tools | |||
│ │ └─ hammer <font color=teal># "hammer" package directory, with the "novaordis.com/tools/hammer" import path</font> | |||
│ │ └─ ... | |||
│ │ | |||
│ └─ github.com | |||
│ └─ blue-org | |||
│ └─ tools | |||
│ └─ wrench <font color=teal># "wrench" package directory, with the "github.com/blue-org/tools/wrench" import path</font> | |||
│ ├─ .git | |||
│ └─ ... | |||
│ | |||
├─ pkg | |||
│ └─ darwin_amd64 | |||
│ ├─ weights.go | |||
│ ├─ a/b/color.a | |||
│ ├─ novaordis.com/tools/hammer.a | |||
│ └─ github.com/bue-org/tools/wrench.a | |||
└─ bin | |||
</font> | |||
==Content== | |||
<font color= | ===<tt>src</tt>=== | ||
The <code>src</code> subdirectory holds source code. Each package resides in a directory whose name relative to <code>${GOPATH}/src</code> represents the package's [[Go_Packages#Import_Path|import path]]. | |||
... | |||
< | |||
... | |||
=== | |||
== | |||
The <code>src</code> subdirectory may contain multiple version-control repository workareas. | |||
===<tt>pkg</tt>=== | |||
The build tool stores compiled packages in the <code>pkg</code> directory, under <code>${GOOS}_${GOARCH}</code> subdirectories. | |||
< | ===<tt>bin</tt>=== | ||
:[[ | The <code>bin</code> directory is where the executables are stored. | ||
</ | ===<tt>vendor</tt>=== | ||
<font color=darkkhaki>TODO: expand this and link to [[Go_Packages#Vendoring]].</font> | |||
= | ==Relationship between Workspace and <tt>GOPATH</tt>== | ||
<code>[[Go_Environment_Variables#GOPATH|GOPATH]]</code> should point to the root of the workspace, the directory that contains <code>src</code>, <code>pkg</code> and <code>bin</code>. <font color=darkkhaki>Further research is required.</font> | |||
=Program= | |||
Go programs are constructed by linking together [[Go_Packages#Overview|packages]]. There must be a [[Go_Packages#The_main_Package|<code>main</code> package]], which contains the <code>main()</code>, to trigger the linker. |
Latest revision as of 17:42, 4 September 2024
Internal
Overview
Go modularization builds upon the concepts of package and module. Packages provide a namespace for their members, and they are a way to encapsulate code, hide implementation details and only expose features, such as variables, functions or type definitions that are meant to be publicly consumed. Packages can be published as part of modules. Modules have been introduced in Go 1.11.
Packages
Modules
Module-Aware or GOPATH Mode
The compiler must locate packages on the local file system every time it handles an import
statement.
The go tool has two modes of resolving package dependencies: module-aware mode or GOPATH mode.
In module-aware mode, the go
commands use go.mod
files to find versioned dependencies and typically load packages out of the module cache, downloading modules if they are missing. As of Go 1.16, the module-aware mode is enabled by default, regardless of whether go.mod
is present or not. The behavior can be controlled with the GO111MODULE
environment variable.
In GOPATH mode, go
commands use the value of the GOPATH
environment variable and vendor directories to resolve packages.
Also see:
Project
Repository
A Go repository typically contains only one module, located in the root of the repository. Repository may contain more than one module.
Packages, Modules, Projects and Repositories
Designing your project, to live in its own repository and host a single module in its root directory will help keep maintenance simpler, particularly over time as you publish new versions.
It is possible to maintain more than one module in a project and repository TODO: https://go.dev/doc/modules/managing-source#multiple-module-source.
Standard Library
Go comes with a set of over 100 "built-in" packages, which are available as part of the locally installed Go development environment.
Standard library package documentation is available online here:
The standard library is a good source of code examples, comments and style guidance.
Standard library packages:
pkg.go.dev
The place to look for published third-party packages is
Workspace
This section needs refactoring after reading:
- Tutorial: Getting started with multi-module workspaces https://go.dev/doc/tutorial/workspaces
- Get familiar with workspaces https://go.dev/blog/get-familiar-with-workspaces
The workspace is a concept introduced in Go 1.18. A workspace allows organizing the code for a project that has several modules which share a common list of dependencies. The workspace maintains metadata, especially dependency metadata, in a file called go.work
. The dependencies declared in this file can span modules and anything declared in go.work
will override dependencies in the modules's go.mod
. The packages and modules maintained in a workspace are managed with the go
tool.
A workspace may contain multiple projects.
The standard workspace layout is:
. ← GOPATH should point to this directory, it contains src, pkg and bin │ ├─ src │ ├─ a │ │ └─ b │ │ └─color # "color" package directory, with the "a/b/color" import path │ │ ├─ colors.go │ │ ├─ aux.go │ │ └─ ... │ │ │ ├─ weight # "weight" package directory, with the "weight" import path │ │ ├─ weights.go │ │ ├─ aux.go │ │ └─ ... │ │ │ ├─ novaordis.com │ │ └─ tools │ │ └─ hammer # "hammer" package directory, with the "novaordis.com/tools/hammer" import path │ │ └─ ... │ │ │ └─ github.com │ └─ blue-org │ └─ tools │ └─ wrench # "wrench" package directory, with the "github.com/blue-org/tools/wrench" import path │ ├─ .git │ └─ ... │ ├─ pkg │ └─ darwin_amd64 │ ├─ weights.go │ ├─ a/b/color.a │ ├─ novaordis.com/tools/hammer.a │ └─ github.com/bue-org/tools/wrench.a └─ bin
Content
src
The src
subdirectory holds source code. Each package resides in a directory whose name relative to ${GOPATH}/src
represents the package's import path.
The src
subdirectory may contain multiple version-control repository workareas.
pkg
The build tool stores compiled packages in the pkg
directory, under ${GOOS}_${GOARCH}
subdirectories.
bin
The bin
directory is where the executables are stored.
vendor
TODO: expand this and link to Go_Packages#Vendoring.
Relationship between Workspace and GOPATH
GOPATH
should point to the root of the workspace, the directory that contains src
, pkg
and bin
. Further research is required.
Program
Go programs are constructed by linking together packages. There must be a main
package, which contains the main()
, to trigger the linker.