lint-staged 5.0.0 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,6 +50,32 @@ See [examples](#examples) and [configuration](#configuration) below.
50
50
  >
51
51
  > To mitigate this rename your `commit` npm script to something non git hook namespace like, for example `{ cz: git-cz }`
52
52
 
53
+ ## Changelog
54
+
55
+ [releases](https://github.com/okonet/lint-staged/releases)
56
+
57
+ ## Command line flags
58
+
59
+ ```
60
+ $ ./node_modules/.bin/lint-staged --help
61
+
62
+ Usage: lint-staged [options]
63
+
64
+
65
+ Options:
66
+
67
+ -V, --version output the version number
68
+ -c, --config [path] Path to configuration file
69
+ -d, --debug Enable debug mode
70
+ -h, --help output usage information
71
+ ```
72
+
73
+ * **`--config [path]`**: This can be used to manually specify the `lint-staged` config file location. However, if the specified file cannot be found, it will error out instead of performing the usual search.
74
+ * **`--debug`**: Enabling the debug mode does the following:
75
+ - `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`.
76
+ - Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`.
77
+ - Do not pass `--silent` to npm scripts.
78
+
53
79
  ## Configuration
54
80
 
55
81
  Starting with v3.1 you can now use different ways of configuring it:
@@ -98,16 +124,19 @@ To set options and keep lint-staged extensible, advanced format can be used. Thi
98
124
 
99
125
  ## Options
100
126
 
101
- * `linters` — `Object` — keys (`String`) are glob patterns, values (`Array<String> | String`) are commands to execute.
102
127
  * `concurrent` — *true* — runs linters for each glob pattern simultaneously. If you don’t want this, you can set `concurrent: false`
103
128
  * `chunkSize` — Max allowed chunk size based on number of files for glob pattern. This is important on windows based systems to avoid command length limitations. See [#147](https://github.com/okonet/lint-staged/issues/147)
129
+ * `globOptions` — `{ matchBase: true, dot: true }` — [minimatch options](https://github.com/isaacs/minimatch#options) to
130
+ customize how glob patterns match files.
131
+ * `ignore` - `['**/docs/**/*.js']` - array of glob patterns to entirely ignore from any task.
132
+ * `linters` — `Object` — keys (`String`) are glob patterns, values (`Array<String> | String`) are commands to execute.
104
133
  * `subTaskConcurrency` — `1` — Controls concurrency for processing chunks generated for each linter. Execution is **not** concurrent by default(see [#225](https://github.com/okonet/lint-staged/issues/225))
105
- * `verbose` — *false* — runs lint-staged in verbose mode. When `true` it will use https://github.com/SamVerschueren/listr-verbose-renderer.
106
- * `globOptions` — `{ matchBase: true, dot: true }` — [minimatch options](https://github.com/isaacs/minimatch#options) to customize how glob patterns match files.
107
134
 
108
135
  ## Filtering files
109
136
 
110
- It is possible to run linters for certain paths only by using [minimatch](https://github.com/isaacs/minimatch) patterns. The paths used for filtering via minimatch are relative to the directory that contains the `.git` directory. The paths passed to the linters are absolute to avoid confusion in case they're executed with a different working directory, as would be the case when using the `gitDir` option.
137
+ It is possible to run linters for certain paths only by using glob patterns. [minimatch](https://github.com/isaacs/minimatch) is used to filter the staged files according to these patterns. File patterns should be specified _relative to the `package.json` location_ (i.e. where `lint-staged` is installed).
138
+
139
+ **NOTE:** If you're using `lint-staged<5` globs have to be _relative to the git root_.
111
140
 
112
141
  ```js
113
142
  {
@@ -122,6 +151,17 @@ It is possible to run linters for certain paths only by using [minimatch](https:
122
151
  }
123
152
  ```
124
153
 
154
+ When matching, `lint-staged` will do the following
155
+
156
+ * Resolve the git root automatically, no configuration needed.
157
+ * Pick the staged files which are present inside the project directory.
158
+ * Filter them using the specified glob patterns.
159
+ * Pass absolute paths to the linters as arguments.
160
+
161
+ **NOTE:** `lint-staged` will pass _absolute_ paths to the linters to avoid any confusion in case they're executed in a different working directory (i.e. when your `.git` directory isn't the same as your `package.json` directory).
162
+
163
+ Also see [How to use `lint-staged` in a multi package monorepo?](#how-to-use-lint-staged-in-a-multi-package-monorepo)
164
+
125
165
  ## What commands are supported?
126
166
 
127
167
  Supported are both local npm scripts (`npm run-script`), or any executables installed locally or globally via `npm` as well as any executable from your $PATH.
@@ -140,6 +180,15 @@ Pass arguments to your commands separated by space as you would do in the shell.
140
180
 
141
181
  Starting from [v2.0.0](https://github.com/okonet/lint-staged/releases/tag/2.0.0) sequences of commands are supported. Pass an array of commands instead of a single one and they will run sequentially. This is useful for running autoformatting tools like `eslint --fix` or `stylefmt` but can be used for any arbitrary sequences.
142
182
 
183
+ ## How to use `lint-staged` in a multi package monorepo?
184
+
185
+ Starting with v5.0, `lint-staged` automatically resolves the git root **without any** additional configuration. You configure `lint-staged` as you normally would if your project root and git root were the same directory.
186
+
187
+ If you wish to use `lint-staged` in a multi package monorepo, it is recommended to install [`husky`](https://github.com/typicode/husky) in the root package.json.
188
+ [`lerna`](https://github.com/lerna/lerna) can be used to execute the `precommit` script in all sub-packages.
189
+
190
+ Example repo: [sudo-suhas/lint-staged-multi-pkg](https://github.com/sudo-suhas/lint-staged-multi-pkg).
191
+
143
192
  ## Reformatting the code
144
193
 
145
194
  Tools like ESLint/TSLint or stylefmt can reformat your code according to an appropriate config by running `eslint --fix`/`tslint --fix`. After the code is reformatted, we want it to be added to the same commit. This can be done using following config:
@@ -223,3 +272,22 @@ This will run `eslint --fix` and automatically add changes to the commit. Please
223
272
  ]
224
273
  }
225
274
  ```
275
+
276
+ ### Minify the images and add files to commit
277
+
278
+ ```json
279
+ {
280
+ "*.{png,jpeg,jpg,gif,svg}": [
281
+ "imagemin-lint-staged",
282
+ "git add"
283
+ ]
284
+ }
285
+ ```
286
+
287
+ <details>
288
+ <summary>More about <code>imagemin-lint-staged</code></summary>
289
+
290
+ [imagemin-lint-staged](https://github.com/tomchentw/imagemin-lint-staged) is a CLI tool designed for lint-staged usage with sensible defaults.
291
+
292
+ See more on [this blog post](https://medium.com/@tomchentw/imagemin-lint-staged-in-place-minify-the-images-before-adding-to-the-git-repo-5acda0b4c57e) for benefits of this approach.
293
+ </details>
package/index.js CHANGED
@@ -3,11 +3,21 @@
3
3
  'use strict'
4
4
 
5
5
  const cmdline = require('commander')
6
+ const debugLib = require('debug')
6
7
  const pkg = require('./package.json')
7
8
 
9
+ const debug = debugLib('lint-staged:bin')
10
+
8
11
  cmdline
9
12
  .version(pkg.version)
10
13
  .option('-c, --config [path]', 'Path to configuration file')
14
+ .option('-d, --debug', 'Enable debug mode')
11
15
  .parse(process.argv)
12
16
 
13
- require('./src')(console, cmdline.config)
17
+ if (cmdline.debug) {
18
+ debugLib.enable('lint-staged*')
19
+ }
20
+
21
+ debug('Running `lint-staged@%s`', pkg.version)
22
+
23
+ require('./src')(console, cmdline.config, cmdline.debug)
package/package.json CHANGED
@@ -1 +1,88 @@
1
- {"name":"lint-staged","version":"5.0.0","description":"Lint files staged by git","license":"MIT","repository":"https://github.com/okonet/lint-staged","author":"Andrey Okonetchnikov <andrey@okonet.ru>","maintainers":["Lufty Wiranda <lufty.wiranda@gmail.com","Suhas Karanth <sudo.suhas@gmail.com"],"engines":{"node":">=4.2.0"},"bin":"index.js","files":["index.js","src"],"scripts":{"precommit":"remove-lockfiles && node index.js","cz":"git-cz","lint":"eslint .","lint:fix":"npm run lint -- --fix","pretest":"npm run lint","test":"jest --coverage","test:watch":"jest --watch"},"dependencies":{"app-root-path":"^2.0.0","chalk":"^2.1.0","commander":"^2.11.0","cosmiconfig":"^3.1.0","dedent":"^0.7.0","execa":"^0.8.0","find-parent-dir":"^0.3.0","is-glob":"^4.0.0","jest-validate":"^21.1.0","listr":"^0.13.0","lodash":"^4.17.4","log-symbols":"^2.0.0","minimatch":"^3.0.0","npm-which":"^3.0.1","p-map":"^1.1.1","path-is-inside":"^1.0.2","pify":"^3.0.0","staged-git-files":"0.0.4","stringify-object":"^3.2.0"},"devDependencies":{"babel-jest":"^21.0.2","babel-preset-env":"^1.6.0","commitizen":"^2.9.6","consolemock":"^0.3.0","cz-conventional-changelog":"^2.0.0","eslint":"^4.5.0","eslint-config-okonet":"^5.0.1","eslint-plugin-node":"^5.1.1","husky":"^0.14.3","jest":"^21.1.0","jest-cli":"^21.1.0","jsonlint":"^1.6.2","prettier":"1.7.4","remove-lockfiles":"^1.1.1"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"jest":{"testEnvironment":"node","setupFiles":["./testSetup.js"]},"keywords":["lint","git","staged","eslint","prettier","stylelint","code","quality","check","format","validate"]}
1
+ {
2
+ "name": "lint-staged",
3
+ "version": "6.1.1",
4
+ "description": "Lint files staged by git",
5
+ "license": "MIT",
6
+ "repository": "https://github.com/okonet/lint-staged",
7
+ "author": "Andrey Okonetchnikov <andrey@okonet.ru>",
8
+ "maintainers": [
9
+ "Lufty Wiranda <lufty.wiranda@gmail.com>",
10
+ "Suhas Karanth <sudo.suhas@gmail.com>"
11
+ ],
12
+ "engines": {
13
+ "node": ">=4.2.0"
14
+ },
15
+ "bin": "index.js",
16
+ "files": [
17
+ "index.js",
18
+ "src"
19
+ ],
20
+ "scripts": {
21
+ "precommit": "node index.js",
22
+ "cz": "git-cz",
23
+ "lint": "eslint .",
24
+ "lint:fix": "yarn lint --fix",
25
+ "pretest": "yarn lint",
26
+ "test": "jest --coverage",
27
+ "test:watch": "jest --watch"
28
+ },
29
+ "dependencies": {
30
+ "app-root-path": "^2.0.0",
31
+ "chalk": "^2.1.0",
32
+ "commander": "^2.11.0",
33
+ "cosmiconfig": "^4.0.0",
34
+ "debug": "^3.1.0",
35
+ "dedent": "^0.7.0",
36
+ "execa": "^0.8.0",
37
+ "find-parent-dir": "^0.3.0",
38
+ "is-glob": "^4.0.0",
39
+ "jest-validate": "^21.1.0",
40
+ "listr": "^0.13.0",
41
+ "lodash": "^4.17.4",
42
+ "log-symbols": "^2.0.0",
43
+ "minimatch": "^3.0.0",
44
+ "npm-which": "^3.0.1",
45
+ "p-map": "^1.1.1",
46
+ "path-is-inside": "^1.0.2",
47
+ "pify": "^3.0.0",
48
+ "staged-git-files": "1.0.0",
49
+ "stringify-object": "^3.2.0"
50
+ },
51
+ "devDependencies": {
52
+ "babel-preset-env": "^1.6.0",
53
+ "commitizen": "^2.9.6",
54
+ "consolemock": "^1.0.2",
55
+ "cz-conventional-changelog": "^2.0.0",
56
+ "eslint": "^4.5.0",
57
+ "eslint-config-okonet": "^5.0.1",
58
+ "eslint-plugin-node": "^5.1.1",
59
+ "husky": "^0.14.3",
60
+ "jest": "^22.0.4",
61
+ "jsonlint": "^1.6.2",
62
+ "prettier": "1.9.2"
63
+ },
64
+ "config": {
65
+ "commitizen": {
66
+ "path": "./node_modules/cz-conventional-changelog"
67
+ }
68
+ },
69
+ "jest": {
70
+ "testEnvironment": "node",
71
+ "setupFiles": [
72
+ "./testSetup.js"
73
+ ]
74
+ },
75
+ "keywords": [
76
+ "lint",
77
+ "git",
78
+ "staged",
79
+ "eslint",
80
+ "prettier",
81
+ "stylelint",
82
+ "code",
83
+ "quality",
84
+ "check",
85
+ "format",
86
+ "validate"
87
+ ]
88
+ }
package/src/findBin.js CHANGED
@@ -2,11 +2,14 @@
2
2
 
3
3
  const npmWhich = require('npm-which')(process.cwd())
4
4
 
5
- module.exports = function findBin(cmd, scripts, options) {
5
+ const debug = require('debug')('lint-staged:find-bin')
6
+
7
+ module.exports = function findBin(cmd, scripts, debugMode) {
8
+ debug('Resolving binary for command `%s`', cmd)
6
9
  const npmArgs = (bin, args) =>
7
10
  // We always add `--` even if args are not defined. This is required
8
11
  // because we pass filenames later.
9
- ['run', options && options.verbose ? undefined : '--silent', bin, '--']
12
+ ['run', debugMode ? undefined : '--silent', bin, '--']
10
13
  // args could be undefined but we filter that out.
11
14
  .concat(args)
12
15
  .filter(arg => arg !== undefined)
@@ -39,6 +42,7 @@ module.exports = function findBin(cmd, scripts, options) {
39
42
  */
40
43
  if (scripts[cmd] !== undefined) {
41
44
  // Support for scripts from package.json
45
+ debug('`%s` resolved to npm script - `%s`', cmd, scripts[cmd])
42
46
  return { bin: 'npm', args: npmArgs(cmd) }
43
47
  }
44
48
 
@@ -47,6 +51,7 @@ module.exports = function findBin(cmd, scripts, options) {
47
51
  const args = parts.splice(1)
48
52
 
49
53
  if (scripts[bin] !== undefined) {
54
+ debug('`%s` resolved to npm script - `%s`', bin, scripts[bin])
50
55
  return { bin: 'npm', args: npmArgs(bin, args) }
51
56
  }
52
57
 
@@ -76,5 +81,6 @@ module.exports = function findBin(cmd, scripts, options) {
76
81
  throw new Error(`${bin} could not be found. Try \`npm install ${bin}\`.`)
77
82
  }
78
83
 
84
+ debug('Binary for `%s` resolved to `%s`', cmd, bin)
79
85
  return { bin, args }
80
86
  }
@@ -6,10 +6,20 @@ const pathIsInside = require('path-is-inside')
6
6
  const getConfig = require('./getConfig').getConfig
7
7
  const resolveGitDir = require('./resolveGitDir')
8
8
 
9
+ const debug = require('debug')('lint-staged:gen-tasks')
10
+
9
11
  module.exports = function generateTasks(config, relFiles) {
12
+ debug('Generating linter tasks')
13
+
10
14
  const normalizedConfig = getConfig(config) // Ensure we have a normalized config
11
15
  const linters = normalizedConfig.linters
12
16
  const globOptions = normalizedConfig.globOptions
17
+ const ignoreFilters = normalizedConfig.ignore.map(pattern => minimatch.filter(pattern))
18
+ // if there are filters, then return false if the input matches any
19
+ // if there are not, then return true for all input
20
+ const ignoreFilter = ignoreFilters.length
21
+ ? input => !ignoreFilters.some(filter => filter(input))
22
+ : () => true
13
23
 
14
24
  const gitDir = resolveGitDir()
15
25
  const cwd = process.cwd()
@@ -26,13 +36,13 @@ module.exports = function generateTasks(config, relFiles) {
26
36
  .map(file => path.relative(cwd, file))
27
37
  // We want to filter before resolving paths
28
38
  .filter(filter)
39
+ .filter(ignoreFilter)
29
40
  // Return absolute path after the filter is run
30
41
  .map(file => path.resolve(cwd, file))
31
42
 
32
- return {
33
- pattern,
34
- commands,
35
- fileList
36
- }
43
+ const task = { pattern, commands, fileList }
44
+ debug('Generated task: \n%O', task)
45
+
46
+ return task
37
47
  })
38
48
  }
package/src/getConfig.js CHANGED
@@ -12,10 +12,12 @@ const logValidationWarning = require('jest-validate').logValidationWarning
12
12
  const unknownOptionWarning = require('jest-validate/build/warnings').unknownOptionWarning
13
13
  const isGlob = require('is-glob')
14
14
 
15
+ const debug = require('debug')('lint-staged:cfg')
16
+
15
17
  /**
16
18
  * Default config object
17
19
  *
18
- * @type {{concurrent: boolean, chunkSize: number, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, subTaskConcurrency: number, renderer: string, verbose: boolean}}
20
+ * @type {{concurrent: boolean, chunkSize: number, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, subTaskConcurrency: number, renderer: string}}
19
21
  */
20
22
  const defaultConfig = {
21
23
  concurrent: true,
@@ -25,9 +27,9 @@ const defaultConfig = {
25
27
  dot: true
26
28
  },
27
29
  linters: {},
30
+ ignore: [],
28
31
  subTaskConcurrency: 1,
29
- renderer: 'update',
30
- verbose: false
32
+ renderer: 'update'
31
33
  }
32
34
 
33
35
  /**
@@ -72,7 +74,7 @@ function unknownValidationReporter(config, example, option, options) {
72
74
  will fix it and remove this message.`
73
75
 
74
76
  const comment = options.comment
75
- const name = (options.title && options.title.warning) || 'WARNING'
77
+ const name = options.title.warning
76
78
  return logValidationWarning(name, message, comment)
77
79
  }
78
80
  // If it is not glob pattern, use default jest-validate reporter
@@ -88,10 +90,11 @@ function unknownValidationReporter(config, example, option, options) {
88
90
  *
89
91
  * @param {Object} sourceConfig
90
92
  * @returns {{
91
- * concurrent: boolean, chunkSize: number, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, subTaskConcurrency: number, renderer: string, verbose: boolean
93
+ * concurrent: boolean, chunkSize: number, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, subTaskConcurrency: number, renderer: string
92
94
  * }}
93
95
  */
94
- function getConfig(sourceConfig) {
96
+ function getConfig(sourceConfig, debugMode) {
97
+ debug('Normalizing config')
95
98
  const config = defaultsDeep(
96
99
  {}, // Do not mutate sourceConfig!!!
97
100
  isSimple(sourceConfig) ? { linters: sourceConfig } : sourceConfig,
@@ -100,18 +103,25 @@ function getConfig(sourceConfig) {
100
103
 
101
104
  // Check if renderer is set in sourceConfig and if not, set accordingly to verbose
102
105
  if (isObject(sourceConfig) && !sourceConfig.hasOwnProperty('renderer')) {
103
- config.renderer = config.verbose ? 'verbose' : 'update'
106
+ config.renderer = debugMode ? 'verbose' : 'update'
104
107
  }
105
108
 
106
109
  return config
107
110
  }
108
111
 
112
+ const optRmMsg = (opt, helpMsg) => ` Option ${chalk.bold(opt)} was removed.
113
+
114
+ ${helpMsg}
115
+
116
+ Please remove ${chalk.bold(opt)} from your configuration.`
117
+
109
118
  /**
110
119
  * Runs config validation. Throws error if the config is not valid.
111
120
  * @param config {Object}
112
121
  * @returns config {Object}
113
122
  */
114
123
  function validateConfig(config) {
124
+ debug('Validating config')
115
125
  const exampleConfig = Object.assign({}, defaultConfig, {
116
126
  linters: {
117
127
  '*.js': ['eslint --fix', 'git add'],
@@ -120,14 +130,12 @@ function validateConfig(config) {
120
130
  })
121
131
 
122
132
  const deprecatedConfig = {
123
- gitDir: () => ` Option ${chalk.bold('gitDir')} was removed.
124
-
125
- lint-staged now automatically resolves '.git' directory.
126
-
127
- Please remove ${chalk.bold('gitDir')} from your configuration.`
133
+ gitDir: () => optRmMsg('gitDir', "lint-staged now automatically resolves '.git' directory."),
134
+ verbose: () =>
135
+ optRmMsg('verbose', `Use the command line flag ${chalk.bold('--debug')} instead.`)
128
136
  }
129
137
 
130
- const validation = validate(config, {
138
+ validate(config, {
131
139
  exampleConfig,
132
140
  deprecatedConfig,
133
141
  unknown: unknownValidationReporter,
@@ -135,10 +143,6 @@ function validateConfig(config) {
135
143
  'Please refer to https://github.com/okonet/lint-staged#configuration for more information...'
136
144
  })
137
145
 
138
- if (!validation.isValid) {
139
- throw new Error('lint-staged config is invalid... Aborting.')
140
- }
141
-
142
146
  return config
143
147
  }
144
148
 
package/src/index.js CHANGED
@@ -11,8 +11,9 @@ const validateConfig = require('./getConfig').validateConfig
11
11
  const printErrors = require('./printErrors')
12
12
  const runAll = require('./runAll')
13
13
 
14
+ const debug = require('debug')('lint-staged')
15
+
14
16
  // Find the right package.json at the root of the project
15
- // TODO: Test if it should be aware of `gitDir`
16
17
  const packageJson = require(appRoot.resolve('package.json'))
17
18
 
18
19
  // Force colors for packages that depend on https://www.npmjs.com/package/supports-color
@@ -26,7 +27,8 @@ const errConfigNotFound = new Error('Config could not be found')
26
27
  /**
27
28
  * Root lint-staged function that is called from .bin
28
29
  */
29
- module.exports = function lintStaged(injectedLogger, configPath) {
30
+ module.exports = function lintStaged(injectedLogger, configPath, debugMode) {
31
+ debug('Loading config using `cosmiconfig`')
30
32
  const logger = injectedLogger || console
31
33
 
32
34
  const explorer = cosmiconfig('lint-staged', {
@@ -36,23 +38,30 @@ module.exports = function lintStaged(injectedLogger, configPath) {
36
38
  })
37
39
 
38
40
  return explorer
39
- .load(process.cwd())
41
+ .load()
40
42
  .then(result => {
41
43
  if (result == null) throw errConfigNotFound
42
44
 
45
+ debug('Successfully loaded config from `%s`:\n%O', result.filepath, result.config)
43
46
  // result.config is the parsed configuration object
44
47
  // result.filepath is the path to the config file that was found
45
- const config = validateConfig(getConfig(result.config))
46
-
47
- if (config.verbose) {
48
+ const config = validateConfig(getConfig(result.config, debugMode))
49
+ if (debugMode) {
50
+ // Log using logger to be able to test through `consolemock`.
48
51
  logger.log('Running lint-staged with the following config:')
49
52
  logger.log(stringifyObject(config, { indent: ' ' }))
53
+ } else {
54
+ // We might not be in debug mode but `DEBUG=lint-staged*` could have
55
+ // been set.
56
+ debug('Normalized config:\n%O', config)
50
57
  }
51
58
 
52
59
  const scripts = packageJson.scripts || {}
60
+ debug('Loaded scripts from package.json:\n%O', scripts)
53
61
 
54
- runAll(scripts, config)
62
+ runAll(scripts, config, debugMode)
55
63
  .then(() => {
64
+ debug('linters were executed successfully!')
56
65
  // No errors, exiting with 0
57
66
  process.exitCode = 0
58
67
  })
package/src/runAll.js CHANGED
@@ -8,30 +8,36 @@ const runScript = require('./runScript')
8
8
  const generateTasks = require('./generateTasks')
9
9
  const resolveGitDir = require('./resolveGitDir')
10
10
 
11
+ const debug = require('debug')('lint-staged:run')
12
+
11
13
  /**
12
14
  * Executes all tasks and either resolves or rejects the promise
13
15
  * @param scripts
14
16
  * @param config {Object}
15
17
  * @returns {Promise}
16
18
  */
17
- module.exports = function runAll(scripts, config) {
19
+ module.exports = function runAll(scripts, config, debugMode) {
20
+ debug('Running all linter scripts')
18
21
  // Config validation
19
22
  if (!config || !has(config, 'concurrent') || !has(config, 'renderer')) {
20
23
  throw new Error('Invalid config provided to runAll! Use getConfig instead.')
21
24
  }
22
25
 
23
- const gitDir = config.gitDir
24
26
  const concurrent = config.concurrent
25
27
  const renderer = config.renderer
26
- sgf.cwd = resolveGitDir(gitDir)
28
+ const gitDir = resolveGitDir()
29
+ debug('Resolved git directory to be `%s`', gitDir)
27
30
 
31
+ sgf.cwd = gitDir
28
32
  return pify(sgf)('ACM').then(files => {
29
33
  /* files is an Object{ filename: String, status: String } */
30
34
  const filenames = files.map(file => file.filename)
35
+ debug('Loaded list of staged files in git:\n%O', filenames)
36
+
31
37
  const tasks = generateTasks(config, filenames).map(task => ({
32
38
  title: `Running tasks for ${task.pattern}`,
33
39
  task: () =>
34
- new Listr(runScript(task.commands, task.fileList, scripts, config), {
40
+ new Listr(runScript(task.commands, task.fileList, scripts, config, debugMode), {
35
41
  // In sub-tasks we don't want to run concurrently
36
42
  // and we want to abort on errors
37
43
  dateFormat: false,
package/src/runScript.js CHANGED
@@ -10,7 +10,11 @@ const calcChunkSize = require('./calcChunkSize')
10
10
  const findBin = require('./findBin')
11
11
  const resolveGitDir = require('./resolveGitDir')
12
12
 
13
- module.exports = function runScript(commands, pathsToLint, scripts, config) {
13
+ const debug = require('debug')('lint-staged:run-script')
14
+
15
+ module.exports = function runScript(commands, pathsToLint, scripts, config, debugMode) {
16
+ debug('Running script with commands %o', commands)
17
+
14
18
  const normalizedConfig = getConfig(config)
15
19
  const chunkSize = normalizedConfig.chunkSize
16
20
  const concurrency = normalizedConfig.subTaskConcurrency
@@ -24,7 +28,7 @@ module.exports = function runScript(commands, pathsToLint, scripts, config) {
24
28
  title: linter,
25
29
  task: () => {
26
30
  try {
27
- const res = findBin(linter, scripts, config)
31
+ const res = findBin(linter, scripts, debugMode)
28
32
 
29
33
  // Only use gitDir as CWD if we are using the git binary
30
34
  // e.g `npm` should run tasks in the actual CWD
@@ -35,6 +39,10 @@ module.exports = function runScript(commands, pathsToLint, scripts, config) {
35
39
  const mapper = pathsChunk => {
36
40
  const args = res.args.concat(pathsChunk)
37
41
 
42
+ debug('bin:', res.bin)
43
+ debug('args: %O', args)
44
+ debug('opts: %o', execaOptions)
45
+
38
46
  return (
39
47
  execa(res.bin, args, Object.assign({}, execaOptions))
40
48
  /* If we don't catch, pMap will terminate on first rejection */
@@ -59,6 +67,7 @@ module.exports = function runScript(commands, pathsToLint, scripts, config) {
59
67
  const errStdout = errors.map(err => err.stdout).join('')
60
68
  const errStderr = errors.map(err => err.stderr).join('')
61
69
 
70
+ // prettier-ignore
62
71
  throw new Error(dedent`
63
72
  ${logSymbols.error} ${linter} found some errors. Please fix them and try committing again.
64
73
  ${errStdout}