Skip to content

Import gist #75

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

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
*.trace
.env
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,31 @@ codemod-cli new <project-name>
This will create a small project structure (`README.md`, `package.json`, etc) which is
ready to help you manage your codemods.

You can also import from ast-explorer to create a codemod project via:

```
codemod-cli new <project-name> --url <ast-explorer-url> --codemod <codemod-name>
```

For example:

```
codemod-cli new my-awesome-codemod --url https://astexplorer.net/#/gist/cb7d2e7ce49741966e5e96a4b2eadc4d/d6b902bf639adc2bc6d31b35ba38aa45910b2413 --codemod reverse-string
```


Once you have a project, you can generate a new codemod:

```
codemod-cli generate codemod <name of codemod>
```

You can also import a codemod from ast-explorer url after you create a new project:

```
codemod-cli import <ast-explorer-url> <codemod-name>
```

This will setup a new jscodeshift codemod within your project at `transforms/<name of codemod>/index.js`
along with a test harness, README, fixture directory, and an initial set of input/output fixtures.

Expand Down
114 changes: 67 additions & 47 deletions commands/global/new.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,34 @@ module.exports.command = 'new <project-name>';
module.exports.desc = 'Generate a new codemod project';

module.exports.builder = function builder(yargs) {
yargs.positional('project-name', {
describe: 'The name of the project to generate',
});
yargs
.positional('project-name', {
describe: 'The name of the project to generate',
})
.option('url', {
alias: 'u',
demandOption: false,
describe: 'ast-explorer gist url to import from',
type: 'string',
})
.option('codemod', {
alias: 'c',
demandOption: false,
describe: 'name of the codemod to generate',
type: 'string',
});
};

module.exports.handler = async function handler(options) {
let { projectName } = options;
let { projectName, url, codemod: codemodName } = options;

const fs = require('fs-extra');
const { stripIndent } = require('common-tags');
const latestVersion = require('latest-version');
const pkg = require('../../package.json');
const { codemodReadme, projectReadme } = require('../../src/readme-support');

fs.outputFileSync(
projectName + '/README.md',
stripIndent`
# ${projectName}\n

A collection of codemod's for ${projectName}.

## Usage

To run a specific codemod from this project, you would run the following:

\`\`\`
npx ${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js

# or

yarn global add ${projectName}
${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
\`\`\`

## Transforms

<!--TRANSFORMS_START-->
<!--TRANSFORMS_END-->

## Contributing

### Installation

* clone the repo
* change into the repo directory
* \`yarn\`

### Running tests

* \`yarn test\`

### Update Documentation

* \`yarn update-docs\`
`,
'utf8'
);
fs.outputFileSync(projectName + '/README.md', projectReadme(projectName), 'utf8');
fs.outputJsonSync(
projectName + '/package.json',
{
Expand Down Expand Up @@ -256,4 +228,52 @@ module.exports.handler = async function handler(options) {
);
fs.outputFileSync(projectName + '/.gitignore', '/node_modules\n/.eslintcache');
fs.ensureFileSync(projectName + '/transforms/.gitkeep');

// If import options [ url && codemod] are present
if (url && codemodName) {
let regex = /https:\/\/astexplorer\.net\/#\/gist\/(\w+)\/(\w+)/;
let matches = regex.exec(url);

let [, gist_id, gistRevision] = matches;

let rawFile = `https://gist.githubusercontent.com/astexplorer/${gist_id}/raw/${gistRevision}/transform.js`;

const request = require('request'); // eslint-disable-line

request.get(rawFile, function(error, response, body) {
if (!error && response.statusCode == 200) {
// HACK: Replacing export default with module.exports
let _body = body.replace('export default', 'module.exports =');

// Formatting with prettier to avoid possible lint errors in new project
const prettier = require('prettier'); // eslint-disable-line
_body = prettier.format(_body, { parser: 'babel', singleQuote: true });
fs.outputFileSync(`${codemodDir}/index.js`, _body, 'utf8');
}
});

let codemodDir = `${process.cwd()}/${projectName}/transforms/${codemodName}`;

fs.outputFileSync(
`${codemodDir}/test.js`,
stripIndent`
'use strict';

const { runTransformTest } = require('codemod-cli');

runTransformTest({
type: 'jscodeshift',
name: '${codemodName}',
});` + '\n',
'utf8'
);

fs.outputFileSync(`${codemodDir}/README.md`, codemodReadme(projectName, codemodName), 'utf-8');

// Generate basic test fixtures
let fixturePath = `${codemodDir}/__testfixtures__/basic`;

fs.outputFileSync(`${fixturePath}.input.js`, '');
fs.outputFileSync(`${fixturePath}.output.js`, '');
}
};
27 changes: 2 additions & 25 deletions commands/local/generate/codemod.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports.handler = function handler(options) {
const { stripIndent } = require('common-tags');
const importCwd = require('import-cwd');
const generateFixture = require('./fixture').handler;
const { codemodReadme } = require('../../../src/readme-support');

let { codemodName } = options;
let projectName = importCwd('./package.json').name;
Expand Down Expand Up @@ -54,32 +55,8 @@ module.exports.handler = function handler(options) {
`,
'utf8'
);
fs.outputFileSync(
`${codemodDir}/README.md`,
stripIndent`
# ${codemodName}\n

## Usage

\`\`\`
npx ${projectName} ${codemodName} path/of/files/ or/some**/*glob.js

# or

yarn global add ${projectName}
${projectName} ${codemodName} path/of/files/ or/some**/*glob.js
\`\`\`

## Input / Output

<!--FIXTURES_TOC_START-->
<!--FIXTURES_TOC_END-->

<!--FIXTURES_CONTENT_START-->
<!--FIXTURES_CONTENT_END-->
`,
'utf8'
);
fs.outputFileSync(`${codemodDir}/README.md`, codemodReadme(projectName, codemodName), 'utf-8');

generateFixture({ codemodName, fixtureName: 'basic' });
};
55 changes: 55 additions & 0 deletions commands/local/import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports.command = 'import <gist-url> <codemod-name>';
module.exports.desc = 'Generate a new codemod file from ast-explorer gist';

module.exports.builder = function builder(yargs) {
yargs.positional('codemod-name', {
describe: 'the name of the codemod to generate',
});
yargs.positional('gist-url', {
describe: 'the url of the ast-explorer gist',
});
};

module.exports.handler = function handler(options) {
const fs = require('fs-extra');
const { stripIndent } = require('common-tags');
const importCwd = require('import-cwd');
const generateFixture = require('./generate/fixture').handler;
const { codemodReadme } = require('../../src/readme-support');

let { codemodName, gistUrl } = options;
let regex = /https:\/\/astexplorer\.net\/#\/gist\/(\w+)\/(\w+)/;
let matches = regex.exec(gistUrl);

let [, gist_id, gistRevision] = matches;

let rawFile = `https://gist.githubusercontent.com/astexplorer/${gist_id}/raw/${gistRevision}/transform.js`;

const request = require('request'); // eslint-disable-line
request.get(rawFile, function(error, response, body) {
if (!error && response.statusCode == 200) {
fs.outputFileSync(`${codemodDir}/index.js`, body, 'utf8');
}
});

let projectName = importCwd('./package.json').name;
let codemodDir = `${process.cwd()}/transforms/${codemodName}`;

fs.outputFileSync(
`${codemodDir}/test.js`,
stripIndent`
'use strict';

const { runTransformTest } = require('codemod-cli');

runTransformTest({
type: 'jscodeshift',
name: '${codemodName}',
});
`,
'utf8'
);

fs.outputFileSync(`${codemodDir}/README.md`, codemodReadme(projectName, codemodName), 'utf-8');
generateFixture({ codemodName, fixtureName: 'basic' });
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@babel/parser": "^7.6.0",
"chalk": "^2.4.2",
"common-tags": "^1.8.0",
"dotenv": "^8.2.0",
"execa": "^2.0.4",
"fs-extra": "^8.1.0",
"globby": "^10.0.1",
Expand Down
75 changes: 75 additions & 0 deletions src/readme-support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const { stripIndent } = require('common-tags');

function projectReadme(projectName) {
return stripIndent`
# ${projectName}\n

A collection of codemod's for ${projectName}.

## Usage

To run a specific codemod from this project, you would run the following:

\`\`\`
npx ${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js

# or

yarn global add ${projectName}
${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
\`\`\`

## Transforms

<!--TRANSFORMS_START-->
<!--TRANSFORMS_END-->

## Contributing

### Installation

* clone the repo
* change into the repo directory
* \`yarn\`

### Running tests

* \`yarn test\`

### Update Documentation

* \`yarn update-docs\`
`;
}

function codemodReadme(projectName, codemodName) {
return stripIndent`
# ${codemodName}\n

## Usage

\`\`\`
npx ${projectName} ${codemodName} path/of/files/ or/some**/*glob.js

# or

yarn global add ${projectName}
${projectName} ${codemodName} path/of/files/ or/some**/*glob.js
\`\`\`

## Input / Output

<!--FIXTURES_TOC_START-->
<!--FIXTURES_TOC_END-->

<!--FIXTURES_CONTENT_START-->
<!--FIXTURES_CONTENT_END-->
`;
}

module.exports = {
codemodReadme,
projectReadme,
};
Loading