diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f31b52cf8..20d670c9b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed the `requires` attribute on the `@Extension` annotation and instead create a new `@Requires` annotation ([#1097](https://github.com/scm-manager/scm-manager/pull/1097)) +- Use os specific locations for scm home directory ([#1109](https://github.com/scm-manager/scm-manager/pull/1109)) +- Use Library/Logs/SCM-Manager on OSX for logging ([#1109](https://github.com/scm-manager/scm-manager/pull/1109)) ### Fixed - Protocol URI for git commands under windows ([#1108](https://github.com/scm-manager/scm-manager/pull/1108)) diff --git a/docs/Home.md b/docs/Home.md index 6028e50499..c5a6293fd9 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -83,6 +83,8 @@ repositories over http. ### SCM Manager 2 - [Getting started](v2/getting-started.md) +- [Base directory](v2/basedirectory.md) +- [Logging](v2/logging.md) - [Configuration for Intellij IDEA](v2/intellij-idea-configuration.md) - [SCM v2 Test Cases](v2/test-cases.md) - [Table of decisions made during development](v2/decision-table.md) diff --git a/docs/v2/basedirectory.md b/docs/v2/basedirectory.md new file mode 100644 index 0000000000..88408fa07b --- /dev/null +++ b/docs/v2/basedirectory.md @@ -0,0 +1,45 @@ +# Base Directory + +The SCM-Manager base directory aka. home directory, +contains all data which is created by SCM-Manager such as repositories and configurations. +The location of the base directory depends on your operating system and type of installation. + +| Type of Installation | Base directory | +|----------------------|----------------| +| Docker | /var/lib/scm | +| RPM | /var/lib/scm | +| DEB | /var/lib/scm | +| Unix | ~/.scm | +| Mac OS X | ~/Library/Application Support/SCM-Manager | +| Windows | %APPDATA%\SCM-Manager | + +## Change base directory location + +The location of the base directory can be changed by using one of the following ways. +The preferences are the following: Properties file over system property over environment variable. + +### Environment variable + +By setting the environment variable **SCM_HOME** e.g.: + +```bash +export SCM_HOME=/home/scm +/opt/scm-server/bin/scm-server +``` + +For rpm and deb installations the variable can be changed via the file `/etc/default/scm-server`. + +## System property + +The path can be changed by setting the system property **scm.home** e.g.: + +```bash +-Dscm.home=/home/scm +``` +## Properties file + +If SCM-Manager finds a file called `scm.properties` on the class path it reads the property `scm.home` e.g.: + +```properties +scm.home=/home/scm +``` diff --git a/docs/v2/logging.md b/docs/v2/logging.md new file mode 100644 index 0000000000..0afa208e5c --- /dev/null +++ b/docs/v2/logging.md @@ -0,0 +1,32 @@ +# Logging + +SCM-Manager logs information which can be useful, if the system does not behave as expected. +The logging behavior depends on your operating system and installation. + +| Type of Installation | Logging | +|----------------------|---------| +| Docker | stdout | +| RPM | /var/log/scm | +| DEB | /var/log/scm | +| Unix | $BASEDIR/logs | +| Mac OS X | ~/Library/Logs/SCM-Manager | +| Windows | $BASEDIR\logs | + +The location of the **$BASEDIR** can be found [here](basedirectory). + +## Configuration + +The logging behaviour of SCM-Manager can be configured via an xml file. +The syntax and properties can be found [here](http://logback.qos.ch/manual/configuration.html). +The location of the file depends also on the type of installation. + +| Type of Installation | Path | +|----------------------|---------| +| Docker | /opt/scm-server/conf/logging.xml | +| RPM | /etc/scm/logging.xml | +| DEB | /etc/scm/logging.xml | +| Unix | $EXTRACT_PATH/scm-server/conf/logging.xml | +| Mac OS X | $EXTRACT_PATH/scm-server/conf/logging.xml | +| Windows | $EXTRACT_PATH/scm-server/conf/logging.xml | + +**$EXTRACT_PATH** is the path were you etract the content of the package. diff --git a/scm-core/src/main/java/sonia/scm/BaseDirectory.java b/scm-core/src/main/java/sonia/scm/BaseDirectory.java new file mode 100644 index 0000000000..b8b59e5726 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/BaseDirectory.java @@ -0,0 +1,142 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm; + +import com.google.common.base.Strings; +import sonia.scm.util.SystemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Properties; + +/** + * Determines the base directory for SCM-Manager. + * This class should not be used directory, use {@link SCMContextProvider#getBaseDirectory()} instead. + * + * @since 2.0.0 + */ +final class BaseDirectory { + + /** Environment variable for the SCM-Manager base directory */ + static final String ENVIRONMENT_VARIABLE = "SCM_HOME"; + + /** Java system property for the SCM-Manager base directory */ + static final String SYSTEM_PROPERTY = "scm.home"; + + /** Classpath resource for the SCM-Manager base directory */ + @SuppressWarnings("java:S1075") // it is already configurable + static final String CLASSPATH_RESOURCE = "/scm.properties"; + + /** Property name in resource file */ + static final String RESOURCE_PROPERTY = "scm.home"; + + private final Platform platform; + private final String classPathResource; + private final Map environment; + private final Properties systemProperties; + + BaseDirectory(Platform platform, String classPathResource, Map environment, Properties systemProperties) { + this.platform = platform; + this.classPathResource = classPathResource; + this.environment = environment; + this.systemProperties = systemProperties; + } + + /** + * Returns the determined base directory. + * + * @return base directory + */ + @SuppressWarnings("java:S5304") // it is safe to use environment in this case + static Path get() { + return new BaseDirectory( + SystemUtil.getPlatform(), + CLASSPATH_RESOURCE, + System.getenv(), + System.getProperties() + ).find(); + } + + Path find() { + String directory = getFromResource(); + if (Strings.isNullOrEmpty(directory)) { + directory = getFromSystemProperty(); + } + if (Strings.isNullOrEmpty(directory)) { + directory = getFromEnvironmentVariable(); + } + if (Strings.isNullOrEmpty(directory)) { + directory = getOsSpecificDefault(); + } + + return Paths.get(directory); + } + + private String getFromResource() { + try (InputStream input = BasicContextProvider.class.getResourceAsStream(classPathResource)) + { + if (input != null) + { + Properties properties = new Properties(); + properties.load(input); + return properties.getProperty(RESOURCE_PROPERTY); + } + } + catch (IOException ex) + { + throw new ConfigurationException("could not load properties form resource " + CLASSPATH_RESOURCE, ex); + } + return null; + } + + private String getFromEnvironmentVariable() { + return environment.get(ENVIRONMENT_VARIABLE); + } + + private String getFromSystemProperty() { + return systemProperties.getProperty(SYSTEM_PROPERTY); + } + + private String getOsSpecificDefault() { + if (platform.isMac()) { + return getOsxDefault(); + } else if (platform.isWindows()) { + return getWindowsDefault(); + } + return systemProperties.getProperty("user.home") + "/.scm"; + } + + private String getOsxDefault() { + return systemProperties.getProperty("user.home") + "/Library/Application Support/SCM-Manager"; + } + + private String getWindowsDefault() { + return environment.get("APPDATA") + "\\SCM-Manager"; + } + +} diff --git a/scm-core/src/main/java/sonia/scm/BasicContextProvider.java b/scm-core/src/main/java/sonia/scm/BasicContextProvider.java index 465c001490..301b437c53 100644 --- a/scm-core/src/main/java/sonia/scm/BasicContextProvider.java +++ b/scm-core/src/main/java/sonia/scm/BasicContextProvider.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- @@ -30,21 +30,21 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import sonia.scm.util.Util; -//~--- JDK imports ------------------------------------------------------------ - import java.io.File; import java.io.IOException; import java.io.InputStream; - import java.nio.file.Path; import java.util.Locale; import java.util.Properties; +//~--- JDK imports ------------------------------------------------------------ + /** * The default implementation of {@link SCMContextProvider}. * * @author Sebastian Sdorra */ +@SuppressWarnings("java:S106") // we can not use logger until base directory is not determined public class BasicContextProvider implements SCMContextProvider { @@ -174,58 +174,29 @@ public class BasicContextProvider implements SCMContextProvider * * @return base directory SCM-Manager */ - private File findBaseDirectory() - { - String path = getPathFromResource(); + private File findBaseDirectory() { + File directory = BaseDirectory.get().toFile(); - if (Util.isEmpty(path)) - { - path = System.getProperty(DIRECTORY_PROPERTY); - - if (Util.isEmpty(path)) - { - path = System.getenv(DIRECTORY_ENVIRONMENT); - - if (Util.isEmpty(path)) - { - path = System.getProperty("user.home").concat(File.separator).concat( - DIRECTORY_DEFAULT); - } - } - } - - File directory = new File(path); - - if (!directory.exists() &&!directory.mkdirs()) - { - String msg = "could not create home directory at ".concat( - directory.getAbsolutePath()); - - // do not use logger - // http://www.slf4j.org/codes.html#substituteLogger - System.err.println("==================================================="); - System.err.append("Error: ").println(msg); - System.err.println("==================================================="); - - throw new IllegalStateException(msg); - } - else if (directory.exists() && !directory.canWrite()) - { - String msg = "could not modify home directory at ".concat( - directory.getAbsolutePath()); - - // do not use logger - // http://www.slf4j.org/codes.html#substituteLogger - System.err.println("==================================================="); - System.err.append("Error: ").println(msg); - System.err.println("==================================================="); - - throw new IllegalStateException(msg); + if (!directory.exists() &&!directory.mkdirs()) { + error("could not create home directory at " + directory.getAbsolutePath()); + } else if (directory.exists() && !directory.canWrite()) { + error("could not modify home directory at " + directory.getAbsolutePath()); } return directory; } + + private void error(String msg) { + // do not use logger + // http://www.slf4j.org/codes.html#substituteLogger + System.err.println("==================================================="); + System.err.append("Error: ").println(msg); + System.err.println("==================================================="); + + throw new IllegalStateException(msg); + } + /** * Find the current stage. * @@ -256,11 +227,11 @@ public class BasicContextProvider implements SCMContextProvider } private String determineVersion() { - String version = System.getProperty(VERSION_PROPERTY); - if (Strings.isNullOrEmpty(version)) { - version = loadVersion(); + String v = System.getProperty(VERSION_PROPERTY); + if (Strings.isNullOrEmpty(v)) { + v = loadVersion(); } - return version; + return v; } /** @@ -304,59 +275,6 @@ public class BasicContextProvider implements SCMContextProvider return properties.getProperty(MAVEN_PROPERTY_VERSION, VERSION_DEFAULT); } - //~--- get methods ---------------------------------------------------------- - - /** - * Load path from classpath resource. - * - * - * @return path from classpath resource or null - */ - private String getPathFromResource() - { - String path = null; - InputStream input = null; - - try - { - input = - BasicContextProvider.class.getResourceAsStream(DIRECTORY_RESOURCE); - - if (input != null) - { - Properties properties = new Properties(); - - properties.load(input); - path = properties.getProperty(DIRECTORY_PROPERTY); - } - } - catch (IOException ex) - { - throw new ConfigurationException( - "could not load properties form resource ".concat(DIRECTORY_RESOURCE), - ex); - } - finally - { - - // do not use logger or IOUtil, - // http://www.slf4j.org/codes.html#substituteLogger - if (input != null) - { - try - { - input.close(); - } - catch (IOException ex) - { - ex.printStackTrace(System.err); - } - } - } - - return path; - } - //~--- fields --------------------------------------------------------------- /** The base directory of the SCM-Manager */ diff --git a/scm-core/src/test/java/sonia/scm/BaseDirectoryTest.java b/scm-core/src/test/java/sonia/scm/BaseDirectoryTest.java new file mode 100644 index 0000000000..b9342db32d --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/BaseDirectoryTest.java @@ -0,0 +1,124 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm; + +import com.google.common.collect.ImmutableMap; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; + +class BaseDirectoryTest { + + @Test + void shouldGetFromClassPathResource() { + BaseDirectory directory = builder().withClassPathResource("/sonia/scm/basedirectory.properties").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp/scm_home"); + } + + @Test + void shouldGetFromSystemProperty() { + BaseDirectory directory = builder().withSystemProperty(BaseDirectory.SYSTEM_PROPERTY, "/tmp/scm_home").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp/scm_home"); + } + + @Test + void shouldGetFromEnvironmentVariable() { + BaseDirectory directory = builder().withEnvironment(BaseDirectory.ENVIRONMENT_VARIABLE, "/tmp/scm_home").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp/scm_home"); + } + + @Nested + class OsSpecificDefaults { + + @Test + void linux() { + BaseDirectory directory = builder().withSystemProperty("user.home", "/tmp").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp/.scm"); + } + + @Test + void osx() { + BaseDirectory directory = builder().withOsx().withSystemProperty("user.home", "/tmp").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp/Library/Application Support/SCM-Manager"); + } + + @Test + void windows() { + BaseDirectory directory = builder().withWindows().withEnvironment("APPDATA", "/tmp").create(); + assertThat(directory.find().toString()).isEqualTo("/tmp\\SCM-Manager"); + } + + } + + private BaseDirectoryBuilder builder() { + return new BaseDirectoryBuilder(); + } + + static class BaseDirectoryBuilder { + + private Platform platform = platform("Linux"); + private String classPathResource = "/scm.properties"; + private Map environment = ImmutableMap.of(); + private Properties systemProperties = new Properties(); + + public BaseDirectoryBuilder withOsx() { + this.platform = platform("Mac OS X"); + return this; + } + + public BaseDirectoryBuilder withWindows() { + this.platform = platform("Windows"); + return this; + } + + private Platform platform(String osName) { + return new Platform(osName, "64", "x86_64"); + } + + public BaseDirectoryBuilder withClassPathResource(String classPathResource) { + this.classPathResource = classPathResource; + return this; + } + + public BaseDirectoryBuilder withEnvironment(String key, String value) { + this.environment = ImmutableMap.of(key, value); + return this; + } + + public BaseDirectoryBuilder withSystemProperty(String key, String value) { + systemProperties.put(key, value); + return this; + } + + public BaseDirectory create() { + return new BaseDirectory(platform, classPathResource, environment, systemProperties); + } + } + +} diff --git a/scm-core/src/test/java/sonia/scm/BasicContextProviderTest.java b/scm-core/src/test/java/sonia/scm/BasicContextProviderTest.java index efd5c2c2c4..18ad14b5f6 100644 --- a/scm-core/src/test/java/sonia/scm/BasicContextProviderTest.java +++ b/scm-core/src/test/java/sonia/scm/BasicContextProviderTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm; import org.junit.jupiter.api.BeforeEach; diff --git a/scm-core/src/test/resources/sonia/scm/basedirectory.properties b/scm-core/src/test/resources/sonia/scm/basedirectory.properties new file mode 100644 index 0000000000..1f05dc7743 --- /dev/null +++ b/scm-core/src/test/resources/sonia/scm/basedirectory.properties @@ -0,0 +1,25 @@ +# +# MIT License +# +# Copyright (c) 2020-present Cloudogu GmbH and Contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + +scm.home = /tmp/scm_home diff --git a/scm-webapp/src/main/java/sonia/scm/ScmLogFilePropertyDefiner.java b/scm-webapp/src/main/java/sonia/scm/ScmLogFilePropertyDefiner.java index 9161c0eec3..a839d95770 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmLogFilePropertyDefiner.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmLogFilePropertyDefiner.java @@ -21,63 +21,64 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- import ch.qos.logback.core.PropertyDefinerBase; +import com.google.common.annotations.VisibleForTesting; +import sonia.scm.util.SystemUtil; //~--- JDK imports ------------------------------------------------------------ import java.io.File; +import java.util.Properties; /** + * Resolve directory path for SCM-Manager logs. * * @author Sebastian Sdorra */ -public class ScmLogFilePropertyDefiner extends PropertyDefinerBase -{ +public class ScmLogFilePropertyDefiner extends PropertyDefinerBase { - /** Field description */ - public static final String LOG_DIRECTORY = "logs"; + private final String logDirectoryPath; - //~--- constructors --------------------------------------------------------- + public ScmLogFilePropertyDefiner() { + this(SCMContext.getContext(), SystemUtil.getPlatform(), System.getProperties()); + } - /** - * Constructs ... - * - */ - public ScmLogFilePropertyDefiner() - { - File logDirectory = new File(SCMContext.getContext().getBaseDirectory(), - LOG_DIRECTORY); + @VisibleForTesting + ScmLogFilePropertyDefiner(SCMContextProvider context, Platform platform, Properties properties) { + File logDirectory = resolveDirectory(context, platform, properties); - if (!logDirectory.exists() &&!logDirectory.mkdirs()) - { + if (!logDirectory.exists() && !logDirectory.mkdirs()) { throw new ConfigurationException( - "could not create log directory ".concat(logDirectory.getPath())); + "could not create log directory ".concat(logDirectory.getPath())); } this.logDirectoryPath = logDirectory.getAbsolutePath(); } - //~--- get methods ---------------------------------------------------------- + private File resolveDirectory(SCMContextProvider context, Platform platform, Properties properties) { + if (platform.isMac()) { + return resolveOsX(properties); + } else { + return resolveDefault(context); + } + } + + private File resolveOsX(Properties properties) { + return new File(properties.getProperty("user.home"), "Library/Logs/SCM-Manager"); + } + + private File resolveDefault(SCMContextProvider context) { + return new File(context.getBaseDirectory(), "logs"); + } - /** - * Method description - * - * - * @return - */ @Override - public String getPropertyValue() - { + public String getPropertyValue() { return logDirectoryPath; } - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private String logDirectoryPath; } diff --git a/scm-webapp/src/test/java/sonia/scm/ScmLogFilePropertyDefinerTest.java b/scm-webapp/src/test/java/sonia/scm/ScmLogFilePropertyDefinerTest.java new file mode 100644 index 0000000000..6372c75aa1 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/ScmLogFilePropertyDefinerTest.java @@ -0,0 +1,93 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junitpioneer.jupiter.TempDirectory; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.nio.file.Path; +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith({MockitoExtension.class, TempDirectory.class}) +class ScmLogFilePropertyDefinerTest { + + @Mock + private SCMContextProvider context; + + @Test + void shouldReturnPath(@TempDirectory.TempDir Path tempDir) { + when(context.getBaseDirectory()).thenReturn(tempDir.toFile()); + ScmLogFilePropertyDefiner definer = builder().create(); + + Path logDirectory = tempDir.resolve("logs"); + assertThat(definer.getPropertyValue()).isEqualTo(logDirectory.toAbsolutePath().toString()); + } + + @Test + void shouldReturnOsxPath(@TempDirectory.TempDir Path tempDir) { + ScmLogFilePropertyDefiner definer = builder() + .withOs("Mac OS X") + .withUserHome(tempDir.toAbsolutePath().toString()) + .create(); + + Path logDirectory = tempDir.resolve("Library/Logs/SCM-Manager"); + assertThat(definer.getPropertyValue()).isEqualTo(logDirectory.toAbsolutePath().toString()); + } + + private ScmLogFilePropertyDefinerBuilder builder() { + return new ScmLogFilePropertyDefinerBuilder(); + } + + private class ScmLogFilePropertyDefinerBuilder { + + private Platform platform; + private Properties properties = new Properties(); + + public ScmLogFilePropertyDefinerBuilder() { + withOs("Linux"); + } + + public ScmLogFilePropertyDefinerBuilder withOs(String osName) { + platform = new Platform(osName, "64", "x86_64"); + return this; + } + + public ScmLogFilePropertyDefinerBuilder withUserHome(String path) { + properties.setProperty("user.home", path); + return this; + } + + public ScmLogFilePropertyDefiner create() { + return new ScmLogFilePropertyDefiner(context, platform, properties); + } + + } +}