Skip to content

Commit cc15b7b

Browse files
committed
Added fix command for reinstalling the IDF
1 parent 961940b commit cc15b7b

File tree

5 files changed

+118
-11
lines changed

5 files changed

+118
-11
lines changed

.github/workflows/build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ jobs:
191191
perl -MText::Template -e "print 'Text::Template loaded successfully\n'"
192192
perl -MParams::Check -e "print 'Params::Check loaded successfully\n'"
193193
perl -MIPC::Cmd -e "print 'IPC::Cmd loaded successfully\n'"
194-
$perl_lib_path = "C:\hostedtoolcache\windows\perl\5.38.4-thr\x64\site\lib"
194+
$perl_lib_path = "C:\hostedtoolcache\windows\perl\5.38.5-thr\x64\site\lib"
195195
echo "PERL5LIB=$perl_lib_path" >> $env:GITHUB_ENV
196196
197197
- name: Cache cargo
@@ -211,7 +211,7 @@ jobs:
211211
OPENSSL_LIB_DIR: 'C:\vcpkg\installed\x64-windows-static-md\lib'
212212
OPENSSL_INCLUDE_DIR: 'C:\vcpkg\installed\x64-windows-static-md\include'
213213
OPENSSL_STATIC: "1"
214-
PERL: 'C:\\hostedtoolcache\\windows\\perl\\5.38.4-thr\\x64\\bin\\perl.exe'
214+
PERL: 'C:\\hostedtoolcache\\windows\\perl\\5.38.5-thr\\x64\\bin\\perl.exe'
215215
run: |
216216
cd src-tauri
217217
cargo build --release --no-default-features --features cli ${{ matrix.target && format('--target {0}', matrix.target) || '' }}

docs/src/cli_commands.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,16 @@ eim discover
144144
145145
This command is planned to discover ESP-IDF installations on your system but is not yet implemented.
146146
147+
### Fix Command
148+
149+
Fix the ESP-IDF installation by reinstalling the tools and dependencies
150+
151+
```bash
152+
eim fix [PATH]
153+
```
154+
155+
If no `PATH` is provided, the user will be presented with selection of all known IDF installation to select from.
156+
147157
## Examples
148158
149159
```bash

src-tauri/src/cli/cli_args.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ pub enum Commands {
9696
/// Run the ESP-IDF Installer GUI with arguments passed through command line
9797
#[cfg(feature = "gui")]
9898
Gui(InstallArgs),
99+
100+
/// Fix the ESP-IDF installation by reinstalling the tools and dependencies
101+
Fix {
102+
#[arg(help = "Fix IDF on a specific path")]
103+
path: Option<String>,
104+
},
99105
}
100106

101107
#[derive(Parser, Debug, Clone, Default)]

src-tauri/src/cli/mod.rs

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use helpers::generic_input;
1010
use helpers::generic_select;
1111
use idf_im_lib::get_log_directory;
1212
use idf_im_lib::settings::Settings;
13+
use idf_im_lib::utils::is_valid_idf_directory;
1314
use idf_im_lib::version_manager::remove_single_idf_version;
1415
use idf_im_lib::version_manager::select_idf_version;
1516
use log::debug;
@@ -353,7 +354,7 @@ pub async fn run_cli(cli: Cli) -> anyhow::Result<()> {
353354
println!("Available versions:");
354355
let options = versions.iter().map(|v| v.name.clone()).collect();
355356
match generic_select("Which version do you want to remove?", &options) {
356-
Ok(selected) => match remove_single_idf_version(&selected) {
357+
Ok(selected) => match remove_single_idf_version(&selected, false) {
357358
Ok(_) => {
358359
info!("Removed version: {}", selected);
359360
Ok(())
@@ -367,7 +368,7 @@ pub async fn run_cli(cli: Cli) -> anyhow::Result<()> {
367368
Err(err) => Err(anyhow::anyhow!(err)),
368369
}
369370
} else {
370-
match remove_single_idf_version(&version.clone().unwrap()) {
371+
match remove_single_idf_version(&version.clone().unwrap(), false) {
371372
Ok(_) => {
372373
println!("Removed version: {}", version.clone().unwrap());
373374
Ok(())
@@ -388,7 +389,7 @@ pub async fn run_cli(cli: Cli) -> anyhow::Result<()> {
388389
let mut failed = false;
389390
for version in versions {
390391
info!("Removing version: {}", version.name);
391-
match remove_single_idf_version(&version.name) {
392+
match remove_single_idf_version(&version.name, false) {
392393
Ok(_) => {
393394
info!("Removed version: {}", version.name);
394395
}
@@ -432,6 +433,89 @@ pub async fn run_cli(cli: Cli) -> anyhow::Result<()> {
432433
Err(err) => Err(anyhow::anyhow!(err)),
433434
}
434435
}
436+
Commands::Fix { path } => {
437+
let path_to_fix = if path.is_some() {
438+
// If a path is provided, fix the IDF installation at that path
439+
let path = path.unwrap();
440+
if is_valid_idf_directory(&path) {
441+
PathBuf::from(path)
442+
} else {
443+
error!("Invalid IDF directory: {}", path);
444+
return Err(anyhow::anyhow!("Invalid IDF directory: {}", path));
445+
}
446+
} else {
447+
match idf_im_lib::version_manager::list_installed_versions() {
448+
Ok(versions) => {
449+
if versions.is_empty() {
450+
warn!("No versions installed");
451+
return Ok(());
452+
} else {
453+
let options = versions.iter().map(|v| v.path.clone()).collect();
454+
let version_path = match helpers::generic_select(
455+
"Which version do you want to fix?",
456+
&options,
457+
) {
458+
Ok(selected) => selected,
459+
Err(err) => {
460+
error!("Error: {}", err);
461+
return Err(anyhow::anyhow!(err));
462+
}
463+
};
464+
PathBuf::from(version_path)
465+
}
466+
}
467+
Err(err) => {
468+
debug!("Error: {}", err);
469+
return Err(anyhow::anyhow!("No versions found. Use eim install to install a new ESP-IDF version."));
470+
}
471+
}
472+
};
473+
info!("Fixing IDF installation at path: {}", path_to_fix.display());
474+
// The fix logic is just instalation with use of existing repository
475+
let mut version_name = None;
476+
match idf_im_lib::version_manager::list_installed_versions() {
477+
Ok(versions) => {
478+
for v in versions {
479+
if v.path == path_to_fix.to_str().unwrap() {
480+
info!("Found existing IDF version: {}", v.name);
481+
// Remove the existing activation script and eim_idf.json entry
482+
match remove_single_idf_version(&v.name, true) {
483+
Ok(_) => {
484+
info!("Removed existing IDF version from eim_idf.json: {}", v.name);
485+
version_name = Some(v.name.clone());
486+
}
487+
Err(err) => {
488+
error!("Failed to remove existing IDF version {}: {}", v.name, err);
489+
}
490+
}
491+
}
492+
}
493+
}
494+
Err(_) => {
495+
info!("Failed to list installed versions. Using default naming.");
496+
}
497+
}
498+
499+
let mut settings = Settings::default();
500+
settings.path = Some(path_to_fix.clone());
501+
settings.non_interactive = Some(true);
502+
settings.version_name = version_name;
503+
settings.install_all_prerequisites = Some(true);
504+
settings.config_file_save_path = None;
505+
let result = wizard::run_wizzard_run(settings).await;
506+
match result {
507+
Ok(r) => {
508+
info!("Fix result: {:?}", r);
509+
info!("Successfully fixed IDF installation at {}", path_to_fix.display());
510+
}
511+
Err(err) => {
512+
error!("Failed to fix IDF installation: {}", err);
513+
return Err(anyhow::anyhow!(err));
514+
}
515+
}
516+
info!("Now you can start using IDF tools");
517+
Ok(())
518+
}
435519
#[cfg(feature = "gui")]
436520
Commands::Gui(_install_args) => {
437521
#[cfg(not(feature = "gui"))]

src-tauri/src/lib/version_manager.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub fn rename_idf_version(identifier: &str, new_name: String) -> Result<String>
173173
///
174174
/// * `Result<String, anyhow::Error>` - On success, returns a `Result` containing a string message indicating
175175
/// that the version has been removed. On error, returns an `anyhow::Error` with a description of the error.
176-
pub fn remove_single_idf_version(identifier: &str) -> Result<String> {
176+
pub fn remove_single_idf_version(identifier: &str, keep_idf_folder: bool) -> Result<String> {
177177
//TODO: remove also from path
178178
let config_path = get_default_config_path();
179179
let mut ide_config = IdfConfig::from_file(&config_path)?;
@@ -183,11 +183,18 @@ pub fn remove_single_idf_version(identifier: &str) -> Result<String> {
183183
.find(|install| install.id == identifier || install.name == identifier)
184184
{
185185
let installation_folder_path = PathBuf::from(installation.path.clone());
186-
let installation_folder = installation_folder_path.parent().unwrap();
187-
match remove_directory_all(installation_folder) {
188-
Ok(_) => {}
189-
Err(e) => {
190-
return Err(anyhow!("Failed to remove installation folder: {}", e));
186+
let installation_folder = installation_folder_path.parent().ok_or_else(|| {
187+
anyhow!(
188+
"Installation path '{}' has no parent directory",
189+
installation_folder_path.display()
190+
)
191+
})?;
192+
if !keep_idf_folder {
193+
match remove_directory_all(installation_folder) {
194+
Ok(_) => {}
195+
Err(e) => {
196+
return Err(anyhow!("Failed to remove installation folder: {}", e));
197+
}
191198
}
192199
}
193200
match remove_directory_all(installation.clone().activation_script) {

0 commit comments

Comments
 (0)