hypermod-community icon indicating copy to clipboard operation
hypermod-community copied to clipboard

Add ability to pass path to codeshift.config.js

Open EliteUser opened this issue 2 years ago • 5 comments

Hello again! Thanks for great tool btw 😃 I'm building a tool which is actually a wrapper around yours. It is a standalone package which contain all codemods and it just runs @codeshift/cli internally.

My package, after installation is located in node_modules and have following structure: image

The problem is that after I install my package and run it, @codeshift/cli is not able to find codeshift.config.js, because it is trying to find it in project root, but config is actually located in node_modules/@my-tool/codeshift.config.js.

I think I can solve this problem if I can pass --config option (or something like this) and specify a path to config (like node_modules/@my-tool/codeshift.config.js).

Maybe there is another solution, can you help me?

EliteUser avatar Feb 21 '23 10:02 EliteUser

Hey again!

That's an interesting one 🤔 Codeshift works by pulling codemods directly off NPM, so given that you have a package containing your codemods and a codeshift.config.js published to NPM, you should be able to avoid bundling and wrapping the CLI with your package.

I've written a few guides for this:

  • (External packages)[https://www.codeshiftcommunity.com/docs/external-packages]
  • See ("How it works" on our homepage)[https://www.codeshiftcommunity.com/]

So for example, let's say you want to create a new package containing codemods you would:

  1. Intialize a new project npx @codeshift/cli init foobar
  2. Or output a config to an existing project codeshift init --config-only --transform 10.0.0 packages/my-package
  3. Then you can build the package with your bundler yarn build etc
  4. Publish your package to npm
  5. Now run your codemod remotely with the CLI npx @codeshift/cli -p [email protected] path/to/src

If you wanted to wrap our CLI with your own to add additional features, that's ok too, but would still do the above and treat that as a separate concern.

LMK if that makes any sense, happy to help you via our Discord if you'd prefer as well 😄

BTW how did you go resolving this issue? Are you all good now? https://github.com/CodeshiftCommunity/CodeshiftCommunity/issues/146

danieldelcore avatar Feb 22 '23 04:02 danieldelcore

Hello, thanks for the answer!

I have read all your guides, they are very good and helpful, thx! Especially recipes for imports and react But looks like I got a unusual case of some sort. I have UI library, for which I need codemodes. So I want to write a cli tool which my consumers will use (our internal projects whiсh use my library). I want this tool to be as simple as it can be, so I see it as a standalone npm package which contain everything the project needs. They will just npm install my magic-tool and run magic-tool upgrade. Then they will choose version and voila 😄

I think they should not know anything about codemode packages (btw I don't want to flood our npm with separate packages for every codemode), or some configs (they will have to add them in their project).

But you led me to a good thought that I need to give the project the opportunity to run a specific codemode within one specific version, thx 😃.

About this one - I came up with solution with rollup and 2 plugins - rollup-plugin-multi-input and rollup-plugin-typescript2. First one is needed, because my index.ts is not the only one entry point (cause I "bundle" all my codemodes), and the second one fully resolves an issue with tsconfig.paths. The only one tool which successfully resolves path, idk why. Tried a lot of other tools and plugins, but it can do things like utils -> ../../utils.

A thought about issue title - IMO it is a good idea to have a config option, like e.g. rollup do. It will allow you to use your tool in more cases

EliteUser avatar Feb 22 '23 07:02 EliteUser

Interesting, that should be possible with the CLI as is, I wonder if there's something else going wrong here 🤔 Would you be able to provide a minimal reproduction for me to play with?

From your screenshot, I noticed that your dist folder contains a package.json, normally package.json sits outside of the dist file. Then the main entry-point would point to dist/codeshift.config.js.

That being said, I think a config arg might come in handy regardless. I'll have a look 👁️

danieldelcore avatar Feb 22 '23 22:02 danieldelcore

Hello! I created a reduced version of my repository - https://stackblitz.com/edit/node-uhcfpx?file=src%2Findex.ts Here you can find a build script, as I said - rollup with some plugins helped me to resolve an issue with paths. Maybe it will be helpful for someone. Here you can reproduce the problem I am talking about - try build a tool, then run node dist/bin/my-cli.js. You will get an error, that config was found but it can't find transform. Thats because it found config file in the project root, not in dist fiolder. When you do cd dist and then run script from here - it will work. But it is not convenient. As I mentioned, my case is specific. The dist folder - is my package that will be in node_modules/my-tool folder, when my consumer install it via npm. But tool will be called from project root, and there wont (and should't) be any codeshift.onfig. So there --config option may help.

EliteUser avatar Feb 27 '23 12:02 EliteUser

Hey @EliteUser, sorry for the wait. I've created a fork of your example here.

codeshift/cli will automatically try to find a config in the cwd, then provide users with a list of runnable codemods.

I.e. codeshift

In my repro, here's what I changed:

  • Moves codeshift.config.js into src/ dir.
  • Update rollup to bundle the codeshift.config.js into the dist/ file with the rest of your source
  • Now when you run codeshift tmp it will show a list of runnable codemods. This should work nicely for dev-loop purposes.
  • Once the package is published to npm it will pull the config from the package.json's main property.
  • And so it's runnable like so codeshift --packages [my-package-name-here]@3.0.0 path/to/src

When you publish to NPM, your users should be able to run your new CLI. Under the hood, your call to codeshift could look something like this:

exec(`codeshift --packages [my-package-name-here]@3.0.0 path/to/src`);

Alternatively, if you already know where the codemods are stored you could simply use the -t flag to run them directly:

exec(`codeshift --transform path/to/codemods/3.0.0 path/to/src`);

📖 CLI docs for reference

All that said I don't think it would be harmful to add an explicit config path, however, I'm not sure if it should just display a selectable list of codemods or just run a single mod. The API might be a bit odd 🤔

Cheers!

danieldelcore avatar Mar 02 '23 23:03 danieldelcore