From 38c246341691b3f7177e0f42556141975db8f066 Mon Sep 17 00:00:00 2001
From: Matthew Holt <mholt@users.noreply.github.com>
Date: Mon, 18 Jul 2016 21:50:27 -0600
Subject: [PATCH] Fix ACME asset migration when renaming folders

---
 caddy/caddymain/run.go | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/caddy/caddymain/run.go b/caddy/caddymain/run.go
index 281f7d5ea..e83ecc173 100644
--- a/caddy/caddymain/run.go
+++ b/caddy/caddymain/run.go
@@ -188,18 +188,25 @@ func moveStorage() {
 		log.Fatalf("[ERROR] Unable to migrate certificate storage: %v\n\nPlease follow instructions at:\nhttps://github.com/mholt/caddy/issues/902#issuecomment-228876011", err)
 	}
 	// convert mixed case folder and file names to lowercase
-	filepath.Walk(string(newPath), func(path string, info os.FileInfo, err error) error {
-		// must be careful to only lowercase the base of the path, not the whole thing!!
-		base := filepath.Base(path)
-		if lowerBase := strings.ToLower(base); base != lowerBase {
-			lowerPath := filepath.Join(filepath.Dir(path), lowerBase)
-			err = os.Rename(path, lowerPath)
-			if err != nil {
-				log.Fatalf("[ERROR] Unable to lower-case: %v\n\nPlease follow instructions at:\nhttps://github.com/mholt/caddy/issues/902#issuecomment-228876011", err)
+	var done bool // walking is recursive and preloads the file names, so we must restart walk after a change until no changes
+	for !done {
+		done = true
+		filepath.Walk(string(newPath), func(path string, info os.FileInfo, err error) error {
+			// must be careful to only lowercase the base of the path, not the whole thing!!
+			base := filepath.Base(path)
+			if lowerBase := strings.ToLower(base); base != lowerBase {
+				lowerPath := filepath.Join(filepath.Dir(path), lowerBase)
+				err = os.Rename(path, lowerPath)
+				if err != nil {
+					log.Fatalf("[ERROR] Unable to lower-case: %v\n\nPlease follow instructions at:\nhttps://github.com/mholt/caddy/issues/902#issuecomment-228876011", err)
+				}
+				// terminate traversal and restart since Walk needs the updated file list with new file names
+				done = false
+				return errors.New("start over")
 			}
-		}
-		return nil
-	})
+			return nil
+		})
+	}
 }
 
 // setVersion figures out the version information