Skip to content

Commit 4a2489e

Browse files
authored
Merge pull request #26 from rwjblue/add-project-readme
Add project readme
2 parents ae0a1ef + 6347f4e commit 4a2489e

5 files changed

Lines changed: 193 additions & 2 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ codemod-cli generate fixture <name of codemod> <name of fixture>
5050
This sets up two new files in `transforms/<name of codemod>/__testfixtures__/` using the fixture name
5151
you provided. These fixtures are used by the testing harness to verify that your codemod is working properly.
5252

53+
Once you have things just how you like them with your new codemod (and your tests are passing :wink:) you
54+
can update your project's README and your transforms README via:
55+
56+
```
57+
codemod-cli update-docs
58+
```
5359

5460
Contributing
5561
------------------------------------------------------------------------------

commands/global/new.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,57 @@ module.exports.handler = function handler(options) {
1616
const { stripIndent } = require('common-tags');
1717
const pkg = require('../../package.json');
1818

19-
fs.outputFileSync(projectName + '/README.md', `# ${projectName}\n`, 'utf8');
19+
fs.outputFileSync(
20+
projectName + '/README.md',
21+
stripIndent`
22+
# ${projectName}\n
23+
24+
A collection of codemod's for ${projectName}.
25+
26+
## Usage
27+
28+
To run a specific codemod from this project, you would run the following:
29+
30+
\`\`\`
31+
npx ${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
32+
33+
# or
34+
35+
yarn global add ${projectName}
36+
${projectName} <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
37+
\`\`\`
38+
39+
## Transforms
40+
41+
<!--TRANSFORMS_START-->
42+
<!--TRANSFORMS_END-->
43+
44+
## Contributing
45+
46+
### Installation
47+
48+
* clone the repo
49+
* change into the repo directory
50+
* \`yarn\`
51+
52+
### Running tests
53+
54+
* \`yarn test\`
55+
56+
### Update Documentation
57+
58+
* \`yarn update-docs\`
59+
`,
60+
'utf8'
61+
);
2062
fs.outputJsonSync(
2163
projectName + '/package.json',
2264
{
2365
name: projectName,
2466
version: '0.1.0',
2567
scripts: {
2668
test: 'codemod-cli test',
69+
'update-docs': 'codemod-cli update-docs',
2770
},
2871
bin: './bin/cli.js',
2972
keywords: ['codemod-cli'],

commands/local/generate/codemod.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ module.exports.builder = function builder(yargs) {
1010
module.exports.handler = function handler(options) {
1111
const fs = require('fs-extra');
1212
const { stripIndent } = require('common-tags');
13+
const importCwd = require('import-cwd');
1314
const generateFixture = require('./fixture').handler;
1415

1516
let { codemodName } = options;
17+
let projectName = importCwd('./package.json').name;
1618
let codemodDir = `${process.cwd()}/transforms/${codemodName}`;
1719

1820
fs.outputFileSync(
@@ -48,7 +50,32 @@ module.exports.handler = function handler(options) {
4850
`,
4951
'utf8'
5052
);
51-
fs.outputFileSync(`${codemodDir}/README.md`, `# ${codemodName}\n`, 'utf8');
53+
fs.outputFileSync(
54+
`${codemodDir}/README.md`,
55+
stripIndent`
56+
# ${codemodName}\n
57+
58+
## Usage
59+
60+
\`\`\`
61+
npx ${projectName} ${codemodName} path/of/files/ or/some**/*glob.js
62+
63+
# or
64+
65+
yarn global add ${projectName}
66+
${projectName} ${codemodName} path/of/files/ or/some**/*glob.js
67+
\`\`\`
68+
69+
## Input / Output
70+
71+
<!--FIXTURES_TOC_START-->
72+
<!--FIXTURES_TOC_END-->
73+
74+
<!--FIXTURES_CONTENT_START-->
75+
<!--FIXTURES_CONTENT_END-->
76+
`,
77+
'utf8'
78+
);
5279

5380
generateFixture({ codemodName, fixtureName: 'basic' });
5481
};

commands/local/update-docs.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module.exports.command = 'update-docs';
2+
module.exports.desc = 'Update the project README with current list of transforms';
3+
4+
function updateProjectREADME() {
5+
const fs = require('fs-extra');
6+
7+
let TRANSFORMS_PLACE_HOLDER = /<!--TRANSFORMS_START-->[\s\S]*<!--TRANSFORMS_END-->/;
8+
9+
let transforms = fs
10+
.readdirSync('transforms')
11+
.filter(file => fs.lstatSync(`transforms/${file}`).isDirectory());
12+
13+
let readmeContent = transforms
14+
.map(name => `* [${name}](transforms/${name}/README.md)`)
15+
.join('\n');
16+
17+
fs.writeFileSync(
18+
'README.md',
19+
fs
20+
.readFileSync('README.md', 'utf8')
21+
.replace(
22+
TRANSFORMS_PLACE_HOLDER,
23+
`<!--TRANSFORMS_START-->\n${readmeContent}\n<!--TRANSFORMS_END-->`
24+
)
25+
);
26+
}
27+
28+
function updateTransformREADME(transformName) {
29+
const fs = require('fs-extra');
30+
const path = require('path');
31+
32+
let toc = [];
33+
let details = [];
34+
35+
let fixtureDir = `transforms/${transformName}/__testfixtures__`;
36+
37+
if (!fs.existsSync(fixtureDir)) {
38+
// project does not include fixtures (perhaps using different testing
39+
// setup)
40+
return;
41+
}
42+
43+
fs.readdirSync(fixtureDir)
44+
.filter(filename => /\.input$/.test(path.basename(filename, path.extname(filename))))
45+
.forEach(filename => {
46+
let extension = path.extname(filename);
47+
let testName = filename.replace(`.input${extension}`, '');
48+
let inputPath = path.join(fixtureDir, `${testName}.input${extension}`);
49+
let outputPath = path.join(fixtureDir, `${testName}.output${extension}`);
50+
51+
toc.push(`* [${testName}](#${testName})`);
52+
details.push(
53+
'---',
54+
`<a id="${testName}"></a>`,
55+
`**Input** (<small>[${testName}.input${extension}](${inputPath})</small>):`,
56+
fs.readFileSync(inputPath),
57+
`**Output** (<small>[${testName}.input${extension}](${outputPath})</small>):`,
58+
fs.readFileSync(outputPath)
59+
);
60+
});
61+
62+
let transformREADMEPath = `transforms/${transformName}/README.md`;
63+
64+
let FIXTURES_TOC_PLACE_HOLDER = /<!--FIXTURES_TOC_START-->[\s\S]*<!--FIXTURES_TOC_END-->/;
65+
let FIXTURES_CONTENTS_PLACE_HOLDER = /<!--FIXTURES_CONTENT_START-->[\s\S]*<!--FIXTURES_CONTENT_END-->/;
66+
67+
fs.writeFileSync(
68+
transformREADMEPath,
69+
fs
70+
.readFileSync(transformREADMEPath, 'utf8')
71+
.replace(
72+
FIXTURES_TOC_PLACE_HOLDER,
73+
`<!--FIXTURES_TOC_START-->\n${toc.join('\n')}\n<!--FIXTURES_TOC_END-->`
74+
)
75+
.replace(
76+
FIXTURES_CONTENTS_PLACE_HOLDER,
77+
`<!--FIXTURES_CONTENTS_START-->\n${details.join('\n')}\n<!--FIXTURES_CONTENTS_END-->`
78+
)
79+
);
80+
}
81+
82+
function updateTransformREADMEs() {
83+
const fs = require('fs-extra');
84+
85+
fs.readdirSync('transforms')
86+
.filter(file => fs.lstatSync(`transforms/${file}`).isDirectory())
87+
.forEach(updateTransformREADME);
88+
}
89+
90+
module.exports.handler = function handler() {
91+
updateProjectREADME();
92+
updateTransformREADMEs();
93+
};

tests/cli-test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,28 @@ QUnit.module('codemod-cli', function(hooks) {
7474
);
7575
});
7676

77+
QUnit.module('update-docs', function(hooks) {
78+
setupProject(hooks);
79+
80+
QUnit.test(
81+
'updates top-level README with links to transform READMEs',
82+
wrap(function*(assert) {
83+
codemodProject.write({
84+
transforms: {
85+
foo: { 'README.md': 'some content' },
86+
bar: { 'README.md': 'some content' },
87+
},
88+
});
89+
90+
yield execa(EXECUTABLE_PATH, ['update-docs']);
91+
92+
let README = fs.readFileSync(codemodProject.path('README.md'), 'utf8');
93+
assert.ok(README.includes('* [foo](transforms/foo/README.md'), 'foo link');
94+
assert.ok(README.includes('* [bar](transforms/bar/README.md'), 'bar link');
95+
})
96+
);
97+
});
98+
7799
QUnit.module('generate', function(hooks) {
78100
setupProject(hooks);
79101

0 commit comments

Comments
 (0)