From 6d272f8e7d76f891c1db3a8145105004e11eed40 Mon Sep 17 00:00:00 2001
From: Kamil Trzcinski <ayufan@ayufan.eu>
Date: Thu, 6 Jul 2017 16:57:34 +0200
Subject: [PATCH] Pass before_script and script as-is preserving arrays

---
 .../unreleased/pass-before-script-as-is.yml   |  4 ++
 lib/ci/gitlab_ci_yaml_processor.rb            |  2 +
 lib/gitlab/ci/build/step.rb                   |  3 +-
 spec/lib/ci/gitlab_ci_yaml_processor_spec.rb  | 47 ++++++++++++------
 spec/lib/gitlab/ci/build/step_spec.rb         | 49 +++++++++++++++----
 5 files changed, 80 insertions(+), 25 deletions(-)
 create mode 100644 changelogs/unreleased/pass-before-script-as-is.yml

diff --git a/changelogs/unreleased/pass-before-script-as-is.yml b/changelogs/unreleased/pass-before-script-as-is.yml
new file mode 100644
index 00000000000..ac6513dcff6
--- /dev/null
+++ b/changelogs/unreleased/pass-before-script-as-is.yml
@@ -0,0 +1,4 @@
+---
+title: Pass before_script and script as-is preserving arrays
+merge_request:
+author:
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index 56ad2c77c7d..cf3a0336792 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -80,6 +80,8 @@ module Ci
           artifacts: job[:artifacts],
           cache: job[:cache],
           dependencies: job[:dependencies],
+          before_script: job[:before_script],
+          script: job[:script],
           after_script: job[:after_script],
           environment: job[:environment]
         }.compact }
diff --git a/lib/gitlab/ci/build/step.rb b/lib/gitlab/ci/build/step.rb
index ee034d9cc56..411f67f8ce7 100644
--- a/lib/gitlab/ci/build/step.rb
+++ b/lib/gitlab/ci/build/step.rb
@@ -12,7 +12,8 @@ module Gitlab
         class << self
           def from_commands(job)
             self.new(:script).tap do |step|
-              step.script = job.commands.split("\n")
+              step.script = job.options[:before_script].to_a + job.options[:script].to_a
+              step.script = job.commands.split("\n") if step.script.empty?
               step.timeout = job.timeout
               step.when = WHEN_ON_SUCCESS
             end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index ef58ef1b0cd..ea79389e67e 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -163,7 +163,10 @@ module Ci
           commands: "pwd\nrspec",
           coverage_regex: nil,
           tag_list: [],
-          options: {},
+          options: {
+            before_script: ["pwd"],
+            script: ["rspec"]
+          },
           allow_failure: false,
           when: "on_success",
           environment: nil,
@@ -616,10 +619,12 @@ module Ci
             coverage_regex: nil,
             tag_list: [],
             options: {
-                image: { name: "ruby:2.1", entrypoint: ["/usr/local/bin/init", "run"] },
-                services: [{ name: "mysql" },
-                           { name: "docker:dind", alias: "docker", entrypoint: ["/usr/local/bin/init", "run"],
-                             command: ["/usr/local/bin/init", "run"] }]
+              before_script: ["pwd"],
+              script: ["rspec"],
+              image: { name: "ruby:2.1", entrypoint: ["/usr/local/bin/init", "run"] },
+              services: [{ name: "mysql" },
+                         { name: "docker:dind", alias: "docker", entrypoint: ["/usr/local/bin/init", "run"],
+                           command: ["/usr/local/bin/init", "run"] }]
             },
             allow_failure: false,
             when: "on_success",
@@ -649,10 +654,12 @@ module Ci
             coverage_regex: nil,
             tag_list: [],
             options: {
-                image: { name: "ruby:2.5", entrypoint: ["/usr/local/bin/init", "run"] },
-                services: [{ name: "postgresql", alias: "db-pg", entrypoint: ["/usr/local/bin/init", "run"],
-                             command: ["/usr/local/bin/init", "run"] },
-                           { name: "docker:dind" }]
+              before_script: ["pwd"],
+              script: ["rspec"],
+              image: { name: "ruby:2.5", entrypoint: ["/usr/local/bin/init", "run"] },
+              services: [{ name: "postgresql", alias: "db-pg", entrypoint: ["/usr/local/bin/init", "run"],
+                           command: ["/usr/local/bin/init", "run"] },
+                         { name: "docker:dind" }]
             },
             allow_failure: false,
             when: "on_success",
@@ -680,6 +687,8 @@ module Ci
             coverage_regex: nil,
             tag_list: [],
             options: {
+              before_script: ["pwd"],
+              script: ["rspec"],
               image: { name: "ruby:2.1" },
               services: [{ name: "mysql" }, { name: "docker:dind" }]
             },
@@ -707,8 +716,10 @@ module Ci
             coverage_regex: nil,
             tag_list: [],
             options: {
-                image: { name: "ruby:2.5" },
-                services: [{ name: "postgresql" }, { name: "docker:dind" }]
+              before_script: ["pwd"],
+              script: ["rspec"],
+              image: { name: "ruby:2.5" },
+              services: [{ name: "postgresql" }, { name: "docker:dind" }]
             },
             allow_failure: false,
             when: "on_success",
@@ -951,6 +962,8 @@ module Ci
           coverage_regex: nil,
           tag_list: [],
           options: {
+            before_script: ["pwd"],
+            script: ["rspec"],
             image: { name: "ruby:2.1" },
             services: [{ name: "mysql" }],
             artifacts: {
@@ -1162,7 +1175,9 @@ module Ci
             commands: "test",
             coverage_regex: nil,
             tag_list: [],
-            options: {},
+            options: {
+              script: ["test"]
+            },
             when: "on_success",
             allow_failure: false,
             environment: nil,
@@ -1208,7 +1223,9 @@ module Ci
             commands: "execute-script-for-job",
             coverage_regex: nil,
             tag_list: [],
-            options: {},
+            options: {
+              script: ["execute-script-for-job"]
+            },
             when: "on_success",
             allow_failure: false,
             environment: nil,
@@ -1221,7 +1238,9 @@ module Ci
             commands: "execute-script-for-job",
             coverage_regex: nil,
             tag_list: [],
-            options: {},
+            options: {
+              script: ["execute-script-for-job"]
+            },
             when: "on_success",
             allow_failure: false,
             environment: nil,
diff --git a/spec/lib/gitlab/ci/build/step_spec.rb b/spec/lib/gitlab/ci/build/step_spec.rb
index 49457b129e3..5a21282712a 100644
--- a/spec/lib/gitlab/ci/build/step_spec.rb
+++ b/spec/lib/gitlab/ci/build/step_spec.rb
@@ -1,21 +1,50 @@
 require 'spec_helper'
 
 describe Gitlab::Ci::Build::Step do
-  let(:job) { create(:ci_build, :no_options, commands: "ls -la\ndate") }
-
   describe '#from_commands' do
-    subject { described_class.from_commands(job) }
-
-    it 'fabricates an object' do
-      expect(subject.name).to eq(:script)
-      expect(subject.script).to eq(['ls -la', 'date'])
-      expect(subject.timeout).to eq(job.timeout)
-      expect(subject.when).to eq('on_success')
-      expect(subject.allow_failure).to be_falsey
+    shared_examples 'has correct script' do
+      subject { described_class.from_commands(job) }
+
+      it 'fabricates an object' do
+        expect(subject.name).to eq(:script)
+        expect(subject.script).to eq(script)
+        expect(subject.timeout).to eq(job.timeout)
+        expect(subject.when).to eq('on_success')
+        expect(subject.allow_failure).to be_falsey
+      end
+    end
+
+    context 'when commands are specified' do
+      it_behaves_like 'has correct script' do
+        let(:job) { create(:ci_build, :no_options, commands: "ls -la\ndate") }
+        let(:script) { ['ls -la', 'date'] }
+      end
+    end
+
+    context 'when script option is specified' do
+      it_behaves_like 'has correct script' do
+        let(:job) { create(:ci_build, :no_options, options: { script: ["ls -la\necho aaa", "date"] }) }
+        let(:script) { ["ls -la\necho aaa", 'date'] }
+      end
+    end
+
+    context 'when before and script option is specified' do
+      it_behaves_like 'has correct script' do
+        let(:job) do
+          create(:ci_build, options: {
+            before_script: ["ls -la\necho aaa"],
+            script: ["date"]
+          })
+        end
+
+        let(:script) { ["ls -la\necho aaa", 'date'] }
+      end
     end
   end
 
   describe '#from_after_script' do
+    let(:job) { create(:ci_build) }
+
     subject { described_class.from_after_script(job) }
 
     context 'when after_script is empty' do
-- 
GitLab