Skip to content

Commit a418423

Browse files
author
曹维杰
authored
Merge pull request #4 from jswh/dev
build two file for interactive and not interactive shell
2 parents ca35159 + 8080021 commit a418423

File tree

5 files changed

+195
-195
lines changed

5 files changed

+195
-195
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
[package]
22
name = "wslexe"
3-
version = "0.7.1"
3+
version = "0.8.0"
44
authors = ["Andreas Riffnaller-Schiefer <[email protected]>"]
55
license = "MIT"
66

7+
[[bin]]
8+
name = "wslexe_i"
9+
path = "./src/main_i.rs"
10+
11+
[[bin]]
12+
name = "wslexe"
13+
path = "./src/main.rs"
14+
715
[dependencies]
816
regex = "0.2"
917
lazy_static = "1.0"

src/main.rs

Lines changed: 2 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -1,200 +1,9 @@
1-
use std::borrow::Cow;
2-
use std::env;
3-
use std::io::{self, Write};
4-
use std::path::Path;
5-
use std::process::{Command, Stdio};
1+
mod processor;
62

73
#[macro_use]
84
extern crate lazy_static;
95
extern crate regex;
10-
use regex::bytes::Regex;
11-
12-
fn translate_path_to_unix(arg: String) -> String {
13-
if let Some(index) = arg.find(":\\") {
14-
if index != 1 {
15-
// Not a path
16-
return arg;
17-
}
18-
let mut path_chars = arg.chars();
19-
if let Some(drive) = path_chars.next() {
20-
let mut wsl_path = String::from("/mnt/");
21-
wsl_path.push_str(&drive.to_lowercase().collect::<String>());
22-
path_chars.next();
23-
wsl_path.push_str(&path_chars
24-
.map(|c| match c {
25-
'\\' => '/',
26-
_ => c,
27-
})
28-
.collect::<String>());
29-
return wsl_path;
30-
}
31-
}
32-
arg
33-
}
34-
35-
fn translate_path_to_win(line: &[u8]) -> Cow<[u8]> {
36-
lazy_static! {
37-
static ref WSLPATH_RE: Regex = Regex::new(r"(?m-u)/mnt/(?P<drive>[A-Za-z])(?P<path>/\S*)")
38-
.expect("Failed to compile WSLPATH regex");
39-
}
40-
WSLPATH_RE.replace_all(line, &b"${drive}:${path}"[..])
41-
}
42-
43-
fn shell_escape(arg: String) -> String {
44-
// ToDo: This really only handles arguments with spaces and newlines.
45-
// More complete shell escaping is required for the general case.
46-
if arg.contains(" ") {
47-
return vec![String::from("\""), arg, String::from("\"")].join("");
48-
}
49-
arg.replace("\n", "$'\n'");
50-
arg.replace(";", "$';'")
51-
}
52-
53-
fn use_interactive_shell() -> bool {
54-
// check for explicit environment variable setting
55-
if let Ok(interactive_flag) = env::var("WSL_USE_INTERACTIVE_SHELL") {
56-
if interactive_flag == "true" || interactive_flag == "1" {
57-
return false;
58-
}
59-
}
60-
// check for advanced usage indicated by BASH_ENV and WSLENV=BASH_ENV
61-
else if env::var("BASH_ENV").is_ok() {
62-
if let Ok(wslenv) = env::var("WSLENV") {
63-
if wslenv
64-
.split(':')
65-
.position(|r| r.eq_ignore_ascii_case("BASH_ENV"))
66-
.is_some()
67-
{
68-
return true;
69-
}
70-
}
71-
}
72-
false
73-
}
746

757
fn main() {
76-
let mut cmd_args = Vec::new();
77-
let mut wsl_args: Vec<String> = vec![];
78-
let wsl_cmd: String;
79-
let exe: String = env::args().next().unwrap();
80-
let path = Path::new(&exe);
81-
let file_stem = path.file_stem().unwrap().to_str().unwrap();
82-
wsl_args.push(String::from(file_stem));
83-
84-
// process wsl command arguments
85-
wsl_args.extend(
86-
env::args()
87-
.skip(1)
88-
.map(translate_path_to_unix)
89-
.map(shell_escape),
90-
);
91-
wsl_cmd = wsl_args.join(" ");
92-
93-
if use_interactive_shell() {
94-
cmd_args.push("bash".to_string());
95-
cmd_args.push("-ic".to_string());
96-
cmd_args.push(wsl_cmd.clone());
97-
} else {
98-
cmd_args.clone_from(&wsl_args);
99-
}
100-
101-
// setup stdin/stdout
102-
let stdin_mode = if wsl_cmd.ends_with("--version") {
103-
// For some reason, the git subprocess seems to hang, waiting for
104-
// input, when VS Code 1.17.2 tries to detect if `git --version` works
105-
// on Windows 10 1709 (specifically, in `findSpecificGit` in the
106-
// VS Code source file `extensions/git/src/git.ts`).
107-
// To workaround this, we only pass stdin to the git subprocess
108-
// for all other commands, but not for the initial `--version` check.
109-
// Stdin is needed for example when commiting, where the commit
110-
// message is passed on stdin.
111-
Stdio::null()
112-
} else {
113-
Stdio::inherit()
114-
};
115-
116-
// setup the wsl subprocess launched inside WSL
117-
let mut wsl_proc_setup = Command::new("wsl.exe");
118-
wsl_proc_setup.args(&cmd_args).stdin(stdin_mode);
119-
let status;
120-
121-
// add git commands that must use translate_path_to_win
122-
const TRANSLATED_CMDS: &[&str] = &["rev-parse", "remote"];
123-
124-
let have_args = wsl_args.len() > 1;
125-
let translate_output = if have_args {
126-
TRANSLATED_CMDS
127-
.iter()
128-
.position(|&r| r == wsl_args[1])
129-
.is_some()
130-
} else {
131-
false
132-
};
133-
134-
if translate_output {
135-
// run the subprocess and capture its output
136-
let wsl_proc = wsl_proc_setup
137-
.stdout(Stdio::piped())
138-
.spawn()
139-
.expect(&format!("Failed to execute command '{}'", &wsl_cmd));
140-
let output = wsl_proc
141-
.wait_with_output()
142-
.expect(&format!("Failed to wait for wsl call '{}'", &wsl_cmd));
143-
status = output.status;
144-
let output_bytes = output.stdout;
145-
let mut stdout = io::stdout();
146-
stdout
147-
.write_all(&translate_path_to_win(&output_bytes))
148-
.expect("Failed to write wsl output");
149-
stdout.flush().expect("Failed to flush output");
150-
} else {
151-
// run the subprocess without capturing its output
152-
// the output of the subprocess is passed through unchanged
153-
status = wsl_proc_setup
154-
.status()
155-
.expect(&format!("Failed to execute command '{}'", &wsl_cmd));
156-
}
157-
158-
// forward any exit code
159-
if let Some(exit_code) = status.code() {
160-
std::process::exit(exit_code);
161-
}
162-
}
163-
164-
#[test]
165-
fn win_to_unix_path_trans() {
166-
assert_eq!(
167-
translate_path_to_unix("d:\\test\\file.txt".to_string()),
168-
"/mnt/d/test/file.txt"
169-
);
170-
assert_eq!(
171-
translate_path_to_unix("C:\\Users\\test\\a space.txt".to_string()),
172-
"/mnt/c/Users/test/a space.txt"
173-
);
174-
}
175-
176-
#[test]
177-
fn unix_to_win_path_trans() {
178-
assert_eq!(
179-
&*translate_path_to_win(b"/mnt/d/some path/a file.md"),
180-
b"d:/some path/a file.md"
181-
);
182-
assert_eq!(
183-
&*translate_path_to_win(b"origin /mnt/c/path/ (fetch)"),
184-
b"origin c:/path/ (fetch)"
185-
);
186-
let multiline = b"mirror /mnt/c/other/ (fetch)\nmirror /mnt/c/other/ (push)\n";
187-
let multiline_result = b"mirror c:/other/ (fetch)\nmirror c:/other/ (push)\n";
188-
assert_eq!(
189-
&*translate_path_to_win(&multiline[..]),
190-
&multiline_result[..]
191-
);
192-
}
193-
194-
#[test]
195-
fn no_path_translation() {
196-
assert_eq!(
197-
&*translate_path_to_win(b"/mnt/other/file.sh"),
198-
b"/mnt/other/file.sh"
199-
);
8+
processor::execute(false)
2009
}

src/main_i.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
mod processor;
2+
3+
#[macro_use]
4+
extern crate lazy_static;
5+
extern crate regex;
6+
7+
fn main() {
8+
processor::execute(true)
9+
}

0 commit comments

Comments
 (0)