From 091db6afebd73adc95a3374b03ce735870239765 Mon Sep 17 00:00:00 2001
From: Toastie <toastie@toastiet0ast.com>
Date: Thu, 13 Feb 2025 14:44:03 +1300
Subject: [PATCH] Handle creds.yml placement in preparation for Ellie v6

---
 EllieHub/EllieHub.csproj                      |  2 +-
 .../BotConfig/Services/EllieResolver.cs       | 22 ++++++++++++++-----
 .../ViewModels/BotConfigViewModel.cs          |  3 ++-
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/EllieHub/EllieHub.csproj b/EllieHub/EllieHub.csproj
index 1104402..4f34f97 100644
--- a/EllieHub/EllieHub.csproj
+++ b/EllieHub/EllieHub.csproj
@@ -20,7 +20,7 @@
         <DebugType>embedded</DebugType>
 
         <!--Version-->
-        <VersionPrefix>1.0.4.0</VersionPrefix>
+        <VersionPrefix>1.0.5.0</VersionPrefix>
 
         <!--Avalonia Settings-->
         <ApplicationManifest>app.manifest</ApplicationManifest>
diff --git a/EllieHub/Features/BotConfig/Services/EllieResolver.cs b/EllieHub/Features/BotConfig/Services/EllieResolver.cs
index 085e9c0..a903774 100644
--- a/EllieHub/Features/BotConfig/Services/EllieResolver.cs
+++ b/EllieHub/Features/BotConfig/Services/EllieResolver.cs
@@ -167,7 +167,7 @@ public sealed partial class EllieResolver : IBotResolver
 
         try
         {
-            using var downloadStream = await http.GetStreamAsync(
+            await using var downloadStream = await http.GetStreamAsync(
                 await GetDownloadUrlAsync(latestVersion, cToken),
                 cToken
             );
@@ -185,11 +185,17 @@ public sealed partial class EllieResolver : IBotResolver
             // Update settings
             await _appConfigManager.UpdateBotEntryAsync(Id, x => x with { Version = latestVersion }, cToken);
 
-            // Create creds.yml
-            var credsUri = Path.Join(installationUri, "creds.yml");
+            // Create creds.yml if it doesn't exist
+            // Old versions have creds.yml and example in ./
+            // New versions have creds.yml and example in ./data/
+            // If downloaded bot has creds example in ./, create creds.yml to ./, else create to ./data/
+            var credsExampleUri = Directory.EnumerateFiles(installationUri, "creds_example.yml", SearchOption.AllDirectories)
+                .Last();
+
+            var credsUri = Path.Join(Directory.GetParent(credsExampleUri)?.FullName ?? Path.Join(installationUri, "data"), "creds.yml");
 
             if (!File.Exists(credsUri))
-                File.Copy(Path.Join(installationUri, "creds_example.yml"), credsUri);
+                File.Copy(Path.Join(installationUri, "data", "creds_example.yml"), credsUri);
 
             return (currentVersion, latestVersion);
         }
@@ -264,7 +270,13 @@ public sealed partial class EllieResolver : IBotResolver
                 .Prepend(Directory.GetParent(installationUri)?.FullName ?? string.Empty)
                 .ToArray();
 
-            await RestoreFileAsync(zippedFile, Path.Join(fileDestinationPath), cToken);
+            // Old versions have creds.yml and example in ./
+            // New versions have creds.yml and example in ./data/
+            // If downloaded bot has creds example in the root, restore creds.yml to root, else restore to ./data/
+            if (zippedFile.Name is "creds.yml" && !File.Exists(Path.Join(installationUri, "creds_example.yml")))
+                await RestoreFileAsync(zippedFile, Path.Join(installationUri, "data", zippedFile.Name), cToken);
+            else
+                await RestoreFileAsync(zippedFile, Path.Join(fileDestinationPath), cToken);
         }
     }
 
diff --git a/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs b/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
index 6806d20..f708b6c 100644
--- a/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
+++ b/EllieHub/Features/BotConfig/ViewModels/BotConfigViewModel.cs
@@ -261,8 +261,9 @@ public class BotConfigViewModel : ViewModelBase<BotConfigView>, IDisposable
     {
         try
         {
+            // Get result from inner directories first, for compatibility with creds.yml being in the root (old versions) and in the data folder (newer versions).
             var fileUri = Directory.EnumerateFiles(_appConfigManager.AppConfig.BotEntries[Resolver.Id].InstanceDirectoryUri, fileName, SearchOption.AllDirectories)
-                .First(x => x.Contains(fileName, StringComparison.Ordinal));
+                .Last();
 
             var process = Process.Start(new ProcessStartInfo()
             {