-
Notifications
You must be signed in to change notification settings - Fork 12
feat(props): add props data gathering and table rendering support #40
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
Changes from 1 commit
3331d6d
7183400
3fc15bf
c13287c
b3514e5
ed7b44e
c12ebd7
40ec0c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| /* eslint-disable no-console */ | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file ingests the files which should have their props parsed, parses the props out using |
||
|
|
||
| import { glob } from 'glob' | ||
| import { writeFile } from 'fs/promises' | ||
| import { join } from 'path' | ||
|
|
||
| import { tsDocgen } from './tsDocGen.js' | ||
| import { getConfig, PropsGlobs } from './getConfig.js' | ||
|
|
||
| // Build unique names for components with a "variant" extension | ||
| function getTsDocName(name: string, variant: string) { | ||
| return `${name}${variant ? `-${variant}` : ''}` | ||
| } | ||
|
|
||
| function getTsDocNameVariant(source: string) { | ||
| if (source.includes('next')) { | ||
| return 'next' | ||
| } | ||
|
|
||
| if (source.includes('deprecated')) { | ||
| return 'deprecated' | ||
| } | ||
| } | ||
|
|
||
| async function getFiles(root: string, globs: PropsGlobs[]) { | ||
| const files = await Promise.all( | ||
| globs.map(async ({ include, exclude }) => { | ||
| const files = await glob(include, { cwd: root, ignore: exclude }) | ||
| return files | ||
| }), | ||
| ) | ||
| return files.flat() | ||
| } | ||
|
|
||
| async function getPropsData(files: string[], verbose: boolean) { | ||
| const perFilePropsData = await Promise.all( | ||
| files.map(async (file) => { | ||
| if (verbose) { | ||
| console.log(`Parsing props from ${file}`) | ||
| } | ||
|
|
||
| const props = await tsDocgen(file) | ||
|
|
||
| const tsDocs = props.reduce((acc, { name, description, props }) => { | ||
| const key = getTsDocName(name, getTsDocNameVariant(file)) | ||
| return { ...acc, [key]: { name, description, props } } | ||
| }, {}) | ||
|
|
||
| return tsDocs | ||
| }), | ||
| ) | ||
|
|
||
| const combinedPropsData = perFilePropsData.reduce((acc, props) => { | ||
| Object.keys(props).forEach((key) => { | ||
| if (acc[key]) { | ||
| acc[key].props = [...acc[key].props, ...props[key].props] | ||
| } else { | ||
| acc[key] = props[key] | ||
| } | ||
| }) | ||
| return acc | ||
| }, {}) | ||
|
|
||
| return combinedPropsData | ||
| } | ||
|
|
||
| export async function buildPropsData( | ||
| rootDir: string, | ||
| astroRoot: string, | ||
| configFile: string, | ||
| verbose: boolean, | ||
| ) { | ||
| const config = await getConfig(configFile) | ||
| if (!config) { | ||
| return | ||
| } | ||
|
|
||
| const { propsGlobs } = config | ||
| if (!propsGlobs) { | ||
| console.error('No props data found in config') | ||
| return | ||
| } | ||
|
|
||
| const files = await getFiles(rootDir, propsGlobs) | ||
| if (verbose) { | ||
| console.log(`Found ${files.length} files to parse`) | ||
| } | ||
|
|
||
| const propsData = await getPropsData(files, verbose) | ||
|
|
||
| const propsFile = join(astroRoot, 'dist', 'props.json') | ||
|
|
||
| await writeFile(propsFile, JSON.stringify(propsData)) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import { setFsRootDir } from './setFsRootDir.js' | |
| import { createConfigFile } from './createConfigFile.js' | ||
| import { updatePackageFile } from './updatePackageFile.js' | ||
| import { getConfig } from './getConfig.js' | ||
| import { buildPropsData } from './buildPropsData.js' | ||
|
|
||
| function updateContent(program: Command) { | ||
| const { verbose } = program.opts() | ||
|
|
@@ -23,16 +24,47 @@ function updateContent(program: Command) { | |
| ) | ||
| } | ||
|
|
||
| const astroRoot = import.meta | ||
| .resolve('@patternfly/patternfly-doc-core') | ||
| .replace('dist/cli/cli.js', '') | ||
| .replace('file://', '') | ||
| async function generateProps(program: Command, forceProps: boolean = false) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious, what would the expected use case of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whenever we want to enforce the props being generated on the CLI internals side regardless of if the user passes the |
||
| const { verbose, props } = program.opts() | ||
|
|
||
| if (!props && !forceProps) { | ||
| return | ||
| } | ||
|
|
||
| if (verbose) { | ||
| console.log('Verbose mode enabled') | ||
| } | ||
|
|
||
| buildPropsData( | ||
| currentDir, | ||
| astroRoot, | ||
| `${currentDir}/pf-docs.config.mjs`, | ||
| verbose, | ||
| ) | ||
| } | ||
|
|
||
| let astroRoot = '' | ||
|
|
||
| try { | ||
| astroRoot = import.meta | ||
| .resolve('@patternfly/patternfly-doc-core') | ||
| .replace('dist/cli/cli.js', '') | ||
| .replace('file://', '') | ||
| } catch (e) { | ||
| if (e.code === 'ERR_MODULE_NOT_FOUND') { | ||
| astroRoot = process.cwd() | ||
| } else { | ||
| console.error('Error resolving astroRoot', e) | ||
| } | ||
| } | ||
|
Comment on lines
+48
to
+60
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change just makes it so that we can run the docs-core locally more easily |
||
|
|
||
| const currentDir = process.cwd() | ||
|
|
||
| const program = new Command() | ||
| program.name('pf-doc-core') | ||
|
|
||
| program.option('--verbose', 'verbose mode', false) | ||
| program.option('--props', 'generate props data', false) | ||
|
|
||
| program.command('setup').action(async () => { | ||
| await Promise.all([ | ||
|
|
@@ -54,11 +86,13 @@ program.command('init').action(async () => { | |
|
|
||
| program.command('start').action(async () => { | ||
| updateContent(program) | ||
| await generateProps(program) | ||
| dev({ mode: 'development', root: astroRoot }) | ||
| }) | ||
|
|
||
| program.command('build').action(async () => { | ||
| updateContent(program) | ||
| await generateProps(program, true) | ||
| const config = await getConfig(`${currentDir}/pf-docs.config.mjs`) | ||
| if (!config) { | ||
| console.error( | ||
|
|
@@ -68,13 +102,20 @@ program.command('build').action(async () => { | |
| } | ||
|
|
||
| if (!config.outputDir) { | ||
| console.error("No outputDir found in config file, an output directory must be defined in your config file e.g. 'dist'") | ||
| console.error( | ||
| "No outputDir found in config file, an output directory must be defined in your config file e.g. 'dist'", | ||
| ) | ||
| return | ||
| } | ||
|
|
||
| build({ root: astroRoot, outDir: join(currentDir, config.outputDir) }) | ||
| }) | ||
|
|
||
| program.command('generate-props').action(async () => { | ||
| await generateProps(program, true) | ||
| console.log('\nProps data generated') | ||
| }) | ||
|
|
||
| program.command('serve').action(async () => { | ||
| updateContent(program) | ||
| preview({ root: astroRoot }) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,5 +16,16 @@ export const config = { | |
| // name: "react-component-docs", | ||
| // }, | ||
| ], | ||
| outputDir: "./dist/docs" | ||
| }; | ||
| outputDir: './dist/docs', | ||
| propsGlobs: [ | ||
| // { | ||
| // include: ['*/@patternfly/react-core/src/**/*.tsx'], | ||
| // exclude: [ | ||
| // '/**/examples/**', | ||
| // '/**/__mocks__/**', | ||
| // '/**/__tests__/**', | ||
| // '/**/*.test.tsx', | ||
| // ], | ||
| // }, | ||
|
Comment on lines
+21
to
+29
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this expected to be removed or uncommented before merging?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope I was planning to leave it commented in the template file like the content entry, but I'm not dead set on that. |
||
| ], | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes enable astro to run a node server for the custom endpoint below in props.json.ts