Skip to content
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

[WIP] Use absolute_path instead of fs::canonicalize #3324

Closed
wants to merge 4 commits into from

Conversation

topecongiro
Copy link
Contributor

Closes #1873.

@BusyJay @CasualX @povilasb @rivy If you have time, could you please try this PR locally?

git clone https://github.com/topecongiro/rustfmt
cd rustfmt
git checkout absolute-path
cargo build --release
./target/release/rustfmt path/to/file

let current_dir_manifest = current_dir.join("Cargo.toml");
let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?;
let workspace_root_path = absolute_path(PathBuf::from(&metadata.workspace_root))?;
let in_workspace_root = workspace_root_path == current_dir;

for package in metadata.packages {
Copy link
Contributor

Choose a reason for hiding this comment

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

based on the findings in https://github.com/rust-lang/rustfmt/pull/3309/files#diff-0f04fceb10cfdeda3716c7824a8dc2deR246, maybe you need to get the absolute_path of manifest_path:

absolute_path(PathBuf::from(&package.manifest_path)) == current_dir_manifest

Copy link
Contributor

Choose a reason for hiding this comment

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

@topecongiro can we merge this PR with #3309 ? this would fix also @rivy 's comment #3324 (comment)

Copy link

@rivy rivy Mar 31, 2019

Choose a reason for hiding this comment

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

I think this should be a bug against PathBuf.canonicalize(). Any conversion to UNC must use the absolute path. PathBuf is taking that responsibility and should do it itself.

Here, as a workaround, I think you should use both; canonicalize the absolute path...

let workspace_root_path = absolute_path(PathBuf::from(&metadata.workspace_root))?.canonicalize()?;

Copy link

@rivy rivy Mar 31, 2019

Choose a reason for hiding this comment

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

I expect a wrapper function (maybe just a passthru for non-windows OS) which executes this work-around would be a good way to proceed. And, I'd replace all uses of canonicalize() in the code base. A quick repo search shows only about about eight uses.

Not meaning to add more work, but any path comparisons should probably be reviewed for possibly needing canonicalizing of both sides. And I'm not sure where those might be scattered throughout the code base.

$0.02

Thanks for taking the time to review and repair this issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

review this in #3309 once this PR is merged.

@rivy
Copy link

rivy commented Feb 7, 2019

This fix corrects the error that I've been having... Thanks.

But the fix leaves the path that it uses ("C:\Users\Roy\OneDrive\Projects\rust\coreutils\src\factor....\mkmain.rs") in a form that might fail for longer paths (eg, over the MAX_PATH length [~260 characters]). In that instance, using an absolute path in the original extended form (\\?\...) would be the only way that I know of that allows successful use of the path.

@scampi
Copy link
Contributor

scampi commented May 13, 2019

@topecongiro is there anything blocking this ? Would you like some help to get this over the finishing line ?

@CasualX
Copy link

CasualX commented May 13, 2019

Oh I completely forgot about this. Just now I tried to follow the instructions to test this but it doesn't compile anymore...

@scampi
Copy link
Contributor

scampi commented May 14, 2019

@CasualX should be fine to test now, thanks!


// FIXME: This `MAX_PATH` may be valid only from Windows 10, version 1607.
// https://docs.microsoft.com/ja-jp/windows/desktop/FileIO/naming-a-file#paths
const MAX_PATH: usize = 32767;
Copy link

Choose a reason for hiding this comment

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

I don't think this is correct.

From my reading of the documentation noted above, it looks like a MAX_PATH of 32000+ can only be depended on for Windows 10, for certain later versions, and only if the system/user has opted-in, by changing a registry entry. This, to me, means that it can never be depended on and should likely not be used.

MAX_PATH should be ~260 characters for normal paths (absolute or relative). For longer paths (up to 32000+ characters), the path would need to be in "extended" format which means absolute form prefixed with "\\?\".

Copy link
Contributor

@scampi scampi May 27, 2019

Choose a reason for hiding this comment

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

It seems like you cannot use \\?\ with relative path according to https://docs.microsoft.com/en-gb/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Because you cannot use the \\?\ prefix with a relative path, relative paths are always limited to a total of MAX_PATH characters.

Copy link
Contributor

Choose a reason for hiding this comment

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

I tried to prefix the path with \\?\ and I get an error:

The specified path is invalid. (os error 161)

Copy link

Choose a reason for hiding this comment

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

Must be in absolute path form.

@CasualX
Copy link

CasualX commented May 15, 2019

I'm on Windows and the build is still failing (appveyor has the error), the fix seems trivial but I've no idea how I can tweak this on my end.

@topecongiro
Copy link
Contributor Author

Currently I do not have a working Windows environment, so I am not able to fix this for a while, sorry.

@scampi
Copy link
Contributor

scampi commented May 26, 2019

@topecongiro I've got a windows environment up and running. I will try to test your PR.

@cheblin
Copy link

cheblin commented Jun 2, 2019

got the same < The specified path is invalid. (os error 161) > error on windows,
at this position in my code

#[path = "../generated/DeviceB.rs"]
pub mod host;

error: couldn't read \?\UNC\Helper\r\H_TEST\InRUST\DeviceB\src\examples..\generated\DeviceB.rs: The specified path is invalid. (os error 161)

windows could not recognize .. in path

@scampi
Copy link
Contributor

scampi commented Jun 2, 2019

@cheblin Can you try the branch from #3590 ?
In there there is a test https://github.com/rust-lang/rustfmt/pull/3590/files#diff-fb7b6d792af4a292faf7cf65b02e0f42 where the .. appears in the path attribute. Does it pass successfully for you ?

error: couldn't read ?\UNC\Helper\r\H_TEST\InRUST\DeviceB\src\examples..\generated\DeviceB.rs: The specified path is invalid. (os error 161)

Looks like there is a backslash missing after examples somehow.

@topecongiro
Copy link
Contributor Author

Closing in favor of #3590.

@topecongiro topecongiro deleted the absolute-path branch June 25, 2019 14:48
@scampi
Copy link
Contributor

scampi commented Jun 25, 2019

@topecongiro If you want I could create a branch within the rustfmt repo with for these changes, so that anyone can work on it more easily ?

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

Successfully merging this pull request may close these issues.

Fail to format nested mod with relative path on windows
5 participants