Skip to content

Commit

Permalink
Merge pull request #1309 from posit-dev/sagerb-home-view-set-config-o…
Browse files Browse the repository at this point in the history
…n-deployment-selection

Set config on deployment selection within Home View
  • Loading branch information
sagerb authored Apr 9, 2024
2 parents b4c197d + 65d8ff0 commit bb3928b
Show file tree
Hide file tree
Showing 4 changed files with 490 additions and 24 deletions.
61 changes: 48 additions & 13 deletions extensions/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "posit.publisher.init-project",
"title": "Initialize Project",
"icon": "${star)",
"category": "Posit Publisher"
},
{
"command": "posit.publisher.init-project.refresh",
"title": "Refresh Project Initialization",
"icon": "${refresh)",
"category": "Posit Publisher"
},
{
"command": "posit.publisher.configurations.refresh",
"title": "Refresh Configurations",
Expand Down Expand Up @@ -292,6 +304,10 @@
}
],
"commandPalette": [
{
"command": "posit.publisher.init-project",
"when": "workbenchState == folder && posit.publish.missing && posit.publish.state == 'initialized'"
},
{
"command": "posit.publisher.configurations.refresh",
"when": "!posit.publish.missing && posit.publish.state == 'initialized'"
Expand Down Expand Up @@ -367,6 +383,10 @@
{
"command": "posit.publisher.homeView.refresh",
"when": "!posit.publish.missing && posit.publish.state == 'initialized'"
},
{
"command": "posit.publisher.init-project.refresh",
"when": "false"
}
]
},
Expand Down Expand Up @@ -400,50 +420,50 @@
"name": "Home",
"contextualTitle": "Publisher",
"icon": "$(symbol-file)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded'"
},
{
"id": "posit.publisher.files",
"name": "Deployment Files",
"contextualTitle": "Publisher",
"icon": "$(symbol-file)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publisher.homeView.deploymentActiveMode == 'basic-mode'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publisher.homeView.deploymentActiveMode == 'basic-mode'"
},
{
"id": "posit.publisher.requirements",
"name": "Requirements",
"contextualTitle": "Publisher",
"icon": "$(package)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publisher.homeView.deploymentActiveMode == 'basic-mode'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publisher.homeView.deploymentActiveMode == 'basic-mode'"
},
{
"id": "posit.publisher.configurations",
"name": "Configurations",
"contextualTitle": "Publisher",
"icon": "$(gear)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
},
{
"id": "posit.publisher.credentials",
"name": "Credentials",
"contextualTitle": "Publisher",
"icon": "$(key)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
},
{
"id": "posit.publisher.deployments",
"name": "Deployments",
"contextualTitle": "Publisher",
"icon": "$(cloud-upload)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publisher.homeView.deploymentActiveMode == 'advanced-mode'"
},
{
"id": "posit.publisher.helpAndFeedback",
"name": "Help And Feedback",
"contextualTitle": "Publisher",
"icon": "$(info)",
"visibility": "collapsed",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded'"
}
],
"posit-publisher-logs": [
Expand All @@ -452,7 +472,7 @@
"name": "Logs",
"contextualTitle": "Logs",
"icon": "$(output)",
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized'"
"when": "workbenchState == folder && !posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.credentialCheck == 'succeeded'"
}
]
},
Expand All @@ -477,25 +497,40 @@
"contents": "Posit Publisher currently uses credentials managed by the following utilities:\n- [RSConnect](https://github.com/rstudio/rsconnect) (R Package)\n- [RSConnect-Python](https://github.com/rstudio/rsconnect-python) (Python utility).\n\nUse one of these utilities to define a credential to your server, then return and click the refresh button\n[Refresh](command:posit.publisher.credentials.refresh)",
"when": "posit.publisher.credentials.isEmpty == empty"
},
{
"view": "posit.publisher.project",
"contents": "Checking for pre-requisites...",
"when": "posit.publish.initialization.credentialCheck == 'inProgress'"
},
{
"view": "posit.publisher.project",
"contents": "Use of Posit Publisher requires that you create at least one account credential using [RSConnect](https://github.com/rstudio/rsconnect) (R Package) or [RSConnect-Python](https://github.com/rstudio/rsconnect-python) (Python utility).\n\nUse one of these utilities to define a credential to your server, then return and click the refresh button\n[Refresh](command:posit.publisher.init-project.refresh)",
"when": "posit.publish.initialization.credentialCheck == 'failed'"
},
{
"view": "posit.publisher.project",
"contents": "In order to deploy using Posit Publisher, you can open a folder initialized as a Posit project or initialize a new project.\n[Open Folder](command:vscode.openFolder)",
"when": "workbenchState == empty"
"when": "workbenchState == empty && posit.publish.initialization.credentialCheck == 'succeeded'"
},
{
"view": "posit.publisher.project",
"contents": "Posit Publisher currently only supports single folder workspaces, open a folder initialized as a Posit project or initialize a new project.\n[Open Folder](command:vscode.openFolder)",
"when": "workbenchState == workspace"
"when": "workbenchState == workspace && posit.publish.initialization.credentialCheck == 'succeeded'"
},
{
"view": "posit.publisher.project",
"contents": "Scanning folder for a Posit project...",
"when": "workbenchState == folder && posit.publish.state == 'uninitialized'"
"when": "workbenchState == folder && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publish.state == 'uninitialized'"
},
{
"view": "posit.publisher.project",
"contents": "Initialization of the Posit Publishing VSCode Extension is required for this project.\nThis initialization involves adding a Posit Publisher subdirectory within your workspace folder and creating two files within it.\n Click the Initialize Project button below to create:\n- a new subdirectory called .posit/publish\n- a default deployment file (Untitled-1.toml)\n- a default configuration file (default.toml)\n[Initialize Project](command:posit.publisher.init-project)",
"when": "workbenchState == folder && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.inProgress === 'false'"
},
{
"view": "posit.publisher.project",
"contents": "Before deploying using Posit Publisher, you need to initialize your project by creating a deployment configuration.\n[Initialize Project](command:posit.publisher.configurations.add)",
"when": "workbenchState == folder && posit.publish.missing && posit.publish.state == 'initialized'"
"contents": "Project Initialization in progress...\n\nPlease answer the prompts at the top of the VSCode window.",
"when": "workbenchState == folder && posit.publish.initialization.credentialCheck == 'succeeded' && posit.publish.missing && posit.publish.state == 'initialized' && posit.publish.initialization.inProgress === 'true'"
}
]
},
Expand Down
63 changes: 62 additions & 1 deletion extensions/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import * as vscode from "vscode";

import * as ports from "./ports";
import api from "./api";
import { Service } from "./services";
import { ProjectTreeDataProvider } from "./views/project";
import { DeploymentsTreeDataProvider } from "./views/deployments";
Expand All @@ -16,7 +17,9 @@ import { HelpAndFeedbackTreeDataProvider } from "./views/helpAndFeedback";
import { LogsTreeDataProvider } from "./views/logs";
import { EventStream } from "./events";
import { HomeViewProvider } from "./views/homeView";
import { commands } from "vscode";
import { commands, window } from "vscode";
import { initWorkspaceWithFixedNames } from "./multiStepInputs/initWorkspace";
import { getSummaryStringFromError } from "./utils/errors";

const STATE_CONTEXT = "posit.publish.state";
const MISSING_CONTEXT = "posit.publish.missing";
Expand All @@ -26,6 +29,21 @@ enum PositPublishState {
uninitialized = "uninitialized",
}

const INITIALIZING_CONTEXT = "posit.publish.initialization.inProgress";
const INIT_PROJECT_COMMAND = "posit.publisher.init-project";
enum InitializationInProgress {
true = "true",
false = "false",
}

const CREDENTIAL_CHECK = "posit.publish.initialization.credentialCheck";
const REFRESH_INIT_PROJECT_COMMAND = "posit.publisher.init-project.refresh";
enum PositPublishCredentialCheck {
inProgress = "inProgress",
failed = "failed",
succeeded = "succeeded",
}

// Once the extension is activate, hang on to the service so that we can stop it on deactivation.
let service: Service;

Expand All @@ -46,6 +64,24 @@ async function isMissingPublishDirs(
}
}

async function checkForCredentials(apiReady: Promise<boolean>) {
await apiReady;
try {
const response = await api.accounts.getAll();
if (response.data.length) {
setCredentialCheckContext(PositPublishCredentialCheck.succeeded);
} else {
setCredentialCheckContext(PositPublishCredentialCheck.failed);
}
} catch (error: unknown) {
const summary = getSummaryStringFromError(
"extension::checkForCredentials",
error,
);
window.showInformationMessage(summary);
}
}

function setMissingContext(context: boolean) {
vscode.commands.executeCommand("setContext", MISSING_CONTEXT, context);
}
Expand All @@ -54,10 +90,20 @@ function setStateContext(context: PositPublishState) {
vscode.commands.executeCommand("setContext", STATE_CONTEXT, context);
}

function setInitializationInProgressContext(context: InitializationInProgress) {
vscode.commands.executeCommand("setContext", INITIALIZING_CONTEXT, context);
}

function setCredentialCheckContext(context: PositPublishCredentialCheck) {
vscode.commands.executeCommand("setContext", CREDENTIAL_CHECK, context);
}

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export async function activate(context: vscode.ExtensionContext) {
setStateContext(PositPublishState.uninitialized);
setCredentialCheckContext(PositPublishCredentialCheck.inProgress);
setInitializationInProgressContext(InitializationInProgress.false);

if (
vscode.workspace.workspaceFolders &&
Expand Down Expand Up @@ -97,6 +143,7 @@ export async function activate(context: vscode.ExtensionContext) {

service = new Service(context, port);
const apiReady = service.isUp();
checkForCredentials(apiReady);

new ProjectTreeDataProvider().register(context);
new DeploymentsTreeDataProvider(stream, apiReady).register(context);
Expand All @@ -110,6 +157,20 @@ export async function activate(context: vscode.ExtensionContext) {

await service.start();

context.subscriptions.push(
commands.registerCommand(INIT_PROJECT_COMMAND, async () => {
setInitializationInProgressContext(InitializationInProgress.true);
await initWorkspaceWithFixedNames();
setInitializationInProgressContext(InitializationInProgress.false);
}),
);

context.subscriptions.push(
commands.registerCommand(REFRESH_INIT_PROJECT_COMMAND, () =>
checkForCredentials(apiReady),
),
);

setStateContext(PositPublishState.initialized);
}

Expand Down
Loading

0 comments on commit bb3928b

Please sign in to comment.