Skip to content

Commit

Permalink
fix(docs): respect custom README content when writing to a custom path
Browse files Browse the repository at this point in the history
On the `docs-readme` output target it's possible to set a custom output
location with the `.dir` property and the README files generation for
components will then be output to relative paths (like
`my-component/readme.md`) within that directory.

This fixes a bug where that behavior didn't properly respect any
manually-entered content in those readme files, so that if, for
instance, you set the output to `custom-readme-output` and had `"My
Custom Text"` at the top of
`custom-readme-output/components/my-component/readme.md` then running a
build would overwrite your custom text.

This changes things so that we read the content of the custom readme and
use that as the basis for the new text that we're going to write to
disk. This has the effect of preserving the custom text that a user
might have input.

fixes #5400
  • Loading branch information
alicewriteswrongs committed Apr 15, 2024
1 parent 2082368 commit fbe8148
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/compiler/docs/generate-doc-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,10 @@ export const getNameText = (name: string, tags: d.JsonDocsTag[]) => {
* @returns the user generated content that occurs before {@link AUTO_GENERATE_COMMENT}. If no user generated content
* exists, or if there was an issue reading the file, return `undefined`
*/
const getUserReadmeContent = async (compilerCtx: d.CompilerCtx, readmePath: string): Promise<string | undefined> => {
export const getUserReadmeContent = async (
compilerCtx: d.CompilerCtx,
readmePath: string,
): Promise<string | undefined> => {
try {
const existingContent = await compilerCtx.fs.readFile(readmePath);
// subtract one to get everything up to, but not including the auto generated comment
Expand Down
48 changes: 41 additions & 7 deletions src/compiler/docs/readme/output-docs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { join, relative } from '@utils';
import { join, normalizePath, relative } from '@utils';

import type * as d from '../../../declarations';
import { AUTO_GENERATE_COMMENT } from '../constants';
import { getUserReadmeContent } from '../generate-doc-data';
import { stylesToMarkdown } from './markdown-css-props';
import { depsToMarkdown } from './markdown-dependencies';
import { eventsToMarkdown } from './markdown-events';
Expand All @@ -12,6 +13,23 @@ import { propsToMarkdown } from './markdown-props';
import { slotsToMarkdown } from './markdown-slots';
import { usageToMarkdown } from './markdown-usage';

/**
* Generate a README for a given component and write it to disk.
*
* Typically the README is going to be a 'sibling' to the component's source
* code (i.e. written to the same directory) but the user may also configure a
* custom output directory by setting {@link d.OutputTargetDocsReadme.dir}.
*
* Output readme files also include {@link AUTO_GENERATE_COMMENT}, and any
* text located _above_ that comment is preserved when the new readme is written
* to disk.
*
* @param config a validated Stencil config
* @param compilerCtx the current compiler context
* @param readmeOutputs docs-readme output targets
* @param docsData documentation data for the component of interest
* @param cmps metadata for all the components in the project
*/
export const generateReadme = async (
config: d.ValidatedConfig,
compilerCtx: d.CompilerCtx,
Expand All @@ -25,10 +43,20 @@ export const generateReadme = async (
await Promise.all(
readmeOutputs.map(async (readmeOutput) => {
if (readmeOutput.dir) {
const readmeContent = generateMarkdown(userContent, docsData, cmps, readmeOutput);
const relPath = relative(config.srcDir, docsData.readmePath);
const absPath = join(readmeOutput.dir, relPath);
const results = await compilerCtx.fs.writeFile(absPath, readmeContent);
const relativeReadmePath = relative(config.srcDir, docsData.readmePath);
const readmeOutputPath = join(readmeOutput.dir, relativeReadmePath);

const currentReadmeContent =
normalizePath(readmeOutput.dir) !== normalizePath(config.srcDir)
? // The user set a custom `.dir` property, which is where we're going
// to write the updated README. We need to read the non-automatically
// generated content from that file and preserve that.
await getUserReadmeContent(compilerCtx, readmeOutputPath)
: userContent;

const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput);

const results = await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
if (results.changedContent) {
if (isUpdate) {
config.logger.info(`updated readme docs: ${docsData.tag}`);
Expand All @@ -42,15 +70,15 @@ export const generateReadme = async (
};

export const generateMarkdown = (
userContent: string,
userContent: string | undefined,
cmp: d.JsonDocsComponent,
cmps: d.JsonDocsComponent[],
readmeOutput: d.OutputTargetDocsReadme,
) => {
//If the readmeOutput.dependencies is true or undefined the dependencies will be generated.
const dependencies = readmeOutput.dependencies !== false ? depsToMarkdown(cmp, cmps) : [];
return [
userContent,
userContent || '',
AUTO_GENERATE_COMMENT,
'',
'',
Expand Down Expand Up @@ -78,6 +106,12 @@ const getDocsDeprecation = (cmp: d.JsonDocsComponent) => {
return [];
};

/**
* Get a minimal default README for a Stencil component
*
* @param docsData documentation data for the component of interest
* @returns a minimal README template for that component
*/
const getDefaultReadme = (docsData: d.JsonDocsComponent) => {
return [`# ${docsData.tag}`, '', '', ''].join('\n');
};
5 changes: 5 additions & 0 deletions src/declarations/stencil-public-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,11 @@ export interface OutputTargetDocsVscode extends OutputTargetBase {

export interface OutputTargetDocsReadme extends OutputTargetBase {
type: 'docs-readme';
/**
* The root directory where README files should be written
*
* defaults to {@link Config.srcDir}
*/
dir?: string;
dependencies?: boolean;
footer?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
This file is in a custom location, set with `.dir` on the `docs-readme` OT.

The content here above the 'auto-generation' comment shouldn't be overwritten.

This is a regression test for the issue reported in ionic-team/stencil#5400.

<!-- Auto Generated Below -->


## Methods

### `onDidDismiss<T>(arg: T) => Promise<ImportedInterface<T>>`

A comment, which should be included, I should think!

#### Parameters

| Name | Type | Description |
| ----- | ---- | ----------- |
| `arg` | `T` | |

#### Returns

Type: `Promise<ImportedInterface<T>>`




----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
4 changes: 4 additions & 0 deletions test/docs-json/stencil.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ export const config: Config = {
file: 'docs.json',
supplementalPublicTypes: 'src/components/interfaces.ts',
},
{
type: 'docs-readme',
dir: 'custom-readme-output',
},
],
};

0 comments on commit fbe8148

Please sign in to comment.