Skip to content

Commit 39694e2

Browse files
author
Maël Nison
committed
Fallbacks to /tmp if the preferred cache folder isn't writable
1 parent f072e96 commit 39694e2

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/config.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,27 @@ export default class Config {
276276
networkConcurrency: this.networkConcurrency,
277277
networkTimeout: this.networkTimeout,
278278
});
279-
this._cacheRootFolder = String(
280-
opts.cacheFolder || this.getOption('cache-folder', true) || constants.MODULE_CACHE_DIRECTORY,
281-
);
279+
280+
let cacheRootFolder = opts.cacheFolder || this.getOption('cache-folder', true);
281+
282+
for (let t = 0; t < constants.PREFERRED_MODULE_CACHE_DIRECTORIES.length && !cacheRootFolder; ++t) {
283+
const tentativeCacheFolder = constants.PREFERRED_MODULE_CACHE_DIRECTORIES[t];
284+
285+
try {
286+
await fs.mkdirp(tentativeCacheFolder);
287+
await fs.writeFile(path.join(tentativeCacheFolder, constants.WTEST_FILENAME), `testing write access`);
288+
cacheRootFolder = tentativeCacheFolder;
289+
} catch (error) {
290+
this.reporter.warn(this.reporter.lang('cacheFolderSkipped', tentativeCacheFolder));
291+
}
292+
}
293+
294+
if (!cacheRootFolder) {
295+
throw new MessageError(this.reporter.lang('cacheFolderMissing'));
296+
} else {
297+
this._cacheRootFolder = String(cacheRootFolder);
298+
}
299+
282300
this.workspacesEnabled = Boolean(this.getOption('workspaces-experimental'));
283301

284302
this.pruneOfflineMirror = Boolean(this.getOption('yarn-offline-mirror-pruning'));

src/constants.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,21 @@ function getDirectory(category: string): string {
4646
return path.join(userHome, `.${category}`, 'yarn');
4747
}
4848

49-
function getCacheDirectory(): string {
49+
function getPreferredCacheDirectories(): Array<string> {
50+
const preferredCacheDirectories = [getDirectory('cache')];
51+
52+
if (process.platform !== 'win32') {
53+
preferredCacheDirectories.unshift('/tmp/.yarn-cache');
54+
}
55+
5056
if (process.platform === 'darwin') {
51-
return path.join(userHome, 'Library', 'Caches', 'Yarn');
57+
preferredCacheDirectories.unshift(path.join(userHome, 'Library', 'Caches', 'Yarn'));
5258
}
5359

54-
return getDirectory('cache');
60+
return preferredCacheDirectories;
5561
}
5662

57-
export const MODULE_CACHE_DIRECTORY = getCacheDirectory();
63+
export const PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories();
5864
export const CONFIG_DIRECTORY = getDirectory('config');
5965
export const LINK_REGISTRY_DIRECTORY = path.join(CONFIG_DIRECTORY, 'link');
6066
export const GLOBAL_MODULE_DIRECTORY = path.join(CONFIG_DIRECTORY, 'global');
@@ -68,6 +74,7 @@ export const LOCKFILE_FILENAME = 'yarn.lock';
6874
export const METADATA_FILENAME = '.yarn-metadata.json';
6975
export const TARBALL_FILENAME = '.yarn-tarball.tgz';
7076
export const CLEAN_FILENAME = '.yarnclean';
77+
export const WTEST_FILENAME = 'yarn-wtest';
7178

7279
export const DEFAULT_INDENT = ' ';
7380
export const SINGLE_INSTANCE_PORT = 31997;

src/reporters/lang/en.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ const messages = {
174174
workspaceNameMandatory: 'Missing name in workspace at $0, ignoring.',
175175
workspaceNameDuplicate: 'There are more than one workspace with name $0',
176176

177+
cacheFolderSkipped: 'Skipping preferred cache folder $0 because it is not writable.',
178+
cacheFolderMissing: "Yarn hasn't been able to find a cache folder. Please use an explicit --cache-folder option to tell it what location to use, or make one of the preferred locations writable.",
179+
177180
execMissingCommand: 'Missing command name.',
178181

179182
commandNotSpecified: 'No command specified.',

0 commit comments

Comments
 (0)