Do git submodule preparation in git
Ansible's performance was disappointing, so let's try to see if I can do
it better in pure shell. `jq` provides access to the repository
structure as exported from Zuul's variable via an intermediate JSON
file.
Change-Id: If420fe6f39eb29f8791551b7240938bbdc5d66b3
diff --git a/playbooks/git-submodules/run.yaml b/playbooks/git-submodules/run.yaml
index 475d677..27a7948 100644
--- a/playbooks/git-submodules/run.yaml
+++ b/playbooks/git-submodules/run.yaml
@@ -1,32 +1,32 @@
- hosts: all
tasks:
+ - name: Prepare git submodules
+ shell: |
+ set -ex
- - name: Point the "origin" git remote to its filesystem location
- shell: git config --get remote.origin.url > /dev/null && git config remote.origin.url "{{ ansible_user_dir }}/{{ item.src_dir}}" || true
- args:
- chdir: "{{ ansible_user_dir }}/{{ item.src_dir}}"
- with_items: "{{ zuul.projects.values() | list }}"
+ 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
- # 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.
- - name: Prepare path/to/foo.git repository aliases for each path/to/foo repository
- file:
- src: "{{ ansible_user_dir }}/{{ item.src_dir}}"
- dest: "{{ ansible_user_dir }}/{{ item.src_dir}}.git"
- state: link
- with_items: "{{ zuul.projects.values() | list }}"
+ # 3) Update submodules via calling out to git
+ cd "$(jq -r '.project.src_dir' ~/zuul-env.json)"
+ git submodule update --init --recursive
- - name: Recursively prepare git submodules of the main project
- shell: git submodule update --init --recursive
- args:
- chdir: "{{ ansible_user_dir }}/{{ zuul.project.src_dir}}"
-
- - name: Set the "origin" git remote back to Zuul's fake /dev/null
- shell: git config --get remote.origin.url > /dev/null && git config remote.origin.url file:///dev/null || true
- args:
- chdir: "{{ ansible_user_dir }}/{{ item.src_dir}}"
- with_items: "{{ zuul.projects.values() | list }}"
+ # 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