From a6d99054be057fcd2c57b7bfb91a6ce5b046e08e Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Thu, 15 Jan 2026 11:44:56 -0800 Subject: [PATCH 1/2] use OS-specific config file paths --- .../io/temporal/envconfig/ClientConfig.java | 29 ++++++++++++++++++- .../envconfig/ClientConfigProfileTest.java | 21 ++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java b/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java index 798644b98..82e5e626a 100644 --- a/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java +++ b/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java @@ -32,12 +32,39 @@ public static ClientConfig getDefaultInstance() { return new ClientConfig.Builder().build(); } - /** Get the default config file path: $HOME/.config/temporalio/temporal.toml */ + /** + * Get the default config file path based on the operating system: + * + * + */ private static String getDefaultConfigFilePath() { String userDir = System.getProperty("user.home"); if (userDir == null || userDir.isEmpty()) { throw new RuntimeException("failed getting user home directory"); } + return getDefaultConfigFilePath(userDir, System.getProperty("os.name"), System.getenv()); + } + + static String getDefaultConfigFilePath( + String userDir, String osName, Map environment) { + if (osName != null) { + String osNameLower = osName.toLowerCase(); + if (osNameLower.contains("mac")) { + return userDir + "/Library/Application Support/temporalio/temporal.toml"; + } + if (osNameLower.contains("win")) { + String appData = environment != null ? environment.get("APPDATA") : null; + if (appData == null || appData.isEmpty()) { + throw new RuntimeException("%APPDATA% is not defined"); + } + return appData + "\\temporalio\\temporal.toml"; + } + } + // Default/fallback is Linux config file path. return userDir + "/.config/temporalio/temporal.toml"; } diff --git a/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java b/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java index 818845dde..01b6b32e9 100644 --- a/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java +++ b/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java @@ -302,6 +302,27 @@ public void loadClientConfigProfileMissingFileReturnsDefault() throws IOExceptio Assert.assertNull(profile.getNamespace()); } + @Test + public void defaultConfigFilePath() { + // macOS: ~/Library/Application Support + Assert.assertEquals( + "/Users/test/Library/Application Support/temporalio/temporal.toml", + ClientConfig.getDefaultConfigFilePath("/Users/test", "Mac OS X", Collections.emptyMap())); + + // Windows: %APPDATA% + Assert.assertEquals( + "C:\\Users\\test\\AppData\\Roaming\\temporalio\\temporal.toml", + ClientConfig.getDefaultConfigFilePath( + "C:\\Users\\test", + "Windows 10", + Collections.singletonMap("APPDATA", "C:\\Users\\test\\AppData\\Roaming"))); + + // Linux: ~/.config + Assert.assertEquals( + "/home/test/.config/temporalio/temporal.toml", + ClientConfig.getDefaultConfigFilePath("/home/test", "Linux", Collections.emptyMap())); + } + @Test public void parseToml() throws IOException { String toml = From c4c111f871dd36298aeb674a8c5d7ff546bae244 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Sun, 18 Jan 2026 14:19:42 -0800 Subject: [PATCH 2/2] address pr nits --- .../io/temporal/envconfig/ClientConfig.java | 30 ++++++++++--------- .../envconfig/ClientConfigProfileTest.java | 12 ++++---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java b/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java index 82e5e626a..f50aced72 100644 --- a/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java +++ b/temporal-envconfig/src/main/java/io/temporal/envconfig/ClientConfig.java @@ -5,11 +5,22 @@ import com.fasterxml.jackson.dataformat.toml.TomlMapper; import io.temporal.common.Experimental; import java.io.*; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Objects; -/** ClientConfig represents a client config file. */ +/** + * ClientConfig represents a client config file. + * + *

The default config file path is OS-specific: + * + *

    + *
  • macOS: $HOME/Library/Application Support/temporalio/temporal.toml + *
  • Windows: %APPDATA%\temporalio\temporal.toml + *
  • Linux/other: $HOME/.config/temporalio/temporal.toml + *
+ */ @Experimental public class ClientConfig { /** Creates a new builder to build a {@link ClientConfig}. */ @@ -32,15 +43,6 @@ public static ClientConfig getDefaultInstance() { return new ClientConfig.Builder().build(); } - /** - * Get the default config file path based on the operating system: - * - *
    - *
  • macOS: $HOME/Library/Application Support/temporalio/temporal.toml - *
  • Windows: %APPDATA%\temporalio\temporal.toml - *
  • Linux/other: $HOME/.config/temporalio/temporal.toml - *
- */ private static String getDefaultConfigFilePath() { String userDir = System.getProperty("user.home"); if (userDir == null || userDir.isEmpty()) { @@ -54,18 +56,18 @@ static String getDefaultConfigFilePath( if (osName != null) { String osNameLower = osName.toLowerCase(); if (osNameLower.contains("mac")) { - return userDir + "/Library/Application Support/temporalio/temporal.toml"; + return Paths.get(userDir, "Library", "Application Support", "temporalio", "temporal.toml") + .toString(); } if (osNameLower.contains("win")) { String appData = environment != null ? environment.get("APPDATA") : null; if (appData == null || appData.isEmpty()) { throw new RuntimeException("%APPDATA% is not defined"); } - return appData + "\\temporalio\\temporal.toml"; + return Paths.get(appData, "temporalio", "temporal.toml").toString(); } } - // Default/fallback is Linux config file path. - return userDir + "/.config/temporalio/temporal.toml"; + return Paths.get(userDir, ".config", "temporalio", "temporal.toml").toString(); } /** diff --git a/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java b/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java index 01b6b32e9..85c50159f 100644 --- a/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java +++ b/temporal-envconfig/src/test/java/io/temporal/envconfig/ClientConfigProfileTest.java @@ -7,6 +7,7 @@ import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import java.io.*; +import java.nio.file.Paths; import java.util.Collections; import org.junit.Assert; import org.junit.Test; @@ -306,20 +307,21 @@ public void loadClientConfigProfileMissingFileReturnsDefault() throws IOExceptio public void defaultConfigFilePath() { // macOS: ~/Library/Application Support Assert.assertEquals( - "/Users/test/Library/Application Support/temporalio/temporal.toml", + Paths.get("/Users/test", "Library", "Application Support", "temporalio", "temporal.toml") + .toString(), ClientConfig.getDefaultConfigFilePath("/Users/test", "Mac OS X", Collections.emptyMap())); // Windows: %APPDATA% Assert.assertEquals( - "C:\\Users\\test\\AppData\\Roaming\\temporalio\\temporal.toml", + Paths.get("C:/Users/test/AppData/Roaming", "temporalio", "temporal.toml").toString(), ClientConfig.getDefaultConfigFilePath( - "C:\\Users\\test", + "C:/Users/test", "Windows 10", - Collections.singletonMap("APPDATA", "C:\\Users\\test\\AppData\\Roaming"))); + Collections.singletonMap("APPDATA", "C:/Users/test/AppData/Roaming"))); // Linux: ~/.config Assert.assertEquals( - "/home/test/.config/temporalio/temporal.toml", + Paths.get("/home/test", ".config", "temporalio", "temporal.toml").toString(), ClientConfig.getDefaultConfigFilePath("/home/test", "Linux", Collections.emptyMap())); }