{"id":13447020,"url":"https://github.com/decaffeinate/bulk-decaffeinate","last_synced_at":"2025-09-07T02:05:02.855Z","repository":{"id":52418319,"uuid":"65167287","full_name":"decaffeinate/bulk-decaffeinate","owner":"decaffeinate","description":"Run decaffeinate and related operations on a whole codebase, or just part of one.","archived":false,"fork":false,"pushed_at":"2022-08-11T19:54:41.000Z","size":233,"stargazers_count":76,"open_issues_count":21,"forks_count":13,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-16T18:07:01.905Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/decaffeinate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-08T02:46:07.000Z","updated_at":"2025-01-21T09:48:29.000Z","dependencies_parsed_at":"2022-08-13T01:51:01.823Z","dependency_job_id":null,"html_url":"https://github.com/decaffeinate/bulk-decaffeinate","commit_stats":null,"previous_names":["alangpierce/bulk-decaffeinate"],"tags_count":80,"template":false,"template_full_name":null,"purl":"pkg:github/decaffeinate/bulk-decaffeinate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decaffeinate%2Fbulk-decaffeinate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decaffeinate%2Fbulk-decaffeinate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decaffeinate%2Fbulk-decaffeinate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decaffeinate%2Fbulk-decaffeinate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/decaffeinate","download_url":"https://codeload.github.com/decaffeinate/bulk-decaffeinate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decaffeinate%2Fbulk-decaffeinate/sbom","scorecard":{"id":331289,"data":{"date":"2025-08-11","repo":{"name":"github.com/decaffeinate/bulk-decaffeinate","commit":"c7fc82e5562b50a238fa5e9113b271b352074325"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T03:42:19.624Z","repository_id":52418319,"created_at":"2025-08-18T03:42:19.624Z","updated_at":"2025-08-18T03:42:19.624Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273986629,"owners_count":25202708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T05:01:06.081Z","updated_at":"2025-09-07T02:05:02.797Z","avatar_url":"https://github.com/decaffeinate.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# bulk-decaffeinate\n\n[![Build Status](https://travis-ci.org/decaffeinate/bulk-decaffeinate.svg?branch=master)](https://travis-ci.org/decaffeinate/bulk-decaffeinate)\n[![npm version](https://badge.fury.io/js/bulk-decaffeinate.svg)](https://www.npmjs.com/package/bulk-decaffeinate)\n[![MIT License](https://img.shields.io/npm/l/express.svg?maxAge=2592000)](LICENSE)\n\nA tool, backed by [decaffeinate](http://decaffeinate-project.org/), to help you\nconvert some or all of a CoffeeScript codebase to JavaScript.\n\nThe tool can check a codebase for decaffeinate-readiness, and once the code (or\na part of it) is ready, bulk-decaffeinate can actually run the conversion and\nsome follow-up cleanups. Here's an example of checking the Hubot repo:\n```\n\u003e npm install -g bulk-decaffeinate decaffeinate eslint\n...\n\u003e git clone https://github.com/philc/vimium.git\n...\n\u003e cd vimium\n\u003e bulk-decaffeinate check\nDoing a dry run of decaffeinate on 50 files...\n50/50\nAll checks succeeded! decaffeinate can convert all 50 files.\nRun \"bulk-decaffeinate convert\" to convert the files to JavaScript.\n\u003e bulk-decaffeinate convert\nVerifying that decaffeinate can successfully convert these files...\n50/50\nBacking up files to .original.coffee...\n50/50\nRenaming files from .coffee to .js...\n50/50\nGenerating the first commit: \"decaffeinate: Rename bg_utils.coffee and 49 other files from .coffee to .js\"...\nMoving files back...\n50/50\nRunning decaffeinate on all files...\n50/50\nDeleting old files...\n50/50\nSetting proper extension for all files...\n50/50\nGenerating the second commit: decaffeinate: Convert bg_utils.coffee and 49 other files to JS...\nRunning eslint --fix on all files...\n50/50\n[Skips eslint for all files because there is no config.]\nGenerating the third commit: decaffeinate: Run post-processing cleanups on bg_utils.coffee and 49 other files...\nSuccessfully ran decaffeinate on 50 files.\nYou should now fix lint issues in any affected files.\nAll CoffeeScript files were backed up as .original.coffee files that you can use for comparison.\nYou can run \"bulk-decaffeinate clean\" to remove those files.\nTo allow git to properly track file history, you should NOT squash the generated commits together.\n```\n\n## Assumptions\n\nWhile the underlying [decaffeinate](https://github.com/decaffeinate/decaffeinate)\ntool tries to be general-purpose, bulk-decaffeinate intentionally makes some\nassumptions about your use case:\n\n* Your build tooling can already handle JavaScript. Replacing a .coffee file\n  with a .js file will \"just work\" as long as the files are equivalent.\n* Adding some extra .original.coffee files as temporary backups won't cause\n  trouble.\n* You are using git for source control and all .coffee files being converted are\n  already tracked in the git repo.\n* You are using eslint for JS linting and you already have a .eslintrc file\n  specifying your preferred styles.\n\nFeel free to file an issue or submit a PR if these assumptions don't match your\ncurrent project. Most steps shouldn't be hard to disable using a config setting.\n\n## What it does\n\nbulk-decaffeinate supports a number of commands:\n* `check` does a dry run of decaffeinate on the specified files and reports how\n  decaffeinate-ready the set of files is.\n* `view-errors` should be run after `check` reports failures. It opens the\n  failed files in the [online decaffeinate repl](http://decaffeinate-project.org/repl/),\n  with one browser tab per failed file. Each browser tab loads the online repl\n  page with your source code encoded in the hash fragment of the URL. Because it\n  is in the hash fragment and not a regular query param, your code is never sent\n  to the server.\n* `convert` actually converts the files from CofeeScript to JavaScript,\n  generating a commit for each intermediate step.\n* `modernize-js` runs only the JS-to-JS transformations on the specified\n  JavaScript files. Unlike `convert`, this command does not create a git commit.\n* `clean` deletes all files with \".original\" in the name in the current\n  directory or any of its subdirectories.\n* `land` packages multiple commits into a merge commit based on an remote branch\n  (`origin/master` by default). Splitting the decaffeinate work into separate\n  commits allows git to properly track file history, but it can create added\n  difficulty after code review is finished, and `land` helps with that. The\n  `land` command does not actually push any commits; it just creates a merge\n  commit that is ready to push after a sanity check.\n  \n  If the `phabricatorAware` option is set, the `land` command does extra work to\n  make sure that every commit has a \"Differential Revision\" line and that the\n  final merge commit has the commit description.\n\nHere's what `convert` does in more detail:\n  1. It does a dry run of decaffeinate on all files to make sure there won't be\n     any failures.\n  2. It backs up all .coffee files to .original.coffee files, which makes it\n     easily to manually do a before-and-after comparison later.\n  3. It generates a commit renaming the files from .coffee to .js (but not\n     changing the contents). Putting this step in its own commit allows git to\n     track the file history across renames (so, if possible, you should land the\n     changes as a merge commit rather than squashing the commits together).\n  4. It runs decaffeinate on all files and gets rid of the .coffee files, then\n     generates a commit.\n  5. If the `jscodeshiftScripts` config value is specified, it runs\n     [jscodeshift](https://github.com/facebook/jscodeshift) with those scripts\n     in the order specified.\n  6. If the `mochaEnvFilePattern` config value is specified, it prepends\n     `/* eslint-env mocha */` to the top of every test file.\n  7. If the `fixImportsConfig` config value is specified, it runs a transform\n     that does whole-codebase analysis to fix any import problems that might\n     have been introduced by decaffeinate.\n  8. It runs `eslint --fix` on all files, which applies some style fixes\n     according to your lint rules. For any remaining lint failures, it puts a\n     comment at the top of the file disabling those specific lint rules and\n     leaves a TODO comment to fix any remaining style issues.\n  9. If the `codePrefix` config value is specified, it prepends that string to\n     every affected file.\n  10. All post-decaffeinate changes are committed as a third commit.\n\nIn all generated commits, \"decaffeinate\" is used as the author name (but not the\nemail address). This makes it clear to people using `git blame` that the file\nwas generated using decaffeinate, and not necessarily authored by the person who\nhappened to run the decaffeinate script.\n\nIf you want to see the full details, the [source code](src/convert.js) should\nhopefully be fairly readable.\n\n## Configuration\n\nYou can specify custom configuration in a config file, usually called\n`bulk-decaffeinate.config.js`, in the current working directory. It should\nexport a JS object with your config. Any file starting with `bulk-decaffeinate`\nand ending with `.config.js` will be counted, and multiple config files may\nexist at once. If there are multiple config files, they are merged, with\nalphabetically-later config file names taking precedence over\nalphabetically-earlier files.\n\nAlternatively, you may specify the config file location using the `--config`\noption, e.g. `bulk-decaffeinate --config ../bulk-decaffeinate.config.js` to use\na config file one level up in the directory structure.\n\nMany config options can also be specified directly as CLI arguments, with CLI\narguments taking precedence over any config file setting.\n\nHere's an example config file:\n\n```js\nmodule.exports = {\n  jscodeshiftScripts: [\n    './scripts/dev/codemods/arrow-function.js',\n    './scripts/dev/codemods/rd-to-create-element.js',\n    './scripts/dev/codemods/create-element-to-jsx.js',\n  ],\n  mochaEnvFilePattern: '^.*-test.js$',\n  fixImportsConfig: {\n    searchPath: './coffee',\n    absoluteImportPaths: ['./coffee'],\n  },\n};\n```\n\n### Specifying files to process\n\nThe following config keys can be specified:\n\n* `searchDirectory`: a path to a directory where bulk-decaffeinate will search\n  for all CoffeeScript files (ignoring files in `node_modules` directories).\n* `pathFile`: a path to a file containing a list of .coffee file paths to\n  process, one per line.\n* `filesToProcess`: an array of .coffee file paths to process.\n* `fileFilterFn`: a optional JavaScript function that takes the absolute path of\n  a file to consider and returns false if the file should be excluded. This is\n  run after the normal file discovery process, and is useful if there are\n  specific files or directories that should not be converted.\n\nIf multiple of `searchDirectory`, `pathFile`, or `filesToProcess` are specified,\nthe union of the files is taken. If none is specified, bulk-decaffeinate will\nrecursively discover all CoffeeScript files in the working directory.\n\nEach of these has a command line arg version, which takes precedence over config\nfile values; see the result of `--help` for more information.\n\n### Common configuration options\n\n* `useJSModules`: an optional boolean. If true, decaffeinate will be configured\n  to produce code with `import`/`export` syntax, and the fix-imports step will\n  be run afterward to correct any import statements across the codebase. The\n  fix-imports step can be configured using `fixImportsConfig`.\n* `decaffeinateArgs`: an optional array of additional command-line arguments to\n  pass to decaffeinate. For example, `['--keep-commonjs']` sets the preference\n  to keep `require` and `module.exports` rather than converting them to `import`\n  and `export`.\n* `jscodeshiftScripts`: an optional array of paths to\n  [jscodeshift](https://github.com/facebook/jscodeshift) scripts to run after\n  decaffeinate. This is useful to automate any cleanups to convert the output of\n  decaffeinate to code matching your JS style. In addition, you can specify any\n  of the built-in scripts included with this package:\n  * `prefer-function-declarations.js`: change `let f = function() {}` into\n    `function f() {}` when possible.\n  * `remove-coffee-from-imports.js`: change `import` and `require` statements\n    for .coffee files to no longer specify an extension.\n  * `top-level-this-to-exports.js`: change `this` at the top level to `exports`,\n    so the code can run in babel and node.\n* `fixImportsConfig`: an optional object. If present, a whole-codebase pass will\n  be done to fix any incorrect imports involving the converted files. It should\n  be an object with up to two fields:\n  * `searchPath`: a required field specifying a path to a directory containing\n    all JS files in the project.\n  * `absoluteImportPaths`: an optional array of strings, each of which is used\n    as an absolute path starting point when resolving imports. This is necessary\n    if you do any tricks to get absolute-style imports in your project, since\n    the fix-imports script needs to be able to resolve import names to files.\n\n### Other configuration\n\n* `customNames`: an optional object mapping old filename to new filename. By\n  default, the extension is removed and replaced with \".js\" (or nothing for\n  extensionless files), but this mapping can be used to override the behavior\n  to provide a specific target directory, name, and/or file extension for any\n  specific files being converted.\n* `outputFileExtension`: an optional file extension, like `\"ts\"` or `\"jsx\"`. If\n  specified, all converted files will have this extension.\n* `mochaEnvFilePattern`: an optional regular expression string. If specified,\n  all generated JavaScript files with a path matching this pattern have the text\n  `/* eslint-env mocha */` added to the start. For example, `\"^.*-test.js$\"`.\n* `codePrefix`: an optional string. If specified, it will be prepended to the\n  start of every affected file, above the autogenerated comment. If the prefix\n  should be on its own line, it should end with a newline.\n* `landConfig`: an object with preferences for the `land` command. There are\n  three available options:\n  * `remote`: an optional string with the name of the remote component of the\n    branch to base commits off of. Defaults to `origin`.\n  * `upstreamBranch`: an optional string with the name of the remote branch to\n    base commits off of. Defaults to `master`. For example, if both `remote` and\n    `upstreamBranch` are unspecified, then commits are created based on\n    `origin/master`.\n  * `phabricatorAware`: an optional boolean that's useful if you're using\n    Phabricator for code review. If specified, the generated commits will all\n    have a proper \"Differential Revision\" line and the final merge commit will\n    be run through `arc amend` to pull in the updated commit message.\n* `landBase`: if specified, overrides the auto-detected base commit when running\n    the `land` command. Generally this is specified on the command line using\n    `--land-base` rather than in a config file.\n* `numWorkers`: if specified, the number of parallel workers to use for parallel\n    operations like `decaffeinate` and `eslint --fix`.\n* `skipVerify`: set to `true` to skip the initial verification step when running\n  the `convert` command. This makes bulk-decaffeinate take less time, but if any\n  files fail to convert, it may leave the filesystem in a partially-converted\n  state.\n* `skipEslintFix`: set to `true` to skip the ESLint step.\n\n### Configuring paths to external tools\n\nRather than having bulk-decaffeinate automatically discover the relevant\nbinaries, you can specify them explicitly. If a path is not specified\nexplicitly, bulk-decaffeinate will first search `node_modules`, then your PATH,\nthen offer to install the tool globally, so generally it's unnecessary to\nspecify these paths in the config file.\n\nThese keys can be specified:\n\n* `decaffeinatePath`: the path to the decaffeinate binary.\n* `jscodeshiftPath`: the path to the jscodeshift binary.\n* `eslintPath`: the path to the eslint binary.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdecaffeinate%2Fbulk-decaffeinate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdecaffeinate%2Fbulk-decaffeinate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdecaffeinate%2Fbulk-decaffeinate/lists"}