├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── generators └── app │ ├── index.js │ └── templates │ └── codemod.js ├── package.json └── test └── app.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [{package.json,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - v5 4 | - v4 5 | - '0.12' 6 | - '0.10' 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 James Talmage (github.com/jamestalmage) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generator-codemod [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] 2 | 3 | > Scaffold a jscodeshift codemod 4 | 5 | Creates a scaffold for a [`jscodeshift`](https://github.com/facebook/jscodeshift) based codemod in the current project. 6 | 7 | 8 | ## Install 9 | 10 | ```console 11 | $ npm install -g yo generator-codemod 12 | ``` 13 | 14 | 15 | ## Usage 16 | 17 | ```console 18 | $ yo codemod 19 | ``` 20 | 21 | 22 | ## License 23 | 24 | MIT © [James Talmage](https://github.com/jamestalmage) 25 | 26 | 27 | [travis-image]: https://travis-ci.org/jamestalmage/generator-codemod.svg?branch=master 28 | [travis-url]: https://travis-ci.org/jamestalmage/generator-codemod 29 | [daviddm-image]: https://david-dm.org/jamestalmage/generator-codemod.svg?theme=shields.io 30 | [daviddm-url]: https://david-dm.org/jamestalmage/generator-codemod 31 | -------------------------------------------------------------------------------- /generators/app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var yeoman = require('yeoman-generator'); 4 | var camelcase = require('camelcase'); 5 | 6 | module.exports = yeoman.Base.extend({ 7 | prompting: function () { 8 | var done = this.async(); 9 | 10 | var prompts = [{ 11 | name: 'filename', 12 | message: 'Specify a folder/filename', 13 | default: 'lib/my-codemod' 14 | }]; 15 | 16 | this.prompt(prompts, function (props) { 17 | var filename = props.filename; 18 | var ext = path.extname(filename); 19 | var base = path.basename(filename, ext); 20 | 21 | if (ext === '') { 22 | ext = '.js'; 23 | } 24 | 25 | this.props = { 26 | filename: path.join(path.dirname(filename), base + ext), 27 | camelName: camelcase(base) 28 | }; 29 | 30 | done(); 31 | }.bind(this)); 32 | }, 33 | 34 | writing: function () { 35 | this.fs.copyTpl( 36 | this.templatePath('codemod.js'), 37 | this.destinationPath(this.props.filename), 38 | this.props 39 | ); 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /generators/app/templates/codemod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function <%= camelName %>(file, api) { 4 | var j = api.jscodeshift; 5 | var ast = j(file.source); 6 | 7 | ast.find(j.CallExpression, { 8 | callee: { 9 | type: 'Identifier', 10 | name: 'foo' 11 | } 12 | }).forEach(function (p) { 13 | p.get('callee').replace(j.identifier('bar')); 14 | }); 15 | 16 | return ast.toSource({ 17 | useTabs: true, 18 | quote: 'single' 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-codemod", 3 | "version": "0.1.1", 4 | "description": "Scaffold a jscodeshift codemod", 5 | "author": { 6 | "name": "James Talmage", 7 | "email": "james@talmage.io", 8 | "url": "github.com/jamestalmage" 9 | }, 10 | "files": [ 11 | "generators" 12 | ], 13 | "main": "generators/index.js", 14 | "keywords": [ 15 | "codemod", 16 | "jscodeshift", 17 | "yeoman-generator" 18 | ], 19 | "dependencies": { 20 | "camelcase": "^2.1.1", 21 | "underscore.string": "^3.3.4", 22 | "yeoman-generator": "^0.22.0" 23 | }, 24 | "devDependencies": { 25 | "ava": "^0.14.0", 26 | "xo": "^0.14.0", 27 | "yeoman-assert": "^2.0.0", 28 | "yeoman-test": "^1.0.0" 29 | }, 30 | "repository": "jamestalmage/generator-codemod", 31 | "scripts": { 32 | "test": "xo && ava" 33 | }, 34 | "license": "MIT", 35 | "xo": { 36 | "ignore": "generators/**/templates/**" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import test from 'ava'; 3 | import assert from 'yeoman-assert'; 4 | import helpers from 'yeoman-test'; 5 | 6 | function runWithPrompts(prompts, cb) { 7 | helpers 8 | .run(path.join(__dirname, '../generators/app')) 9 | .withPrompts(prompts) 10 | .on('end', cb); 11 | } 12 | 13 | test.cb('generator-codemod:app', t => { 14 | runWithPrompts({filename: 'my-codemod'}, err => { 15 | t.ifError(err); 16 | assert.file([ 17 | 'my-codemod.js' 18 | ]); 19 | t.end(); 20 | }); 21 | }); 22 | --------------------------------------------------------------------------------