| 'use strict' | 
|   | 
| /** @typedef {import('./index').Logger} Logger */ | 
|   | 
| const { Listr } = require('listr2') | 
|   | 
| const chunkFiles = require('./chunkFiles') | 
| const debugLog = require('debug')('lint-staged:run') | 
| const execGit = require('./execGit') | 
| const generateTasks = require('./generateTasks') | 
| const getRenderer = require('./getRenderer') | 
| const getStagedFiles = require('./getStagedFiles') | 
| const GitWorkflow = require('./gitWorkflow') | 
| const makeCmdTasks = require('./makeCmdTasks') | 
| const { | 
|   DEPRECATED_GIT_ADD, | 
|   FAILED_GET_STAGED_FILES, | 
|   NOT_GIT_REPO, | 
|   NO_STAGED_FILES, | 
|   NO_TASKS, | 
|   SKIPPED_GIT_ERROR, | 
|   skippingBackup, | 
| } = require('./messages') | 
| const resolveGitRepo = require('./resolveGitRepo') | 
| const { | 
|   applyModificationsSkipped, | 
|   cleanupEnabled, | 
|   cleanupSkipped, | 
|   getInitialState, | 
|   hasPartiallyStagedFiles, | 
|   restoreOriginalStateEnabled, | 
|   restoreOriginalStateSkipped, | 
|   restoreUnstagedChangesSkipped, | 
| } = require('./state') | 
| const { GitRepoError, GetStagedFilesError, GitError } = require('./symbols') | 
|   | 
| const createError = (ctx) => Object.assign(new Error('lint-staged failed'), { ctx }) | 
|   | 
| /** | 
|  * Executes all tasks and either resolves or rejects the promise | 
|  * | 
|  * @param {object} options | 
|  * @param {Object} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes | 
|  * @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially | 
|  * @param {Object} [options.config] - Task configuration | 
|  * @param {Object} [options.cwd] - Current working directory | 
|  * @param {boolean} [options.debug] - Enable debug mode | 
|  * @param {number} [options.maxArgLength] - Maximum argument string length | 
|  * @param {boolean} [options.quiet] - Disable lint-staged’s own console output | 
|  * @param {boolean} [options.relative] - Pass relative filepaths to tasks | 
|  * @param {boolean} [options.shell] - Skip parsing of tasks for better shell support | 
|  * @param {boolean} [options.stash] - Enable the backup stash, and revert in case of errors | 
|  * @param {boolean} [options.verbose] - Show task output even when tasks succeed; by default only failed output is shown | 
|  * @param {Logger} logger | 
|  * @returns {Promise} | 
|  */ | 
| const runAll = async ( | 
|   { | 
|     allowEmpty = false, | 
|     concurrent = true, | 
|     config, | 
|     cwd = process.cwd(), | 
|     debug = false, | 
|     maxArgLength, | 
|     quiet = false, | 
|     relative = false, | 
|     shell = false, | 
|     stash = true, | 
|     verbose = false, | 
|   }, | 
|   logger = console | 
| ) => { | 
|   debugLog('Running all linter scripts') | 
|   | 
|   const ctx = getInitialState({ quiet }) | 
|   | 
|   const { gitDir, gitConfigDir } = await resolveGitRepo(cwd) | 
|   if (!gitDir) { | 
|     if (!quiet) ctx.output.push(NOT_GIT_REPO) | 
|     ctx.errors.add(GitRepoError) | 
|     throw createError(ctx) | 
|   } | 
|   | 
|   // Test whether we have any commits or not. | 
|   // Stashing must be disabled with no initial commit. | 
|   const hasInitialCommit = await execGit(['log', '-1'], { cwd: gitDir }) | 
|     .then(() => true) | 
|     .catch(() => false) | 
|   | 
|   // Lint-staged should create a backup stash only when there's an initial commit | 
|   ctx.shouldBackup = hasInitialCommit && stash | 
|   if (!ctx.shouldBackup) { | 
|     logger.warn(skippingBackup(hasInitialCommit)) | 
|   } | 
|   | 
|   const files = await getStagedFiles({ cwd: gitDir }) | 
|   if (!files) { | 
|     if (!quiet) ctx.output.push(FAILED_GET_STAGED_FILES) | 
|     ctx.errors.add(GetStagedFilesError) | 
|     throw createError(ctx, GetStagedFilesError) | 
|   } | 
|   debugLog('Loaded list of staged files in git:\n%O', files) | 
|   | 
|   // If there are no files avoid executing any lint-staged logic | 
|   if (files.length === 0) { | 
|     if (!quiet) ctx.output.push(NO_STAGED_FILES) | 
|     return ctx | 
|   } | 
|   | 
|   const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative }) | 
|   const chunkCount = stagedFileChunks.length | 
|   if (chunkCount > 1) debugLog(`Chunked staged files into ${chunkCount} part`, chunkCount) | 
|   | 
|   // lint-staged 10 will automatically add modifications to index | 
|   // Warn user when their command includes `git add` | 
|   let hasDeprecatedGitAdd = false | 
|   | 
|   const listrOptions = { | 
|     ctx, | 
|     exitOnError: false, | 
|     nonTTYRenderer: 'verbose', | 
|     registerSignalListeners: false, | 
|     ...getRenderer({ debug, quiet }), | 
|   } | 
|   | 
|   const listrTasks = [] | 
|   | 
|   // Set of all staged files that matched a task glob. Values in a set are unique. | 
|   const matchedFiles = new Set() | 
|   | 
|   for (const [index, files] of stagedFileChunks.entries()) { | 
|     const chunkTasks = generateTasks({ config, cwd, gitDir, files, relative }) | 
|     const chunkListrTasks = [] | 
|   | 
|     for (const task of chunkTasks) { | 
|       const subTasks = await makeCmdTasks({ | 
|         commands: task.commands, | 
|         files: task.fileList, | 
|         gitDir, | 
|         renderer: listrOptions.renderer, | 
|         shell, | 
|         verbose, | 
|       }) | 
|   | 
|       // Add files from task to match set | 
|       task.fileList.forEach((file) => { | 
|         matchedFiles.add(file) | 
|       }) | 
|   | 
|       hasDeprecatedGitAdd = subTasks.some((subTask) => subTask.command === 'git add') | 
|   | 
|       chunkListrTasks.push({ | 
|         title: `Running tasks for ${task.pattern}`, | 
|         task: async () => | 
|           new Listr(subTasks, { | 
|             // In sub-tasks we don't want to run concurrently | 
|             // and we want to abort on errors | 
|             ...listrOptions, | 
|             concurrent: false, | 
|             exitOnError: true, | 
|           }), | 
|         skip: () => { | 
|           // Skip task when no files matched | 
|           if (task.fileList.length === 0) { | 
|             return `No staged files match ${task.pattern}` | 
|           } | 
|           return false | 
|         }, | 
|       }) | 
|     } | 
|   | 
|     listrTasks.push({ | 
|       // No need to show number of task chunks when there's only one | 
|       title: | 
|         chunkCount > 1 ? `Running tasks (chunk ${index + 1}/${chunkCount})...` : 'Running tasks...', | 
|       task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent }), | 
|       skip: () => { | 
|         // Skip if the first step (backup) failed | 
|         if (ctx.errors.has(GitError)) return SKIPPED_GIT_ERROR | 
|         // Skip chunk when no every task is skipped (due to no matches) | 
|         if (chunkListrTasks.every((task) => task.skip())) return 'No tasks to run.' | 
|         return false | 
|       }, | 
|     }) | 
|   } | 
|   | 
|   if (hasDeprecatedGitAdd) { | 
|     logger.warn(DEPRECATED_GIT_ADD) | 
|   } | 
|   | 
|   // If all of the configured tasks should be skipped | 
|   // avoid executing any lint-staged logic | 
|   if (listrTasks.every((task) => task.skip())) { | 
|     if (!quiet) ctx.output.push(NO_TASKS) | 
|     return ctx | 
|   } | 
|   | 
|   // Chunk matched files for better Windows compatibility | 
|   const matchedFileChunks = chunkFiles({ | 
|     // matched files are relative to `cwd`, not `gitDir`, when `relative` is used | 
|     baseDir: cwd, | 
|     files: Array.from(matchedFiles), | 
|     maxArgLength, | 
|     relative: false, | 
|   }) | 
|   | 
|   const git = new GitWorkflow({ allowEmpty, gitConfigDir, gitDir, matchedFileChunks }) | 
|   | 
|   const runner = new Listr( | 
|     [ | 
|       { | 
|         title: 'Preparing...', | 
|         task: (ctx) => git.prepare(ctx), | 
|       }, | 
|       { | 
|         title: 'Hiding unstaged changes to partially staged files...', | 
|         task: (ctx) => git.hideUnstagedChanges(ctx), | 
|         enabled: hasPartiallyStagedFiles, | 
|       }, | 
|       ...listrTasks, | 
|       { | 
|         title: 'Applying modifications...', | 
|         task: (ctx) => git.applyModifications(ctx), | 
|         skip: applyModificationsSkipped, | 
|       }, | 
|       { | 
|         title: 'Restoring unstaged changes to partially staged files...', | 
|         task: (ctx) => git.restoreUnstagedChanges(ctx), | 
|         enabled: hasPartiallyStagedFiles, | 
|         skip: restoreUnstagedChangesSkipped, | 
|       }, | 
|       { | 
|         title: 'Reverting to original state because of errors...', | 
|         task: (ctx) => git.restoreOriginalState(ctx), | 
|         enabled: restoreOriginalStateEnabled, | 
|         skip: restoreOriginalStateSkipped, | 
|       }, | 
|       { | 
|         title: 'Cleaning up...', | 
|         task: (ctx) => git.cleanup(ctx), | 
|         enabled: cleanupEnabled, | 
|         skip: cleanupSkipped, | 
|       }, | 
|     ], | 
|     listrOptions | 
|   ) | 
|   | 
|   await runner.run() | 
|   | 
|   if (ctx.errors.size > 0) { | 
|     throw createError(ctx) | 
|   } | 
|   | 
|   return ctx | 
| } | 
|   | 
| module.exports = runAll |