This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git

commit 45d20615ec9effd57bfbd18f7bbd43ca38617d83
Author: Yang Luo <[email protected]>
AuthorDate: Fri Sep 4 12:11:42 2026 +0800

    fix(hermes): write the model config to the home Hermes reads
---
 agent/scan_windows.go      |  8 +-----
 agentpatch/hermes_agent.go | 31 +---------------------
 agentprovider/hermes.go    |  8 +++---
 internal/hermes/home.go    | 65 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 41 deletions(-)

diff --git a/agent/scan_windows.go b/agent/scan_windows.go
index e1df2cf..9210cb9 100644
--- a/agent/scan_windows.go
+++ b/agent/scan_windows.go
@@ -162,13 +162,7 @@ func localAppData(home homeDir) string   { return 
appDataDir(home, "Local", "LOC
 func roamingAppData(home homeDir) string { return appDataDir(home, "Roaming", 
"APPDATA") }
 
 func scanHermesWindows(home homeDir) []Installation {
-       hermesHome := filepath.Join(localAppData(home), "hermes")
-       if isCurrentHome(home.path) {
-               if configured := os.Getenv("HERMES_HOME"); configured != "" {
-                       hermesHome = configured
-               }
-       }
-       root := filepath.Join(hermesHome, hermes.ProjectDir)
+       root := filepath.Join(hermes.Home(home.path), hermes.ProjectDir)
        launcher := filepath.Join(root, "venv", "Scripts", 
hermes.ExecName+".exe")
        return hermesInstallation(launcher, home.owner, root)
 }
diff --git a/agentpatch/hermes_agent.go b/agentpatch/hermes_agent.go
index 167fce1..b97d6de 100644
--- a/agentpatch/hermes_agent.go
+++ b/agentpatch/hermes_agent.go
@@ -251,18 +251,7 @@ func (hermesPatcher) layoutOf(target Target) 
(hermesLayout, error) {
        if err != nil {
                return hermesLayout{}, err
        }
-       hermesHome := filepath.Join(home, ".hermes")
-       if runtime.GOOS == "windows" {
-               hermesHome = filepath.Join(home, "AppData", "Local", "hermes")
-               if isProcessHome(home) {
-                       if local := os.Getenv("LOCALAPPDATA"); local != "" {
-                               hermesHome = filepath.Join(local, "hermes")
-                       }
-               }
-       }
-       if configured := os.Getenv("HERMES_HOME"); configured != "" && 
isProcessHome(home) {
-               hermesHome = configured
-       }
+       hermesHome := hermes.Home(home)
        return hermesLayout{
                home:       hermesHome,
                configPath: filepath.Join(hermesHome, "config.yaml"),
@@ -321,21 +310,3 @@ func readHermesObserverConfig(pluginDir string) 
(hermesObserverConfig, bool, err
        return config, config.Owner == "casbin-gateway" &&
                config.SchemaVersion == hermesConfigSchema, nil
 }
-
-func isProcessHome(home string) bool {
-       current, err := os.UserHomeDir()
-       if err != nil {
-               return false
-       }
-       left, right := filepath.Clean(home), filepath.Clean(current)
-       if resolved, err := filepath.EvalSymlinks(left); err == nil {
-               left = resolved
-       }
-       if resolved, err := filepath.EvalSymlinks(right); err == nil {
-               right = resolved
-       }
-       if runtime.GOOS == "windows" {
-               return strings.EqualFold(left, right)
-       }
-       return left == right
-}
diff --git a/agentprovider/hermes.go b/agentprovider/hermes.go
index e33783b..6eefaf4 100644
--- a/agentprovider/hermes.go
+++ b/agentprovider/hermes.go
@@ -18,7 +18,6 @@ import (
        "errors"
        "fmt"
        "os"
-       "path/filepath"
 
        "github.com/apache/casbin-gateway/agenthome"
        "github.com/apache/casbin-gateway/internal/hermes"
@@ -280,12 +279,13 @@ func (hermesWriter) save(path string, document 
*yamledit.Document) error {
        return changes.commit()
 }
 
-// configPath is the file Hermes reads its settings from, in the home directory
-// its own launcher keeps them in.
+// configPath is the file Hermes reads its settings from, in the Hermes home of
+// the installation's owner: %LOCALAPPDATA%\hermes on Windows, ~/.hermes
+// elsewhere.
 func (hermesWriter) configPath(target Target) (string, error) {
        home, err := agenthome.Resolve(target.Owner)
        if err != nil {
                return "", err
        }
-       return filepath.Join(home, ".hermes", "config.yaml"), nil
+       return hermes.ConfigPath(home), nil
 }
diff --git a/internal/hermes/home.go b/internal/hermes/home.go
new file mode 100644
index 0000000..5d61b91
--- /dev/null
+++ b/internal/hermes/home.go
@@ -0,0 +1,65 @@
+// Copyright 2026 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hermes
+
+import (
+       "os"
+       "path/filepath"
+       "runtime"
+       "strings"
+)
+
+// Home is the directory Hermes keeps config.yaml, its plugins and its
+// credentials in, for the user whose home directory is userHome. Windows
+// installs live under %LOCALAPPDATA%\hermes, every other platform under
+// ~/.hermes. HERMES_HOME and a relocated LOCALAPPDATA come from this process's
+// environment, so they only speak for the account Gateway runs as.
+func Home(userHome string) string {
+       current := isProcessHome(userHome)
+       home := filepath.Join(userHome, ".hermes")
+       if runtime.GOOS == "windows" {
+               home = filepath.Join(userHome, "AppData", "Local", "hermes")
+               if local := os.Getenv("LOCALAPPDATA"); local != "" && current {
+                       home = filepath.Join(local, "hermes")
+               }
+       }
+       if configured := os.Getenv("HERMES_HOME"); configured != "" && current {
+               home = configured
+       }
+       return home
+}
+
+// ConfigPath is the config.yaml Hermes reads its settings from.
+func ConfigPath(userHome string) string {
+       return filepath.Join(Home(userHome), "config.yaml")
+}
+
+func isProcessHome(home string) bool {
+       current, err := os.UserHomeDir()
+       if err != nil {
+               return false
+       }
+       left, right := filepath.Clean(home), filepath.Clean(current)
+       if resolved, err := filepath.EvalSymlinks(left); err == nil {
+               left = resolved
+       }
+       if resolved, err := filepath.EvalSymlinks(right); err == nil {
+               right = resolved
+       }
+       if runtime.GOOS == "windows" {
+               return strings.EqualFold(left, right)
+       }
+       return left == right
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to