Skip to content

Commit 550091f

Browse files
Merge pull request #381 from paritytech/mod-hide-missing-setup
fix(mod): hide the setup.sh step when an app has none
2 parents c2270c1 + 8026977 commit 550091f

3 files changed

Lines changed: 51 additions & 19 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"playground-cli": patch
3+
---
4+
5+
`playground mod`: stop showing a warning when an app has no `setup.sh`. Apps without a setup script are the common case, and surfacing it as a yellow warning row alarmed users. The step is now skipped silently and the usual "Next steps" footer is printed as before.

src/commands/mod/SetupScreen.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,11 @@ export function SetupScreen({ domain, metadata: initial, registry, targetDir, on
154154
run: async (log) => {
155155
const setupPath = resolve(targetDir, "setup.sh");
156156
if (!existsSync(setupPath)) {
157-
throw new StepWarning("no setup.sh found");
157+
// Most moddable apps have no setup.sh, and that's normal —
158+
// surfacing it as a warning row alarmed users. Skip the step
159+
// silently so nothing is shown; the parent still prints the
160+
// generic "Next steps" footer because `setupRan` stays false.
161+
throw new SilentSkip("no setup.sh found");
158162
}
159163
const missing = await findUnsatisfiedPackageManagers(
160164
readFileSync(setupPath, "utf8"),
@@ -216,10 +220,17 @@ export function SetupScreen({ domain, metadata: initial, registry, targetDir, on
216220
);
217221
}
218222

219-
class StepWarning extends Error {
220-
isWarning = true;
223+
/**
224+
* Thrown inside a StepRunner step to remove its row from the UI entirely
225+
* (StepRunner duck-types the `isSilentSkip` flag). Execution continues and the
226+
* run still reports `ok: true`. Used when an optional step has nothing to do
227+
* and its absence is a non-event the user shouldn't see.
228+
*/
229+
class SilentSkip extends Error {
230+
readonly isSilentSkip = true;
221231
constructor(message: string) {
222232
super(message);
233+
this.name = "SilentSkip";
223234
}
224235
}
225236

src/utils/ui/components/StepRunner.tsx

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
* STOP execution, but report `ok: false` with no `error` — for cases the
2424
* parent wants to present gently (its own Callout) rather than as a red
2525
* failure row, while still skipping any success-only output.
26+
* Silent skips (`isSilentSkip = true`) remove the step's row from the UI
27+
* entirely and don't stop execution (`ok` is preserved) — for optional steps
28+
* whose absence is a non-event the user shouldn't see (e.g. an app with no
29+
* `setup.sh` to run).
2630
*/
2731

2832
import { useState, useEffect, useRef } from "react";
@@ -46,7 +50,7 @@ export interface Step {
4650
keepLogOnSuccess?: boolean;
4751
}
4852

49-
type StepStatus = "pending" | "running" | "ok" | "failed" | "warning";
53+
type StepStatus = "pending" | "running" | "ok" | "failed" | "warning" | "skipped";
5054

5155
interface StepState {
5256
name: string;
@@ -144,7 +148,14 @@ export function StepRunner({ title, steps, onDone }: Props) {
144148
const isWarning = err instanceof Error && (err as any).isWarning === true;
145149
const haltAsWarning =
146150
err instanceof Error && (err as any).haltAsWarning === true;
151+
const isSilentSkip = err instanceof Error && (err as any).isSilentSkip === true;
147152

153+
if (isSilentSkip) {
154+
setStates((prev) =>
155+
prev.map((s, j) => (j === i ? { ...s, status: "skipped" } : s)),
156+
);
157+
continue;
158+
}
148159
if (haltAsWarning) {
149160
setStates((prev) =>
150161
prev.map((s, j) =>
@@ -188,21 +199,26 @@ export function StepRunner({ title, steps, onDone }: Props) {
188199

189200
return (
190201
<Section title={title}>
191-
{states.map((step) => (
192-
<Box key={step.name} flexDirection="column">
193-
<Row
194-
mark={toMark(step.status)}
195-
label={step.name}
196-
value={step.message}
197-
tone={step.status === "failed" ? "danger" : "muted"}
198-
/>
199-
{step.retainedLog && step.retainedLog.length > 0 && (
200-
<Box marginTop={1} marginBottom={1}>
201-
<LogTail lines={step.retainedLog} height={step.retainedLog.length} />
202-
</Box>
203-
)}
204-
</Box>
205-
))}
202+
{states
203+
.filter((step) => step.status !== "skipped")
204+
.map((step) => (
205+
<Box key={step.name} flexDirection="column">
206+
<Row
207+
mark={toMark(step.status)}
208+
label={step.name}
209+
value={step.message}
210+
tone={step.status === "failed" ? "danger" : "muted"}
211+
/>
212+
{step.retainedLog && step.retainedLog.length > 0 && (
213+
<Box marginTop={1} marginBottom={1}>
214+
<LogTail
215+
lines={step.retainedLog}
216+
height={step.retainedLog.length}
217+
/>
218+
</Box>
219+
)}
220+
</Box>
221+
))}
206222
{running && liveOutput.length > 0 && (
207223
<Box marginTop={1}>
208224
<LogTail lines={liveOutput} height={LIVE_LOG_LINES} />

0 commit comments

Comments
 (0)