From 6639ea4a0ca34e259778736e5d0c4e2fc92560f4 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Sun, 9 Jul 2023 16:19:16 -0700 Subject: cache server env in .continue folder --- extension/src/activation/environmentSetup.ts | 97 +++++++++++++++++++++------- 1 file changed, 73 insertions(+), 24 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 714080e3..02118501 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -7,6 +7,7 @@ import * as fs from "fs"; import { getContinueServerUrl } from "../bridge"; import fetch from "node-fetch"; import * as vscode from "vscode"; +import * as os from "os"; import fkill from "fkill"; import { sendTelemetryEvent, TelemetryEvent } from "../telemetry"; @@ -127,8 +128,7 @@ function getActivateUpgradeCommands(pythonCmd: string, pipCmd: string) { function checkEnvExists() { const envBinPath = path.join( - getExtensionUri().fsPath, - "scripts", + serverPath(), "env", process.platform == "win32" ? "Scripts" : "bin" ); @@ -140,10 +140,32 @@ function checkEnvExists() { ); } -function checkRequirementsInstalled() { +async function checkRequirementsInstalled() { + // First, check if the requirements have been installed most recently for a later version of the extension + if (fs.existsSync(requirementsVersionPath())) { + const requirementsVersion = fs.readFileSync( + requirementsVersionPath(), + "utf8" + ); + if (requirementsVersion !== getExtensionVersion()) { + // Remove the old version of continuedev from site-packages + const [pythonCmd, pipCmd] = await getPythonPipCommands(); + const [activateCmd] = getActivateUpgradeCommands(pythonCmd, pipCmd); + const removeOldVersionCommand = [ + `cd "${serverPath()}"`, + activateCmd, + `${pipCmd} uninstall -y continuedev`, + ].join(" ; "); + const [, stderr] = await runCommand(removeOldVersionCommand); + if (stderr) { + throw new Error(stderr); + } + return false; + } + } + let envLibsPath = path.join( - getExtensionUri().fsPath, - "scripts", + serverPath(), "env", process.platform == "win32" ? "Lib" : "lib" ); @@ -165,10 +187,6 @@ function checkRequirementsInstalled() { const continuePath = path.join(envLibsPath, "continuedev"); return fs.existsSync(continuePath); - - // return fs.existsSync( - // path.join(getExtensionUri().fsPath, "scripts", ".continue_env_installed") - // ); } async function setupPythonEnv() { @@ -180,12 +198,13 @@ async function setupPythonEnv() { pipCmd ); + // First, create the virtual environment if (checkEnvExists()) { console.log("Python env already exists, skipping..."); } else { // Assemble the command to create the env const createEnvCommand = [ - `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`, + `cd "${serverPath()}"`, `${pythonCmd} -m venv env`, ].join(" ; "); @@ -216,10 +235,7 @@ async function setupPythonEnv() { console.log(msg); await vscode.window.showErrorMessage(msg); } else if (checkEnvExists()) { - console.log( - "Successfully set up python env at ", - getExtensionUri().fsPath + "/scripts/env" - ); + console.log("Successfully set up python env at ", `${serverPath()}/env`); } else { const msg = [ "Python environment not successfully created. Trying again. Here was the stdout + stderr: ", @@ -231,12 +247,13 @@ async function setupPythonEnv() { } } + // Install the requirements await retryThenFail(async () => { - if (checkRequirementsInstalled()) { + if (await checkRequirementsInstalled()) { console.log("Python requirements already installed, skipping..."); } else { const installRequirementsCommand = [ - `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`, + `cd "${serverPath()}"`, activateCmd, pipUpgradeCmd, `${pipCmd} install -r requirements.txt`, @@ -245,6 +262,8 @@ async function setupPythonEnv() { if (stderr) { throw new Error(stderr); } + // Write the version number for which requirements were installed + fs.writeFileSync(requirementsVersionPath(), getExtensionVersion()); } }); } @@ -297,9 +316,39 @@ async function checkServerRunning(serverUrl: string): Promise { } } +export function getContinueGlobalPath(): string { + // This is ~/.continue on mac/linux + const continuePath = path.join(os.homedir(), ".continue"); + if (!fs.existsSync(continuePath)) { + fs.mkdirSync(continuePath); + } + return continuePath; +} + +function setupServerPath() { + const sPath = serverPath(); + const extensionServerPath = path.join(getExtensionUri().fsPath, "server"); + const files = fs.readdirSync(extensionServerPath); + files.forEach((file) => { + const filePath = path.join(extensionServerPath, file); + fs.copyFileSync(filePath, path.join(sPath, file)); + }); +} + +function serverPath(): string { + const sPath = path.join(getContinueGlobalPath(), "server"); + if (!fs.existsSync(sPath)) { + fs.mkdirSync(sPath); + } + return sPath; +} + function serverVersionPath(): string { - const extensionPath = getExtensionUri().fsPath; - return path.join(extensionPath, "server_version.txt"); + return path.join(serverPath(), "server_version.txt"); +} + +function requirementsVersionPath(): string { + return path.join(serverPath(), "requirements_version.txt"); } function getExtensionVersion() { @@ -314,6 +363,8 @@ export async function startContinuePythonServer() { return; } + setupServerPath(); + return await retryThenFail(async () => { if (await checkServerRunning(serverUrl)) { // Kill the server if it is running an old version @@ -337,16 +388,14 @@ export async function startContinuePythonServer() { // Do this after above check so we don't have to waste time setting up the env await setupPythonEnv(); + // Spawn the server process on port 65432 const [pythonCmd] = await getPythonPipCommands(); const activateCmd = process.platform == "win32" ? ".\\env\\Scripts\\activate" : ". env/bin/activate"; - const command = `cd "${path.join( - getExtensionUri().fsPath, - "scripts" - )}" && ${activateCmd} && cd .. && ${pythonCmd} -m scripts.run_continue_server`; + const command = `cd "${serverPath()}" && ${activateCmd} && cd .. && ${pythonCmd} -m server.run_continue_server`; console.log("Starting Continue python server..."); @@ -392,8 +441,8 @@ export async function startContinuePythonServer() { } export function isPythonEnvSetup(): boolean { - let pathToEnvCfg = getExtensionUri().fsPath + "/scripts/env/pyvenv.cfg"; - return fs.existsSync(path.join(pathToEnvCfg)); + const pathToEnvCfg = path.join(serverPath(), "env", "pyvenv.cfg"); + return fs.existsSync(pathToEnvCfg); } export async function downloadPython3() { -- cgit v1.2.3-70-g09d2 From 35f447b643f76afaeff81d75408393359ff9ef67 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 11:48:43 -0700 Subject: air on the side of killing server --- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/src/activation/environmentSetup.ts | 34 +++++++++++++++------------- 3 files changed, 21 insertions(+), 19 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/package-lock.json b/extension/package-lock.json index 71f4d974..d778b097 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.147", + "version": "0.0.149", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.147", + "version": "0.0.149", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index d9f155df..56c49f27 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.147", + "version": "0.0.149", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 02118501..ff8d3158 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -366,24 +366,26 @@ export async function startContinuePythonServer() { setupServerPath(); return await retryThenFail(async () => { - if (await checkServerRunning(serverUrl)) { - // Kill the server if it is running an old version - if (fs.existsSync(serverVersionPath())) { - const serverVersion = fs.readFileSync(serverVersionPath(), "utf8"); - if (serverVersion === getExtensionVersion()) { - return; - } - } - console.log("Killing old server..."); - try { - await fkill(":65432"); - } catch (e) { - console.log( - "Failed to kill old server, likely because it didn't exist:", - e - ); + // Kill the server if it is running an old version + if (fs.existsSync(serverVersionPath())) { + const serverVersion = fs.readFileSync(serverVersionPath(), "utf8"); + if ( + serverVersion === getExtensionVersion() && + (await checkServerRunning(serverUrl)) + ) { + // The current version is already up and running, no need to continue + return; } } + console.log("Killing old server..."); + try { + await fkill(":65432"); + } catch (e) { + console.log( + "Failed to kill old server, likely because it didn't exist:", + e + ); + } // Do this after above check so we don't have to waste time setting up the env await setupPythonEnv(); -- cgit v1.2.3-70-g09d2 From 857303c78860806fb28205389cb6304cfd374111 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 12:15:35 -0700 Subject: don't override error messages with a second one --- extension/src/activation/environmentSetup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extension/src/activation') diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index ff8d3158..f5d825c9 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -22,7 +22,7 @@ async function retryThenFail( if (retries > 0) { return await retryThenFail(fn, retries - 1); } - vscode.window.showErrorMessage( + vscode.window.showInformationMessage( "Failed to set up Continue extension. Please email nate@continue.dev and we'll get this fixed ASAP!" ); sendTelemetryEvent(TelemetryEvent.ExtensionSetupError, { -- cgit v1.2.3-70-g09d2 From 655b4394507a351a76d32cbb018b448c9f7ebda4 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 12:33:02 -0700 Subject: patch --- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/src/activation/environmentSetup.ts | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/package-lock.json b/extension/package-lock.json index d778b097..c43851a2 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.149", + "version": "0.0.150", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.149", + "version": "0.0.150", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 56c49f27..e2fe6e8e 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.149", + "version": "0.0.150", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index f5d825c9..8b384e1d 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -224,6 +224,9 @@ async function setupPythonEnv() { // First, try to run the command to install python3-venv let [stdout, stderr] = await runCommand(`${pythonCmd} --version`); if (stderr) { + await vscode.window.showErrorMessage( + "Python3 is not installed. Please install from https://www.python.org/downloads, reload VS Code, and try again." + ); throw new Error(stderr); } const version = stdout.split(" ")[1].split(".")[1]; -- cgit v1.2.3-70-g09d2 From f52f108e971b590f80bbf0806f30b0ebf60e139c Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 12:43:15 -0700 Subject: fix bug uninstalling continuedev --- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/src/activation/environmentSetup.ts | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/package-lock.json b/extension/package-lock.json index c43851a2..b6147b2c 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.150", + "version": "0.0.151", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.150", + "version": "0.0.151", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index e2fe6e8e..a57f6065 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.150", + "version": "0.0.151", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 8b384e1d..881da9b5 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -156,10 +156,7 @@ async function checkRequirementsInstalled() { activateCmd, `${pipCmd} uninstall -y continuedev`, ].join(" ; "); - const [, stderr] = await runCommand(removeOldVersionCommand); - if (stderr) { - throw new Error(stderr); - } + await runCommand(removeOldVersionCommand); return false; } } -- cgit v1.2.3-70-g09d2 From 64e9877d2929f36aa2af94708620d3f2247ebebb Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 11 Jul 2023 15:14:03 -0700 Subject: check for old version of Continue, notify --- extension/src/activation/activate.ts | 22 +++++++++++++++++++++- extension/src/activation/environmentSetup.ts | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts index 18650561..2c5ba58c 100644 --- a/extension/src/activation/activate.ts +++ b/extension/src/activation/activate.ts @@ -7,9 +7,16 @@ import IdeProtocolClient from "../continueIdeClient"; import { getContinueServerUrl } from "../bridge"; import { CapturedTerminal } from "../terminal/terminalEmulator"; import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel"; -import { startContinuePythonServer } from "./environmentSetup"; +import { + getExtensionVersion, + startContinuePythonServer, +} from "./environmentSetup"; +import fetch from "node-fetch"; // import { CapturedTerminal } from "../terminal/terminalEmulator"; +const PACKAGE_JSON_RAW_GITHUB_URL = + "https://raw.githubusercontent.com/continuedev/continue/main/extension/package.json"; + export let extensionContext: vscode.ExtensionContext | undefined = undefined; export let ideProtocolClient: IdeProtocolClient; @@ -20,6 +27,19 @@ export async function activateExtension( ) { extensionContext = context; + // Before anything else, check whether this is an out-of-date version of the extension + // Do so by grabbing the package.json off of the GitHub respository for now. + fetch(PACKAGE_JSON_RAW_GITHUB_URL) + .then(async (res) => res.json()) + .then((packageJson) => { + if (packageJson.version !== getExtensionVersion()) { + vscode.window.showInformationMessage( + `You are using an out-of-date version of the Continue extension. Please update to the latest version.` + ); + } + }) + .catch((e) => console.log("Error checking for extension updates: ", e)); + await new Promise((resolve, reject) => { vscode.window.withProgress( { diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 881da9b5..c277a539 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -351,7 +351,7 @@ function requirementsVersionPath(): string { return path.join(serverPath(), "requirements_version.txt"); } -function getExtensionVersion() { +export function getExtensionVersion() { const extension = vscode.extensions.getExtension("continue.continue"); return extension?.packageJSON.version || ""; } -- cgit v1.2.3-70-g09d2 From e424831f6103c0f08d021085de106d1f6c37d327 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 12 Jul 2023 10:03:11 -0700 Subject: better onboarding --- extension/package-lock.json | 4 +- extension/package.json | 2 +- extension/react-app/src/components/Onboarding.tsx | 51 ++++++++++++++++++----- extension/src/activation/activate.ts | 2 +- 4 files changed, 45 insertions(+), 14 deletions(-) (limited to 'extension/src/activation') diff --git a/extension/package-lock.json b/extension/package-lock.json index d310643b..5d1cf395 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.153", + "version": "0.0.154", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.153", + "version": "0.0.154", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 61eee205..ab23b0b0 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.153", + "version": "0.0.154", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 1b37acc4..776ad460 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -4,6 +4,7 @@ import React, { useState, useEffect } from "react"; import styled from "styled-components"; import { ArrowLeft, ArrowRight } from "@styled-icons/heroicons-outline"; import { defaultBorderRadius } from "."; +import Loader from "./Loader"; const StyledDiv = styled.div` position: absolute; @@ -39,13 +40,9 @@ const Onboarding = () => { "Let Continue build the scaffolding of Python scripts, React components, and more", ]; - const vscMediaUrl = useSelector( - (state: RootStore) => state.config.vscMediaUrl - ); - useEffect(() => { const hasVisited = localStorage.getItem("hasVisited"); - if (hasVisited) { + if (hasVisited && false) { setCounter(4); } else { setCounter(0); @@ -53,6 +50,12 @@ const Onboarding = () => { } }, []); + const [loading, setLoading] = useState(true); + + useEffect(() => { + setLoading(true); + }, [counter]); + return (