Implementing utilities to detect OS type and apprpriate location of runtime data files, using it to determine daemon run dir. Fixes KT-9696

This commit is contained in:
Ilya Chernikov
2015-10-26 12:10:37 +01:00
parent bf16efb8cc
commit 2fa7b53d2c
2 changed files with 85 additions and 3 deletions
@@ -42,7 +42,6 @@ public val COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY: String = "kotlin.daemon.verbo
public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String = "--daemon-"
public val COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY: String = "kotlin.daemon.startup.timeout"
public val COMPILE_DAEMON_DEFAULT_FILES_PREFIX: String = "kotlin-daemon"
public val COMPILE_DAEMON_DATA_DIRECTORY_NAME: String = "." + COMPILE_DAEMON_DEFAULT_FILES_PREFIX
public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0
public val COMPILE_DAEMON_DEFAULT_IDLE_TIMEOUT_S: Int = 7200 // 2 hours
public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L
@@ -50,8 +49,7 @@ public val COMPILE_DAEMON_FORCE_SHUTDOWN_DEFAULT_TIMEOUT_MS: Long = 10000L // 10
public val COMPILE_DAEMON_FORCE_SHUTDOWN_TIMEOUT_INFINITE: Long = 0L
public val COMPILE_DAEMON_DEFAULT_RUN_DIR_PATH: String get() =
// TODO consider special case for windows - local appdata
File(System.getProperty("user.home"), COMPILE_DAEMON_DATA_DIRECTORY_NAME).absolutePath
FileSystem.getRuntimeStateFilesPath("kotlin", "daemon")
val COMPILER_ID_DIGEST = "MD5"
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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 org.jetbrains.kotlin.rmi
import java.io.File
public enum class OSKind {
Windows,
OSX,
Unix,
Unknown;
companion object {
val current: OSKind = System.getProperty("os.name").toLowerCase().let {
when {
// partly taken from http://www.code4copy.com/java/post/detecting-os-type-in-java
it.startsWith("windows") -> OSKind.Windows
it.startsWith("mac os") -> OSKind.OSX
it.contains("unix") -> OSKind.Unix
it.startsWith("linux") -> OSKind.Unix
it.contains("bsd") -> OSKind.Unix
it.startsWith("irix") -> OSKind.Unix
it.startsWith("mpe/ix") -> OSKind.Unix
it.startsWith("aix") -> OSKind.Unix
it.startsWith("hp-ux") -> OSKind.Unix
it.startsWith("sunos") -> OSKind.Unix
it.startsWith("sun os") -> OSKind.Unix
it.startsWith("solaris") -> OSKind.Unix
else -> OSKind.Unknown
}
}
}
}
private fun String?.orDefault(v: String): String =
if (this == null || this.isBlank()) v else this
// Note links to OS recommendations for storing various kinds of files
// Windows: http://www.microsoft.com/security/portal/mmpc/shared/variables.aspx
// unix (freedesktop): http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// OS X: https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html
public object FileSystem {
val userHomePath: String get() = System.getProperty("user.home")
val tempPath: String get() = System.getProperty("java.io.tmpdir")
val logFilesPath: String get() = tempPath
val runtimeStateFilesBasePath: String get() = when (OSKind.current) {
OSKind.Windows -> System.getenv("LOCALAPPDATA").orDefault(tempPath)
OSKind.OSX -> userHomePath + "/Library/Application Support"
OSKind.Unix -> System.getenv("XDG_DATA_HOME").orDefault(userHomePath + "/.local/share")
OSKind.Unknown -> tempPath
}
fun getRuntimeStateFilesPath(vararg names: String): String {
assert(names.any())
val base = File(runtimeStateFilesBasePath)
// if base is not suitable, take home dir as a base and ensure the first name is prefixed with "." -
// this will work ok as a fallback solution on most systems
val dir = if (base.exists() && base.isDirectory) names.fold(base, { r, v -> File(r, v) })
else names.drop(1)
.fold(File(userHomePath, names.first().let { if (it.startsWith(".")) it else ".$it" }),
{ r, v -> File(r, v)})
return if ((dir.exists() && dir.isDirectory) || dir.mkdirs()) dir.absolutePath
else tempPath
}
}