mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.53k stars 32.19k forks source link

[Migration] v4 to v5 codemod converts all .js files to CRLF line endings on Windows, ignoring existing line endings #29822

Open fwextensions opened 2 years ago

fwextensions commented 2 years ago

Duplicates

Latest version

Current behavior 😯

The codemod rewrites every JS file in the specified directory using CRLF line endings, even files that aren't otherwise modified by the codemod.

Expected behavior 🤔

Files that need to be modified to migrate to v5 should be written out with the existing line endings, regardless of which OS the codemod is being run on. Other files should be left untouched.

Steps to reproduce 🕹

Steps:

  1. On Windows 10, check out a repo with LF line endings.
  2. Run npx @mui/codemod v5.0.0/preset-safe .

Result: every file will now have CRLF line endings.

Context 🔦

The repo I'm working with has all files checked in with LF line endings. The autocrlf git setting is set to input on my machine, so the files are checked out with unchanged line endings.

I looked at the jscodeshift options, but didn't see anything obvious that would be able to change this behavior.

Your environment 🌎

`npx @mui/envinfo` ``` System: OS: Windows 10 10.0.19043 CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz Memory: 1.43 GB / 15.81 GB Binaries: Node: 16.13.0 - C:\Program Files\nodejs\node.EXE npm: 8.1.4 - ~\AppData\Roaming\npm\npm.CMD Managers: RubyGems: 3.1.4 - C:\Ruby27-x64\bin\gem.CMD Utilities: Git: 2.34.0. Virtualization: Docker: 20.10.8 - C:\Program Files\Docker\Docker\resources\bin\docker.EXE SDKs: Windows SDK: AllowAllTrustedApps: Disabled Languages: Bash: 5.0.17 - C:\WINDOWS\system32\bash.EXE Ruby: 2.7.2 - C:\Ruby27-x64\bin\ruby.EXE Browsers: Chrome: 95.0.4638.69 Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.29), ChromiumDev (97.0.1069.0) Internet Explorer: 11.0.19041.1202 ```
siriwatknp commented 2 years ago

Please share example input and output from the Codemod.

fwextensions commented 2 years ago

The actual code that the codemod outputs is fine, and makes it easier to upgrade. The problem is that the line endings, even for files that are otherwise unchanged, all switch from LF to CRLF on Windows. I assume something in the codemod is detecting that it's on Windows and just deciding that everything should be output with CRLF, despite what the files' current line endings are.

SamoraMabuya commented 2 years ago

Hope this helps.

  1. Open command palette: Ctrl + Shift + P
  2. Type Settings.Json and enter
  3. Ctrl + f and search 'files.eol
  4. Set "files.eol": "what's ever here", to "files.eol": "\n",
  5. Save and reload vsc window

Note: This change may only apply to new files. For old ofiles, you'd have to go and use the manual method as shown below.

image

fwextensions commented 2 years ago

Fixing the line endings isn't a problem. I'm using Webstorm, which can easily do a bulk change.

The bug is that codemods shouldn't change line endings. They should just modify the code.

I haven't used codemods extensively before, so maybe this is just a limitation of the underlying library. But it sure seems like buggy behavior.

mnajdova commented 2 years ago

The line endings does not change when I run the tests (I am using Windows). As @siriwatknp mentioned, please share example input and output from the Codemod, otherwise there is not much that we can do.

fwextensions commented 2 years ago

The line endings does not change when I run the tests (I am using Windows).

If the files you're running the tests on already have CRLF line endings (the default on Windows), then you won't see any change. It's when you run the codemod on an LF file on Windows that you see the line endings get changed.

Here I created a 3 line JS file and set the line endings to LF. I copied it to another folder and ran the codemod on it there. Then I diff'd the modded file with the original one:

image

The code is completely unchanged, since there are no MUI references in the file. But every line now ends with CRLF instead of LF. In a larger project, dozens or hundreds of files will appear changed, even though it's just a line ending change.

siriwatknp commented 2 years ago

@fwextensions I don't think we add anything on top of jscodeshift. Can you test with react-codemod to see if it cause the same issue?

fwextensions commented 2 years ago

Sorry for the delay. I did finally try a react-codemod and noticed two things:

  1. Files that did not include any code to be modified by the codemod were left unchanged, so their line endings were untouched. In the MUI codemod, every file's line endings are changed.
  2. Their readme says there's a way to pass options to the recast printer, but it doesn't seem to work. I tried npx react-codemod pure-component . --force --jscodeshift="--printOptions='{\"lineTerminator\":\"\n\"}'" to force the line terminator to be \n, but it didn't work. That was echoed as --printOptions='{lineTerminator:\\n}' when the jscodeshift command was shown in the log, so it looks like something is messing up the parsing of the quotes.

So it looks like part of this issue is caused by an underlying problem with recast. The default lineTerminator option is require("os").EOL, when just defaulting to the first line ending of the first file scanned would give better results.

But it would also be nice if the MUI codemod would skip files that don't require any code modification, like the React codemods.

siriwatknp commented 2 years ago

I think this issue can be fixed by "skip files that don't require any code modification, like the React codemods." as @fwextensions suggested.

bdefore commented 2 years ago

A further note for the future fix: this occurred to me in reverse: running the codemon tool converted CRLF -> LF when run on my Manjaro Linux machine, causing a loud diff that interfered with review. This alerted me to another tool that had inadvertently changed my LF -> CRLF and something I wanted to address anyway, but ideally codemon's underlying tools don't make any line ending changes.

More reading on this and how to prevent it happening to you: https://www.aleksandrhovhannisyan.com/blog/crlf-vs-lf-normalizing-line-endings-in-git/

rolint commented 4 months ago

--jscodeshift="--printOptions..." didn't working for me either. In my case, there were 3 undesirable modifications, not just line endings, so my desired config is {"lineTerminator":"\n", "quote":"single", "trailingComma":true}

In the end, I called jscodeshift directly. I did the follow in Git Bash on Windows (mileage may vary)

npm install --global @mui/codemod
npm install --global jscodeshift
npx jscodeshift --transform=${APPDATA}/npm/node_modules/@mui/codemod/node/v5.0.0/jss-to-styled.js --extensions=js,ts,jsx,tsx,json --parser=tsx --ignore-pattern='**/node_modules/**' --ignore-pattern='**/*.css' --verbose=2 --printOptions='{"lineTerminator":"\n","quote":"single", "trailingComma":true}' /path/to/your/source/code