Skip to content
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

Resolves folder options (i.e. --modules-folder) relative to cwd (#7074) #7607

Merged
merged 1 commit into from Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions __tests__/integration.js
Expand Up @@ -560,3 +560,36 @@ test('yarn init -y', async () => {
const manifestFile = await fs.readFile(path.join(cwd, 'package.json'));
expect(manifestFile).toEqual(initialManifestFile);
});

test('--modules-folder option', async () => {
/**
* The behavior of --modules-folder (and other folder options) was that it resolved relative not to the current
* working directory, but instead to the closest project root (folder containing a package.json file).
*
* This behavior was at best surprising and could result in data loss. This test captures a scenario in which
* there would previously have been data loss, demonstrating the fix for --modules-folder and other folder options.
*
*/
const projectFolder = await makeTemp();
const libraryFolder = path.join(projectFolder, 'lib');

const initialManifestFile = JSON.stringify({name: 'test', license: 'ISC', version: '1.0.0'});
const importantData = 'I definitely care about this file!';

await fs.writeFile(`${projectFolder}/package.json`, initialManifestFile);
await fs.writeFile(`${projectFolder}/IMPORTANT_FILE.txt`, importantData);
await fs.mkdirp(libraryFolder);

const options = {cwd: libraryFolder};

// This yarn command fails with the previous behavior, the rest of the test is defense in depth
await runYarn(['add', 'left-pad', '--modules-folder', '.'], options);

// Dependencies should have been installed in the 'lib' folder
const libraryFolderContents = await fs.readdir(`${libraryFolder}`);
expect(libraryFolderContents).toContain('left-pad');

// Additionally, there should have not been any data loss in the project folder
const importantFile = await fs.readFile(`${projectFolder}/IMPORTANT_FILE.txt`);
expect(importantFile).toBe(importantData);
});
17 changes: 11 additions & 6 deletions src/cli/index.js
Expand Up @@ -509,21 +509,26 @@ export async function main({

const cwd = command.shouldRunInCurrentCwd ? commander.cwd : findProjectRoot(commander.cwd);

const folderOptionKeys = ['linkFolder', 'globalFolder', 'preferredCacheFolder', 'cacheFolder', 'modulesFolder'];

// Resolve all folder options relative to cwd
const resolvedFolderOptions = {};
folderOptionKeys.forEach(folderOptionKey => {
const folderOption = commander[folderOptionKey];
const resolvedFolderOption = folderOption ? path.resolve(commander.cwd, folderOption) : folderOption;
resolvedFolderOptions[folderOptionKey] = resolvedFolderOption;
});

await config
.init({
cwd,
commandName,

...resolvedFolderOptions,
enablePnp: commander.pnp,
disablePnp: commander.disablePnp,
enableDefaultRc: commander.defaultRc,
extraneousYarnrcFiles: commander.useYarnrc,
binLinks: commander.binLinks,
modulesFolder: commander.modulesFolder,
linkFolder: commander.linkFolder,
globalFolder: commander.globalFolder,
preferredCacheFolder: commander.preferredCacheFolder,
cacheFolder: commander.cacheFolder,
preferOffline: commander.preferOffline,
captureHar: commander.har,
ignorePlatform: commander.ignorePlatform,
Expand Down