Repository: esp-rs/espflash (language: rust)

Issue:
Serial port selection provides too many options, some of which are invalid
Previously we filtered the available serial ports to only those which looked like ESP devices. This was changed to display all devices, however, due to reports from some users that not all ports were listed on some Linux distributions. However, as a result of this change there are too many ports listed on other OSs (like macOS), many of which are not flashable in any way.

I would like to see us go back to filtering serial ports, and maybe we can have an option to list everything using a flag and/or environment variable instead.
Serial port selection provides too many options, some of which are invalid
Previously we filtered the available serial ports to only those which looked like ESP devices. This was changed to display all devices, however, due to reports from some users that not all ports were listed on some Linux distributions. However, as a result of this change there are too many ports listed on other OSs (like macOS), many of which are not flashable in any way.

I would like to see us go back to filtering serial ports, and maybe we can have an option to list everything using a flag and/or environment variable instead.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d3f4651e..ee576d4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,12 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## [Unreleased]
 
 ### Added
+- Add `--list-all-ports` connection argument to avoid serial port filtering (#590)
 - Allow config file to live in parent folder (#595)
 
 ### Fixed
 - Change the `hard_reset` sequence to fix Windows issues (#594)
 
 ### Changed
+- Non-linux-musl: Only list the available USB Ports by default (#590)
 - `FlashData::new` now returns `crate::Error` (#591)
 - Moved `reset_after_flash` method to `reset` module (#594)
 
diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs
index b514d8a1..45e82321 100644
--- a/espflash/src/cli/mod.rs
+++ b/espflash/src/cli/mod.rs
@@ -61,6 +61,9 @@ pub struct ConnectArgs {
     /// Require confirmation before auto-connecting to a recognized device.
     #[arg(short = 'C', long)]
     pub confirm_port: bool,
+    /// List all available ports.
+    #[arg(long)]
+    pub list_all_ports: bool,
     /// Do not use the RAM stub for loading
     #[arg(long)]
     pub no_stub: bool,
diff --git a/espflash/src/cli/serial.rs b/espflash/src/cli/serial.rs
index badbd045..c4ebbed5 100644
--- a/espflash/src/cli/serial.rs
+++ b/espflash/src/cli/serial.rs
@@ -33,7 +33,7 @@ pub fn get_serial_port_info(
     // doesn't work (on Windows) with "dummy" device paths like `COM4`. That's
     // the reason we need to handle Windows/Posix differently.
 
-    let ports = detect_usb_serial_ports().unwrap_or_default();
+    let ports = detect_usb_serial_ports(matches.list_all_ports).unwrap_or_default();
 
     if let Some(serial) = &matches.port {
         find_serial_port(&ports, serial)
@@ -108,7 +108,7 @@ fn find_serial_port(ports: &[SerialPortInfo], name: &str) -> Result<SerialPortIn
 /// Linux we can do some manual parsing of sysfs to get the relevant bits
 /// without udev
 #[cfg(all(target_os = "linux", target_env = "musl"))]
-fn detect_usb_serial_ports() -> Result<Vec<SerialPortInfo>> {
+fn detect_usb_serial_ports(_list_all_ports: bool) -> Result<Vec<SerialPortInfo>> {
     use std::{
         fs::{read_link, read_to_string},
         path::PathBuf,
@@ -166,20 +166,24 @@ fn detect_usb_serial_ports() -> Result<Vec<SerialPortInfo>> {
 
 /// Returns a vector with available USB serial ports.
 #[cfg(not(all(target_os = "linux", target_env = "musl")))]
-fn detect_usb_serial_ports() -> Result<Vec<SerialPortInfo>> {
+fn detect_usb_serial_ports(list_all_ports: bool) -> Result<Vec<SerialPortInfo>> {
     let ports = available_ports().into_diagnostic()?;
     let ports = ports
         .into_iter()
         .filter(|port_info| {
-            matches!(
-                &port_info.port_type,
-                SerialPortType::UsbPort(..) |
-                // Allow PciPort. The user may want to use it.
-                // The port might have been misdetected by the system as PCI.
-                SerialPortType::PciPort |
-                // Good luck.
-                SerialPortType::Unknown
-            )
+            if list_all_ports {
+                matches!(
+                    &port_info.port_type,
+                    SerialPortType::UsbPort(..) |
+                    // Allow PciPort. The user may want to use it.
+                    // The port might have been misdetected by the system as PCI.
+                    SerialPortType::PciPort |
+                    // Good luck.
+                    SerialPortType::Unknown
+                )
+            } else {
+                matches!(&port_info.port_type, SerialPortType::UsbPort(..))
+            }
         })
         .collect::<Vec<_>>();
 
diff --git a/espflash/src/error.rs b/espflash/src/error.rs
index 55ae2581..8a1f54ef 100644
--- a/espflash/src/error.rs
+++ b/espflash/src/error.rs
@@ -115,7 +115,7 @@ pub enum Error {
     #[error("No serial ports could be detected")]
     #[diagnostic(
         code(espflash::no_serial),
-        help("Make sure you have connected a device to the host system")
+        help("Make sure you have connected a device to the host system. If the device is connected but not listed, try using the `--list-all-ports` flag.")
     )]
     NoSerial,
 


Test patch: