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

Request: Support codemods published to npm #126

Open
DrewML opened this issue Jul 4, 2016 · 10 comments
Open

Request: Support codemods published to npm #126

DrewML opened this issue Jul 4, 2016 · 10 comments

Comments

@DrewML
Copy link
Contributor

DrewML commented Jul 4, 2016

Right now, there are 2 ways that a developer can run a codemod:

  1. Copy the codemod to their local machine, and pass the file path in with -t
  2. Provide a URI to a remote .js file (with the caveat that the script must be entirely self contained).

I'd like to propose a 3rd option: being able to npm install -g a codemod.

I can think of 2 different options for how this would work.

  1. A developer passes in the name of the globally-installed transform (either with -t or a new flag)
  2. jscodeshift can look for all globally-installed modules matching a specific prefix, and present the developer with a list of available transforms when one is not explicitly provided on the command line (this is how the yo CLI works for yeoman).

I think the major benefit here would be that it then becomes easier to author + distribute a codemod that is not entirely self-contained. Right now, if I wanted to publish a codemod that uses require for modules other than node built-ins, a consumer of my codemod needs to:

  1. Clone the repository
  2. Run npm install
  3. Navigate to their project
  4. Specify the exact path to my codemod's entry point with the cloned repository

Another benefit is discoverability: If the docs encourage users to publish to npm with specific tags, it will make searching for available transforms much less of a struggle.

This is work I'd definitely be willing to contribute, but wanted to elicit feedback before taking that work on.

@relekang
Copy link

relekang commented Jul 4, 2016

I think it would be great if it was easier to consume codemods. I like both options ✌️

Another option worth considering is custom cli. I did this with my repo of codemods. A benefit with this approach is that jscodeshift becomes a dependency of the codemod and thus the user knows that is it tested with the jscodeshift version they use it with. jscodeshift could have a helper which makes it a bit easier to generate the cli wrapper as well as keeping it in sync with jscodeshift cli options.

@DrewML
Copy link
Contributor Author

DrewML commented Jul 5, 2016

Another option worth considering is custom cli.

That would be cool. ava-codemods does a similar thing (wraps jscodeshift with a different CLI). While it's technically possible now, the API you can use isn't documented (unless you use child_process.exec), which makes it less-obvious to newer consumers. Probably worth a separate issue on this repo.

@fkling
Copy link
Contributor

fkling commented Jul 18, 2016

Sorry for the late response, I've been on vacation the last two weeks.

I like both ideas.

jscodeshift could have a helper which makes it a bit easier to generate the cli wrapper as well as keeping it in sync with jscodeshift cli options.

Definitely. A custom CLI has the advantage that additional preprocessing and configuration could happen before the codemod is run.

A benefit with this approach is that jscodeshift becomes a dependency of the codemod and thus the user knows that is it tested with the jscodeshift version they use it with.

Yep, that's what I like too. However, I would expect "non-selfcontained" codemods to list jscodeshift in peerDependencies and then we can least verify whether the versions are compatible.

But being able to run any globally installed codemod could be useful too. I think I like option 1 more. Maybe we could even offer the user to install that module if it doesn't exist (but is available on npm). We could also add a search subcommand to search for packages by name (and a specific tag) on npm.

When using a global jscodeshift installation, we could still delegate to the codemod's local jscodeshift version, if available.

@relekang
Copy link

Great :)
Should I create a separate issue for the cli part like @DrewML suggested? I can work on an implementation of that next week.

@fkling
Copy link
Contributor

fkling commented Jul 19, 2016

@relekang, yep that would be good. Thanks so much for your help :)

@brysgo
Copy link

brysgo commented Sep 12, 2016

This was my attempt at this a while back https://github.com/brysgo/jscodemigrate

@nickserv
Copy link
Contributor

nickserv commented Dec 8, 2016

I'm in favor of changing jscodeshift's CLI to look for npm packages of transforms automatically, especially since it could theoretically be done without any changes to the existing transforms. As long as they're published on npm, jscodeshift could locate them locally or in the package repository and just provide abstractions for running specific transforms. I think it would also be useful to have an option for running all of a package's transforms together, since many pck have related transforms that are meant to be run together. Perhaps something like jscodeshift --package NAME could run all transforms, with the -t flag modified to support locating the file by its name only (file instead of .../transforms/file.js).

That being said, I do think that the custom CLi feature could be very useful, though for what I would want I would find the package-based approach more convenient since I wouldn't have to modify as much existing code or publish new packages.

I would be interested in working on this, I just wanted to post my ideas first and see if anyone else has progress or similar ideas.

@sibelius
Copy link
Contributor

I think this should be similar of how react-native or gatsby templates works, something like this:

jscodeshift -t git:sibelius/ast-i18n

we should have a default path for the transformer

@danieldelcore
Copy link

danieldelcore commented May 27, 2021

Hey folks, I'm working on a project based on jscodeshift that acts as a community registry for codemods.

The way it works in a nutshell is:

  1. Create a codemod and push it to the repo
  2. We'll bundle and publish it to npm
  3. You can then run the codemod via our custom CLI npx @codeshift/cli --packages mypackage@14 path/to/src

If you want to publish your codemods you can get started by reading the Authoring and the Contribution guides.

The project is called CodeshiftCommunity, if you're interested 😄 It's early days, but would be keen to see what you all think about it/ if you find it useful 😄

@mon-jai
Copy link

mon-jai commented Sep 24, 2023

I made a customized codemod with the following code.

#!/usr/bin/env node
import { spawn } from "child_process"
import { readFile } from "fs/promises"

const PACKAGE_NAME = JSON.parse(await readFile(resolve("../package.json"))).name

function resolve(path) {
  return import.meta.resolve(path).replace(/^file:\/\/\//, "")
}

function rebrand(data) {
  return data.toString().replaceAll("jscodeshift", PACKAGE_NAME)
}

const jscodeshift = spawn(
  "node",
  [resolve("../node_modules/jscodeshift/bin/jscodeshift.js"), "-t", resolve("../codemod.ts"), ...process.argv.slice(2)],
  { env: { ...process.env, FORCE_COLOR: true } }
)

process.stdin.pipe(jscodeshift.stdin)

jscodeshift.stdout.on("data", data => process.stdout.write(rebrand(data)))
jscodeshift.stderr.on("data", data => process.stderr.write(rebrand(data)))
jscodeshift.on("exit", process.exit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants