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

Yarn config respect --no-defaults with --json (fixes #6341) #6635

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .yarn/versions/c7de517e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
releases:
"@yarnpkg/cli": patch
"@yarnpkg/plugin-essentials": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Commands config test (folder with rcfile / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "{"key":"initScope","effective":"my-test","source":"WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml","description":"Scope used when creating packages via the init command","type":"STRING","default":null}
",
}
`;

exports[`Commands config test (folder with rcfile / as json) 1`] = `
{
"code": 0,
Expand All @@ -11,6 +20,18 @@ exports[`Commands config test (folder with rcfile / as json) 1`] = `
}
`;
exports[`Commands config test (folder with rcfile / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "└─ initScope
- ├─ Description: Scope used when creating packages via the init command
- ├─ Source: WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml
- └─ Value: 'my-test'
",
}
`;
exports[`Commands config test (folder with rcfile / without flags) 1`] = `
{
"code": 0,
Expand All @@ -33,6 +54,16 @@ exports[`Commands config test (folder with rcfile / without flags) 1`] = `
}
`;
exports[`Commands config test (folder with rcfile and rc in ancestor parent / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "{"key":"initScope","effective":"my-test","source":"WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml","description":"Scope used when creating packages via the init command","type":"STRING","default":null}
{"key":"lastUpdateCheck","effective":"1555784893958","source":"WORKSPACE_ROOT/.yarnrc.yml","description":"Last timestamp we checked whether new Yarn versions were available","type":"STRING","default":null}
",
}
`;
exports[`Commands config test (folder with rcfile and rc in ancestor parent / as json) 1`] = `
{
"code": 0,
Expand All @@ -44,6 +75,23 @@ exports[`Commands config test (folder with rcfile and rc in ancestor parent / as
}
`;
exports[`Commands config test (folder with rcfile and rc in ancestor parent / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "├─ initScope
- ├─ Description: Scope used when creating packages via the init command
- ├─ Source: WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml
- └─ Value: 'my-test'
└─ lastUpdateCheck
- ├─ Description: Last timestamp we checked whether new Yarn versions were available
- ├─ Source: WORKSPACE_ROOT/.yarnrc.yml
- └─ Value: '1555784893958'
",
}
`;
exports[`Commands config test (folder with rcfile and rc in ancestor parent / without flags) 1`] = `
{
"code": 0,
Expand All @@ -66,6 +114,16 @@ exports[`Commands config test (folder with rcfile and rc in ancestor parent / wi
}
`;
exports[`Commands config test (folder with rcfile and rc in home folder / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "{"key":"initScope","effective":"my-test","source":"WORKSPACE_ROOT/.yarnrc.yml","description":"Scope used when creating packages via the init command","type":"STRING","default":null}
{"key":"lastUpdateCheck","effective":"1555784893958","source":"WORKSPACE_ROOT/.yarnrc.yml","description":"Last timestamp we checked whether new Yarn versions were available","type":"STRING","default":null}
",
}
`;
exports[`Commands config test (folder with rcfile and rc in home folder / as json) 1`] = `
{
"code": 0,
Expand All @@ -77,6 +135,23 @@ exports[`Commands config test (folder with rcfile and rc in home folder / as jso
}
`;
exports[`Commands config test (folder with rcfile and rc in home folder / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "├─ initScope
- ├─ Description: Scope used when creating packages via the init command
- ├─ Source: WORKSPACE_ROOT/.yarnrc.yml
- └─ Value: 'my-test'
└─ lastUpdateCheck
- ├─ Description: Last timestamp we checked whether new Yarn versions were available
- ├─ Source: WORKSPACE_ROOT/.yarnrc.yml
- └─ Value: '1555784893958'
",
}
`;
exports[`Commands config test (folder with rcfile and rc in home folder / without flags) 1`] = `
{
"code": 0,
Expand All @@ -99,6 +174,16 @@ exports[`Commands config test (folder with rcfile and rc in home folder / withou
}
`;
exports[`Commands config test (folder with rcfile and rc in parent / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "{"key":"initScope","effective":"my-test","source":"WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml","description":"Scope used when creating packages via the init command","type":"STRING","default":null}
{"key":"lastUpdateCheck","effective":"1555784893958","source":"WORKSPACE_ROOT/subfolder/.yarnrc.yml","description":"Last timestamp we checked whether new Yarn versions were available","type":"STRING","default":null}
",
}
`;
exports[`Commands config test (folder with rcfile and rc in parent / as json) 1`] = `
{
"code": 0,
Expand All @@ -110,6 +195,23 @@ exports[`Commands config test (folder with rcfile and rc in parent / as json) 1`
}
`;
exports[`Commands config test (folder with rcfile and rc in parent / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "├─ initScope
- ├─ Description: Scope used when creating packages via the init command
- ├─ Source: WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml
- └─ Value: 'my-test'
└─ lastUpdateCheck
- ├─ Description: Last timestamp we checked whether new Yarn versions were available
- ├─ Source: WORKSPACE_ROOT/subfolder/.yarnrc.yml
- └─ Value: '1555784893958'
",
}
`;
exports[`Commands config test (folder with rcfile and rc in parent / without flags) 1`] = `
{
"code": 0,
Expand All @@ -132,6 +234,15 @@ exports[`Commands config test (folder with rcfile and rc in parent / without fla
}
`;
exports[`Commands config test (folder with rcfile without trailing newline / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "{"key":"initScope","effective":"my-test","source":"WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml","description":"Scope used when creating packages via the init command","type":"STRING","default":null}
",
}
`;
exports[`Commands config test (folder with rcfile without trailing newline / as json) 1`] = `
{
"code": 0,
Expand All @@ -143,6 +254,18 @@ exports[`Commands config test (folder with rcfile without trailing newline / as
}
`;
exports[`Commands config test (folder with rcfile without trailing newline / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "└─ initScope
- ├─ Description: Scope used when creating packages via the init command
- ├─ Source: WORKSPACE_ROOT/subfolder/subfolder/.yarnrc.yml
- └─ Value: 'my-test'
",
}
`;
exports[`Commands config test (folder with rcfile without trailing newline / without flags) 1`] = `
{
"code": 0,
Expand All @@ -165,6 +288,14 @@ exports[`Commands config test (folder with rcfile without trailing newline / wit
}
`;
exports[`Commands config test (folder without rcfile in ancestry / as json no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "",
}
`;
exports[`Commands config test (folder without rcfile in ancestry / as json) 1`] = `
{
"code": 0,
Expand All @@ -176,6 +307,14 @@ exports[`Commands config test (folder without rcfile in ancestry / as json) 1`]
}
`;
exports[`Commands config test (folder without rcfile in ancestry / no defaults) 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "",
}
`;
exports[`Commands config test (folder without rcfile in ancestry / without flags) 1`] = `
{
"code": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {PortablePath, npath, ppath, xfs} from '@yarnpkg/fslib';

const RC_FILENAME = `.yarnrc.yml`;
const SUBFOLDER = `subfolder`;
const FAKE_REGISTRY_URL = `http://yarn.test.registry`;
const FAKE_LOCAL_APP_DATA = `LOCAL_APP_DATA`;
const FAKE_WORKSPACE_ROOT = `WORKSPACE_ROOT`;
const FAKE_HOME = `HOME`;
Expand Down Expand Up @@ -40,7 +39,7 @@ const environments: Record<string, (opts: {
},
};

function cleanupPlainOutput(output: string, path: PortablePath, homePath: PortablePath) {
function cleanupOutput(output: string, path: PortablePath, homePath: PortablePath) {
// Replace multiple consecutive spaces with one space.
// The output of the config command is aligned according to the longest value, which probably
// contains `path`. In other words, the formatting depends on the length of `path`.
Expand All @@ -65,51 +64,17 @@ function cleanupPlainOutput(output: string, path: PortablePath, homePath: Portab
return output;
}

function cleanupJsonOutput(output: string, path: PortablePath, homePath: PortablePath) {
let outputObject;
try {
outputObject = JSON.parse(output);
} catch (e) {
return cleanupPlainOutput(output, path, homePath);
}

// the default globalFolder contains the user's home folder, override that value
outputObject.globalFolder.default = `DEFAULT_GLOBAL_FOLDER`;

// replace the generated registry server URL with a constant
outputObject.npmRegistryServer.effective = FAKE_REGISTRY_URL;

const pathN = npath.fromPortablePath(path);
const homePathN = npath.fromPortablePath(homePath);

const cleanPath = (input: string) => input
.replaceAll(pathN, FAKE_WORKSPACE_ROOT)
.replaceAll(homePathN, FAKE_HOME);

for (const setting of Object.values<any>(outputObject)) {
if (typeof setting.source === `string`)
setting.source = cleanPath(setting.source);

if (typeof setting.default === `string`)
setting.default = cleanPath(setting.default);

if (typeof setting.effective === `string`) {
setting.effective = cleanPath(setting.effective);
}
}

return JSON.stringify(outputObject);
}

const options = {
[`without flags`]: {cleanupStdout: cleanupPlainOutput, flags: []},
[`as json`]: {cleanupStdout: cleanupJsonOutput, flags: [`--json`]},
[`without flags`]: {flags: []},
[`as json`]: {flags: [`--json`]},
[`no defaults`]: {flags: [`--no-defaults`]},
[`as json no defaults`]: {flags: [`--json`, `--no-defaults`]},
};

describe(`Commands`, () => {
describe(`config`, () => {
for (const [environmentDescription, environment] of Object.entries(environments)) {
for (const [optionDescription, {flags, cleanupStdout}] of Object.entries(options)) {
for (const [optionDescription, {flags}] of Object.entries(options)) {
test(`test (${environmentDescription} / ${optionDescription})`, makeTemporaryEnv({}, async ({path, run, source}) => {
const cwd = ppath.join(path, `${SUBFOLDER}/${SUBFOLDER}`);
const homePath = await xfs.mktempPromise();
Expand All @@ -127,8 +92,8 @@ describe(`Commands`, () => {
({code, stdout, stderr} = error);
}

stdout = cleanupStdout(stdout, path, homePath);
stderr = cleanupPlainOutput(stderr, path, homePath);
stdout = cleanupOutput(stdout, path, homePath);
stderr = cleanupOutput(stderr, path, homePath);

expect({code, stdout, stderr}).toMatchSnapshot();
}));
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-essentials/sources/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export default class ConfigCommand extends BaseCommand {

if (this.json) {
for (const name of names) {
if (this.noDefaults && !configuration.sources.has(name))
continue;

const data = configuration.settings.get(name);
if (typeof data === `undefined`)
report.reportError(MessageName.INVALID_CONFIGURATION_KEY, `No configuration key named "${name}"`);
Expand Down
Loading