Skip to content

Commit 2689ac8

Browse files
authored
Adds UserCacheHome. (#2)
1 parent a25c1ca commit 2689ac8

2 files changed

Lines changed: 199 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2018 Google LLC. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
17+
package com.google.cloud.tools.skaffold.filesystem;
18+
19+
import com.google.common.annotations.VisibleForTesting;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
22+
import java.nio.file.Paths;
23+
import java.util.Locale;
24+
import java.util.Map;
25+
import java.util.Properties;
26+
import java.util.logging.Logger;
27+
28+
/**
29+
* Obtains an OS-specific user cache directory based on the XDG Base Directory Specification.
30+
*
31+
* <p>Specifically, from the specification:
32+
*
33+
* <ul>
34+
* <li>This directory is defined by the environment variable {@code $XDG_CACHE_HOME}.
35+
* <li>If {@code $XDG_CACHE_HOME} is either not set or empty, a default equal to {@code
36+
* $HOME/.cache} should be used.
37+
* </ul>
38+
*
39+
* @see <a
40+
* href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html">https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html</a>
41+
*/
42+
public class UserCacheHome {
43+
44+
private static final Logger logger = Logger.getLogger(UserCacheHome.class.getName());
45+
46+
public static Path getCacheHome() {
47+
return getCacheHome(System.getProperties(), System.getenv());
48+
}
49+
50+
/**
51+
* Returns {@code $XDG_CACHE_HOME}, if available, or resolves the OS-specific user cache home
52+
* based.
53+
*
54+
* <p>For Linus, this is {@code $HOME/.cache/}.
55+
*
56+
* <p>For Windows, this is {@code %LOCALAPPDATA%}.
57+
*
58+
* <p>For macOS, this is {@code $HOME/Library/Application Support/}.
59+
*/
60+
@VisibleForTesting
61+
static Path getCacheHome(Properties properties, Map<String, String> environment) {
62+
// Use environment variable $XDG_CACHE_HOME if set and not empty.
63+
String xdgCacheHome = environment.get("XDG_CACHE_HOME");
64+
if (xdgCacheHome != null && !xdgCacheHome.trim().isEmpty()) {
65+
return Paths.get(xdgCacheHome);
66+
}
67+
68+
String userHome = properties.getProperty("user.home");
69+
70+
Path userHomeDirectory = Paths.get(userHome);
71+
Path xdgPath = userHomeDirectory.resolve(".cache");
72+
73+
String rawOsName = properties.getProperty("os.name");
74+
String osName = rawOsName.toLowerCase(Locale.ENGLISH);
75+
76+
if (osName.contains("linux")) {
77+
return xdgPath;
78+
79+
} else if (osName.contains("windows")) {
80+
// Use %LOCALAPPDATA% for Windows.
81+
String localAppDataEnv = environment.get("LOCALAPPDATA");
82+
if (localAppDataEnv == null || localAppDataEnv.trim().isEmpty()) {
83+
logger.warning("LOCALAPPDATA environment is invalid or missing");
84+
return xdgPath;
85+
}
86+
Path localAppData = Paths.get(localAppDataEnv);
87+
if (!Files.exists(localAppData)) {
88+
logger.warning(localAppData + " does not exist");
89+
return xdgPath;
90+
}
91+
return localAppData;
92+
93+
} else if (osName.contains("mac") || osName.contains("darwin")) {
94+
// Use '~/Library/Application Support/' for macOS.
95+
Path applicationSupport = userHomeDirectory.resolve("Library").resolve("Application Support");
96+
if (!Files.exists(applicationSupport)) {
97+
logger.warning(applicationSupport + " does not exist");
98+
return xdgPath;
99+
}
100+
return applicationSupport;
101+
}
102+
103+
throw new IllegalStateException("Unknown OS: " + rawOsName);
104+
}
105+
106+
private UserCacheHome() {}
107+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright 2018 Google LLC. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
17+
package com.google.cloud.tools.skaffold.filesystem;
18+
19+
import com.google.common.collect.ImmutableMap;
20+
import java.io.IOException;
21+
import java.nio.file.Files;
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
24+
import java.util.Collections;
25+
import java.util.Map;
26+
import java.util.Properties;
27+
import org.junit.Assert;
28+
import org.junit.Before;
29+
import org.junit.Rule;
30+
import org.junit.Test;
31+
import org.junit.rules.TemporaryFolder;
32+
import org.mockito.Mockito;
33+
34+
/** Tests for {@link UserCacheHome}. */
35+
public class UserCacheHomeTest {
36+
37+
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
38+
39+
private String fakeCacheHome;
40+
41+
@Before
42+
public void setUp() throws IOException {
43+
fakeCacheHome = temporaryFolder.newFolder().getPath();
44+
}
45+
46+
@Test
47+
public void testGetCacheHome_hasXdgCacheHome() {
48+
Map<String, String> fakeEnvironment = ImmutableMap.of("XDG_CACHE_HOME", fakeCacheHome);
49+
50+
Assert.assertEquals(
51+
Paths.get(fakeCacheHome),
52+
UserCacheHome.getCacheHome(Mockito.mock(Properties.class), fakeEnvironment));
53+
}
54+
55+
@Test
56+
public void testGetCacheHome_linux() {
57+
Properties fakeProperties = new Properties();
58+
fakeProperties.setProperty("user.home", fakeCacheHome);
59+
fakeProperties.setProperty("os.name", "os is LiNuX");
60+
61+
Assert.assertEquals(
62+
Paths.get(fakeCacheHome).resolve(".cache"),
63+
UserCacheHome.getCacheHome(fakeProperties, Collections.emptyMap()));
64+
}
65+
66+
@Test
67+
public void testGetCacheHome_windows() {
68+
Properties fakeProperties = new Properties();
69+
fakeProperties.setProperty("user.home", "nonexistent");
70+
fakeProperties.setProperty("os.name", "os is WiNdOwS");
71+
72+
Map<String, String> fakeEnvironment = ImmutableMap.of("LOCALAPPDATA", fakeCacheHome);
73+
74+
Assert.assertEquals(
75+
Paths.get(fakeCacheHome), UserCacheHome.getCacheHome(fakeProperties, fakeEnvironment));
76+
}
77+
78+
@Test
79+
public void testGetCacheHome_mac() throws IOException {
80+
Path libraryApplicationSupport =
81+
Paths.get(fakeCacheHome).resolve("Library").resolve("Application Support");
82+
Files.createDirectories(libraryApplicationSupport);
83+
84+
Properties fakeProperties = new Properties();
85+
fakeProperties.setProperty("user.home", fakeCacheHome);
86+
fakeProperties.setProperty("os.name", "os is mAc or DaRwIn");
87+
88+
Assert.assertEquals(
89+
libraryApplicationSupport,
90+
UserCacheHome.getCacheHome(fakeProperties, Collections.emptyMap()));
91+
}
92+
}

0 commit comments

Comments
 (0)