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: + * + *

+ */ @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 =