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

[codemod][FN] msw/2/upgrade-recipe #1350

Open
jiri-prokop-pb opened this issue Oct 8, 2024 · 1 comment
Open

[codemod][FN] msw/2/upgrade-recipe #1350

jiri-prokop-pb opened this issue Oct 8, 2024 · 1 comment
Labels
codemod-issue Any issues related to a codemod, FP or FN.

Comments

@jiri-prokop-pb
Copy link

Faulty codemod

msw/2/upgrade-recipe source

Sample code

https://github.com/jiri-prokop-pb/codemod-msw2-repro

There is test.spec.ts that use msw.

You can also find upgrade-msw-v2.sh script there that runs the codemo and shows the problems mentioned below.

Original

import { rest } from 'msw';

rest.get('/api', (req, res, ctx) => {
  params = req.url.searchParams;

  return res(
    ctx.json({
      data: [],
    }),
  );
});

Expected

import { http, HttpResponse } from 'msw';

http.get('/api', ({ request }) => {
  const url = new URL(request.url);

  params = url.searchParams;

  return HttpResponse.json({
    data: [],
  });
});

Actual

import { http } from 'msw';

http.get('/api', (req, res, ctx) => {
  params = req.url.searchParams;

  return res(
    ctx.json({
      data: [],
    }),
  );
});

Estimated impact

Numbers about your specific codemod run:

  • Total number of files/instances transformed: 106

  • Number of files/instances missed by the codemod (FN): 106

  • Number of files/instances mistakenly transformed (FP): 0

  • I fixed my issue with a workaround, but I'm reporting this for other community members.

Note: the workaround involved copying the codemod files directly to my project and not using codemod package at all. Instead I created a small wrapper that runs the codemod with ts-morph and globby directly:

wrapper script
import { globbyStream } from 'globby';
import { Project } from 'ts-morph';

import { readFile } from 'fs/promises';

import { handleSourceFile as handleSourceFile_07_callbackSignature } from './codemods/msw2/callback-signature.ts';
import { handleSourceFile as handleSourceFile_04_ctxFetch } from './codemods/msw2/ctx-fetch.ts';
import { handleSourceFile as handleSourceFile_01_imports } from './codemods/msw2/imports.ts';
import { handleSourceFile as handleSourceFile_08_lifecycleEventsSignature } from './codemods/msw2/lifecycle-events-signature.ts';
import { handleSourceFile as handleSourceFile_09_printHandler } from './codemods/msw2/print-handler.ts';
import { handleSourceFile as handleSourceFile_05_reqPassthrough } from './codemods/msw2/req-passthrough.ts';
import { handleSourceFile as handleSourceFile_03_requestChanges } from './codemods/msw2/request-changes.ts';
import { handleSourceFile as handleSourceFile_06_responseUsages } from './codemods/msw2/response-usages.ts';
import { handleSourceFile as handleSourceFile_02_typeArgs } from './codemods/msw2/type-args.ts';

const handleSourceFileFns = [
  handleSourceFile_01_imports,
  handleSourceFile_02_typeArgs,
  handleSourceFile_03_requestChanges,
  handleSourceFile_04_ctxFetch,
  handleSourceFile_05_reqPassthrough,
  handleSourceFile_06_responseUsages,
  handleSourceFile_07_callbackSignature,
  handleSourceFile_08_lifecycleEventsSignature,
  handleSourceFile_09_printHandler,
];

function transform(oldPath: string, oldData: string) {
  const project = new Project({
    skipFileDependencyResolution: true,
    compilerOptions: {
      allowJs: true,
    },
  });
  let beforeData = oldData;
  let afterData = oldData;

  for (const handleSourceFile of handleSourceFileFns) {
    try {
      const sourceFile = project.createSourceFile(oldPath, beforeData, {
        overwrite: true,
      });

      afterData = handleSourceFile(sourceFile);

      if (typeof afterData === 'string') {
        beforeData = afterData;
        sourceFile.saveSync();
      }
    } catch (err) {
      console.error(`Error transforming ${oldPath}: ${err.message}`);
    }
  }

  return afterData;
}

async function transformFiles() {
  for await (const path of globbyStream('{src,libs,apps}/**/*.{ts,tsx}', {
    gitignore: true,
  })) {
    console.log(`Transforming ${path.toString()}...`);
    const data = await readFile(path, 'utf-8');

    transform(path, data);
  }
}

void transformFiles();

Logs:

❯ cat .codemod/logs/2024-10-08T09:51:25.898Z-error.log
- CLI version: 0.14.1
- Node version: 20.16.0
- OS: Darwin 24.0.0 arm64

Error at codemod-msw2-repro/test.spec.ts:
Invalid transformer

(last two lines are repeated multiple times; probably once per sub-codemod)

Additional context

I'd like to report two problems actually:

  1. the codemods not working (but only in context of codemod repository)
  2. silent failures when --logs is not used; as you can see in the output of the provided script, if you don't use --logs you won't know that codemods didn't work, the process will have exit code 0 and there is no indication that something went wrong; when --logs is used then the process will fail and you can see the logs but they are still not very helpful

I wasn't able to figure out why point 1 is happening, it's very strange issue. What's making it even worse is that one of the codemods worked and changed the import so you can see it partially working but you have no idea why other changes weren't applied.

Regarding point 2, I believe better logging would be useful for cases like this. Most likely issues like this one won't be reported because people may not realized codemods are failing (and they only may have assumption that their code is too complicated to be handled by codemod or similar).

@jiri-prokop-pb jiri-prokop-pb added the codemod-issue Any issues related to a codemod, FP or FN. label Oct 8, 2024
@alexbit-codemod
Copy link
Contributor

Thanks so much for the detailed report. Will ask the team to lookin into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codemod-issue Any issues related to a codemod, FP or FN.
Projects
None yet
Development

No branches or pull requests

2 participants