Fixed bug with upload
This commit is contained in:
@@ -111,7 +111,10 @@ pub fn run_build(
|
|||||||
// Upload
|
// Upload
|
||||||
let port = match port {
|
let port = match port {
|
||||||
Some(p) => p.to_string(),
|
Some(p) => p.to_string(),
|
||||||
None => board::auto_detect_port()?,
|
None => match &config.monitor.port {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => board::auto_detect_port()?,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
upload_to_board(&cli, fqbn, &port, &cache_dir, verbose)?;
|
upload_to_board(&cli, fqbn, &port, &cache_dir, verbose)?;
|
||||||
@@ -193,7 +196,10 @@ pub fn run_upload_only(
|
|||||||
|
|
||||||
let port = match port {
|
let port = match port {
|
||||||
Some(p) => p.to_string(),
|
Some(p) => p.to_string(),
|
||||||
None => board::auto_detect_port()?,
|
None => match &config.monitor.port {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => board::auto_detect_port()?,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
upload_to_board(&cli, fqbn, &port, &cache_dir, verbose)?;
|
upload_to_board(&cli, fqbn, &port, &cache_dir, verbose)?;
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ pub struct BuildConfig {
|
|||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct MonitorConfig {
|
pub struct MonitorConfig {
|
||||||
pub baud: u32,
|
pub baud: u32,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub port: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectConfig {
|
impl ProjectConfig {
|
||||||
@@ -49,6 +51,7 @@ impl ProjectConfig {
|
|||||||
},
|
},
|
||||||
monitor: MonitorConfig {
|
monitor: MonitorConfig {
|
||||||
baud: 115200,
|
baud: 115200,
|
||||||
|
port: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ extra_flags = ["-Werror"]
|
|||||||
|
|
||||||
[monitor]
|
[monitor]
|
||||||
baud = 115200
|
baud = 115200
|
||||||
|
# port = "/dev/ttyUSB0" # Uncomment to skip auto-detect
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ die() { echo "${RED}FAIL${RST} $*" >&2; exit 1; }
|
|||||||
# Searches the whole file; for sectioned keys, grep is specific enough
|
# Searches the whole file; for sectioned keys, grep is specific enough
|
||||||
# given our small, flat schema.
|
# given our small, flat schema.
|
||||||
toml_get() {
|
toml_get() {
|
||||||
grep "^$1 " "$CONFIG" | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
(grep "^$1 " "$CONFIG" 2>/dev/null || true) | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extract a TOML array as space-separated values: toml_array "key"
|
# Extract a TOML array as space-separated values: toml_array "key"
|
||||||
toml_array() {
|
toml_array() {
|
||||||
grep "^$1 " "$CONFIG" | head -1 \
|
(grep "^$1 " "$CONFIG" 2>/dev/null || true) | head -1 \
|
||||||
| sed 's/.*\[//; s/\].*//; s/"//g; s/,/ /g' | tr -s ' '
|
| sed 's/.*\[//; s/\].*//; s/"//g; s/,/ /g' | tr -s ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,12 @@ die() { echo "${RED}FAIL${RST} $*" >&2; exit 1; }
|
|||||||
[[ -f "$CONFIG" ]] || die "No .anvil.toml found in $SCRIPT_DIR"
|
[[ -f "$CONFIG" ]] || die "No .anvil.toml found in $SCRIPT_DIR"
|
||||||
|
|
||||||
toml_get() {
|
toml_get() {
|
||||||
grep "^$1 " "$CONFIG" | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
(grep "^$1 " "$CONFIG" 2>/dev/null || true) | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
BAUD="$(toml_get 'baud')"
|
BAUD="$(toml_get 'baud')"
|
||||||
BAUD="${BAUD:-115200}"
|
BAUD="${BAUD:-115200}"
|
||||||
|
DEFAULT_PORT="$(toml_get 'port')"
|
||||||
|
|
||||||
# -- Parse arguments -------------------------------------------------------
|
# -- Parse arguments -------------------------------------------------------
|
||||||
PORT=""
|
PORT=""
|
||||||
@@ -62,16 +63,35 @@ command -v arduino-cli &>/dev/null \
|
|||||||
|
|
||||||
# -- Auto-detect port ------------------------------------------------------
|
# -- Auto-detect port ------------------------------------------------------
|
||||||
auto_detect() {
|
auto_detect() {
|
||||||
arduino-cli board list 2>/dev/null \
|
# Prefer ttyUSB/ttyACM (real USB devices) over ttyS (hardware UART)
|
||||||
|
local port
|
||||||
|
port=$(arduino-cli board list 2>/dev/null \
|
||||||
| grep -i "serial" \
|
| grep -i "serial" \
|
||||||
| head -1 \
|
| awk '{print $1}' \
|
||||||
| awk '{print $1}'
|
| grep -E 'ttyUSB|ttyACM|COM' \
|
||||||
|
| head -1)
|
||||||
|
|
||||||
|
# Fallback: any serial port
|
||||||
|
if [[ -z "$port" ]]; then
|
||||||
|
port=$(arduino-cli board list 2>/dev/null \
|
||||||
|
| grep -i "serial" \
|
||||||
|
| head -1 \
|
||||||
|
| awk '{print $1}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$port"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ -z "$PORT" ]]; then
|
if [[ -z "$PORT" ]]; then
|
||||||
PORT="$(auto_detect)"
|
# Check .anvil.toml for configured port
|
||||||
|
if [[ -n "$DEFAULT_PORT" ]]; then
|
||||||
|
PORT="$DEFAULT_PORT"
|
||||||
|
else
|
||||||
|
PORT="$(auto_detect)"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$PORT" ]]; then
|
if [[ -z "$PORT" ]]; then
|
||||||
die "No serial port detected. Is the board plugged in?\n Specify manually: ./monitor.sh -p /dev/ttyUSB0"
|
die "No serial port detected. Is the board plugged in?\n Specify manually: ./monitor.sh -p /dev/ttyUSB0\n Or set port in .anvil.toml"
|
||||||
fi
|
fi
|
||||||
warn "Auto-detected port: $PORT (use -p to override)"
|
warn "Auto-detected port: $PORT (use -p to override)"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ die() { echo "${RED}FAIL${RST} $*" >&2; exit 1; }
|
|||||||
[[ -f "$CONFIG" ]] || die "No .anvil.toml found in $SCRIPT_DIR"
|
[[ -f "$CONFIG" ]] || die "No .anvil.toml found in $SCRIPT_DIR"
|
||||||
|
|
||||||
toml_get() {
|
toml_get() {
|
||||||
grep "^$1 " "$CONFIG" | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
(grep "^$1 " "$CONFIG" 2>/dev/null || true) | head -1 | sed 's/.*= *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
toml_array() {
|
toml_array() {
|
||||||
grep "^$1 " "$CONFIG" | head -1 \
|
(grep "^$1 " "$CONFIG" 2>/dev/null || true) | head -1 \
|
||||||
| sed 's/.*\[//; s/\].*//; s/"//g; s/,/ /g' | tr -s ' '
|
| sed 's/.*\[//; s/\].*//; s/"//g; s/,/ /g' | tr -s ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ BAUD="$(toml_get 'baud')"
|
|||||||
[[ -n "$FQBN" ]] || die "Could not read fqbn from .anvil.toml"
|
[[ -n "$FQBN" ]] || die "Could not read fqbn from .anvil.toml"
|
||||||
|
|
||||||
BAUD="${BAUD:-115200}"
|
BAUD="${BAUD:-115200}"
|
||||||
|
DEFAULT_PORT="$(toml_get 'port')"
|
||||||
SKETCH_DIR="$SCRIPT_DIR/$SKETCH_NAME"
|
SKETCH_DIR="$SCRIPT_DIR/$SKETCH_NAME"
|
||||||
BUILD_DIR="$SCRIPT_DIR/.build"
|
BUILD_DIR="$SCRIPT_DIR/.build"
|
||||||
|
|
||||||
@@ -86,14 +87,28 @@ command -v arduino-cli &>/dev/null \
|
|||||||
|
|
||||||
# -- Auto-detect port ------------------------------------------------------
|
# -- Auto-detect port ------------------------------------------------------
|
||||||
if [[ -z "$PORT" ]]; then
|
if [[ -z "$PORT" ]]; then
|
||||||
# Look for the first serial port arduino-cli can see
|
# Check .anvil.toml for configured port
|
||||||
PORT=$(arduino-cli board list 2>/dev/null \
|
if [[ -n "$DEFAULT_PORT" ]]; then
|
||||||
| grep -i "serial" \
|
PORT="$DEFAULT_PORT"
|
||||||
| head -1 \
|
else
|
||||||
| awk '{print $1}')
|
# Prefer ttyUSB/ttyACM (real USB devices) over ttyS (hardware UART)
|
||||||
|
PORT=$(arduino-cli board list 2>/dev/null \
|
||||||
|
| grep -i "serial" \
|
||||||
|
| awk '{print $1}' \
|
||||||
|
| grep -E 'ttyUSB|ttyACM|COM' \
|
||||||
|
| head -1)
|
||||||
|
|
||||||
|
# Fallback: any serial port if no USB ports found
|
||||||
|
if [[ -z "$PORT" ]]; then
|
||||||
|
PORT=$(arduino-cli board list 2>/dev/null \
|
||||||
|
| grep -i "serial" \
|
||||||
|
| head -1 \
|
||||||
|
| awk '{print $1}')
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$PORT" ]]; then
|
if [[ -z "$PORT" ]]; then
|
||||||
die "No serial port detected. Is the board plugged in?\n Specify manually: ./upload.sh -p /dev/ttyUSB0"
|
die "No serial port detected. Is the board plugged in?\n Specify manually: ./upload.sh -p /dev/ttyUSB0\n Or set port in .anvil.toml"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
warn "Auto-detected port: $PORT (use -p to override)"
|
warn "Auto-detected port: $PORT (use -p to override)"
|
||||||
|
|||||||
@@ -637,3 +637,35 @@ fn test_readme_documents_self_contained_workflow() {
|
|||||||
"README should mention self-contained"
|
"README should mention self-contained"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_scripts_tolerate_missing_toml_keys() {
|
||||||
|
// Regression: toml_get must not kill the script when a key is absent.
|
||||||
|
// With set -euo pipefail, bare grep returns exit 1 on no match,
|
||||||
|
// pipefail propagates it, and set -e terminates silently.
|
||||||
|
// Every grep in toml_get/toml_array must have "|| true".
|
||||||
|
let tmp = TempDir::new().unwrap();
|
||||||
|
let ctx = TemplateContext {
|
||||||
|
project_name: "grep_safe".to_string(),
|
||||||
|
anvil_version: "1.0.0".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||||
|
|
||||||
|
for script in &["build.sh", "upload.sh", "monitor.sh"] {
|
||||||
|
let content = fs::read_to_string(tmp.path().join(script)).unwrap();
|
||||||
|
|
||||||
|
// If the script uses set -e (or -euo pipefail), then every
|
||||||
|
// toml_get/toml_array function must guard grep with || true
|
||||||
|
if content.contains("set -e") || content.contains("set -euo") {
|
||||||
|
// Find the toml_get function body and check for || true
|
||||||
|
let has_safe_grep = content.contains("|| true");
|
||||||
|
assert!(
|
||||||
|
has_safe_grep,
|
||||||
|
"{} uses set -e but toml_get/toml_array lacks '|| true' guard. \
|
||||||
|
Missing TOML keys will silently kill the script.",
|
||||||
|
script
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user