diff --git a/src/rules/no-file-dependencies.ts b/src/rules/no-file-dependencies.ts index 9187c8bc..60d2845c 100644 --- a/src/rules/no-file-dependencies.ts +++ b/src/rules/no-file-dependencies.ts @@ -1,19 +1,27 @@ import {PackageJson} from 'type-fest'; -import {doVersContainFileUrl} from '../validators/dependency-audit'; +import {auditDependenciesForFileUrlVersion} from '../validators/dependency-audit'; import {LintIssue} from '../lint-issue'; import {RuleType} from '../types/rule-type'; import {Severity} from '../types/severity'; const lintId = 'no-file-dependencies'; const nodeName = 'dependencies'; -const message = 'You are using dependencies via url to local file. Please use dependencies from npm.'; export const ruleType = RuleType.OptionalObject; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const lint = (packageJsonData: PackageJson | any, severity: Severity, config: any): LintIssue | null => { - if (packageJsonData.hasOwnProperty(nodeName) && doVersContainFileUrl(packageJsonData, nodeName, config)) { - return new LintIssue(lintId, severity, nodeName, message); + const auditResult = auditDependenciesForFileUrlVersion(packageJsonData, nodeName, config); + + if (packageJsonData.hasOwnProperty(nodeName) && auditResult.hasFileUrlVersions) { + return new LintIssue( + lintId, + severity, + nodeName, + `You are using ${nodeName} via url to local file. Please use ${nodeName} from npm. Invalid ${nodeName} include: ${auditResult.dependenciesWithFileUrlVersion.join( + ', ' + )}` + ); } return null; diff --git a/src/rules/no-file-devDependencies.ts b/src/rules/no-file-devDependencies.ts index 2eabcd6d..37990edb 100644 --- a/src/rules/no-file-devDependencies.ts +++ b/src/rules/no-file-devDependencies.ts @@ -1,19 +1,27 @@ import {PackageJson} from 'type-fest'; -import {doVersContainFileUrl} from '../validators/dependency-audit'; +import {auditDependenciesForFileUrlVersion} from '../validators/dependency-audit'; import {LintIssue} from '../lint-issue'; import {RuleType} from '../types/rule-type'; import {Severity} from '../types/severity'; const lintId = 'no-file-devDependencies'; const nodeName = 'devDependencies'; -const message = 'You are using devDependencies via url to local file. Please use devDependencies from npm.'; export const ruleType = RuleType.OptionalObject; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const lint = (packageJsonData: PackageJson | any, severity: Severity, config: any): LintIssue | null => { - if (packageJsonData.hasOwnProperty(nodeName) && doVersContainFileUrl(packageJsonData, nodeName, config)) { - return new LintIssue(lintId, severity, nodeName, message); + const auditResult = auditDependenciesForFileUrlVersion(packageJsonData, nodeName, config); + + if (packageJsonData.hasOwnProperty(nodeName) && auditResult.hasFileUrlVersions) { + return new LintIssue( + lintId, + severity, + nodeName, + `You are using ${nodeName} via url to local file. Please use ${nodeName} from npm. Invalid ${nodeName} include: ${auditResult.dependenciesWithFileUrlVersion.join( + ', ' + )}` + ); } return null; diff --git a/src/validators/dependency-audit.ts b/src/validators/dependency-audit.ts index ca134a36..c8b8e4a4 100755 --- a/src/validators/dependency-audit.ts +++ b/src/validators/dependency-audit.ts @@ -370,15 +370,30 @@ export const doVersContainArchiveUrl = (packageJsonData: PackageJson | any, node return false; }; +export interface AuditDependenciesForFileUrlVersionResponse { + hasFileUrlVersions: boolean; + dependenciesWithFileUrlVersion: string[]; + dependenciesWithoutFileUrlVersion: string[]; +} + /** * Determines whether or not dependency versions contains file url - * @param {object} packageJsonData Valid JSON - * @param {string} nodeName Name of a node in the package.json file - * @param {object} config Rule configuration - * @return {boolean} True if the package contain file url. + * @param packageJsonData Valid JSON + * @param nodeName Name of a node in the package.json file + * @param config Rule configuration + * @return True if the package contain file url. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const doVersContainFileUrl = (packageJsonData: PackageJson | any, nodeName: string, config: any): boolean => { +export const auditDependenciesForFileUrlVersion = ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + packageJsonData: PackageJson | any, + nodeName: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + config: any +): AuditDependenciesForFileUrlVersionResponse => { + let hasFileUrlVersions = false; + const dependenciesWithFileUrlVersion = []; + const dependenciesWithoutFileUrlVersion = []; + // eslint-disable-next-line no-restricted-syntax for (const dependencyName in packageJsonData[nodeName]) { if (hasExceptions(config) && config.exceptions.includes(dependencyName)) { @@ -389,9 +404,16 @@ export const doVersContainFileUrl = (packageJsonData: PackageJson | any, nodeNam const dependencyVersion = packageJsonData[nodeName][dependencyName]; if (dependencyVersion.startsWith('file:')) { - return true; + hasFileUrlVersions = true; + dependenciesWithFileUrlVersion.push(dependencyName); + } else { + dependenciesWithoutFileUrlVersion.push(dependencyName); } } - return false; + return { + hasFileUrlVersions, + dependenciesWithFileUrlVersion, + dependenciesWithoutFileUrlVersion, + }; }; diff --git a/test/unit/rules/no-file-dependencies.test.ts b/test/unit/rules/no-file-dependencies.test.ts index 81437179..306f1df9 100644 --- a/test/unit/rules/no-file-dependencies.test.ts +++ b/test/unit/rules/no-file-dependencies.test.ts @@ -21,7 +21,7 @@ describe('no-archive-dependencies Unit Tests', () => { expect(response.severity).toStrictEqual('error'); expect(response.node).toStrictEqual('dependencies'); expect(response.lintMessage).toStrictEqual( - 'You are using dependencies via url to local file. Please use dependencies from npm.' + 'You are using dependencies via url to local file. Please use dependencies from npm. Invalid dependencies include: test-module' ); }); }); diff --git a/test/unit/rules/no-file-devDependencies.test.ts b/test/unit/rules/no-file-devDependencies.test.ts index bb48a710..04ce7a0f 100644 --- a/test/unit/rules/no-file-devDependencies.test.ts +++ b/test/unit/rules/no-file-devDependencies.test.ts @@ -21,7 +21,7 @@ describe('no-archive-devDependencies Unit Tests', () => { expect(response.severity).toStrictEqual('error'); expect(response.node).toStrictEqual('devDependencies'); expect(response.lintMessage).toStrictEqual( - 'You are using devDependencies via url to local file. Please use devDependencies from npm.' + 'You are using devDependencies via url to local file. Please use devDependencies from npm. Invalid devDependencies include: test-module' ); }); }); diff --git a/test/unit/validators/dependency-audit.test.ts b/test/unit/validators/dependency-audit.test.ts index ba3bda20..dd674b91 100755 --- a/test/unit/validators/dependency-audit.test.ts +++ b/test/unit/validators/dependency-audit.test.ts @@ -1025,7 +1025,7 @@ describe('dependency-audit Unit Tests', () => { }); }); - describe('doVersContainFileUrl method', () => { + describe('auditDependenciesForFileUrlVersion method', () => { describe('when the node exists in the package.json file, some versions are url to file', () => { test('with github dependency true should be returned', () => { const packageJson = { @@ -1033,9 +1033,13 @@ describe('dependency-audit Unit Tests', () => { 'my-module': 'file:local-module', }, }; - const response = dependencyAudit.doVersContainFileUrl(packageJson, 'dependencies', {}); + const response = dependencyAudit.auditDependenciesForFileUrlVersion(packageJson, 'dependencies', {}); - expect(response).toBe(true); + expect(response).toStrictEqual({ + hasFileUrlVersions: true, + dependenciesWithFileUrlVersion: ['my-module'], + dependenciesWithoutFileUrlVersion: [], + }); }); }); @@ -1050,9 +1054,19 @@ describe('dependency-audit Unit Tests', () => { 'module-from-archive': 'https://github.com/user/repo/archive/v1.2.3.tar.gz', }, }; - const response = dependencyAudit.doVersContainFileUrl(packageJson, 'dependencies', {}); + const response = dependencyAudit.auditDependenciesForFileUrlVersion(packageJson, 'dependencies', {}); - expect(response).toBe(false); + expect(response).toStrictEqual({ + hasFileUrlVersions: false, + dependenciesWithFileUrlVersion: [], + dependenciesWithoutFileUrlVersion: [ + 'npm-package-json-lint', + 'grunt-npm-package-json-lint', + 'gulp-npm-package-json-lint', + 'module-from-git', + 'module-from-archive', + ], + }); }); }); @@ -1065,11 +1079,15 @@ describe('dependency-audit Unit Tests', () => { 'gulp-npm-package-json-lint': '^2.0.0', }, }; - const response = dependencyAudit.doVersContainFileUrl(packageJson, 'dependencies', { + const response = dependencyAudit.auditDependenciesForFileUrlVersion(packageJson, 'dependencies', { exceptions: ['module-from-file'], }); - expect(response).toBe(false); + expect(response).toStrictEqual({ + hasFileUrlVersions: false, + dependenciesWithFileUrlVersion: [], + dependenciesWithoutFileUrlVersion: ['grunt-npm-package-json-lint', 'gulp-npm-package-json-lint'], + }); }); }); }); diff --git a/website/docs/rules/dependencies/no-file-dependencies.md b/website/docs/rules/dependencies/no-file-dependencies.md index 76afba43..6379385d 100644 --- a/website/docs/rules/dependencies/no-file-dependencies.md +++ b/website/docs/rules/dependencies/no-file-dependencies.md @@ -63,4 +63,5 @@ With exceptions ## History +* Improved messaging when an invalid configuration is detected in version 6.2.0 * Introduced in version 4.3.0 diff --git a/website/docs/rules/dependencies/no-file-devDependencies.md b/website/docs/rules/dependencies/no-file-devDependencies.md index 02979192..8b0a4534 100644 --- a/website/docs/rules/dependencies/no-file-devDependencies.md +++ b/website/docs/rules/dependencies/no-file-devDependencies.md @@ -63,4 +63,5 @@ With exceptions ## History +* Improved messaging when an invalid configuration is detected in version 6.2.0 * Introduced in version 4.3.0