Skip to content

Commit 711039c

Browse files
authored
Merge pull request esp-rs#172 from svenstaro/add-partition-subcommand
Add partition-table subcommand
2 parents 544f700 + 17cd3f5 commit 711039c

File tree

9 files changed

+410
-34
lines changed

9 files changed

+410
-34
lines changed

.github/workflows/rust.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
- uses: actions-rs/toolchain@v1
3838
with:
3939
profile: minimal
40-
toolchain: 1.56
40+
toolchain: 1.58
4141
override: true
4242
- uses: Swatinem/rust-cache@v1
4343
- uses: actions-rs/cargo@v1

Cargo.lock

Lines changed: 51 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This repository contains two applications:
1414
| [cargo-espflash] | Cargo subcommand for espflash |
1515
| [espflash] | Library and `espflash` binary (_without_ Cargo integration) |
1616

17-
> **NOTE:** requires `rustc >= 1.56.0` in order to build either application
17+
> **NOTE:** requires `rustc >= 1.58.0` in order to build either application
1818
1919
## Installation
2020

cargo-espflash/src/main.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
22
fs,
3+
io::Write,
34
path::PathBuf,
45
process::{exit, Command, ExitStatus, Stdio},
56
str::FromStr,
@@ -12,7 +13,7 @@ use espflash::{
1213
board_info, connect, flash_elf_image, monitor::monitor, save_elf_as_image, ConnectOpts,
1314
FlashConfigOpts, FlashOpts,
1415
},
15-
Chip, Config, ImageFormatId,
16+
Chip, Config, ImageFormatId, InvalidPartitionTable, PartitionTable,
1617
};
1718
use miette::{IntoDiagnostic, Result, WrapErr};
1819

@@ -56,6 +57,8 @@ pub enum SubCommand {
5657
BoardInfo(ConnectOpts),
5758
/// Save the image to disk instead of flashing to device
5859
SaveImage(SaveImageOpts),
60+
/// Operations for partitions tables
61+
PartitionTable(PartitionTableOpts),
5962
}
6063

6164
#[derive(Parser)]
@@ -102,6 +105,24 @@ pub struct SaveImageOpts {
102105
pub partition_table: Option<PathBuf>,
103106
}
104107

108+
#[derive(Parser)]
109+
pub struct PartitionTableOpts {
110+
/// Convert CSV parition table to binary representation
111+
#[clap(long, required_unless_present_any = ["info", "to-csv"])]
112+
to_binary: bool,
113+
/// Convert binary partition table to CSV representation
114+
#[clap(long, required_unless_present_any = ["info", "to-binary"])]
115+
to_csv: bool,
116+
/// Show information on partition table
117+
#[clap(short, long, required_unless_present_any = ["to-binary", "to-csv"])]
118+
info: bool,
119+
/// Input partition table
120+
partition_table: PathBuf,
121+
/// Optional output file name, if unset will output to stdout
122+
#[clap(short, long)]
123+
output: Option<PathBuf>,
124+
}
125+
105126
fn main() -> Result<()> {
106127
miette::set_panic_hook();
107128

@@ -117,6 +138,7 @@ fn main() -> Result<()> {
117138
match subcommand {
118139
BoardInfo(opts) => board_info(opts, config),
119140
SaveImage(opts) => save_image(opts, metadata, cargo_config),
141+
PartitionTable(opts) => partition_table(opts),
120142
}
121143
} else {
122144
flash(opts, config, metadata, cargo_config)
@@ -344,6 +366,53 @@ fn save_image(
344366
Ok(())
345367
}
346368

369+
fn partition_table(opts: PartitionTableOpts) -> Result<()> {
370+
if opts.to_binary {
371+
let input = fs::read(&opts.partition_table).into_diagnostic()?;
372+
let part_table = PartitionTable::try_from_str(String::from_utf8(input).into_diagnostic()?)
373+
.into_diagnostic()?;
374+
375+
// Use either stdout or a file if provided for the output.
376+
let mut writer: Box<dyn Write> = if let Some(output) = opts.output {
377+
Box::new(fs::File::create(output).into_diagnostic()?)
378+
} else {
379+
Box::new(std::io::stdout())
380+
};
381+
part_table.save_bin(&mut writer).into_diagnostic()?;
382+
} else if opts.to_csv {
383+
let input = fs::read(&opts.partition_table).into_diagnostic()?;
384+
let part_table = PartitionTable::try_from_bytes(input).into_diagnostic()?;
385+
386+
// Use either stdout or a file if provided for the output.
387+
let mut writer: Box<dyn Write> = if let Some(output) = opts.output {
388+
Box::new(fs::File::create(output).into_diagnostic()?)
389+
} else {
390+
Box::new(std::io::stdout())
391+
};
392+
part_table.save_csv(&mut writer).into_diagnostic()?;
393+
} else if opts.info {
394+
let input = fs::read(&opts.partition_table).into_diagnostic()?;
395+
396+
// Try getting the partition table from either the csv or the binary representation and
397+
// fail otherwise.
398+
let part_table = if let Ok(part_table) =
399+
PartitionTable::try_from_bytes(input.clone()).into_diagnostic()
400+
{
401+
part_table
402+
} else if let Ok(part_table) =
403+
PartitionTable::try_from_str(String::from_utf8(input).into_diagnostic()?)
404+
{
405+
part_table
406+
} else {
407+
return Err((InvalidPartitionTable {}).into());
408+
};
409+
410+
part_table.pretty_print();
411+
}
412+
413+
Ok(())
414+
}
415+
347416
#[cfg(unix)]
348417
fn exit_with_process_status(status: ExitStatus) -> ! {
349418
use std::os::unix::process::ExitStatusExt;

espflash/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ authors = [
66
"Jesse Braham <[email protected]>",
77
]
88
edition = "2021"
9-
rust-version = "1.56"
9+
rust-version = "1.58"
1010
description = "A command-line tool for flashing Espressif devices over serial"
1111
repository = "https://github.com/esp-rs/espflash"
1212
license = "GPL-2.0"
@@ -35,6 +35,7 @@ path = "src/main.rs"
3535
binread = "2.2"
3636
bytemuck = { version = "1.9", features = ["derive"] }
3737
clap = { version = "3.1", features = ["derive"] }
38+
comfy-table = "5"
3839
crossterm = "0.23"
3940
csv = "1.1"
4041
dialoguer = "0.10"

espflash/src/error.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,18 @@ pub enum PartitionTableError {
346346
#[error(transparent)]
347347
#[diagnostic(transparent)]
348348
UnalignedPartitionError(#[from] UnalignedPartitionError),
349+
#[error(transparent)]
350+
#[diagnostic(transparent)]
351+
LengthNotMultipleOf32(#[from] LengthNotMultipleOf32),
352+
#[error(transparent)]
353+
#[diagnostic(transparent)]
354+
InvalidChecksum(#[from] InvalidChecksum),
355+
#[error(transparent)]
356+
#[diagnostic(transparent)]
357+
NoEndMarker(#[from] NoEndMarker),
358+
#[error(transparent)]
359+
#[diagnostic(transparent)]
360+
InvalidPartitionTable(#[from] InvalidPartitionTable),
349361
}
350362

351363
#[derive(Debug, Error, Diagnostic)]
@@ -535,6 +547,26 @@ impl UnalignedPartitionError {
535547
}
536548
}
537549

550+
#[derive(Debug, Error, Diagnostic)]
551+
#[error("Partition table length not a multiple of 32")]
552+
#[diagnostic(code(espflash::partition_table::invalid_length))]
553+
pub struct LengthNotMultipleOf32;
554+
555+
#[derive(Debug, Error, Diagnostic)]
556+
#[error("Checksum invalid")]
557+
#[diagnostic(code(espflash::partition_table::invalid_checksum))]
558+
pub struct InvalidChecksum;
559+
560+
#[derive(Debug, Error, Diagnostic)]
561+
#[error("No end marker found")]
562+
#[diagnostic(code(espflash::partition_table::no_end_marker))]
563+
pub struct NoEndMarker;
564+
565+
#[derive(Debug, Error, Diagnostic)]
566+
#[error("Invalid partition table")]
567+
#[diagnostic(code(espflash::partition_table::invalid_partition_table))]
568+
pub struct InvalidPartitionTable;
569+
538570
#[derive(Debug, Error)]
539571
#[error("{0}")]
540572
pub struct ElfError(&'static str);

espflash/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub use chip::Chip;
22
pub use cli::config::Config;
33
pub use elf::{FlashFrequency, FlashMode};
4-
pub use error::Error;
4+
pub use error::{Error, InvalidPartitionTable};
55
pub use flasher::{FlashSize, Flasher};
66
pub use image_format::ImageFormatId;
77
pub use partition_table::PartitionTable;

0 commit comments

Comments
 (0)