blob: 5e143a5dccda96b80f5e3a1e2edbbeca53add8f8 [file] [log] [blame]
// Copyright 2019 The Chromium OS 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 repo
import (
"fmt"
"io/ioutil"
"log"
"path/filepath"
"regexp"
"strconv"
)
type VersionComponent string
const (
ChromeBranch VersionComponent = "CHROME_BRANCH"
Build VersionComponent = "CHROMEOS_BUILD"
Branch VersionComponent = "CHROMEOS_BRANCH"
Patch VersionComponent = "CHROMEOS_PATCH"
)
// This is a var and not a const for testing purposes.
var (
versionFilePath string = "src/third_party/chromiumos-overlay/" +
"chromeos/config/chromeos_version.sh"
)
const (
keyValueRegex string = `%s=(\d+)\b`
)
var chromeosVersionMapping = map[VersionComponent](*regexp.Regexp){
ChromeBranch: regexp.MustCompile(fmt.Sprintf(keyValueRegex, ChromeBranch)),
Build: regexp.MustCompile(fmt.Sprintf(keyValueRegex, Build)),
Branch: regexp.MustCompile(fmt.Sprintf(keyValueRegex, Branch)),
Patch: regexp.MustCompile(fmt.Sprintf(keyValueRegex, Patch)),
}
type VersionInfo struct {
ChromeBranch int
BuildNumber int
BranchBuildNumber int
PatchNumber int
VersionFile string
}
func GetVersionInfoFromRepo(sourceRepo string) (VersionInfo, error) {
var v VersionInfo
v.VersionFile = filepath.Join(sourceRepo, versionFilePath)
fileData, err := ioutil.ReadFile(v.VersionFile)
if err != nil {
return VersionInfo{}, fmt.Errorf("could not read version file %s", v.VersionFile)
}
for field, pattern := range chromeosVersionMapping {
if match := findValue(pattern, string(fileData)); match != "" {
num, err := strconv.Atoi(match)
if err != nil {
log.Fatal(fmt.Sprintf("%s value %s could not be converted to integer.", field, match))
}
switch field {
case ChromeBranch:
v.ChromeBranch = num
case Build:
v.BuildNumber = num
case Branch:
v.BranchBuildNumber = num
case Patch:
v.PatchNumber = num
default:
// This should never happen.
log.Fatal("Invalid version component.")
}
continue
}
}
return v, nil
}
func findValue(re *regexp.Regexp, line string) string {
match := re.FindSubmatch([]byte(line))
if len(match) == 0 {
return ""
}
// Return first submatch (the value).
return string(match[1])
}
func (v *VersionInfo) IncrementVersion(incrType VersionComponent) string {
if incrType == ChromeBranch {
v.ChromeBranch += 1
}
// Increment build_number for ChromeBranch incrType to avoid
// crbug.com/213075.
if incrType == ChromeBranch || incrType == Build {
v.BuildNumber += 1
v.BranchBuildNumber = 0
v.PatchNumber = 0
} else if incrType == Branch && v.PatchNumber == 0 {
v.BranchBuildNumber += 1
} else {
v.PatchNumber += 1
}
return v.VersionString()
}
func incrString(str string) string {
num, err := strconv.Atoi(str)
if err != nil {
log.Fatal(fmt.Sprintf("String %s could not be converted to integer.", str))
}
return strconv.Itoa(num + 1)
}
func (v *VersionInfo) VersionString() string {
return fmt.Sprintf("%d.%d.%d", v.BuildNumber, v.BranchBuildNumber, v.PatchNumber)
}
func (v *VersionInfo) VersionComponents() []int {
return []int{v.BuildNumber, v.BranchBuildNumber, v.PatchNumber}
}