Skip to content

Instantly share code, notes, and snippets.

@timofei-iatsenko
Last active July 6, 2017 10:38
Show Gist options
  • Save timofei-iatsenko/ef754b2617bd9c781474886fb935f3c4 to your computer and use it in GitHub Desktop.
Save timofei-iatsenko/ef754b2617bd9c781474886fb935f3c4 to your computer and use it in GitHub Desktop.
jscodeshift codemod
var path = require('path');
var fs = require('fs');
module.exports = function (file, api, options) {
const j = api.jscodeshift;
const ast = j(file.source);
const body = ast.find(j.Program).get('body');
// Find each angular.<method>() usage
var moduleUsages = ast.find(j.CallExpression, isModuleExpression)
.forEach((ast) => {
j(ast).replaceWith(j.identifier('module'))
});
if (moduleUsages.length === 0) {
return null;
}
// import angular from 'angular'
const moduleImport = ast.find(j.ImportDeclaration, isModuleImport);
if (moduleImport.length) {
return null;
}
var modulePath = options.modulePath || findModule(path.dirname(file.path), 0);
if (!modulePath) {
return null;
}
body.get(0).insertBefore(getImport(j, modulePath));
// Restore opening comments/position
body.value[0].comments = body.value[1].comments;
delete body.value[1].comments;
return ast.toSource({
arrowParensAlways: true,
quote: 'single',
});
};
function findModule(startPath, levels) {
var files = fs.readdirSync(startPath);
var module = files.find((file) => {
return file.indexOf('module.js') !== -1;
});
if (module) {
var prefix = levels === 0 ? './' : '../'.repeat(levels);
var filenaname = path.basename(module).replace('.js', '');
return prefix + filenaname;
} else if (levels < 4) {
//console.log('parent', getParentFolder(startPath));
return findModule(getParentFolder(startPath), ++levels);
}
}
function getParentFolder(folder) {
var parts = path.normalize(folder).split(path.sep);
parts.pop();
var parent = parts.join(path.sep);
if (parent === '') {
return process.cwd();
}
return parent;
}
function isModuleExpression(node) {
return (
node.arguments && node.arguments.length !== 2 &&
node.callee.object &&
node.callee.object.name === 'angular' &&
node.callee.property.name === 'module'
);
}
function isModuleImport(node) {
return (
node.type === 'ImportDeclaration' &&
node.specifiers.length > 0 &&
node.specifiers[0].local.name === 'module'
);
}
function getImport(j, modulePath) {
return j.importDeclaration([j.importSpecifier(j.identifier('module'))], j.literal(modulePath));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment