Skip to content

Commit

Permalink
Add createProject command (#1286)
Browse files Browse the repository at this point in the history
  • Loading branch information
billti authored Mar 21, 2024
1 parent 60af2bc commit eb5dc1b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 0 deletions.
11 changes: 11 additions & 0 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@
"command": "qsharp-vscode.workspacePythonCode",
"when": "view == quantum-workspaces && viewItem == workspace"
}
],
"explorer/context": [
{
"command": "qsharp-vscode.createProject",
"when": "explorerResourceIsFolder"
}
]
},
"views": {
Expand All @@ -236,6 +242,11 @@
}
],
"commands": [
{
"command": "qsharp-vscode.createProject",
"title": "Create Q# project",
"category": "Q#"
},
{
"command": "qsharp-vscode.webOpener",
"title": "Internal web opener",
Expand Down
66 changes: 66 additions & 0 deletions vscode/src/createProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import * as vscode from "vscode";
import { log, samples } from "qsharp-lang";
import { EventType, sendTelemetryEvent } from "./telemetry";

export async function initProjectCreator(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand(
"qsharp-vscode.createProject",
async (folderUri: vscode.Uri | undefined) => {
sendTelemetryEvent(EventType.CreateProject, {}, {});

if (!folderUri) {
// This was run from the command palette, not the context menu, so create the project
// in the root of an open workspace folder.
const workspaceCount = vscode.workspace.workspaceFolders?.length || 0;
if (workspaceCount === 0) {
// No workspaces open
vscode.window.showErrorMessage(
"You must have a folder open to create a Q# project in",
);
return;
} else if (workspaceCount === 1) {
folderUri = vscode.workspace.workspaceFolders![0].uri;
} else {
const workspaceChoice = await vscode.window.showWorkspaceFolderPick(
{ placeHolder: "Pick the workspace folder for the project" },
);
if (!workspaceChoice) return;
folderUri = workspaceChoice.uri;
}
}

const edit = new vscode.WorkspaceEdit();
const projUri = vscode.Uri.joinPath(folderUri, "qsharp.json");
const mainUri = vscode.Uri.joinPath(folderUri, "src", "Main.qs");

const sample = samples.find((elem) => elem.title === "Minimal");
if (!sample) {
// Should never happen.
log.error("Unable to find the Minimal sample");
return;
}

edit.createFile(projUri);
edit.createFile(mainUri);

edit.set(projUri, [
new vscode.TextEdit(new vscode.Range(0, 0, 0, 0), "{}"),
]);
edit.set(mainUri, [
new vscode.TextEdit(new vscode.Range(0, 0, 0, 0), sample.code),
]);

// This doesn't throw on failure, it just returns false
if (!(await vscode.workspace.applyEdit(edit))) {
vscode.window.showErrorMessage(
"Unable to create the project. Check the project files don't already exist and that the file system is writable",
);
}
},
),
);
}
2 changes: 2 additions & 0 deletions vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
sendTelemetryEvent,
} from "./telemetry.js";
import { registerWebViewCommands } from "./webviewPanel.js";
import { initProjectCreator } from "./createProject.js";

export async function activate(
context: vscode.ExtensionContext,
Expand Down Expand Up @@ -88,6 +89,7 @@ export async function activate(
registerCreateNotebookCommand(context);
registerWebViewCommands(context);
initFileSystem(context);
initProjectCreator(context);

log.info("Q# extension activated.");

Expand Down
6 changes: 6 additions & 0 deletions vscode/src/memfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ export class MemFS implements vscode.FileSystemProvider {
newUri: vscode.Uri,
options: { overwrite: boolean },
): void {
log.debug(`rename: ${oldUri.path} to ${newUri.path}`);

if (!options.overwrite && this._lookup(newUri, true)) {
throw vscode.FileSystemError.FileExists(newUri);
}
Expand All @@ -280,6 +282,8 @@ export class MemFS implements vscode.FileSystemProvider {
}

delete(uri: vscode.Uri): void {
log.debug(`delete: ${uri.path}`);

const dirName = uri.with({ path: dirname(uri.path) });
const baseName = basename(uri.path);
const parent = this._lookupAsDirectory(dirName, false);
Expand All @@ -296,6 +300,8 @@ export class MemFS implements vscode.FileSystemProvider {
}

createDirectory(uri: vscode.Uri): void {
log.debug(`createDirectory: ${uri.path}`);

const baseName = basename(uri.path);
const dirName = uri.with({ path: dirname(uri.path) });
const parent = this._lookupAsDirectory(dirName, false);
Expand Down
5 changes: 5 additions & 0 deletions vscode/src/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export enum EventType {
HistogramEnd = "Qsharp.HistogramEnd",
FormatStart = "Qsharp.FormatStart",
FormatEnd = "Qsharp.FormatEnd",
CreateProject = "Qsharp.CreateProject",
}

type Empty = { [K in any]: never };
Expand Down Expand Up @@ -216,6 +217,10 @@ type EventTypes = {
properties: { associationId: string };
measurements: { timeToCompleteMs: number; numberOfEdits: number };
};
[EventType.CreateProject]: {
properties: Empty;
measurements: Empty;
};
};

export enum QsharpDocumentType {
Expand Down

0 comments on commit eb5dc1b

Please sign in to comment.