Skip to content

Commit

Permalink
feat: support --group, --app and --set for check, fixes #3
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneslumpe committed Jun 13, 2019
1 parent c70a239 commit 6d17338
Show file tree
Hide file tree
Showing 31 changed files with 948 additions and 450 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/node_modules
/.vscode
/coverage
/lib
copied_*.json
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
module.exports = {
coverageDirectory: './coverage/',
collectCoverageFrom: ['src/**/*.ts'],
collectCoverage: true,
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.ts'],
globals: {
Expand Down
824 changes: 621 additions & 203 deletions src/cli/__tests__/index.ts

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions src/cli/commands/applications/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ export function addApplicationCommand(
});
await writeConfig(config.path, updatedConfig);
success(
emphasize`${pluralize(
'Application',
applicationpaths.length,
)} in ${pluralize(
`${pluralize('Application', applicationpaths.length)} in ${pluralize(
'path',
applicationpaths.length,
)} ${applicationpaths.join(', ')} added to group ${groupname}`,
)} ${emphasize`${applicationpaths.join(
', ',
)}`} added to group ${groupname}`,
);
})();
},
Expand Down
57 changes: 46 additions & 11 deletions src/cli/commands/version-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,53 @@ export function versionCheckCommand(
yargs: ArgvWithGlobalOptions,
): ArgvWithGlobalOptions {
return yargs.command(
'check [groups..]',
'check',
'check dependencies for given groups',
yargs =>
yargs
.positional('groups', {
describe: 'groups to check dependencies for',
})
.string('groups')
.array('groups'),
yargs.options({
group: {
array: true,
description: 'groups to check',
type: 'string',
default: [] as string[],
},
app: {
array: true,
description: 'applications to check',
type: 'string',
default: [] as string[],
},
set: {
array: true,
description: 'sets to check',
type: 'string',
default: [] as string[],
},
}),
argv => {
argv._asyncResult = (async () => {
const { config, verbose, groups } = argv;
const { config, verbose, group, set, app } = argv;
const result = await checkDependencies({
config: config.contents,
configPath: config.path,
groupsToCheck: groups,
groups: group,
sets: set,
applications: app,
});

// TODO support --json
// format:
// {
// failed: [{
// application: string;
// applicationPath: string;
// dependencies: string[];
// }]
// passed: [{
// same as above
// }]
// }

if (verbose) {
const tables = Object.entries(result.groupResults).reduce(
(acc, [, groupResult]) => {
Expand All @@ -103,9 +132,15 @@ export function versionCheckCommand(
}

if (!result.passed) {
const groups = Object.keys(result.groupResults);
const groups = Object.entries(result.groupResults);
const failedGroups = groups
.filter(([, groupResult]) => !groupResult.passed)
.map(([group]) => group);
throw VersionGuardError.from(
`${pluralize('Group', groups.length)} ${emphasize`${groups.join(
`${pluralize(
'Group',
failedGroups.length,
)} ${emphasize`${failedGroups.join(
', ',
)} did not meet dependency version requirements`}`,
);
Expand Down
60 changes: 38 additions & 22 deletions src/core/version-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,14 @@ async function readPackageJsons({

function invalidGroupsInvariant({
config,
availableGroups,
groups,
}: {
config: VersionGuardConfig;
availableGroups: string[];
groups: string[];
}): void {
const allGroups = Object.keys(config);
if (availableGroups.length) {
const invalidGroups = availableGroups.filter(
group => !allGroups.includes(group),
);
if (groups.length) {
const invalidGroups = groups.filter(group => !allGroups.includes(group));
if (invalidGroups.length) {
throw VersionGuardError.from(
`${pluralize(
Expand All @@ -88,37 +86,55 @@ function invalidGroupsInvariant({
export async function checkDependencies({
config,
configPath,
groupsToCheck,
groups,
sets,
applications,
}: {
config: VersionGuardConfig;
configPath: string;
groupsToCheck: string[];
groups: string[];
sets: string[];
applications: string[];
}): Promise<Readonly<CheckResult>> {
const availableGroups = Object.keys(config);
invalidGroupsInvariant({ config, availableGroups });
const groups = availableGroups.filter(
group => !groupsToCheck.length || groupsToCheck.includes(group),
);
invalidGroupsInvariant({ config, groups: groups });
const groupResults: Dictionary<GroupCheckResult> = {};
const applicationDependencyResults: Dictionary<ApplicationResult> = {};
let allGroupsPassed = true;
// TODO refactor
for (const group of groups) {
const groupConfig = config[group];
const { applications, dependencies } = groupConfig;
const allEntries = Object.entries(config);
const entriesToCheck = !groups.length
? allEntries
: allEntries.filter(([group]) => groups.includes(group));

for (const [group, groupConfig] of entriesToCheck) {
const applicationDependencyResults: Dictionary<ApplicationResult> = {};
const { applications: availableApplications, dependencies } = groupConfig;
const applicationsToCheck = applications.length
? availableApplications.filter(app => applications.includes(app))
: availableApplications;
// this group does not contain any applications we want to check
if (!applicationsToCheck.length) {
continue;
}
const availableDependencySets = Object.entries(dependencies);
const dependencySetsToCheck = sets.length
? availableDependencySets.filter(([setName]) => sets.includes(setName))
: availableDependencySets;
// this group does not contain any dependency sets we want to check
if (!dependencySetsToCheck.length) {
continue;
}
const dependenciesByApplication = await readPackageJsons({
configPath,
applications,
applications: applicationsToCheck,
});
const dependencySets = Object.keys(dependencies);
let groupPassed = true;
for (const setKey of dependencySets) {
const setConfig = dependencies[setKey];

for (const [, setConfig] of dependencySetsToCheck) {
for (const dependency of Object.keys(setConfig.dependencySemvers)) {
const [, requiredDependencyVersion] = setConfig.dependencySemvers[
dependency
].semver.split('@');
for (const application of applications) {
for (const application of applicationsToCheck) {
const dependencyVersion =
dependenciesByApplication[application][dependency];
const dependencySatisfied = semver.satisfies(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "application-a",
"name": "application-b",
"dependencies": {
"dep_a": "^1.0.0",
"dep_b": "1.2.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "application-a",
"name": "application-c",
"dependencies": {
"dep_a": "^1.0.0",
"dep_b": "1.2.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "application-a",
"name": "application-d",
"dependencies": {
"dep_a": "^1.0.0",
"dep_b": "1.2.3",
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/check/mixed-config/application_e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "application-d",
"dependencies": {
"dep_a": "^1.0.0",
"dep_b": "1.2.3",
"dep_c": "~1.5.0"
}
}
8 changes: 8 additions & 0 deletions test/fixtures/check/mixed-config/application_f/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "application-d",
"dependencies": {
"dep_a": "^1.0.0",
"dep_b": "1.2.3",
"dep_c": "~1.5.0"
}
}

0 comments on commit 6d17338

Please sign in to comment.