Skip to content

Commit dc48d7c

Browse files
author
Akos Kitta
committed
fix: copy when punctuation marks in sketch path
Changed the `source` and `cwd` args to avoid accidentally creating an invalid `glob` patterns when doing the brace expansion by `cpy`. Closes #2043 Signed-off-by: Akos Kitta <[email protected]>
1 parent 45aeb7f commit dc48d7c

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

Diff for: arduino-ide-extension/src/node/sketches-service-impl.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ export class SketchesServiceImpl
438438
* For example, on Windows, instead of getting an [8.3 filename](https://en.wikipedia.org/wiki/8.3_filename), callers will get a fully resolved path.
439439
* `C:\\Users\\KITTAA~1\\AppData\\Local\\Temp\\.arduinoIDE-unsaved2022615-21100-iahybb.yyvh\\sketch_jul15a` will be `C:\\Users\\kittaakos\\AppData\\Local\\Temp\\.arduinoIDE-unsaved2022615-21100-iahybb.yyvh\\sketch_jul15a`
440440
*/
441-
createTempFolder(): Promise<string> {
441+
private createTempFolder(): Promise<string> {
442442
return new Promise<string>((resolve, reject) => {
443443
temp.mkdir({ prefix: TempSketchPrefix }, (createError, dirPath) => {
444444
if (createError) {
@@ -520,13 +520,14 @@ export class SketchesServiceImpl
520520

521521
const cpyModule = await import('cpy');
522522
const cpy = cpyModule.default;
523-
await cpy(source, destination, {
523+
await cpy(sourceFolderBasename, destination, {
524524
rename: (basename) =>
525525
sourceFolderBasename !== destinationFolderBasename &&
526526
basename === `${sourceFolderBasename}.ino`
527527
? `${destinationFolderBasename}.ino`
528528
: basename,
529529
filter,
530+
cwd: path.dirname(source),
530531
});
531532
const copiedSketch = await this.doLoadSketch(destinationUri, false);
532533
return copiedSketch;

Diff for: arduino-ide-extension/src/test/node/sketches-service-impl.slow-test.ts

+61-5
Original file line numberDiff line numberDiff line change
@@ -226,16 +226,72 @@ describe('sketches-service-impl', () => {
226226
expect(mainFileContentOneAfterCopy).to.be.equal(contentOne);
227227
expect(mainFileContentTwoAfterCopy).to.be.equal(contentOne);
228228
});
229+
230+
[
231+
['(', ')', 'parentheses'],
232+
['[', ']', 'brackets'],
233+
['{', '}', 'braces'],
234+
['<', '>', 'chevrons'],
235+
].map(([open, close, name]) =>
236+
it(`should copy a sketch when the path contains ${name} in the sketch folder path: '${open},${close}'`, async function () {
237+
this.timeout(testTimeout);
238+
const sketchesService =
239+
container.get<SketchesServiceImpl>(SketchesService);
240+
const content = `// special content when ${name} are in the path`;
241+
const tempRoot = await sketchesService['createTempFolder']();
242+
toDispose.push(disposeFolder(tempRoot));
243+
const sketch = await sketchesService.createNewSketch(
244+
'punctuation_marks',
245+
content
246+
);
247+
toDispose.push(disposeSketch(sketch));
248+
249+
// the destination path contains punctuation marks
250+
const tempRootUri = FileUri.create(tempRoot);
251+
const testSegment = `path segment with ${open}${name}${close}`;
252+
const firstDestinationUri = tempRootUri
253+
.resolve(testSegment)
254+
.resolve('first')
255+
.resolve(sketch.name);
256+
257+
const firstSketchCopy = await sketchesService.copy(sketch, {
258+
destinationUri: firstDestinationUri.toString(),
259+
});
260+
expect(firstSketchCopy).to.be.not.undefined;
261+
expect(firstSketchCopy.mainFileUri).to.be.equal(
262+
firstDestinationUri.resolve(`${sketch.name}.ino`).toString()
263+
);
264+
const firstCopyContent = await mainFileContentOf(firstSketchCopy);
265+
expect(firstCopyContent).to.be.equal(content);
266+
267+
// the source path contains punctuation marks. yes, the target too, but it does not matter
268+
const secondDestinationUri = tempRootUri
269+
.resolve(testSegment)
270+
.resolve('second')
271+
.resolve(sketch.name);
272+
const secondSketchCopy = await sketchesService.copy(firstSketchCopy, {
273+
destinationUri: secondDestinationUri.toString(),
274+
});
275+
expect(secondSketchCopy).to.be.not.undefined;
276+
expect(secondSketchCopy.mainFileUri).to.be.equal(
277+
secondDestinationUri.resolve(`${sketch.name}.ino`).toString()
278+
);
279+
const secondCopyContent = await mainFileContentOf(secondSketchCopy);
280+
expect(secondCopyContent).to.be.equal(content);
281+
})
282+
);
229283
});
230284
});
231285

232286
function disposeSketch(...sketch: Sketch[]): Disposable {
287+
return disposeFolder(...sketch.map(({ uri }) => FileUri.fsPath(uri)));
288+
}
289+
290+
function disposeFolder(...paths: string[]): Disposable {
233291
return new DisposableCollection(
234-
...sketch
235-
.map(({ uri }) => FileUri.fsPath(uri))
236-
.map((path) =>
237-
Disposable.create(() => rimrafSync(path, { maxBusyTries: 5 }))
238-
)
292+
...paths.map((path) =>
293+
Disposable.create(() => rimrafSync(path, { maxBusyTries: 5 }))
294+
)
239295
);
240296
}
241297

0 commit comments

Comments
 (0)