-
Notifications
You must be signed in to change notification settings - Fork 888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix duplicated PATH entries #2849
Conversation
This is going to need a test case, I suggest a unit test of some sort close to the code, since the external contract is only changing in the manner of the duplication, and getting at this will be a little tricky. |
@rbtcollins Thanks for your comment. I will add some unit test. |
I am trying to add a unit test in
|
Unit tests belong in the crate, not in |
I had a wrong understanding. I will try to fix it. Thanks so much for your comment. |
d4f51e6
to
1d034f3
Compare
I'm using |
src/env_var.rs
Outdated
@@ -27,6 +27,8 @@ pub fn prepend_path(name: &str, value: Vec<PathBuf>, cmd: &mut Command) { | |||
if let Some(ref v) = old_value { | |||
parts = value; | |||
parts.extend(env::split_paths(v).collect::<Vec<_>>()); | |||
parts.sort(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorted PATH entries changes the semantic meaning of them: they are not a set, they are a sorted list, because 'bash' in a lower-index entry wins over 'bash' in a higher index entry.
src/env_var.rs
Outdated
|
||
prepend_path("PATH", path_entries, &mut cmd); | ||
|
||
let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one way you could avoid using this unstable method is to have the code you're testing depend on a trait defined in this module.
Implement it once for Command, and once for a trivial test struct (or use mockall), and then you can assert on what the set env is, rather than interacting with Command at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to reimplement the unit test but I'm stuck on this part. Which trait should I depend on?
a trait defined in this module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define one:
trait ProcessEnvs {
type Item;
type Iter: Iterator;
fn get_envs(&self) -> Self::Iter<Item=Self::Item>;
fn env<K, V>(&mut self, key: K, val: V) -> &mut Self
where
K: AsRef<OsStr>,
V: AsRef<OsStr>;
}
And then in your test you can just use a mock (e.g. with mockall) or a manually constructed test double. Change prepend/append _path to be generic over that trait, and provide an impl for Process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub fn append_path(
name: &str,
value: Vec<PathBuf>,
cmd: &mut dyn ProcessEnvs<Item = Command, Iter = vec::IntoIter<Command>>,
) {
I am stack on the trait
ProcessEnvs cannot be made into an object
error. I tried to separate the trait but it didn't work. This is the latest commit.
I think this will work but I have a couple of suggestions:
|
@rbtcollins Thanks so much for your suggestion. I will fix this. |
Thanks for the support. I am stuck for about a month and would like to close it. |
Sorry I didn't realise you're stuck. https://internals.rust-lang.org/t/generic-methods-over-object-safe-traits/6774 is the thing to read to understand this - and the reason you needed trait objects is because you didn't make prepend_path generic over an implementation of ProcessEnvs. I've got a fix - should be pushed up in a minute. However the patch fails tests now :) |
bc6547a
to
34b6878
Compare
I've also rebased all the incremental commits together - there isn't enough here for a large commit history. |
@chansuke @rbtcollins Hi, I don't have much experience with rustup's internals nor the time to dig too deeply into them right now, but I have been affected by PyO3/pyo3#1708 and would like to help push this across the finish line if possible. If the only thing blocking this PR from being merged is the failing test on Windows, I submitted a PR with a fix here (though I'm not sure whether it's considered okay to call |
@rbtcollins @dmartin |
89a1635
to
5893916
Compare
Wondering what the status of this is -- seems to be blocking PyO3/pyo3#1708 (among other things) |
I have requested the review to @rbtcollins |
I too have come here from PyO3/pyo3#1708 @rbtcollins / @chansuke what is needed to push this to completion? Is there someone else who can review? |
- Unit test append_path and prepend_path - Order is preserved, second and above instances of a given entry are dropped. Co-Authored-By: Robert Collins <robertc@robertcollins.net> Signed-off-by: Robert Collins <robertc@robertcollins.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow I had forgotten this. thank you. I'm sure we could code golf it more but the essentials are fine:
- it fixes the bug
- it has a test to prevent accidental recurrence
I'm quite confident the android failure is unrelated; will merge this. |
Fixes #2848