工作区
4 分钟阅读
Workspaces 工作区
工作区是磁盘上模块的集合,在运行minimal version selection (MVS) (最小版本选择(MVS))时这些模块被用作主模块。
工作区可以在 go.work 文件中声明,该文件指定了工作区中每个模块目录的相对路径。当没有go.work文件存在时,工作区由包含当前目录的单个模块组成。
大多数处理模块的go子命令都是在由当前工作区决定的模块集合上操作的。go mod init、go mod why、go mod edit、go mod tidy、go mod vendor和go get总是在一个主模块上操作。
命令首先通过检查GOWORK环境变量来确定它是否处于工作区上下文中。如果GOWORK被设置为off,该命令将处于单模块上下文中。如果它是空的或者未提供,命令将在当前工作目录中搜索,然后在连续的父目录中搜索go.work这个文件。如果找到一个(go.work)文件,该命令将在该文件定义的工作区中操作;否则,工作区将只包括包含工作目录的模块。如果GOWORK命名一个以.work结尾的现有文件的路径,工作区模式将被启用。任何其他的值都是一个错误。您可以使用go env GOWORK命令来确定go命令正在使用哪个go.work文件。如果go命令没有进入工作区模式,go env GOWORK将为空。
go.work files
工作区是由一个名为go.work的UTF-8编码文本文件定义的。go.work文件是面向行的。每行包含一个指令,由一个关键字和参数组成。例如:
go 1.18
use ./my/first/thing
use ./my/second/thing
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
与go.mod文件一样,前导关键字可以从相邻的行中分解出来,形成一个块。
use (
./my/first/thing
./my/second/thing
)
go命令提供了几个操作go.work文件的子命令。go work init创建新的go.work文件。go work use向go.work文件添加模块目录。go work edit执行低级别的编辑。Go 程序可以使用 golang.org/x/mod/modfile 包,以编程方式进行相同的更改。
Lexical elements 词汇元素
go.work文件中的词汇元素的定义方式与go.mod 文件完全相同。
Grammar 语法
go.work的语法由下面使用Extended Backus-Naur Form (EBNF)来指定。有关 EBNF 语法的详细信息,请参见 Go 语言规范中的标记法部分。
GoWork = { Directive } .
Directive = GoDirective |
UseDirective |
ReplaceDirective .
换行符、标识符和字符串分别用newline、ident和string表示。
模块路径和版本用ModulePath和Version来表示。模块路径和版本的指定方式与go.mod文件的指定方式完全相同。
ModulePath = ident | string . /* see restrictions above */
Version = ident | string . /* see restrictions above */
go directive
在一个有效的go.work文件中需要一个go指令。版本必须是有效的Go发布版本:一个正整数后跟一个点和一个非负整数(例如,1.18,1.19)。
go指令表示go.work文件所要使用的go工具链版本。如果go.work文件的格式发生了变化,未来版本的工具链将根据其指示的版本来解释该文件。
一个go.work文件最多只能包含一个go指令。
GoDirective = "go" GoVersion newline .
GoVersion = string | ident . /* valid release version; see above */
示例:
go 1.18
use directive
use将磁盘上的一个模块添加到工作区的主模块集合中。它的参数是包含该模块的go.mod文件的目录的相对路径。use指令并不添加包含在其参数目录下的子目录中的模块。这些模块可以由包含其go.mod文件的目录在单独的use指令中添加。=>仍有疑问??这里应该是"require指令中添加吧"??
UseDirective = "use" ( UseSpec | "(" newline { UseSpec } ")" newline ) .
UseSpec = FilePath newline .
FilePath = /* platform-specific relative or absolute file path */
示例:
use ./mymod // example.com/mymod
use (
../othermod
./subdir/thirdmod
)
replace directive
与go.mod文件中的replace指令类似,go.work文件中的replace指令用其他地方的内容替换一个模块的特定版本,或一个模块的所有版本。go.work中的通配符替换可以覆盖go.mod文件中特定版本的replace。
go.work文件中的replace指令会覆盖工作区模块中相同模块或模块版本的任何替换。
ReplaceDirective = "replace" ( ReplaceSpec | "(" newline { ReplaceSpec } ")" newline ) .
ReplaceSpec = ModulePath [ Version ] "=>" FilePath newline
| ModulePath [ Version ] "=>" ModulePath Version newline .
FilePath = /* platform-specific relative or absolute file path */
示例:
replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
replace (
golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
golang.org/x/net => example.com/fork/net v1.4.5
golang.org/x/net v1.2.3 => ./fork/net
golang.org/x/net => ./fork/net
)