mirror of https://github.com/sbt/sbt.git
Introduce support for OS-specific standard cache directories (#676)
This cleans up the home directories of users and helps making sure that
Coursier's cache is not accidentically backed up by applications or OS
functionality.
The precedence is as follows:
- existing $COURSIER_CACHE environment variable
- existing coursier.cache Java property
- existing operating system specific standards:
- Linux: $XDG_CACHE_HOME/coursier, with fallback to ~/.cache/coursier
- Windows: {SpecialFolder.LocalApplicationData}/cache/Coursier
- macOS: $HOME/Library/Caches/Coursier
- existing ~/.coursier/
- fallback to operating system specific standard directory else.
See discussion in https://github.com/coursier/coursier/pull/676#issuecomment-338974822
This commit is contained in:
parent
e2f47b0f43
commit
1871610751
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "tests/metadata"]
|
||||
path = tests/metadata
|
||||
url = https://github.com/coursier/test-metadata.git
|
||||
[submodule "directories"]
|
||||
path = directories
|
||||
url = https://github.com/soc/directories.git
|
||||
|
|
|
|||
15
build.sbt
15
build.sbt
|
|
@ -85,7 +85,8 @@ lazy val `proxy-tests` = project
|
|||
lazy val paths = project
|
||||
.settings(
|
||||
pureJava,
|
||||
dontPublish
|
||||
dontPublish,
|
||||
addDirectoriesSources
|
||||
)
|
||||
|
||||
lazy val cache = project
|
||||
|
|
@ -461,6 +462,14 @@ lazy val sharedTestResources = {
|
|||
unmanagedResourceDirectories.in(Test) += baseDirectory.in(LocalRootProject).value / "tests" / "shared" / "src" / "test" / "resources"
|
||||
}
|
||||
|
||||
lazy val addPathsSources = {
|
||||
unmanagedSourceDirectories.in(Compile) ++= unmanagedSourceDirectories.in(Compile).in(paths).value
|
||||
// Using directly the sources of directories, rather than depending on it.
|
||||
// This is required to use it from the bootstrap module, whose jar is launched as is (so shouldn't require dependencies).
|
||||
// This is done for the other use of it too, from the cache module, not to have to manage two ways of depending on it.
|
||||
lazy val addDirectoriesSources = {
|
||||
unmanagedSourceDirectories.in(Compile) += baseDirectory.in(LocalRootProject).value / "directories" / "src" / "main" / "java"
|
||||
}
|
||||
|
||||
lazy val addPathsSources = Seq(
|
||||
addDirectoriesSources,
|
||||
unmanagedSourceDirectories.in(Compile) ++= unmanagedSourceDirectories.in(Compile).in(paths).value
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ed193b425d5c184029481e2330baaf5628bbefac
|
||||
|
|
@ -85,18 +85,7 @@ public class CachePath {
|
|||
}
|
||||
|
||||
public static File defaultCacheDirectory() {
|
||||
|
||||
// cache this method result so that it's only ever computed once?
|
||||
|
||||
String path = System.getenv("COURSIER_CACHE");
|
||||
|
||||
if (path == null)
|
||||
path = System.getProperty("coursier.cache");
|
||||
|
||||
if (path == null)
|
||||
path = System.getProperty("user.home") + "/.coursier/cache/v1"; // shouldn't have put a "v1" component here...
|
||||
|
||||
return new File(path).getAbsoluteFile();
|
||||
return new File(CoursierPaths.cacheDirectory(), "v1");
|
||||
}
|
||||
|
||||
private static ConcurrentHashMap<File, Object> processStructureLocks = new ConcurrentHashMap<File, Object>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package coursier;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import io.github.soc.directories.ProjectDirectories;
|
||||
|
||||
/**
|
||||
* Computes Coursier's directories according to the standard
|
||||
* defined by operating system Coursier is running on.
|
||||
*
|
||||
* @implNote If more paths e. g. for configuration or application data is required,
|
||||
* use {@link #coursierDirectories} and do not roll your own logic.
|
||||
*/
|
||||
public final class CoursierPaths {
|
||||
private CoursierPaths() {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
private static ProjectDirectories coursierDirectories;
|
||||
|
||||
private static volatile File cacheDirectory0 = null;
|
||||
|
||||
private static final Object lock = new Object();
|
||||
|
||||
// TODO After switching to nio, that logic can be unit tested with mock filesystems.
|
||||
|
||||
private static File computeCacheDirectory() {
|
||||
String path = System.getenv("COURSIER_CACHE");
|
||||
|
||||
if (path == null)
|
||||
path = System.getProperty("coursier.cache");
|
||||
|
||||
String xdgPath = coursierDirectories.projectCacheDir;
|
||||
File xdgDir = new File(xdgPath);
|
||||
|
||||
if (path == null) {
|
||||
if (xdgDir.isDirectory())
|
||||
path = xdgPath;
|
||||
}
|
||||
|
||||
if (path == null) {
|
||||
File coursierDotFile = new File(System.getProperty("user.home") + "/.coursier");
|
||||
if (coursierDotFile.isDirectory())
|
||||
path = System.getProperty("user.home") + "/.coursier/cache/";
|
||||
}
|
||||
|
||||
if (path == null) {
|
||||
path = xdgPath;
|
||||
xdgDir.mkdirs();
|
||||
}
|
||||
|
||||
File coursierCacheDirectory = new File(path).getAbsoluteFile();
|
||||
|
||||
if (coursierCacheDirectory.getName().equals("v1"))
|
||||
coursierCacheDirectory = coursierCacheDirectory.getParentFile();
|
||||
|
||||
return coursierCacheDirectory;
|
||||
}
|
||||
|
||||
public static File cacheDirectory() {
|
||||
|
||||
if (cacheDirectory0 == null)
|
||||
synchronized (lock) {
|
||||
if (cacheDirectory0 == null) {
|
||||
coursierDirectories = ProjectDirectories.fromProjectName("Coursier");
|
||||
cacheDirectory0 = computeCacheDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
return cacheDirectory0;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue