Skip to content

Commit de661ef

Browse files
Merge #937
937: Support Windows-style manifest paths. r=Emilgardis a=Alexhuszagh Also adds support for absolute manifest paths. Closes #935. Co-authored-by: Alex Huszagh <ahuszagh@gmail.com>
2 parents c8bb213 + ddf77c6 commit de661ef

File tree

2 files changed

+87
-32
lines changed

2 files changed

+87
-32
lines changed

.changes/937.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "fixed",
3+
"description": "support Windows-style and absolute manifest paths",
4+
"issues": [935]
5+
}

src/cli.rs

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use std::{env, path::PathBuf};
1+
use std::env;
2+
use std::path::{Path, PathBuf};
23

34
use crate::cargo::Subcommand;
45
use crate::errors::Result;
6+
use crate::file::PathExt;
57
use crate::rustc::TargetList;
68
use crate::shell::{self, MessageInfo};
79
use crate::Target;
@@ -104,36 +106,73 @@ fn is_value_arg(arg: &str, field: &str) -> Option<ArgKind> {
104106
fn parse_next_arg<T>(
105107
arg: String,
106108
out: &mut Vec<String>,
107-
parse: impl Fn(&str) -> T,
109+
parse: impl Fn(&str) -> Result<T>,
110+
store_cb: impl Fn(String) -> Result<String>,
108111
iter: &mut impl Iterator<Item = String>,
109-
) -> Option<T> {
112+
) -> Result<Option<T>> {
110113
out.push(arg);
111114
match iter.next() {
112115
Some(next) => {
113-
let result = parse(&next);
114-
out.push(next);
115-
Some(result)
116+
let result = parse(&next)?;
117+
out.push(store_cb(next)?);
118+
Ok(Some(result))
116119
}
117-
None => None,
120+
None => Ok(None),
118121
}
119122
}
120123

121-
fn parse_equal_arg<T>(arg: String, out: &mut Vec<String>, parse: impl Fn(&str) -> T) -> T {
122-
let result = parse(arg.split_once('=').expect("argument should contain `=`").1);
123-
out.push(arg);
124+
fn parse_equal_arg<T>(
125+
arg: String,
126+
out: &mut Vec<String>,
127+
parse: impl Fn(&str) -> Result<T>,
128+
store_cb: impl Fn(String) -> Result<String>,
129+
) -> Result<T> {
130+
let (first, second) = arg.split_once('=').expect("argument should contain `=`");
131+
let result = parse(second)?;
132+
out.push(format!("{first}={}", store_cb(second.to_owned())?));
124133

125-
result
134+
Ok(result)
126135
}
127136

128-
fn parse_manifest_path(path: &str) -> Option<PathBuf> {
137+
fn parse_manifest_path(path: &str) -> Result<Option<PathBuf>> {
129138
let p = PathBuf::from(path);
130-
env::current_dir().ok().map(|cwd| cwd.join(p))
139+
Ok(absolute_path(p).ok())
131140
}
132141

133142
fn parse_target_dir(path: &str) -> Result<PathBuf> {
134143
absolute_path(PathBuf::from(path))
135144
}
136145

146+
fn identity(arg: String) -> Result<String> {
147+
Ok(arg)
148+
}
149+
150+
fn str_to_owned(arg: &str) -> Result<String> {
151+
Ok(arg.to_owned())
152+
}
153+
154+
#[allow(clippy::needless_return)]
155+
fn store_manifest_path(path: String) -> Result<String> {
156+
let p = Path::new(&path);
157+
if p.is_absolute() {
158+
#[cfg(target_os = "windows")]
159+
{
160+
return p.as_wslpath();
161+
}
162+
#[cfg(not(target_os = "windows"))]
163+
{
164+
use crate::file::ToUtf8;
165+
return p.to_utf8().map(ToOwned::to_owned);
166+
}
167+
} else {
168+
p.as_posix()
169+
}
170+
}
171+
172+
fn store_target_dir(_: String) -> Result<String> {
173+
Ok("/target".to_owned())
174+
}
175+
137176
pub fn parse(target_list: &TargetList) -> Result<Args> {
138177
let mut channel = None;
139178
let mut target = None;
@@ -164,57 +203,68 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
164203
} else if let Some(kind) = is_value_arg(&arg, "--color") {
165204
color = match kind {
166205
ArgKind::Next => {
167-
match parse_next_arg(arg, &mut all, ToOwned::to_owned, &mut args) {
206+
match parse_next_arg(arg, &mut all, str_to_owned, identity, &mut args)? {
168207
Some(c) => Some(c),
169208
None => shell::invalid_color(None),
170209
}
171210
}
172-
ArgKind::Equal => Some(parse_equal_arg(arg, &mut all, ToOwned::to_owned)),
211+
ArgKind::Equal => Some(parse_equal_arg(arg, &mut all, str_to_owned, identity)?),
173212
};
174213
} else if let Some(kind) = is_value_arg(&arg, "--manifest-path") {
175214
manifest_path = match kind {
176-
ArgKind::Next => {
177-
parse_next_arg(arg, &mut all, parse_manifest_path, &mut args).flatten()
215+
ArgKind::Next => parse_next_arg(
216+
arg,
217+
&mut all,
218+
parse_manifest_path,
219+
store_manifest_path,
220+
&mut args,
221+
)?
222+
.flatten(),
223+
ArgKind::Equal => {
224+
parse_equal_arg(arg, &mut all, parse_manifest_path, store_manifest_path)?
178225
}
179-
ArgKind::Equal => parse_equal_arg(arg, &mut all, parse_manifest_path),
180226
};
181227
} else if let ("+", ch) = arg.split_at(1) {
182228
channel = Some(ch.to_owned());
183229
} else if let Some(kind) = is_value_arg(&arg, "--target") {
230+
let parse_target = |t: &str| Ok(Target::from(t, target_list));
184231
target = match kind {
185232
ArgKind::Next => {
186-
parse_next_arg(arg, &mut all, |t| Target::from(t, target_list), &mut args)
233+
parse_next_arg(arg, &mut all, parse_target, identity, &mut args)?
187234
}
188-
ArgKind::Equal => Some(parse_equal_arg(arg, &mut all, |t| {
189-
Target::from(t, target_list)
190-
})),
235+
ArgKind::Equal => Some(parse_equal_arg(arg, &mut all, parse_target, identity)?),
191236
};
192237
} else if let Some(kind) = is_value_arg(&arg, "--features") {
193238
match kind {
194239
ArgKind::Next => {
195-
let next = parse_next_arg(arg, &mut all, ToOwned::to_owned, &mut args);
240+
let next =
241+
parse_next_arg(arg, &mut all, str_to_owned, identity, &mut args)?;
196242
if let Some(feature) = next {
197243
features.push(feature);
198244
}
199245
}
200246
ArgKind::Equal => {
201-
features.push(parse_equal_arg(arg, &mut all, ToOwned::to_owned));
247+
features.push(parse_equal_arg(arg, &mut all, str_to_owned, identity)?);
202248
}
203249
}
204250
} else if let Some(kind) = is_value_arg(&arg, "--target-dir") {
205251
match kind {
206252
ArgKind::Next => {
207-
all.push(arg);
208-
if let Some(td) = args.next() {
209-
target_dir = Some(parse_target_dir(&td)?);
210-
all.push("/target".to_owned());
211-
}
253+
target_dir = parse_next_arg(
254+
arg,
255+
&mut all,
256+
parse_target_dir,
257+
store_target_dir,
258+
&mut args,
259+
)?;
212260
}
213261
ArgKind::Equal => {
214-
target_dir = Some(parse_target_dir(
215-
arg.split_once('=').expect("argument should contain `=`").1,
262+
target_dir = Some(parse_equal_arg(
263+
arg,
264+
&mut all,
265+
parse_target_dir,
266+
store_target_dir,
216267
)?);
217-
all.push("--target-dir=/target".into());
218268
}
219269
}
220270
} else {

0 commit comments

Comments
 (0)