Skip to content
This repository has been archived by the owner on May 21, 2019. It is now read-only.

Windows support #1033

Merged
Merged

Conversation

ForNeVeR
Copy link
Contributor

@ForNeVeR ForNeVeR commented May 20, 2017

In this branch, I've included the exact changes I've done to execute black-screen on my Windows machine.

There're many unwanted changes in this PR;

  • eventually I'll squash the changes together and provide a clean PR without all the debug / logging / leftover stuff.

Issues remaining

  • ⚠ At some places, I've replaced Linux commands / options with their Windows counterparts; I will remove that and fix properly, but I'd like community help on that part. (It's not always obvious how do I change the architecture to provide platform-specific options.)
  • ⚠ I've disabled some compiler checks to make it compile; need to enable checks back and fix issues properly.
  • I've added some excessive logging; it should be removed.
  • There're troubles with node-pty typings; waiting for my pull request Add "types" to package.json microsoft/node-pty#83 to be merged and published. We could write our own typings if necessary (e.g. maintainer won't answer for a while).
  • Replace "start": "bash housekeeping/start.sh", with something more portable; we have no bash on Windows.
  • Conduct final testing before passing to the review

Most of the code come from quick hacks and fixes, so, please, help me to fix it properly and follow the project architecture.

Impact

This will close issue #800; we should urge Windows users to open new issues for every missing/misbehaving feature after that (e.g. PowerShell support, proper alias support on Windows etc. etc.)

package.json Outdated
@@ -83,7 +82,7 @@
"lint": "tslint `find src -name '*.ts*'` `find test -name '*.ts*'`",
"cleanup": "rm -rf compiled/src",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use portable rimraf for that command.

package.json Outdated
@@ -83,7 +82,7 @@
"lint": "tslint `find src -name '*.ts*'` `find test -name '*.ts*'`",
"cleanup": "rm -rf compiled/src",
"copy-html": "mkdir -p compiled/src/views && cp src/views/index.html compiled/src/views",
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite in portable way (because Windows have no mkdir and cp).

package.json Outdated
@@ -83,7 +82,7 @@
"lint": "tslint `find src -name '*.ts*'` `find test -name '*.ts*'`",
"cleanup": "rm -rf compiled/src",
"copy-html": "mkdir -p compiled/src/views && cp src/views/index.html compiled/src/views",
"compile": "npm run cleanup && npm run tsc && npm run copy-html",
"compile": "npm run tsc",
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to put these commands back after fix.

src/PTY.ts Outdated
import {loginShell} from "./utils/Shell";
import {debug} from "./utils/Common";

let smth = true ? null : pty.createTerminal(undefined, undefined, undefined);
type ITerminal = typeof smth;
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to do that hack because:
a) node-pty doesn't export its ITerminal type
b) microsoft/TypeScript#6606 isn't (yet?) implemented, so we cannot directly do type ITerminal = typeof(pty.createTerminal(undefined, undefined, undefined))

Both could be solved by either exporting the proper types from node-pty library or writing our own type definitions (it's not that complex).


// TODO: write proper signatures.
// TODO: use generators.
// TODO: terminate. https://github.com/atom/atom/blob/v1.0.15/src/task.coffee#L151
constructor(words: EscapedShellWord[], env: ProcessEnvironment, dimensions: Dimensions, dataHandler: (d: string) => void, exitHandler: (c: number) => void) {
const shellArguments = [...loginShell.noConfigSwitches, "-i", "-c", words.join(" ")];
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠ Warning: Unix-specific options were replaced by Windows-specific; need to find a portable way to express this option set.

  • (It has been fixed)

src/PTY.ts Outdated
dataHandler(data);
});
(this.terminal as any).on("exit", (code: number) => {
console.log('PTY: exit');
exitHandler(code);
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, ITerminal doesn't declare its on method. So I had to do these ugly as any casts.

src/PTY.ts Outdated
@@ -65,9 +81,11 @@ export function executeCommand(
...execOptions,
env: _.extend({PWD: directory}, process.env),
cwd: directory,
shell: "/bin/bash",
shell: "cmd",
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠ Warning: honestly I'm not sure what's this option impact; probably need to use some portable path definition from loginShell.

src/PTY.ts Outdated
const sourceCommands = (await loginShell.existingConfigFiles()).map(fileName => `source ${fileName} &> /dev/null`);

return await linedOutputOf(loginShell.executableName, ["-c", `'${[...sourceCommands, command].join("; ")}'`], process.env.HOME);
return await linedOutputOf(loginShell.executableName, ["/c", `"${[...sourceCommands, command].join(" && ")}"`], process.env.HOME);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠ Warning: Unix-specific options were replaced by Windows-specific; need to find a portable way to express this option set.

//lines.map(parseAlias).forEach(parsed => aliasesFromConfig[parsed.name] = parsed.value);
} catch (error) {
console.error(error);
}
Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠ Warning: As far as I know, Windows' cmd shell doesn't have a concept of alias. That's why I had to comment these out. We'll need to add an option haveAliases to loginShell or something like that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows PowerShell has aliasing feature which you can know more
by opening a PowerShell, then run

Get-Help about_Aliases

Copy link
Contributor Author

@ForNeVeR ForNeVeR May 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know about that, although I've decided to add only cmd support for now. I love PowerShell, but alternate shell support on Windows is another issue, and I'd like to limit scope of this issue to just cmd.exe.

@@ -34,7 +34,7 @@ export const preprocessEnv = (lines: string[]) => {

export const processEnvironment: Dictionary<string> = {};
export async function loadEnvironment(): Promise<void> {
const lines = preprocessEnv(await executeCommandWithShellConfig("env"));
const lines = preprocessEnv(await executeCommandWithShellConfig("set"));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠ Warning: Unix-specific command was replaced by a Windows-specific; need to find a portable way to express this command.

};

const shell = () => {
if (!process.env.SHELL) {
process.env.SHELL = 'C:\\Windows\\System32\\cmd.exe';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug leftover; just drop this.

Although we'll probably better add Windows detection and fallback to cmd.exe instead of /bin/bash on Windows below.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$SHELL typically isn't set on Windows, they have a similar environment variable COMSPEC but it defaults to the 32-bit version of cmd.exe, as does "cmd.exe" on the path. I've found defaulting to %windir%\Sysnative\cmd.exe on 64-bit machine and %windir%\System32\cmd.exe on 32-bit machines is the best way to go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good suggestion. I think I'll implement it, thanks.

tsconfig.json Outdated
"noImplicitThis": true,
"inlineSourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are disabled checks I was talking about in the PR description; ⚠ we need to put them all back.

@ForNeVeR ForNeVeR mentioned this pull request May 22, 2017
@ForNeVeR ForNeVeR changed the title [WIP] [HELP WANTED] Windows support [WIP] Windows support May 24, 2017
@ForNeVeR ForNeVeR force-pushed the feature/800-windows-support branch from b41b254 to 423a7bd Compare May 25, 2017 16:10
@ForNeVeR ForNeVeR changed the title [WIP] Windows support Windows support May 25, 2017
@ForNeVeR
Copy link
Contributor Author

Squashed and cleaned the PR. Please review.

@ForNeVeR ForNeVeR force-pushed the feature/800-windows-support branch 3 times, most recently from 81c5089 to d9fe19b Compare May 25, 2017 16:52
@ForNeVeR
Copy link
Contributor Author

Well, the tests are failing; obviously I've broken something. If anybody wants to help me to fix that issue — you're welcome, guys!

@Odonno
Copy link

Odonno commented May 25, 2017

I can see the current master branch is failing. I suppose you need to wait until a fix is done and then merge the new commits.

@ForNeVeR ForNeVeR force-pushed the feature/800-windows-support branch from d9fe19b to c06298e Compare May 27, 2017 10:59
@ForNeVeR
Copy link
Contributor Author

Alright. Rebased my branch on top of current master, and everything is okay now. Ready for review.

@vlad-shatskyi
Copy link
Contributor

@ForNeVeR great job, thanks! I'm not able to test if it works, so I'll just merge it. Please mention me next time, so that I see your messages sooner.

@vlad-shatskyi vlad-shatskyi merged commit d0daa7a into railsware:master May 28, 2017
@ForNeVeR
Copy link
Contributor Author

Thank you! I can confirm that it still works in master.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants