Repository navigation
Allow reading args from @path - #7220
Conversation
53d0976 to
765b765
Compare
| let cmdline_args = env::args().skip(1).collect::<Vec<String>>(); | ||
| // if we saw a `@path` arg, read arguments from that file and merge them with the other | ||
| // arguments. | ||
| let args = rustc_driver::args::arg_expand_all(&early_dcx, &cmdline_args); |
There was a problem hiding this comment.
It's nice that we can leverage existing code from rustc_driver. Will this enforce that options are newline separated? For example, can we pass more than one argument on a single line? I think we should add some tests for this.
I see that your tests below dynamically create files with build_args_file. We can probably create some sample @path files and store them in the tests/ directory.
// Is this okay?
--config=wrap_comments=true --config=comment_width=80
How is whitespace handled?
// is this okay?
--config=wrap_comments=true
--config=comment_width=80
// there's trailing whitespace here ^^^^^^^^^^^
There was a problem hiding this comment.
Will this enforce that options are newline separated?
Yep, it just reads lines from the file and adds them as args, so
// Is this okay? --config=wrap_comments=true --config=comment_width=80
This will add a single arg like: "--config=wrap_comments=true --config=comment_width=80"
How is whitespace handled?
// is this okay? --config=wrap_comments=true --config=comment_width=80 // there's trailing whitespace here ^^^^^^^^^^^
It's left untouched, so that would result in two args:
[" --config=wrap_comments=true"., "--config=comment_width=80"]
Additionally it means it can't accepts any arguments with newlines in it e.g.
path/to/my/file_that_has_a_newline
in_its_name.rs
Would present as two arguments
There was a problem hiding this comment.
Cool. I wouldn't expect us to handle newlines in arguments so that seems fine to me.
b768351 to
2a70ce7
Compare
There was a problem hiding this comment.
Is this necessary?
There was a problem hiding this comment.
Is this necessary?
From experience, yes: otherwise git on Windows will try and convert these to plain \n (IIRC, that happens under default config, but I can't remember all the details, see the eol attribute if you want to go down a documentation rabbit hole
There was a problem hiding this comment.
Which files are we worried about having their line endings changed? I guess I'm just confused because we don't have this setup anywhere else.
There was a problem hiding this comment.
Which files are we worried about having their line endings changed?
args_full_carriage_return uses \r\n for its line endings, so I want to preserve those
I guess I'm just confused because we don't have this setup anywhere else.
We have an equivalent setup for some files in the top level .gitattributes, e.g. tests/source/issue-3494/crlf.rs -text
Which disables the text attribute, and since that attribute means:
This attribute marks the path as a text file, which enables end-of-line conversion
Disabling it means we don't do any eol conversion. I prefer setting the eol attribute as it's more explicit plus it means if e.g. your editor decides to write the file with just \n instead, then git will convert them back.
Poking around, I'm wondering if these tests are silently doing nothing:
$ git grep --files-with-matches $'\r' | git check-attr --stdin text | awk '$NF!="unset"'
tests/source/preserves_carriage_return_for_unix.rs: text: auto
tests/source/preserves_carriage_return_for_windows.rs: text: auto
tests/target/preserves_carriage_return_for_unix.rs: text: auto
tests/target/preserves_carriage_return_for_windows.rs: text: auto
tests/writemode/target/stdin.xml: text: auto
I.e. with text=auto I suspect git will convert all those \r\n to \n (in both source and target files) so the tests pass but we don't actually test anything
There was a problem hiding this comment.
Thanks for elaborating. Let's leave a comment somewhere to make it clear that this is for args_full_carriage_return
We can look into those other tests later.
There was a problem hiding this comment.
Added comment to the attributes: f169a87
There was a problem hiding this comment.
After more experimentation: -text is indeed the right choice:
Unsetting the text attribute on a path tells Git not to attempt any end-of-line conversion upon checkin or checkout.
I.e. tell git to just leave the file alone cb331d2
There was a problem hiding this comment.
We can look into those other tests later.
Turns out those tests just ignored line endings: #7233
There was a problem hiding this comment.
Do we need a whole args_file cargo project? Is it enough to just have the src dir with .rs files?
There was a problem hiding this comment.
Do we need a whole
args_filecargo project? Is it enough to just have thesrcdir with.rsfiles?
Nope, plain .rs should be fine: c70847a
|
@rustbot ready |
There was a problem hiding this comment.
@matthewhughes934 things are looking good. I also wanted to double double check if this supports multiple @path declarations? Maybe arg_expand_all already handles that?
If that's the case maybe we need to update the help text to make it clear that more than one @path can be passed.
Yep, the added test
Done a7b1781, I also added a full example in the README since I don't think the short help alone is fully clear (at least for me, since I wasn't familiar with args-file via the |
0a4169e to
a7b1781
Compare
|
@rustbot ready |
Sorry, a lot going on and I missed that.
Agreed. This is also something I didn't know what possible. Thank you for updating the README. |
That is, something like
$ printf "--config path/to/config.toml\n--check\n" > @args-file
$ rustfmt @args-file path/to/format.rs
# same as: rustfmt --config path/to/config.toml --check path/to/format.rs
The motivation for this is that `cargo fmt` collects the list of files
to be formatted and passes them to `rustfmt` as arguments. But this list
can get so long that it reaches OS limits, see rust-lang#6934.
The process for making this change was:
1. Go and look for inspiration from other tools
2. Find out the `rustdoc` supports this pattern[1] so just re-use its
approach[2]
Conveniently, that approach uses helpers from internal compiler crates
that are also available to us. Note, those helpers expect UTF-8
everywhere, which is what the current code also does, but this will be
an additional place to consider in the future if we want to move away
from that (see rustfmt/issues#7210).
Link: https://doc.rust-lang.org/rustdoc/command-line-arguments.html#path-load-command-line-flags-from-a-path [1]
Link: https://github.com/rust-lang/rust/blob/ab019e71a1a1f4688bcc4d5bf06d2c5a424a31a5/src/librustdoc/lib.rs#L827 [2]
a7b1781 to
c2856f3
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
@matthewhughes934 thanks for rebasing! was just about to say that I saw some |
|
Just noting, I commented on the original issue about this being a breaking change for anyone running |
|
ah, thanks @ytmimi I removed it from queue because I wasn't sure if there was subtree syncing going at the moment (so I should avoid merges to keep things simple) |
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file` This required updating some test files that used `newline_style=Windows` but never actually added those line endings in the corresponding `target`. In these cases carriage returns are added to the `target` files, but not the `source` ones so these tests also assert that we do indeed convert the line endings. The files `tests/{target,source}/configs/enum_discrim_align_threshold/40.rs` had CRLF line endings, but not corresponding `newline_style` option and the feature does not depend on line endings, so these were converted back to used Unix line endings
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file` This required updating some test files that used `newline_style=Windows` but never actually added those line endings in the corresponding `target`. In these cases carriage returns are added to the `target` files, but not the `source` ones so these tests also assert that we do indeed convert the line endings. The files `tests/{target,source}/configs/enum_discrim_align_threshold/40.rs` had CRLF line endings, but not corresponding `newline_style` option and the feature does not depend on line endings, so these were converted back to used Unix line endings
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file` This required updating some test files that used `newline_style=Windows` but never actually added those line endings in the corresponding `target`. In these cases carriage returns are added to the `target` files, but not the `source` ones so these tests also assert that we do indeed convert the line endings. The files `tests/{target,source}/configs/enum_discrim_align_threshold/40.rs` had CRLF line endings, but not corresponding `newline_style` option and the feature does not depend on line endings, so these were converted back to used Unix line endings
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file`
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file`
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file`
While working on rust-lang#7220 I got curious about how the integration tests handle line endings, specifically CRLF, and it turns out they don't. Given we have features that explicitly add/remove these line endings we should ensure the tests correctly cover this case to avoid regressions. We use `diff::lines` to generate diffs, and this calls `str::lines` under the hood, which strip any trailing `\r\n` or `\n`. So the only way we can tell that line-endings differ is by comparing the two contents, previously we performed this comparison in a way that would ignore if one file had `\r\n` endings and another had `\n` endings. This meant we never actually asserted that we saw the expected line endings. Note: we can only tell the files have differing line endings, not the lines where this occurs. It _could_ be a future improvement to make this more specific, but I think the approach is reasonable since there aren't any tests (or really any use case) for mixed line-endings in a single file. This reflects the behaviour of how we report such errors with e.g. `emitter::diff::DiffEmitter::emit_formatted_file`
That is, something like
The motivation for this is that
cargo fmtcollects the list of files to be formatted and passes them torustfmtas arguments. But this list can get so long that it reaches OS limits, see #6934.The process for making this change was:
rustdocsupports this pattern[1] so just re-use its approach[2]Conveniently, that approach uses helpers from internal compiler crates that are also available to us. Note, those helpers expect UTF-8 everywhere, which is what the current code also does, but this will be an additional place to consider in the future if we want to move away from that (see #7210).
Link: https://doc.rust-lang.org/rustdoc/command-line-arguments.html#path-load-command-line-flags-from-a-path [1]
Link: https://github.com/rust-lang/rust/blob/ab019e71a1a1f4688bcc4d5bf06d2c5a424a31a5/src/librustdoc/lib.rs#L827 [2]