Rework jobs/playbooks/roles

Current setup doesn't work that well when inheriting. I would like "all
my projects" to only inherit from the job which uses the
`run-test-command` playbook. Then, those jobs which need submodules,
should explicitly ask for that pre- playbook provided by
`git-submodules`.

In Zuul and Ansible, roles are the bits that are supposed to be shared.
As per corvus recommendation on IRC, let's use job variables to control
execution in a more fine-grained manner.

Change-Id: I48c13bff0be7cf796b75e5176774226fb3bb5cc8
diff --git a/roles/git-submodules/meta/main.yaml b/roles/git-submodules/meta/main.yaml
new file mode 100644
index 0000000..7767619
--- /dev/null
+++ b/roles/git-submodules/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+  - role: zuul-var-to-json
diff --git a/roles/git-submodules/tasks/main.yaml b/roles/git-submodules/tasks/main.yaml
new file mode 100644
index 0000000..100de13
--- /dev/null
+++ b/roles/git-submodules/tasks/main.yaml
@@ -0,0 +1,30 @@
+- name: Prepare git submodules
+  shell: |
+    set -ex
+
+    jq -r '.projects | .[] | .src_dir ' ~/zuul-env.json | while read PROJECT; do
+      pushd "{{ ansible_user_dir }}/${PROJECT}"
+      # 1) Adjust the origin's URL so that it points to its filesystem location.
+      # This makes relative URLs in submodules work.
+      git config --get remote.origin.url > /dev/null && git config remote.origin.url "{{ ansible_user_dir }}/${PROJECT}" || true
+      # 2) Prepare an alias for each repository, appending the .git suffix.
+      # E.g. Boost uses submodule URLs which end with a .git trailing suffix.
+      # That happens to be handled by many git servers automagically.
+      # Instead of rewriting the submodule URLs within each repo (which would either mark
+      # the repo dirty, or change its hash), use a big hammer and provide these
+      # "compatibility" repository names.
+      # If both a `repo` and `repo.git` already exist, then we're screwed.
+      ln -s $(basename "${PROJECT}") ../$(basename "${PROJECT}").git
+      popd
+    done
+
+    # 3) Update submodules via calling out to git
+    cd "$(jq -r '.project.src_dir' ~/zuul-env.json)"
+    git submodule update --init --recursive
+
+    # 4) Undo changes made in step 1
+    jq -r '.projects | .[] | .src_dir ' ~/zuul-env.json | while read PROJECT; do
+      pushd "{{ ansible_user_dir }}/${PROJECT}"
+      git config --get remote.origin.url > /dev/null && git config remote.origin.url file:///dev/null || true
+      popd
+    done
diff --git a/roles/run-test-command/meta/main.yaml b/roles/run-test-command/meta/main.yaml
new file mode 100644
index 0000000..7767619
--- /dev/null
+++ b/roles/run-test-command/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+  - role: zuul-var-to-json
diff --git a/roles/run-test-command/tasks/main.yaml b/roles/run-test-command/tasks/main.yaml
new file mode 100644
index 0000000..1f16aa6
--- /dev/null
+++ b/roles/run-test-command/tasks/main.yaml
@@ -0,0 +1,4 @@
+- name: Run test_command
+  command: '{{ test_command }}'
+  args:
+    chdir: '{{ zuul.project.src_dir }}'
diff --git a/roles/zuul-var-to-json/tasks/main.yaml b/roles/zuul-var-to-json/tasks/main.yaml
new file mode 100644
index 0000000..5d6e1d7
--- /dev/null
+++ b/roles/zuul-var-to-json/tasks/main.yaml
@@ -0,0 +1,4 @@
+- name: Export Zuul variables into JSON
+  copy:
+    dest: '{{ ansible_user_dir }}/zuul-env.json'
+    content: '{{ zuul | to_json }}'