Skip to content

Commit 16a5186

Browse files
authored
Load plugin readme from file system (#14699)
1 parent b63b8d5 commit 16a5186

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

packages/vsx-registry/src/browser/vsx-extensions-model.ts

+34-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { OVSXClientProvider } from '../common/ovsx-client-provider';
3333
import { RequestContext, RequestService } from '@theia/core/shared/@theia/request';
3434
import { OVSXApiFilterProvider } from '@theia/ovsx-client';
3535
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
36+
import { FileService } from '@theia/filesystem/lib/browser/file-service';
3637

3738
@injectable()
3839
export class VSXExtensionsModel {
@@ -81,6 +82,9 @@ export class VSXExtensionsModel {
8182
@inject(OVSXApiFilterProvider)
8283
protected vsxApiFilter: OVSXApiFilterProvider;
8384

85+
@inject(FileService)
86+
protected readonly fileService: FileService;
87+
8488
@inject(ApplicationServer)
8589
protected readonly applicationServer: ApplicationServer;
8690

@@ -135,13 +139,24 @@ export class VSXExtensionsModel {
135139
resolve(id: string): Promise<VSXExtension> {
136140
return this.doChange(async () => {
137141
await this.initialized;
138-
const extension = await this.refresh(id);
142+
const extension = await this.refresh(id) ?? this.getExtension(id);
139143
if (!extension) {
140144
throw new Error(`Failed to resolve ${id} extension.`);
141145
}
142-
if (extension.readmeUrl) {
146+
if (extension.readme === undefined) {
143147
try {
144-
const rawReadme = RequestContext.asText(await this.request.request({ url: extension.readmeUrl }));
148+
let rawReadme: string = '';
149+
const installedReadme = await this.findReadmeFile(extension);
150+
// Attempt to read the local readme first
151+
// It saves network resources and is faster
152+
if (installedReadme) {
153+
const readmeContent = await this.fileService.readFile(installedReadme);
154+
rawReadme = readmeContent.value.toString();
155+
} else if (extension.readmeUrl) {
156+
rawReadme = RequestContext.asText(
157+
await this.request.request({ url: extension.readmeUrl })
158+
);
159+
}
145160
const readme = this.compileReadme(rawReadme);
146161
extension.update({ readme });
147162
} catch (e) {
@@ -154,6 +169,22 @@ export class VSXExtensionsModel {
154169
});
155170
}
156171

172+
protected async findReadmeFile(extension: VSXExtension): Promise<URI | undefined> {
173+
if (!extension.plugin) {
174+
return undefined;
175+
}
176+
// Since we don't know the exact capitalization of the readme file (might be README.md, readme.md, etc.)
177+
// We attempt to find the readme file by searching through the plugin's directories
178+
const packageUri = new URI(extension.plugin.metadata.model.packageUri);
179+
const pluginUri = packageUri.withPath(packageUri.path.join('..'));
180+
const pluginDirStat = await this.fileService.resolve(pluginUri);
181+
const possibleNames = ['readme.md', 'readme.txt', 'readme'];
182+
const readmeFileUri = pluginDirStat.children
183+
?.find(child => possibleNames.includes(child.name.toLowerCase()))
184+
?.resource;
185+
return readmeFileUri;
186+
}
187+
157188
protected async initInstalled(): Promise<void> {
158189
await this.pluginSupport.willStart;
159190
this.pluginSupport.onDidChangePlugins(() => this.updateInstalled());

0 commit comments

Comments
 (0)