diff --git a/lib/error.js b/lib/errors.js similarity index 100% rename from lib/error.js rename to lib/errors.js diff --git a/lib/spawner.js b/lib/executor.js similarity index 99% rename from lib/spawner.js rename to lib/executor.js index c60f283..8d81900 100644 --- a/lib/spawner.js +++ b/lib/executor.js @@ -267,7 +267,7 @@ async function which(tool, check) { return '' } -export async function spawner(cmd, args = [], opts = {}) { +export async function executor(cmd, args = [], opts = {}) { let prefix = await getPrefix(process.cwd()) if (prefix) { diff --git a/lib/git.js b/lib/git.js index 1d030ae..db8700c 100644 --- a/lib/git.js +++ b/lib/git.js @@ -1,6 +1,6 @@ import { join, normalize } from 'path' -import { spawner } from './spawner.js' +import { executor } from './executor.js' import { toArray } from './utils.js' const ADDED = 'A'.charCodeAt(0) @@ -56,7 +56,7 @@ export function createGit(cwd = process.cwd()) { async exec(args = [], opts = {}) { try { - return await spawner('git', args, { + return await executor('git', args, { ...opts, cwd: opts.cwd || git.cwd, }) diff --git a/lib/index.js b/lib/index.js index 1521692..f435ad2 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,8 @@ -import { createReporter } from './create-reporter.js' import { getConfig, validConfig } from './config.js' -import { NanoStagedError } from './error.js' +import { createReporter } from './reporter.js' +import { NanoStagedError } from './errors.js' import { createRunner } from './runner.js' +import { toArray } from './utils.js' const defaultOptions = { config: undefined, @@ -13,7 +14,7 @@ const defaultOptions = { } export default async function (opts = { ...defaultOptions, ...opts }) { - const report = createReporter(opts.stream) + const reporter = createReporter(opts.stream) try { const config = await getConfig(opts.cwd, opts.config) @@ -40,10 +41,8 @@ export default async function (opts = { ...defaultOptions, ...opts }) { await runner.run() } } catch (error) { - const errors = Array.isArray(error) ? error : [error] - - for (const error of errors) { - report.error(error) + for (const error of toArray(error)) { + reporter.error(error) } throw error diff --git a/lib/create-reporter.js b/lib/reporter.js similarity index 91% rename from lib/create-reporter.js rename to lib/reporter.js index 5003337..f73c8a0 100644 --- a/lib/create-reporter.js +++ b/lib/reporter.js @@ -1,6 +1,6 @@ import c from 'picocolors' -import { NanoStagedError, TaskRunnerError } from './error.js' +import { NanoStagedError, TaskRunnerError } from './errors.js' export function createReporter(stream = process.stderr) { function print(lines) { diff --git a/lib/runner.js b/lib/runner.js index e8af601..91764e9 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -1,16 +1,16 @@ -import { createReporter } from './create-reporter.js' import { createGitWorkflow } from './git-workflow.js' -import { createTaskRunner } from './task-runner.js' -import { NanoStagedError } from './error.js' +import { createTasksRunner } from './tasks-runner.js' +import { createReporter } from './reporter.js' +import { NanoStagedError } from './errors.js' import { MultiSpinner } from './spinner.js' import { createGit } from './git.js' export function createRunner({ cwd, stream, allowEmpty, config }) { + const reporter = createReporter(stream) const git = createGit(cwd) - const report = createReporter(stream) const runner = { - async run(type = 'staged', { refs = [] } = {}) { + async run(type = 'staged', opts = {}) { const { repoPath, dotGitPath } = await git.getRepoAndDotGitPaths() if (!repoPath) { @@ -21,19 +21,19 @@ export function createRunner({ cwd, stream, allowEmpty, config }) { if (type === 'unstaged') { files = await git.unstagedFiles({ cwd: repoPath }) } else if (type === 'diff') { - files = await git.changedFiles(refs, { cwd: repoPath }) + files = await git.changedFiles(opts.refs, { cwd: repoPath }) } else { files = await git.stagedFiles({ cwd: repoPath }) } if (!files.working.length) { - report.error(new NanoStagedError('noFiles', type)) + reporter.error(new NanoStagedError('noFiles', type)) return } const changes = [...files.changed, ...files.deleted] const gitWorkflow = await createGitWorkflow({ allowEmpty, repoPath, dotGitPath }) - const taskRunner = await createTaskRunner({ + const tasksRunner = await createTasksRunner({ files: files.working, repoPath, config, @@ -41,8 +41,8 @@ export function createRunner({ cwd, stream, allowEmpty, config }) { cwd, }) - if (!taskRunner.tasks.some(({ files }) => files.length > 0)) { - report.error(new NanoStagedError('noMatchingFiles')) + if (!tasksRunner.tasks.some(({ files }) => files.length > 0)) { + reporter.error(new NanoStagedError('noMatchingFiles')) return } @@ -82,7 +82,7 @@ export function createRunner({ cwd, stream, allowEmpty, config }) { title: `Running tasks for ${type} files...`, task: async (spin) => { try { - await taskRunner.run(spin) + await tasksRunner.run(spin) } catch (e) { revert = true throw e diff --git a/lib/task-runner.js b/lib/tasks-runner.js similarity index 93% rename from lib/task-runner.js rename to lib/tasks-runner.js index 22ea46f..73cda78 100644 --- a/lib/task-runner.js +++ b/lib/tasks-runner.js @@ -3,11 +3,11 @@ import c from 'picocolors' import { globToRegex } from './glob-to-regex.js' import { stringArgvToArray } from './utils.js' -import { TaskRunnerError } from './error.js' -import { spawner } from './spawner.js' +import { TaskRunnerError } from './errors.js' +import { executor } from './executor.js' import { toArray } from './utils.js' -export async function createTaskRunner({ +export async function createTasksRunner({ cwd = process.cwd(), type = 'staged', repoPath = '', @@ -97,7 +97,7 @@ export async function createTaskRunner({ continue } - await spawner(command, task.cmdFn ? args : args.concat(task.files), { + await executor(command, task.cmdFn ? args : args.concat(task.files), { cwd: repoPath, }) diff --git a/test/error.test.js b/test/error.test.js index 95f4134..2e1c38e 100644 --- a/test/error.test.js +++ b/test/error.test.js @@ -1,7 +1,7 @@ import { is } from 'uvu/assert' import { test } from 'uvu' -import { NanoStagedError, TaskRunnerError } from '../lib/error.js' +import { NanoStagedError, TaskRunnerError } from '../lib/errors.js' import { createStdout } from './utils/index.js' let stdout = createStdout() diff --git a/test/index.test.js b/test/index.test.js index 6a4b843..124ab43 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -127,7 +127,7 @@ test('should runner run error', async () => { try { await nanoStaged({ stream: stdout }) } catch (error) { - is(stdout.out, '\n\x1B[31m×\x1B[39m \x1B[31mTask error\x1B[39m\n') + is(stdout.out, '\n\x1B[31mTask error\x1B[39m\n') } }) diff --git a/test/create-reporter.test.js b/test/reporter.test.js similarity index 77% rename from test/create-reporter.test.js rename to test/reporter.test.js index 7ec0815..72093d2 100644 --- a/test/create-reporter.test.js +++ b/test/reporter.test.js @@ -1,9 +1,9 @@ import { is } from 'uvu/assert' import { test } from 'uvu' +import { NanoStagedError, TaskRunnerError } from '../lib/errors.js' +import { createReporter } from '../lib/reporter.js' import { createStdout } from './utils/index.js' -import { createReporter } from '../lib/create-reporter.js' -import { NanoStagedError, TaskRunnerError } from '../lib/error.js' let stdout = createStdout() let report = createReporter(stdout) @@ -16,7 +16,7 @@ test('should reported error correctly', () => { let err = new Error('Error') report.error(err) - is(stdout.out, '\n\x1B[31m×\x1B[39m \x1B[31mError\x1B[39m\n') + is(stdout.out, '\n\x1B[31mError\x1B[39m\n') }) test('should reported TaskRunnerError correctly', () => { @@ -24,7 +24,7 @@ test('should reported TaskRunnerError correctly', () => { err.name = 'TaskRunnerError' report.error(err) - is(stdout.out, '\n\x1B[31m×\x1B[39m \x1B[31mTaskRunnerError\x1B[39m\n') + is(stdout.out, '\n\x1B[31mTaskRunnerError\x1B[39m\n') }) test('should reported NanoStagedError correctly', () => { diff --git a/test/runner.test.js b/test/runner.test.js index f19ac92..fbf291c 100644 --- a/test/runner.test.js +++ b/test/runner.test.js @@ -20,6 +20,7 @@ test('should return when git not found', async () => { }) let runner = createRunner({ stream: stdout }) + try { await runner.run() } catch (error) { @@ -71,8 +72,8 @@ test('should return when no files match any configured task', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: [] }], }), }, @@ -95,8 +96,8 @@ test('should step success', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -137,8 +138,8 @@ test('should backupOriginalState error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -171,8 +172,8 @@ test('should backupUnstagedFiles error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -211,8 +212,8 @@ test('should applyModifications error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -254,8 +255,8 @@ test('should restoreUnstagedFiles error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -297,8 +298,8 @@ test('should restoreOriginalState error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), @@ -335,8 +336,8 @@ test('should restoreOriginalState error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.reject('Task runner error'), }), @@ -377,8 +378,8 @@ test('should cleanUp error', async () => { stagedFiles: async () => ({ working: ['a.js'], deleted: [], changed: ['a.js'] }), }), }, - '../lib/task-runner.js': { - createTaskRunner: () => ({ + '../lib/tasks-runner.js': { + createTasksRunner: () => ({ tasks: [{ files: ['a.js'] }], run: async () => Promise.resolve(), }), diff --git a/test/task-runner.test.js b/test/tasks-runner.test.js similarity index 65% rename from test/task-runner.test.js rename to test/tasks-runner.test.js index 72555b1..3bff718 100644 --- a/test/task-runner.test.js +++ b/test/tasks-runner.test.js @@ -5,7 +5,7 @@ import esmock from 'esmock' import { test } from 'uvu' import { createStdout } from './utils/index.js' -import { Spinner } from '../lib/spinner.js' +import { MultiSpinner } from '../lib/spinner.js' let stdout = createStdout() @@ -14,9 +14,9 @@ test.before.each(() => { }) test('should create runner and resolve tasks', async () => { - const { createTaskRunner } = await esmock('../lib/task-runner.js') + const { createTasksRunner } = await esmock('../lib/tasks-runner.js') - let runner = await createTaskRunner({ + let runner = await createTasksRunner({ repoPath: join(homedir(), 'test'), cwd: join(homedir(), 'test'), files: ['a.js', '../../b.css'], @@ -43,24 +43,28 @@ test('should create runner and resolve tasks', async () => { }) test('should run handle error', async () => { - const { createTaskRunner } = await esmock('../lib/task-runner.js', { - '../lib/spawner.js': { - spawner: async () => Promise.reject('Run error'), + const { createTasksRunner } = await esmock('../lib/tasks-runner.js', { + '../lib/executor.js': { + executor: async () => Promise.reject('Run error'), }, }) - let runner = await createTaskRunner({ + let runner = await createTasksRunner({ repoPath: 'test', files: ['a.js', '../../b.css'], config: { '*.js': ['prettier --write', 'prettier --write'], '*.css': () => 'prettier --write' }, stream: stdout, }) - const spinner = new Spinner({ stream: stdout }) + const spinner = new MultiSpinner({ stream: stdout }) - await runner.run(spinner) - - spinner.stop() + try { + await runner.run(spinner) + } catch (error) { + is(stdout.out, '\x1B[?25l\x1B[33m\\\x1B[39m *.js\x1B[2m - 1 file\x1B[22m') + } finally { + spinner.stop() + } }) test.run()