Skip to content

Commit

Permalink
Merge pull request #1289 from okonet/updates-2023-04-20
Browse files Browse the repository at this point in the history
Drop Node.js v14, run tests for 20, update dependencies
  • Loading branch information
iiroj committed Aug 13, 2023
2 parents 5cead2d + 217c404 commit f895e97
Show file tree
Hide file tree
Showing 43 changed files with 2,783 additions and 2,137 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Expand Up @@ -9,11 +9,11 @@ on:
- alpha
# Do not run on tags
tags-ignore:
- "*"
- '*'
pull_request:
# Run on to branches with an open PR
branches:
- "*"
- '*'

permissions:
contents: read
Expand All @@ -26,7 +26,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
# Install node_modules
- uses: actions/cache@v3
id: cache-node_modules
Expand All @@ -42,11 +42,11 @@ jobs:
test:
strategy:
matrix:
# Test with Node.js v14 (LTS), v16 (LTS), and 18 (Current)
# Test with Node.js v16 (LTS), v18 (LTS), and v20 (Current)
node:
- 14
- 16
- 18
- 20
# Test with Ubuntu, macOS, and Windows
os:
- ubuntu-latest
Expand Down Expand Up @@ -124,7 +124,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18 # release using Node.js LTS
node-version: 20
# Release using semantic-release.
# While this runs on all branches, it will only release latest from master
- uses: codfish/semantic-release-action@v2
Expand Down
3 changes: 2 additions & 1 deletion .prettierrc.json
@@ -1,5 +1,6 @@
{
"printWidth": 100,
"singleQuote": true,
"semi": false
"semi": false,
"trailingComma": "es5"
}
16 changes: 9 additions & 7 deletions README.md
Expand Up @@ -72,6 +72,10 @@ See [Releases](https://github.com/okonet/lint-staged/releases).

### Migration

#### 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

- 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.
Expand Down Expand Up @@ -218,11 +222,11 @@ If necessary, you can limit the concurrency using `--concurrent <number>` or dis
Linter commands work on a subset of all staged files, defined by a _glob pattern_. lint-staged uses [micromatch](https://github.com/micromatch/micromatch) for matching files with the following rules:

- 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`

When matching, lint-staged will do the following

Expand Down Expand Up @@ -624,9 +628,7 @@ See more on [this blog post](https://medium.com/@tomchentw/imagemin-lint-staged-
const path = require('path')

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 ')}`

module.exports = {
'*.{js,jsx,ts,tsx}': [buildEslintCommand],
Expand Down
22 changes: 9 additions & 13 deletions bin/lint-staged.js
@@ -1,8 +1,6 @@
#!/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'

import { supportsColor } from 'chalk'
import { Option, program } from 'commander'
Expand All @@ -19,8 +17,7 @@ if (supportsColor) {
// Do not terminate main Listr process on SIGINT
process.on('SIGINT', () => {})

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

const debugLog = debug('lint-staged:bin')
Expand Down Expand Up @@ -113,7 +110,7 @@ debugLog('Options parsed from command-line:', options)
if (options.configPath === '-') {
delete options.configPath
try {
options.config = fs.readFileSync(process.stdin.fd, 'utf8').toString().trim()
options.config = await fs.readFile(process.stdin.fd, 'utf8').toString().trim()
} catch {
console.error(CONFIG_STDIN_ERROR)
process.exit(1)
Expand All @@ -126,10 +123,9 @@ if (options.configPath === '-') {
}
}

lintStaged(options)
.then((passed) => {
process.exitCode = passed ? 0 : 1
})
.catch(() => {
process.exitCode = 1
})
try {
const passed = await lintStaged(options)
process.exitCode = passed ? 0 : 1
} catch {
process.exitCode = 1
}
5 changes: 3 additions & 2 deletions lib/chunkFiles.js
@@ -1,7 +1,8 @@
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')

Expand Down Expand Up @@ -35,7 +36,7 @@ const chunkArray = (arr, chunkCount) => {
*/
export const chunkFiles = ({ files, baseDir, maxArgLength = null, relative = false }) => {
const normalizedFiles = files.map((file) =>
normalize(relative || !baseDir ? file : path.resolve(baseDir, file))
normalizePath(relative || !baseDir ? file : path.resolve(baseDir, file))
)

if (!maxArgLength) {
Expand Down
7 changes: 4 additions & 3 deletions lib/generateTasks.js
Expand Up @@ -2,7 +2,8 @@ import path from 'node:path'

import debug from 'debug'
import micromatch from 'micromatch'
import normalize from 'normalize-path'

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

const debugLog = debug('lint-staged:generateTasks')

Expand All @@ -19,7 +20,7 @@ const debugLog = debug('lint-staged:generateTasks')
export const generateTasks = ({ config, cwd = process.cwd(), files, relative = false }) => {
debugLog('Generating linter tasks')

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

return Object.entries(config).map(([pattern, commands]) => {
const isParentDirPattern = pattern.startsWith('../')
Expand All @@ -42,7 +43,7 @@ export const generateTasks = ({ config, cwd = process.cwd(), files, relative = f
strictBrackets: true,
})

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

const task = { pattern, commands, fileList }
debugLog('Generated task: \n%O', task)
Expand Down
64 changes: 50 additions & 14 deletions lib/getRenderer.js
@@ -1,28 +1,64 @@
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',
}
}

const getFallbackRenderer = ({ renderer }, { FORCE_COLOR }) => {
if (renderer === 'silent') {
return 'silent'
return {
renderer: 'update',
rendererOptions: {
formatOutput: 'truncate',
},
}
}

// If colors are being forced, then also force non-fallback rendering
if (Number(FORCE_COLOR) > 0) {
const getFallbackRenderer = ({ renderer }, { FORCE_COLOR }) => {
if (renderer === 'silent' || renderer === 'test' || Number(FORCE_COLOR) > 0) {
return renderer
}

return 'verbose'
}

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),
}
}
5 changes: 2 additions & 3 deletions lib/getStagedFiles.js
@@ -1,17 +1,16 @@
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'

export const getStagedFiles = async ({ cwd = process.cwd(), diff, diffFilter } = {}) => {
try {
const lines = await execGit(getDiffCommand(diff, diffFilter), { cwd })
if (!lines) return []

return parseGitZOutput(lines).map((file) => normalize(path.resolve(cwd, file)))
return parseGitZOutput(lines).map((file) => normalizePath(path.resolve(cwd, file)))
} catch {
return null
}
Expand Down
25 changes: 2 additions & 23 deletions lib/makeCmdTasks.js
@@ -1,28 +1,10 @@
import cliTruncate from 'cli-truncate'
import debug from 'debug'

import { configurationError } from './messages.js'
import { resolveTaskFn } from './resolveTaskFn.js'

const debugLog = debug('lint-staged:makeCmdTasks')

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.
*
Expand All @@ -31,11 +13,10 @@ const getTitleLength = (renderer, columns = process.stdout.columns) => {
* @param {string} options.cwd
* @param {Array<string>} options.files
* @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)
const commandArray = Array.isArray(commands) ? commands : [commands]
const cmdTasks = []
Expand All @@ -60,10 +41,8 @@ export const makeCmdTasks = async ({ commands, cwd, files, gitDir, renderer, she
)
}

// 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 })
}
}

Expand Down
7 changes: 3 additions & 4 deletions lib/messages.js
@@ -1,14 +1,13 @@
import { inspect } from 'node:util'

import chalk from 'chalk'
import inspect from 'object-inspect'

import { error, info, warning } from './figures.js'

export const configurationError = (opt, helpMsg, value) =>
`${chalk.redBright(`${error} Validation Error:`)}
Invalid value for '${chalk.bold(opt)}': ${chalk.bold(
inspect(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY })
)}
Invalid value for '${chalk.bold(opt)}': ${chalk.bold(inspect(value))}
${helpMsg}`

Expand Down

0 comments on commit f895e97

Please sign in to comment.