Skip to content

Commit c888652

Browse files
authored
Add utils.status.show() (#1264)
1 parent 8c7a775 commit c888652

File tree

10 files changed

+108
-38
lines changed

10 files changed

+108
-38
lines changed

packages/build/src/core/commands.js

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const { startTimer, endTimer } = require('../log/timer')
1313
const { EVENTS } = require('../plugins/events')
1414
const { callChild } = require('../plugins/ipc')
1515

16+
const { getSuccessStatus, addStatus } = require('./status')
17+
1618
// Get commands for all events
1719
const getCommands = function(pluginsCommands, netlifyConfig) {
1820
const commands = addBuildCommand(pluginsCommands, netlifyConfig)
@@ -57,40 +59,45 @@ const isSuccessCommand = function({ event }) {
5759
// If an error arises, runs `onError` events.
5860
// Runs `onEnd` events at the end, whether an error was thrown or not.
5961
const runCommands = async function({ commands, configPath, buildDir, nodePath, childEnv, errorMonitor, api }) {
60-
const { index: commandsCount, error: errorA } = await pReduce(
62+
const { index: commandsCount, error: errorA, statuses: statusesB } = await pReduce(
6163
commands,
6264
async (
63-
{ index, error, failedPlugins, envChanges },
65+
{ index, error, failedPlugins, envChanges, statuses },
6466
{ event, childProcess, package, packageJson, local, buildCommand },
6567
) => {
66-
const { newIndex = index, newError = error, failedPlugin = [], newEnvChanges = {} } = await runCommand({
67-
event,
68-
childProcess,
69-
package,
70-
packageJson,
71-
local,
72-
buildCommand,
73-
configPath,
74-
buildDir,
75-
nodePath,
76-
index,
77-
childEnv,
78-
envChanges,
79-
errorMonitor,
80-
api,
81-
error,
82-
failedPlugins,
83-
})
68+
const { newIndex = index, newError = error, failedPlugin = [], newEnvChanges = {}, newStatus } = await runCommand(
69+
{
70+
event,
71+
childProcess,
72+
package,
73+
packageJson,
74+
local,
75+
buildCommand,
76+
configPath,
77+
buildDir,
78+
nodePath,
79+
index,
80+
childEnv,
81+
envChanges,
82+
statuses,
83+
errorMonitor,
84+
api,
85+
error,
86+
failedPlugins,
87+
},
88+
)
89+
const statusesA = addStatus({ newStatus, statuses, event, package, packageJson })
8490
return {
8591
index: newIndex,
8692
error: newError,
8793
failedPlugins: [...failedPlugins, ...failedPlugin],
8894
envChanges: { ...envChanges, ...newEnvChanges },
95+
statuses: statusesA,
8996
}
9097
},
91-
{ index: 0, failedPlugins: [], envChanges: {} },
98+
{ index: 0, failedPlugins: [], envChanges: {}, statuses: [] },
9299
)
93-
return { commandsCount, error: errorA }
100+
return { commandsCount, error: errorA, statuses: statusesB }
94101
}
95102

96103
// Run a command (shell or plugin)
@@ -107,6 +114,7 @@ const runCommand = async function({
107114
index,
108115
childEnv,
109116
envChanges,
117+
statuses,
110118
errorMonitor,
111119
api,
112120
error,
@@ -120,7 +128,7 @@ const runCommand = async function({
120128

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

123-
const { newEnvChanges, newError } = await fireCommand({
131+
const { newEnvChanges, newError, newStatus } = await fireCommand({
124132
event,
125133
childProcess,
126134
package,
@@ -132,12 +140,13 @@ const runCommand = async function({
132140
nodePath,
133141
childEnv,
134142
envChanges,
143+
statuses,
135144
error,
136145
})
137146

138147
const newValues =
139148
newError === undefined
140-
? handleCommandSuccess({ event, package, newEnvChanges, methodTimer })
149+
? handleCommandSuccess({ event, package, newEnvChanges, newStatus, methodTimer })
141150
: await handleCommandError({ newError, errorMonitor, api })
142151
return { ...newValues, newIndex: index + 1 }
143152
}
@@ -166,13 +175,14 @@ const fireCommand = function({
166175
nodePath,
167176
childEnv,
168177
envChanges,
178+
statuses,
169179
error,
170180
}) {
171181
if (buildCommand !== undefined) {
172182
return fireBuildCommand({ buildCommand, configPath, buildDir, nodePath, childEnv, envChanges })
173183
}
174184

175-
return firePluginCommand({ event, childProcess, package, packageJson, local, envChanges, error })
185+
return firePluginCommand({ event, childProcess, package, packageJson, local, envChanges, statuses, error })
176186
}
177187

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

205215
// Fire a plugin command
206-
const firePluginCommand = async function({ event, childProcess, package, packageJson, local, envChanges, error }) {
216+
const firePluginCommand = async function({
217+
event,
218+
childProcess,
219+
package,
220+
packageJson,
221+
local,
222+
envChanges,
223+
statuses,
224+
error,
225+
}) {
207226
pipeOutput(childProcess)
208227

209228
try {
210-
const { newEnvChanges } = await callChild(
229+
const { newEnvChanges, status } = await callChild(
211230
childProcess,
212231
'run',
213232
{ event, error, envChanges },
214233
{ plugin: { packageJson, package }, location: { event, package, local } },
215234
)
216-
return { newEnvChanges }
235+
const newStatus = getSuccessStatus({ status, statuses, package })
236+
return { newEnvChanges, newStatus }
217237
} catch (newError) {
218238
return { newError }
219239
} finally {
@@ -222,13 +242,13 @@ const firePluginCommand = async function({ event, childProcess, package, package
222242
}
223243

224244
// `build.command` or plugin event handle success
225-
const handleCommandSuccess = function({ event, package, newEnvChanges, methodTimer }) {
245+
const handleCommandSuccess = function({ event, package, newEnvChanges, newStatus, methodTimer }) {
226246
logCommandSuccess()
227247

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

231-
return { newEnvChanges }
251+
return { newEnvChanges, newStatus }
232252
}
233253

234254
// Handle shell or plugin error:

packages/build/src/core/status.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Assign default value for successful `newStatus`
2+
// Retrieved from `utils.status.show()`, which is optional
3+
const getSuccessStatus = function({ status, statuses, package }) {
4+
// `utils.status.show()` called in the current event
5+
if (status !== undefined) {
6+
return status
7+
}
8+
9+
// `utils.status.show()` not called, but set in a previous event
10+
const hasStatus = statuses.some(pluginStatus => pluginStatus.package === package)
11+
if (hasStatus) {
12+
return
13+
}
14+
15+
// `utils.status.show()` not called, but this is the first event, so we assign a default
16+
return { state: 'success' }
17+
}
18+
19+
// Merge `success` status to the list of plugin statuses.
20+
const addStatus = function({ newStatus, statuses, event, package, packageJson: { version } = {} }) {
21+
// Either:
22+
// - `build.command`
23+
// - `utils.status.show()` not called but set in a previous event
24+
if (newStatus === undefined) {
25+
return statuses
26+
}
27+
28+
// Overrides plugin's previous status and add more information
29+
const newStatuses = statuses.filter(status => status.package !== package)
30+
return [...newStatuses, { ...newStatus, event, package, version }]
31+
}
32+
33+
module.exports = { getSuccessStatus, addStatus }

packages/build/src/error/type.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const getTypeInfo = function({ type }) {
88

99
// List of error types, and their related properties
1010
// Related to build error logs:
11-
// - `title`: main title shown in build error logs
11+
// - `title`: main title shown in build error logs and in the UI (statuses)
1212
// - `getLocation()`: retrieve a human-friendly location of the error, printed
1313
// in build error logs
1414
// - `isSuccess`: `true` when this should not be reported as an error

packages/build/src/plugins/child/load.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const { getApiClient } = require('./api')
22
const { getLogic } = require('./logic')
33
const { normalizePlugin } = require('./normalize')
4-
const { getUtils } = require('./utils')
54
const { validatePlugin } = require('./validate')
65

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

3534
// Retrieve context passed to every event handler
3635
const getContext = function(pluginCommands, { manifest, inputs, netlifyConfig, constants, utilsData, token }) {
37-
const utils = getUtils({ utilsData, constants })
3836
const api = getApiClient({ manifest, token })
39-
return { pluginCommands, api, utils, constants, inputs, netlifyConfig }
37+
return { pluginCommands, api, utilsData, constants, inputs, netlifyConfig }
4038
}
4139

4240
module.exports = { load }

packages/build/src/plugins/child/run.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
const { getNewEnvChanges, setEnvChanges } = require('../../env/changes.js')
22

3+
const { getUtils } = require('./utils')
4+
35
// Run a specific plugin event handler
46
const run = async function(
57
{ event, error, envChanges },
6-
{ pluginCommands, api, utils, constants, inputs, netlifyConfig },
8+
{ pluginCommands, api, utilsData, constants, inputs, netlifyConfig },
79
) {
810
const { method } = pluginCommands.find(pluginCommand => pluginCommand.event === event)
11+
const runState = {}
12+
const utils = getUtils({ utilsData, constants, runState })
913
const runOptions = { api, utils, constants, inputs, netlifyConfig, error }
1014
addBackwardCompatibility(runOptions)
1115

1216
const envBefore = setEnvChanges(envChanges)
1317
await method(runOptions)
1418
const newEnvChanges = getNewEnvChanges(envBefore)
15-
return { newEnvChanges }
19+
return { ...runState, newEnvChanges }
1620
}
1721

1822
// Add older names, kept for backward compatibility. Non-enumerable.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Retrieve `utils.status.*` methods
2+
const getStatusUtil = function(runState) {
3+
return { show: show.bind(undefined, runState) }
4+
}
5+
6+
// Report status information to the UI
7+
const show = function(runState, { title, summary, text }) {
8+
runState.status = { state: 'success', title, summary, text }
9+
}
10+
11+
module.exports = { getStatusUtil }

packages/build/src/plugins/child/utils.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const runUtils = require('@netlify/run-utils')
55

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

8+
const { getStatusUtil } = require('./status')
9+
810
// Some utilities need to perform some async initialization logic first.
911
// We do it once for all plugins in the parent process then pass it to the child
1012
// processes.
@@ -14,18 +16,20 @@ const startUtils = async function(buildDir) {
1416
}
1517

1618
// Retrieve the `utils` argument.
17-
const getUtils = function({ utilsData: { git }, constants: { FUNCTIONS_SRC, CACHE_DIR } }) {
19+
const getUtils = function({ utilsData: { git }, constants: { FUNCTIONS_SRC, CACHE_DIR }, runState }) {
1820
const buildUtils = { failBuild, failPlugin, cancelBuild }
1921
const gitA = gitUtils.load(git)
2022
const cache = cacheUtils.bindOpts({ cacheDir: CACHE_DIR })
2123
const add = src => functionsUtils.add(src, FUNCTIONS_SRC, { fail: failBuild })
2224
const functions = { add }
25+
const status = getStatusUtil(runState)
2326
const utils = {
2427
build: buildUtils,
2528
git: gitA,
2629
cache,
2730
run: runUtils,
2831
functions,
32+
status,
2933
}
3034

3135
// Older names, kept for backward compatibility. Non-enumerable.
Binary file not shown.

packages/build/tests/plugins/utils/snapshots/tests.js.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ Generated by [AVA](https://ava.li).
300300
│ 1. onInit command from /file/path │␊
301301
└─────────────────────────────────┘␊
302302
303-
build cache functions git run␊
303+
build cache functions git run status
304304
305305
(/file/path onInit completed in 1ms)␊
306306
Binary file not shown.

0 commit comments

Comments
 (0)