-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
242 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,116 @@ | ||
package rules | ||
|
||
import "github.com/jenkins-x/jx-promote/pkg/apis/boot/v1alpha1" | ||
import ( | ||
"io/ioutil" | ||
"path/filepath" | ||
"strings" | ||
"text/template" | ||
|
||
func MakefileRule(dir string, config *v1alpha1.Promote) error { | ||
"github.com/jenkins-x/jx-logging/pkg/log" | ||
"github.com/jenkins-x/jx/pkg/util" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
var ( | ||
makeLinePrefix = "\t" | ||
) | ||
|
||
// MakefileRule applies the Makefile rule to the file | ||
func MakefileRule(r *PromoteRule) error { | ||
config := r.Config | ||
if config.Spec.MakefileRule == nil { | ||
return errors.Errorf("no makefile rule configured") | ||
} | ||
rule := config.Spec.MakefileRule | ||
path := rule.Path | ||
if path == "" { | ||
path = "Makefile" | ||
} | ||
path = filepath.Join(r.Dir, path) | ||
exists, err := util.FileExists(path) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to check if file exists %s", path) | ||
} | ||
if !exists { | ||
return errors.Errorf("file does not exist: %s", path) | ||
} | ||
|
||
data, err := ioutil.ReadFile(path) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to read file %s", path) | ||
} | ||
|
||
lines := strings.Split(string(data), "\n") | ||
|
||
line, err := evaluateTemplate(r, rule.CommandTemplate) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to create Makefile statement") | ||
} | ||
line = makeLinePrefix + line | ||
updatePrefix, err := evaluateTemplate(r, rule.UpdatePrefixTemplate) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to create update prefix") | ||
} | ||
insertAfterPrefix := rule.InsertAfterPrefix | ||
|
||
updated := false | ||
if updatePrefix != "" { | ||
updatePrefix = makeLinePrefix + updatePrefix | ||
} | ||
if insertAfterPrefix != "" { | ||
insertAfterPrefix = makeLinePrefix + insertAfterPrefix | ||
} | ||
insertIdx := -1 | ||
for i, line := range lines { | ||
if updatePrefix != "" && strings.HasPrefix(line, updatePrefix) { | ||
updated = true | ||
lines[i] = line | ||
break | ||
} | ||
if insertAfterPrefix != "" && strings.HasPrefix(line, insertAfterPrefix) { | ||
insertIdx = i | ||
} | ||
} | ||
if insertIdx >= 0 { | ||
updated = true | ||
lines = insertItem(lines, insertIdx+1, line) | ||
} | ||
if !updated { | ||
lines = append(lines, line) | ||
} | ||
|
||
data = []byte(strings.Join(lines, "\n")) | ||
err = ioutil.WriteFile(path, data, util.DefaultFileWritePermissions) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to write file %s", path) | ||
} | ||
log.Logger().Infof("modified file %s", util.ColorInfo(path)) | ||
return nil | ||
} | ||
|
||
func insertItem(a []string, index int, value string) []string { | ||
if index >= len(a) { | ||
return append(a, value) | ||
} | ||
a = append(a[:index+1], a[index:]...) // index < len(a) | ||
a[index] = value | ||
return a | ||
} | ||
|
||
func evaluateTemplate(r *PromoteRule, templateText string) (string, error) { | ||
tmpl, err := template.New("test").Parse(templateText) | ||
if err != nil { | ||
return "", errors.Wrapf(err, "failed to parse go template: %s", templateText) | ||
} | ||
ctx := TemplateContext{ | ||
GitURL: r.GitURL, | ||
Version: r.Version, | ||
AppName: r.AppName, | ||
} | ||
buf := &strings.Builder{} | ||
err = tmpl.Execute(buf, &ctx) | ||
if err != nil { | ||
return buf.String(), errors.Wrapf(err, "failed to evaluate template with %#v", ctx) | ||
} | ||
return buf.String(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package rules | ||
|
||
import ( | ||
"io/ioutil" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/jenkins-x/jx-promote/pkg/promoteconfig" | ||
"github.com/jenkins-x/jx-promote/pkg/testhelpers" | ||
"github.com/jenkins-x/jx/pkg/util" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestMakefileRules(t *testing.T) { | ||
dir, err := ioutil.TempDir("", "") | ||
require.NoError(t, err, "could not make a temp dir") | ||
|
||
err = util.CopyDirOverwrite("test_data", dir) | ||
require.NoError(t, err, "could not copy source data to %s", dir) | ||
|
||
makefile := filepath.Join(dir, "Makefile") | ||
assert.FileExists(t, makefile) | ||
|
||
expectedFile := filepath.Join("test_data", "Makefile.1.expected") | ||
assert.FileExistsf(t, expectedFile, "should have expected file") | ||
|
||
config, _, err := promoteconfig.LoadPromote(dir, true) | ||
require.NoError(t, err, "failed to load config dir %s", dir) | ||
require.NotNil(t, config, "no project config found in dir %s", dir) | ||
require.NotNil(t, config.Spec.MakefileRule, "config.Spec.MakefileRule") | ||
require.NotEmpty(t, config.Spec.MakefileRule.InsertAfterPrefix, "config.Spec.MakefileRule.InsertAfterPrefix") | ||
require.NotEmpty(t, config.Spec.MakefileRule.UpdatePrefixTemplate, "config.Spec.MakefileRule.UpdatePrefixTemplate") | ||
require.NotEmpty(t, config.Spec.MakefileRule.CommandTemplate, "config.Spec.MakefileRule.CommandTemplate") | ||
|
||
r := &PromoteRule{ | ||
Dir: dir, | ||
Config: *config, | ||
GitURL: "https://github.com/myorg/myapp.git", | ||
Version: "1.2.3", | ||
AppName: "myapp", | ||
} | ||
|
||
err = MakefileRule(r) | ||
require.NoError(t, err, "failed to run MakefileRule at dir %s", dir) | ||
|
||
testhelpers.AssertTextFilesEqual(t, expectedFile, makefile, "makefile") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: promote.jenkins-x.io/v1alpha1 | ||
kind: Promote | ||
spec: | ||
makefileRule: | ||
insertAfterPrefix: "kpt pkg get" | ||
updatePrefixTemplate: "kpt pkg get {{.GitURL}}@" | ||
commandTemplate: "kpt pkg get {{.GitURL}}/kubernetess@v{{.Version}} $(FETCH_DIR)/namespaces/jx" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
FETCH_DIR := build/base | ||
OUTPUT_DIR := config-root | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf build $(OUTPUT_DIR) | ||
|
||
init: | ||
mkdir -p $(FETCH_DIR) | ||
mkdir -p $(OUTPUT_DIR)/namespaces/jx | ||
cp -r src/* build | ||
mkdir -p $(FETCH_DIR)/cluster/crds | ||
mkdir -p $(FETCH_DIR)/namespaces/nginx | ||
mkdir -p $(FETCH_DIR)/namespaces/vault-infra | ||
|
||
|
||
.PHONY: fetch | ||
fetch: init | ||
kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jx-labs/jenkins-x-crds@master $(FETCH_DIR)/cluster/crds | ||
- kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jenkins-x/jx@master $(FETCH_DIR)/namespaces/jx | ||
kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jenkins-x/jxboot-helmfile-resources@master $(FETCH_DIR)/namespaces/jx | ||
|
||
# this step is not required if using `helm template --namespace` for each chart | ||
jx-gitops namespace --dir-mode --dir $(FETCH_DIR)/namespaces |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
FETCH_DIR := build/base | ||
OUTPUT_DIR := config-root | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf build $(OUTPUT_DIR) | ||
|
||
init: | ||
mkdir -p $(FETCH_DIR) | ||
mkdir -p $(OUTPUT_DIR)/namespaces/jx | ||
cp -r src/* build | ||
mkdir -p $(FETCH_DIR)/cluster/crds | ||
mkdir -p $(FETCH_DIR)/namespaces/nginx | ||
mkdir -p $(FETCH_DIR)/namespaces/vault-infra | ||
|
||
|
||
.PHONY: fetch | ||
fetch: init | ||
kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jx-labs/jenkins-x-crds@master $(FETCH_DIR)/cluster/crds | ||
- kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jenkins-x/jx@master $(FETCH_DIR)/namespaces/jx | ||
kpt pkg get https://github.com/jenkins-x/jxr-kube-resources.git/jenkins-x/jxboot-helmfile-resources@master $(FETCH_DIR)/namespaces/jx | ||
kpt pkg get https://github.com/myorg/myapp.git/[email protected] $(FETCH_DIR)/namespaces/jx | ||
|
||
# this step is not required if using `helm template --namespace` for each chart | ||
jx-gitops namespace --dir-mode --dir $(FETCH_DIR)/namespaces |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package rules | ||
|
||
import "github.com/jenkins-x/jx-promote/pkg/apis/boot/v1alpha1" | ||
|
||
// PromoteRule represents a profile rule | ||
type PromoteRule struct { | ||
Dir string | ||
Config v1alpha1.Promote | ||
GitURL string | ||
Version string | ||
AppName string | ||
} | ||
|
||
// TemplateContext expressions used in templates | ||
type TemplateContext struct { | ||
GitURL string | ||
Version string | ||
AppName string | ||
} |