Skip to content

Commit 74b988b

Browse files
committed
automatically convert files with #! and CRLF
It is a common mistake for Windows users to not notice the line endings of the file. The default on Windows is to use CRLF which causes files with a #! to fail to execute when run on the EV3. This automatically converts the file when downloading so that users don't have to worry about it.
1 parent 67aeb91 commit 74b988b

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes to the "ev3dev-browser" extension will be documented in this
77

88
### Fixed
99
- Fixed Windows path separator in "program" in `.vscode/launch.json` not converted to UNIX path.
10+
- Fixed running files with `#!` and Windows line endings (CRLF vs. LF).
1011

1112
## v1.2.0 - 2020-07-20
1213
### Changed

src/extension.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
toastStatusBarMessage,
1818
verifyFileHeader,
1919
getPlatform,
20+
normalizeLineEndings,
2021
} from './utils';
2122

2223
// fs.constants.S_IXUSR is undefined on win32!
@@ -438,6 +439,10 @@ async function download(folder: vscode.WorkspaceFolder, device: Device): Promise
438439
let mode: string;
439440
if (await verifyFileHeader(f.fsPath, Buffer.from('#!/'))) {
440441
mode = '755';
442+
// Bash will fail to execute a file when the shebang line
443+
// contains Windows line endings because it treats \r as
444+
// text rather than a line break.
445+
await normalizeLineEndings(f.fsPath);
441446
}
442447
else {
443448
const stat = fs.statSync(f.fsPath);

src/utils.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,40 @@ export function getSharedTempDir(sharedKey: string): Promise<string> {
3333
});
3434
}
3535

36+
/**
37+
* Checks a file for Windows line endings. If found, modifies the file to remove
38+
* the Windows line endings.
39+
* @param path The path to the file.
40+
* @returns true if the file was modified, otherwise false
41+
*/
42+
export function normalizeLineEndings(path: string): Promise<boolean> {
43+
return new Promise((resolve, reject) => {
44+
fs.readFile(path, { encoding: "utf8" }, (err, data) => {
45+
if (err) {
46+
reject(err);
47+
return;
48+
}
49+
50+
const replace = data.replace("\r\n", "\n");
51+
52+
if (replace === data) {
53+
// not changed
54+
resolve(false);
55+
return;
56+
}
57+
58+
fs.writeFile(path, replace, (err) => {
59+
if (err) {
60+
reject(err);
61+
return;
62+
}
63+
64+
resolve(true);
65+
});
66+
});
67+
});
68+
}
69+
3670
export function openAndRead(path: string, offset: number, length: number, position: number): Promise<Buffer> {
3771
return new Promise((resolve, reject) => {
3872
fs.open(path, 'r', (err, fd) => {

0 commit comments

Comments
 (0)