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

Ktlint 1.3.* converts crlf to lf on Windows #2747

Closed
mxkmn opened this issue Jul 20, 2024 · 21 comments · Fixed by #2752
Closed

Ktlint 1.3.* converts crlf to lf on Windows #2747

mxkmn opened this issue Jul 20, 2024 · 21 comments · Fixed by #2752

Comments

@mxkmn
Copy link

mxkmn commented Jul 20, 2024

Expected Behavior

Ktlint should not affect the line break settings unless the break type is specified in .editorconfig

Observed Behavior

Ktlint sets default line breaks in Unix, not in Windows, without asking. This cannot be disabled. The Difference Editor in Idea is filled with a bunch of files that contain no changes other than line breaks. The different line breaks are not sent as commits to the repository, because git stores lf data by default as it is.

The only solution is to add *.kt text eol=lf to .gitattributes and clone the repository again, but I'm not happy with that.

Steps to Reproduce

Just create a new .kt file without special .editorconfig rules on Windows (so the file will have crlf endings) and run ktlint.

Your Environment

  • Version of ktlint used: 1.3.1/1.3.0 (kotlinter 4.4.1/4.4.0)
  • Relevant parts of the .editorconfig settings: nothing special
  • Name and version (or code for custom task) of integration used (Gradle plugin, Maven plugin, command line, custom Gradle task): formatKotlin
  • Version of Gradle used (if applicable): 8.9
  • Operating System and version: last Win 11
paul-dingemans added a commit that referenced this issue Jul 23, 2024
When running on Windows, and `end_of_line` property not set in `.editorconfig` the line separators should not be changed from CRLF to LF whenever the file does not contain any lint violation that can be autocorrected.

Closes #2747
@paul-dingemans
Copy link
Collaborator

paul-dingemans commented Jul 23, 2024

I think that I have found the problem. Can you please help to verify whether the solution is working as I do not have a Windows computer?

The problem seems to be restricted to files in which not lint violations is found that can be autocorrected. In such files the line endings were indeed changed from CRLF to LF. In files in which a lint violation is found, and which could also be autocorrected, the line endings were not changed.

Please run Ktlint CLI latest snapshot build or ktlint-cli-1.4.0-20240723.140247-11-all.jar on your project to check that line endings are no longer changed.

*edited: update direct link to jar to refer to fat jar

@mxkmn
Copy link
Author

mxkmn commented Jul 23, 2024

As I understand from the description of this pull request, ktlint will still change the ending to lf in case of finding problems in the file. If this is indeed the case, this will cause confusion in file endings, they will not be standardised under default settings in projects developed on Windows machines. What are your thoughts on this?

I'm ready to test this version of the formatter if you explain whether crlf would change to cr in case the file requires formatting, but the .editorconfig doesn't specify the corresponding rule.

@paul-dingemans
Copy link
Collaborator

My expectation is that the problem only occurred in files where no Ktlint violations were autocorrected. In that case the end of line separator was not determined whilst still updating the end of line separator with the default value.

For files in which a violation was found, the behavior was not changed in Ktlint 1.3. So in this case the end of line separator was, and still is, correctly determined.

@mxkmn
Copy link
Author

mxkmn commented Jul 24, 2024

Good to know.

I can't figure out how I can run ktlint-cli-1.4.0-20240723.140247-11.jar, since it is compiled without -include-runtime. Could you please help me with this? I usually use kotlinter.

@paul-dingemans
Copy link
Collaborator

I can't figure out how I can run ktlint-cli-1.4.0-20240723.140247-11.jar, since it is compiled without -include-runtime. Could you please help me with this? I usually use kotlinter.

Sorry, I should have pointed you to the fat jar and to the run instructions for Windows.

@mxkmn
Copy link
Author

mxkmn commented Jul 25, 2024

Okay… Now there are a few problems:

  • Without specifying end_of_line in .editorconfig, files are still formatted in lf if ktlint decides to modify them;
  • When end_of_line is specified in .editorconfig, files are not formatted if they contain another endings, but there are no other problems.

@paul-dingemans
Copy link
Collaborator

  • Without specifying end_of_line in .editorconfig, files are still formatted in lf if ktlint decides to modify them;

This behavior was changed in #1831 (ktlint version 0.49.0). I missed the impact of the change by setting the default value to lf when the value was not set in the .editorconfig. At this moment, I cannot revert this behavior to the old situation as too many new versions have been released since then. Especially as you are the first one who identified this as an issue.

@mxkmn
Copy link
Author

mxkmn commented Aug 2, 2024

Although I've already added a workaround for these problems using .gitattributes, I still think it's a bug and worth fixing.

I understand that this behavior was introduced quite a while ago, but I don't think anyone is going to be frustrated by the fact that their files are no longer randomly switching from crlf to cr. The second issue you didn't mention is also an obvious bug.

@gavvvr
Copy link

gavvvr commented Aug 5, 2024

Faced the same issue while upgrading ktlint from 1.2.1 to 1.3.1. I do format all the code, but see no changes, only different line-endings.
@paul-dingemans I can confirm that 1.4.0-SNAPSHOT solves the problem.
So, waiting for 1.4.0 (or 1.3.2) to upgrade to the latest ktlint 😎


But as @mxkmn has noted, the line endings of auto-fixed files get indeed transformed from CRLF to LF even without explicit end_of_line specified in .editorconfig

I cannot revert this behavior to the old situation as too many new versions have been released since then.

I don't think anyone is going to be frustrated by the fact that their files are no longer randomly switching from crlf to cr

I am not aware of any potential harm of changing line endings of Kotlin source code, so I tend to agree that most probably nobody will be frustrated if ktlint will stop converting from CRLF to LF on auto-formatting for Windows users.

It's also interesting, that if you generate a project on Windows either with gradle init of simply with Intellij's "New project..." menu, the line ending of generated sample code will be LF anyway. But as soon as you create a new file in Intellij with Alt+Insert, it will be CRLF, so Intellij it also a bit inconsistent while generating a new project.

@paul-dingemans
Copy link
Collaborator

Although I've already added a workaround for these problems using .gitattributes, I still think it's a bug and worth fixing.

I understand that this behavior was introduced quite a while ago, but I don't think anyone is going to be frustrated by the fact that their files are no longer randomly switching from crlf to cr.

It will be a problem for projects that have started using ktlint with ktlint 0.49 or later. They might not have set the property explicitly, and be depending on the lf default which is set by ktlint when no explicit value is set. Reverting the behavior to version 0.49 would result in a breaking change for them. I prioritize users on the more recent versions of ktlint above users who skip (multiple) versions of ktlint. So this will not be fixed.

The second issue you didn't mention is also an obvious bug.

This is a direct result of the change I made to fix the original problem. An incorrect line ending is not seen as a format violation itself. Before checking for violation, all code is normalized to lf endings. Once formatting is done, line endings are re-applied according to settings.

  • Since 0.49 the line ending property always has a value which is used in the formatted code. With the fix made for this issue, the line endings are only re-applied to files in which a violation was found and autocorrected. Files without violations are indeed not updated anymore.
  • Before 0.49 the \r\n line ending was used if the property was not set and at least one \r character was found in the original code.

@hantsy
Copy link

hantsy commented Nov 18, 2024

We used Kotlinter-gradle in our project, and I want to know how to disable it completely.

In my project, we have set different rules in Git to satisfy the end-of-line requirements for all team members. https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings

We use different rules in different os. You know not everyone uses Windows or Macos in the team. But these Git settings will unite the format in the repository(remote), and in the local system, we use different end-of-lines.

@paul-dingemans
Copy link
Collaborator

We used Kotlinter-gradle in our project, and I want to know how to disable it completely.

Sorry, this is not possible. For internal processing all line endings are normalized before linting/formatting starts. When formatting is done, all line endings in the file will be based on the .editorconfig property end_of_line (or on its default when not set).

@hantsy
Copy link

hantsy commented Nov 19, 2024

Currently, I follow the Github guide, https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings and set input on Windows.

When I sync my pr to develop branch by git merge develop, there are no changes to commit, and I run the formatKolin task, it always formats all files Then I run git status, and it reports a lot of changes from the format task, when I do git commit and try to push, there are no changes.

@hantsy
Copy link

hantsy commented Nov 19, 2024

I hope there is an option to disable the processing of the line endings.

@paul-dingemans
Copy link
Collaborator

As said, this is not possible. At least not in reasonable limits as I can see right now. But proof me wrong, and submit a PR ;-)

@hantsy
Copy link

hantsy commented Nov 20, 2024

As said, this is not possible. At least not in reasonable limits as I can see right now. But proof me wrong, and submit a PR ;-)

When I sync my pr to the develop branch by git merge develop, there should be no changes to commit. But when I run the formatKolin task, it always formats all files. And I run git status, and it reports many changes from the format task. Then I do a git commit and try to push, there are no changes.

I want to remove the useless format line endings and keep it as it is. As I said before, to unite the line-ending settings of the team, we apply different strategies in Git config on the developer's OS. I worked well before this linter changes.

@paul-dingemans
Copy link
Collaborator

I want to remove the useless format line endings and keep it as it is. As I said before, to unite the line-ending settings of the team, we apply different strategies in Git config on the developer's OS. I worked well before this linter changes.

See my earlier comment: #2747 (comment)

@hantsy
Copy link

hantsy commented Nov 27, 2024

In other words, we want to use git to control the line endings and unite codes from all team members in the remote repository, we allow developers to use different line endings on different OS, git command will convert the line endings to the developer's OS compatible when reading from and writing to the remote repository.

Is it possible to disable the Klint line ending properties like others?

@paul-dingemans
Copy link
Collaborator

paul-dingemans commented Nov 27, 2024

No, line endings are not transformed by a rule. Your best way forward is to configure git. Maybe https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings?platform=windows helps.

@hantsy
Copy link

hantsy commented Nov 28, 2024

@paul-dingemans Yes, we followed this guide and configured git. Git will use local line endings, which are converted automatically between the local OS system(Windows and Linux users will use the OS special line endings) and the remote repository when fetching and committing codes. It works well.

Now kotliner/klint broke the rule.

@paul-dingemans
Copy link
Collaborator

https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/

Git’s primary solution to all this is to specify that LF is the best way to store line endings for text files in a Git repository’s object database. It doesn’t force this on you but most developers using Git and GitHub have adopted this as a convention and even our own help recommends setting up your config to do this.

The git configuration on the local machine of the developer should convert the git line-endings to OS specific line endings.

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 a pull request may close this issue.

4 participants