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..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,13 +43,31 @@ public static ClientConfig getDefaultInstance() {
return new ClientConfig.Builder().build();
}
- /** Get the default config file path: $HOME/.config/temporalio/temporal.toml */
private static String getDefaultConfigFilePath() {
String userDir = System.getProperty("user.home");
if (userDir == null || userDir.isEmpty()) {
throw new RuntimeException("failed getting user home directory");
}
- return userDir + "/.config/temporalio/temporal.toml";
+ 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 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 Paths.get(appData, "temporalio", "temporal.toml").toString();
+ }
+ }
+ 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 818845dde..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;
@@ -302,6 +303,28 @@ public void loadClientConfigProfileMissingFileReturnsDefault() throws IOExceptio
Assert.assertNull(profile.getNamespace());
}
+ @Test
+ public void defaultConfigFilePath() {
+ // macOS: ~/Library/Application Support
+ Assert.assertEquals(
+ Paths.get("/Users/test", "Library", "Application Support", "temporalio", "temporal.toml")
+ .toString(),
+ ClientConfig.getDefaultConfigFilePath("/Users/test", "Mac OS X", Collections.emptyMap()));
+
+ // Windows: %APPDATA%
+ Assert.assertEquals(
+ Paths.get("C:/Users/test/AppData/Roaming", "temporalio", "temporal.toml").toString(),
+ ClientConfig.getDefaultConfigFilePath(
+ "C:/Users/test",
+ "Windows 10",
+ Collections.singletonMap("APPDATA", "C:/Users/test/AppData/Roaming")));
+
+ // Linux: ~/.config
+ Assert.assertEquals(
+ Paths.get("/home/test", ".config", "temporalio", "temporal.toml").toString(),
+ ClientConfig.getDefaultConfigFilePath("/home/test", "Linux", Collections.emptyMap()));
+ }
+
@Test
public void parseToml() throws IOException {
String toml =