Skip to content

Commit

Permalink
Config alternatives (#45)
Browse files Browse the repository at this point in the history
* #43 Add test fixtures for new config loading options

* Bump version and dependencies

* Pass package.json file contents to Config class

* #43 Update config class with new options

1. a `npmPackageJsonLintConfig` property in `package.json`
2. a `.npmpackagejsonlintrc` file in the current working directory
3. a `npmpackagejsonlint.config.js` file that exports a config object
in the current working directory.
4. a global `.npmpackagejsonlintrc` file in the root of your user
directory
5. a global `npmpackagejsonlint.config.js` file that exports a config
object in the root of your user directory

* #43 Update changelog with new config options

* #43  Update README with documentation on configuration

* Fix case typo in file page

* Adjusting coverage for require methods
  • Loading branch information
tclindner authored Aug 9, 2017
1 parent 35b33fb commit 498d329
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 46 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Removed

## [2.7.0] - 2017-08-08
### Added
- The ability to pass config using:
1. a `npmPackageJsonLintConfig` property in `package.json`
2. a `.npmpackagejsonlintrc` file in the current working directory
3. a `npmpackagejsonlint.config.js` file that exports a config object in the current working directory.
4. a global `.npmpackagejsonlintrc` file in the root of your user directory
5. a global `npmpackagejsonlint.config.js` file that exports a config object in the root of your user directory

## [2.6.0] - 2017-07-30
### Changed
- Bumped dependencies
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ Run a specific rule, require-author, set severity to warning on a file relative
Run using the config in `.npmpackagejsonlintrc` on a file relative to the current working directory.
`pjl-cli -f "../relative-path/package.json" -c "./.npmpackagejsonlintrc"`

Run using the default config on a file relative to the current working directory
Run on file relative to the current working directory. npm-package-json-lint attempts to find config. See lookup order below.
`pjl-cli -f "../relative-path/package.json"`

Run on file in the current working directory. npm-package-json-lint attempts to find config. See lookup order below.
`pjl-cli`

## Lint Rules

npm-package-json-lint has a configurable set of rules. Please see the [wiki](https://github.com/tclindner/npm-package-json-lint/wiki) for a full list of available rules. By default no rules are enabled. If you would like to use npm-package-json-lint's default ruleset, please see [npm-package-json-lint-config-default](https://github.com/tclindner/npm-package-json-lint-config-default).
Expand All @@ -80,7 +83,13 @@ Each rule contains the following properties:
3. Message - example: author is required
4. Rule Type - example: required

As mentioned in the "Commands and configuration" section there are two ways to specify rule sets. The first is using `--rule` to specify a given rule. This will run npm-package-json-lint with just this rule. The second is using `--rules-file` to specify a JSON file, named [`.npmpackagejsonlintrc`](https://github.com/tclindner/npm-package-json-lint/wiki/npm-package-json-lint-rc), to run a set of rules. If neither of the options above are specified then npm-package-json-lint looks for a global [`.npmpackagejsonlintrc`](https://github.com/tclindner/npm-package-json-lint/wiki/npm-package-json-lint-rc) file in the root of your user directory.
As mentioned in the "Commands and configuration" section there are two ways to specify rule sets. The first is using `--rule` to specify a given rule. This will run npm-package-json-lint with just this rule. The second is providing a configuration object. As of v2.7.0, there are multiple ways to provide a [configuration object](https://github.com/tclindner/npm-package-json-lint/wiki/configuration).

1. Adding a `--rules-file` to the command to specify a JSON file. This file is typically named [`.npmpackagejsonlintrc`](https://github.com/tclindner/npm-package-json-lint/wiki/npm-package-json-lint-rc); however, you may optionally add a .json extension if you prefer.
2. Add a `npmPackageJsonLintConfig` property in `package.json` file
3. Add a `npmpackagejsonlint.config.js` file that exports a config object in the current working directory.
4. Add a global `.npmpackagejsonlintrc.json` file in the root of your user directory
5. Add a global `npmpackagejsonlint.config.js` file that exports a config object in the root of your user directory

### Configuring rules

Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "npm-package-json-lint",
"version": "2.6.0",
"version": "2.7.0",
"description": "CLI app for linting package.json files.",
"keywords": [
"lint",
Expand Down Expand Up @@ -31,10 +31,10 @@
"eslint": "eslint . --format=node_modules/eslint-formatter-pretty",
"lint": "npm run eslint",
"test": "mocha tests/unit --recursive",
"coverage": "nyc --extension .js --check-coverage --lines 99 --branches 97 --functions 98 npm test"
"coverage": "nyc --extension .js --check-coverage --lines 99 --branches 97 --functions 96 npm test"
},
"dependencies": {
"chalk": "^2.0.1",
"chalk": "^2.1.0",
"commander": "^2.11.0",
"in-array": "^0.1.2",
"is-plain-obj": "^1.1.0",
Expand All @@ -45,14 +45,14 @@
"validator": "^8.0.0"
},
"devDependencies": {
"chai": "^4.1.0",
"eslint": "^4.3.0",
"eslint-config-tc": "^2.0.0",
"chai": "^4.1.1",
"eslint": "^4.4.1",
"eslint-config-tc": "^2.1.0",
"eslint-formatter-pretty": "^1.1.0",
"figures": "^2.0.0",
"mocha": "^3.4.2",
"mocha": "^3.5.0",
"nyc": "^11.1.0",
"sinon": "^2.4.1"
"sinon": "^3.1.0"
},
"engines": {
"node": ">=4.2.0",
Expand Down
109 changes: 92 additions & 17 deletions src/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

/* eslint class-methods-use-this: 'off' */

const fs = require('fs');
const inArray = require('in-array');
const Parser = require('./Parser');
const path = require('path');
const userHome = require('user-home');

class Config {

/**
* Constructor
* @param {Object|String} passedConfigParam Object or string with desired configuration
* @param {Object} packageJsonData User's package.json data
*/
constructor(passedConfigParam) {
constructor(passedConfigParam, packageJsonData) {
this.arrayRules = [
'valid-values-author',
'valid-values-private',
Expand All @@ -23,29 +26,54 @@ class Config {
];

this.passedConfigParam = passedConfigParam;
this.packageJsonData = packageJsonData;
this.rcFileName = '.npmpackagejsonlintrc';
this.configFileName = 'npmpackagejsonlint.config.js';
}

/**
* Gets the config
* @return {Object} Config object
*/
get() {
if (this._isConfigPassed(this.passedConfigParam)) {
const passedConfig = this._getPassedConfig(this.passedConfigParam);
let extendsConfig = {};
const userConfig = this._getUserConfig();

if (passedConfig.hasOwnProperty('extends')) {
extendsConfig = this._getExtendsConfig(passedConfig.extends);
}
this._validateConfig(userConfig);

if (!passedConfig.hasOwnProperty('rules')) {
return Object.assign({}, extendsConfig);
}
let extendsConfig = {};

if (userConfig.hasOwnProperty('extends')) {
extendsConfig = this._getExtendsConfig(userConfig.extends);
}

if (!userConfig.hasOwnProperty('rules')) {
return Object.assign({}, extendsConfig);
}

return Object.assign({}, extendsConfig, userConfig.rules);
}

return Object.assign({}, extendsConfig, passedConfig.rules);
/**
* Get users config with multiple fallbacks
*
* @returns {Object} Users config
*/
_getUserConfig() {
if (this._isConfigPassed(this.passedConfigParam)) {
return this._getPassedConfig(this.passedConfigParam);
} else if (this.packageJsonData.hasOwnProperty('npmPackageJsonLintConfig')) {
return this.packageJsonData.npmPackageJsonLintConfig;
} else if (this._isConfigFileExist(this._getRelativeConfigFilePth(this.rcFileName))) {
return this._loadRcFile(this._getRelativeConfigFilePth(this.rcFileName));
} else if (this._isConfigFileExist(this._getRelativeConfigFilePth(this.configFileName))) {
return this._loadConfigFile(this._getRelativeConfigFilePth(this.configFileName));
} else if (this._isConfigFileExist(this._getUsrHmConfigFilePath(this.rcFileName))) {
return this._loadRcFile(this._getUsrHmConfigFilePath(this.rcFileName));
} else if (this._isConfigFileExist(this._getUsrHmConfigFilePath(this.configFileName))) {
return this._loadConfigFile(this._getUsrHmConfigFilePath(this.configFileName));
}

throw new Error('No configuration passed');
throw new Error('No configuration found');
}

/**
Expand Down Expand Up @@ -73,11 +101,7 @@ class Config {
configFile = path.join(process.cwd(), passedConfig);
}

const rcFileObj = parser.parse(configFile);

this._validateConfig(rcFileObj);

return rcFileObj;
return parser.parse(configFile);
}

return passedConfig;
Expand All @@ -104,6 +128,57 @@ class Config {
return configObj.rules;
}

/**
* Gets relative config file path
*
* @param {String} fileName Name of the file
* @return {String} File path of the config file
*/
_getRelativeConfigFilePth(fileName) {
return path.join(process.cwd(), fileName);
}

/**
* Gets userhome directory config file path
*
* @param {String} fileName Name of the file
* @return {String} File path of the config file
*/
_getUsrHmConfigFilePath(fileName) {
return path.join(userHome, fileName);
}

/**
* Checks if a .npmpackagejsonlintrc.json file exists
*
* @param {String} filePath Path of the file
* @return {Boolean} true if it exists, false if not
*/
_isConfigFileExist(filePath) {
return fs.existsSync(filePath);
}

/**
* Gets configuration from a extends config module
* @param {String} filePath File path of config file
* @return {Object} Configuration object
*/
_loadRcFile(filePath) {
const parser = new Parser();

return parser.parse(filePath);
}

/**
* Checks if a .npmpackagejsonlintrc.json file exists
*
* @param {String} filePath File path of config file
* @return {Boolean} true if it exists, false if not
*/
_loadConfigFile(filePath) {
return require(filePath);
}

/**
* Loads extends config module
* @param {String} moduleName Name of the configuration module
Expand Down
2 changes: 1 addition & 1 deletion src/NpmPackageJsonLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class NpmPackageJsonLint {
* @return {Object} Configuration object for the run
*/
_getConfig(config) {
const configObj = new Config(config);
const configObj = new Config(config, this.packageJsonData);

return configObj.get();
}
Expand Down
28 changes: 28 additions & 0 deletions tests/fixtures/configJavaScriptFile/npmpackagejsonlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

module.exports = {
rules: {
'require-author': 'error',
'require-description': 'error',
'require-devDependencies': 'error',
'require-homepage': 'error',
'require-keywords': 'error',
'require-license': 'warning',
'require-name': 'error',
'require-repository': 'error',
'require-scripts': 'error',
'require-version': 'error',
'description-type': 'error',
'devDependencies-type': 'error',
'homepage-type': 'error',
'keywords-type': 'error',
'name-type': 'error',
'repository-type': 'error',
'version-type': 'error',
'valid-values-author': ['error', [
'Thomas Lindner'
]],
'name-format': 'error',
'version-format': 'error'
}
};
17 changes: 17 additions & 0 deletions tests/fixtures/configJavaScriptFile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "npm-package-json-lint",
"version": "0.1.0",
"description": "CLI app for linting package.json files.",
"keywords": [
"lint"
],
"homepage": "https://github.com/tclindner/npm-package-json-lint",
"author": "Thomas Lindner",
"repository": {
"type": "git",
"url": "https://github.com/tclindner/npm-package-json-lint"
},
"devDependencies": {
"mocha": "^2.4.5"
}
}
43 changes: 43 additions & 0 deletions tests/fixtures/packageJsonProperty/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "npm-package-json-lint",
"version": "0.1.0",
"description": "CLI app for linting package.json files.",
"keywords": [
"lint"
],
"homepage": "https://github.com/tclindner/npm-package-json-lint",
"author": "Thomas Lindner",
"repository": {
"type": "git",
"url": "https://github.com/tclindner/npm-package-json-lint"
},
"devDependencies": {
"mocha": "^2.4.5"
},
"npmPackageJsonLintConfig": {
"rules": {
"require-author": "error",
"require-description": "error",
"require-devDependencies": "error",
"require-homepage": "error",
"require-keywords": "error",
"require-license": "warning",
"require-name": "error",
"require-repository": "error",
"require-scripts": "error",
"require-version": "error",
"description-type": "error",
"devDependencies-type": "error",
"homepage-type": "error",
"keywords-type": "error",
"name-type": "error",
"repository-type": "error",
"version-type": "error",
"valid-values-author": ["error", [
"Thomas Lindner"
]],
"name-format": "error",
"version-format": "error"
}
}
}
Loading

0 comments on commit 498d329

Please sign in to comment.