Enhance CLI actions and default handling
Add timed follow, src/lib upload helpers, and store default startup pattern under default key. Made-with: Cursor
This commit is contained in:
71
cli.py
71
cli.py
@@ -139,6 +139,26 @@ def _get_ordered_actions(argv: List[str]) -> List[tuple]:
|
||||
if vals:
|
||||
actions.append(('upload', vals))
|
||||
continue
|
||||
if arg == '--src':
|
||||
# Upload local DIR (default: ./src) to device root (:/
|
||||
local_dir = "src"
|
||||
if i + 1 < len(argv) and not argv[i + 1].startswith('-'):
|
||||
local_dir = argv[i + 1]
|
||||
i += 2
|
||||
else:
|
||||
i += 1
|
||||
# Use empty string as remote_dir to map to root on device
|
||||
actions.append(('upload', [local_dir, ""]))
|
||||
continue
|
||||
if arg == '--lib':
|
||||
# Upload local DIR to /lib on device
|
||||
if i + 1 < len(argv):
|
||||
local_dir = argv[i + 1]
|
||||
actions.append(('upload', [local_dir, "lib"]))
|
||||
i += 2
|
||||
else:
|
||||
raise ValueError("--lib requires a directory argument")
|
||||
continue
|
||||
if arg == '-e':
|
||||
actions.append(('erase_all', None))
|
||||
i += 1
|
||||
@@ -151,8 +171,19 @@ def _get_ordered_actions(argv: List[str]) -> List[tuple]:
|
||||
raise ValueError("--rm requires an argument")
|
||||
continue
|
||||
if arg in ('-f', '--follow'):
|
||||
actions.append(('follow', None))
|
||||
i += 1
|
||||
# Optional duration in seconds: --follow [SECONDS]
|
||||
follow_secs = None
|
||||
if i + 1 < len(argv) and not argv[i + 1].startswith('-'):
|
||||
try:
|
||||
follow_secs = float(argv[i + 1])
|
||||
i += 2
|
||||
except ValueError:
|
||||
# Not a number, treat as flag-only
|
||||
i += 1
|
||||
actions.append(('follow', follow_secs))
|
||||
else:
|
||||
actions.append(('follow', None))
|
||||
i += 1
|
||||
continue
|
||||
# Skip non-action flags and their values
|
||||
if arg in _FLAGS_WITH_VALUE and i + 1 < len(argv):
|
||||
@@ -258,7 +289,7 @@ Examples:
|
||||
parser.add_argument(
|
||||
"--default",
|
||||
metavar="PATTERN",
|
||||
help="Default/startup pattern (startup_preset in settings.json)"
|
||||
help="Default/startup pattern (stored as 'default' in settings.json)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
@@ -276,8 +307,11 @@ Examples:
|
||||
|
||||
parser.add_argument(
|
||||
"-f", "--follow",
|
||||
action="store_true",
|
||||
help="Follow device output continuously (like tail -f)"
|
||||
nargs="?",
|
||||
const=None,
|
||||
type=float,
|
||||
metavar="SECONDS",
|
||||
help="Follow device output continuously (like tail -f). Optionally specify SECONDS to limit follow duration."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
@@ -293,6 +327,20 @@ Examples:
|
||||
help="Upload a directory recursively to the device. Usage: -u SRC [DEST] (DEST is optional, defaults to basename of SRC)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--src",
|
||||
nargs="?",
|
||||
const="src",
|
||||
metavar="DIR",
|
||||
help="Upload DIR recursively to device root (:/, no leading directory). If DIR is omitted, uses local ./src."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--lib",
|
||||
metavar="DIR",
|
||||
help="Upload DIR recursively to /lib on device"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
dest="erase_all",
|
||||
@@ -410,9 +458,12 @@ Examples:
|
||||
if ran_reset:
|
||||
time.sleep(0.5)
|
||||
try:
|
||||
print(f"Following output from {port}... (Press Ctrl+C to stop)", file=sys.stderr)
|
||||
if value is None:
|
||||
print(f"Following output from {port}... (Press Ctrl+C to stop)", file=sys.stderr)
|
||||
else:
|
||||
print(f"Following output from {port} for {value} seconds...", file=sys.stderr)
|
||||
conn = DeviceConnection(port)
|
||||
conn.follow_output()
|
||||
conn.follow_output(value)
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped following.", file=sys.stderr)
|
||||
sys.exit(0)
|
||||
@@ -421,10 +472,6 @@ Examples:
|
||||
sys.exit(1)
|
||||
return # follow blocks; when interrupted we're done
|
||||
|
||||
# If we ran any actions and follow wasn't last, we're done
|
||||
if ordered_actions:
|
||||
return
|
||||
|
||||
# Collect all edit parameters
|
||||
edits: Dict[str, Any] = {}
|
||||
|
||||
@@ -450,7 +497,7 @@ Examples:
|
||||
edits["pattern"] = args.preset
|
||||
|
||||
if args.default is not None:
|
||||
edits["startup_preset"] = args.default
|
||||
edits["default"] = args.default
|
||||
|
||||
# 1. Download: get current settings from device
|
||||
try:
|
||||
|
||||
13
device.py
13
device.py
@@ -208,12 +208,21 @@ class DeviceConnection:
|
||||
except Exception as e:
|
||||
raise TransportError(f"Failed to reset device: {e}") from e
|
||||
|
||||
def follow_output(self):
|
||||
"""Follow device output continuously (like tail -f)."""
|
||||
def follow_output(self, duration=None):
|
||||
"""
|
||||
Follow device output (like tail -f).
|
||||
|
||||
Args:
|
||||
duration: Optional number of seconds to follow output for. If None,
|
||||
follow indefinitely until interrupted.
|
||||
"""
|
||||
# Use direct serial connection like dev.py does
|
||||
start_time = time.time()
|
||||
try:
|
||||
with serial.Serial(self.device, baudrate=115200) as ser:
|
||||
while True:
|
||||
if duration is not None and (time.time() - start_time) >= duration:
|
||||
break
|
||||
if ser.in_waiting > 0:
|
||||
data = ser.readline().decode('utf-8', errors='replace').strip()
|
||||
if data:
|
||||
|
||||
Reference in New Issue
Block a user