Skip to content

Commit

Permalink
refactor: move skip and enable cheks of listr tasks to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
iiroj committed Apr 21, 2020
1 parent 6da7667 commit e95d1b0
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 98 deletions.
4 changes: 2 additions & 2 deletions lib/gitWorkflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class GitWorkflow {
/**
* Create a diff of partially staged files and backup stash if enabled.
*/
async prepare(ctx, shouldBackup) {
async prepare(ctx) {
try {
debug('Backing up original state...')

Expand All @@ -194,7 +194,7 @@ class GitWorkflow {
/**
* If backup stash should be skipped, no need to continue
*/
if (!shouldBackup) return
if (!ctx.shouldBackup) return

// When backup is enabled, the revert will clear ongoing merge status.
await this.backupMergeStatus()
Expand Down
5 changes: 4 additions & 1 deletion lib/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const DEPRECATED_GIT_ADD = `${symbols.warning} ${chalk.yellow(

const TASK_ERROR = 'Skipped because of errors from tasks.'

const GIT_ERROR = 'Skipped because of previous git error.'
const SKIPPED_GIT_ERROR = 'Skipped because of previous git error.'

const GIT_ERROR = `\n ${symbols.error} ${chalk.red(`lint-staged failed due to a git error.`)}`

const PREVENTED_EMPTY_COMMIT = `
${symbols.warning} ${chalk.yellow(`lint-staged prevented an empty git commit.
Expand All @@ -36,6 +38,7 @@ module.exports = {
skippingBackup,
DEPRECATED_GIT_ADD,
TASK_ERROR,
SKIPPED_GIT_ERROR,
GIT_ERROR,
PREVENTED_EMPTY_COMMIT,
RESTORE_STASH_EXAMPLE
Expand Down
90 changes: 20 additions & 70 deletions lib/runAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

/** @typedef {import('./index').Logger} Logger */

const chalk = require('chalk')
const { Listr } = require('listr2')
const symbols = require('log-symbols')

const chunkFiles = require('./chunkFiles')
const execGit = require('./execGit')
Expand All @@ -18,18 +16,19 @@ const {
NO_STAGED_FILES,
PREVENTED_EMPTY_COMMIT,
RESTORE_STASH_EXAMPLE,
TASK_ERROR,
SKIPPED_GIT_ERROR,
skippingBackup
} = require('./messages')
const resolveGitRepo = require('./resolveGitRepo')
const { ApplyEmptyCommitError, GetBackupStashError, GitError } = require('./symbols')
const {
ApplyEmptyCommitError,
TaskError,
RestoreOriginalStateError,
GetBackupStashError,
GitError,
RestoreUnstagedChangesError
} = require('./symbols')
applyModificationsSkipped,
cleanupSkipped,
hasPartiallyStagedFiles,
restoreOriginalStateEnabled,
restoreOriginalStateSkipped,
restoreUnstagedChangesSkipped
} = require('./state')

const debugLog = require('debug')('lint-staged:run')

Expand All @@ -41,43 +40,6 @@ const getRenderer = ({ debug, quiet }) => {
return 'update'
}

const shouldSkipApplyModifications = (ctx) => {
// Should be skipped in case of git errors
if (ctx.errors.has(GitError)) {
return GIT_ERROR
}
// Should be skipped when tasks fail
if (ctx.errors.has(TaskError)) {
return TASK_ERROR
}
}

const shouldSkipRevert = (ctx) => {
// Should be skipped in case of unknown git errors
if (
ctx.errors.has(GitError) &&
!ctx.errors.has(ApplyEmptyCommitError) &&
!ctx.errors.has(RestoreUnstagedChangesError)
) {
return GIT_ERROR
}
}

const shouldSkipCleanup = (ctx) => {
// Should be skipped in case of unknown git errors
if (
ctx.errors.has(GitError) &&
!ctx.errors.has(ApplyEmptyCommitError) &&
!ctx.errors.has(RestoreUnstagedChangesError)
) {
return GIT_ERROR
}
// Should be skipped when reverting to original state fails
if (ctx.errors.has(RestoreOriginalStateError)) {
return GIT_ERROR
}
}

/**
* Executes all tasks and either resolves or rejects the promise
*
Expand Down Expand Up @@ -146,6 +108,7 @@ const runAll = async (

const listrCtx = {
hasPartiallyStagedFiles: false,
shouldBackup,
errors: new Set([])
}

Expand Down Expand Up @@ -208,7 +171,7 @@ const runAll = async (
task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent }),
skip: () => {
// Skip if the first step (backup) failed
if (listrCtx.errors.has(GitError)) return GIT_ERROR
if (listrCtx.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
Expand All @@ -233,41 +196,36 @@ const runAll = async (
[
{
title: 'Preparing...',
task: (ctx) => git.prepare(ctx, shouldBackup)
task: (ctx) => git.prepare(ctx)
},
{
title: 'Hiding unstaged changes to partially staged files...',
task: (ctx) => git.hideUnstagedChanges(ctx),
enabled: (ctx) => ctx.hasPartiallyStagedFiles
enabled: hasPartiallyStagedFiles
},
...listrTasks,
{
title: 'Applying modifications...',
task: (ctx) => git.applyModifications(ctx),
// Always apply back unstaged modifications when skipping backup
skip: (ctx) => shouldBackup && shouldSkipApplyModifications(ctx)
skip: applyModificationsSkipped
},
{
title: 'Restoring unstaged changes to partially staged files...',
task: (ctx) => git.restoreUnstagedChanges(ctx),
enabled: (ctx) => ctx.hasPartiallyStagedFiles,
skip: shouldSkipApplyModifications
enabled: hasPartiallyStagedFiles,
skip: restoreUnstagedChangesSkipped
},
{
title: 'Reverting to original state because of errors...',
task: (ctx) => git.restoreOriginalState(ctx),
enabled: (ctx) =>
shouldBackup &&
(ctx.errors.has(TaskError) ||
ctx.errors.has(ApplyEmptyCommitError) ||
ctx.errors.has(RestoreUnstagedChangesError)),
skip: shouldSkipRevert
enabled: restoreOriginalStateEnabled,
skip: restoreOriginalStateSkipped
},
{
title: 'Cleaning up...',
task: (ctx) => git.cleanup(ctx),
enabled: () => shouldBackup,
skip: shouldSkipCleanup
skip: cleanupSkipped
}
],
listrOptions
Expand All @@ -279,8 +237,7 @@ const runAll = async (
if (context.errors.has(ApplyEmptyCommitError)) {
logger.warn(PREVENTED_EMPTY_COMMIT)
} else if (context.errors.has(GitError) && !context.errors.has(GetBackupStashError)) {
logger.error(`\n ${symbols.error} ${chalk.red(`lint-staged failed due to a git error.`)}`)

logger.error(GIT_ERROR)
if (shouldBackup) {
// No sense to show this if the backup stash itself is missing.
logger.error(RESTORE_STASH_EXAMPLE)
Expand All @@ -292,10 +249,3 @@ const runAll = async (
}

module.exports = runAll

// Exported for testing
module.exports.shouldSkip = {
shouldSkipApplyModifications,
shouldSkipRevert,
shouldSkipCleanup
}
77 changes: 77 additions & 0 deletions lib/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict'

const { GIT_ERROR, TASK_ERROR } = require('./messages')
const {
ApplyEmptyCommitError,
TaskError,
RestoreOriginalStateError,
GitError,
RestoreUnstagedChangesError
} = require('./symbols')

const hasPartiallyStagedFiles = (ctx) => ctx.hasPartiallyStagedFiles

const applyModificationsSkipped = (ctx) => {
// Always apply back unstaged modifications when skipping backup
if (!ctx.shouldBackup) return false
// Should be skipped in case of git errors
if (ctx.errors.has(GitError)) {
return GIT_ERROR
}
// Should be skipped when tasks fail
if (ctx.errors.has(TaskError)) {
return TASK_ERROR
}
}

const restoreUnstagedChangesSkipped = (ctx) => {
// Should be skipped in case of git errors
if (ctx.errors.has(GitError)) {
return GIT_ERROR
}
// Should be skipped when tasks fail
if (ctx.errors.has(TaskError)) {
return TASK_ERROR
}
}

const restoreOriginalStateEnabled = (ctx) =>
ctx.shouldBackup &&
(ctx.errors.has(TaskError) ||
ctx.errors.has(ApplyEmptyCommitError) ||
ctx.errors.has(RestoreUnstagedChangesError))

const restoreOriginalStateSkipped = (ctx) => {
// Should be skipped in case of unknown git errors
if (
ctx.errors.has(GitError) &&
!ctx.errors.has(ApplyEmptyCommitError) &&
!ctx.errors.has(RestoreUnstagedChangesError)
) {
return GIT_ERROR
}
}

const cleanupSkipped = (ctx) => {
// Should be skipped in case of unknown git errors
if (
ctx.errors.has(GitError) &&
!ctx.errors.has(ApplyEmptyCommitError) &&
!ctx.errors.has(RestoreUnstagedChangesError)
) {
return GIT_ERROR
}
// Should be skipped when reverting to original state fails
if (ctx.errors.has(RestoreOriginalStateError)) {
return GIT_ERROR
}
}

module.exports = {
hasPartiallyStagedFiles,
applyModificationsSkipped,
restoreUnstagedChangesSkipped,
restoreOriginalStateEnabled,
restoreOriginalStateSkipped,
cleanupSkipped
}
2 changes: 2 additions & 0 deletions test/index2.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('lintStaged', () => {
"ctx": Object {
"errors": Set {},
"hasPartiallyStagedFiles": false,
"shouldBackup": true,
},
"dateFormat": false,
"exitOnError": false,
Expand All @@ -49,6 +50,7 @@ describe('lintStaged', () => {
"ctx": Object {
"errors": Set {},
"hasPartiallyStagedFiles": false,
"shouldBackup": true,
},
"dateFormat": false,
"exitOnError": false,
Expand Down
27 changes: 2 additions & 25 deletions test/runAll.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import path from 'path'
import getStagedFiles from '../lib/getStagedFiles'
import GitWorkflow from '../lib/gitWorkflow'
import resolveGitRepo from '../lib/resolveGitRepo'
import runAll, { shouldSkip } from '../lib/runAll'
import { GitError, RestoreOriginalStateError } from '../lib/symbols'
import runAll from '../lib/runAll'
import { GitError } from '../lib/symbols'

jest.mock('../lib/file')
jest.mock('../lib/getStagedFiles')
Expand Down Expand Up @@ -190,26 +190,3 @@ describe('runAll', () => {
`)
})
})

describe('shouldSkip', () => {
describe('shouldSkipApplyModifications', () => {
it('should return error message when there is an unkown git error', () => {
const result = shouldSkip.shouldSkipApplyModifications({ errors: new Set([GitError]) })
expect(typeof result === 'string').toEqual(true)
})
})

describe('shouldSkipRevert', () => {
it('should return error message when there is an unkown git error', () => {
const result = shouldSkip.shouldSkipRevert({ errors: new Set([GitError]) })
expect(typeof result === 'string').toEqual(true)
})
})

describe('shouldSkipCleanup', () => {
it('should return error message when reverting to original state fails', () => {
const result = shouldSkip.shouldSkipCleanup({ errors: new Set([RestoreOriginalStateError]) })
expect(typeof result === 'string').toEqual(true)
})
})
})
40 changes: 40 additions & 0 deletions test/state.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
applyModificationsSkipped,
cleanupSkipped,
restoreOriginalStateSkipped,
restoreUnstagedChangesSkipped
} from '../lib/state'
import { GitError, RestoreOriginalStateError } from '../lib/symbols'

describe('applyModificationsSkipped', () => {
it('should return false when backup is disabled', () => {
const result = applyModificationsSkipped({ shouldBackup: false })
expect(result).toEqual(false)
})

it('should return error message when there is an unkown git error', () => {
const result = applyModificationsSkipped({ shouldBackup: true, errors: new Set([GitError]) })
expect(typeof result === 'string').toEqual(true)
})
})

describe('restoreUnstagedChangesSkipped', () => {
it('should return error message when there is an unkown git error', () => {
const result = restoreUnstagedChangesSkipped({ errors: new Set([GitError]) })
expect(typeof result === 'string').toEqual(true)
})
})

describe('restoreOriginalStateSkipped', () => {
it('should return error message when there is an unkown git error', () => {
const result = restoreOriginalStateSkipped({ errors: new Set([GitError]) })
expect(typeof result === 'string').toEqual(true)
})
})

describe('shouldSkipCleanup', () => {
it('should return error message when reverting to original state fails', () => {
const result = cleanupSkipped({ errors: new Set([RestoreOriginalStateError]) })
expect(typeof result === 'string').toEqual(true)
})
})

0 comments on commit e95d1b0

Please sign in to comment.