-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: More resillient global and cache folder determination #4325
Changes from 5 commits
fa98ad9
f4b48aa
b1c43cc
a9b3542
e478af9
dcb953c
5685843
9576dbd
b9c0fb8
73c61ae
1e6b708
54c7581
86de168
89d52ce
f21abfb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,7 +82,7 @@ function getYarnBinPath(): string { | |
export const NODE_MODULES_FOLDER = 'node_modules'; | ||
export const NODE_PACKAGE_JSON = 'package.json'; | ||
|
||
export const POSIX_GLOBAL_PREFIX = '/usr/local'; | ||
export const POSIX_GLOBAL_PREFIX = `${process.env.DESTIR || ''}/usr/local`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. darn |
||
export const FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); | ||
|
||
export const META_FOLDER = '.yarn-meta'; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,18 @@ | ||
/* @flow */ | ||
|
||
import type {ReadStream} from 'fs'; | ||
|
||
import type Reporter from '../reporters/base-reporter.js'; | ||
|
||
import fs from 'fs'; | ||
import globModule from 'glob'; | ||
import os from 'os'; | ||
import path from 'path'; | ||
|
||
import BlockingQueue from './blocking-queue.js'; | ||
import * as promise from './promise.js'; | ||
import {promisify} from './promise.js'; | ||
import map from './map.js'; | ||
|
||
const fs = require('fs'); | ||
const globModule = require('glob'); | ||
const os = require('os'); | ||
const path = require('path'); | ||
|
||
export const constants = | ||
typeof fs.constants !== 'undefined' | ||
? fs.constants | ||
|
@@ -92,6 +92,16 @@ type CopyOptions = { | |
artifactFiles: Array<string>, | ||
}; | ||
|
||
type FailedFolderQuery = { | ||
error: Error, | ||
folder: string, | ||
}; | ||
|
||
type FolderQueryResult = { | ||
skipped: Array<FailedFolderQuery>, | ||
folder: ?string, | ||
}; | ||
|
||
export const fileDatesEqual = (a: Date, b: Date) => { | ||
const aTime = a.getTime(); | ||
const bTime = b.getTime(); | ||
|
@@ -880,3 +890,30 @@ export async function readFirstAvailableStream( | |
|
||
return {stream, triedPaths}; | ||
} | ||
|
||
export async function getFirstWriteableFolder(paths: Iterable<string>): Promise<FolderQueryResult> { | ||
const result: FolderQueryResult = { | ||
skipped: [], | ||
folder: null, | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we just return a raw string? The list of skipped directories can be deduced relatively easily by the caller anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I also attach the error, in case that matters. May be it is EACCESS, may be it is EROFS or may be it is something else? Also deducing the list would require another traversal of the entire list until the selected folder is found which is a bit unnecessary. |
||
|
||
for (const folder of paths) { | ||
try { | ||
await mkdirp(folder); | ||
const testFile = path.join(folder, `.yarn-write-test-${process.pid}`); | ||
await writeFile(testFile, ''); | ||
await readFile(testFile); | ||
await unlink(testFile); | ||
|
||
result.folder = folder; | ||
|
||
return result; | ||
} catch (error) { | ||
result.skipped.push({ | ||
error, | ||
folder, | ||
}); | ||
} | ||
} | ||
return result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failedFolder
is not a string, so the display will probably be wrong. I think you meantfailedFolder.folder
? The variable name would probably be better asskippedEntry
btw, so that it would beskippedEntry.folder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup to both, good catch!