Skip to content

Commit

Permalink
feat(upgrade, add): Separately log added/upgraded dependencies (yarnp…
Browse files Browse the repository at this point in the history
…kg#5227)

* feat(upgrade, add): Separate added/upgraded dependencies into direct/transitive

When adding or upgrading dependencies, group the dependencies into directly required ones vs.
transitive ones so that version shown is clearer to the end user.

https://github.com/yarnpkg/rfcs/blob/master/accepted/0000-show-updated-packages-only.md

* fix tests

* flow

* review feedback

* add snapshots

* update snapshots
  • Loading branch information
kaylieEB authored and arcanis committed Jan 30, 2018
1 parent aa200e4 commit d68b6c9
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 29 deletions.
78 changes: 78 additions & 0 deletions __tests__/__snapshots__/index.js.snap
@@ -0,0 +1,78 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should add lockfile package 1`] = `
Array [
"info No lockfile found.",
"[1/4] Resolving packages...",
"[2/4] Fetching packages...",
"[3/4] Linking dependencies...",
"[4/4] Building fresh packages...",
"success Saved lockfile.",
"success Saved 1 new dependency.",
"info Direct dependencies",
"└─ lockfile@1.0.3",
"info All dependencies",
"└─ lockfile@1.0.3",
]
`;

exports[`should add package 1`] = `
Array [
"info No lockfile found.",
"[1/4] Resolving packages...",
"[2/4] Fetching packages...",
"[3/4] Linking dependencies...",
"[4/4] Building fresh packages...",
"success Saved lockfile.",
"success Saved 1 new dependency.",
"info Direct dependencies",
"└─ left-pad@1.2.0",
"info All dependencies",
"└─ left-pad@1.2.0",
]
`;

exports[`should add package with frozen-lockfile option 1`] = `
Array [
"info No lockfile found.",
"[1/4] Resolving packages...",
"[2/4] Fetching packages...",
"[3/4] Linking dependencies...",
"[4/4] Building fresh packages...",
"success Saved 1 new dependency.",
"info Direct dependencies",
"└─ repeating@3.0.0",
"info All dependencies",
"└─ repeating@3.0.0",
]
`;

exports[`should add package with no-lockfile option 1`] = `
Array [
"info No lockfile found.",
"[1/4] Resolving packages...",
"[2/4] Fetching packages...",
"[3/4] Linking dependencies...",
"[4/4] Building fresh packages...",
"success Saved 1 new dependency.",
"info Direct dependencies",
"└─ repeating@3.0.0",
"info All dependencies",
"└─ repeating@3.0.0",
]
`;

exports[`should add package with no-lockfile option in front 1`] = `
Array [
"info No lockfile found.",
"[1/4] Resolving packages...",
"[2/4] Fetching packages...",
"[3/4] Linking dependencies...",
"[4/4] Building fresh packages...",
"success Saved 1 new dependency.",
"info Direct dependencies",
"└─ split-lines@1.1.0",
"info All dependencies",
"└─ split-lines@1.1.0",
]
`;
5 changes: 4 additions & 1 deletion __tests__/__snapshots__/integration.js.snap
Expand Up @@ -8,5 +8,8 @@ exports[`yarnrc-args 1`] = `
{\\"type\\":\\"step\\",\\"data\\":{\\"message\\":\\"Building fresh packages\\",\\"current\\":4,\\"total\\":4}}
{\\"type\\":\\"success\\",\\"data\\":\\"Saved lockfile.\\"}
{\\"type\\":\\"success\\",\\"data\\":\\"Saved 1 new dependency.\\"}
{\\"type\\":\\"tree\\",\\"data\\":{\\"type\\":\\"newDependencies\\",\\"trees\\":[{\\"name\\":\\"left-pad@1.1.3\\",\\"children\\":[],\\"hint\\":null,\\"color\\":null,\\"depth\\":0}]}}"
{\\"type\\":\\"info\\",\\"data\\":\\"Direct dependencies\\"}
{\\"type\\":\\"tree\\",\\"data\\":{\\"type\\":\\"newDirectDependencies\\",\\"trees\\":[{\\"name\\":\\"left-pad@1.1.3\\",\\"children\\":[],\\"hint\\":null,\\"color\\":null,\\"depth\\":0}]}}
{\\"type\\":\\"info\\",\\"data\\":\\"All dependencies\\"}
{\\"type\\":\\"tree\\",\\"data\\":{\\"type\\":\\"newAllDependencies\\",\\"trees\\":[{\\"name\\":\\"left-pad@1.1.3\\",\\"children\\":[],\\"hint\\":null,\\"color\\":null,\\"depth\\":0}]}}"
`;
28 changes: 28 additions & 0 deletions __tests__/commands/upgrade.js
Expand Up @@ -275,6 +275,34 @@ test.concurrent('upgrades optional dependency packages not in registry', (): Pro
});
});

test.concurrent('informs the type of dependency after upgrade', (): Promise<void> => {
return buildRun(
reporters.BufferReporter,
fixturesLoc,
async (args, flags, config, reporter): Promise<void> => {
await upgrade(config, reporter, flags, args);

const output = reporter.getBuffer();
const infos = output.filter(({type}) => type === 'info');
const getTreeInfo = pkgName =>
output.filter(
({type, data: {trees = []}}) => type === 'tree' && trees.some(({name}) => name.indexOf(pkgName) > -1),
);

expect(
infos.some(info => {
return info.data.toString().indexOf('Direct dependencies') > -1;
}),
).toEqual(true);
expect(getTreeInfo('async')).toHaveLength(2);
expect(getTreeInfo('lodash')).toHaveLength(1);
},
['async'],
{latest: true},
'direct-dependency',
);
});

test.concurrent('warns when peer dependency is not met after upgrade', (): Promise<void> => {
return buildRun(
reporters.BufferReporter,
Expand Down
5 changes: 5 additions & 0 deletions __tests__/fixtures/upgrade/direct-dependency/package.json
@@ -0,0 +1,5 @@
{
"dependencies": {
"async": "2.0.0"
}
}
13 changes: 13 additions & 0 deletions __tests__/fixtures/upgrade/direct-dependency/yarn.lock
@@ -0,0 +1,13 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


async@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.0.0.tgz#d0900ad385af13804540a109c42166e3ae7b2b9d"
dependencies:
lodash "^4.8.0"

lodash@^4.8.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
36 changes: 12 additions & 24 deletions __tests__/index.js
Expand Up @@ -60,20 +60,8 @@ async function execCommand(
});
}

function expectAddSuccessfullOutput(stdout, pkg) {
const lastLines = stdout.slice(stdout.length - 4);
expect(lastLines[0]).toEqual('success Saved lockfile.');
expect(lastLines[1]).toEqual('success Saved 1 new dependency.');
expect(lastLines[2]).toContain(pkg);
expect(lastLines[3]).toContain('Done');
}

function expectAddSuccessfullOutputWithNoLockFile(stdout, pkg) {
const lastLines = stdout.slice(stdout.length - 4);
expect(lastLines[0]).not.toEqual('success Saved lockfile.');
expect(lastLines[1]).toEqual('success Saved 1 new dependency.');
expect(lastLines[2]).toContain(pkg);
expect(lastLines[3]).toContain('Done');
function expectAddOutput(stdout) {
expect(stdout.slice(1, stdout.length - 1)).toMatchSnapshot();
}

function expectRunOutput(stdout) {
Expand Down Expand Up @@ -112,29 +100,29 @@ function expectAnInfoMessageAfterError(command: Promise<Array<?string>>, expecte
.catch(error => expect(error.stdout).toContain(expectedInfo));
}

test.concurrent('should add package', async () => {
test('should add package', async () => {
const stdout = await execCommand('add', ['left-pad'], 'run-add', true);
expectAddSuccessfullOutput(stdout, 'left-pad');
expectAddOutput(stdout);
});

test.concurrent('should add package with no-lockfile option', async () => {
test('should add package with no-lockfile option', async () => {
const stdout = await execCommand('add', ['repeating', '--no-lockfile'], 'run-add-option', true);
expectAddSuccessfullOutputWithNoLockFile(stdout, 'repeating');
expectAddOutput(stdout);
});

test.concurrent('should add package with frozen-lockfile option', async () => {
test('should add package with frozen-lockfile option', async () => {
const stdout = await execCommand('add', ['repeating', '--frozen-lockfile'], 'run-add-option', true);
expectAddSuccessfullOutputWithNoLockFile(stdout, 'repeating');
expectAddOutput(stdout);
});

test.concurrent('should add package with no-lockfile option in front', async () => {
test('should add package with no-lockfile option in front', async () => {
const stdout = await execCommand('add', ['--no-lockfile', 'split-lines'], 'run-add-option-in-front', true);
expectAddSuccessfullOutputWithNoLockFile(stdout, 'split-lines');
expectAddOutput(stdout);
});

test.concurrent('should add lockfile package', async () => {
test('should add lockfile package', async () => {
const stdout = await execCommand('add', ['lockfile'], 'run-add-lockfile', true);
expectAddSuccessfullOutput(stdout, 'lockfile');
expectAddOutput(stdout);
});

// test is failing on Node 4, https://travis-ci.org/yarnpkg/yarn/jobs/216254539
Expand Down
26 changes: 22 additions & 4 deletions src/cli/commands/add.js
Expand Up @@ -204,10 +204,28 @@ export class Add extends Install {
const merged = [...patterns, ...this.addedPatterns];

const {trees, count} = await buildTree(this.resolver, this.linker, merged, opts, true, true);
this.reporter.success(
count === 1 ? this.reporter.lang('savedNewDependency') : this.reporter.lang('savedNewDependencies', count),
);
this.reporter.tree('newDependencies', trees);

if (count === 1) {
this.reporter.success(this.reporter.lang('savedNewDependency'));
} else {
this.reporter.success(this.reporter.lang('savedNewDependencies', count));
}

if (!count) {
return;
}

const resolverPatterns = new Set();
for (const pattern of patterns) {
const {version, name} = this.resolver.getResolvedPattern(pattern) || {};
resolverPatterns.add(`${name}@${version}`);
}
const directRequireDependencies = trees.filter(({name}) => resolverPatterns.has(name));

this.reporter.info(this.reporter.lang('directDependencies'));
this.reporter.tree('newDirectDependencies', directRequireDependencies);
this.reporter.info(this.reporter.lang('allDependencies'));
this.reporter.tree('newAllDependencies', trees);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/reporters/lang/en.js
Expand Up @@ -239,6 +239,8 @@ const messages = {

savedNewDependency: 'Saved 1 new dependency.',
savedNewDependencies: 'Saved $0 new dependencies.',
directDependencies: 'Direct dependencies',
allDependencies: 'All dependencies',

foundWarnings: 'Found $0 warnings.',
foundErrors: 'Found $0 errors.',
Expand Down

0 comments on commit d68b6c9

Please sign in to comment.