Skip to content

Commit

Permalink
fix: disallow nested sketch on save as
Browse files Browse the repository at this point in the history
Do not wipe source sketch after save as if not a temp

Closes #1882

Signed-off-by: Akos Kitta <[email protected]>
  • Loading branch information
Akos Kitta committed Feb 13, 2023
1 parent fef3b6a commit bec6e92
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 18 deletions.
78 changes: 62 additions & 16 deletions arduino-ide-extension/src/browser/contributions/save-as-sketch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,17 @@ export class SaveAsSketch extends CloudSketchContribution {
if (cloudUri) {
destinationUri = await this.createCloudCopy({ cloudUri, sketch });
} else {
destinationUri = await this.createLocalCopy(sketch, execOnlyIfTemp);
const isTemp = await this.sketchesService.isTemp(sketch);
if (!isTemp) {
// If the current sketch is an ordinary non-temp sketch, do not delete it after the rename.
// https://github.com/arduino/arduino-ide/issues/1882#issuecomment-1427524645
wipeOriginal = false;
}
destinationUri = await this.createLocalCopy(
sketch,
isTemp,
execOnlyIfTemp
);
}
if (!destinationUri) {
return false;
Expand Down Expand Up @@ -119,9 +129,9 @@ export class SaveAsSketch extends CloudSketchContribution {

private async createLocalCopy(
sketch: Sketch,
isTemp?: boolean,
execOnlyIfTemp?: boolean
): Promise<string | undefined> {
const isTemp = await this.sketchesService.isTemp(sketch);
if (!isTemp && !!execOnlyIfTemp) {
return undefined;
}
Expand All @@ -147,7 +157,7 @@ export class SaveAsSketch extends CloudSketchContribution {
Sketch.toValidSketchFolderName(sketch.name, exists)
);
const defaultPath = await this.fileService.fsPath(defaultUri);
return await this.promptLocalSketchFolderDestination(defaultPath);
return await this.promptLocalSketchFolderDestination(sketch, defaultPath);
}

/**
Expand All @@ -156,6 +166,7 @@ export class SaveAsSketch extends CloudSketchContribution {
* or `undefined` if the operation was canceled.
*/
private async promptLocalSketchFolderDestination(
sketch: Sketch,
defaultPath: string
): Promise<string | undefined> {
let sketchFolderDestinationUri: string | undefined;
Expand All @@ -174,22 +185,51 @@ export class SaveAsSketch extends CloudSketchContribution {
return undefined;
}
const destinationUri = await this.fileSystemExt.getUri(filePath);
const sketchFolderName = new URI(destinationUri).path.base;
const errorMessage = Sketch.validateSketchFolderName(sketchFolderName);
if (errorMessage) {
// The new location of the sketch cannot be inside the location of current sketch.
// https://github.com/arduino/arduino-ide/issues/1882
let dialogContent: InvalidSketchFolderDialogContent | undefined;
if (new URI(sketch.uri).isEqualOrParent(new URI(destinationUri))) {
dialogContent = {
message: nls.localize(
'arduino/sketch/invalidSketchFolderLocationMessage',
"Invalid sketch folder location: '{0}'",
filePath
),
details: nls.localize(
'arduino/sketch/invalidSketchFolderLocationDetails',
'You cannot save a sketch into a folder inside itself. This would go on forever.'
),
question: nls.localize(
'arduino/sketch/editInvalidSketchFolderLocationQuestion',
'Do you want to try to save the sketch to a different location?'
),
};
}
if (!dialogContent) {
const sketchFolderName = new URI(destinationUri).path.base;
const errorMessage = Sketch.validateSketchFolderName(sketchFolderName);
if (errorMessage) {
dialogContent = {
message: nls.localize(
'arduino/sketch/invalidSketchFolderNameMessage',
"Invalid sketch folder name: '{0}'",
sketchFolderName
),
details: errorMessage,
question: nls.localize(
'arduino/sketch/editInvalidSketchFolderQuestion',
'Do you want to try to save the sketch with a different name?'
),
};
}
}
if (dialogContent) {
const message = `
${nls.localize(
'arduino/sketch/invalidSketchFolderNameTitle',
"Invalid sketch folder name: '{0}'",
sketchFolderName
)}
${dialogContent.message}
${errorMessage}
${dialogContent.details}
${nls.localize(
'arduino/sketch/editInvalidSketchFolderName',
'Do you want to try to save the sketch folder with a different name?'
)}`.trim();
${dialogContent.question}`.trim();
defaultPath = filePath;
const { response } = await remote.dialog.showMessageBox(
remote.getCurrentWindow(),
Expand Down Expand Up @@ -257,6 +297,12 @@ ${nls.localize(
}
}

interface InvalidSketchFolderDialogContent {
readonly message: string;
readonly details: string;
readonly question: string;
}

export namespace SaveAsSketch {
export namespace Commands {
export const SAVE_AS_SKETCH: Command = {
Expand Down
7 changes: 5 additions & 2 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,13 @@
"createdArchive": "Created archive '{0}'.",
"doneCompiling": "Done compiling.",
"doneUploading": "Done uploading.",
"editInvalidSketchFolderName": "Do you want to try to save the sketch folder with a different name?",
"editInvalidSketchFolderLocationQuestion": "Do you want to try to save the sketch to a different location?",
"editInvalidSketchFolderQuestion": "Do you want to try to save the sketch with a different name?",
"exportBinary": "Export Compiled Binary",
"invalidCloudSketchName": "The name must start with a letter or number, followed by letters, numbers, dashes, dots and underscores. Maximum length is 36 characters.",
"invalidSketchFolderNameTitle": "Invalid sketch folder name: '{0}'",
"invalidSketchFolderLocationDetails": "You cannot save a sketch into a folder inside itself. This would go on forever.",
"invalidSketchFolderLocationMessage": "Invalid sketch folder location: '{0}'",
"invalidSketchFolderNameMessage": "Invalid sketch folder name: '{0}'",
"invalidSketchName": "The name must start with a letter or number, followed by letters, numbers, dashes, dots and underscores. Maximum length is 63 characters.",
"moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
Expand Down

0 comments on commit bec6e92

Please sign in to comment.