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 14.0.1 to 15.2.0

lib/configFiles.js

30

bin/lint-staged.js

@@ -18,2 +18,4 @@ #!/usr/bin/env node

const debugLog = debug('lint-staged:bin')
// Do not terminate main Listr process on SIGINT

@@ -25,5 +27,2 @@ process.on('SIGINT', () => {})

const debugLog = debug('lint-staged:bin')
debugLog('Running `lint-staged@%s`', version)
const cli = program.version(version)

@@ -73,3 +72,23 @@

'--no-stash',
'disable the backup stash, and do not revert in case of errors'
'disable the backup stash, and do not revert in case of errors. Implies "--no-hide-partially-staged".'
)
.default(false)
.implies({ hidePartiallyStaged: false })
)
/**
* We don't want to show the `--hide-partially-staged` flag because it's on by default, and only show the
* negatable flag `--no-hide-partially-staged` in stead. There seems to be a bug in Commander.js where
* configuring only the latter won't actually set the default value.
*/
cli
.addOption(
new Option('--hide-partially-staged', 'hide unstaged changes from partially staged files')
.default(true)
.hideHelp()
)
.addOption(
new Option(
'--no-hide-partially-staged',
'disable hiding unstaged changes from partially staged files'
).default(false)

@@ -96,2 +115,4 @@ )

debugLog('Running `lint-staged@%s` on Node.js %s (%s)', version, process.version, process.platform)
const options = {

@@ -110,2 +131,3 @@ allowEmpty: !!cliOptions.allowEmpty,

stash: !!cliOptions.stash, // commander inverts `no-<x>` flags to `!x`
hidePartiallyStaged: !!cliOptions.hidePartiallyStaged, // commander inverts `no-<x>` flags to `!x`
verbose: !!cliOptions.verbose,

@@ -112,0 +134,0 @@ }

@@ -80,2 +80,3 @@ import debug from 'debug'

stash = diff === undefined,
hidePartiallyStaged = stash,
verbose = false,

@@ -105,2 +106,3 @@ } = {},

stash,
hidePartiallyStaged,
verbose,

@@ -107,0 +109,0 @@ }

90

lib/loadConfig.js
/** @typedef {import('./index').Logger} Logger */
import fs from 'node:fs/promises'
import path from 'node:path'
import debug from 'debug'
import { lilconfig } from 'lilconfig'
import YAML from 'yaml'

@@ -9,31 +11,34 @@

import { resolveConfig } from './resolveConfig.js'
import {
CONFIG_FILE_NAMES,
CONFIG_NAME,
PACKAGE_JSON_FILE,
PACKAGE_YAML_FILES,
} from './configFiles.js'
const debugLog = debug('lint-staged:loadConfig')
const PACKAGE_JSON = 'package.json'
const jsonParse = (filePath, content) => {
const isPackageFile = PACKAGE_JSON_FILE.includes(path.basename(filePath))
try {
const json = JSON.parse(content)
return isPackageFile ? json[CONFIG_NAME] : json
} catch (error) {
if (path.basename(filePath) === PACKAGE_JSON_FILE) {
debugLog('Ignoring invalid package file `%s` with content:\n%s', filePath, content)
return undefined
}
/**
* The list of files `lint-staged` will read configuration
* from, in the declared order.
*/
export const searchPlaces = [
PACKAGE_JSON,
'.lintstagedrc',
'.lintstagedrc.json',
'.lintstagedrc.yaml',
'.lintstagedrc.yml',
'.lintstagedrc.mjs',
'.lintstagedrc.js',
'.lintstagedrc.cjs',
'lint-staged.config.mjs',
'lint-staged.config.js',
'lint-staged.config.cjs',
]
throw error
}
}
const jsonParse = (path, content) => {
const yamlParse = (filePath, content) => {
const isPackageFile = PACKAGE_YAML_FILES.includes(path.basename(filePath))
try {
return JSON.parse(content)
const yaml = YAML.parse(content)
return isPackageFile ? yaml[CONFIG_NAME] : yaml
} catch (error) {
if (path.endsWith(PACKAGE_JSON)) {
debugLog('Ignoring invalid package file `%s` with content:\n%s', path, content)
if (isPackageFile) {
debugLog('Ignoring invalid package file `%s` with content:\n%s', filePath, content)
return undefined

@@ -46,3 +51,3 @@ }

const yamlParse = (path, content) => YAML.parse(content)
const NO_EXT = 'noExt'

@@ -62,7 +67,28 @@ /**

'.yml': yamlParse,
noExt: yamlParse,
[NO_EXT]: yamlParse,
}
const explorer = lilconfig('lint-staged', { searchPlaces, loaders })
const readFile = async (filepath) => {
const absolutePath = path.resolve(filepath)
const file = await fs.readFile(absolutePath)
return await file.toString()
}
const loadConfigByExt = async (filepath) => {
filepath = path.resolve(filepath)
const ext = path.extname(filepath) || NO_EXT
const loader = loaders[ext]
/**
* No need to read file contents when loader only takes in the filepath argument
* and reads itself; this is for `lilconfig` compatibility
*/
const content = loader.length > 1 ? await readFile(filepath) : undefined
return {
config: await loader(filepath, content),
filepath,
}
}
/**

@@ -75,16 +101,18 @@ * @param {object} options

try {
let result
if (configPath) {
debugLog('Loading configuration from `%s`...', configPath)
result = await loadConfigByExt(resolveConfig(configPath))
} else {
debugLog('Searching for configuration from `%s`...', cwd)
const { lilconfig } = await import('lilconfig')
const explorer = lilconfig(CONFIG_NAME, { searchPlaces: CONFIG_FILE_NAMES, loaders })
result = await explorer.search(cwd)
}
const result = await (configPath
? explorer.load(resolveConfig(configPath))
: explorer.search(cwd))
if (!result) return {}
// config is a promise when using the `dynamicImport` loader
const config = await result.config
const config = (await result.config) ?? null
const filepath = result.filepath

@@ -91,0 +119,0 @@

@@ -27,4 +27,6 @@ import debug from 'debug'

const isFn = typeof cmd === 'function'
const resolved = isFn ? await cmd(files) : cmd
/** Pass copy of file list to prevent mutation by function from config file. */
const resolved = isFn ? await cmd([...files]) : cmd
const resolvedArray = Array.isArray(resolved) ? resolved : [resolved] // Wrap non-array command as array

@@ -31,0 +33,0 @@

@@ -35,4 +35,4 @@ import { inspect } from 'node:util'

: hasInitialCommit
? '`--no-stash` was used'
: 'there’s no initial commit yet'
? '`--no-stash` was used'
: 'there’s no initial commit yet'

@@ -42,2 +42,15 @@ return chalk.yellow(`${warning} Skipping backup because ${reason}.\n`)

export const skippingHidePartiallyStaged = (stash, diff) => {
const reason =
diff !== undefined
? '`--diff` was used'
: !stash
? '`--no-stash` was used'
: '`--no-hide-partially-staged` was used'
return chalk.yellow(
`${warning} Skipping hiding unstaged changes from partially staged files because ${reason}.\n`
)
}
export const DEPRECATED_GIT_ADD = chalk.yellow(

@@ -44,0 +57,0 @@ `${warning} Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index.

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

// Get the real path in case it's a symlink
const defaultDir = normalizePath(await fs.realpath(path.join(gitDir, '.git')))
const defaultDir = path.join(gitDir, '.git')
const stats = await fs.lstat(defaultDir)
// If .git is a directory, use it
if (stats.isDirectory()) return defaultDir
if (stats.isDirectory()) {
return defaultDir
}
// If .git is a symlink, return the real location
if (stats.isSymbolicLink()) {
return await fs.realpath(gitDir)
}
// Otherwise .git is a file containing path to real location

@@ -37,6 +46,6 @@ const file = (await readFile(defaultDir)).toString()

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

@@ -61,3 +70,3 @@ }

const gitRel = normalizePath(await execGit(['rev-parse', '--show-prefix'], { cwd }))
const gitDir = determineGitDir(normalizePath(cwd), gitRel)
const gitDir = normalizePath(determineGitDir(normalizePath(cwd), gitRel))
const gitConfigDir = normalizePath(await resolveGitConfigDir(gitDir))

@@ -64,0 +73,0 @@

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

skippingBackup,
skippingHidePartiallyStaged,
} from './messages.js'

@@ -34,3 +35,3 @@ import { normalizePath } from './normalizePath.js'

getInitialState,
hasPartiallyStagedFiles,
shouldHidePartiallyStagedFiles,
restoreOriginalStateEnabled,

@@ -84,2 +85,3 @@ restoreOriginalStateSkipped,

stash = diff === undefined,
hidePartiallyStaged = stash,
verbose = false,

@@ -114,6 +116,11 @@ },

ctx.shouldBackup = hasInitialCommit && stash
if (!ctx.shouldBackup) {
if (!ctx.shouldBackup && !quiet) {
logger.warn(skippingBackup(hasInitialCommit, diff))
}
ctx.shouldHidePartiallyStaged = hidePartiallyStaged
if (!ctx.shouldHidePartiallyStaged && !quiet) {
logger.warn(skippingHidePartiallyStaged(hasInitialCommit && stash, diff))
}
const files = await getStagedFiles({ cwd: gitDir, diff, diffFilter })

@@ -249,3 +256,3 @@ if (!files) {

if (hasDeprecatedGitAdd) {
if (hasDeprecatedGitAdd && !quiet) {
logger.warn(DEPRECATED_GIT_ADD)

@@ -288,6 +295,6 @@ }

task: (ctx) => git.hideUnstagedChanges(ctx),
enabled: hasPartiallyStagedFiles,
enabled: shouldHidePartiallyStagedFiles,
},
{
title: `Running tasks for staged files...`,
title: `Running tasks for ${diff ? 'changed' : 'staged'} files...`,
task: (ctx, task) => task.newListr(listrTasks, { concurrent }),

@@ -304,3 +311,3 @@ skip: () => listrTasks.every((task) => task.skip()),

task: (ctx) => git.restoreUnstagedChanges(ctx),
enabled: hasPartiallyStagedFiles,
enabled: shouldHidePartiallyStagedFiles,
skip: restoreUnstagedChangesSkipped,

@@ -307,0 +314,0 @@ },

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

import { execGit } from './execGit.js'
import { loadConfig, searchPlaces } from './loadConfig.js'
import { loadConfig } from './loadConfig.js'
import { normalizePath } from './normalizePath.js'
import { parseGitZOutput } from './parseGitZOutput.js'
import { validateConfig } from './validateConfig.js'
import { CONFIG_FILE_NAMES } from './configFiles.js'

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

const filterPossibleConfigFiles = (files) =>
files.filter((file) => searchPlaces.includes(path.basename(file)))
files.filter((file) => CONFIG_FILE_NAMES.includes(path.basename(file)))

@@ -22,0 +23,0 @@ const numberOfLevels = (file) => file.split('/').length

@@ -15,2 +15,3 @@ import EventEmitter from 'events'

shouldBackup: null,
shouldHidePartiallyStaged: true,
errors: new Set([]),

@@ -22,3 +23,4 @@ events: new EventEmitter(),

export const hasPartiallyStagedFiles = (ctx) => ctx.hasPartiallyStagedFiles
export const shouldHidePartiallyStagedFiles = (ctx) =>
ctx.hasPartiallyStagedFiles && ctx.shouldHidePartiallyStaged

@@ -25,0 +27,0 @@ export const applyModificationsSkipped = (ctx) => {

{
"name": "lint-staged",
"version": "14.0.1",
"version": "15.2.0",
"description": "Lint files staged by git",

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

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

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

"lint": "eslint .",
"test": "jest --coverage",
"test:watch": "jest --watch"
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest --coverage",
"test:watch": "npm run test -- --watch",
"version": "npx changeset version",
"postversion": "npm i --package-lock-only && git commit -am \"chore(changeset): release\"",
"tag": "npx changeset tag"
},
"dependencies": {
"chalk": "5.3.0",
"commander": "11.0.0",
"commander": "11.1.0",
"debug": "4.3.4",
"execa": "7.2.0",
"lilconfig": "2.1.0",
"listr2": "6.6.1",
"execa": "8.0.1",
"lilconfig": "3.0.0",
"listr2": "8.0.0",
"micromatch": "4.0.5",
"pidtree": "0.6.0",
"string-argv": "0.3.2",
"yaml": "2.3.1"
"yaml": "2.3.4"
},
"devDependencies": {
"@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",
"@changesets/changelog-github": "0.5.0",
"@changesets/cli": "2.27.1",
"@commitlint/cli": "18.4.3",
"@commitlint/config-conventional": "18.4.3",
"consolemock": "1.1.0",
"eslint": "8.46.0",
"cross-env": "7.0.3",
"eslint": "8.55.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "5.0.0",
"eslint-plugin-prettier": "5.0.1",
"husky": "8.0.3",
"jest": "29.6.2",
"jest": "29.7.0",
"jest-snapshot-serializer-ansi": "2.1.0",
"mock-stdin": "1.0.0",
"prettier": "3.0.1"
"prettier": "3.1.0"
},

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

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

# 🚫💩 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)
# 🚫💩 lint-staged [![Test & Release](https://github.com/okonet/lint-staged/actions/workflows/push.yml/badge.svg)](https://github.com/okonet/lint-staged/actions/workflows/push.yml) [![Publish](https://github.com/okonet/lint-staged/actions/workflows/tag.yml/badge.svg)](https://github.com/okonet/lint-staged/actions/workflows/tag.yml) [![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)

@@ -75,2 +75,6 @@ Run linters against staged git files and don't let :poop: slip into your code base!

#### v15
- Since `v15.0.0` _lint-staged_ no longer supports Node.js 16. Please upgrade your Node.js version to at least `18.12.0`.
#### v14

@@ -83,2 +87,3 @@

- Since `v13.0.0` _lint-staged_ no longer supports Node.js 12. Please upgrade your Node.js version to at least `14.13.1`, or `16.0.0` onward.
- Version `v13.3.0` was incorrectly released including code of version `v14.0.0`. This means the breaking changes of `v14` are also included in `v13.3.0`, the last `v13` version released

@@ -117,3 +122,5 @@ #### v12

--max-arg-length [number] maximum length of the command-line argument string (default: 0)
--no-stash disable the backup stash, and do not revert in case of errors
--no-stash disable the backup stash, and do not revert in case of errors. Implies
"--no-hide-partially-staged".
--no-hide-partially-staged disable hiding unstaged changes from partially staged files
-q, --quiet disable lint-staged’s own console output (default: false)

@@ -141,3 +148,4 @@ -r, --relative pass relative filepaths to tasks (default: false)

- **`--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`. This option also implies `--no-hide-partially-staged`.
- **`--no-hide-partially-staged`**: By default, unstaged changes from partially staged files will be hidden. This option will disable this behavior and include all unstaged changes in partially staged files. Can be re-enabled with `--hide-partially-staged`
- **`--quiet`**: Supress all CLI output, except from tasks.

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

- `lint-staged` object in your `package.json`
- `lint-staged` object in your `package.json`, or [`package.yaml`](https://github.com/pnpm/pnpm/pull/1799)
- `.lintstagedrc` file in JSON or YML format, or you can be explicit with the file extension:

@@ -647,3 +655,3 @@ - `.lintstagedrc.json`

### The output of commit hook looks weird (no colors, duplicate lines, …)
### The output of commit hook looks weird (no colors, duplicate lines, verbose output on Windows, …)

@@ -664,2 +672,17 @@ <details>

If updating Git doesn't help, you can try to manually redirect the output in your Git hook; for example:
```shell
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
if sh -c ": >/dev/tty" >/dev/null 2>/dev/null; then exec >/dev/tty 2>&1; fi
npx lint-staged
```
Source: https://github.com/typicode/husky/issues/968#issuecomment-1176848345
</details>

@@ -916,2 +939,19 @@

#### ESLint >= 8.51.0 && [Flat ESLint config](https://eslint.org/docs/latest/use/configure/configuration-files-new)
<details>
<summary>Click to expand</summary>
ESLint v8.51.0 introduced [`--no-warn-ignored` CLI flag](https://eslint.org/docs/latest/use/command-line-interface#--no-warn-ignored). It suppresses the `warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override` warning, so manually ignoring files via `eslint.isPathIgnored` is no longer necessary.
```json
{
"*.js": "eslint --max-warnings=0 --no-warn-ignored"
}
```
**NOTE:** `--no-warn-ignored` flag is only available when [Flat ESLint config](https://eslint.org/docs/latest/use/configure/configuration-files-new) is used.
</details>
</details>
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