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

Improve output for no-restricted-* rules #615

Merged
merged 1 commit into from
Mar 20, 2022
Merged
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
16 changes: 12 additions & 4 deletions src/rules/no-restricted-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {PackageJson} from 'type-fest';
import {hasDependency} from '../validators/dependency-audit';
import {auditDependenciesWithRestrictedVersion} from '../validators/dependency-audit';
import {LintIssue} from '../lint-issue';
import {RuleType} from '../types/rule-type';
import {Severity} from '../types/severity';

const lintId = 'no-restricted-dependencies';
const nodeName = 'dependencies';
const message = 'You are using a restricted dependency. Please remove it.';

export const ruleType = RuleType.Array;

Expand All @@ -18,8 +17,17 @@ export const lint = (
severity: Severity,
invalidDependencies: string[]
): LintIssue | null => {
if (hasDependency(packageJsonData, nodeName, invalidDependencies)) {
return new LintIssue(lintId, severity, nodeName, message);
const auditResult = auditDependenciesWithRestrictedVersion(packageJsonData, nodeName, invalidDependencies);

if (auditResult.hasDependencyWithRestrictedVersion) {
return new LintIssue(
lintId,
severity,
nodeName,
`You are using a restricted dependency. Please remove it. Invalid ${nodeName} include: ${auditResult.dependenciesWithRestrictedVersion.join(
', '
)}`
);
}

return null;
Expand Down
16 changes: 12 additions & 4 deletions src/rules/no-restricted-devDependencies.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {PackageJson} from 'type-fest';
import {hasDependency} from '../validators/dependency-audit';
import {auditDependenciesWithRestrictedVersion} from '../validators/dependency-audit';
import {LintIssue} from '../lint-issue';
import {RuleType} from '../types/rule-type';
import {Severity} from '../types/severity';

const lintId = 'no-restricted-devDependencies';
const nodeName = 'devDependencies';
const message = 'You are using a restricted dependency. Please remove it.';

export const ruleType = RuleType.Array;

Expand All @@ -18,8 +17,17 @@ export const lint = (
severity: Severity,
invalidDependencies: string[]
): LintIssue | null => {
if (hasDependency(packageJsonData, nodeName, invalidDependencies)) {
return new LintIssue(lintId, severity, nodeName, message);
const auditResult = auditDependenciesWithRestrictedVersion(packageJsonData, nodeName, invalidDependencies);

if (auditResult.hasDependencyWithRestrictedVersion) {
return new LintIssue(
lintId,
severity,
nodeName,
`You are using a restricted dependency. Please remove it. Invalid ${nodeName} include: ${auditResult.dependenciesWithRestrictedVersion.join(
', '
)}`
);
}

return null;
Expand Down
16 changes: 12 additions & 4 deletions src/rules/no-restricted-pre-release-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {PackageJson} from 'type-fest';
import {hasDepPrereleaseVers} from '../validators/dependency-audit';
import {auditDependenciesWithRestrictedPrereleaseVersion} from '../validators/dependency-audit';
import {LintIssue} from '../lint-issue';
import {RuleType} from '../types/rule-type';
import {Severity} from '../types/severity';

const lintId = 'no-restricted-pre-release-dependencies';
const nodeName = 'dependencies';
const message = 'You are using a restricted pre-release dependency. Please remove it.';

export const ruleType = RuleType.Array;

Expand All @@ -18,8 +17,17 @@ export const lint = (
severity: Severity,
invalidPreRelDeps: string[]
): LintIssue | null => {
if (hasDepPrereleaseVers(packageJsonData, nodeName, invalidPreRelDeps)) {
return new LintIssue(lintId, severity, nodeName, message);
const auditResult = auditDependenciesWithRestrictedPrereleaseVersion(packageJsonData, nodeName, invalidPreRelDeps);

if (auditResult.hasDependencyWithRestrictedPrereleaseVersion) {
return new LintIssue(
lintId,
severity,
nodeName,
`You are using a restricted pre-release dependency. Please remove it. Invalid ${nodeName} include: ${auditResult.dependenciesWithRestrictedPrereleaseVersion.join(
', '
)}`
);
}

return null;
Expand Down
16 changes: 12 additions & 4 deletions src/rules/no-restricted-pre-release-devDependencies.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {PackageJson} from 'type-fest';
import {hasDepPrereleaseVers} from '../validators/dependency-audit';
import {auditDependenciesWithRestrictedPrereleaseVersion} from '../validators/dependency-audit';
import {LintIssue} from '../lint-issue';
import {RuleType} from '../types/rule-type';
import {Severity} from '../types/severity';

const lintId = 'no-restricted-pre-release-devDependencies';
const nodeName = 'devDependencies';
const message = 'You are using a restricted pre-release dependency. Please remove it.';

export const ruleType = RuleType.Array;

Expand All @@ -18,8 +17,17 @@ export const lint = (
severity: Severity,
invalidPreRelDeps: string[]
): LintIssue | null => {
if (hasDepPrereleaseVers(packageJsonData, nodeName, invalidPreRelDeps)) {
return new LintIssue(lintId, severity, nodeName, message);
const auditResult = auditDependenciesWithRestrictedPrereleaseVersion(packageJsonData, nodeName, invalidPreRelDeps);

if (auditResult.hasDependencyWithRestrictedPrereleaseVersion) {
return new LintIssue(
lintId,
severity,
nodeName,
`You are using a restricted pre-release dependency. Please remove it. Invalid ${nodeName} include: ${auditResult.dependenciesWithRestrictedPrereleaseVersion.join(
', '
)}`
);
}

return null;
Expand Down
89 changes: 67 additions & 22 deletions src/validators/dependency-audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,92 @@ const semver = require('semver');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hasExceptions = (config: any): boolean => typeof config === 'object' && config.hasOwnProperty('exceptions');

export interface AuditDependenciesWithRestrictedVersionResponse {
hasDependencyWithRestrictedVersion: boolean;
dependenciesWithRestrictedVersion: string[];
dependenciesWithoutRestrictedVersion: string[];
}

/**
* Determines whether or not the package has a given dependency
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} depsToCheckFor An array of packages to check for
* @return {boolean} True if the package has a dependency. False if it is not or the node is missing.
* @param packageJsonData Valid JSON
* @param nodeName Name of a node in the package.json file
* @param depsToCheckFor An array of packages to check for
* @return True if the package has a dependency. False if it is not or the node is missing.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const hasDependency = (packageJsonData: PackageJson | any, nodeName: string, depsToCheckFor: string[]): boolean => {
export const auditDependenciesWithRestrictedVersion = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
packageJsonData: PackageJson | any,
nodeName: string,
depsToCheckFor: string[]
): AuditDependenciesWithRestrictedVersionResponse => {
let hasDependencyWithRestrictedVersion = false;
const dependenciesWithRestrictedVersion = [];
const dependenciesWithoutRestrictedVersion = [];

if (!packageJsonData.hasOwnProperty(nodeName)) {
return false;
return {
hasDependencyWithRestrictedVersion,
dependenciesWithRestrictedVersion,
dependenciesWithoutRestrictedVersion,
};
}

// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const dependencyName in packageJsonData[nodeName]) {
// eslint-disable-next-line no-restricted-syntax
for (const depToCheckFor of depsToCheckFor) {
if (depToCheckFor === dependencyName) {
return true;
}

if (
hasDependencyWithRestrictedVersion = true;
dependenciesWithRestrictedVersion.push(dependencyName);
} else if (
depToCheckFor.endsWith('*') &&
dependencyName.startsWith(depToCheckFor.slice(0, Math.max(0, depToCheckFor.length - 1)))
) {
return true;
hasDependencyWithRestrictedVersion = true;
dependenciesWithRestrictedVersion.push(dependencyName);
} else {
dependenciesWithoutRestrictedVersion.push(dependencyName);
}
}
}

return false;
return {
hasDependencyWithRestrictedVersion,
dependenciesWithRestrictedVersion,
dependenciesWithoutRestrictedVersion,
};
};

export interface AuditDependenciesWithRestrictedPrereleaseVersionResponse {
hasDependencyWithRestrictedPrereleaseVersion: boolean;
dependenciesWithRestrictedPrereleaseVersion: string[];
dependenciesWithoutRestrictedPrereleaseVersion: string[];
}

/**
* Determines whether or not the package has a pre-release version of a given dependency
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} depsToCheckFor An array of packages to check for
* @return {boolean} True if the package has a pre-release version of a dependency. False if it is not or the node is missing.
* @param packageJsonData Valid JSON
* @param nodeName Name of a node in the package.json file
* @param depsToCheckFor An array of packages to check for
* @return True if the package has a pre-release version of a dependency. False if it is not or the node is missing.
*/
export const hasDepPrereleaseVers = (
export const auditDependenciesWithRestrictedPrereleaseVersion = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
packageJsonData: PackageJson | any,
nodeName: string,
depsToCheckFor: string[]
): boolean => {
): AuditDependenciesWithRestrictedPrereleaseVersionResponse => {
let hasDependencyWithRestrictedPrereleaseVersion = false;
const dependenciesWithRestrictedPrereleaseVersion = [];
const dependenciesWithoutRestrictedPrereleaseVersion = [];

if (!packageJsonData.hasOwnProperty(nodeName)) {
return false;
return {
hasDependencyWithRestrictedPrereleaseVersion,
dependenciesWithRestrictedPrereleaseVersion,
dependenciesWithoutRestrictedPrereleaseVersion,
};
}

// eslint-disable-next-line no-restricted-syntax
Expand All @@ -63,12 +101,19 @@ export const hasDepPrereleaseVers = (
const dependencyVersion = packageJsonData[nodeName][dependencyName];

if (dependencyVersion.includes('-beta') || dependencyVersion.includes('-rc')) {
return true;
hasDependencyWithRestrictedPrereleaseVersion = true;
dependenciesWithRestrictedPrereleaseVersion.push(dependencyName);
} else {
dependenciesWithoutRestrictedPrereleaseVersion.push(dependencyName);
}
}
}

return false;
return {
hasDependencyWithRestrictedPrereleaseVersion,
dependenciesWithRestrictedPrereleaseVersion,
dependenciesWithoutRestrictedPrereleaseVersion,
};
};

export interface AuditDependenciesWithMajorVersionOfZeroResponse {
Expand Down
8 changes: 6 additions & 2 deletions test/unit/rules/no-restricted-dependencies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('no-restricted-dependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-dependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('dependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted dependency. Please remove it. Invalid dependencies include: npm-package-json-lint'
);
});
});

Expand All @@ -44,7 +46,9 @@ describe('no-restricted-dependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-dependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('dependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted dependency. Please remove it. Invalid dependencies include: @types/node'
);
});
});

Expand Down
8 changes: 6 additions & 2 deletions test/unit/rules/no-restricted-devDependencies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('no-restricted-devDependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-devDependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('devDependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted dependency. Please remove it. Invalid devDependencies include: npm-package-json-lint'
);
});
});

Expand All @@ -44,7 +46,9 @@ describe('no-restricted-devDependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-devDependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('devDependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted dependency. Please remove it. Invalid devDependencies include: @types/node'
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('no-restricted-pre-release-dependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-pre-release-dependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('dependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted pre-release dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted pre-release dependency. Please remove it. Invalid dependencies include: npm-package-json-lint'
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('no-restricted-pre-release-devDependencies Unit Tests', () => {
expect(response.lintId).toStrictEqual('no-restricted-pre-release-devDependencies');
expect(response.severity).toStrictEqual('error');
expect(response.node).toStrictEqual('devDependencies');
expect(response.lintMessage).toStrictEqual('You are using a restricted pre-release dependency. Please remove it.');
expect(response.lintMessage).toStrictEqual(
'You are using a restricted pre-release dependency. Please remove it. Invalid devDependencies include: npm-package-json-lint'
);
});
});

Expand Down
Loading