-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: parse monorepo project readme (#1001)
- Loading branch information
1 parent
fc4d7b9
commit ae76db7
Showing
8 changed files
with
315 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
|
||
/* eslint-disable no-console */ | ||
|
||
import fs from 'fs' | ||
import path from 'path' | ||
import { | ||
ensureFileHasContents | ||
} from './utils.js' | ||
import { toc as makeToc } from 'mdast-util-toc' | ||
import { parseMarkdown, writeMarkdown } from './readme/utils.js' | ||
import { HEADER } from './readme/header.js' | ||
import { LICENSE } from './readme/license.js' | ||
import { STRUCTURE } from './readme/structure.js' | ||
|
||
/** | ||
* @param {string} projectDir | ||
* @param {string} repoUrl | ||
* @param {string} defaultBranch | ||
* @param {string[]} projectDirs | ||
*/ | ||
export async function checkMonorepoReadme (projectDir, repoUrl, defaultBranch, projectDirs) { | ||
const repoParts = repoUrl.split('/') | ||
const repoName = repoParts.pop() | ||
const repoOwner = repoParts.pop() | ||
|
||
if (repoName == null || repoOwner == null) { | ||
throw new Error(`Could not parse repo owner & name from ${repoUrl}`) | ||
} | ||
|
||
console.info('Check README files') | ||
|
||
const pkg = JSON.parse(fs.readFileSync(path.join(projectDir, 'package.json'), { | ||
encoding: 'utf-8' | ||
})) | ||
|
||
const readmePath = path.join(projectDir, 'README.md') | ||
let readmeContents = '' | ||
|
||
if (fs.existsSync(readmePath)) { | ||
readmeContents = fs.readFileSync(path.join(projectDir, 'README.md'), { | ||
encoding: 'utf-8' | ||
}) | ||
} | ||
|
||
// replace the magic OPTION+SPACE character that messes up headers | ||
readmeContents = readmeContents.replaceAll(' ', ' ') | ||
|
||
// parse the project's readme file | ||
const file = parseMarkdown(readmeContents) | ||
|
||
// create basic readme with heading, CI link, etc | ||
const readme = parseMarkdown(HEADER(pkg, repoOwner, repoName, defaultBranch)) | ||
|
||
// remove existing header, CI link, etc | ||
/** @type {import('mdast').Root} */ | ||
const parsedReadme = { | ||
type: 'root', | ||
children: [] | ||
} | ||
|
||
let structureIndex = -1 | ||
let tocIndex = -1 | ||
let licenseFound = false | ||
|
||
file.children.forEach((child, index) => { | ||
const rendered = writeMarkdown(child).toLowerCase() | ||
|
||
if (child.type === 'heading' && index === 0) { | ||
// skip heading | ||
return | ||
} | ||
|
||
if (child.type === 'paragraph' && index === 1) { | ||
// skip badges | ||
return | ||
} | ||
|
||
if (child.type === 'blockquote' && tocIndex === -1 && tocIndex === -1) { | ||
// skip project overview | ||
return | ||
} | ||
|
||
if (rendered.includes('## table of')) { | ||
// skip toc header | ||
tocIndex = index | ||
return | ||
} | ||
|
||
if (tocIndex !== -1 && index === tocIndex + 1) { | ||
// skip toc | ||
return | ||
} | ||
|
||
if (child.type === 'heading' && rendered.includes('structure')) { | ||
// skip structure header | ||
structureIndex = index | ||
return | ||
} | ||
|
||
if (structureIndex !== -1 && index === structureIndex + 1) { | ||
// skip structure | ||
return | ||
} | ||
|
||
if ((child.type === 'heading' && rendered.includes('license')) || licenseFound) { | ||
licenseFound = true | ||
return | ||
} | ||
|
||
parsedReadme.children.push(child) | ||
}) | ||
|
||
const license = parseMarkdown(LICENSE[repoOwner]) | ||
const structure = parseMarkdown(STRUCTURE(projectDir, projectDirs)) | ||
|
||
parsedReadme.children = [ | ||
...structure.children, | ||
...parsedReadme.children, | ||
...license.children | ||
] | ||
|
||
const toc = makeToc(parsedReadme, { | ||
tight: true | ||
}) | ||
|
||
if (toc.map == null) { | ||
throw new Error('Could not create TOC for README.md') | ||
} | ||
|
||
readme.children = [ | ||
...readme.children, | ||
toc.map, | ||
...parsedReadme.children | ||
] | ||
|
||
await ensureFileHasContents(projectDir, 'README.md', writeMarkdown(readme)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* @type {Record<string, (repoOwner: string, repoName: string, defaultBranch: string) => string>} | ||
*/ | ||
const BADGES = { | ||
libp2p: (repoOwner, repoName, defaultBranch) => ` | ||
[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) | ||
[![IRC](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) | ||
[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) | ||
[![codecov](https://img.shields.io/codecov/c/github/${repoOwner}/${repoName}.svg?style=flat-square)](https://codecov.io/gh/${repoOwner}/${repoName}) | ||
[![CI](https://img.shields.io/github/workflow/status/libp2p/js-libp2p-interfaces/test%20&%20maybe%20release/${defaultBranch}?style=flat-square)](https://github.com/${repoOwner}/${repoName}/actions/workflows/js-test-and-release.yml) | ||
`, | ||
ipfs: (repoOwner, repoName, defaultBranch) => ` | ||
[![ipfs.io](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io) | ||
[![IRC](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) | ||
[![Discord](https://img.shields.io/discord/806902334369824788?style=flat-square)](https://discord.gg/ipfs) | ||
[![codecov](https://img.shields.io/codecov/c/github/${repoOwner}/${repoName}.svg?style=flat-square)](https://codecov.io/gh/${repoOwner}/${repoName}) | ||
[![CI](https://img.shields.io/github/workflow/status/libp2p/js-libp2p-interfaces/test%20&%20maybe%20release/${defaultBranch}?style=flat-square)](https://github.com/${repoOwner}/${repoName}/actions/workflows/js-test-and-release.yml) | ||
` | ||
} | ||
|
||
/** | ||
* @param {*} pkg | ||
* @param {string} repoOwner | ||
* @param {string} repoName | ||
* @param {string} defaultBranch | ||
*/ | ||
export const HEADER = (pkg, repoOwner, repoName, defaultBranch) => { | ||
return ` | ||
# ${pkg.name} <!-- omit in toc --> | ||
${BADGES[repoOwner](repoOwner, repoName, defaultBranch).trim()} | ||
> ${pkg.description} | ||
## Table of contents <!-- omit in toc --> | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/** | ||
* @param {*} pkg | ||
*/ | ||
export const INSTALL = (pkg) => { | ||
return ` | ||
## Install | ||
\`\`\`console | ||
$ npm i ${pkg.name} | ||
\`\`\` | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
/** @type {Record<string, string>} */ | ||
export const LICENSE = { | ||
libp2p: ` | ||
## License | ||
Licensed under either of | ||
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0) | ||
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT) | ||
## Contribution | ||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. | ||
`, | ||
ipfs: ` | ||
## License | ||
Licensed under either of | ||
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0) | ||
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT) | ||
## Contribute | ||
Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/js-ipfs-unixfs-importer/issues)! | ||
This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). | ||
[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) | ||
` | ||
} |
Oops, something went wrong.