mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
feat (shellExecute) extend shellExecute to accept script arguments (#3823)
* adding arguments * splitting strings into args and checking position * addtional check on adding arguments * unit testing * refactoring code * unit test clean up * add unit test for multiple params in multiple scripts * unit test name Co-authored-by: anilkeshav27 <you@example.com>
This commit is contained in:
parent
5edb0d2566
commit
011ba40f87
@ -51,7 +51,7 @@ func shellExecute(config shellExecuteOptions, telemetryData *telemetry.CustomDat
|
||||
func runShellExecute(config *shellExecuteOptions, telemetryData *telemetry.CustomData, utils shellExecuteUtils) error {
|
||||
// check input data
|
||||
// example for script: sources: ["./script.sh"]
|
||||
for _, source := range config.Sources {
|
||||
for position, source := range config.Sources {
|
||||
|
||||
if strings.Contains(source, "https") {
|
||||
scriptLocation, err := downloadScript(config, utils, source)
|
||||
@ -70,9 +70,15 @@ func runShellExecute(config *shellExecuteOptions, telemetryData *telemetry.Custo
|
||||
log.Entry().WithError(err).Errorf("the script '%v' could not be found: %v", source, err)
|
||||
return fmt.Errorf("the script '%v' could not be found", source)
|
||||
}
|
||||
|
||||
args := []string{}
|
||||
if len(config.ScriptArguments) > 0 && isArgumentAtPosition(config.ScriptArguments, position) {
|
||||
args = strings.Split(config.ScriptArguments[position], " ")
|
||||
}
|
||||
|
||||
log.Entry().Info("starting running script:", source)
|
||||
|
||||
err = utils.RunExecutable(source)
|
||||
err = utils.RunExecutable(source, args...)
|
||||
if err != nil {
|
||||
log.Entry().Errorln("starting running script:", source)
|
||||
}
|
||||
@ -96,6 +102,10 @@ func runShellExecute(config *shellExecuteOptions, telemetryData *telemetry.Custo
|
||||
return nil
|
||||
}
|
||||
|
||||
func isArgumentAtPosition(scriptArguments []string, index int) bool {
|
||||
return ((len(scriptArguments) > index) && scriptArguments[index] != "")
|
||||
}
|
||||
|
||||
func downloadScript(config *shellExecuteOptions, utils shellExecuteUtils, url string) (string, error) {
|
||||
header := http.Header{}
|
||||
if len(config.GithubToken) > 0 {
|
||||
|
@ -16,8 +16,9 @@ import (
|
||||
)
|
||||
|
||||
type shellExecuteOptions struct {
|
||||
Sources []string `json:"sources,omitempty"`
|
||||
GithubToken string `json:"githubToken,omitempty"`
|
||||
Sources []string `json:"sources,omitempty"`
|
||||
GithubToken string `json:"githubToken,omitempty"`
|
||||
ScriptArguments []string `json:"scriptArguments,omitempty"`
|
||||
}
|
||||
|
||||
// ShellExecuteCommand Step executes defined script
|
||||
@ -112,6 +113,7 @@ func ShellExecuteCommand() *cobra.Command {
|
||||
func addShellExecuteFlags(cmd *cobra.Command, stepConfig *shellExecuteOptions) {
|
||||
cmd.Flags().StringSliceVar(&stepConfig.Sources, "sources", []string{}, "Scripts paths that must be present in the current workspace or https links to scripts. Only https urls from github are allowed and must be in the format :https://{githubBaseurl}/api/v3/repos/{owner}/{repository}/contents/{path to script} Authentication for the download is only supported via the 'githubToken' param. Make sure the script has the necessary execute permissions.")
|
||||
cmd.Flags().StringVar(&stepConfig.GithubToken, "githubToken", os.Getenv("PIPER_githubToken"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.ScriptArguments, "scriptArguments", []string{}, "scriptArguments that are needed to be passed to scripts. the scriptArguments list is a flat list and has a positional relationship to the `sources` param. For e.g. The scriptArguments string at position 1 will be considered as the argument(s) for script at position 1 in `sources` list")
|
||||
|
||||
}
|
||||
|
||||
@ -158,6 +160,15 @@ func shellExecuteMetadata() config.StepData {
|
||||
Aliases: []config.Alias{{Name: "access_token"}},
|
||||
Default: os.Getenv("PIPER_githubToken"),
|
||||
},
|
||||
{
|
||||
Name: "scriptArguments",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "[]string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: []string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []config.Container{
|
||||
|
@ -73,23 +73,21 @@ func TestRunShellExecute(t *testing.T) {
|
||||
assert.EqualError(t, err, "the script 'path/to/script.sh' could not be found")
|
||||
})
|
||||
|
||||
t.Run("success case - script is present", func(t *testing.T) {
|
||||
o := &shellExecuteOptions{}
|
||||
u := newShellExecuteTestsUtils()
|
||||
|
||||
err := runShellExecute(o, nil, u)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("success case - script run successfully", func(t *testing.T) {
|
||||
o := &shellExecuteOptions{}
|
||||
o := &shellExecuteOptions{
|
||||
Sources: []string{"path/script.sh"},
|
||||
}
|
||||
|
||||
u := newShellExecuteTestsUtils()
|
||||
u.AddFile("path/script.sh", []byte(`echo dummy`))
|
||||
|
||||
err := runShellExecute(o, nil, u)
|
||||
assert.Equal(t, "path/script.sh", u.ExecMockRunner.Calls[0].Exec)
|
||||
assert.Equal(t, []string{}, u.ExecMockRunner.Calls[0].Params)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("success case - download script header", func(t *testing.T) {
|
||||
t.Run("success case - download script header gets added", func(t *testing.T) {
|
||||
o := &shellExecuteOptions{
|
||||
Sources: []string{"https://myScriptLocation/myScript.sh"},
|
||||
GithubToken: "dummy@12345",
|
||||
@ -100,4 +98,42 @@ func TestRunShellExecute(t *testing.T) {
|
||||
|
||||
assert.Equal(t, http.Header{"Accept": []string{"application/vnd.github.v3.raw"}, "Authorization": []string{"Token dummy@12345"}}, u.header)
|
||||
})
|
||||
|
||||
t.Run("success case - single positional script arguments gets added to the correct script", func(t *testing.T) {
|
||||
o := &shellExecuteOptions{
|
||||
Sources: []string{"path1/script1.sh", "path2/script2.sh"},
|
||||
ScriptArguments: []string{"arg1", "arg2"},
|
||||
}
|
||||
|
||||
u := newShellExecuteTestsUtils()
|
||||
u.AddFile("path1/script1.sh", []byte(`echo dummy1`))
|
||||
u.AddFile("path2/script2.sh", []byte(`echo dummy2`))
|
||||
|
||||
err := runShellExecute(o, nil, u)
|
||||
|
||||
assert.Equal(t, "path1/script1.sh", u.ExecMockRunner.Calls[0].Exec)
|
||||
assert.Equal(t, []string{"arg1"}, u.ExecMockRunner.Calls[0].Params)
|
||||
assert.Equal(t, "path2/script2.sh", u.ExecMockRunner.Calls[1].Exec)
|
||||
assert.Equal(t, []string{"arg2"}, u.ExecMockRunner.Calls[1].Params)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("success case - multiple positional script arguments gets added to the correct script", func(t *testing.T) {
|
||||
o := &shellExecuteOptions{
|
||||
Sources: []string{"path1/script1.sh", "path2/script2.sh"},
|
||||
ScriptArguments: []string{"arg1 arg2", "arg3 arg4"},
|
||||
}
|
||||
|
||||
u := newShellExecuteTestsUtils()
|
||||
u.AddFile("path1/script1.sh", []byte(`echo dummy1`))
|
||||
u.AddFile("path2/script2.sh", []byte(`echo dummy2`))
|
||||
|
||||
err := runShellExecute(o, nil, u)
|
||||
|
||||
assert.Equal(t, "path1/script1.sh", u.ExecMockRunner.Calls[0].Exec)
|
||||
assert.Equal(t, []string{"arg1", "arg2"}, u.ExecMockRunner.Calls[0].Params)
|
||||
assert.Equal(t, "path2/script2.sh", u.ExecMockRunner.Calls[1].Exec)
|
||||
assert.Equal(t, []string{"arg3", "arg4"}, u.ExecMockRunner.Calls[1].Params)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
@ -36,6 +36,15 @@ spec:
|
||||
- type: vaultSecret
|
||||
default: github
|
||||
name: githubVaultSecretName
|
||||
- name: scriptArguments
|
||||
type: "[]string"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
description: scriptArguments that are needed to be passed to scripts. the scriptArguments list is a flat list and has a positional relationship to the `sources` param.
|
||||
For e.g. The scriptArguments string at position 1 will be considered as the argument(s) for script at position 1 in `sources` list
|
||||
mandatory: false
|
||||
containers:
|
||||
- name: shell
|
||||
image: node:lts-stretch
|
||||
|
Loading…
Reference in New Issue
Block a user