cert-manager/hack/release/pkg/flags/flags.go
James Munnelly 81c3ca2d98 Set default appVersin to v0.0.0-experimental
Signed-off-by: James Munnelly <james@munnelly.eu>
2019-05-03 11:16:26 +01:00

177 lines
5.3 KiB
Go

/*
Copyright 2019 The Jetstack cert-manager contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package flags
import (
"fmt"
"os"
"strings"
flag "github.com/spf13/pflag"
"os/exec"
logf "github.com/jetstack/cert-manager/hack/release/pkg/log"
"github.com/jetstack/cert-manager/hack/release/pkg/util"
)
var (
Default = &Global{}
log = logf.Log.WithName("global")
)
type Global struct {
// Path to the root of the cert-manager repository
RepoRoot string
// DockerRepo is the docker repository used to store release images
DockerRepo string
// UpstreamRepoURL is the URL of the git repo used to check for tags
UpstreamRepoURL string
// AppVersion is the version tag to use for this release
AppVersion string
// GitState contains the state of the git working tree.
GitState string
// GitCommitRef is the current git commit hash being built
GitCommitRef string
GitPath string
// Path to the cert-manager Helm chart.
// This is defined as a global as the manifests plugin also needs
// access to this flag
ChartPath string
}
const defaultDockerRepo = "quay.io/jetstack"
func (g *Global) AddFlags(fs *flag.FlagSet) {
fs.StringVar(&g.RepoRoot, "repo-root", "", "path to the root of the cert-manager repository")
fs.StringVar(&g.DockerRepo, "docker-repo", defaultDockerRepo, "the docker repository that images will be tagged with")
fs.StringVar(&g.AppVersion, "app-version", "", "app version to use when building and generating manifests. Defaults to 'git describe --tags --abbrev=0 --exact-match'")
fs.StringVar(&g.UpstreamRepoURL, "git.upstream-repo-url", "https://github.com/jetstack/cert-manager.git", "the URL of the git repo used to check for tags when generating --app-version")
fs.StringVar(&g.GitState, "git.state", "", "the state of the git working tree. if set and not 'clean', this will be appended to the app-version during builds")
fs.StringVar(&g.GitCommitRef, "git.commit-ref", "", "the git commit ref of this build. Defaults to 'git rev-parse --short HEAD'")
fs.StringVar(&g.GitPath, "git.path", "git", "path to the git binary to use")
fs.StringVar(&g.ChartPath, "chart.path", "deploy/charts/cert-manager", "the path to the cert-manager helm chart, relative to the repo root")
}
func (g *Global) Validate() []error {
var errs []error
if g.UpstreamRepoURL == "" {
errs = append(errs, fmt.Errorf("--git.upstream-repo-url must be specified"))
}
return errs
}
func (g *Global) Complete() error {
log = log.WithName("default-flags")
if g.DockerRepo == "" {
log := log.WithValues("flag", "docker-repo")
g.DockerRepo = defaultDockerRepo
log.Info("set default value", "value", g.DockerRepo)
}
if g.RepoRoot == "" {
log := log.WithValues("flag", "repo-root")
if bwd := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); bwd != "" {
g.RepoRoot = bwd
} else {
dir, err := os.Getwd()
if err != nil {
return fmt.Errorf("error determining repo root: %v", err)
}
g.RepoRoot = dir
}
log.Info("set default value", "value", g.RepoRoot)
}
if err := os.Chdir(g.RepoRoot); err != nil {
return fmt.Errorf("error changing directory to --repo-root=%q: %v", g.RepoRoot, err)
}
if g.AppVersion == "" {
log := log.WithValues("flag", "app-version")
log.V(logf.LogLevelDebug).Info("fetching upstream git repo tags")
_, err := g.gitOutput("fetch", "--tags", g.UpstreamRepoURL)
if err != nil {
return fmt.Errorf("error fetching tags: %v", err)
}
log.V(logf.LogLevelDebug).Info("finding tags that match the current commit ref")
g.AppVersion, err = g.gitOutput("describe", "--tags", "--abbrev=0", "--exact-match")
if err != nil {
log.Error(err, "failed to determine tag for current git ref/HEAD")
g.AppVersion = ""
}
if g.AppVersion == "" {
// default to 'v0.0.0-experimental' if no tags point to the current ref
g.AppVersion = "v0.0.0-experimental"
}
log.WithValues("value", g.AppVersion).Info("set default value")
}
if g.GitCommitRef == "" {
log := log.WithValues("flag", "git.commit-ref")
log.V(logf.LogLevelDebug).Info("parsing current git commit ref")
var err error
g.GitCommitRef, err = g.gitOutput("rev-parse", "--short", "HEAD")
if err != nil {
return fmt.Errorf("error getting current commit ref: %v", err)
}
log.WithValues("value", g.GitCommitRef).Info("set default value")
}
if g.GitState == "" {
log := log.WithValues("flag", "git.commit-state")
log.V(logf.LogLevelDebug).Info("evaluating current git working tree dirty status")
changes, err := g.gitOutput("status", "--porcelain")
if err != nil {
return fmt.Errorf("error checking git status: %v", err)
}
if len(changes) == 0 {
g.GitState = "clean"
} else {
g.GitState = "dirty"
}
log.WithValues("value", g.GitState).Info("set default value")
}
return nil
}
func (g *Global) gitOutput(args ...string) (string, error) {
cmd := exec.Command(g.GitPath, args...)
b, err := util.RunPrintCombined(log, cmd)
return strings.TrimSpace(string(b)), err
}