From b882a109376d53c8b319d2dd44f2c0a92fdb4d2e Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Thu, 17 Mar 2022 23:14:13 +0100 Subject: [PATCH] feat: allow denormalization to target systems --- go.mod | 2 +- go.sum | 4 ---- pkg/azuredevops/azuredevops.go | 5 +++++ pkg/cmd/root.go | 4 +++- pkg/cmd/run.go | 20 +++++++++++++---- pkg/common/common.go | 1 + pkg/githubactions/githubactions.go | 5 +++++ pkg/gitlabci/gitlabci.go | 5 +++++ pkg/localgit/localgit.go | 5 +++++ pkg/ncispec/spec_v1.go | 8 +++---- pkg/normalizeci/normalizeci.go | 36 +++++++++++++++++++++++------- 11 files changed, 73 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index ced1161..a263d92 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cidverse/normalizeci -go 1.17 +go 1.18 require ( github.com/Masterminds/semver/v3 v3.1.1 diff --git a/go.sum b/go.sum index 8ef54d6..f4de012 100644 --- a/go.sum +++ b/go.sum @@ -258,7 +258,6 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -534,11 +533,9 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -749,7 +746,6 @@ google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUb google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= diff --git a/pkg/azuredevops/azuredevops.go b/pkg/azuredevops/azuredevops.go index a0568a5..bc5240d 100644 --- a/pkg/azuredevops/azuredevops.go +++ b/pkg/azuredevops/azuredevops.go @@ -24,6 +24,11 @@ func (n Normalizer) GetName() string { return n.name } +// GetSlug returns the slug of the normalizer +func (n Normalizer) GetSlug() string { + return n.slug +} + // Check if this package can handle the current environment func (n Normalizer) Check(env map[string]string) bool { if env["TF_BUILD"] == "True" { diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index dbe097b..581cf8b 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -34,8 +34,9 @@ var rootCmd = &cobra.Command{ output, _ := cmd.Flags().GetString("output") hostEnv, _ := cmd.Flags().GetBool("hostEnv") strict, _ := cmd.Flags().GetBool("strict") + targets, _ := cmd.Flags().GetStringArray("target") - normalizationCommand(format, hostEnv, output, strict) + normalizationCommand(format, hostEnv, output, strict, targets) }, } @@ -45,6 +46,7 @@ func init() { rootCmd.PersistentFlags().Bool("hostenv", false, "Should include os env along with normalized variables into the target?") rootCmd.PersistentFlags().Bool("strict", false, "Validate the generated variables against the spec and fail on errors?") rootCmd.PersistentFlags().BoolP("version", "v", false, "all software has versions, this prints version information for normalizeci") + rootCmd.PersistentFlags().StringArrayP("target", "t", []string{}, "Additionally generates the environment for the target ci services") } // Execute executes the root command. diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 5b00659..e27b470 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -8,20 +8,32 @@ import ( "os" ) -func normalizationCommand(format string, hostEnv bool, output string, strict bool) { +func normalizationCommand(format string, hostEnv bool, output string, strict bool, targets []string) { // run normalization var normalizedEnv = normalizeci.RunDefaultNormalization() - normalizeci.ConfigureProcessEnvironment(normalizedEnv) - // set normalized variables in current session var nci = ncispec.OfMap(normalizedEnv) if hostEnv == false { nci.DATA = nil // exclude hostEnv from generation } - content := normalizeci.FormatEnvironment(ncispec.ToMap(nci), format) + outputEnv := ncispec.ToMap(nci) + + // set process env + normalizeci.SetProcessEnvironment(normalizedEnv) + + // targets + if len(targets) > 0 { + for _, target := range targets { + denormalized := normalizeci.RunDenormalization(target, normalizedEnv) + for key, value := range denormalized { + outputEnv[key] = value + } + } + } // content? + content := normalizeci.FormatEnvironment(outputEnv, format) if len(content) == 0 { log.Error().Msg("unsupported format!") os.Exit(1) diff --git a/pkg/common/common.go b/pkg/common/common.go index 10668ef..2c01e3d 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -11,6 +11,7 @@ import ( // Normalizer is a common interface to work with all normalizers type Normalizer interface { GetName() string + GetSlug() string Check(env map[string]string) bool Normalize(env map[string]string) map[string]string Denormalize(env map[string]string) map[string]string diff --git a/pkg/githubactions/githubactions.go b/pkg/githubactions/githubactions.go index 90a33ef..b0aadae 100644 --- a/pkg/githubactions/githubactions.go +++ b/pkg/githubactions/githubactions.go @@ -24,6 +24,11 @@ func (n Normalizer) GetName() string { return n.name } +// GetSlug returns the slug of the normalizer +func (n Normalizer) GetSlug() string { + return n.slug +} + // Check if this package can handle the current environment func (n Normalizer) Check(env map[string]string) bool { if env["GITHUB_ACTIONS"] == "true" { diff --git a/pkg/gitlabci/gitlabci.go b/pkg/gitlabci/gitlabci.go index 565571a..27cfc0b 100644 --- a/pkg/gitlabci/gitlabci.go +++ b/pkg/gitlabci/gitlabci.go @@ -21,6 +21,11 @@ func (n Normalizer) GetName() string { return n.name } +// GetSlug returns the slug of the normalizer +func (n Normalizer) GetSlug() string { + return n.slug +} + // Check if this package can handle the current environment func (n Normalizer) Check(env map[string]string) bool { if env["GITLAB_CI"] == "true" { diff --git a/pkg/localgit/localgit.go b/pkg/localgit/localgit.go index 8c8ab9a..2e663aa 100644 --- a/pkg/localgit/localgit.go +++ b/pkg/localgit/localgit.go @@ -23,6 +23,11 @@ func (n Normalizer) GetName() string { return n.name } +// GetSlug returns the slug of the normalizer +func (n Normalizer) GetSlug() string { + return n.slug +} + // Check if this package can handle the current environment func (n Normalizer) Check(env map[string]string) bool { return true diff --git a/pkg/ncispec/spec_v1.go b/pkg/ncispec/spec_v1.go index 685eeb4..9318a6d 100644 --- a/pkg/ncispec/spec_v1.go +++ b/pkg/ncispec/spec_v1.go @@ -112,10 +112,10 @@ type NormalizeCISpec struct { NCI_COMMIT_DESCRIPTION string // The description of the latest commit on the current reference. NCI_COMMIT_COUNT string `validate:"required"` // The total amount of commits inside of the current reference, can be used as build number. - NCI_LASTRELEASE_REF_NAME string // Human readable name of the last stable release. - NCI_LASTRELEASE_REF_SLUG string // Slug of the last stable release. - NCI_LASTRELEASE_REF_VCS string // Holds the vcs specific absolute reference name of the last stable release. (ex: `refs/heads/main`) - NCI_LASTRELEASE_COMMIT_AFTER_COUNT string // Holds the count of commits since the last stable release. + NCI_LASTRELEASE_REF_NAME string `validate:"required"` // Human readable name of the last stable release. + NCI_LASTRELEASE_REF_SLUG string `validate:"required"` // Slug of the last stable release. + NCI_LASTRELEASE_REF_VCS string `validate:"required"` // Holds the vcs specific absolute reference name of the last stable release. (ex: `refs/heads/main`) + NCI_LASTRELEASE_COMMIT_AFTER_COUNT string `validate:"required"` // Holds the count of commits since the last stable release. NCI_DEPLOY_FREEZE string `validate:"required,boolean"` // Currently in a deploy freeze window? (`true`, `false`) } diff --git a/pkg/normalizeci/normalizeci.go b/pkg/normalizeci/normalizeci.go index a0a3496..df31194 100644 --- a/pkg/normalizeci/normalizeci.go +++ b/pkg/normalizeci/normalizeci.go @@ -14,6 +14,16 @@ import ( "github.com/cidverse/normalizeci/pkg/localgit" ) +// holds all known normalizers +var normalizers []common.Normalizer + +func init() { + normalizers = append(normalizers, azuredevops.NewNormalizer()) + normalizers = append(normalizers, githubactions.NewNormalizer()) + normalizers = append(normalizers, gitlabci.NewNormalizer()) + normalizers = append(normalizers, localgit.NewNormalizer()) +} + func RunDefaultNormalization() map[string]string { env := common.GetMachineEnvironment() return RunNormalization(env) @@ -21,13 +31,6 @@ func RunDefaultNormalization() map[string]string { // RunNormalization executes the ci normalization for all supported services func RunNormalization(env map[string]string) map[string]string { - // initialize normalizers - var normalizers []common.Normalizer - normalizers = append(normalizers, azuredevops.NewNormalizer()) - normalizers = append(normalizers, githubactions.NewNormalizer()) - normalizers = append(normalizers, gitlabci.NewNormalizer()) - normalizers = append(normalizers, localgit.NewNormalizer()) - // normalize (iterate over all supported systems and normalize variables if possible) var normalized map[string]string for _, normalizer := range normalizers { @@ -43,6 +46,23 @@ func RunNormalization(env map[string]string) map[string]string { return normalized } +// RunDenormalization will generate ci variables for the target service +func RunDenormalization(target string, env map[string]string) map[string]string { + // denormalize + var normalized map[string]string + for _, normalizer := range normalizers { + if target == normalizer.GetSlug() { + log.Debug().Msg("Matched " + normalizer.GetName() + ", not checking for any other matches.") + normalized = normalizer.Denormalize(env) + break + } else { + log.Debug().Msg("Didn't match in " + normalizer.GetName()) + } + } + + return normalized +} + // FormatEnvironment makes the normalized environment available in the current session func FormatEnvironment(normalized map[string]string, format string) string { if format == "export" { @@ -66,7 +86,7 @@ func GetDefaultFormat() string { return "" } -func ConfigureProcessEnvironment(normalized map[string]string) { +func SetProcessEnvironment(normalized map[string]string) { for key, element := range normalized { err := os.Setenv(key, element) if err != nil {