prettier/prettier-vscode

Running find & replace on files with formatOnSave enabled overwrites files with incorrect content

mogzol opened this issue · 3 comments

Summary

When running find and replace on files in a workspace which includes multiple packages, each with their own Prettier version, and with format on save enabled, files are sometimes overwritten with the contents of other files.

Github Repository to Reproduce Issue

https://github.com/mogzol/prettier-vscode-plugin-repro

Steps To Reproduce:

  1. Clone the above repo
  2. Run npm install on all packages: bash -c 'for d in ./*/ ; do (cd "$d" && npm i); done'
  3. In VSCode, search all files for "1.0.0" and replace with "2.0.0"
    • This should replace 3 occurrences across 3 package.json files
    • If there are more occurrences, make sure the "Use Exclude Settings and Ignore Files" option is enabled
  4. Check the package.json files, verify that ONLY that string was replaced in each file (check that package name still matches folder name)
    • If the issue occurs, one or more of the files will have been completely replaced with the contents of one of the other files
    • This may take a few attempts

Expected result

Files should not be overwritten with the contents of other files.

Actual result

Files are overwritten with the contents of other files.

Additional information

The same issue was reported nearly a year ago, here: #3040

That issue was closed as stale, however the issue is still happening on the latest version of the extension.

VS Code Version:

Version: 1.89.1
Commit: dc96b837cf6bb4af9cd736aa3af08cf8279f7685
Date: 2024-05-07T05:14:24.611Z
Electron: 28.2.8
ElectronBuildId: 27744544
Chromium: 120.0.6099.291
Node.js: 18.18.2
V8: 12.0.267.19-electron.0
OS: Darwin x64 23.5.0

Prettier Extension Version: v10.4.0

OS and version: macOS Sonoma 14.5

Prettier Log Output

These are the logs from a find & replace operation where all files ended up with the contents of pkg-c's package.json file:

Log Output
["INFO" - 5:21:49 PM] Extension Name: esbenp.prettier-vscode.
["INFO" - 5:21:49 PM] Extension Version: 10.4.0.
["DEBUG" - 5:21:49 PM] Enabling Prettier globally
{
  "languageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "mongo"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "json5"
    },
    {
      "language": "css"
    },
    {
      "language": "postcss"
    },
    {
      "language": "less"
    },
    {
      "language": "scss"
    },
    {
      "language": "handlebars"
    },
    {
      "language": "graphql"
    },
    {
      "language": "markdown"
    },
    {
      "language": "mdx"
    },
    {
      "language": "html"
    },
    {
      "language": "vue"
    },
    {
      "language": "yaml"
    },
    {
      "language": "ansible"
    },
    {
      "language": "home-assistant"
    },
    {
      "language": "jsonc",
      "scheme": "vscode-userdata"
    }
  ],
  "rangeLanguageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "graphql"
    }
  ]
}
["DEBUG" - 5:21:49 PM] Using bundled version of prettier.
["DEBUG" - 5:21:49 PM] Enabling Prettier for Workspace /Users/(trimmed)/prettier-plugin-repro-main
{
  "languageSelector": [
    {
      "pattern": "/Users/(trimmed)/prettier-plugin-repro-main/**/*.{js,_js,bones,cjs,es,es6,frag,gs,jake,javascript,jsb,jscad,jsfl,jslib,jsm,jspre,jss,mjs,njs,pac,sjs,ssjs,xsjs,xsjslib,wxs,js.flow,jsx,ts,cts,mts,tsx,importmap,json,4DForm,4DProject,avsc,geojson,gltf,har,ice,JSON-tmLanguage,mcmeta,tfstate,tfstate.backup,topojson,webapp,webmanifest,yy,yyp,jsonc,code-snippets,sublime-build,sublime-commands,sublime-completions,sublime-keymap,sublime-macro,sublime-menu,sublime-mousemap,sublime-project,sublime-settings,sublime-theme,sublime-workspace,sublime_metrics,sublime_session,json5,css,wxss,pcss,postcss,less,scss,handlebars,hbs,graphql,gql,graphqls,md,livemd,markdown,mdown,mdwn,mkd,mkdn,mkdown,ronn,scd,workbook,mdx,component.html,html,hta,htm,html.hl,inc,xht,xhtml,mjml,vue,yml,mir,reek,rviz,sublime-syntax,syntax,yaml,yaml-tmlanguage,yaml.sed,yml.mysql}",
      "scheme": "file"
    },
    {
      "language": "javascript"
    },
    {
      "language": "mongo"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "json5"
    },
    {
      "language": "css"
    },
    {
      "language": "postcss"
    },
    {
      "language": "less"
    },
    {
      "language": "scss"
    },
    {
      "language": "handlebars"
    },
    {
      "language": "graphql"
    },
    {
      "language": "markdown"
    },
    {
      "language": "mdx"
    },
    {
      "language": "html"
    },
    {
      "language": "vue"
    },
    {
      "language": "yaml"
    },
    {
      "language": "ansible"
    },
    {
      "language": "home-assistant"
    },
    {
      "language": "jsonc",
      "scheme": "vscode-userdata"
    }
  ],
  "rangeLanguageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "graphql"
    }
  ]
}
["INFO" - 5:21:58 PM] Formatting file:///Users/(trimmed)/prettier-plugin-repro-main/pkg-a/package.json
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-a/node_modules/prettier/index.cjs
["INFO" - 5:21:58 PM] Formatting file:///Users/(trimmed)/prettier-plugin-repro-main/pkg-c/package.json
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-c/node_modules/prettier/index.cjs
["INFO" - 5:21:58 PM] Formatting file:///Users/(trimmed)/prettier-plugin-repro-main/pkg-b/package.json
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-b/node_modules/prettier/index.cjs
["DEBUG" - 5:21:58 PM] Using prettier version 3.3.1
["DEBUG" - 5:21:58 PM] Using prettier version 3.3.1
["DEBUG" - 5:21:58 PM] Using prettier version 3.3.1
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-a/node_modules/prettier/index.cjs
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-c/node_modules/prettier/index.cjs
["DEBUG" - 5:21:58 PM] Local prettier module path: /Users/(trimmed)/prettier-plugin-repro-main/pkg-b/node_modules/prettier/index.cjs
["INFO" - 5:21:58 PM] PrettierInstance:
{
  "modulePath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-a/node_modules/prettier/index.cjs",
  "importResolver": {},
  "callMethodResolvers": {},
  "currentCallMethodId": 2,
  "version": "3.3.1"
}
["INFO" - 5:21:58 PM] PrettierInstance:
{
  "modulePath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-c/node_modules/prettier/index.cjs",
  "importResolver": {},
  "callMethodResolvers": {},
  "currentCallMethodId": 2,
  "version": "3.3.1"
}
["INFO" - 5:21:58 PM] PrettierInstance:
{
  "modulePath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-b/node_modules/prettier/index.cjs",
  "importResolver": {},
  "callMethodResolvers": {},
  "currentCallMethodId": 2,
  "version": "3.3.1"
}
["INFO" - 5:21:58 PM] Using ignore file (if present) at /Users/(trimmed)/prettier-plugin-repro-main/.prettierignore
["INFO" - 5:21:58 PM] Using ignore file (if present) at /Users/(trimmed)/prettier-plugin-repro-main/.prettierignore
["INFO" - 5:21:58 PM] Using ignore file (if present) at /Users/(trimmed)/prettier-plugin-repro-main/.prettierignore
["INFO" - 5:21:58 PM] File Info:
{
  "ignored": false,
  "inferredParser": "json-stringify"
}
["INFO" - 5:21:58 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 5:21:58 PM] Prettier Options:
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "singleAttributePerLine": false,
  "bracketSameLine": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 100,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "embeddedLanguageFormatting": "auto",
  "vueIndentScriptAndStyle": false,
  "filepath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-a/package.json",
  "parser": "json-stringify"
}
["INFO" - 5:21:58 PM] File Info:
{
  "ignored": false,
  "inferredParser": "json-stringify"
}
["INFO" - 5:21:58 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 5:21:58 PM] Prettier Options:
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "singleAttributePerLine": false,
  "bracketSameLine": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 100,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "embeddedLanguageFormatting": "auto",
  "vueIndentScriptAndStyle": false,
  "filepath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-c/package.json",
  "parser": "json-stringify"
}
["INFO" - 5:21:58 PM] File Info:
{
  "ignored": false,
  "inferredParser": "json-stringify"
}
["INFO" - 5:21:58 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 5:21:58 PM] Prettier Options:
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "singleAttributePerLine": false,
  "bracketSameLine": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 100,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "embeddedLanguageFormatting": "auto",
  "vueIndentScriptAndStyle": false,
  "filepath": "/Users/(trimmed)/prettier-plugin-repro-main/pkg-b/package.json",
  "parser": "json-stringify"
}
["INFO" - 5:21:58 PM] Formatting completed in 222ms.
["INFO" - 5:21:58 PM] Formatting completed in 218ms.
["INFO" - 5:21:58 PM] Formatting completed in 216ms.
["DEBUG" - 5:21:58 PM] Using bundled version of prettier.

Decided to look into this since the issue is incredibly annoying for me. Turns out it was a very simple issue, I have created a pull request with the fix: #3481

this issue almost ruined my life. It's insane it's still active. I hope this get merged soon.