Skip to content

Commit

Permalink
refactor(core): spread getInstallations across dir
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMason committed Aug 29, 2020
1 parent 9a9a530 commit feb146d
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 117 deletions.
2 changes: 1 addition & 1 deletion src/commands/fix-mismatches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { EOL } from 'os';
import { relative } from 'path';
import { SyncpackConfig } from '../constants';
import { getHighestVersion } from './lib/get-highest-version';
import { getMismatchedDependencies } from './lib/get-installations';
import { getWrappers, SourceWrapper } from './lib/get-wrappers';
import { getMismatchedDependencies } from './lib/installations/get-mismatched-dependencies';
import { log } from './lib/log';

type Options = Pick<SyncpackConfig, 'dev' | 'filter' | 'indent' | 'peer' | 'prod' | 'source' | 'versionGroups'>;
Expand Down
93 changes: 0 additions & 93 deletions src/commands/lib/get-installations.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'expect-more-jest';
import { DEFAULT_CONFIG } from '../../constants';
import { getDependencies, getMismatchedDependencies, Installation, sortByName } from './get-installations';
import { SourceWrapper } from './get-wrappers';
import { DEFAULT_CONFIG } from '../../../constants';
import { SourceWrapper } from '../get-wrappers';
import { getDependencies, Installation } from './get-dependencies';

const mocked = {
projects: (): SourceWrapper[] => [
Expand Down Expand Up @@ -33,19 +33,3 @@ describe('getDependencies', () => {
]);
});
});

describe('getMismatchedDependencies', () => {
it('lists dependencies installed with different versions', () => {
const iterator = getMismatchedDependencies(mocked.projects(), DEFAULT_CONFIG);
expect(Array.from(iterator)).toEqual([getShape('chalk', ['dependencies', '2.3.0'], ['dependencies', '1.0.0'])]);
});
});

describe('sortByName', () => {
it('orders installed packages by name', () => {
const toShape = (name: string): ExpectedShape => getShape(name);
const unordered = ['c', 'a', 'b', 'c'].map(toShape);
const ordered = ['a', 'b', 'c', 'c'].map(toShape);
expect(unordered.sort(sortByName)).toEqual(ordered);
});
});
45 changes: 45 additions & 0 deletions src/commands/lib/installations/get-dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { DependencyType, SyncpackConfig } from '../../../constants';
import { getDependencyTypes } from '../get-dependency-types';
import { SourceWrapper } from '../get-wrappers';
import { getInstallationsOf } from './get-installations-of';

export interface Installation {
/** which section the package was installed in */
type: DependencyType;
/** eg 'lodash' */
name: string;
/** package.json file contents */
source: SourceWrapper;
/** eg '0.1.0' */
version: string;
}

export interface InstalledPackage {
/** eg 'lodash' */
name: string;
/** each location this package is installed */
installations: Installation[];
}

export function* getDependencies(
wrappers: SourceWrapper[],
options: Pick<SyncpackConfig, 'dev' | 'peer' | 'prod'>,
): Generator<InstalledPackage> {
const types = getDependencyTypes(options);
const visited: { [name: string]: boolean } = {};
for (const type of types) {
for (const wrapper of wrappers) {
if (wrapper.contents[type]) {
for (const name in wrapper.contents[type]) {
if (visited[name] === undefined) {
visited[name] = true;
yield {
installations: Array.from(getInstallationsOf(name, types, wrappers)),
name,
};
}
}
}
}
}
}
23 changes: 23 additions & 0 deletions src/commands/lib/installations/get-installations-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DependencyType } from '../../../constants';
import { SourceWrapper } from '../get-wrappers';
import { Installation } from './get-dependencies';

export function* getInstallationsOf(
name: string,
types: DependencyType[],
wrappers: SourceWrapper[],
): Generator<Installation> {
for (const type of types) {
for (const wrapper of wrappers) {
const dependencies = wrapper.contents[type];
if (dependencies && dependencies[name]) {
yield {
name,
source: wrapper,
type,
version: dependencies[name],
};
}
}
}
}
32 changes: 32 additions & 0 deletions src/commands/lib/installations/get-mismatched-dependencies.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'expect-more-jest';
import { DEFAULT_CONFIG } from '../../../constants';
import { SourceWrapper } from '../get-wrappers';
import { Installation } from './get-dependencies';
import { getMismatchedDependencies } from './get-mismatched-dependencies';

const mocked = {
projects: (): SourceWrapper[] => [
{ filePath: '', contents: { dependencies: { chalk: '2.3.0' } } },
{ filePath: '', contents: { devDependencies: { jest: '22.1.4' } } },
{ filePath: '', contents: { peerDependencies: { jest: '22.1.4' } } },
{ filePath: '', contents: { dependencies: { chalk: '1.0.0' } } },
{ filePath: '', contents: { dependencies: { biggy: '0.1.0' } } },
],
};

type ExpectedShape = {
installations: Installation[];
name: string;
};

const getShape = (name: string, ...installations: Array<[string, string]>): ExpectedShape => ({
installations: installations.map(([type, version]) => expect.objectContaining({ name, type, version })),
name,
});

describe('getMismatchedDependencies', () => {
it('lists dependencies installed with different versions', () => {
const iterator = getMismatchedDependencies(mocked.projects(), DEFAULT_CONFIG);
expect(Array.from(iterator)).toEqual([getShape('chalk', ['dependencies', '2.3.0'], ['dependencies', '1.0.0'])]);
});
});
22 changes: 22 additions & 0 deletions src/commands/lib/installations/get-mismatched-dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SyncpackConfig } from '../../../constants';
import { SourceWrapper } from '../get-wrappers';
import { getDependencies, InstalledPackage } from './get-dependencies';

export function* getMismatchedDependencies(
wrappers: SourceWrapper[],
options: Pick<SyncpackConfig, 'dev' | 'peer' | 'prod'>,
): Generator<InstalledPackage> {
const iterator = getDependencies(wrappers, options);
for (const installedPackage of iterator) {
const { installations } = installedPackage;
const len = installations.length;
if (len > 1) {
for (let i = 1; i < len; i++) {
if (installations[i].version !== installations[i - 1].version) {
yield installedPackage;
break;
}
}
}
}
}
22 changes: 22 additions & 0 deletions src/commands/lib/installations/sort-by-name.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'expect-more-jest';
import { Installation } from './get-dependencies';
import { sortByName } from './sort-by-name';

type ExpectedShape = {
installations: Installation[];
name: string;
};

const getShape = (name: string, ...installations: Array<[string, string]>): ExpectedShape => ({
installations: installations.map(([type, version]) => expect.objectContaining({ name, type, version })),
name,
});

describe('sortByName', () => {
it('orders installed packages by name', () => {
const toShape = (name: string): ExpectedShape => getShape(name);
const unordered = ['c', 'a', 'b', 'c'].map(toShape);
const ordered = ['a', 'b', 'c', 'c'].map(toShape);
expect(unordered.sort(sortByName)).toEqual(ordered);
});
});
11 changes: 11 additions & 0 deletions src/commands/lib/installations/sort-by-name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { InstalledPackage } from './get-dependencies';

export const sortByName = (a: InstalledPackage, b: InstalledPackage): 0 | 1 | -1 => {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
};
4 changes: 3 additions & 1 deletion src/commands/list-mismatches.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import chalk from 'chalk';
import { SyncpackConfig } from '../constants';
import { getMismatchedDependencies, InstalledPackage, sortByName } from './lib/get-installations';
import { getWrappers, SourceWrapper } from './lib/get-wrappers';
import { InstalledPackage } from './lib/installations/get-dependencies';
import { getMismatchedDependencies } from './lib/installations/get-mismatched-dependencies';
import { sortByName } from './lib/installations/sort-by-name';
import { log } from './lib/log';

type Options = Pick<SyncpackConfig, 'dev' | 'filter' | 'peer' | 'prod' | 'source' | 'versionGroups'>;
Expand Down
3 changes: 2 additions & 1 deletion src/commands/list.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import chalk from 'chalk';
import { SyncpackConfig } from '../constants';
import { getDependencies, sortByName } from './lib/get-installations';
import { getWrappers, SourceWrapper } from './lib/get-wrappers';
import { getDependencies } from './lib/installations/get-dependencies';
import { sortByName } from './lib/installations/sort-by-name';
import { log } from './lib/log';

type Options = Pick<SyncpackConfig, 'dev' | 'filter' | 'peer' | 'prod' | 'source'>;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/set-semver-ranges.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RANGE_LOOSE, SyncpackConfig } from '../constants';
import { getDependencies } from './lib/get-installations';
import { getWrappers, SourceWrapper } from './lib/get-wrappers';
import { getDependencies } from './lib/installations/get-dependencies';
import { isLooseSemver, isSemver, isValidSemverRange } from './lib/is-semver';
import { writeIfChanged } from './lib/write-if-changed';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/get-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('getConfig', () => {
});
});

it('overrides all dependency types when CLI options are used', () => {
it('overrides all dependency types when any CLI option is used', () => {
setConfigFileTo({ dev: true, peer: true, prod: true });
expect(getConfig({ prod: true })).toEqual(
expect.objectContaining({
Expand Down

0 comments on commit feb146d

Please sign in to comment.