Socket
Socket
Sign inDemoInstall

lint-staged

Package Overview
Dependencies
Maintainers
1
Versions
250
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lint-staged - npm Package Compare versions

Comparing version 13.2.2 to 14.0.1

lib/normalizePath.js

41

bin/lint-staged.js
#!/usr/bin/env node
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import fs from 'node:fs/promises'

@@ -13,2 +11,3 @@ import { supportsColor } from 'chalk'

import { CONFIG_STDIN_ERROR } from '../lib/messages.js'
import { readStdin } from '../lib/readStdin.js'

@@ -23,4 +22,3 @@ // Force colors for packages that depend on https://www.npmjs.com/package/supports-color

const packageJsonPath = path.join(fileURLToPath(import.meta.url), '../../package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath))
const packageJson = JSON.parse(await fs.readFile(new URL('../package.json', import.meta.url)))
const version = packageJson.version

@@ -47,5 +45,7 @@

cli.option(
'--diff [string]',
'override the default "--staged" flag of "git diff" to get list of files. Implies "--no-stash".'
cli.addOption(
new Option(
'--diff [string]',
'override the default "--staged" flag of "git diff" to get list of files. Implies "--no-stash".'
).implies({ stash: false })
)

@@ -117,21 +117,16 @@

try {
options.config = fs.readFileSync(process.stdin.fd, 'utf8').toString().trim()
} catch {
debugLog('Reading config from stdin')
options.config = JSON.parse(await readStdin())
} catch (error) {
debugLog(CONFIG_STDIN_ERROR, error)
console.error(CONFIG_STDIN_ERROR)
process.exit(1)
}
}
try {
options.config = JSON.parse(options.config)
} catch {
// Let config parsing complain if it's not JSON
}
try {
const passed = await lintStaged(options)
process.exitCode = passed ? 0 : 1
} catch {
process.exitCode = 1
}
lintStaged(options)
.then((passed) => {
process.exitCode = passed ? 0 : 1
})
.catch(() => {
process.exitCode = 1
})
import path from 'node:path'
import debug from 'debug'
import normalize from 'normalize-path'
import { normalizePath } from './normalizePath.js'
const debugLog = debug('lint-staged:chunkFiles')

@@ -38,3 +39,3 @@

const normalizedFiles = files.map((file) =>
normalize(relative || !baseDir ? file : path.resolve(baseDir, file))
normalizePath(relative || !baseDir ? file : path.resolve(baseDir, file))
)

@@ -41,0 +42,0 @@

@@ -5,4 +5,5 @@ import path from 'node:path'

import micromatch from 'micromatch'
import normalize from 'normalize-path'
import { normalizePath } from './normalizePath.js'
const debugLog = debug('lint-staged:generateTasks')

@@ -23,3 +24,3 @@

const relativeFiles = files.map((file) => normalize(path.relative(cwd, file)))
const relativeFiles = files.map((file) => normalizePath(path.relative(cwd, file)))

@@ -47,3 +48,3 @@ return Object.entries(config).map(([pattern, commands]) => {

const fileList = matches.map((file) => normalize(relative ? file : path.resolve(cwd, file)))
const fileList = matches.map((file) => normalizePath(relative ? file : path.resolve(cwd, file)))

@@ -50,0 +51,0 @@ const task = { pattern, commands, fileList }

@@ -1,16 +0,51 @@

const getMainRendererOptions = ({ debug, quiet }, env) => {
if (quiet) return { renderer: 'silent' }
import { EOL } from 'node:os'
import { Writable } from 'node:stream'
import { ListrLogger, ProcessOutput } from 'listr2'
const EOLRegex = new RegExp(EOL + '$')
const bindLogger = (consoleLogMethod) =>
new Writable({
write: function (chunk, encoding, next) {
consoleLogMethod(chunk.toString().replace(EOLRegex, ''))
next()
},
})
const getMainRendererOptions = ({ debug, quiet }, logger, env) => {
if (quiet) {
return {
renderer: 'silent',
}
}
if (env.NODE_ENV === 'test') {
return {
renderer: 'test',
rendererOptions: {
logger: new ListrLogger({
processOutput: new ProcessOutput(bindLogger(logger.log), bindLogger(logger.error)),
}),
},
}
}
// Better support for dumb terminals: https://en.wikipedia.org/wiki/Computer_terminal#Dumb_terminals
const isDumbTerminal = env.TERM === 'dumb'
if (debug || isDumbTerminal || env.NODE_ENV === 'test') return { renderer: 'verbose' }
return { renderer: 'update', rendererOptions: { dateFormat: false } }
if (debug || env.TERM === 'dumb') {
return {
renderer: 'verbose',
}
}
return {
renderer: 'update',
rendererOptions: {
formatOutput: 'truncate',
},
}
}
const getFallbackRenderer = ({ renderer }, { FORCE_COLOR }) => {
if (renderer === 'silent') {
return 'silent'
}
// If colors are being forced, then also force non-fallback rendering
if (Number(FORCE_COLOR) > 0) {
if (renderer === 'silent' || renderer === 'test' || Number(FORCE_COLOR) > 0) {
return renderer

@@ -22,8 +57,9 @@ }

export const getRenderer = (options, env = process.env) => {
const mainRendererOptions = getMainRendererOptions(options, env)
export const getRenderer = (options, logger, env = process.env) => {
const mainRendererOptions = getMainRendererOptions(options, logger, env)
return {
...mainRendererOptions,
nonTTYRenderer: getFallbackRenderer(mainRendererOptions, env),
fallbackRenderer: getFallbackRenderer(mainRendererOptions, env),
}
}
import path from 'node:path'
import normalize from 'normalize-path'
import { execGit } from './execGit.js'
import { getDiffCommand } from './getDiffCommand.js'
import { normalizePath } from './normalizePath.js'
import { parseGitZOutput } from './parseGitZOutput.js'

@@ -14,3 +13,3 @@

return parseGitZOutput(lines).map((file) => normalize(path.resolve(cwd, file)))
return parseGitZOutput(lines).map((file) => normalizePath(path.resolve(cwd, file)))
} catch {

@@ -17,0 +16,0 @@ return null

@@ -1,2 +0,1 @@

import cliTruncate from 'cli-truncate'
import debug from 'debug'

@@ -9,20 +8,3 @@

const STDOUT_COLUMNS_DEFAULT = 80
const listrPrefixLength = {
update: ` X `.length, // indented task title where X is a checkmark or a cross (failure)
verbose: `[STARTED] `.length, // verbose renderer uses 7-letter STARTED/SUCCESS prefixes
}
/**
* Get length of title based on the number of available columns prefix length
* @param {string} renderer The name of the Listr renderer
* @returns {number}
*/
const getTitleLength = (renderer, columns = process.stdout.columns) => {
const prefixLength = listrPrefixLength[renderer] || 0
return (columns || STDOUT_COLUMNS_DEFAULT) - prefixLength
}
/**
* Creates and returns an array of listr tasks which map to the given commands.

@@ -35,7 +17,6 @@ *

* @param {string} options.gitDir
* @param {string} options.renderer
* @param {Boolean} shell
* @param {Boolean} verbose
*/
export const makeCmdTasks = async ({ commands, cwd, files, gitDir, renderer, shell, verbose }) => {
export const makeCmdTasks = async ({ commands, cwd, files, gitDir, shell, verbose }) => {
debugLog('Creating listr tasks for commands %o', commands)

@@ -65,6 +46,4 @@ const commandArray = Array.isArray(commands) ? commands : [commands]

// Truncate title to single line based on renderer
const title = cliTruncate(command, getTitleLength(renderer))
const task = resolveTaskFn({ command, cwd, files, gitDir, isFn, shell, verbose })
cmdTasks.push({ title, command, task })
cmdTasks.push({ title: command, command, task })
}

@@ -71,0 +50,0 @@ }

@@ -0,3 +1,4 @@

import { inspect } from 'node:util'
import chalk from 'chalk'
import inspect from 'object-inspect'

@@ -9,5 +10,3 @@ import { error, info, warning } from './figures.js'

Invalid value for '${chalk.bold(opt)}': ${chalk.bold(
inspect(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY })
)}
Invalid value for '${chalk.bold(opt)}': ${chalk.bold(inspect(value))}

@@ -76,2 +75,2 @@ ${helpMsg}`

export const CONFIG_STDIN_ERROR = 'Error: Could not read config from stdin.'
export const CONFIG_STDIN_ERROR = chalk.redBright(`${error} Failed to read config from stdin.`)

@@ -5,6 +5,6 @@ import fs from 'node:fs/promises'

import debug from 'debug'
import normalize from 'normalize-path'
import { execGit } from './execGit.js'
import { readFile } from './file.js'
import { normalizePath } from './normalizePath.js'

@@ -19,3 +19,3 @@ const debugLog = debug('lint-staged:resolveGitRepo')

// Get the real path in case it's a symlink
const defaultDir = normalize(await fs.realpath(path.join(gitDir, '.git')))
const defaultDir = normalizePath(await fs.realpath(path.join(gitDir, '.git')))
const stats = await fs.lstat(defaultDir)

@@ -38,6 +38,6 @@ // If .git is a directory, use it

// the current working dir is inside the git top-level directory
return normalize(cwd.substring(0, cwd.lastIndexOf(relativeDir)))
return normalizePath(cwd.substring(0, cwd.lastIndexOf(relativeDir)))
} else {
// the current working dir is the top-level git directory
return normalize(cwd)
return normalizePath(cwd)
}

@@ -61,5 +61,5 @@ }

// don't read the toplevel directly, it will lead to an posix conform path on non posix systems (cygwin)
const gitRel = normalize(await execGit(['rev-parse', '--show-prefix'], { cwd }))
const gitDir = determineGitDir(normalize(cwd), gitRel)
const gitConfigDir = normalize(await resolveGitConfigDir(gitDir))
const gitRel = normalizePath(await execGit(['rev-parse', '--show-prefix'], { cwd }))
const gitDir = determineGitDir(normalizePath(cwd), gitRel)
const gitConfigDir = normalizePath(await resolveGitConfigDir(gitDir))

@@ -66,0 +66,0 @@ debugLog('Resolved git directory to be `%s`', gitDir)

@@ -8,3 +8,2 @@ /** @typedef {import('./index').Logger} Logger */

import { Listr } from 'listr2'
import normalize from 'normalize-path'

@@ -28,2 +27,3 @@ import { chunkFiles } from './chunkFiles.js'

} from './messages.js'
import { normalizePath } from './normalizePath.js'
import { resolveGitRepo } from './resolveGitRepo.js'

@@ -156,3 +156,3 @@ import {

registerSignalListeners: false,
...getRenderer({ debug, quiet }),
...getRenderer({ debug, quiet }, logger),
}

@@ -166,3 +166,3 @@

for (const [configPath, { config, files }] of Object.entries(filesByConfig)) {
const configName = configPath ? normalize(path.relative(cwd, configPath)) : 'Config object'
const configName = configPath ? normalizePath(path.relative(cwd, configPath)) : 'Config object'

@@ -189,3 +189,2 @@ const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative })

gitDir,
renderer: listrOptions.renderer,
shell,

@@ -201,3 +200,3 @@ verbose,

? file
: normalize(path.join(groupCwd, file))
: normalizePath(path.join(groupCwd, file))

@@ -204,0 +203,0 @@ matchedFiles.add(normalizedFile)

@@ -6,6 +6,6 @@ /** @typedef {import('./index').Logger} Logger */

import debug from 'debug'
import normalize from 'normalize-path'
import { execGit } from './execGit.js'
import { loadConfig, searchPlaces } from './loadConfig.js'
import { normalizePath } from './normalizePath.js'
import { parseGitZOutput } from './parseGitZOutput.js'

@@ -25,3 +25,3 @@ import { validateConfig } from './validateConfig.js'

const isInsideDirectory = (dir) => (file) => file.startsWith(normalize(dir))
const isInsideDirectory = (dir) => (file) => file.startsWith(normalizePath(dir))

@@ -73,3 +73,3 @@ /**

const possibleConfigFiles = [...cachedFiles, ...otherFiles]
.map((file) => normalize(path.join(gitDir, file)))
.map((file) => normalizePath(path.join(gitDir, file)))
.filter(isInsideDirectory(cwd))

@@ -76,0 +76,0 @@ .sort(sortDeepestParth)

@@ -20,4 +20,4 @@ import { incorrectBraces } from './messages.js'

* @example <caption>Globs with brace expansions</caption>
* - *.{js,tx} // expanded as *.js, *.ts
* - *.{{j,t}s,css} // expanded as *.js, *.ts, *.css
* - *.{js,tx} // expanded as *.js, *.ts
* - *.{{j,t}s,css} // expanded as *.js, *.ts, *.css
* - file_{1..10}.css // expanded as file_1.css, file_2.css, …, file_10.css

@@ -32,3 +32,3 @@ *

*/
export const BRACES_REGEXP = /(?<![\\$])({)(?:(?!(?<!\\),|\.\.|\{|\}).)*?(?<!\\)(})/g
export const INCORRECT_BRACES_REGEXP = /(?<![\\$])({)(?:(?!(?<!\\),|\.\.|\{|\}).)*?(?<!\\)(})/g

@@ -39,7 +39,7 @@ /**

*/
const withoutIncorrectBraces = (pattern) => {
const stripIncorrectBraces = (pattern) => {
let output = `${pattern}`
let match = null
while ((match = BRACES_REGEXP.exec(pattern))) {
while ((match = INCORRECT_BRACES_REGEXP.exec(pattern))) {
const fullMatch = match[0]

@@ -54,2 +54,26 @@ const withoutBraces = fullMatch.replace(/{/, '').replace(/}/, '')

/**
* This RegExp matches "duplicate" opening and closing braces, without any other braces
* in between, where the duplication is redundant and should be removed.
*
* @example *.{{js,ts}} // should just be *.{js,ts}
*/
export const DOUBLE_BRACES_REGEXP = /{{[^}{]*}}/
/**
* @param {string} pattern
* @returns {string}
*/
const stripDoubleBraces = (pattern) => {
let output = `${pattern}`
const match = DOUBLE_BRACES_REGEXP.exec(pattern)?.[0]
if (match) {
const withoutBraces = match.replace('{{', '{').replace('}}', '}')
output = output.replace(match, withoutBraces)
}
return output
}
/**
* Validate and remove incorrect brace expansions from glob pattern.

@@ -64,3 +88,3 @@ * For example `*.{js}` is incorrect because it doesn't contain a `,` or `..`,

export const validateBraces = (pattern, logger) => {
const fixedPattern = withoutIncorrectBraces(pattern)
const fixedPattern = stripDoubleBraces(stripIncorrectBraces(pattern))

@@ -67,0 +91,0 @@ if (fixedPattern !== pattern) {

/** @typedef {import('./index').Logger} Logger */
import { inspect } from 'node:util'
import debug from 'debug'
import inspect from 'object-inspect'

@@ -112,5 +113,5 @@ import { configurationError } from './messages.js'

debugLog('Validated config from `%s`:', configPath)
debugLog(inspect(config, { indent: 2 }))
debugLog(inspect(config, { compact: false }))
return validatedConfig
}
{
"name": "lint-staged",
"version": "13.2.2",
"version": "14.0.1",
"description": "Lint files staged by git",

@@ -17,3 +17,3 @@ "license": "MIT",

"engines": {
"node": "^14.13.1 || >=16.0.0"
"node": "^16.14.0 || >=18.0.0"
},

@@ -37,33 +37,30 @@ "type": "module",

"dependencies": {
"chalk": "5.2.0",
"cli-truncate": "^3.1.0",
"commander": "^10.0.0",
"debug": "^4.3.4",
"execa": "^7.0.0",
"chalk": "5.3.0",
"commander": "11.0.0",
"debug": "4.3.4",
"execa": "7.2.0",
"lilconfig": "2.1.0",
"listr2": "^5.0.7",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"object-inspect": "^1.12.3",
"pidtree": "^0.6.0",
"string-argv": "^0.3.1",
"yaml": "^2.2.2"
"listr2": "6.6.1",
"micromatch": "4.0.5",
"pidtree": "0.6.0",
"string-argv": "0.3.2",
"yaml": "2.3.1"
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/eslint-parser": "^7.19.1",
"@babel/preset-env": "^7.20.2",
"babel-jest": "^29.5.0",
"@babel/core": "7.22.10",
"@babel/eslint-parser": "7.22.10",
"@babel/preset-env": "7.22.10",
"babel-jest": "29.6.2",
"babel-plugin-transform-imports": "2.0.0",
"consolemock": "^1.1.0",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.2.1",
"fs-extra": "^11.1.0",
"husky": "^8.0.3",
"jest": "^29.5.0",
"jest-snapshot-serializer-ansi": "^1.0.0",
"prettier": "^2.8.4"
"consolemock": "1.1.0",
"eslint": "8.46.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "5.0.0",
"husky": "8.0.3",
"jest": "29.6.2",
"jest-snapshot-serializer-ansi": "2.1.0",
"mock-stdin": "1.0.0",
"prettier": "3.0.1"
},

@@ -70,0 +67,0 @@ "keywords": [

@@ -61,3 +61,3 @@ # 🚫💩 lint-staged ![GitHub Actions](https://github.com/okonet/lint-staged/workflows/CI/badge.svg) [![npm version](https://badge.fury.io/js/lint-staged.svg)](https://badge.fury.io/js/lint-staged) [![Codecov](https://codecov.io/gh/okonet/lint-staged/branch/master/graph/badge.svg)](https://codecov.io/gh/okonet/lint-staged)

- for example: `{ "*.js": "eslint" }` to run ESLint for all staged JS files
- See [Configuration](#Configuration) for more info
- See [Configuration](#configuration) for more info

@@ -76,2 +76,6 @@ Don't forget to commit changes to `package.json` and `.husky` to share this setup with your team!

#### v14
- Since `v14.0.0` _lint-staged_ no longer supports Node.js 14. Please upgrade your Node.js version to at least `16.14.0`.
#### v13

@@ -136,3 +140,3 @@

- **`--max-arg-length`**: 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.
- **`--no-stash`**: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit. Can be re-enabled with `--stash`
- **`--no-stash`**: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit. Can be re-enabled with `--stash`.
- **`--quiet`**: Supress all CLI output, except from tasks.

@@ -224,7 +228,7 @@ - **`--relative`**: Pass filepaths relative to `process.cwd()` (where `lint-staged` runs) to tasks. Default is `false`.

- If the glob pattern contains no slashes (`/`), micromatch's `matchBase` option will enabled, so globs match a file's basename regardless of directory:
- **`"*.js"`** will match all JS files, like `/test.js` and `/foo/bar/test.js`
- **`"!(*test).js"`**. will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js`
- `"*.js"` will match all JS files, like `/test.js` and `/foo/bar/test.js`
- `"!(*test).js"` will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js`
- If the glob pattern does contain a slash (`/`), it will match for paths as well:
- **`"./*.js"`** will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js`
- **`"foo/**/*.js"`** will match all JS files inside the `/foo` directory, so `/foo/bar/test.js` but not `/test.js`
- `"./*.js"` will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js`
- `"foo/**/*.js"` will match all JS files inside the `/foo` directory, so `/foo/bar/test.js` but not `/test.js`

@@ -631,5 +635,3 @@ When matching, lint-staged will do the following

const buildEslintCommand = (filenames) =>
`next lint --fix --file ${filenames
.map((f) => path.relative(process.cwd(), f))
.join(' --file ')}`
`next lint --fix --file ${filenames.map((f) => path.relative(process.cwd(), f)).join(' --file ')}`

@@ -636,0 +638,0 @@ module.exports = {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc