Repository navigation
Fix --home-dir log path and missing app folder errors - #1766
Conversation
mohnjiles
left a comment
There was a problem hiding this comment.
Two path-handling edge cases on the current head. The NLog layout case was reproduced on Windows with the pinned NLog 5.3.2; the Unix backslash case is based on static path analysis.
ionite34
left a comment
There was a problem hiding this comment.
Really nice PR, thanks! The --home-dir log fix with escaping plus tests is exactly right, and folding the three TryFindLibrary branches into LoadLibrary() is a good cleanup 🐺
One design ask before we approve: could LoadLibrary() skip calling EnsureAppDirectories(), so TryFindLibrary only finds and loads the library?
The fixes don't depend on that startup call. The places that open folders already handle it themselves:
OpenDirectoryShortcutcallsEnsureAppDirectories()right before opening.- Workflows and Outputs call it on load.
IOCommandsshows the not-found warning.
Those use-site calls also cover a folder deleted after startup, which the startup call can't. Without it there's no side effect hidden inside a method named Try/Find. Logs, AppData and Models already get created elsewhere: NLog, SetLibraryPath, SetupSharedModelFolders.
SettingsManagerDirectoriesTests would then call EnsureAppDirectories() directly instead of going through TryFindLibrary.
Happy to push that change on top if you'd prefer, just say so!
The NLog file target was hardcoded to %AppData%/StabilityMatrix/Logs, while the Settings "Logs" shortcut and the exception dialog's log zip read from Compat.AppDataHome/Logs. With --home-dir set, those diverged and the log folder never existed, throwing DirectoryNotFoundException. Also resolve a relative --home-dir to a full path so folder-browser calls and file:// URIs don't receive relative paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FileName and ArchiveFileName are parsed as NLog layouts, so a home
directory containing "${...}" (e.g. "${shortdate}") was rendered instead
of used literally, sending logs to a different folder than Settings and
the log zip read from. Escape the path with SimpleLayout.Escape.
Drop the backslash-to-slash rewrite: NLog treats backslashes literally
outside "${...}", and on Unix a backslash is a valid filename character.
Move file target setup into LogFileTarget.Create so it can be tested.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the hand-built AppDataHome/Logs and LibraryDir/Packages paths with named properties, so each well-known folder is defined in one place. No behavior change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Folders like Packages were only created on first use (e.g. the first package install), so Settings > App Folders > Packages crashed on a fresh library. Add SettingsManager.EnsureAppDirectories() as the one place that creates the app's well-known folders (AppDataHome, Logs, Packages, Workflows, Images, ExtensionPacks, and the default Models folder), and call it whenever the library is found. It runs after LoadSettings so a ModelDirectoryOverride is known; an override is never created since it may be on an unmounted drive. Images/Consolidated is left to the consolidate action, since Images subfolders show as Outputs categories. Failures are logged, not thrown. The three TryFindLibrary branches now share LoadLibrary(), and the Workflows and Outputs pages call EnsureAppDirectories() instead of creating their own folders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening a folder that doesn't exist threw from shell execute and showed the exception dialog. Add IOCommands.OpenFolderBrowserAsync and OpenFileBrowserAsync, which check the path first and show a "Folder not found" / "File not found" warning instead. They never create anything, so a genuinely missing package or model folder is reported, not hidden. The IOCommands browser commands use them. The Settings > App Folders shortcuts call EnsureAppDirectories() first, so app folders deleted while running are recreated, then open through the checked path. A missing ModelDirectoryOverride gets the notification. CreateLogFolderZip no longer throws if the Logs folder is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Folders are created where they are used, so TryFindLibrary only finds and loads the library. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
91e4095 to
c8bfb57
Compare
|
Valid point. Thought it might be good to enforce certain directories existing as an invariant at startup but probably better to keep the side-effects to a minimum if its too strict or not in the right spot for that and its getting smoothed over on access anyway. I made the corresponding changes, if anything else needs a correction or tweak go right ahead. |
Changes
--home-dir. The log file target is built fromCompat.AppDataHome, and the path is escaped withSimpleLayout.Escapeso NLog treats it literally. A relative--home-diris resolved to a full path.Compat.LogsDirandSettingsManager.PackagesDirectoryreplace the hand-built paths.SettingsManager.EnsureAppDirectories()creates the app's well-known folders: AppDataHome, Logs, Packages, Workflows, Images, ExtensionPacks and the default Models folder.LoadSettings. The threeTryFindLibrarybranches now shareLoadLibrary().Images/Consolidated.IOCommands.OpenFolderBrowserAsyncandOpenFileBrowserAsyncshow a "Folder not found" or "File not found" warning, and they never create anything. The Settings → App Folders shortcuts callEnsureAppDirectories()before opening.CreateLogFolderZiphandles a missing Logs folder.Testing
LogFileTargetTestsandSettingsManagerDirectoriesTests.--home-dirset to a folder named${shortdate}: logs, the Packages and Logs shortcuts, and recreating deleted folders.TestGetInstalledExtensionsLiteAsync) also fails onmain.Note: other hardcoded paths that could drift (not changed here)
LibraryDir/Packages/<name>is built by hand inPackageInstallDetailViewModel, both one-click install view models andBaseGitPackage.DownloadLocation. These could usePackagesDirectory.LibraryPathvalues use a literal"Packages"in about 7 places.PackageInstallDetailViewModelandIndexUnknownPackagescompareLibraryPathas plain strings using the current OS separator. They could miss matches for a library moved between Windows and Unix. This hasn't been reproduced.GlobalConfig.ModelsDiris set before settings load, so it ignores aModelDirectoryOverride.🤖 Generated with Claude Code