github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/constants/preprocess/preprocess.go (about)

     1  package preprocess
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/ActiveState/cli/internal/constants"
    13  	"github.com/ActiveState/cli/internal/constants/version"
    14  	"github.com/blang/semver"
    15  )
    16  
    17  // Constants holds constants that will be preprocessed, meaning the key value parts here will be built into the constants
    18  // package as actual constants, using the build-time interpretations
    19  var Constants = map[string]func() interface{}{}
    20  
    21  func init() {
    22  	channelName, commitRef := channelName()
    23  	buildNumber := buildNumber()
    24  
    25  	if sha, exists := os.LookupEnv("GITHUB_SHA_OVERRIDE"); exists {
    26  		fmt.Printf("Using GITHUB_SHA_OVERRIDE: %s", sha)
    27  		commitRef = sha
    28  	} else if sha, exists := os.LookupEnv("GITHUB_SHA"); exists {
    29  		fmt.Printf("Using GITHUB_SHA: %s", sha)
    30  		commitRef = sha
    31  	}
    32  
    33  	newVersion, err := version.Detect("")
    34  	if err != nil {
    35  		log.Fatalf("Could not parse new version: %s", err)
    36  	}
    37  
    38  	remoteInstallerVersion, err := version.Detect("cmd/state-remote-installer")
    39  	if err != nil {
    40  		log.Fatalf("Could not parse new remote installer version: %s", err)
    41  	}
    42  
    43  	Constants["ChannelName"] = func() interface{} { return channelName }
    44  	Constants["BuildNumber"] = func() interface{} { return buildNumber }
    45  	Constants["RevisionHash"] = func() interface{} { return getCmdOutput("git rev-parse --verify " + commitRef) }
    46  	Constants["RevisionHashShort"] = func() interface{} { return getCmdOutput("git rev-parse --short " + commitRef) }
    47  	Constants["Version"] = func() interface{} {
    48  		return mustVersionWithRevision(newVersion, Constants["RevisionHashShort"]().(string))
    49  	}
    50  	Constants["VersionNumber"] = func() interface{} { return newVersion.String() }
    51  	Constants["RemoteInstallerVersion"] = func() interface{} { return remoteInstallerVersion.String() }
    52  	Constants["Date"] = func() interface{} { return time.Now().Format(constants.DateTimeFormatRecord) }
    53  	Constants["UserAgent"] = func() interface{} {
    54  		return fmt.Sprintf("%s/%s; %s", constants.CommandName, Constants["Version"](), channelName)
    55  	}
    56  	Constants["APITokenName"] = func() interface{} { return fmt.Sprintf("%s-%s", constants.APITokenNamePrefix, channelName) }
    57  	Constants["OnCI"] = func() interface{} { return os.Getenv("CI") }
    58  }
    59  
    60  // gitBranchName returns the branch name of the current git commit / PR
    61  func gitBranchName() string {
    62  	// branch name variable set by Github Actions
    63  	if branch, isset := os.LookupEnv("GITHUB_HEAD_REF"); isset && branch != "" {
    64  		return "origin/" + branch
    65  	}
    66  	if branch, isset := os.LookupEnv("GITHUB_REF"); isset && branch != "" {
    67  		return "origin/" + strings.TrimPrefix(branch, "refs/heads/")
    68  	}
    69  	branch := getCmdOutput("git rev-parse --abbrev-ref HEAD")
    70  	return branch
    71  }
    72  
    73  // channelName returns the release name and the branch name it is generated from
    74  // Usually the release name is identical to the branch name.
    75  func channelName() (string, string) {
    76  	branch := gitBranchName()
    77  	releaseName := strings.TrimPrefix(branch, "origin/")
    78  
    79  	return releaseName, branch
    80  }
    81  
    82  func buildNumber() string {
    83  	out := getCmdOutput("git rev-list --all --count")
    84  	return strings.TrimSpace(out)
    85  }
    86  
    87  func getCmdOutput(cmdString string) string {
    88  	cmdArgs := strings.Split(cmdString, " ")
    89  
    90  	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
    91  	var out bytes.Buffer
    92  	var stderr bytes.Buffer
    93  	cmd.Stdout = &out
    94  	cmd.Stderr = &stderr
    95  
    96  	err := cmd.Run()
    97  	if err != nil {
    98  		log.Fatalf("Command failed, command: %s, args: %v, output: %s, error: %s, code: %s", cmdArgs[0], cmdArgs[1:], out.String(), stderr.String(), err)
    99  		os.Exit(1)
   100  	}
   101  	return strings.Trim(out.String(), "\n")
   102  }
   103  
   104  func mustVersionWithRevision(ver semver.Version, revision string) string {
   105  	v, err := version.VersionWithRevision(ver, revision)
   106  	if err != nil {
   107  		log.Fatalf("failed to add")
   108  	}
   109  
   110  	return v.String()
   111  }