Skip to content

Add utils.status.show() #1264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 50 additions & 30 deletions packages/build/src/core/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const { startTimer, endTimer } = require('../log/timer')
const { EVENTS } = require('../plugins/events')
const { callChild } = require('../plugins/ipc')

const { getSuccessStatus, addStatus } = require('./status')

// Get commands for all events
const getCommands = function(pluginsCommands, netlifyConfig) {
const commands = addBuildCommand(pluginsCommands, netlifyConfig)
Expand Down Expand Up @@ -57,40 +59,45 @@ const isSuccessCommand = function({ event }) {
// If an error arises, runs `onError` events.
// Runs `onEnd` events at the end, whether an error was thrown or not.
const runCommands = async function({ commands, configPath, buildDir, nodePath, childEnv, errorMonitor, api }) {
const { index: commandsCount, error: errorA } = await pReduce(
const { index: commandsCount, error: errorA, statuses: statusesB } = await pReduce(
commands,
async (
{ index, error, failedPlugins, envChanges },
{ index, error, failedPlugins, envChanges, statuses },
{ event, childProcess, package, packageJson, local, buildCommand },
) => {
const { newIndex = index, newError = error, failedPlugin = [], newEnvChanges = {} } = await runCommand({
event,
childProcess,
package,
packageJson,
local,
buildCommand,
configPath,
buildDir,
nodePath,
index,
childEnv,
envChanges,
errorMonitor,
api,
error,
failedPlugins,
})
const { newIndex = index, newError = error, failedPlugin = [], newEnvChanges = {}, newStatus } = await runCommand(
{
event,
childProcess,
package,
packageJson,
local,
buildCommand,
configPath,
buildDir,
nodePath,
index,
childEnv,
envChanges,
statuses,
errorMonitor,
api,
error,
failedPlugins,
},
)
const statusesA = addStatus({ newStatus, statuses, event, package, packageJson })
return {
index: newIndex,
error: newError,
failedPlugins: [...failedPlugins, ...failedPlugin],
envChanges: { ...envChanges, ...newEnvChanges },
statuses: statusesA,
}
},
{ index: 0, failedPlugins: [], envChanges: {} },
{ index: 0, failedPlugins: [], envChanges: {}, statuses: [] },
)
return { commandsCount, error: errorA }
return { commandsCount, error: errorA, statuses: statusesB }
}

// Run a command (shell or plugin)
Expand All @@ -107,6 +114,7 @@ const runCommand = async function({
index,
childEnv,
envChanges,
statuses,
errorMonitor,
api,
error,
Expand All @@ -120,7 +128,7 @@ const runCommand = async function({

logCommand({ event, package, index, configPath, error })

const { newEnvChanges, newError } = await fireCommand({
const { newEnvChanges, newError, newStatus } = await fireCommand({
event,
childProcess,
package,
Expand All @@ -132,12 +140,13 @@ const runCommand = async function({
nodePath,
childEnv,
envChanges,
statuses,
error,
})

const newValues =
newError === undefined
? handleCommandSuccess({ event, package, newEnvChanges, methodTimer })
? handleCommandSuccess({ event, package, newEnvChanges, newStatus, methodTimer })
: await handleCommandError({ newError, errorMonitor, api })
return { ...newValues, newIndex: index + 1 }
}
Expand Down Expand Up @@ -166,13 +175,14 @@ const fireCommand = function({
nodePath,
childEnv,
envChanges,
statuses,
error,
}) {
if (buildCommand !== undefined) {
return fireBuildCommand({ buildCommand, configPath, buildDir, nodePath, childEnv, envChanges })
}

return firePluginCommand({ event, childProcess, package, packageJson, local, envChanges, error })
return firePluginCommand({ event, childProcess, package, packageJson, local, envChanges, statuses, error })
}

// Fire `build.command`
Expand Down Expand Up @@ -203,17 +213,27 @@ const fireBuildCommand = async function({ buildCommand, configPath, buildDir, no
const SHELL = platform === 'win32' ? true : 'bash'

// Fire a plugin command
const firePluginCommand = async function({ event, childProcess, package, packageJson, local, envChanges, error }) {
const firePluginCommand = async function({
event,
childProcess,
package,
packageJson,
local,
envChanges,
statuses,
error,
}) {
pipeOutput(childProcess)

try {
const { newEnvChanges } = await callChild(
const { newEnvChanges, status } = await callChild(
childProcess,
'run',
{ event, error, envChanges },
{ plugin: { packageJson, package }, location: { event, package, local } },
)
return { newEnvChanges }
const newStatus = getSuccessStatus({ status, statuses, package })
return { newEnvChanges, newStatus }
} catch (newError) {
return { newError }
} finally {
Expand All @@ -222,13 +242,13 @@ const firePluginCommand = async function({ event, childProcess, package, package
}

// `build.command` or plugin event handle success
const handleCommandSuccess = function({ event, package, newEnvChanges, methodTimer }) {
const handleCommandSuccess = function({ event, package, newEnvChanges, newStatus, methodTimer }) {
logCommandSuccess()

const timerName = package === undefined ? 'build.command' : `${package} ${event}`
endTimer(methodTimer, timerName)

return { newEnvChanges }
return { newEnvChanges, newStatus }
}

// Handle shell or plugin error:
Expand Down
33 changes: 33 additions & 0 deletions packages/build/src/core/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Assign default value for successful `newStatus`
// Retrieved from `utils.status.show()`, which is optional
const getSuccessStatus = function({ status, statuses, package }) {
// `utils.status.show()` called in the current event
if (status !== undefined) {
return status
}

// `utils.status.show()` not called, but set in a previous event
const hasStatus = statuses.some(pluginStatus => pluginStatus.package === package)
if (hasStatus) {
return
}

// `utils.status.show()` not called, but this is the first event, so we assign a default
return { state: 'success' }
}

// Merge `success` status to the list of plugin statuses.
const addStatus = function({ newStatus, statuses, event, package, packageJson: { version } = {} }) {
// Either:
// - `build.command`
// - `utils.status.show()` not called but set in a previous event
if (newStatus === undefined) {
return statuses
}

// Overrides plugin's previous status and add more information
const newStatuses = statuses.filter(status => status.package !== package)
return [...newStatuses, { ...newStatus, event, package, version }]
}

module.exports = { getSuccessStatus, addStatus }
2 changes: 1 addition & 1 deletion packages/build/src/error/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const getTypeInfo = function({ type }) {

// List of error types, and their related properties
// Related to build error logs:
// - `title`: main title shown in build error logs
// - `title`: main title shown in build error logs and in the UI (statuses)
// - `getLocation()`: retrieve a human-friendly location of the error, printed
// in build error logs
// - `isSuccess`: `true` when this should not be reported as an error
Expand Down
4 changes: 1 addition & 3 deletions packages/build/src/plugins/child/load.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const { getApiClient } = require('./api')
const { getLogic } = require('./logic')
const { normalizePlugin } = require('./normalize')
const { getUtils } = require('./utils')
const { validatePlugin } = require('./validate')

// Load context passed to every plugin method.
Expand Down Expand Up @@ -34,9 +33,8 @@ const isEventHandler = function([, value]) {

// Retrieve context passed to every event handler
const getContext = function(pluginCommands, { manifest, inputs, netlifyConfig, constants, utilsData, token }) {
const utils = getUtils({ utilsData, constants })
const api = getApiClient({ manifest, token })
return { pluginCommands, api, utils, constants, inputs, netlifyConfig }
return { pluginCommands, api, utilsData, constants, inputs, netlifyConfig }
}

module.exports = { load }
8 changes: 6 additions & 2 deletions packages/build/src/plugins/child/run.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
const { getNewEnvChanges, setEnvChanges } = require('../../env/changes.js')

const { getUtils } = require('./utils')

// Run a specific plugin event handler
const run = async function(
{ event, error, envChanges },
{ pluginCommands, api, utils, constants, inputs, netlifyConfig },
{ pluginCommands, api, utilsData, constants, inputs, netlifyConfig },
) {
const { method } = pluginCommands.find(pluginCommand => pluginCommand.event === event)
const runState = {}
const utils = getUtils({ utilsData, constants, runState })
const runOptions = { api, utils, constants, inputs, netlifyConfig, error }
addBackwardCompatibility(runOptions)

const envBefore = setEnvChanges(envChanges)
await method(runOptions)
const newEnvChanges = getNewEnvChanges(envBefore)
return { newEnvChanges }
return { ...runState, newEnvChanges }
}

// Add older names, kept for backward compatibility. Non-enumerable.
Expand Down
11 changes: 11 additions & 0 deletions packages/build/src/plugins/child/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Retrieve `utils.status.*` methods
const getStatusUtil = function(runState) {
return { show: show.bind(undefined, runState) }
}

// Report status information to the UI
const show = function(runState, { title, summary, text }) {
runState.status = { state: 'success', title, summary, text }
}

module.exports = { getStatusUtil }
6 changes: 5 additions & 1 deletion packages/build/src/plugins/child/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const runUtils = require('@netlify/run-utils')

const { failBuild, failPlugin, cancelBuild } = require('../error')

const { getStatusUtil } = require('./status')

// Some utilities need to perform some async initialization logic first.
// We do it once for all plugins in the parent process then pass it to the child
// processes.
Expand All @@ -14,18 +16,20 @@ const startUtils = async function(buildDir) {
}

// Retrieve the `utils` argument.
const getUtils = function({ utilsData: { git }, constants: { FUNCTIONS_SRC, CACHE_DIR } }) {
const getUtils = function({ utilsData: { git }, constants: { FUNCTIONS_SRC, CACHE_DIR }, runState }) {
const buildUtils = { failBuild, failPlugin, cancelBuild }
const gitA = gitUtils.load(git)
const cache = cacheUtils.bindOpts({ cacheDir: CACHE_DIR })
const add = src => functionsUtils.add(src, FUNCTIONS_SRC, { fail: failBuild })
const functions = { add }
const status = getStatusUtil(runState)
const utils = {
build: buildUtils,
git: gitA,
cache,
run: runUtils,
functions,
status,
}

// Older names, kept for backward compatibility. Non-enumerable.
Expand Down
Binary file modified packages/build/tests/plugins/handlers/snapshots/tests.js.snap
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/build/tests/plugins/utils/snapshots/tests.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ Generated by [AVA](https://ava.li).
│ 1. onInit command from /file/path │␊
└─────────────────────────────────┘␊
build cache functions git run␊
build cache functions git run status
(/file/path onInit completed in 1ms)␊
Expand Down
Binary file modified packages/build/tests/plugins/utils/snapshots/tests.js.snap
Binary file not shown.