/
PackagePlugin.ts
133 lines (119 loc) · 4.49 KB
/
PackagePlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import * as Path from "path";
import * as FS from "fs";
import { Component, ConverterComponent } from "../components";
import { Converter } from "../converter";
import type { Context } from "../context";
import { BindOption, readFile } from "../../utils";
import { getCommonDirectory } from "../../utils/fs";
import { nicePath } from "../../utils/paths";
/**
* A handler that tries to find the package.json and readme.md files of the
* current project.
*/
@Component({ name: "package" })
export class PackagePlugin extends ConverterComponent {
@BindOption("readme")
readme!: string;
@BindOption("includeVersion")
includeVersion!: boolean;
/**
* The file name of the found readme.md file.
*/
private readmeFile?: string;
/**
* The file name of the found package.json file.
*/
private packageFile?: string;
/**
* Create a new PackageHandler instance.
*/
override initialize() {
this.listenTo(this.owner, {
[Converter.EVENT_BEGIN]: this.onBegin,
[Converter.EVENT_RESOLVE_BEGIN]: this.onBeginResolve,
[Converter.EVENT_END]: () => {
delete this.readmeFile;
delete this.packageFile;
},
});
}
/**
* Triggered when the converter begins converting a project.
*/
private onBegin(_context: Context) {
this.readmeFile = undefined;
this.packageFile = undefined;
// Path will be resolved already. This is kind of ugly, but...
const noReadmeFile = this.readme.endsWith("none");
if (!noReadmeFile && this.readme) {
if (FS.existsSync(this.readme)) {
this.readmeFile = this.readme;
}
}
const packageAndReadmeFound = () =>
(noReadmeFile || this.readmeFile) && this.packageFile;
const reachedTopDirectory = (dirName: string) =>
dirName === Path.resolve(Path.join(dirName, ".."));
let dirName = Path.resolve(
getCommonDirectory(this.application.options.getValue("entryPoints"))
);
this.application.logger.verbose(
`Begin readme.md/package.json search at ${nicePath(dirName)}`
);
while (!packageAndReadmeFound() && !reachedTopDirectory(dirName)) {
FS.readdirSync(dirName).forEach((file) => {
const lowercaseFileName = file.toLowerCase();
if (
!noReadmeFile &&
!this.readmeFile &&
lowercaseFileName === "readme.md"
) {
this.readmeFile = Path.join(dirName, file);
}
if (!this.packageFile && lowercaseFileName === "package.json") {
this.packageFile = Path.join(dirName, file);
}
});
dirName = Path.resolve(Path.join(dirName, ".."));
}
}
/**
* Triggered when the converter begins resolving a project.
*
* @param context The context object describing the current state the converter is in.
*/
private onBeginResolve(context: Context) {
const project = context.project;
if (this.readmeFile) {
project.readme = readFile(this.readmeFile);
}
if (this.packageFile) {
project.packageInfo = JSON.parse(readFile(this.packageFile));
if (!project.name) {
if (!project.packageInfo.name) {
context.logger.warn(
'The --name option was not specified, and package.json does not have a name field. Defaulting project name to "Documentation"'
);
project.name = "Documentation";
} else {
project.name = String(project.packageInfo.name);
}
}
if (this.includeVersion) {
project.name = `${project.name} - v${project.packageInfo.version}`;
}
} else {
if (!project.name) {
context.logger.warn(
'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation"'
);
project.name = "Documentation";
}
if (this.includeVersion) {
context.logger.warn(
"--includeVersion was specified, but no package.json was found. Not adding package version to the documentation."
);
}
}
}
}