lint-staged 17.1.0 → 17.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
@@ -1,9 +1,5 @@
1
1
  # 🚫💩 lint-staged
2
2
 
3
- [![npm version](https://badge.fury.io/js/lint-staged.svg)](https://badge.fury.io/js/lint-staged)
4
-
5
- ---
6
-
7
3
  Run tasks like formatters and linters against staged git files and don't let :poop: slip into your code base!
8
4
 
9
5
  ```bash
@@ -168,7 +164,7 @@ By default changes made by tasks are automatically staged and added to the commi
168
164
 
169
165
  #### `--max-arg-length [number]`
170
166
 
171
- long commands (a lot of files) are automatically split into multiple chunks when it detects the current shell cannot handle them. Use this flag to override the maximum length of the generated command string.
167
+ The list of staged files are appended to configured tasks as arguments, and the resulting string might be too long for the current shell, especially on Windows. _Lint-staged_ tries to avoid this by splitting the list of staged files into chunks resulting in the commands being run multiple times. This behavior affects all tasks, including functions. Use the `--max-arg-length` to override the platform-specific default value if you want to avoid this. Setting `--max-arg-length=Infinity` will disable chunking completely.
172
168
 
173
169
  #### `--no-stash`
174
170
 
package/lib/chunkFiles.js CHANGED
@@ -46,8 +46,8 @@ export const chunkFiles = ({ files, baseDir, maxArgLength = null, relative = fal
46
46
  }
47
47
  })
48
48
 
49
- if (!maxArgLength) {
50
- debugLog('Skip chunking files because of undefined maxArgLength')
49
+ if (!maxArgLength || maxArgLength === Infinity) {
50
+ debugLog(`Skip chunking files because of maxArgLength is ${maxArgLength}`)
51
51
  return [normalizedFiles] // wrap in an array to return a single chunk
52
52
  }
53
53
 
package/lib/cli.js CHANGED
@@ -91,7 +91,7 @@ const CLI_OPTIONS = [
91
91
  },
92
92
  {
93
93
  flag: 'max-arg-length',
94
- type: 'string', // Parsed with `parseInt()` below
94
+ type: 'string', // Parsed with `Number()` below
95
95
  positional: '[number]',
96
96
  description: 'maximum length of the command-line argument string (default: 0)',
97
97
  },
@@ -128,6 +128,20 @@ const CLI_OPTIONS = [
128
128
  },
129
129
  ]
130
130
 
131
+ /** @type {(value: string |undefined) => number | boolean | null | undefined} */
132
+ const parseBoolOrNumber = (value) => {
133
+ switch (value) {
134
+ case undefined:
135
+ return undefined
136
+ case 'true':
137
+ return true
138
+ case 'false':
139
+ return false
140
+ default:
141
+ return Number(value)
142
+ }
143
+ }
144
+
131
145
  /** @param {string[]} argv */
132
146
  export const parseCliOptions = (argv) => {
133
147
  const options = CLI_OPTIONS.reduce((acc, current) => {
@@ -167,18 +181,9 @@ export const parseCliOptions = (argv) => {
167
181
  values['hide-unstaged'] = false // becomes redundant
168
182
  }
169
183
 
170
- const maxArgLength =
171
- values['max-arg-length'] !== undefined ? parseInt(values['max-arg-length'], 10) : undefined
172
-
173
- if (Number.isNaN(maxArgLength)) {
174
- throw new TypeError(`Option '--mar-arg-length' takes a numeric argument`, {
175
- cause: { '--max-arg-length': values['max-arg-length'] },
176
- })
177
- }
178
-
179
184
  return {
180
185
  allowEmpty: values['allow-empty'] ?? false,
181
- concurrent: values.concurrent === undefined ? true : JSON.parse(values.concurrent),
186
+ concurrent: parseBoolOrNumber(values.concurrent) ?? true,
182
187
  configPath: values.config,
183
188
  continueOnError: !!values['continue-on-error'],
184
189
  cwd: values.cwd,
@@ -190,7 +195,7 @@ export const parseCliOptions = (argv) => {
190
195
  hidePartiallyStaged: values['hide-partially-staged'] ?? true,
191
196
  hideUnstaged: !!values['hide-unstaged'],
192
197
  hideAll: !!values['hide-all'],
193
- maxArgLength,
198
+ maxArgLength: parseBoolOrNumber(values['max-arg-length']),
194
199
  quiet: !!values.quiet,
195
200
  relative: !!values.relative,
196
201
  revert: values.revert ?? true,
package/lib/index.js CHANGED
@@ -28,7 +28,8 @@ import { getVersion } from './version.js'
28
28
  const debugLog = createDebug('lint-staged')
29
29
 
30
30
  /**
31
- * Get the maximum length of a command-line argument string based on current platform
31
+ * Get the maximum length of a command-line argument string based on current platform,
32
+ * roughly half of the real maximum length
32
33
  *
33
34
  * https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x
34
35
  * https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation
@@ -36,12 +37,12 @@ const debugLog = createDebug('lint-staged')
36
37
  */
37
38
  const getMaxArgLength = () => {
38
39
  switch (process.platform) {
39
- case 'darwin':
40
- return 262144
41
- case 'win32':
42
- return 8191
43
- default:
44
- return 131072
40
+ case 'darwin': // 262_144
41
+ return 131_072
42
+ case 'win32': // 8_191
43
+ return 4_096
44
+ default: // 131_072
45
+ return 65_536
45
46
  }
46
47
  }
47
48
 
@@ -91,7 +92,7 @@ const lintStaged = async (
91
92
  hideAll = false,
92
93
  hideUnstaged = false,
93
94
  hidePartiallyStaged = !(hideAll || hideUnstaged),
94
- maxArgLength = getMaxArgLength() / 2,
95
+ maxArgLength = getMaxArgLength(),
95
96
  quiet = false,
96
97
  relative = false,
97
98
  // Stashing should be disabled by default when the `diff` option is used
@@ -6,15 +6,15 @@ const debugLog = createDebug('lint-staged:runParallelTasks')
6
6
 
7
7
  /** @param {Number | boolean} options.concurrent Boolean value for whether to run concurrently */
8
8
  export const parseConcurrency = (concurrent) => {
9
- if (concurrent === false || concurrent < 1 || Number.isNaN(concurrent)) {
10
- return 1
9
+ if (concurrent === true || concurrent === Infinity) {
10
+ return Infinity
11
11
  }
12
12
 
13
- if (concurrent === true) {
14
- return Infinity
13
+ if (concurrent === false || concurrent < 1 || !Number.isInteger(concurrent)) {
14
+ return 1
15
15
  }
16
16
 
17
- return parseInt(concurrent)
17
+ return concurrent
18
18
  }
19
19
 
20
20
  /**
@@ -8,6 +8,9 @@ import { InvalidOptionsError } from './symbols.js'
8
8
 
9
9
  const debugLog = createDebug('lint-staged:validateOptions')
10
10
 
11
+ /** @type {(value: number) => boolean} */
12
+ const isValidIntegerValue = (value) => Number.isInteger(value) || value === Infinity
13
+
11
14
  /**
12
15
  * Validate lint-staged options, either from the Node.js API or the command line flags.
13
16
  * @param {*} options
@@ -17,26 +20,41 @@ const debugLog = createDebug('lint-staged:validateOptions')
17
20
  export const validateOptions = async (options = {}, logger) => {
18
21
  debugLog('Validating options...')
19
22
 
23
+ const { concurrent, cwd, maxArgLength } = options
24
+
20
25
  if (
21
- options.concurrent !== undefined &&
22
- typeof options.concurrent !== 'boolean' &&
23
- (!Number.isInteger(options.concurrent) || Number.isNaN(options.concurrent))
26
+ concurrent !== undefined &&
27
+ typeof concurrent !== 'boolean' &&
28
+ (!isValidIntegerValue(concurrent) || concurrent < 1)
24
29
  ) {
25
- logger.error(invalidOption('concurrent', `${options.concurrent}`, 'Must be boolean or integer'))
30
+ logger.error(
31
+ invalidOption('concurrent', `${concurrent}`, 'Must be boolean, positive integer or Infinite')
32
+ )
26
33
  throw InvalidOptionsError
27
34
  }
28
35
 
29
36
  /** Ensure the passed cwd option exists; it might also be relative */
30
- if (typeof options.cwd === 'string') {
37
+ if (typeof cwd === 'string') {
31
38
  try {
32
- const resolved = path.resolve(options.cwd)
39
+ const resolved = path.resolve(cwd)
33
40
  await fs.access(resolved, constants.F_OK)
34
41
  } catch (error) {
35
42
  debugLog('Failed to validate options: %o', options)
36
- logger.error(invalidOption('cwd', options.cwd, error.message))
43
+ logger.error(invalidOption('cwd', cwd, error.message))
37
44
  throw InvalidOptionsError
38
45
  }
39
46
  }
40
47
 
48
+ if (
49
+ maxArgLength !== undefined &&
50
+ maxArgLength !== null &&
51
+ (!isValidIntegerValue(maxArgLength) || maxArgLength < 1)
52
+ ) {
53
+ logger.error(
54
+ invalidOption('maxArgLength', `${maxArgLength}`, 'Must be positive integer, or Infinite')
55
+ )
56
+ throw InvalidOptionsError
57
+ }
58
+
41
59
  debugLog('Validated options: %o', options)
42
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-staged",
3
- "version": "17.1.0",
3
+ "version": "17.1.1",
4
4
  "description": "Lint files staged by git",
5
5
  "license": "MIT",
6
6
  "repository": {