Skip to content

Commit

Permalink
✨ improve(patch): heal cli commands cache (#2400)
Browse files Browse the repository at this point in the history
- prevent errors from being overwritten (in case of multiple node errors)
- rebuild command cache on type errors

## Type of change

**PATCH: backwards compatible change**
  • Loading branch information
kellymears authored Aug 9, 2023
1 parent 5c3f02f commit 7eb502f
Showing 36 changed files with 377 additions and 225 deletions.
4 changes: 1 addition & 3 deletions sources/@roots/bud-compiler/src/service/index.tsx
Original file line number Diff line number Diff line change
@@ -93,9 +93,7 @@ class Compiler extends Service implements BudCompiler {

this.instance.hooks.done.tap(bud.label, (stats: any) => {
this.onStats(stats)
bud.hooks.fire(`compiler.done`, bud, this.stats).catch(error => {
throw error
})
bud.hooks.fire(`compiler.done`, bud, this.stats).catch(this.onError)
})

return this.instance
217 changes: 121 additions & 96 deletions sources/@roots/bud-dashboard/src/components/error.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable n/no-process-env */
import {BudError} from '@roots/bud-support/errors'
import figures from '@roots/bud-support/figures'
import {Box, Text} from '@roots/bud-support/ink'
import {Box, type ReactNode, Static, Text} from '@roots/bud-support/ink'
import isString from '@roots/bud-support/lodash/isString'

const basePath =
process.env.PROJECT_CWD ?? process.env.INIT_CWD ?? process.cwd()

export const Error = ({error}: {error: BudError | Error}) => {
export const Error = ({error}: {error: unknown}): ReactNode => {
let normalError: BudError

if (!error) {
@@ -35,110 +35,135 @@ export const Error = ({error}: {error: BudError | Error}) => {
error instanceof BudError ? error : BudError.normalize(error)

return (
<Box flexDirection="column" paddingTop={1}>
<Text backgroundColor="red" color="white">
{` `}
{normalError.name ?? `Error`}
{` `}
</Text>

{normalError.message && (
<Box marginTop={1}>
<Text>
<Text color="red">{figures.cross}</Text>
<Static items={[0]}>
{() => (
<Box flexDirection="column" paddingTop={1}>
<Text backgroundColor="red" color="white">
{` `}
{normalError.name ?? `Error`}
{` `}
{normalError.message
.replace(basePath, `.`)
.replace(`Error: `, ``)}
</Text>
</Box>
)}

{normalError.details &&
!normalError.details.startsWith(`resolve`) && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.ellipsis}
{` `}Details{` `}
{normalError.message && (
<Box marginTop={1}>
<Text>
<Text color="red">{figures.cross}</Text>
{` `}
{normalError.message
.replace(basePath, `.`)
.replace(`Error: `, ``)}
</Text>
</Box>
)}

{normalError.details &&
!normalError.details.startsWith(`resolve`) && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.ellipsis}
{` `}Details{` `}
</Text>

<Text>{normalError.details.replace(basePath, `.`)}</Text>
</Text>
</Box>
)}

{normalError.thrownBy && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.ellipsis}
{` `}Thrown by{` `}
</Text>

<Text>{normalError.thrownBy}</Text>
</Text>
</Box>
)}

{normalError.docs && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.arrowRight}
{` `}Documentation
</Text>
{` `}
<Text>{normalError.docs.href}</Text>
</Text>
</Box>
)}

{normalError.issues && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.arrowRight}
{` `}
Issues
</Text>
{` `}
<Text>{normalError.issues.href}</Text>
</Text>
</Box>
)}

<Text>{normalError.details.replace(basePath, `.`)}</Text>
</Text>
</Box>
)}

{normalError.thrownBy && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.ellipsis}
{` `}Thrown by{` `}
</Text>

<Text>{normalError.thrownBy}</Text>
</Text>
</Box>
)}

{normalError.docs && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.arrowRight}
{` `}Documentation
</Text>
{` `}
<Text>{normalError.docs.href}</Text>
</Text>
</Box>
)}

{normalError.issues && (
<Box marginTop={1}>
<Text>
<Text color="blue">
{figures.arrowRight}
{` `}
Issues
</Text>
{` `}
<Text>{normalError.issues.href}</Text>
</Text>
</Box>
)}
{normalError.file && (
<Box marginTop={1}>
<Text color="blue">
{figures.info}
{` `}See file{` `}
</Text>
<Text>{normalError.file.path}</Text>
</Box>
)}

{normalError.file && (
<Box marginTop={1}>
<Text color="blue">
{figures.info}
{` `}See file{` `}
</Text>
<Text>{normalError.file.path}</Text>
</Box>
)}
{normalError.origin && (
<Box flexDirection="column" marginTop={1}>
<Text color="blue">
{figures.home}
{` `}Originating error{` `}
</Text>

{normalError.origin && (
<Box flexDirection="column">
<Text color="blue">
{figures.home}
{` `}Originating error{` `}
</Text>
<Box
borderBottom={false}
borderColor="red"
borderLeft
borderRight={false}
borderStyle="single"
borderTop={false}
paddingLeft={1}
>
<Error error={normalError.origin} />
</Box>
</Box>
)}

{normalError.stack && (
<Box flexDirection="column" marginTop={1}>
<Text color="blue">
{figures.home}
{` `}Stack trace{` `}
</Text>

<Box
borderBottom={false}
borderColor="red"
borderLeft
borderRight={false}
borderStyle="single"
borderTop={false}
paddingLeft={1}
>
<Error error={normalError.origin} />
</Box>
<Box
borderBottom={false}
borderColor="red"
borderLeft
borderRight={false}
borderStyle="single"
borderTop={false}
paddingLeft={1}
>
<Text>{normalError.stack}</Text>
</Box>
</Box>
)}
</Box>
)}
</Box>
</Static>
)
}

1 change: 0 additions & 1 deletion sources/@roots/bud-dashboard/src/views/server.tsx
Original file line number Diff line number Diff line change
@@ -120,5 +120,4 @@ const Dev = ({
)
}


export {Server as default}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Option} from '@roots/bud-support/clipanion'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

/**
* Bud eslint command
2 changes: 1 addition & 1 deletion sources/@roots/bud-framework/src/bud.ts
Original file line number Diff line number Diff line change
@@ -324,7 +324,7 @@ export class Bud {

await this.children[context.label].promise()

this.get(context.label).hooks.on(
this.get(context.label)?.hooks.on(
`build.dependencies`,
typeof request !== `string` && request.dependsOn
? request.dependsOn
2 changes: 2 additions & 0 deletions sources/@roots/bud-framework/src/context.ts
Original file line number Diff line number Diff line change
@@ -82,6 +82,8 @@ export interface Context {
*/
clean?: boolean

colorDepth?: number

/**
* Render dashboard in CLI
*
2 changes: 1 addition & 1 deletion sources/@roots/bud-hooks/src/base/base.ts
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ export abstract class Hooks<Store> {

@bind
public catch(e: Error, id?: string, iteration?: number): void {
throw new BudError(`problem running hook ${id}`, {cause: e})
throw new BudError(`problem running hook ${id}`, {origin: e})
}

/**
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Command, Option} from '@roots/bud-support/clipanion'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

/**
* `bud prettier` command
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Command, Option} from '@roots/bud-support/clipanion'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

/**
* Bud stylelint command
20 changes: 18 additions & 2 deletions sources/@roots/bud-support/src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import cleanStack from 'clean-stack'

/**
* Props for Bud errors
*/
@@ -14,7 +16,7 @@ interface BudErrorProps extends Error {
isBudError: true
issue: URL
message: string
origin: BudError
origin: BudError | Error | string
thrownBy: string
}

@@ -64,7 +66,7 @@ class BudError extends Error {
/**
* Original error
*/
public declare origin: BudError | false
public declare origin: BudError | Error | string

/**
* Name of method that threw error
@@ -81,6 +83,20 @@ class BudError extends Error {

if (!this.instance) this.instance = `default`

if (this.stack) {
this.stack = cleanStack(this.stack, {
pathFilter: path =>
!path.includes(`react-reconciler`) &&
!path.includes(`bud-support/lib/errors`),
})
}
if (this.message) {
this.message = cleanStack(this.message, {
pathFilter: path =>
!path.includes(`react-reconciler`) &&
!path.includes(`bud-support/lib/errors`),
})
}
this.isBudError = true
}

1 change: 1 addition & 0 deletions sources/@roots/bud-support/src/ink/index.ts
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ export {
memo,
type PropsWithChildren,
type ReactElement,
type ReactNode,
useCallback,
useContext,
useDebugValue,
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {relative} from 'node:path'

import {Option} from '@roots/bud-support/clipanion'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

export class BudTailwindCommand extends BudCommand {
/**
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {bind} from '@roots/bud-support/decorators/bind'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

/**
* Bud ts check command
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Command, Option} from '@roots/bud-support/clipanion'
import BudCommand from '@roots/bud/cli/commands/bud'
import BudCommand from '@roots/bud/cli/commands'

/**
* Bud tsc command
Loading

0 comments on commit 7eb502f

Please sign in to comment.