From 3144a467e9f62e347b99c2ddea327f20ab3d08d1 Mon Sep 17 00:00:00 2001
From: Tomasz Maczukin <tomasz@maczukin.pl>
Date: Tue, 11 Jul 2017 20:11:54 +0200
Subject: [PATCH] Introduce updated syntax in gitlab_ci_yaml_parser

---
 common/network.go                            |  1 -
 helpers/gitlab_ci_yaml_parser/data_bag.go    | 14 ++++++++++
 helpers/gitlab_ci_yaml_parser/parser.go      | 29 +++++++-------------
 helpers/gitlab_ci_yaml_parser/parser_test.go | 23 +++++++++-------
 4 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/common/network.go b/common/network.go
index c09dda5d7..3f9f52a5c 100644
--- a/common/network.go
+++ b/common/network.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"io"
-	"strings"
 
 	"gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers/url"
 )
diff --git a/helpers/gitlab_ci_yaml_parser/data_bag.go b/helpers/gitlab_ci_yaml_parser/data_bag.go
index c76f76e3b..af46fc9f2 100644
--- a/helpers/gitlab_ci_yaml_parser/data_bag.go
+++ b/helpers/gitlab_ci_yaml_parser/data_bag.go
@@ -22,6 +22,20 @@ func (m *DataBag) GetSlice(keys ...string) ([]interface{}, bool) {
 	return nil, false
 }
 
+func (m *DataBag) GetStringSlice(keys ...string) (slice []string, ok bool) {
+	rawSlice, ok := m.GetSlice(keys...)
+	if !ok {
+		return
+	}
+
+	for _, rawElement := range rawSlice {
+		if element, ok := rawElement.(string); ok {
+			slice = append(slice, element)
+		}
+	}
+	return
+}
+
 func (m *DataBag) GetSubOptions(keys ...string) (result DataBag, ok bool) {
 	value, ok := helpers.GetMapKey(*m, keys...)
 	if ok {
diff --git a/helpers/gitlab_ci_yaml_parser/parser.go b/helpers/gitlab_ci_yaml_parser/parser.go
index 7f5aa5dbc..c3f0f53bc 100644
--- a/helpers/gitlab_ci_yaml_parser/parser.go
+++ b/helpers/gitlab_ci_yaml_parser/parser.go
@@ -223,7 +223,7 @@ func (c *GitLabCiYamlParser) prepareImage(job *common.JobResponse) (err error) {
 
 	if imageDefinition, ok := c.jobConfig.GetSubOptions("image"); ok {
 		job.Image.Name, _ = imageDefinition.GetString("name")
-		job.Image.Entrypoint, _ = imageDefinition.GetString("entrypoint")
+		job.Image.Entrypoint, _ = imageDefinition.GetStringSlice("entrypoint")
 		return
 	}
 
@@ -234,33 +234,24 @@ func (c *GitLabCiYamlParser) prepareImage(job *common.JobResponse) (err error) {
 
 	if imageDefinition, ok := c.config.GetSubOptions("image"); ok {
 		job.Image.Name, _ = imageDefinition.GetString("name")
+		job.Image.Entrypoint, _ = imageDefinition.GetStringSlice("entrypoint")
 		return
 	}
 
 	return
 }
 
-func parseExtendedServiceDefinitionMap(serviceDefinition map[interface{}]interface{}) common.Image {
-	var name, alias, command, entrypoint string
+func parseExtendedServiceDefinitionMap(serviceDefinition map[interface{}]interface{}) (image common.Image) {
+	service := make(DataBag)
 	for key, value := range serviceDefinition {
-		switch key {
-		case "name":
-			name = value.(string)
-		case "alias":
-			alias = value.(string)
-		case "command":
-			command = value.(string)
-		case "entrypoint":
-			entrypoint = value.(string)
-		}
+		service[key.(string)] = value
 	}
 
-	return common.Image{
-		Name:       name,
-		Alias:      alias,
-		Command:    command,
-		Entrypoint: entrypoint,
-	}
+	image.Name, _ = service.GetString("name")
+	image.Alias, _ = service.GetString("alias")
+	image.Command, _ = service.GetStringSlice("command")
+	image.Entrypoint, _ = service.GetStringSlice("entrypoint")
+	return
 }
 
 func (c *GitLabCiYamlParser) prepareServices(job *common.JobResponse) (err error) {
diff --git a/helpers/gitlab_ci_yaml_parser/parser_test.go b/helpers/gitlab_ci_yaml_parser/parser_test.go
index 57bc79576..d128df3c6 100644
--- a/helpers/gitlab_ci_yaml_parser/parser_test.go
+++ b/helpers/gitlab_ci_yaml_parser/parser_test.go
@@ -34,26 +34,27 @@ job4:
   script: job4
   image:
     name: alpine
-    entrypoint: /bin/sh
+    entrypoint: ["/bin/sh"]
   services:
   - name: service:1
-    command: sleep 30
+    command: ["sleep", "30"]
     alias: service-1
   - name: service:2
-    entrypoint: /bin/sh
+    entrypoint: ["/bin/sh"]
     alias: service-2
 `
 
 var testFile2 = `
 image:
   name: global:image
+  entrypoint: [/bin/sh]
 
 services:
 - name: service:1
-  command: sleep 30
+  command: ["sleep", "30"]
   alias: service-1
 - name: service:2
-  entrypoint: /bin/sh
+  entrypoint: [/bin/sh]
   alias: service-2
 
 job1:
@@ -126,33 +127,35 @@ func TestFileParsing(t *testing.T) {
 	// file1 - job4
 	jobResponse = getJobResponse(t, testFile1, "job4", false)
 	assert.Equal(t, "alpine", jobResponse.Image.Name)
-	assert.Equal(t, "/bin/sh", jobResponse.Image.Entrypoint)
+	assert.Equal(t, []string{"/bin/sh"}, jobResponse.Image.Entrypoint)
 	require.Len(t, jobResponse.Services, 2)
 	assert.Equal(t, "service:1", jobResponse.Services[0].Name)
 	assert.Equal(t, "service-1", jobResponse.Services[0].Alias)
-	assert.Equal(t, "sleep 30", jobResponse.Services[0].Command)
+	assert.Equal(t, []string{"sleep", "30"}, jobResponse.Services[0].Command)
 	assert.Empty(t, jobResponse.Services[0].Entrypoint)
 	assert.Equal(t, "service:2", jobResponse.Services[1].Name)
 	assert.Equal(t, "service-2", jobResponse.Services[1].Alias)
 	assert.Empty(t, jobResponse.Services[1].Command)
-	assert.Equal(t, "/bin/sh", jobResponse.Services[1].Entrypoint)
+	assert.Equal(t, []string{"/bin/sh"}, jobResponse.Services[1].Entrypoint)
 
 	// file2 - job1
 	jobResponse = getJobResponse(t, testFile2, "job1", false)
 	assert.Equal(t, "global:image", jobResponse.Image.Name)
+	assert.Equal(t, []string{"/bin/sh"}, jobResponse.Image.Entrypoint)
 	require.Len(t, jobResponse.Services, 2)
 	assert.Equal(t, "service:1", jobResponse.Services[0].Name)
 	assert.Equal(t, "service-1", jobResponse.Services[0].Alias)
-	assert.Equal(t, "sleep 30", jobResponse.Services[0].Command)
+	assert.Equal(t, []string{"sleep", "30"}, jobResponse.Services[0].Command)
 	assert.Empty(t, jobResponse.Services[0].Entrypoint)
 	assert.Equal(t, "service:2", jobResponse.Services[1].Name)
 	assert.Equal(t, "service-2", jobResponse.Services[1].Alias)
 	assert.Empty(t, jobResponse.Services[1].Command)
-	assert.Equal(t, "/bin/sh", jobResponse.Services[1].Entrypoint)
+	assert.Equal(t, []string{"/bin/sh"}, jobResponse.Services[1].Entrypoint)
 
 	// file2 - job2
 	jobResponse = getJobResponse(t, testFile2, "job2", false)
 	assert.Equal(t, "job2:image", jobResponse.Image.Name)
+	assert.Empty(t, jobResponse.Image.Entrypoint)
 	require.Len(t, jobResponse.Services, 2)
 	assert.Equal(t, "service:1", jobResponse.Services[0].Name)
 	assert.Empty(t, jobResponse.Services[0].Alias)
-- 
GitLab