lint-staged
Advanced tools
Comparing version 12.3.8 to 12.4.0
@@ -37,2 +37,3 @@ #!/usr/bin/env node | ||
.option('-d, --debug', 'print additional debug information', false) | ||
.option('--max-arg-length', 'maximum length of the command-line argument string') | ||
.option('--no-stash', 'disable the backup stash, and do not revert in case of errors', false) | ||
@@ -58,20 +59,2 @@ .option('-q, --quiet', 'disable lint-staged’s own console output', false) | ||
/** | ||
* Get the maximum length of a command-line argument string based on current platform | ||
* | ||
* https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x | ||
* https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation | ||
* https://unix.stackexchange.com/a/120652 | ||
*/ | ||
const getMaxArgLength = () => { | ||
switch (process.platform) { | ||
case 'darwin': | ||
return 262144 | ||
case 'win32': | ||
return 8191 | ||
default: | ||
return 131072 | ||
} | ||
} | ||
const options = { | ||
@@ -83,3 +66,3 @@ allowEmpty: !!cmdlineOptions.allowEmpty, | ||
debug: !!cmdlineOptions.debug, | ||
maxArgLength: getMaxArgLength() / 2, | ||
maxArgLength: JSON.parse(cmdlineOptions.maxArgLength || null), | ||
quiet: !!cmdlineOptions.quiet, | ||
@@ -86,0 +69,0 @@ relative: !!cmdlineOptions.relative, |
@@ -24,5 +24,3 @@ import path from 'path' | ||
return Object.entries(config).map(([rawPattern, commands]) => { | ||
let pattern = rawPattern | ||
return Object.entries(config).map(([pattern, commands]) => { | ||
const isParentDirPattern = pattern.startsWith('../') | ||
@@ -44,2 +42,3 @@ | ||
matchBase: !pattern.includes('/'), | ||
posixSlashes: true, | ||
strictBrackets: true, | ||
@@ -46,0 +45,0 @@ }) |
import debug from 'debug' | ||
import { PREVENTED_EMPTY_COMMIT, GIT_ERROR, RESTORE_STASH_EXAMPLE } from './messages.js' | ||
import { | ||
PREVENTED_EMPTY_COMMIT, | ||
GIT_ERROR, | ||
RESTORE_STASH_EXAMPLE, | ||
NO_CONFIGURATION, | ||
} from './messages.js' | ||
import { printTaskOutput } from './printTaskOutput.js' | ||
import { runAll } from './runAll.js' | ||
import { ApplyEmptyCommitError, GetBackupStashError, GitError } from './symbols.js' | ||
import { | ||
ApplyEmptyCommitError, | ||
ConfigNotFoundError, | ||
GetBackupStashError, | ||
GitError, | ||
} from './symbols.js' | ||
import { validateOptions } from './validateOptions.js' | ||
@@ -12,2 +22,20 @@ | ||
/** | ||
* Get the maximum length of a command-line argument string based on current platform | ||
* | ||
* https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x | ||
* https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation | ||
* https://unix.stackexchange.com/a/120652 | ||
*/ | ||
const getMaxArgLength = () => { | ||
switch (process.platform) { | ||
case 'darwin': | ||
return 262144 | ||
case 'win32': | ||
return 8191 | ||
default: | ||
return 131072 | ||
} | ||
} | ||
/** | ||
* @typedef {(...any) => void} LogFunction | ||
@@ -43,3 +71,3 @@ * @typedef {{ error: LogFunction, log: LogFunction, warn: LogFunction }} Logger | ||
debug = false, | ||
maxArgLength, | ||
maxArgLength = getMaxArgLength() / 2, | ||
quiet = false, | ||
@@ -83,3 +111,6 @@ relative = false, | ||
const { ctx } = runAllError | ||
if (ctx.errors.has(ApplyEmptyCommitError)) { | ||
if (ctx.errors.has(ConfigNotFoundError)) { | ||
logger.error(NO_CONFIGURATION) | ||
} else if (ctx.errors.has(ApplyEmptyCommitError)) { | ||
logger.warn(PREVENTED_EMPTY_COMMIT) | ||
@@ -86,0 +117,0 @@ } else if (ctx.errors.has(GitError) && !ctx.errors.has(GetBackupStashError)) { |
@@ -25,2 +25,4 @@ import { redBright, bold, yellow } from 'colorette' | ||
export const NO_CONFIGURATION = `${error} No valid configuration found.` | ||
export const NO_STAGED_FILES = `${info} No staged files found.` | ||
@@ -27,0 +29,0 @@ |
@@ -8,3 +8,5 @@ /** | ||
input | ||
.replace(/\u0000$/, '') // eslint-disable-line no-control-regex | ||
.split('\u0000') | ||
? input | ||
.replace(/\u0000$/, '') // eslint-disable-line no-control-regex | ||
.split('\u0000') | ||
: [] |
@@ -65,4 +65,6 @@ import { redBright, dim } from 'colorette' | ||
const ids = await pidTree(execaChildProcess.pid) | ||
ids.forEach((id) => process.kill(id)) | ||
const childPids = await pidTree(execaChildProcess.pid) | ||
for (const pid of childPids) { | ||
process.kill(pid) | ||
} | ||
@@ -69,0 +71,0 @@ // The execa process is killed separately in order |
@@ -13,6 +13,6 @@ /** @typedef {import('./index').Logger} Logger */ | ||
import { generateTasks } from './generateTasks.js' | ||
import { getConfigGroups } from './getConfigGroups.js' | ||
import { getRenderer } from './getRenderer.js' | ||
import { getStagedFiles } from './getStagedFiles.js' | ||
import { GitWorkflow } from './gitWorkflow.js' | ||
import { groupFilesByConfig } from './groupFilesByConfig.js' | ||
import { makeCmdTasks } from './makeCmdTasks.js' | ||
@@ -40,3 +40,3 @@ import { | ||
import { GitRepoError, GetStagedFilesError, GitError, ConfigNotFoundError } from './symbols.js' | ||
import { searchConfigs } from './searchConfigs.js' | ||
import { ConfigObjectSymbol, searchConfigs } from './searchConfigs.js' | ||
@@ -125,8 +125,5 @@ const debugLog = debug('lint-staged:runAll') | ||
const configGroups = await getConfigGroups({ configObject, configPath, cwd, files }, logger) | ||
const foundConfigs = await searchConfigs({ configObject, configPath, cwd, gitDir }, logger) | ||
const numberOfConfigs = Reflect.ownKeys(foundConfigs).length | ||
const hasExplicitConfig = configObject || configPath | ||
const foundConfigs = hasExplicitConfig ? null : await searchConfigs(gitDir, logger) | ||
const numberOfConfigs = hasExplicitConfig ? 1 : Object.keys(foundConfigs).length | ||
// Throw if no configurations were found | ||
@@ -138,3 +135,3 @@ if (numberOfConfigs === 0) { | ||
debugLog('Found %d configs:\n%O', numberOfConfigs, foundConfigs) | ||
const filesByConfig = await groupFilesByConfig({ configs: foundConfigs, files }) | ||
@@ -159,4 +156,10 @@ const hasMultipleConfigs = numberOfConfigs > 1 | ||
for (const [configPath, { config, files }] of Object.entries(configGroups)) { | ||
const relativeConfig = normalize(path.relative(cwd, configPath)) | ||
for (const configPath of Reflect.ownKeys(filesByConfig)) { | ||
const { config, files } = filesByConfig[configPath] | ||
const configName = | ||
configPath === ConfigObjectSymbol | ||
? 'Config object' | ||
: normalize(path.relative(cwd, configPath)) | ||
const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative }) | ||
@@ -227,3 +230,3 @@ | ||
title: | ||
`${relativeConfig}${dim(` — ${files.length} ${files.length > 1 ? 'files' : 'file'}`)}` + | ||
`${configName}${dim(` — ${files.length} ${files.length > 1 ? 'files' : 'file'}`)}` + | ||
(chunkCount > 1 ? dim(` (chunk ${index + 1}/${chunkCount})...`) : ''), | ||
@@ -236,3 +239,3 @@ task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent, exitOnError: true }), | ||
if (chunkListrTasks.every((task) => task.skip())) { | ||
return `${relativeConfig}${dim(' — no tasks to run')}` | ||
return `${configName}${dim(' — no tasks to run')}` | ||
} | ||
@@ -239,0 +242,0 @@ return false |
@@ -5,2 +5,3 @@ /** @typedef {import('./index').Logger} Logger */ | ||
import debug from 'debug' | ||
import normalize from 'normalize-path' | ||
@@ -13,2 +14,4 @@ | ||
const debugLog = debug('lint-staged:searchConfigs') | ||
const EXEC_GIT = ['ls-files', '-z', '--full-name'] | ||
@@ -22,10 +25,40 @@ | ||
const isInsideDirectory = (dir) => (file) => file.startsWith(normalize(dir)) | ||
export const ConfigObjectSymbol = Symbol() | ||
/** | ||
* Search all config files from the git repository | ||
* Search all config files from the git repository, preferring those inside `cwd`. | ||
* | ||
* @param {string} gitDir | ||
* @param {object} options | ||
* @param {Object} [options.configObject] - Explicit config object from the js API | ||
* @param {string} [options.configPath] - Explicit path to a config file | ||
* @param {string} [options.cwd] - Current working directory | ||
* @param {Logger} logger | ||
* @returns {Promise<{ [key: string]: * }>} found configs with filepath as key, and config as value | ||
* | ||
* @returns {Promise<{ [key: string]: { config: *, files: string[] } }>} found configs with filepath as key, and config as value | ||
*/ | ||
export const searchConfigs = async (gitDir = process.cwd(), logger) => { | ||
export const searchConfigs = async ( | ||
{ configObject, configPath, cwd = process.cwd(), gitDir = cwd }, | ||
logger | ||
) => { | ||
debugLog('Searching for configuration files...') | ||
// Return explicit config object from js API | ||
if (configObject) { | ||
debugLog('Using single direct configuration object...') | ||
return { [ConfigObjectSymbol]: validateConfig(configObject, 'config object', logger) } | ||
} | ||
// Use only explicit config path instead of discovering multiple | ||
if (configPath) { | ||
debugLog('Using single configuration path...') | ||
const { config, filepath } = await loadConfig({ configPath }, logger) | ||
if (!config) return {} | ||
return { [configPath]: validateConfig(config, filepath, logger) } | ||
} | ||
/** Get all possible config files known to git */ | ||
@@ -45,4 +78,7 @@ const cachedFiles = parseGitZOutput(await execGit(EXEC_GIT, { cwd: gitDir })).filter( | ||
.map((file) => normalize(file)) | ||
.filter(isInsideDirectory(cwd)) | ||
.sort(sortDeepestParth) | ||
debugLog('Found possible config files:', possibleConfigFiles) | ||
/** Create object with key as config file, and value as null */ | ||
@@ -72,3 +108,22 @@ const configs = possibleConfigFiles.reduce( | ||
/** | ||
* Try to find a single config from parent directories | ||
* to match old behavior before monorepo support | ||
*/ | ||
if (!Object.keys(foundConfigs).length) { | ||
debugLog('Could not find config files inside "%s"', cwd) | ||
const { config, filepath } = await loadConfig({ cwd }, logger) | ||
if (config) { | ||
debugLog('Found parent configuration file from "%s"', filepath) | ||
foundConfigs[filepath] = validateConfig(config, filepath, logger) | ||
} else { | ||
debugLog('Could not find parent configuration files from "%s"', cwd) | ||
} | ||
} | ||
debugLog('Found %d config files', Object.keys(foundConfigs).length) | ||
return foundConfigs | ||
} |
{ | ||
"name": "lint-staged", | ||
"version": "12.3.8", | ||
"version": "12.4.0", | ||
"description": "Lint files staged by git", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
102103
1801