From bb14abbfc5caed1c069e8adefde540f87bd1a0d2 Mon Sep 17 00:00:00 2001
From: jaden <noreply@example.com>
Date: Mon, 26 Jun 2017 14:25:28 +0200
Subject: [PATCH] make sure project docs dir & all parent dirs exist

---
 gitlab/functions.sh | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/gitlab/functions.sh b/gitlab/functions.sh
index e716ea0..2d7cccc 100644
--- a/gitlab/functions.sh
+++ b/gitlab/functions.sh
@@ -210,11 +210,19 @@ dav_upload() {
 
 # Creates a folder at our intranet location via curl
 # $1: Path of the folder to create (e.g. private-upload/docs/test-folder)
+# $2: which HTTP response code it should return instead of exit on (e.g. 405 means the folder already exists)
 dav_mkdir() {
   local code=$(curl --location --silent --fail --write-out "%{http_code}" --user "${DOCUSER}:${DOCPASS}" -X MKCOL "${DOCSERVER}/${1}")
 
   if [[ ${code} == *204 || ${code} == *201 ]]; then
     log_info "curl: mkdir ${DOCSERVER}/${1}"
+  # if the return code was not a success, the function should usually treat it as an error.
+  # however, sometimes the codes must be treated more flexibly, e.g.:
+  # dav_recursive_mkdir wants the directory created *or* already existing,
+  # which means that a 405 (directory already exists) should not be treated as an error.
+  # other codes may also have similar consideration in the future.
+  elif [[ "${code}" == "$2" ]]; then
+    return "${code}"
   else
     log_error "Curl command finished with an error condition (code=${code}):"
     curl --location --silent --user "${DOCUSER}:${DOCPASS}" -X MKCOL "${DOCSERVER}/${1}"
@@ -223,6 +231,34 @@ dav_mkdir() {
 }
 
 
+# Creates a folder and all parent folders at a intranet location via curl (mkdir -p)
+# $1: Path of a folder to guarantee to be writeable (e.g. private-upload/docs/bob/bob.admin)
+dav_recursive_mkdir() {
+  log_info "curl: mkdir -p ${DOCSERVER}/${1}"
+
+  # split path into an array of path segments
+  # uses a subshell so setting the IFS doesnt mess up *this* shell
+  local path_segments=($(IFS=/ read -r -A arr <<< "$1"; echo "$arr"))
+  local current_subpath=''
+
+  # loop through segments
+  for seg in $path_segments; do
+    # append each segment to the current subpath
+    current_subpath="${current_subpath}${seg}/"
+
+    # make sure the current subpath folder is created
+    local response
+    # a 405 exit code is returned when the folder already exists
+    response=$(dav_mkdir "$current_subpath" 405)
+    if [[ "${response}" == "405" ]]; then
+      log_info "Directory ${current_subpath} already exists."
+    else
+      log_info "Directory ${current_subpath} did not exist and was created."
+    fi
+  done
+}
+
+
 # Deletes a file/folder from our intranet location via curl
 # $1: Path to the file/folder to delete (e.g. dist/myfile.whl)
 dav_delete() {
@@ -435,5 +471,12 @@ fi
 if [[ -n "${CI_COMMIT_TAG}" && "${IS_MASTER}" == "true" ]]; then
   DOC_UPLOADS+=("${DOC_SERVER_PREFIX}/stable/")
 fi
+
+# if the docs will be uploaded to at least one place,
+# make sure that the project folder will be available
+if [[ ${#DOC_UPLOADS[@]} -gt 0 ]]; then
+  dav_recursive_mkdir "${DOC_SERVER_PREFIX}"
+fi
+
 unset DOC_SERVER_PREFIX
 check_env DOC_UPLOADS
-- 
GitLab