forked from gatsbyjs/gatsby
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(gatsby-cli): rework cli to use ink (gatsbyjs#13089)
Replaces our augmented yurnalist reporter with ink. Everything still works the same as before so no changes were made to the reporter api.
- Loading branch information
Showing
11 changed files
with
425 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const semver = require(`semver`) | ||
const { isCI } = require(`ci-info`) | ||
|
||
if (semver.satisfies(process.version, `>=8`) && !isCI) { | ||
module.exports = require(`./ink`).default | ||
} else { | ||
module.exports = require(`./yurnalist`) | ||
} |
23 changes: 23 additions & 0 deletions
23
packages/gatsby-cli/src/reporter/reporters/ink/components/activity.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from "react" | ||
import convertHrtime from "convert-hrtime" | ||
import { Box } from "ink" | ||
import Spinner from "ink-spinner" | ||
|
||
export const calcElapsedTime = startTime => { | ||
const elapsed = process.hrtime(startTime) | ||
|
||
return convertHrtime(elapsed)[`seconds`].toFixed(3) | ||
} | ||
|
||
export default function Activity({ name, status }) { | ||
let statusText = name | ||
if (status) { | ||
statusText += ` — ${status}` | ||
} | ||
|
||
return ( | ||
<Box> | ||
<Spinner type="dots" /> {statusText} | ||
</Box> | ||
) | ||
} |
48 changes: 48 additions & 0 deletions
48
packages/gatsby-cli/src/reporter/reporters/ink/components/messages.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React from "react" | ||
import { Color } from "ink" | ||
import stripAnsi from "strip-ansi" | ||
|
||
const ColorSwitcher = ({ hideColors, children, ...props }) => { | ||
if (hideColors) { | ||
return <>{stripAnsi(children)}</> | ||
} | ||
|
||
return <Color {...props}>{children}</Color> | ||
} | ||
|
||
const createLabel = (text, color) => (...props) => ( | ||
<ColorSwitcher {...{ [color]: true, ...props }}>{text}</ColorSwitcher> | ||
) | ||
|
||
const getLabel = type => { | ||
switch (type) { | ||
case `success`: | ||
return createLabel(`success`, `green`) | ||
case `error`: | ||
return createLabel(`error`, `red`) | ||
case `warn`: | ||
return createLabel(`warn`, `yellow`) | ||
case `verbose`: | ||
return createLabel(`verbose`, `gray`) | ||
case `info`: | ||
return createLabel(`info`, `blue`) | ||
default: | ||
return createLabel(`debug ${type}`, `blue`) | ||
} | ||
} | ||
|
||
export const Message = ({ type, hideColors, children }) => { | ||
if (!type) { | ||
return <>{children}</> | ||
} | ||
|
||
const TextLabel = getLabel(type) | ||
|
||
return ( | ||
<> | ||
<TextLabel hideColors={hideColors} /> | ||
{` `} | ||
{children} | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from "react" | ||
import { render } from "ink" | ||
import GatsbyReporter from "./reporter" | ||
|
||
// render the react component and expose it so it can be changed from the outside world | ||
const inkReporter = React.createRef() | ||
render(<GatsbyReporter ref={inkReporter} />) | ||
|
||
export default /** @type {GatsbyReporter} */ (inkReporter.current) |
144 changes: 144 additions & 0 deletions
144
packages/gatsby-cli/src/reporter/reporters/ink/reporter.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import React from "react" | ||
import { Static, Box } from "ink" | ||
import { isCI } from "ci-info" | ||
import chalk from "chalk" | ||
import Activity, { calcElapsedTime } from "./components/activity" | ||
import { Message } from "./components/messages" | ||
|
||
const showProgress = process.stdout.isTTY && !isCI | ||
|
||
const generateActivityFinishedText = (name, activity) => { | ||
let successText = `${name} - ${calcElapsedTime(activity.startTime)} s` | ||
if (activity.status) { | ||
successText += ` — ${activity.status}` | ||
} | ||
|
||
return successText | ||
} | ||
|
||
export default class GatsbyReporter extends React.Component { | ||
verbose = process.env.gatsby_log_level === `verbose` | ||
state = { | ||
verbose: false, | ||
messages: [], | ||
activities: {}, | ||
} | ||
|
||
format = chalk | ||
|
||
createActivity = name => { | ||
return { | ||
start: () => { | ||
this.setState(state => { | ||
return { | ||
activities: { | ||
...state.activities, | ||
[name]: { | ||
status: ``, | ||
startTime: process.hrtime(), | ||
}, | ||
}, | ||
} | ||
}) | ||
}, | ||
setStatus: status => { | ||
this.setState(state => { | ||
const activity = state.activities[name] | ||
|
||
return { | ||
activities: { | ||
...state.activities, | ||
[name]: { | ||
...activity, | ||
status: status, | ||
}, | ||
}, | ||
} | ||
}) | ||
}, | ||
end: () => { | ||
const activity = this.state.activities[name] | ||
|
||
this.success(generateActivityFinishedText(name, activity)) | ||
|
||
this.setState(state => { | ||
const activities = { ...state.activities } | ||
delete activities[name] | ||
|
||
return { | ||
activities, | ||
} | ||
}) | ||
}, | ||
} | ||
} | ||
|
||
setColors(useColors = false) { | ||
this.setState({ | ||
disableColors: !useColors, | ||
}) | ||
} | ||
|
||
setVerbose(isVerbose = true) { | ||
this.verbose = isVerbose | ||
} | ||
|
||
_addMessage(type, str) { | ||
// threat null/undefind as an empty character, it seems like ink can't handle empty str | ||
if (!str) { | ||
str = `\u2800` | ||
} | ||
|
||
this.setState(state => { | ||
return { | ||
messages: [ | ||
...state.messages, | ||
{ | ||
text: str, | ||
type, | ||
}, | ||
], | ||
} | ||
}) | ||
} | ||
|
||
log = this._addMessage.bind(this, null) | ||
info = this._addMessage.bind(this, `info`) | ||
success = this._addMessage.bind(this, `success`) | ||
warn = this._addMessage.bind(this, `warn`) | ||
error = this._addMessage.bind(this, `error`) | ||
verbose = str => { | ||
if (!this.verbose) { | ||
return | ||
} | ||
|
||
this._addMessage(`verbose`, str) | ||
} | ||
|
||
render() { | ||
return ( | ||
<Box flexDirection="column"> | ||
<Box flexDirection="column"> | ||
<Static> | ||
{this.state.messages.map((msg, index) => ( | ||
<Box textWrap="wrap" key={index}> | ||
<Message type={msg.type} hideColors={this.state.disableColors}> | ||
{msg.text} | ||
</Message> | ||
</Box> | ||
))} | ||
</Static> | ||
|
||
{showProgress && | ||
Object.keys(this.state.activities).map(activityName => ( | ||
<Activity | ||
key={activityName} | ||
name={activityName} | ||
{...this.state.activities[activityName]} | ||
/> | ||
))} | ||
</Box> | ||
</Box> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.