Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation for existing setup path #1228

Merged
merged 12 commits into from
Aug 5, 2024
46 changes: 43 additions & 3 deletions src/setup/SetupPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ import { createPyReqs } from "./pyReqsInstallStep";
import { downloadIdfTools } from "./toolsDownloadStep";
import { installIdfGit, installIdfPython } from "./embedGitPy";
import { getOpenOcdRules } from "./addOpenOcdRules";
import { checkSpacesInPath, getEspIdfFromCMake } from "../utils";
import {
checkSpacesInPath,
getEspIdfFromCMake,
canAccessFile,
execChildProcess,
compareVersion,
} from "../utils";
import { useIdfSetupSettings } from "./setupValidation/espIdfSetup";
import { clearPreviousIdfSetups } from "./existingIdfSetups";

Expand Down Expand Up @@ -325,6 +331,40 @@ export class SetupPanel {
case "exploreComponents":
await commands.executeCommand("esp.component-manager.ui.show");
break;
case "canAccessFile":
if (message.path) {
const pathIdfPy = path.join(message.path, "tools", "idf.py");
const fileExists = await canAccessFile(pathIdfPy);
if (!fileExists) {
this.panel.webview.postMessage({
command: "canAccessFileResponse",
path: message.path,
exists: fileExists,
});
} else {
let versionEspIdf;
if (
message.currentVersion &&
typeof message.currentVersion === "string"
) {
versionEspIdf = message.currentVersion;
} else {
versionEspIdf = await getEspIdfFromCMake(message.path);
}
// compareVersion returns a negative value if versionEspIdf is less than "5.0"
const noWhiteSpaceSupport =
compareVersion(versionEspIdf, "5.0") < 0;
const hasWhitespace = /\s/.test(message.path);
this.panel.webview.postMessage({
command: "canAccessFileResponse",
path: message.path,
exists: fileExists,
noWhiteSpaceSupport,
hasWhitespace,
});
}
}
break;
default:
break;
}
Expand All @@ -334,7 +374,8 @@ export class SetupPanel {
}

setupErrHandler(error: Error) {
const errMsg = error && error.message ? error.message : "Error during ESP-IDF setup";
const errMsg =
error && error.message ? error.message : "Error during ESP-IDF setup";
if (
errMsg.indexOf("ERROR_EXISTING_ESP_IDF") !== -1 ||
errMsg.indexOf("IDF_PATH_WITH_SPACES") !== -1 ||
Expand Down Expand Up @@ -443,7 +484,6 @@ export class SetupPanel {
? espIdfPath
: idfContainerPath;
this.checkSpacesInPaths(toolsPath);

if (idfPathToCheck === toolsPath) {
const idfPathSameIdfToolsPathMsg = `IDF_PATH and IDF_TOOLS_PATH can't be the same. Please use another location. (ERROR_SAME_IDF_PATH_AND__IDF_TOOLS_PATH)`;
throw new Error(idfPathSameIdfToolsPathMsg);
Expand Down
45 changes: 30 additions & 15 deletions src/views/setup/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,22 @@ function goTo(route: string, setupMode: SetupMode) {
<div class="centerize notification" v-if="hasPrerequisites">
<div class="control centerize home-title">
<h1 class="title is-spaced">Welcome.</h1>
<p v-if="platform !== 'win32'">
Make sure that
<a
href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/macos-setup.html"
v-if="platform === 'darwin'"
>ESP-IDF Prerequisites for MacOS</a
>
<a
href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-setup.html"
v-if="platform === 'linux'"
>ESP-IDF Prerequisites for Linux</a
>
</p>
<p>are installed before choosing the setup mode.</p>
<div v-if="platform !== 'win32'" class="prerequisites-info">
<p>Make sure that</p>
<p>
<a
href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/macos-setup.html"
v-if="platform === 'darwin'"
>ESP-IDF Prerequisites for MacOS</a
>
<a
href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-setup.html"
v-if="platform === 'linux'"
>ESP-IDF Prerequisites for Linux</a
>
</p>
<p>are installed before choosing the setup mode.</p>
</div>
<h2 class="subtitle">Choose a setup mode.</h2>
<selectSaveScope />
</div>
Expand Down Expand Up @@ -172,5 +174,18 @@ function goTo(route: string, setupMode: SetupMode) {
div.notification.is-danger {
background-color: var(--vscode-editorGutter-deletedBackground);
}

.prerequisites-info {
text-align: center;
margin: 1em 0;

p {
margin: 0.5em 0;
}

a {
font-weight: bold;
}
}
</style>
./types
./types
17 changes: 15 additions & 2 deletions src/views/setup/Install.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,26 @@
import { storeToRefs } from "pinia";
import { useSetupStore } from "./store";
import { SetupMode } from "./types";
import { computed, watchEffect } from "vue";
import { computed, watchEffect, onMounted, onUnmounted } from "vue";
import folderOpen from "./components/folderOpen.vue";
import selectEspIdf from "./components/selectEspIdf.vue";
import selectPyVersion from "./components/selectPyVersion.vue";
import { IconClose } from "@iconify-prerendered/vue-codicon";

const store = useSetupStore();

onMounted(() => {
if (store.espIdf) {
store.validateEspIdfPath(store.espIdf);
} else if (store.espIdfContainer) {
store.validateEspIdfPath(store.espIdfContainer);
}
});

onUnmounted(() => {
store.setIdfPathError("");
});

const {
espIdfErrorStatus,
gitVersion,
Expand All @@ -20,6 +32,7 @@ const {
selectedEspIdfVersion,
espIdf,
espIdfContainer,
isInstallButtonDisabled,
} = storeToRefs(store);

const isNotWinPlatform = computed(() => {
Expand Down Expand Up @@ -149,7 +162,7 @@ function setToolsFolder(newToolsPath: string) {
@click="store.installEspIdf"
class="button"
data-config-id="start-install-btn"
:disabled="isInstallDisabled"
:disabled="isInstallDisabled || store.isInstallButtonDisabled"
>
{{ actionButtonText }}
</button>
Expand Down
26 changes: 21 additions & 5 deletions src/views/setup/components/folderOpen.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
<script setup lang="ts">
import { IconFolder, IconFolderOpened } from "@iconify-prerendered/vue-codicon";
import { computed } from "vue";
import { defineProps, defineEmits } from "vue";
import { useSetupStore } from "../store";

let folderIcon = "folder";
const store = useSetupStore();
const props = defineProps<{
keyEnterMethod?: () => void;
onChangeMethod?: () => void;
openMethod: () => void;
openMethod: () => Promise<string | undefined>;
propLabel: string;
propModel: string;
propMutate: (val: string) => void;
staticText?: string;
}>();

const store = useSetupStore();
const emit = defineEmits(["blur"]);

const dataModel = computed({
get() {
return props.propModel;
Expand All @@ -31,6 +35,17 @@ function onKeyEnter() {
props.keyEnterMethod();
}
}

async function selectFolder() {
const folder = await props.openMethod();
if (folder !== undefined) {
props.propMutate(folder);
emit("blur", folder);
if (props.onChangeMethod) {
props.onChangeMethod();
}
}
}
</script>

<template>
Expand All @@ -42,6 +57,7 @@ function onKeyEnter() {
type="text"
class="input"
v-model="dataModel"
@blur="$emit('blur', dataModel)"
@keyup.enter="onKeyEnter"
/>
</div>
Expand All @@ -54,10 +70,10 @@ function onKeyEnter() {
style="text-decoration: none;"
@mouseover="folderIcon = 'folder-opened'"
@mouseout="folderIcon = 'folder'"
v-on:click="openMethod"
@click="selectFolder"
>
<IconFolderOpened v-if="(folderIcon === 'folder-opened')" />
<IconFolder v-if="(folderIcon === 'folder')" />
<IconFolderOpened v-if="folderIcon === 'folder-opened'" />
<IconFolder v-if="folderIcon === 'folder'" />
</div>
</div>
</div>
Expand Down
45 changes: 31 additions & 14 deletions src/views/setup/components/selectEspIdf.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { storeToRefs } from "pinia";
import { useSetupStore } from "../store";
import { IdfMirror } from "../types";
import folderOpen from "./folderOpen.vue";
import { computed, watchEffect } from "vue";
import { computed, watchEffect, watch } from "vue";

const store = useSetupStore();

Expand All @@ -19,6 +19,9 @@ const {
selectedEspIdfVersion,
selectedIdfMirror,
showIdfTagList,
whiteSpaceErrorIDFContainer,
idfPathError,
isInstallButtonDisabled,
} = storeToRefs(store);

const idfVersionList = computed(() => {
Expand All @@ -39,6 +42,8 @@ const idfVersionList = computed(() => {

function clearIDfErrorStatus() {
store.espIdfErrorStatus = "";
store.whiteSpaceErrorIDFContainer = "";
store.idfPathError = "";
}

function setEspIdfPath(idfPath: string) {
Expand All @@ -49,6 +54,12 @@ function setEspIdfContainerPath(idfContainerPath: string) {
store.espIdfContainer = idfContainerPath;
}

function validatePathOnBlur(path: string) {
if (selectedEspIdfVersion.value.filename === "manual") {
store.validateEspIdfPath(path);
}
}

const resultingIdfPath = computed(() => {
return `${selectedEspIdfVersion.value.version.replace("release/", "")}${
store.pathSep
Expand Down Expand Up @@ -93,13 +104,6 @@ const isPathEmpty = computed(() => {
}
});

const showManualVersionWarning = computed(() => {
return (
selectedEspIdfVersion.value.filename === "manual" &&
hasWhitespaceInEspIdf.value
);
});

watchEffect(() => {
if (!hasWhitespaceInEspIdf.value) {
store.whiteSpaceErrorIDF = "";
Expand All @@ -108,6 +112,16 @@ watchEffect(() => {
store.whiteSpaceErrorIDFContainer = "";
}
});

watch(selectedEspIdfVersion, (newVal) => {
clearIDfErrorStatus();
store.clearIdfPathError();
if (newVal.filename === "manual") {
radurentea marked this conversation as resolved.
Show resolved Hide resolved
validatePathOnBlur(espIdf.value);
} else {
validatePathOnBlur(espIdfContainer.value);
}
});
</script>

<template>
Expand All @@ -119,7 +133,9 @@ watchEffect(() => {
<div class="control">
<div class="select">
radurentea marked this conversation as resolved.
Show resolved Hide resolved
<select v-model="selectedIdfMirror" @change="clearIDfErrorStatus">
<option :value="idfMirror.Espressif">Espressif (Better speed for China)</option>
<option :value="idfMirror.Espressif"
>Espressif (Better speed for China)</option
>
<option :value="idfMirror.Github">Github</option>
</select>
</div>
Expand Down Expand Up @@ -158,6 +174,7 @@ watchEffect(() => {
:propMutate="setEspIdfPath"
:openMethod="store.openEspIdfFolder"
:onChangeMethod="clearIDfErrorStatus"
@blur="validatePathOnBlur"
v-if="
selectedEspIdfVersion && selectedEspIdfVersion.filename === 'manual'
"
Expand All @@ -170,14 +187,11 @@ watchEffect(() => {
:openMethod="store.openEspIdfContainerFolder"
:onChangeMethod="clearIDfErrorStatus"
:staticText="resultingIdfPath"
@blur="validatePathOnBlur"
v-if="
selectedEspIdfVersion && selectedEspIdfVersion.filename !== 'manual'
"
/>
<div v-if="showManualVersionWarning" class="notification is-warning">
Make sure the ESP-IDF version is not lower than 5.0, since white spaces
are not supported for earlier versions.
</div>
<div
v-if="
selectedEspIdfVersion &&
Expand All @@ -187,11 +201,14 @@ watchEffect(() => {
"
class="notification is-danger"
>
White spaces are only supported for ESP-IDF path for versions > 5.0.
White spaces are only supported for ESP-IDF path for versions >= 5.0.
</div>
<div v-if="isPathEmpty" class="notification is-danger">
ESP-IDF path should not be empty.
</div>
<div v-if="idfPathError" class="notification is-danger">
{{ idfPathError }}
</div>
</div>
</template>

Expand Down
20 changes: 20 additions & 0 deletions src/views/setup/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ app.use(pinia);
app.use(router);
app.mount("#app");

router.beforeEach((to, from, next) => {
if (from.path === "/autoinstall" && to.path !== "/autoinstall") {
store.setIdfPathError("");
}
next();
});

const store = useSetupStore();

window.addEventListener("message", (event) => {
Expand Down Expand Up @@ -267,6 +274,19 @@ window.addEventListener("message", (event) => {
store.setStatusIdfPython(msg.status);
}
break;
case "canAccessFileResponse":
if (!msg.exists) {
store.setIdfPathError(
"The path for ESP-IDF is not valid: /tools/idf.py not found."
);
} else if (msg.noWhiteSpaceSupport && msg.hasWhitespace) {
store.setIdfPathError(
"White spaces are only supported for ESP-IDF path for versions >= 5.0."
);
} else {
store.setIdfPathError("");
}
break;
default:
break;
}
Expand Down
Loading
Loading