| // Copyright 2021 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package internal |
| |
| import "fmt" |
| |
| // A BuildContext describes a build context for the Go tool: information needed |
| // to build a Go package. For our purposes, we only care about the information |
| // that affects documentation generated from the package. |
| type BuildContext struct { |
| GOOS, GOARCH string |
| } |
| |
| // String returns a string formatted representation of the build context. |
| func (b BuildContext) String() string { |
| return fmt.Sprintf("%s/%s", b.GOOS, b.GOARCH) |
| } |
| |
| // Match reports whether its receiver, which acts like a pattern, matches its |
| // target, an ordinary BuildContext. In addition to the usual values, a pattern |
| // can have an empty GOOS or GOARCH, which means "match anything." |
| func (pattern BuildContext) Match(target BuildContext) bool { |
| match := func(pat, targ string) bool { return pat == "" || targ == All || pat == targ } |
| |
| return match(pattern.GOOS, target.GOOS) && match(pattern.GOARCH, target.GOARCH) |
| } |
| |
| // All represents all values for a build context element (GOOS or GOARCH). |
| const All = "all" |
| |
| var ( |
| BuildContextAll = BuildContext{All, All} |
| BuildContextLinux = BuildContext{"linux", "amd64"} |
| BuildContextWindows = BuildContext{"windows", "amd64"} |
| BuildContextDarwin = BuildContext{"darwin", "amd64"} |
| BuildContextJS = BuildContext{"js", "wasm"} |
| ) |
| |
| // BuildContexts are the build contexts we check when loading a package (see |
| // internal/fetch/load.go). |
| // We store documentation for all of the listed contexts. |
| // The order determines which environment's docs we will show as the default. |
| var BuildContexts = []BuildContext{ |
| BuildContextLinux, |
| BuildContextWindows, |
| BuildContextDarwin, |
| BuildContextJS, |
| } |
| |
| // CompareBuildContexts returns a negative number, 0, or a positive number depending on |
| // the relative positions of c1 and c2 in BuildContexts. |
| func CompareBuildContexts(c1, c2 BuildContext) int { |
| if c1 == c2 { |
| return 0 |
| } |
| // Although we really shouldn't see a BuildContext with "all" here, we may if the |
| // DB erroneously has both an all/all row and some other row. So just prefer the all/all. |
| if c1 == BuildContextAll { |
| if c2 == BuildContextAll { |
| return 0 |
| } |
| return -1 |
| } |
| if c2 == BuildContextAll { |
| return 1 |
| } |
| pos := func(c BuildContext) int { |
| for i, d := range BuildContexts { |
| if c == d { |
| return i |
| } |
| } |
| return len(BuildContexts) // unknowns sort last |
| } |
| return pos(c1) - pos(c2) |
| } |
| |
| // BuildContext returns the BuildContext for d. |
| func (d *Documentation) BuildContext() BuildContext { |
| return BuildContext{GOOS: d.GOOS, GOARCH: d.GOARCH} |
| } |
| |
| // DocumentationForBuildContext returns the first Documentation the list that |
| // matches the BuildContext, or nil if none does. A Documentation matches if its |
| // GOOS and GOARCH fields are the same as those of the BuildContext, or if the |
| // Documentation field is "all", or if the BuildContext field is empty. That is, |
| // empty BuildContext fields act as wildcards. So the zero BuildContext will |
| // match the first element of docs, if there is one. |
| func DocumentationForBuildContext(docs []*Documentation, bc BuildContext) *Documentation { |
| for _, d := range docs { |
| if bc.Match(BuildContext{d.GOOS, d.GOARCH}) { |
| return d |
| } |
| } |
| return nil |
| } |