Skip to content

Commit 6bfba1d

Browse files
fix(docs): respect custom README content when writing to a custom path (#5648)
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 STENCIL-1185
1 parent 84e1a14 commit 6bfba1d

File tree

5 files changed

+76
-8
lines changed

5 files changed

+76
-8
lines changed

src/compiler/docs/generate-doc-data.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,10 @@ export const getNameText = (name: string, tags: d.JsonDocsTag[]) => {
377377
* @returns the user generated content that occurs before {@link AUTO_GENERATE_COMMENT}. If no user generated content
378378
* exists, or if there was an issue reading the file, return `undefined`
379379
*/
380-
const getUserReadmeContent = async (compilerCtx: d.CompilerCtx, readmePath: string): Promise<string | undefined> => {
380+
export const getUserReadmeContent = async (
381+
compilerCtx: d.CompilerCtx,
382+
readmePath: string,
383+
): Promise<string | undefined> => {
381384
try {
382385
const existingContent = await compilerCtx.fs.readFile(readmePath);
383386
// subtract one to get everything up to, but not including the auto generated comment

src/compiler/docs/readme/output-docs.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { join, relative } from '@utils';
1+
import { join, normalizePath, relative } from '@utils';
22

33
import type * as d from '../../../declarations';
44
import { AUTO_GENERATE_COMMENT } from '../constants';
5+
import { getUserReadmeContent } from '../generate-doc-data';
56
import { stylesToMarkdown } from './markdown-css-props';
67
import { depsToMarkdown } from './markdown-dependencies';
78
import { eventsToMarkdown } from './markdown-events';
@@ -12,6 +13,23 @@ import { propsToMarkdown } from './markdown-props';
1213
import { slotsToMarkdown } from './markdown-slots';
1314
import { usageToMarkdown } from './markdown-usage';
1415

16+
/**
17+
* Generate a README for a given component and write it to disk.
18+
*
19+
* Typically the README is going to be a 'sibling' to the component's source
20+
* code (i.e. written to the same directory) but the user may also configure a
21+
* custom output directory by setting {@link d.OutputTargetDocsReadme.dir}.
22+
*
23+
* Output readme files also include {@link AUTO_GENERATE_COMMENT}, and any
24+
* text located _above_ that comment is preserved when the new readme is written
25+
* to disk.
26+
*
27+
* @param config a validated Stencil config
28+
* @param compilerCtx the current compiler context
29+
* @param readmeOutputs docs-readme output targets
30+
* @param docsData documentation data for the component of interest
31+
* @param cmps metadata for all the components in the project
32+
*/
1533
export const generateReadme = async (
1634
config: d.ValidatedConfig,
1735
compilerCtx: d.CompilerCtx,
@@ -25,10 +43,20 @@ export const generateReadme = async (
2543
await Promise.all(
2644
readmeOutputs.map(async (readmeOutput) => {
2745
if (readmeOutput.dir) {
28-
const readmeContent = generateMarkdown(userContent, docsData, cmps, readmeOutput);
29-
const relPath = relative(config.srcDir, docsData.readmePath);
30-
const absPath = join(readmeOutput.dir, relPath);
31-
const results = await compilerCtx.fs.writeFile(absPath, readmeContent);
46+
const relativeReadmePath = relative(config.srcDir, docsData.readmePath);
47+
const readmeOutputPath = join(readmeOutput.dir, relativeReadmePath);
48+
49+
const currentReadmeContent =
50+
normalizePath(readmeOutput.dir) !== normalizePath(config.srcDir)
51+
? // The user set a custom `.dir` property, which is where we're going
52+
// to write the updated README. We need to read the non-automatically
53+
// generated content from that file and preserve that.
54+
await getUserReadmeContent(compilerCtx, readmeOutputPath)
55+
: userContent;
56+
57+
const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput);
58+
59+
const results = await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
3260
if (results.changedContent) {
3361
if (isUpdate) {
3462
config.logger.info(`updated readme docs: ${docsData.tag}`);
@@ -42,15 +70,15 @@ export const generateReadme = async (
4270
};
4371

4472
export const generateMarkdown = (
45-
userContent: string,
73+
userContent: string | undefined,
4674
cmp: d.JsonDocsComponent,
4775
cmps: d.JsonDocsComponent[],
4876
readmeOutput: d.OutputTargetDocsReadme,
4977
) => {
5078
//If the readmeOutput.dependencies is true or undefined the dependencies will be generated.
5179
const dependencies = readmeOutput.dependencies !== false ? depsToMarkdown(cmp, cmps) : [];
5280
return [
53-
userContent,
81+
userContent || '',
5482
AUTO_GENERATE_COMMENT,
5583
'',
5684
'',
@@ -78,6 +106,12 @@ const getDocsDeprecation = (cmp: d.JsonDocsComponent) => {
78106
return [];
79107
};
80108

109+
/**
110+
* Get a minimal default README for a Stencil component
111+
*
112+
* @param docsData documentation data for the component of interest
113+
* @returns a minimal README template for that component
114+
*/
81115
const getDefaultReadme = (docsData: d.JsonDocsComponent) => {
82116
return [`# ${docsData.tag}`, '', '', ''].join('\n');
83117
};

src/declarations/stencil-public-compiler.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,11 @@ export interface OutputTargetDocsVscode extends OutputTargetBase {
22662266

22672267
export interface OutputTargetDocsReadme extends OutputTargetBase {
22682268
type: 'docs-readme';
2269+
/**
2270+
* The root directory where README files should be written
2271+
*
2272+
* defaults to {@link Config.srcDir}
2273+
*/
22692274
dir?: string;
22702275
dependencies?: boolean;
22712276
footer?: string;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# styleurls-component
2+
3+
This file is in a custom location, set with `.dir` on the `docs-readme` OT.
4+
5+
The content here above the 'auto-generation' comment shouldn't be overwritten.
6+
7+
This is a regression test for the issue reported in ionic-team/stencil#5400.
8+
9+
<!-- Auto Generated Below -->
10+
11+
12+
## CSS Custom Properties
13+
14+
| Name | Description |
15+
| ------- | ------------ |
16+
| `--one` | Property One |
17+
| `--two` | Property Two |
18+
19+
20+
----------------------------------------------
21+
22+
*Built with [StencilJS](https://stenciljs.com/)*

test/docs-readme/stencil.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,9 @@ export const config: Config = {
99
{
1010
type: 'dist',
1111
},
12+
{
13+
type: 'docs-readme',
14+
dir: 'custom-readme-output',
15+
},
1216
],
1317
};

0 commit comments

Comments
 (0)