/* * BSD 3-Clause License * Copyright (c) 2024, NetFireâ„¢ * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package version import ( `fmt` `strings` `golang.org/x/mod/semver` ) // Detail returns a multiline string containing every possible piece of information we collect. func (b *BuildInfo) Detail() (ver string) { var sb strings.Builder sb.WriteString(fmt.Sprintf("%v\n\n", b.short)) sb.WriteString(fmt.Sprintf("====\nSource Control: %v\nRepo URI: %v\n", b.SourceControl, b.RepoURI)) if b.TagVersion != "" { if b.PostTagCommits > 0 { sb.WriteString(fmt.Sprintf("Version Base: %v\nCommit Hash: %v\n", b.TagVersion, b.CommitHash)) } else { sb.WriteString(fmt.Sprintf("Version: %v\n", b.TagVersion)) } } else { sb.WriteString(fmt.Sprintf("Version: (Unversioned)\nCommit Hash: %v\n", b.CommitHash)) } // Post-commits if b.TagVersion != "" { sb.WriteString(fmt.Sprintf("# of Commits Since %v: %v\n", b.TagVersion, b.PostTagCommits)) } else { sb.WriteString(fmt.Sprintf("# of Commits Since %v: %v\n", b.CommitId, b.PostTagCommits)) } sb.WriteString("Uncommitted/Unstaged Changes: ") if b.Dirty { sb.WriteString("yes (dirty/monkeypatched build)\n") } else { sb.WriteString("no (clean build)\n") } if b.TagVersion != "" { sb.WriteString( fmt.Sprintf( "====\nMajor: %v\nMinor: %v\nPatch: %v\n", b.Major, b.Minor, b.Patch, ), ) } sb.WriteString("====\n") sb.WriteString(b.Meta()) ver = sb.String() return } // Short returns a uniquely identifiable version string. func (b *BuildInfo) Short() (ver string) { ver = b.short return } // Meta returns the build/compile-time info. func (b *BuildInfo) Meta() (meta string) { var sb strings.Builder if b.RealBuildUser != b.BuildUser && b.RealBuildUser != "" { sb.WriteString(fmt.Sprintf("Real Build User: %v\n", b.RealBuildUser)) sb.WriteString(fmt.Sprintf("Sudo Build User: %v\n", b.BuildUser)) } else { sb.WriteString(fmt.Sprintf("Build User: %v\n", b.BuildUser)) } sb.WriteString(fmt.Sprintf("Build Time: %v\nBuild Host: %v\nGo Version: %v\n", b.BuildTime, b.BuildHost, b.GoVersion)) meta = sb.String() return } // getReMap gets a regex map of map[pattern]match. func (b *BuildInfo) getReMap() (matches map[string]string) { var s string = b.Short() var sections []string if !semver.IsValid(s) { return } sections = strings.Split(s, ".") // The split should contain everything in the third element. // Or, if using a "simplified" semver, the last element. matches = make(map[string]string) for idx, str := range patchRe.FindStringSubmatch(sections[len(sections)-1]) { matches[patchRe.SubexpNames()[idx]] = str } return }