From 3d0170de198701320a14acd637448c0f7cb4de43 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Mon, 27 Jun 2022 10:59:53 +0300 Subject: [PATCH 1/2] #284 Optimization of VC UTBot Quickstart wizard - support CMake-generated version - `disabled` and `checked` attribute support for Unix/MS HTML render - added client/server version verification at `Handshake` call - deep refactoring `.css` files - remove `Test server` button and make the mandatory job in background - remove useless class `WizardHTMLBuilder` - fix CMake parameter editor --- server/CMakeLists.txt | 1 + server/proto/testgen.proto | 6 +- server/src/Server.cpp | 9 +- server/src/Server.h | 4 +- server/src/Version.h | 3 +- server/src/utils/StringFormat.h | 2 +- vscode-plugin/media/vscode.css | 31 +- vscode-plugin/media/wizard.css | 95 ++----- vscode-plugin/media/wizard.html | 246 ++++++++++------ vscode-plugin/media/wizard.js | 264 +++++++++++------- vscode-plugin/src/client/client.ts | 12 +- .../src/client/clientEventsEmitter.ts | 4 +- vscode-plugin/src/config/defaultValues.ts | 43 ++- vscode-plugin/src/config/prefs.ts | 8 +- vscode-plugin/src/utils/grpcServicePing.ts | 27 +- vscode-plugin/src/wizard/wizard.ts | 162 ++++++++--- vscode-plugin/src/wizard/wizardHtmlBuilder.ts | 72 ----- 17 files changed, 568 insertions(+), 421 deletions(-) delete mode 100644 vscode-plugin/src/wizard/wizardHtmlBuilder.ts diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index e804fe22a..4a31bbbf9 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -25,6 +25,7 @@ message("Organisation: ${PROJECT_ORG}") message("Homepage: ${CMAKE_PROJECT_HOMEPAGE_URL}") message("Version: ${CMAKE_PROJECT_VERSION}") message("Run from: ${RUN_INFO}") +include_directories(${PROJECT_BINARY_BIN}) configure_file(config.h.in config.h @ONLY) diff --git a/server/proto/testgen.proto b/server/proto/testgen.proto index b44fbda52..89f14cda6 100644 --- a/server/proto/testgen.proto +++ b/server/proto/testgen.proto @@ -6,7 +6,7 @@ import "util.proto"; import "google/protobuf/duration.proto"; service TestsGenService { - rpc Handshake(DummyRequest) returns(DummyResponse) {} + rpc Handshake(VersionInfo) returns(VersionInfo) {} rpc Heartbeat(DummyRequest) returns(HeartbeatResponse) {} @@ -59,6 +59,10 @@ message DummyRequest {} message DummyResponse {} +message VersionInfo { + string version = 1; +} + message RegisterClientRequest { string clientId = 1; } diff --git a/server/src/Server.cpp b/server/src/Server.cpp index ca914c294..00717c3d0 100644 --- a/server/src/Server.cpp +++ b/server/src/Server.cpp @@ -40,7 +40,7 @@ const std::string Server::logPrefix = "logTo"; const std::string Server::gtestLogPrefix = "gtestLogTo"; void Server::run(uint16_t customPort) { - LOG_S(INFO) << "UnitTestBot Server, build " << UTBOT_BUILD_NUMBER; + LOG_S(INFO) << "UnitTestBot Server, build " << UTBOT_BUILD_VERSION; LOG_S(INFO) << "Logs directory: " << Paths::logPath; LOG_S(INFO) << "Latest log path: " << Paths::getUtbotLogAllFilePath(); LOG_S(INFO) << "Tmp directory path: " << Paths::tmpPath; @@ -157,9 +157,10 @@ Status Server::TestsGenServiceImpl::GeneratePredicateTests(ServerContext *contex } Status Server::TestsGenServiceImpl::Handshake(ServerContext *context, - const DummyRequest *request, - DummyResponse *response) { - LOG_S(INFO) << "Handshake complete"; + const VersionInfo *request, + VersionInfo *response) { + LOG_S(INFO) << "Handshake complete. Client version: " << request->version(); + response->set_version(UTBOT_BUILD_VERSION); return Status::OK; } diff --git a/server/src/Server.h b/server/src/Server.h index c7f43583a..121f79194 100644 --- a/server/src/Server.h +++ b/server/src/Server.h @@ -65,8 +65,8 @@ class Server { explicit TestsGenServiceImpl(bool testMode); Status Handshake(ServerContext *context, - const DummyRequest *request, - DummyResponse *response) override; + const VersionInfo *request, + VersionInfo *response) override; Status OpenLogChannel(ServerContext *context, const LogChannelRequest *request, diff --git a/server/src/Version.h b/server/src/Version.h index a20721894..ef8c51a20 100644 --- a/server/src/Version.h +++ b/server/src/Version.h @@ -1,6 +1,7 @@ #ifndef UNITTESTBOT_VERSION_H #define UNITTESTBOT_VERSION_H -#define UTBOT_BUILD_NUMBER "DEVBUILD" +#include "config.h" //CMake generated +#define UTBOT_BUILD_VERSION PROJECT_VERSION #endif //UNITTESTBOT_VERSION_H diff --git a/server/src/utils/StringFormat.h b/server/src/utils/StringFormat.h index 64d448b3e..4b083a022 100644 --- a/server/src/utils/StringFormat.h +++ b/server/src/utils/StringFormat.h @@ -38,7 +38,7 @@ namespace StringUtils { } formatBuffer.resize(std::max(formatBuffer.size(), size)); snprintf(formatBuffer.data(), size, format.c_str(), internal::extractCString(std::forward(args))...); - return std::string(formatBuffer.begin(), formatBuffer.begin() + size - 1); // We don't want the '\0' inside + return {formatBuffer.begin(), formatBuffer.begin() + size - 1}; // We don't want the '\0' inside } } diff --git a/vscode-plugin/media/vscode.css b/vscode-plugin/media/vscode.css index 0d13c3841..69d2c1bc7 100644 --- a/vscode-plugin/media/vscode.css +++ b/vscode-plugin/media/vscode.css @@ -73,34 +73,39 @@ button.secondary:hover { background: var(--vscode-button-secondaryHoverBackground); } -button:disabled, -button[disabled] { - color: var(--vscode-debugIcon-breakpointDisabledForeground); - background: var(--vscode-button-secondaryBackground); -} -button:disabled:hover, -button:hover[disabled] { - cursor: default; -} - - input:not([type='checkbox']), textarea { display: block; width: 100%; border: none; + outline-style: solid; + outline-width: thin; + outline-color: var(--vscode-input-border); font-family: var(--vscode-font-family); padding: var(--input-padding-vertical) var(--input-padding-horizontal); color: var(--vscode-input-foreground); - outline-color: var(--vscode-input-border); background-color: var(--vscode-input-background); } input::placeholder, textarea::placeholder { - color: var(--vscode-input-placeholderForeground); + color: var(--vscode-input-placeholderForeground, #cccccc); } label { font-family: var(--vscode-font-family); } + +input[type = "*"]:disabled, +input[disabled] { + color: var(--vscode-disabledForeground); + background: var(--vscode-disabledBackground); + cursor: default; +} + +button:disabled, +button[disabled] { + color: var(--vscode-debugIcon-breakpointDisabledForeground); + background: var(--vscode-button-secondaryBackground); + cursor: default; +} diff --git a/vscode-plugin/media/wizard.css b/vscode-plugin/media/wizard.css index 740c87118..9512ccd10 100644 --- a/vscode-plugin/media/wizard.css +++ b/vscode-plugin/media/wizard.css @@ -1,11 +1,7 @@ -:root { - --custom-shaded-backgroud: rgba(0, 0, 0, 0.3); -} - .utbot-form { background-color: var(--vscode-welcomePage-background); - margin: 150px auto; - margin-top: 75px; + margin: auto auto; + margin-top: 15px; vertical-align: middle; padding: 40px; width: 70%; @@ -16,6 +12,7 @@ /* Hide all steps by default: */ .utbot-form__tab { display: none; + min-height: 280px; } .utbot-form__tab.active { @@ -32,17 +29,26 @@ height: 10px; width: 10px; margin: 0 2px; - /* background-color: #bbbbbb; */ + background-color: var(--vscode-titleBar-activeForeground); + /* background-color: #bbbbbb; */ border: none; border-radius: 50%; display: inline-block; - opacity: 0.5; + + opacity: 50%; } /* Mark the active step: */ .utbot-form__steps_step.active { - opacity: 1; + opacity: 100%; +} + +.utbot-form__tab_label { + text-align: right; + margin-top: 10px; + margin-right: 15px; + float:left; } .utbot-form__tab_input { @@ -50,25 +56,22 @@ } .utbot-form__tab_item { - margin-top: 15px; - margin-bottom: 15px; -} - -.utbot-form__tab_connection_test-button { - max-width: 30%; - display: inline-block; + margin-top: 5px; + margin-bottom: 5px; } /* By default turn off connection status */ -.utbot-form__tab_connection_loader, -.utbot-form__tab_connection_success, -.utbot-form__tab_connection_failure { +#connection_loader, +#connection_success, +#connection_warning, +#connection_failure { display: none; } -.utbot-form__tab_connection_loader.active, -.utbot-form__tab_connection_success.active, -.utbot-form__tab_connection_failure.active { +#connection_loader.active, +#connection_success.active, +#connection_warning.active, +#connection_failure.active { display: inline-block; } @@ -76,10 +79,6 @@ background-color: var(--vscode-editorInfo-foreground); } -.utbot-form__tab_input { - box-sizing: border-box; -} - .utbot-form__navigation { display: flex; flex-direction: row; @@ -117,44 +116,6 @@ margin-right: 0; } -.utbot-form__tab { - min-height: 190px; -} - -/** Connection loader **/ -.utbot-form__tab_connection_loader.active { - top: 5px; - position: relative; - height: 100%; -} - -.utbot-form__tab_connection_loader.active:after { - content: " "; - display: block; - border-radius: 50%; - width: 0; - height: 0; - margin: 0px; - box-sizing: border-box; - border: 10px solid #fff; - border-color: #fff transparent #fff transparent; - animation: lds-hourglass 1.2s infinite; -} - -@keyframes lds-hourglass { - 0% { - transform: rotate(0); - animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); - } - 50% { - transform: rotate(900deg); - animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); - } - 100% { - transform: rotate(1800deg); - } -} - .utbot-modal { position: fixed; top: 0; @@ -162,7 +123,7 @@ display: flex; align-items: center; justify-content: center; - height: 0vh; + height: 0; overflow: hidden; transition: background-color 0.25s ease; z-index: 9999; @@ -283,7 +244,7 @@ background: var(--vscode-diffEditor-diagonalFill); } -.utbot-modal__close-button::before, +.utbot-modal__close-button::before, .utbot-modal__close-button::after { content: ""; position: absolute; @@ -311,7 +272,7 @@ transform: rotate(-45deg); } -.utbot-modal__close-button.thick::before, +.utbot-modal__close-button.thick::before, .utbot-modal__close-button.thick::after { height: 4px; margin-top: -2px; diff --git a/vscode-plugin/media/wizard.html b/vscode-plugin/media/wizard.html index 7c5e77d93..e1da37a91 100644 --- a/vscode-plugin/media/wizard.html +++ b/vscode-plugin/media/wizard.html @@ -3,130 +3,196 @@ - UTBot: Quickstart - - + + - + UTBot: Quickstart - -
-
-
- - -
-

- UTBot failed to establish connection with specified server. - If you wish to continue anyway, press "Continue" button. -

-

In any case, you will need to specify correct port and host of UTBot server to use the extension. - You can do it via Visual Studio Code Settings.

-
-
- -
+
+
+ + +
+

+ UTBot failed to establish connection with specified server. + If you wish to continue anyway, press "Continue" button. +

+

In any case, you will need to specify correct port and host of UTBot server to use the extension. + You can do it via Visual Studio Code Settings.

+
+
+ + -
-
-
+ onclick="closeModalAndGoToNextStep();this.blur();">Continue + + + +

UTBot: Quickstart

-
-

👋Welcome to "UTBot: Quickstart" Wizard!

+

👋 Welcome to "UTBot: Quickstart" Wizard!

UTBot discovered that this is the first time you use it with this project. - The Wizard will help you to configure the extension appropriatly. - In case you don't wish to proceed, you can close this wizard at any time.

-

In order to learn more about UTBot C/C++, please, refer to this manual.

+ The Wizard will help you to configure the extension appropriatly. + In case you don't wish to proceed, you can close this wizard at any time.

+

In order to learn more about UTBot C/C++, please, refer to this + manual.

-

🖥️Server Installation

-

If you are working on remote machine you can start UTBot Server installation - right from here. Otherwise, please do it manually.

-

In order to learn more about UTBot Server Installation process, please, refer to the installation manual.

+
🖥️ Server Installation
+
+ If you are working on remote machine you can start UTBot Server installation + right from here. Otherwise, please do it manually.
+ In order to learn more about UTBot Server Installation process, please, refer to the + installation manual. +
-
Please, continue the process in the opened terminal below. When you are finished, return here.
+ class="utbot-form__tab_installer_button" + id="runInstallerBtn" + onclick="this.blur();runInstallator();">Install + +
Please, continue the process in the opened terminal below. + When you are finished, return here. +
-
-

📶Connection

-

Fill the parameters below accordingly to the ones specified during the - UTBot Server installation.

- -
- - +
+

🖥️ Server Setup

+
+ +
+
-
- - + + 📶 Connection + + ⏳ Connecting... + ✔️Successfully pinged server! + + ❌ Failed to establish connection! + + +
+ Fill the parameters below accordingly to the ones specified during the + UTBot Server installation. + Please make sure that in case of remote host the SFTP plugin + has a consistent host.
- -
- - -
-
✔️ Succesfully pinged server!
-
❌ Failed to establish connection!
+
+ +
-
+
+ + +
+
-
-

📁Remote Path

-

Remote path configuration specifies the path to the project on a remote host.

- - + + 📁 Project Path On Server + + + + + + + +
+ Project path on server specifies the path to the project on a server host. + On the remote server the path need to be synchronized with the project path on the client (local) by + SFTP plugin. + Please make sure that the SFTP plugin has a consistent remotePath. + The localhost server don't need the synchronization. +
+
+ + +
-

🏗️Build Directory

-

Relative path to the build directory. Files compile_commands.json and link_commands.json should be located in this directory.

- - -

🎌CMake Options

-

Options passed to CMake command.

- - +

📑️ Project Setup

+
🏗️ Build Directory
+
Relative path to the build directory. Files compile_commands.json and link_commands.json should be located + in this directory. +
+
+ + +
+
+
🎌 CMake Options
+
Options passed to CMake command.
+
+ + +
-

🎉Success!

-

UTBot extension was successfully configured, and now you are ready to use all its functionality.

-

If you want to learn more about UTBot C/C++ or you have ay questions related to its usage, please, refer to this - manual.

-

+

🎉Success!
+
+ UTBot extension was successfully configured, and now you are ready to use all its functionality.
+ If you want to learn more about UTBot C/C++ or you have ay questions related to its usage, please, + refer to this + manual. +
- + + onclick="nextButtonHandler();this.blur();">Next +
@@ -135,10 +201,8 @@

🎉Success!

-
- - + diff --git a/vscode-plugin/media/wizard.js b/vscode-plugin/media/wizard.js index 270fe0438..375c2441f 100644 --- a/vscode-plugin/media/wizard.js +++ b/vscode-plugin/media/wizard.js @@ -1,56 +1,88 @@ window.addEventListener('message', event => { - const message = event.data; // The JSON data our extension sent - switch (message.command) { - case 'test_server_ping_success': - showConnectionSuccessStatus(); + case 'test_connection_success': + showConnectionSuccessStatus(message.clientVersion, message.serverVersion); break; - case 'test_server_ping_failure': + case 'test_connection_failure': showConnectionFailureStatus(); break; - case 'check_server_ping_success': - showConnectionSuccessStatus(); + case 'check_connection_success': + showConnectionSuccessStatus(message.clientVersion, message.serverVersion); nextStep(); break; - case 'check_server_ping_failure': + case 'check_connection_failure': showConnectionFailureStatus(); openModal(); - break; default: - console.log(`ERROR: Unkown message: ${message.command}`); + console.log(`ERROR: Unknown message: ${message.command}`); + break; } }); +function $(id) { + return document.getElementById(id); +} + +/* + * Communication with VSCode via API + */ +const vscode = acquireVsCodeApi(); +function DbgMessage(message) { + // vscode.postMessage({ + // command: 'dbg_message', + // message: message + // }); +} + const os = getVarValue("os"); console.log(`OS Platform: ${os}`); -if (os === 'win32') { - removeElementByClassName('installer-tab'); - removeElementByClassName('installer-step'); +let nonLocalGRPCPort = getVarValue("defaultPort"); +let nonLocalHost = getVarValue("sftpHost"); +let nonLocalRemoteDir = getVarValue("sftpDir"); +let currentTabIndex = 0; + +function onStart() { + DbgMessage("OnStart"); + const hostInput = $('hostInput'); + const portInput = $('portInput'); + const mappingInput = $('mappingInput'); + if (hostInput.value === "localhost" + && portInput.value === getVarValue("defaultPort") + && mappingInput.value === getVarValue("projectDir")) { + $('useLocalHost').checked = true; + hostInput.disabled = true; + portInput.disabled = true; + mappingInput.disabled = true; + } + if (os === 'win32') { + removeElementByClassName('installer-tab'); + removeElementByClassName('installer-step'); + } + showTab(currentTabIndex); } -let currentTabIndex = 0; -showTab(currentTabIndex); +onStart(); function showTab(tabIndex) { - const prevButton = document.getElementById("prevBtn"); - const nextButton = document.getElementById("nextBtn"); + const prevButton = $("prevBtn"); + const nextButton = $("nextBtn"); const tabElements = document.getElementsByClassName("utbot-form__tab"); const currentTabElement = tabElements[tabIndex]; currentTabElement.classList.add('active'); - // Show previous button if neccesary - if (tabIndex == 0) { + // Show previous button if necessary + if (tabIndex === 0) { prevButton.classList.remove('active'); } else { prevButton.classList.add('active'); } // Set nextButton title according to tab number - if (tabIndex == tabElements.length - 1) { + if (tabIndex === tabElements.length - 1) { nextButton.innerHTML = "Finish"; } else { nextButton.innerHTML = "Next"; @@ -58,17 +90,53 @@ function showTab(tabIndex) { fixStepIndicator(tabIndex); } -function nextButtonHandler() { +let checkHostTimer = null; +function showProgress(toShow) { + showElement($("connection_loader"), toShow); + if (toShow) { + showElement($("connection_success"), false); + showElement($("connection_warning"), false); + showElement($("connection_failure"), false); + } +} + +function showElement(el, toShow) { + if (toShow) { + el.classList.add('active'); + } + else { + el.classList.remove('active'); + } +} + +function restartCheckingConnection() { + if (checkHostTimer != null) { + clearTimeout(checkHostTimer); + checkHostTimer = null; + showProgress(false); + } + checkHostTimer = setTimeout(testConnection, 250, false); + showProgress(true); +} + +function isConnectionTab() { const tab = document.getElementsByClassName("connection-tab"); if (!tab || tab.length !== 1) { console.log("Something is wrong: connection-tab"); return; } - isConnectionTabActive = tab[0].classList.contains("active"); - if (isConnectionTabActive) { - checkConnectionImplicitly(); - } else { + return tab[0].classList.contains("active"); +} + +function nextButtonHandler() { + if (isConnectionTab()) { + testConnection(true); + } + else { nextStep(); + if (isConnectionTab()) { + testConnection(false); + } } } @@ -84,44 +152,42 @@ function prevStep() { return nextPrev(-1); } -function showConnectionSuccessStatus() { - const connectionLoader = document.getElementsByClassName("utbot-form__tab_connection_loader")[0]; - const connectionSuccess = document.getElementsByClassName("utbot-form__tab_connection_success")[0]; - const connectionFailure = document.getElementsByClassName("utbot-form__tab_connection_failure")[0]; - - connectionSuccess.classList.add('active'); - connectionLoader.classList.remove('active'); - connectionFailure.classList.remove('active'); +function showConnectionSuccessStatus(clientVersion, serverVersion) { + showProgress(false); + if (clientVersion !== serverVersion) { + const connectionWarning = $("connection_warning"); + connectionWarning.innerText = + connectionWarning.getAttribute("format").toString() + + " " + + `Server: ${serverVersion}, Client: ${clientVersion}`; + showElement($("connection_success"), false); + showElement(connectionWarning, true); + } + else { + showElement($("connection_success"), true); + showElement($("connection_warning"), false); + } + showElement($("connection_failure"), false); } function showConnectionFailureStatus() { - const connectionLoader = document.getElementsByClassName("utbot-form__tab_connection_loader")[0]; - const connectionSuccess = document.getElementsByClassName("utbot-form__tab_connection_success")[0]; - const connectionFailure = document.getElementsByClassName("utbot-form__tab_connection_failure")[0]; - - connectionFailure.classList.add('active'); - connectionLoader.classList.remove('active'); - connectionSuccess.classList.remove('active'); + showProgress(false); + showElement($("connection_success"), false); + showElement($("connection_warning"), false); + showElement($("connection_failure"), true); } function showConnectionLoadingStatus() { - const connectionLoader = document.getElementsByClassName("utbot-form__tab_connection_loader")[0]; - const connectionSuccess = document.getElementsByClassName("utbot-form__tab_connection_success")[0]; - const connectionFailure = document.getElementsByClassName("utbot-form__tab_connection_failure")[0]; - - connectionLoader.classList.add('active'); - connectionFailure.classList.remove('active'); - connectionSuccess.classList.remove('active'); + showProgress(true); } - function nextPrev(tabShift) { if (tabShift !== 1 && tabShift !== -1) { return false; } let tabElements = document.getElementsByClassName("utbot-form__tab"); let currentTabElement = tabElements[currentTabIndex]; - if (tabShift == 1 && !validateForm()) { + if (tabShift === 1 && !validateForm()) { return false; } let actionToPerform = currentTabElement.getAttribute("vs-message-callback"); @@ -147,10 +213,10 @@ function validateForm() { let tabInputs = tabElements[currentTabIndex].getElementsByTagName("input"); for (let i = 0; i < tabInputs.length; i++) { let tabInput = tabInputs[i]; - if (tabInput.value == "") { + if (tabInput.value === "") { tabInput.value = tabInput.placeholder; } - if (tabInput.value == "" || !tabInput.checkValidity()) { + if (tabInput.value === "" || !tabInput.checkValidity()) { // TODO: custom validators tabInput.classList.add("invalid"); valid = false; @@ -197,7 +263,7 @@ function closeModalAndGoToNextStep() { } function restoreOriginalStateOfSomeElements() { - const button = document.getElementById("runInstallerBtn"); + const button = $("runInstallerBtn"); const messageBlock = document.getElementsByClassName("utbot-form__tab_installer_message")[0] if (button !== undefined && button !== null) { button.disabled = false; @@ -205,10 +271,10 @@ function restoreOriginalStateOfSomeElements() { if (messageBlock !== undefined && messageBlock !== null) { messageBlock.classList.remove("active"); } - } function getVarValue(name) { + DbgMessage("var = " + document.getElementsByClassName("utbot-vars")[0].getAttribute(name)); return document.getElementsByClassName("utbot-vars")[0].getAttribute(name); } @@ -222,32 +288,48 @@ function removeElementByClassName(className) { } } -/* - * Communication with VSCode via API - */ -const vscode = acquireVsCodeApi(); +function setupLocalHost() { + const mappingInput = $('mappingInput'); + const hostInput = $('hostInput'); + const portInput = $('portInput'); + const useLocalhost = $('useLocalHost').checked; + if (useLocalhost) { + DbgMessage("Local host is used!"); -function sendPortAndHost() { - const hostInputElement = document.getElementById('hostInput'); - const portInputElement = document.getElementById('portInput'); - vscode.postMessage({ - command: 'set_host_and_port', - host: hostInputElement.value, - port: parseInt(portInputElement.value) - }); + nonLocalHost = hostInput.value; + hostInput.value = "localhost"; + + nonLocalGRPCPort = portInput.value; + portInput.value = getVarValue("defaultPort"); + + nonLocalRemoteDir = mappingInput.value; + mappingInput.value = getVarValue("projectDir"); + } + else { + DbgMessage("Local host is not used!"); + hostInput.value = nonLocalHost; + portInput.value = nonLocalGRPCPort; + mappingInput.value = nonLocalRemoteDir; + } + mappingInput.disabled= useLocalhost; + hostInput.disabled = useLocalhost; + portInput.disabled = useLocalhost; + + restartCheckingConnection(); } -function sendMappingPath() { - const mappingInputElement = document.getElementById('mappingInput'); +function sendServerSetup() { vscode.postMessage({ - command: 'set_mapping_path', - mappingPath: mappingInputElement.value + command: 'set_server_setup', + host: $('hostInput').value, + port: parseInt($('portInput').value), + mappingPath: $('mappingInput').value, }); } function sendBuildInfo() { - const buildDirInputElement = document.getElementById('buildDirectory'); - const cmakeOptionsInputElement = document.getElementById('cmakeOptions'); + const buildDirInputElement = $('buildDirectory'); + const cmakeOptionsInputElement = $('cmakeOptions'); vscode.postMessage({ command: 'set_build_info', buildDirectory: buildDirInputElement.value, @@ -256,14 +338,14 @@ function sendBuildInfo() { } /** - * Request to test the connection explicitly (on button click). + * Request to test the connection with host */ -function testConnection() { - const hostInputElement = document.getElementById('hostInput'); - const portInputElement = document.getElementById('portInput'); - showConnectionLoadingStatus(); +function testConnection(withNextContinuation) { + const hostInputElement = $('hostInput'); + const portInputElement = $('portInput'); + showProgress(true); vscode.postMessage({ - command: 'test_connection', + command: (withNextContinuation ? 'check_connection' : 'test_connection'), host: hostInputElement.value, port: parseInt(portInputElement.value) }); @@ -272,30 +354,24 @@ function testConnection() { /** * Request to run installation script. */ -function runInstallator() { - const button = document.getElementById("runInstallerBtn"); +function runInstaller() { + const button = $("runInstallerBtn"); const messageBlock = document.getElementsByClassName("utbot-form__tab_installer_message")[0] button.disabled = true; messageBlock.classList.add("active"); vscode.postMessage({ - command: 'run_installator' - }); -} - -/** - * Request to check the connection before proceeding to the next step. - */ -function checkConnectionImplicitly() { - const hostInputElement = document.getElementById('hostInput'); - const portInputElement = document.getElementById('portInput'); - showConnectionLoadingStatus(); - vscode.postMessage({ - command: 'check_connection', - host: hostInputElement.value, - port: parseInt(portInputElement.value) + command: 'run_installer' }); } function closeWizard() { vscode.postMessage({ command: 'close_wizard' }); } + +function openSFTPSettings(paramKey) { + DbgMessage("openSFTPSettings"); + vscode.postMessage({ + command: 'openSFTPSettings', + key: paramKey + }); +} \ No newline at end of file diff --git a/vscode-plugin/src/client/client.ts b/vscode-plugin/src/client/client.ts index 871559da2..7bec9ac1a 100644 --- a/vscode-plugin/src/client/client.ts +++ b/vscode-plugin/src/client/client.ts @@ -30,7 +30,8 @@ import { TestFilter, TestsResponse, FileTargetsRequest, - ProjectTargetsRequest + ProjectTargetsRequest, + VersionInfo } from '../proto-ts/testgen_pb'; import { SourceCode, SourceInfo, ValidationType } from '../proto-ts/util_pb'; import { RequestCoverageAndResultParams, RequestTestsParams } from '../requests/params'; @@ -149,8 +150,8 @@ export class Client { }); this.events.onDidHandshakeSuccessEventEmitter.on(response => { - logger.info(`Handshake successfull`); - logger.debug(`Handshake successfull response: ${response}`); + logger.info(`Handshake successful`); + logger.debug(`Handshake successful response: ${response}`); }); } @@ -349,7 +350,8 @@ export class Client { } async makeHandshakeRequest(): Promise { - const dummyRequest = new DummyRequest(); + const versionInfo = new VersionInfo(); + versionInfo.setVersion("Client"); let resolved = false; logger.info(`Sending handshake request`); setTimeout(() => { @@ -358,7 +360,7 @@ export class Client { } }, this.DEFAULT_TIMEOUT); return new Promise((resolve, reject) => { - this.testsService.handshake(dummyRequest, async (err, response) => { + this.testsService.handshake(versionInfo, async (err, response) => { if (err) { await this.events.onDidHandshakeFailureEventEmitter.fire(err.message); reject(err); diff --git a/vscode-plugin/src/client/clientEventsEmitter.ts b/vscode-plugin/src/client/clientEventsEmitter.ts index af0a9d59b..1e6f73ebb 100644 --- a/vscode-plugin/src/client/clientEventsEmitter.ts +++ b/vscode-plugin/src/client/clientEventsEmitter.ts @@ -1,4 +1,4 @@ -import { DummyResponse, HeartbeatResponse } from "../proto-ts/testgen_pb"; +import {HeartbeatResponse, VersionInfo} from "../proto-ts/testgen_pb"; import { UTBotEventEmitter } from "../emitter/UTBotEventEmitter"; type ErrorMessage = string; @@ -23,7 +23,7 @@ export class ClientEventsEmitter { readonly onDidHeartbeatSuccessEventEmitter: UTBotEventEmitter = new UTBotEventEmitter(); - readonly onDidHandshakeSuccessEventEmitter: UTBotEventEmitter = + readonly onDidHandshakeSuccessEventEmitter: UTBotEventEmitter = new UTBotEventEmitter(); readonly onDidHandshakeFailureEventEmitter: UTBotEventEmitter = diff --git a/vscode-plugin/src/config/defaultValues.ts b/vscode-plugin/src/config/defaultValues.ts index b09ef1bde..c819bf96a 100644 --- a/vscode-plugin/src/config/defaultValues.ts +++ b/vscode-plugin/src/config/defaultValues.ts @@ -4,9 +4,10 @@ import * as vsUtils from '../utils/vscodeUtils'; import { Prefs } from './prefs'; import * as pathUtils from '../utils/pathUtils'; import { isIP } from 'net'; +import {isWin32} from "../utils/utils"; export class DefaultConfigValues { - public static readonly DEFAULT_HOST = "127.0.0.1"; + public static readonly DEFAULT_HOST = "localhost"; public static readonly DEFAULT_PORT = 2121; public static readonly POSSIBLE_BUILD_DIR_NAMES = ['out', 'build']; @@ -14,11 +15,26 @@ export class DefaultConfigValues { public static readonly DEFAULT_CMAKE_OPTIONS = ['-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', '-DCMAKE_EXPORT_LINK_COMMANDS=ON']; + public static toWSLPathOnWindows(path: string): string { + if (!isWin32()) { + return path; + } + return path + .replace(/^(\w):|\\+/g,'/$1') + .replace(/^\//g,'/mnt/'); + } + + public static hasConfiguredRemotePath(): boolean { + return Prefs.getRemotePath().length !== 0; + } + public static getDefaultHost(): string { let host = Prefs.getGlobalHost(); - const sftHost = vsUtils.getFromSftpConfig("host"); - if (sftHost && isIP(sftHost)) { - host = sftHost; + if (!DefaultConfigValues.hasConfiguredRemotePath()) { + const sftHost = vsUtils.getFromSftpConfig("host"); + if (sftHost && isIP(sftHost)) { + host = sftHost; + } } return host; } @@ -28,14 +44,17 @@ export class DefaultConfigValues { } public static getDefaultRemotePath(): string { - let remotePath = ""; - if (Prefs.isRemoteScenario()) { - const sftpRemotePath = vsUtils.getFromSftpConfig("remotePath"); - if (sftpRemotePath) { - remotePath = sftpRemotePath; + let remotePath = Prefs.getRemotePath(); + if (remotePath.length === 0) { + if (DefaultConfigValues.getDefaultHost() === vsUtils.getFromSftpConfig("host")) { + // if `host` is the same as SFTP host, inherit the remote path from SFTP plugin + const sftpRemotePath = vsUtils.getFromSftpConfig("remotePath"); + if (sftpRemotePath) { + remotePath = sftpRemotePath; + } + } else { + remotePath = DefaultConfigValues.toWSLPathOnWindows(vsUtils.getProjectDirByOpenedFile().fsPath); } - } else { - remotePath = vsUtils.getProjectDirByOpenedFile().fsPath; } return remotePath; } @@ -50,7 +69,7 @@ export class DefaultConfigValues { await vs.workspace.fs.readDirectory(vs.Uri.parse(rootPath)) .then(resultArray => { resultArray.forEach(([name, type]) => { - // add only non hidden directories and not a build directory by default + // add only non-hidden directories and not a build directory by default if (type === vs.FileType.Directory && DefaultConfigValues.looksLikeBuildDirectory(name)) { buildDirName = name; diff --git a/vscode-plugin/src/config/prefs.ts b/vscode-plugin/src/config/prefs.ts index a5b5da599..8c22a378b 100644 --- a/vscode-plugin/src/config/prefs.ts +++ b/vscode-plugin/src/config/prefs.ts @@ -43,9 +43,13 @@ export class Prefs { public static SHOW_TEST_RESULTS_PREF = 'unittestbot.visual.showTestResults'; - public static isRemoteScenario(): boolean { + public static isLocalHost(): boolean { const host = Prefs.getAsset(Prefs.HOST_PREF); - return !(host === '127.0.0.1' || host === 'localhost') || isWin32(); + return host === '127.0.0.1' || host === 'localhost'; + } + + public static isRemoteScenario(): boolean { + return !this.isLocalHost() || isWin32(); } /** diff --git a/vscode-plugin/src/utils/grpcServicePing.ts b/vscode-plugin/src/utils/grpcServicePing.ts index 80b981137..719fdef9e 100644 --- a/vscode-plugin/src/utils/grpcServicePing.ts +++ b/vscode-plugin/src/utils/grpcServicePing.ts @@ -1,39 +1,42 @@ import { ExtensionLogger } from '../logger'; import { ITestsGenServiceClient } from '../proto-ts/testgen_grpc_pb'; -import { DummyRequest } from '../proto-ts/testgen_pb'; +import { VersionInfo } from '../proto-ts/testgen_pb'; const { logger } = ExtensionLogger; export class GrpcServicePing { - constructor(public readonly service: ITestsGenServiceClient) {} + constructor( + public readonly clientVersion: string, + public readonly service: ITestsGenServiceClient) {} /** * Returns true if server responds in a given time (milliseconds). */ - public async ping(timeout: number): Promise { - let responded = true; + public async ping(timeout: number): Promise { + let responded = null; await Promise.race([ this.pingInner(), this.timeoutPromise(timeout) ]) - .then(_value => { - responded = true; + .then(serverVer => { + logger.error(`Server version: ${serverVer}`); + responded = serverVer; }) .catch(err => { logger.error(`Server failed to respond: ${err}`); - responded = false; }); return responded; } - private async pingInner(): Promise { - const dummyRequest = new DummyRequest(); - return new Promise((resolve, reject) => { - this.service.handshake(dummyRequest, (err, _response) => { + private async pingInner(): Promise { + const versionInfo = new VersionInfo(); + versionInfo.setVersion(this.clientVersion); + return new Promise((resolve, reject) => { + this.service.handshake(versionInfo, (err, _response) => { if (err) { reject(`Error: ${err}`); } else { - resolve(); + resolve(_response.getVersion()); } }); }); diff --git a/vscode-plugin/src/wizard/wizard.ts b/vscode-plugin/src/wizard/wizard.ts index c9efa92ab..30d4e9c9f 100644 --- a/vscode-plugin/src/wizard/wizard.ts +++ b/vscode-plugin/src/wizard/wizard.ts @@ -1,23 +1,36 @@ import * as grpc from 'grpc'; import * as os from 'os'; import * as vs from 'vscode'; +import {Uri} from 'vscode'; import * as defcfg from '../config/defaultValues'; import * as messages from '../config/notificationMessages'; -import { Prefs } from '../config/prefs'; -import { ExtensionLogger } from '../logger'; -import { TestsGenServiceClient } from '../proto-ts/testgen_grpc_pb'; -import { GrpcServicePing } from '../utils/grpcServicePing'; +import {Prefs} from '../config/prefs'; +import {ExtensionLogger} from '../logger'; +import {TestsGenServiceClient} from '../proto-ts/testgen_grpc_pb'; +import {GrpcServicePing} from '../utils/grpcServicePing'; import * as pathUtils from '../utils/pathUtils'; -import { WizardEventsEmitter } from './wizardEventsEmitter'; -import { WizardHtmlBuilder } from './wizardHtmlBuilder'; +import {WizardEventsEmitter} from './wizardEventsEmitter'; +import * as fs from "fs"; +import * as vsUtils from "../utils/vscodeUtils"; + const { logger } = ExtensionLogger; +function getNonce(): string { + let text = ''; + const possible = 'abcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 10; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} + export class UtbotWizardPanel { public static currentPanel: UtbotWizardPanel | undefined; private disposables: vs.Disposable[] = []; private static PING_TIMEOUT_MS = 5000; private static events = WizardEventsEmitter.getWizardEventsEmitter(); + private static checkNonInitializedVars = /[{][{][a-zA-Z]+[}][}]/g; public static createOrShow(context: vs.ExtensionContext): void { const column = vs.window.activeTextEditor @@ -56,41 +69,57 @@ export class UtbotWizardPanel { this.panel.webview.onDidReceiveMessage( async message => { switch (message.command) { - case 'run_installator': + case 'openSFTPSettings': + if (message.key !== undefined) { + const keyName = message.key; + //await vs.commands.executeCommand('workbench.action.openSettings', 'Natizyskunk.sftp.remotePath'); + await vs.commands.getCommands(true).then( + async (commands: string[]) => { + if (commands.includes("sftp.config")) { + await vs.commands.executeCommand("sftp.config").then( + async () => { + // TODO: positioning at keyname/value line + // await vs.commands.executeCommand('actions.find', `${keyName}`).then( + // () => messages.showErrorMessage(`query: @${keyName}`) + // ); + } + ); + } else { + messages.showErrorMessage("SFTP plugin isn't installed!"); + } + } + ); + } + break; + case 'run_installer': this.runInstallationScript(); break; - case 'set_host_and_port': + case 'set_server_setup': await Prefs.setHost(message.host); await Prefs.setPort(message.port); - break; - case 'set_mapping_path': await Prefs.setRemotePath(message.mappingPath); break; case 'set_build_info': await Prefs.setBuildDirectory(message.buildDirectory); await Prefs.setCmakeOptions(message.cmakeOptions); break; - case 'test_connection': - this.pingAction( - message.host, - message.port, - 'test_server_ping_success', - 'test_server_ping_failure' - ); - break; case 'check_connection': + case 'test_connection': this.pingAction( message.host, message.port, - 'check_server_ping_success', - 'check_server_ping_failure' - ); + message.command + '_success', + message.command + '_failure'); break; case 'close_wizard': this.panel.dispose(); break; + case 'dbg_message': + logger.info(`dbg_message: ${message.message}`); + break; default: messages.showErrorMessage(`Unknown message (${message.command}) from WizardWebView: ${message}`); + break; } }, null, @@ -105,22 +134,38 @@ export class UtbotWizardPanel { terminal.sendText(onDiskPath.fsPath, true); } + private lastRequest: Promise | null = null; private pingAction(host: string, port: number, successCmd: string, failureCmd: string): void { const servicePing = new GrpcServicePing( + this.context.extension.packageJSON.version, new TestsGenServiceClient( `${host}:${port}`, grpc.credentials.createInsecure() ) ); - servicePing.ping(UtbotWizardPanel.PING_TIMEOUT_MS).then(async pinged => { - if (pinged) { - await this.panel.webview.postMessage({ command: successCmd }); + + const capturedPingPromiseForLambda = servicePing.ping(UtbotWizardPanel.PING_TIMEOUT_MS); + this.lastRequest = capturedPingPromiseForLambda; + capturedPingPromiseForLambda.then(async serverVer => { + if (this.lastRequest !== capturedPingPromiseForLambda) { + // ignore: there is more actual request + return; + } + if (serverVer !== null) { + await this.panel.webview.postMessage({ + command: successCmd, + clientVersion: this.context.extension.packageJSON.version, + serverVersion: (serverVer.length === 0 + ? "undefined" + : serverVer)}); } else { await this.panel.webview.postMessage({ command: failureCmd }); } }).catch(async err => { logger.error(`Error! ${err}`); - await this.panel.webview.postMessage({ command: failureCmd }); + if (this.lastRequest === capturedPingPromiseForLambda) { + await this.panel.webview.postMessage({command: failureCmd}); + } }); return; } @@ -168,26 +213,59 @@ export class UtbotWizardPanel { }; } - private async getHtmlForWebview(webview: vs.Webview): Promise { - const stylesUri = webview.asWebviewUri(vs.Uri.joinPath(this.context.extensionUri, 'media', 'wizard.css')); - const vscodeUri = webview.asWebviewUri(vs.Uri.joinPath(this.context.extensionUri, 'media', 'vscode.css')); - const scriptUri = webview.asWebviewUri(vs.Uri.joinPath(this.context.extensionUri, 'media', 'wizard.js')); - const htmlUri = vs.Uri.joinPath(this.context.extensionUri, 'media', 'wizard.html'); + + const extUri = this.context.extensionUri; + function mediaPath(fileName: string): Uri { + return webview.asWebviewUri(vs.Uri.joinPath(extUri, 'media', fileName)); + } const predictedBuildDirectory = await defcfg.DefaultConfigValues.getDefaultBuildDirectoryPath(); + const initVars: {param: string; value: string|undefined}[] = [ + // UI javascript + {param: 'scriptUri', value: mediaPath('wizard.js').toString()}, + + // Security (switched off) + //{param: 'wvscriptUri', value: webview.cspSource}, + //{param: 'nonce', value: getNonce()}, // Use a nonce to only allow a specific script to be run. - const htmlBuilder = new WizardHtmlBuilder(htmlUri); - return htmlBuilder - .setVSCodeStyleUri(vscodeUri) - .setCustomStyleUri(stylesUri) - .setScriptUri(scriptUri) - .setPredictedHost(defcfg.DefaultConfigValues.getDefaultHost()) - .setPredictedPort(defcfg.DefaultConfigValues.getDefaultPort()) - .setPredictedRemotePath(defcfg.DefaultConfigValues.getDefaultRemotePath()) - .setPredictedBuildDirectory(predictedBuildDirectory) - .setPlatform(os.platform()) - .setCmakeOptions(defcfg.DefaultConfigValues.DEFAULT_CMAKE_OPTIONS) - .build(); + // CSS in header + {param: 'vscodeUri', value: mediaPath('vscode.css').toString()}, + {param: 'stylesUri', value: mediaPath('wizard.css').toString()}, + + // vars + {param: 'os', value: os.platform()}, + {param: 'projectDir', value: defcfg.DefaultConfigValues.toWSLPathOnWindows(vsUtils.getProjectDirByOpenedFile().fsPath)}, + {param: 'defaultPort', value: defcfg.DefaultConfigValues.DEFAULT_PORT.toString()}, + {param: 'sftpHost', value: vsUtils.getFromSftpConfig("host")}, + {param: 'sftpDir', value: vsUtils.getFromSftpConfig("remotePath")}, + + // connection tab + {param: 'predictedHost', value: defcfg.DefaultConfigValues.getDefaultHost()}, + {param: 'predictedPort', value: Prefs.getGlobalPort()}, + {param: 'predictedRemotePath', value: defcfg.DefaultConfigValues.getDefaultRemotePath()}, + + // project tab + {param: 'predictedBuildDirectory', value:predictedBuildDirectory}, + {param: 'cmakeOptions', value: defcfg.DefaultConfigValues.DEFAULT_CMAKE_OPTIONS.join("\n")}, + ]; + + let content = fs.readFileSync(mediaPath('wizard.html').fsPath, 'utf8'); + for (const p2v of initVars) { + logger.info(`map ${p2v.param} -> ${p2v.value}`); + // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // @ts-ignore + content = content.replaceAll(`{{${p2v.param}}}`, + `${p2v.value === undefined + ? '' + : p2v.value}`); + } + + const uninitVars = UtbotWizardPanel.checkNonInitializedVars.exec(content); + if (uninitVars !== null) { + logger.error(`Error! Wizard has non-initialized variable ${uninitVars[0]}.`); + throw new Error(`Wizard has non-initialized variable ${uninitVars[0]}.`); + } + return content; } } diff --git a/vscode-plugin/src/wizard/wizardHtmlBuilder.ts b/vscode-plugin/src/wizard/wizardHtmlBuilder.ts deleted file mode 100644 index 058dac19e..000000000 --- a/vscode-plugin/src/wizard/wizardHtmlBuilder.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as fs from "fs"; -import * as vs from "vscode"; - -export class WizardHtmlBuilder { - - private content: string; - - constructor(htmlUri: vs.Uri) { - this.content = fs.readFileSync(htmlUri.fsPath, 'utf8'); - } - - public build(): string { - return this.content; - } - - public setVSCodeStyleUri(vscodeStylesUri: vs.Uri): WizardHtmlBuilder { - return this.setVSCodeStylePath(`${vscodeStylesUri}`); - } - - public setVSCodeStylePath(vscodeStylesPath: string): WizardHtmlBuilder { - this.content = this.content.replace('{{vscodeUri}}', vscodeStylesPath); - return this; - } - - public setCustomStyleUri(stylesUri: vs.Uri): WizardHtmlBuilder { - return this.setCustomStylePath(`${stylesUri}`); - } - - public setCustomStylePath(stylesPath: string): WizardHtmlBuilder { - this.content = this.content.replace('{{stylesUri}}', stylesPath); - return this; - } - - public setScriptUri(scriptUri: vs.Uri): WizardHtmlBuilder { - return this.setScriptPath(`${scriptUri}`); - } - - public setScriptPath(scriptPath: string): WizardHtmlBuilder { - this.content = this.content.replace('{{scriptUri}}', scriptPath); - return this; - } - - public setPredictedHost(predictedHost: string): WizardHtmlBuilder { - this.content = this.content.replace('{{predictedHost}}', predictedHost); - return this; - } - - public setPredictedPort(predictedPort: number): WizardHtmlBuilder { - this.content = this.content.replace('{{predictedPort}}', `${predictedPort}`); - return this; - } - - public setPredictedRemotePath(predictedRemotePath: string): WizardHtmlBuilder { - this.content = this.content.replace('{{predictedRemotePath}}', predictedRemotePath); - return this; - } - - public setPredictedBuildDirectory(predictedBuildDirectory: string): WizardHtmlBuilder { - this.content = this.content.replace('{{predictedBuildDirectory}}', predictedBuildDirectory); - return this; - } - - public setPlatform(platform: string): WizardHtmlBuilder { - this.content = this.content.replace('{{os}}', platform); - return this; - } - public setCmakeOptions(cmakeOptions: Array): WizardHtmlBuilder { - this.content = this.content.replace('{{cmakeOptions}}', cmakeOptions.join("\n")); - return this; - } - -} From 3a93096232737f35f5214d348026fd4474065f7f Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Thu, 30 Jun 2022 09:56:36 +0300 Subject: [PATCH 2/2] #284 Optimization of VC UTBot Quickstart wizard - fix `isRemoteScenario` for local-remote scenario (remote root != project path) --- vscode-plugin/media/wizard.html | 12 ++++++------ vscode-plugin/media/wizard.js | 10 +++++----- vscode-plugin/src/config/prefs.ts | 3 ++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/vscode-plugin/media/wizard.html b/vscode-plugin/media/wizard.html index e1da37a91..7e7a0f72c 100644 --- a/vscode-plugin/media/wizard.html +++ b/vscode-plugin/media/wizard.html @@ -77,19 +77,19 @@

👋 Welcome to "UTBot: Quickstart" Wizard!

-

🖥️ Server Setup

+

🖥️ Server Setup

- +

- 📶 Connection + 📶 Connection ⏳ Connecting... - ✔️Successfully pinged server! - + ✔️ Successfully pinged server! + ❌ Failed to establish connection! @@ -173,7 +173,7 @@

📑️ Project Setup

-
🎉Success!
+
🎉 Success!
UTBot extension was successfully configured, and now you are ready to use all its functionality.
If you want to learn more about UTBot C/C++ or you have ay questions related to its usage, please, diff --git a/vscode-plugin/media/wizard.js b/vscode-plugin/media/wizard.js index 375c2441f..78429a81c 100644 --- a/vscode-plugin/media/wizard.js +++ b/vscode-plugin/media/wizard.js @@ -30,10 +30,10 @@ function $(id) { */ const vscode = acquireVsCodeApi(); function DbgMessage(message) { - // vscode.postMessage({ - // command: 'dbg_message', - // message: message - // }); + vscode.postMessage({ + command: 'dbg_message', + message: message + }); } const os = getVarValue("os"); @@ -288,7 +288,7 @@ function removeElementByClassName(className) { } } -function setupLocalHost() { +function handleOnOffDefaultConfigurationOnLocalhost() { const mappingInput = $('mappingInput'); const hostInput = $('hostInput'); const portInput = $('portInput'); diff --git a/vscode-plugin/src/config/prefs.ts b/vscode-plugin/src/config/prefs.ts index 8c22a378b..b3fed36e0 100644 --- a/vscode-plugin/src/config/prefs.ts +++ b/vscode-plugin/src/config/prefs.ts @@ -49,7 +49,8 @@ export class Prefs { } public static isRemoteScenario(): boolean { - return !this.isLocalHost() || isWin32(); + return !(this.isLocalHost() && this.getRemotePath() === vsUtils.getProjectDirByOpenedFile().fsPath) + || isWin32(); } /**