Skip to content

Commit 05de4cf

Browse files
committed
Fix #185, Silent fail on example cp fail
Signed-off-by: paulober <[email protected]>
1 parent 2933052 commit 05de4cf

File tree

2 files changed

+140
-42
lines changed

2 files changed

+140
-42
lines changed

src/utils/examplesUtil.mts

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { get } from "https";
1414
import { isInternetConnected, getDataRoot } from "./downloadHelpers.mjs";
1515
import { unknownErrorToString } from "./errorHelper.mjs";
1616
import { CURRENT_DATA_VERSION } from "./sharedConstants.mjs";
17+
import { window } from "vscode";
1718

1819
const EXAMPLES_REPOSITORY_URL =
1920
"https://github.com/raspberrypi/pico-examples.git";
@@ -181,21 +182,40 @@ export async function setupExample(
181182
process.env.ComSpec === "powershell.exe" ? "&" : ""
182183
}"${gitPath}" rev-parse HEAD`
183184
);
184-
Logger.log(`Examples git ref is ${ref.stdout}\n`);
185+
Logger.debug(
186+
LoggerSource.examples,
187+
`Examples git ref is ${ref.stdout}\n`
188+
);
185189
if (ref.stdout.trim() !== EXAMPLES_GITREF) {
186-
Logger.log(`Removing old examples repo\n`);
190+
Logger.debug(LoggerSource.examples, `Removing old examples repo\n`);
187191
rmSync(examplesRepoPath, { recursive: true, force: true });
188192
}
189193
// eslint-disable-next-line @typescript-eslint/no-unused-vars
190194
} catch (error) {
191195
// Corrupted examples directory
192-
Logger.log(`Removing corrupted examples repo\n`);
193-
rmSync(examplesRepoPath, { recursive: true, force: true });
196+
Logger.debug(LoggerSource.examples, `Removing corrupted examples repo\n`);
197+
try {
198+
rmSync(examplesRepoPath, { recursive: true, force: true });
199+
} catch (error) {
200+
Logger.warn(
201+
LoggerSource.examples,
202+
"Failed to remove corrupted examples repo.",
203+
unknownErrorToString(error)
204+
);
205+
}
194206
}
195207
} else if (existsSync(examplesRepoPath)) {
196208
// Examples path exists, but does not contain a git repository
197-
Logger.log(`Removing empty examples repo\n`);
198-
rmSync(examplesRepoPath, { recursive: true, force: true });
209+
Logger.debug(LoggerSource.examples, `Removing empty examples repo\n`);
210+
try {
211+
rmSync(examplesRepoPath, { recursive: true, force: true });
212+
} catch (error) {
213+
Logger.warn(
214+
LoggerSource.examples,
215+
"Failed to remove empty examples repo.",
216+
unknownErrorToString(error)
217+
);
218+
}
199219
}
200220

201221
if (!existsSync(examplesRepoPath)) {
@@ -211,43 +231,115 @@ export async function setupExample(
211231
}
212232
}
213233

214-
Logger.log(`Sparse-checkout selected example: ${example.name}`);
234+
Logger.debug(
235+
LoggerSource.examples,
236+
`Sparse-checkout selected example: ${example.name}`
237+
);
215238
const result = await sparseCheckout(examplesRepoPath, example.path, gitPath);
216239
if (!result) {
240+
Logger.error(
241+
LoggerSource.examples,
242+
`Failed to checkout example '${example.name}':`,
243+
unknownErrorToString(result)
244+
);
245+
void window.showErrorMessage(
246+
`Failed to checkout example: ${example.name}. ` +
247+
"Please check the output window for more details."
248+
);
249+
217250
return result;
218251
}
219252

220253
for (const libPath of example.libPaths) {
221-
Logger.log(`Sparse-checkout selected example required path: ${libPath}`);
254+
Logger.debug(
255+
LoggerSource.examples,
256+
`Sparse-checkout selected example required path: ${libPath}`
257+
);
222258
const result = await sparseCheckout(examplesRepoPath, libPath, gitPath);
223259
if (!result) {
260+
Logger.error(
261+
LoggerSource.examples,
262+
`Failed to checkout example required path '${libPath}':`,
263+
unknownErrorToString(result)
264+
);
265+
void window.showErrorMessage(
266+
`Failed to checkout example required path '${libPath}'. ` +
267+
"Please check the output window for more details."
268+
);
269+
224270
return result;
225271
}
226272
}
227273

228-
Logger.log(`Copying example from ${absoluteExamplePath} to ${targetPath}`);
274+
Logger.debug(
275+
LoggerSource.examples,
276+
`Copying example from ${absoluteExamplePath} to ${targetPath}`
277+
);
229278
// TODO: use example.name or example.search key for project folder name?
230-
await cp(absoluteExamplePath, joinPosix(targetPath, example.searchKey), {
231-
recursive: true,
232-
});
279+
try {
280+
await cp(absoluteExamplePath, joinPosix(targetPath, example.searchKey), {
281+
recursive: true,
282+
});
283+
} catch (error) {
284+
const msg = unknownErrorToString(error);
285+
if (
286+
msg.includes("EACCESS") ||
287+
msg.includes("EPERM") ||
288+
msg.includes("access denied")
289+
) {
290+
Logger.error(
291+
LoggerSource.examples,
292+
"Failed to copy example. " +
293+
"Please check if the target path is writable.",
294+
msg
295+
);
296+
void window.showErrorMessage(
297+
"Failed to copy example. " +
298+
"Please check if the target path is writable."
299+
);
300+
} else {
301+
Logger.error(LoggerSource.examples, "Failed to copy example.", msg);
302+
void window.showErrorMessage(
303+
"Failed to copy example. " +
304+
"Please check the output window for more details."
305+
);
306+
}
307+
308+
return false;
309+
}
233310

234311
for (let i = 0; i < example.libPaths.length; i++) {
235312
const libPath = example.libPaths[i];
236313
const libName = example.libNames[i];
237314
const absoluteLibPath = joinPosix(examplesRepoPath, libPath);
238-
Logger.log(
315+
Logger.debug(
316+
LoggerSource.examples,
239317
`Copying example required path from ${absoluteLibPath} ` +
240318
`to ${targetPath}/${example.searchKey}/${libName}`
241319
);
242320
// TODO: use example.name or example.search key for project folder name?
243-
await cp(
244-
absoluteLibPath,
245-
joinPosix(targetPath, example.searchKey, libName),
246-
{ recursive: true }
247-
);
321+
try {
322+
await cp(
323+
absoluteLibPath,
324+
joinPosix(targetPath, example.searchKey, libName),
325+
{ recursive: true }
326+
);
327+
} catch (error) {
328+
Logger.error(
329+
LoggerSource.examples,
330+
`Failed to copy example requirement '${libName}':`,
331+
unknownErrorToString(error)
332+
);
333+
void window.showErrorMessage(
334+
`Failed to copy example requirement '${libName}'. ` +
335+
"Please check the output window for more details."
336+
);
337+
338+
return false;
339+
}
248340
}
249341

250-
Logger.log("Done copying example.");
342+
Logger.info(LoggerSource.examples, "Done copying example.");
251343

252344
return result;
253345
}

src/webview/newProjectPanel.mts

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,10 @@ export class NewProjectPanel {
650650
this.dispose();
651651

652652
// required to support backslashes in macOS/Linux folder names
653-
const targetPath = process.platform !== "win32"
654-
? this._projectRoot.fsPath
655-
: this._projectRoot.fsPath.replaceAll("\\", "/");
653+
const targetPath =
654+
process.platform !== "win32"
655+
? this._projectRoot.fsPath
656+
: this._projectRoot.fsPath.replaceAll("\\", "/");
656657

657658
const result = await window.withProgress(
658659
{
@@ -662,34 +663,38 @@ export class NewProjectPanel {
662663
},
663664
async progress => {
664665
// download and install selected example
665-
const result = await setupExample(
666-
example,
667-
targetPath
668-
);
669-
666+
const result = await setupExample(example, targetPath);
667+
670668
if (result) {
671-
this._logger.debug(`Successfully downloaded ${example.name} example.`);
672-
669+
this._logger.debug(
670+
`Successfully downloaded ${example.name} example.`
671+
);
672+
673673
progress.report({
674674
increment: 100,
675675
message: `Successfully downloaded ${example.name} example.`,
676676
});
677-
677+
678678
return true;
679679
}
680-
681-
this._logger.error(`Failed to download ${example.name} example.`);
682-
680+
681+
this._logger.error(
682+
`Failed to download ${example.name} example.`
683+
);
684+
683685
progress.report({
684686
increment: 100,
685687
});
686-
688+
687689
return false;
688690
}
689691
);
690692

691693
if (!result) {
692-
await window.showErrorMessage("Failed to setup example.");
694+
void window.setStatusBarMessage(
695+
`Failed to setup example ${example.name}. Please check the output window for more details.`,
696+
5000
697+
);
693698

694699
return;
695700
}
@@ -769,7 +774,7 @@ export class NewProjectPanel {
769774
);
770775
}
771776
break;
772-
case 'updateSetting':
777+
case "updateSetting":
773778
{
774779
const key = message.key as string;
775780
const value = message.value as boolean;
@@ -1511,7 +1516,8 @@ export class NewProjectPanel {
15111516
window.activeColorTheme.kind === ColorThemeKind.HighContrast
15121517
? "dark"
15131518
: "light";
1514-
const riscvDefaultSvgUri = defaultTheme === "dark" ? riscvWhiteSvgUri : riscvBlackSvgUri;
1519+
const riscvDefaultSvgUri =
1520+
defaultTheme === "dark" ? riscvWhiteSvgUri : riscvBlackSvgUri;
15151521

15161522
this._versionBundlesLoader = new VersionBundlesLoader(this._extensionUri);
15171523

@@ -1706,7 +1712,9 @@ export class NewProjectPanel {
17061712
const riscvColorSvgUri = "${riscvColorSvgUri.toString()}";
17071713
</script>
17081714
</head>
1709-
<body class="scroll-smooth w-screen${defaultTheme === "dark" ? " dark" : ""}">
1715+
<body class="scroll-smooth w-screen${
1716+
defaultTheme === "dark" ? " dark" : ""
1717+
}">
17101718
<div id="above-nav" class="container max-w-6xl mx-auto flex justify-between items-center w-full sticky top-0 z-10 pl-5 h-5">
17111719
</div>
17121720
<div id="nav-overlay" class="overlay hidden md:hidden inset-y-0 right-0 w-auto z-50 overflow-y-auto ease-out bg-slate-400 dark:bg-slate-800 drop-shadow-lg">
@@ -2186,10 +2194,8 @@ export class NewProjectPanel {
21862194
<div class="flex items-stretch space-x-4">
21872195
<div class="flex items-center px-4 py-2 border border-gray-200 rounded dark:border-gray-700">
21882196
<input id="use-cmake-tools-cb" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 outline-none focus:ring-0 focus:ring-offset-5 dark:bg-gray-700 dark:border-gray-600" ${
2189-
defaultUseCmakeTools
2190-
? 'checked'
2191-
: ''
2192-
}>
2197+
defaultUseCmakeTools ? "checked" : ""
2198+
}>
21932199
<label for="use-cmake-tools-cb" class="w-full py-4 ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Enable CMake-Tools extension integration</label>
21942200
</div>
21952201
</div>

0 commit comments

Comments
 (0)