Skip to content

Commit 33656d0

Browse files
chr1shaefn3rtclindner
authored andcommitted
Enhance absolute version dependency to accept "1.0.0" (#39)
Instead of relying only on a "=" prefix, this enhanced version works by making sure all "non-absolute" version rangs are not used, e.g. "~", "^". From the semver Backus-Naur grammar (https://www.npmjs.com/package/semver) is only missing that a "x" and "X" can be used instead of "*".
1 parent 922f13d commit 33656d0

6 files changed

+165
-6
lines changed

src/rules/prefer-absolute-version-dependencies.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
'use strict';
22

3-
const areVersRangesValid = require('./../validators/dependency-audit').areVersRangesValid;
3+
const isVersionAbsolute = require('./../validators/dependency-audit').isVersionAbsolute;
44
const LintIssue = require('./../LintIssue');
55
const lintId = 'prefer-absolute-version-dependencies';
66
const nodeName = 'dependencies';
77
const message = 'You are using an invalid version range. Please use absolute versions.';
88
const ruleType = 'dependencies-version-range';
99

1010
const lint = function(packageJsonData, lintType) {
11-
const rangeSpecifier = '=';
1211

13-
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
12+
if (!isVersionAbsolute(packageJsonData, nodeName)) {
1413
return new LintIssue(lintId, lintType, nodeName, message);
1514
}
1615

src/rules/prefer-absolute-version-devDependencies.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
'use strict';
22

3-
const areVersRangesValid = require('./../validators/dependency-audit').areVersRangesValid;
3+
const isVersionAbsolute = require('./../validators/dependency-audit').isVersionAbsolute;
44
const LintIssue = require('./../LintIssue');
55
const lintId = 'prefer-absolute-version-devDependencies';
66
const nodeName = 'devDependencies';
77
const message = 'You are using an invalid version range. Please use absolute versions.';
88
const ruleType = 'devDependencies-version-range';
99

1010
const lint = function(packageJsonData, lintType) {
11-
const rangeSpecifier = '=';
1211

13-
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
12+
if (!isVersionAbsolute(packageJsonData, nodeName)) {
1413
return new LintIssue(lintId, lintType, nodeName, message);
1514
}
1615

src/validators/dependency-audit.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,39 @@ const areVersRangesValid = function(packageJsonData, nodeName, rangeSpecifier) {
105105
return rangesValid;
106106
};
107107

108+
/**
109+
* Determines whether or not all dependency versions are absolut
110+
* @param {object} packageJsonData Valid JSON
111+
* @param {string} nodeName Name of a node in the package.json file
112+
* @return {boolean} False if the package has an non-absolute version. True if it is not or the node is missing.
113+
*/
114+
const isVersionAbsolute = function(packageJsonData, nodeName) {
115+
if (!packageJsonData.hasOwnProperty(nodeName)) {
116+
return true;
117+
}
118+
119+
const NOT_FOUND = -1;
120+
const firstCharOfStr = 0;
121+
let rangesValid = true;
122+
123+
for (const dependencyName in packageJsonData[nodeName]) {
124+
const dependencyVersion = packageJsonData[nodeName][dependencyName];
125+
126+
if (dependencyVersion.startsWith('^', firstCharOfStr) ||
127+
dependencyVersion.startsWith('~', firstCharOfStr) ||
128+
dependencyVersion.startsWith('>', firstCharOfStr) ||
129+
dependencyVersion.startsWith('<', firstCharOfStr) ||
130+
dependencyVersion.indexOf('*') !== NOT_FOUND
131+
) {
132+
rangesValid = false;
133+
}
134+
}
135+
136+
return rangesValid;
137+
};
138+
108139
module.exports.hasDependency = hasDependency;
109140
module.exports.hasDepPrereleaseVers = hasDepPrereleaseVers;
110141
module.exports.hasDepVersZero = hasDepVersZero;
111142
module.exports.areVersRangesValid = areVersRangesValid;
143+
module.exports.isVersionAbsolute = isVersionAbsolute;

tests/unit/rules/prefer-absolute-version-dependenciesTest.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ describe('prefer-absolute-version-dependencies Unit Tests', function() {
3434
});
3535
});
3636

37+
context('when package.json has node with a valid value', function() {
38+
it('LintIssue object should be returned', function() {
39+
const packageJsonData = {
40+
dependencies: {
41+
'gulp-npm-package-json-lint': '1.0.0'
42+
}
43+
};
44+
const response = lint(packageJsonData, 'error');
45+
46+
response.should.be.true();
47+
});
48+
});
49+
3750
context('when package.json does not have node', function() {
3851
it('true should be returned', function() {
3952
const packageJsonData = {};

tests/unit/rules/prefer-absolute-version-devDependenciesTest.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ describe('prefer-absolute-version-devDependencies Unit Tests', function() {
3434
});
3535
});
3636

37+
context('when package.json has node with a valid value', function() {
38+
it('LintIssue object should be returned', function() {
39+
const packageJsonData = {
40+
devDependencies: {
41+
'gulp-npm-package-json-lint': '1.0.0'
42+
}
43+
};
44+
const response = lint(packageJsonData, 'error');
45+
46+
response.should.be.true();
47+
});
48+
});
49+
3750
context('when package.json does not have node', function() {
3851
it('true should be returned', function() {
3952
const packageJsonData = {};

tests/unit/validators/dependency-auditTest.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,107 @@ describe('dependency-audit Unit Tests', function() {
477477
});
478478
});
479479
});
480+
481+
describe('isVersionAbsolute method', function() {
482+
context('when the node does not exist in the package.json file', function() {
483+
it('true should be returned', function() {
484+
const packageJson = {
485+
dependencies: {
486+
'npm-package-json-lint': '^1.0.0',
487+
'grunt-npm-package-json-lint': '~2.0.0-beta1',
488+
'gulp-npm-package-json-lint': '^2.0.0-rc1'
489+
}
490+
};
491+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'devDependencies');
492+
493+
response.should.be.true();
494+
});
495+
});
496+
497+
context('when the node exists in the package.json file, not all versions are absolute', function() {
498+
it('with caret versioning false should be returned', function() {
499+
const packageJson = {
500+
dependencies: {
501+
'npm-package-json-lint': '^1.0.0',
502+
'gulp-npm-package-json-lint': '^2.0.0-rc1'
503+
}
504+
};
505+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
506+
507+
response.should.be.false();
508+
});
509+
it('with tilde versioning false should be returned', function() {
510+
const packageJson = {
511+
dependencies: {
512+
'npm-package-json-lint': '~1.0.0',
513+
'gulp-npm-package-json-lint': '~2.0.0-rc1'
514+
}
515+
};
516+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
517+
518+
response.should.be.false();
519+
});
520+
it('with star versioning false should be returned', function() {
521+
const packageJson = {
522+
dependencies: {
523+
'npm-package-json-lint': '1.0.*',
524+
'gulp-npm-package-json-lint': '2.*'
525+
}
526+
};
527+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
528+
529+
response.should.be.false();
530+
});
531+
it('with greater versioning false should be returned', function() {
532+
const packageJson = {
533+
dependencies: {
534+
'npm-package-json-lint': '>1.0.0',
535+
'gulp-npm-package-json-lint': '>=2.0.0'
536+
}
537+
};
538+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
539+
540+
response.should.be.false();
541+
});
542+
it('with greater versioning false should be returned', function() {
543+
const packageJson = {
544+
dependencies: {
545+
'npm-package-json-lint': '>1.0.0',
546+
'gulp-npm-package-json-lint': '>=2.0.0'
547+
}
548+
};
549+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
550+
551+
response.should.be.false();
552+
});
553+
it('with less versioning false should be returned', function() {
554+
const packageJson = {
555+
dependencies: {
556+
'npm-package-json-lint': '<1.0.0',
557+
'gulp-npm-package-json-lint': '<=2.0.0'
558+
}
559+
};
560+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
561+
562+
response.should.be.false();
563+
});
564+
});
565+
566+
context('when the node exists in the package.json file, all versions are absolute', function() {
567+
it('true should be returned', function() {
568+
const packageJson = {
569+
dependencies: {
570+
'npm-package-json-lint': '1.0.0',
571+
'grunt-npm-package-json-lint': '2.1.0',
572+
'gulp-npm-package-json-lint': '=2.4.0'
573+
}
574+
};
575+
const response = dependencyAudit.isVersionAbsolute(packageJson, 'dependencies');
576+
577+
response.should.be.true();
578+
});
579+
});
580+
581+
});
582+
480583
});

0 commit comments

Comments
 (0)