Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,11 @@
"command": "swift.generateSourcekitConfiguration",
"title": "Generate SourceKit-LSP Configuration",
"category": "Swift"
},
{
"command": "swift.createDocumentationCatalog",
"title": "Create Documentation Catalog",
"category": "Swift"
}
],
"configuration": [
Expand Down
5 changes: 5 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { WorkspaceContext } from "./WorkspaceContext";
import { attachDebugger } from "./commands/attachDebugger";
import { cleanBuild, debugBuild, runBuild } from "./commands/build";
import { captureDiagnostics } from "./commands/captureDiagnostics";
import { createDocumentationCatalog } from "./commands/createDocumentationCatalog";
import { createNewProject } from "./commands/createNewProject";
import { editDependency } from "./commands/dependencies/edit";
import { resolveDependencies } from "./commands/dependencies/resolve";
Expand Down Expand Up @@ -350,6 +351,10 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(packagePath));
}),
vscode.commands.registerCommand("swift.openDocumentation", () => openDocumentation()),
vscode.commands.registerCommand(
"swift.createDocumentationCatalog",
async () => await createDocumentationCatalog()
),
vscode.commands.registerCommand(
Commands.GENERATE_SOURCEKIT_CONFIG,
async () => await generateSourcekitConfiguration(ctx)
Expand Down
40 changes: 40 additions & 0 deletions src/commands/createDocumentationCatalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as fs from "fs";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Missing copyright header.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably use fs/promises not fs so that you don't need to use all the synchronous methods below. Most cases we want to use asynchronous for file operations

import * as path from "path";
import * as vscode from "vscode";

export async function createDocumentationCatalog(): Promise<void> {
const folders = vscode.workspace.workspaceFolders;
if (!folders || folders.length === 0) {
await vscode.window.showErrorMessage("Open a workspace first.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: This error message is a bit vague. Can we change it to something like Creating a documentation catalog requires that a folder or workspace be opened?

suggestion: We can also make it less likely for this situation to occur by only showing swift.createDocumentationCatalog in the command palette if a workspace is present. See the other commands with when clauses in the package.json for examples.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also you don't want to await if not waiting for input. Error messages don't go away until cleared. In this case use void instead of await

return;
}

const moduleName = await vscode.window.showInputBox({
prompt: "Enter Swift module name",
placeHolder: "MyModule",
validateInput: value =>
value.trim().length === 0 ? "Module name cannot be empty" : undefined,
});

if (!moduleName) {
return; // user cancelled
}

const rootPath = folders[0].uri.fsPath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: We can't assume there will only be a single workspace folder. The command should guide the user through creating a catalog in any workspace folder they wish to use.

const doccDir = path.join(rootPath, `${moduleName}.docc`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: We can't assume that the user will only place a catalog at the root of the workspace. Documentation catalogs can be located anywhere in the project structure. However, they are most commonly placed within targets from the Package.swift to provide documentation for them. I would show a quick pick with the available targets and an option at the end for creating a standalone documentation catalog.

const markdownFile = path.join(doccDir, `${moduleName}.md`);

if (fs.existsSync(doccDir)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: We can show this error in the input and not allow continuing instead of forcing the user to restart the whole command. See the create new project command for an example of this.

await vscode.window.showErrorMessage(
`Documentation catalog "${moduleName}.docc" already exists.`
);
return;
}

fs.mkdirSync(doccDir, { recursive: true });
fs.writeFileSync(markdownFile, `# ${moduleName}\n`, { encoding: "utf8" });

await vscode.window.showInformationMessage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await => void

`Created DocC documentation catalog: ${moduleName}.docc`
);
}