Skip to content

Commit

Permalink
feat(publish): include all deps in package graph by default, allow no…
Browse files Browse the repository at this point in the history
…-sort (#277)

* feat(publish): include all dependencies in package graph by default, allow no-sort
  • Loading branch information
ghiscoding committed Jul 27, 2022
1 parent 8e45a1e commit 3229e77
Show file tree
Hide file tree
Showing 15 changed files with 202 additions and 76 deletions.
4 changes: 1 addition & 3 deletions helpers/logging-output.ts
@@ -1,6 +1,4 @@
'use strict';

const log = require('npmlog');
import log from 'npmlog';
import { multiLineTrimRight } from './index';

// clear logs between tests
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/__mocks__/index.ts
@@ -0,0 +1 @@
export * from './output';
@@ -1,15 +1,13 @@
'use strict';

const chalk = require('chalk');
const { multiLineTrimRight } = require('@lerna-test/helpers');
import chalk from 'chalk';
import { multiLineTrimRight } from '@lerna-test/helpers';

// keep snapshots stable cross-platform
chalk.level = 0;

// @lerna/output is just a wrapper around console.log
const mockOutput = jest.fn();

function logged() {
export function logged() {
return mockOutput.mock.calls.map((args) => multiLineTrimRight(args[0])).join('\n');
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/command.ts
Expand Up @@ -42,7 +42,7 @@ export class Command<T extends AvailableCommandOption> {
concurrency!: number;
envDefaults: any;
sort: any;
toposort?: number;
toposort?: boolean;

execOpts!: ExecOpts;
commandName: CommandType = '';
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/models/interfaces.ts
Expand Up @@ -193,7 +193,7 @@ export interface ProjectConfig extends LernaConfig, QueryGraphConfig {
lernaVersion: string;
progress?: boolean;
since?: string;
sort?: any;
sort?: boolean;
stream?: boolean;
useNx?: boolean;
onRejected?: (result: any) => void;
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/package.ts
@@ -1,7 +1,6 @@
import loadJsonFile from 'load-json-file';
import npa from 'npm-package-arg';
import npmlog from 'npmlog';
import os from 'os';
import path from 'path';
import writePkg from 'write-pkg';

Expand Down
15 changes: 7 additions & 8 deletions packages/publish/src/__tests__/publish-canary.spec.ts
@@ -1,5 +1,3 @@
'use strict';

// mocked modules of @lerna-lite/core
jest.mock('@lerna-lite/core', () => ({
...jest.requireActual('@lerna-lite/core'), // return the other real methods, below we'll mock only 2 of the methods
Expand Down Expand Up @@ -29,7 +27,8 @@ import yargParser from 'yargs-parser';
// mocked modules
import writePkg from 'write-pkg';
import { npmPublish } from '../lib/npm-publish';
import { promptConfirmation, throwIfUncommitted } from '@lerna-lite/core';
import { npmPublish as npmPublishMock } from '../lib/__mocks__/npm-publish';
import { promptConfirmation, PublishCommandOption, throwIfUncommitted } from '@lerna-lite/core';

// helpers
import { gitAdd } from '@lerna-test/helpers';
Expand Down Expand Up @@ -57,7 +56,7 @@ const createArgv = (cwd, ...args) => {
const parserArgs = args.join(' ');
const argv = yargParser(parserArgs);
argv['$0'] = cwd;
return argv;
return argv as unknown as PublishCommandOption;
};

async function initTaggedFixture(fixtureName, tagVersionPrefix = 'v') {
Expand Down Expand Up @@ -102,12 +101,12 @@ test('publish --canary', async () => {
await new PublishCommand(createArgv(cwd, '--canary'));

expect(promptConfirmation).toHaveBeenLastCalledWith('Are you sure you want to publish these packages?');
expect((npmPublish as any).registry).toMatchInlineSnapshot(`
expect((npmPublish as typeof npmPublishMock).registry).toMatchInlineSnapshot(`
Map {
"package-1" => "canary",
"package-3" => "canary",
"package-4" => "canary",
"package-2" => "canary",
"package-3" => "canary",
}
`);
expect((writePkg as any).updatedVersions()).toMatchInlineSnapshot(`
Expand All @@ -131,12 +130,12 @@ test('publish --canary with auto-confirm --yes', async () => {
await new PublishCommand(createArgv(cwd, '--canary', '--yes'));

expect(promptConfirmation).not.toHaveBeenCalled();
expect((npmPublish as any).registry).toMatchInlineSnapshot(`
expect((npmPublish as typeof npmPublishMock).registry).toMatchInlineSnapshot(`
Map {
"package-1" => "canary",
"package-3" => "canary",
"package-4" => "canary",
"package-2" => "canary",
"package-3" => "canary",
}
`);
expect((writePkg as any).updatedVersions()).toMatchInlineSnapshot(`
Expand Down
82 changes: 68 additions & 14 deletions packages/publish/src/__tests__/publish-command.spec.ts
Expand Up @@ -61,6 +61,7 @@ import yargParser from 'yargs-parser';

// mocked or stubbed modules
import { npmPublish } from '../lib/npm-publish';
import { npmPublish as npmPublishMock } from '../lib/__mocks__/npm-publish';
import { promptConfirmation, PublishCommandOption } from '@lerna-lite/core';
import { getOneTimePassword, collectUpdates } from '@lerna-lite/core';
import { packDirectory } from '../lib/pack-directory';
Expand Down Expand Up @@ -149,24 +150,24 @@ describe('PublishCommand', () => {
expect((packDirectory as any).registry).toMatchInlineSnapshot(`
Set {
"package-1",
"package-3",
"package-4",
"package-2",
"package-3",
}
`);
expect((npmPublish as any).registry).toMatchInlineSnapshot(`
expect((npmPublish as typeof npmPublishMock).registry).toMatchInlineSnapshot(`
Map {
"package-1" => "latest",
"package-3" => "latest",
"package-4" => "latest",
"package-2" => "latest",
"package-3" => "latest",
}
`);
expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
expect(npmDistTag.remove).not.toHaveBeenCalled();
Expand All @@ -188,13 +189,12 @@ Map {
const testDir = await initFixture('independent');

await new PublishCommand(createArgv(testDir));
// await lernaPublish(testDir)();

expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
});
Expand All @@ -209,13 +209,51 @@ Map {
});

describe('--graph-type', () => {
it('produces a topological ordering that _includes_ devDependencies when value is not set', async () => {
const cwd = await initFixture('normal');

await new PublishCommand(createArgv(cwd));

expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-4',
'package-2',
// package-3 has a peer/devDependency on package-2
'package-3',
// package-5 is private
]);
});

it("produces a topological ordering that _excludes_ devDependencies when value is 'dependencies' (DEPRECATED)", async () => {
const cwd = await initFixture('normal');

await new PublishCommand(createArgv(cwd, '--graph-type', 'dependencies'));

expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
// package-3 has a peer/devDependency on package-2
'package-3',
'package-4',
'package-2',
// package-5 is private
]);

const logMessages = loggingOutput('warn');
expect(logMessages).toMatchInlineSnapshot(`
Array [
"--graph-type=dependencies is deprecated and will be removed in the next major version of lerna-lite. If you have a use-case you feel requires it please open an issue to discuss: https://github.com/lerna/lerna/issues/new/choose",
"we recommend using --sync-workspace-lock which will sync your lock file via your favorite npm client instead of relying on Lerna-Lite itself to update it.",
]
`);
});

it("produces a topological ordering that _includes_ devDependencies when value is 'all'", async () => {
const cwd = await initFixture('normal');

// await lernaPublish(cwd)("--graph-type", "all");
await new PublishCommand(createArgv(cwd, '--graph-type', 'all'));

expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-4',
'package-2',
Expand All @@ -233,6 +271,22 @@ Map {
});
});

describe('--no-sort', () => {
it('produces a lexical ordering when --no-sort is set', async () => {
const cwd = await initFixture('normal');

await new PublishCommand(createArgv(cwd, '--no-sort'));

expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-2',
'package-3',
'package-4',
// package-5 is private
]);
});
});

describe('--otp', () => {
(getOneTimePassword as any).mockImplementation(() => Promise.resolve('654321'));

Expand Down Expand Up @@ -382,24 +436,24 @@ Map {
expect((packDirectory as any).registry).toMatchInlineSnapshot(`
Set {
"package-1",
"package-3",
"package-4",
"package-2",
"package-3",
}
`);
expect((npmPublish as any).registry).toMatchInlineSnapshot(`
expect((npmPublish as typeof npmPublishMock).registry).toMatchInlineSnapshot(`
Map {
"package-1" => "latest",
"package-3" => "latest",
"package-4" => "latest",
"package-2" => "latest",
"package-3" => "latest",
}
`);
expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
expect(npmDistTag.remove).not.toHaveBeenCalled();
Expand Down
39 changes: 30 additions & 9 deletions packages/publish/src/__tests__/publish-from-git.spec.ts
Expand Up @@ -34,7 +34,8 @@ jest.mock('../lib/npm-publish', () => jest.requireActual('../lib/__mocks__/npm-p

// mocked modules
import { npmPublish } from '../lib/npm-publish';
import { logOutput, promptConfirmation, throwIfUncommitted } from '@lerna-lite/core';
import { npmPublish as npmPublishMock } from '../lib/__mocks__/npm-publish';
import { logOutput, promptConfirmation, PublishCommandOption, throwIfUncommitted } from '@lerna-lite/core';

// helpers
import { gitTag } from '@lerna-test/helpers';
Expand All @@ -54,7 +55,7 @@ const createArgv = (cwd, ...args) => {
const parserArgs = args.join(' ');
const argv = yargParser(parserArgs);
argv['$0'] = cwd;
return argv;
return argv as unknown as PublishCommandOption;
};

describe('publish from-git', () => {
Expand All @@ -69,11 +70,31 @@ describe('publish from-git', () => {

expect(promptConfirmation).toHaveBeenLastCalledWith('Are you sure you want to publish these packages?');
expect((logOutput as any).logged()).toMatch('Found 4 packages to publish:');
expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
});

it('publishes tagged packages, lexically sorted when --no-sort is present', async () => {
const cwd = await initFixture('normal');

await gitTag(cwd, 'v1.0.0');
await new PublishCommand(createArgv(cwd, 'from-git', '--no-sort'));

// called from chained describeRef()
expect(throwIfUncommitted).toHaveBeenCalled();

expect(promptConfirmation).toHaveBeenLastCalledWith('Are you sure you want to publish these packages?');
expect((logOutput as any).logged()).toMatch('Found 4 packages to publish:');
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-2',
'package-3',
'package-4',
// package-5 is private
]);
});
Expand All @@ -90,11 +111,11 @@ describe('publish from-git', () => {
]);
await new PublishCommand(createArgv(cwd, '--bump', 'from-git'));

expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
});
Expand All @@ -105,11 +126,11 @@ describe('publish from-git', () => {
await gitTag(cwd, 'foo/1.0.0');
await new PublishCommand(createArgv(cwd, '--bump', 'from-git', '--tag-version-prefix', 'foo/'));

expect((npmPublish as any).order()).toEqual([
expect((npmPublish as typeof npmPublishMock).order()).toEqual([
'package-1',
'package-3',
'package-4',
'package-2',
'package-3',
// package-5 is private
]);
});
Expand All @@ -121,7 +142,7 @@ describe('publish from-git', () => {
await new PublishCommand(createArgv(cwd, '--bump', 'from-git'));

expect((logOutput as any).logged()).toMatch('Found 1 package to publish:');
expect((npmPublish as any).order()).toEqual(['package-3']);
expect((npmPublish as typeof npmPublishMock).order()).toEqual(['package-3']);
});

it('exits early when the current commit is not tagged', async () => {
Expand Down

0 comments on commit 3229e77

Please sign in to comment.