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

Add --newline=[LF|CRLF|native|preserve] option to compile, to override the line separator characters used #1491

Closed
wants to merge 6 commits into from

Conversation

AndydeCleyre
Copy link
Contributor

@AndydeCleyre AndydeCleyre commented Sep 27, 2021

pip-compile gains an option with two three four valid choices: --newline=[LF|CRLF|native|preserve],
which can be used to override the guessed newline character used in the output file. The default is native preserve, which uses os.linesep tries to be consistent with an existing output file, or input file, or FALLBACK_VALUE (native, or LF? TBD) falls back to LF, in that order.

This aims to address #1448.

Note: poll for fallback value

Contributor checklist
  • Provided the tests for the changes.
  • Assure PR title is short, clear, and good to be included in the user-oriented changelog
Maintainer checklist
  • Assure one of these labels is present: backwards incompatible, feature, enhancement, deprecation, bug, dependency, docs or skip-changelog as they determine changelog listing.
  • Assign the PR to an existing or new milestone for the target version (following Semantic Versioning).

@AndydeCleyre

This comment has been minimized.

@AndydeCleyre

This comment has been minimized.

@AndydeCleyre

This comment has been minimized.

@AndydeCleyre AndydeCleyre changed the title Add --newline [LF|CRLF] option to compile, to override the line separator control characters Add --newline=[LF|CRLF|native] option to compile, to override the line separator control characters Sep 28, 2021
@Jackenmen
Copy link

IMO \n as that's the line endings that usually get checked into the repository by git due to autocrlf and some other settings. BUT a different potential problem here is that not using native might be considered a breaking change by some. I have no clue whether it would be considered as such by maintainers of this project and I personally wouldn't mind it but it's worth bringing up.

@AndydeCleyre

This comment was marked as outdated.

@AndydeCleyre AndydeCleyre marked this pull request as ready for review September 28, 2021 15:04
@webknjaz

This comment was marked as outdated.

@AndydeCleyre

This comment was marked as outdated.

@AndydeCleyre

This comment was marked as outdated.

@altendky

This comment was marked as outdated.

@AndydeCleyre
Copy link
Contributor Author

I do care about backwards compatibility, but I must note that the current (and "backward" behavior) on Windows is, I think, an inconsistent mix of line endings, depending on annotations and warnings and maybe hashes.

This is because we create some multi line "line" strings for warnings, for example, then join/print these.

@altendky

This comment was marked as outdated.

@atugushev
Copy link
Member

I do care about backwards compatibility, but I must note that the current (and "backward" behavior) on Windows is, I think, an inconsistent mix of line endings, depending on annotations and warnings and maybe hashes.

@AndydeCleyre this looks like a bug. We can fix that inconsistency before the --newline option.

@AndydeCleyre
Copy link
Contributor Author

What would the backwards compatible behavior be, for windows?

@atugushev
Copy link
Member

atugushev commented Sep 28, 2021

What would the backwards compatible behavior be, for windows?

I'd guess, If we fix the "inconsistent mix of line endings" then it would be os.linesep. What would you think?

@AndydeCleyre
Copy link
Contributor Author

I'd guess, If we fix the "inconsistent mix of line endings" then it would be os.linesep. What would you think?

I'd like someone using Windows to confirm. If that is indeed the case, then isn't this PR, in its current state, what is desired anyway?

@webknjaz

This comment was marked as outdated.

@AndydeCleyre

This comment was marked as outdated.

@AndydeCleyre AndydeCleyre changed the title Add --newline=[LF|CRLF|native] option to compile, to override the line separator control characters Add --newline=[LF|CRLF|native|preserve] option to compile, to override the line separator control characters Sep 28, 2021
@AndydeCleyre

This comment was marked as outdated.

@graingert

This comment was marked as outdated.

@AndydeCleyre

This comment was marked as outdated.

@AndydeCleyre
Copy link
Contributor Author

Duplicating my own comment from the relevant issue, for visibility and feedback here:


Maybe the move forward is to collpase #1491 into a single new flag, --preserve-newlines (or similar):

  • without it, always use LF
  • with it, and existing newlines can be detected, use those
  • with it, and no existing newlines are detected, use LF

What do you think?

@graingert
Copy link
Member

preserve-newlines should be the default. Having no example line separator and forcing pip-compile to guess is so rare (passed from stdin) that the choice barely matters

@AndydeCleyre
Copy link
Contributor Author

So more like an --LF flag is called for?

@Jackenmen
Copy link

preserve-newlines should be the default. Having no example line separator and forcing pip-compile to guess is so rare (passed from stdin) that the choice barely matters

Perhaps it barely matters which line ending is chosen but it does matter for it to be consistent between systems which is not currently the case either.

@AndydeCleyre
Copy link
Contributor Author

I just threw up draft #1584 based on this PR and one more commit that implements this change and all it entails:

 @click.option(
-    "--newline",
-    type=click.Choice(("LF", "CRLF", "native", "preserve"), case_sensitive=False),
-    default="preserve",
-    help="Override the newline control characters used",
+    "--force-unix-newlines",
+    is_flag=True,
+    default=False,
+    help="Always use LF newlines, rather than auto-detecting from existing files.",
 )

Is that close to what we need?

@AndydeCleyre
Copy link
Contributor Author

I'd like to direct anyone here to the latest poll back at the source issue, about which behavior should be the default, and what other options should be available, if any. Thanks for any feedback!

@AndydeCleyre
Copy link
Contributor Author

There aren't very many votes in the poll, but the current winner is still the implementation as it is here in this PR.

- Use it in writer to override the line sep used in output
- Set default to preserve, which checks the output file
- Falls back to native if that's not possible, which uses os.linesep
Check the src_files for an existing newline, and use that if found
And remove outdated parameter to existing --newline test
when --newline=preserve and an existing newline isn't detected
This is either done by specifying --newline=LF,
or *not* writing a newline to the input,
so that the default --newline=preserve falls back to LF
@ssbarnea
Copy link
Member

ssbarnea commented Jul 1, 2022

Whom from those with review/merge are supporting this feature? I am still -0.5 on it as it would add unrequired complexity to the code as users can control the newlines using git. If I would support something in this area it will enforcing use of LF newlines regardless platform, making it predictable.

@atugushev Are you? Asking because I do not want to see @AndydeCleyre spending more and more time on a task that never gets in.

As I am against, he will need two +1 reviews to get it in.

PS. Sorry, but I am only trying to protect the codebase.

@@ -264,7 +266,7 @@ def write(
else:
log.info(line)
self.dst_file.write(unstyle(line).encode())
self.dst_file.write(os.linesep.encode())
self.dst_file.write(self.linesep.encode())
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be neater to use a TextIOWrapper so the existing code can continue to use \n, which should sharply reduce the number of lines changed here

try:
    dst_file = io.TextIOWrapper(self.dst_file, encoding="utf8", newlines=self.linesep):
    for line in self._iter_lines(...):
        dst_file.write(line)
        dst_file.write("\n")
finally:
    dst_file.detatch()

Copy link
Member

@graingert graingert left a comment

Choose a reason for hiding this comment

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

I'm hugely in favor of this feature, and I think using a TextIOWrapper to translate the newlines will keep the changes small enough to justify it

@AndydeCleyre
Copy link
Contributor Author

@graingert

Thanks!

Closing this in favor of #1652

from +140 −17
to +132 −8

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.

None yet

7 participants