Skip to content

Commit

Permalink
Merge pull request #172 from svenstaro/add-partition-subcommand
Browse files Browse the repository at this point in the history
Add partition-table subcommand
  • Loading branch information
jessebraham authored May 3, 2022
2 parents 544f700 + 17cd3f5 commit 711039c
Show file tree
Hide file tree
Showing 9 changed files with 410 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.56
toolchain: 1.58
override: true
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
Expand Down
55 changes: 51 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This repository contains two applications:
| [cargo-espflash] | Cargo subcommand for espflash |
| [espflash] | Library and `espflash` binary (_without_ Cargo integration) |

> **NOTE:** requires `rustc >= 1.56.0` in order to build either application
> **NOTE:** requires `rustc >= 1.58.0` in order to build either application
## Installation

Expand Down
71 changes: 70 additions & 1 deletion cargo-espflash/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
fs,
io::Write,
path::PathBuf,
process::{exit, Command, ExitStatus, Stdio},
str::FromStr,
Expand All @@ -12,7 +13,7 @@ use espflash::{
board_info, connect, flash_elf_image, monitor::monitor, save_elf_as_image, ConnectOpts,
FlashConfigOpts, FlashOpts,
},
Chip, Config, ImageFormatId,
Chip, Config, ImageFormatId, InvalidPartitionTable, PartitionTable,
};
use miette::{IntoDiagnostic, Result, WrapErr};

Expand Down Expand Up @@ -56,6 +57,8 @@ pub enum SubCommand {
BoardInfo(ConnectOpts),
/// Save the image to disk instead of flashing to device
SaveImage(SaveImageOpts),
/// Operations for partitions tables
PartitionTable(PartitionTableOpts),
}

#[derive(Parser)]
Expand Down Expand Up @@ -102,6 +105,24 @@ pub struct SaveImageOpts {
pub partition_table: Option<PathBuf>,
}

#[derive(Parser)]
pub struct PartitionTableOpts {
/// Convert CSV parition table to binary representation
#[clap(long, required_unless_present_any = ["info", "to-csv"])]
to_binary: bool,
/// Convert binary partition table to CSV representation
#[clap(long, required_unless_present_any = ["info", "to-binary"])]
to_csv: bool,
/// Show information on partition table
#[clap(short, long, required_unless_present_any = ["to-binary", "to-csv"])]
info: bool,
/// Input partition table
partition_table: PathBuf,
/// Optional output file name, if unset will output to stdout
#[clap(short, long)]
output: Option<PathBuf>,
}

fn main() -> Result<()> {
miette::set_panic_hook();

Expand All @@ -117,6 +138,7 @@ fn main() -> Result<()> {
match subcommand {
BoardInfo(opts) => board_info(opts, config),
SaveImage(opts) => save_image(opts, metadata, cargo_config),
PartitionTable(opts) => partition_table(opts),
}
} else {
flash(opts, config, metadata, cargo_config)
Expand Down Expand Up @@ -344,6 +366,53 @@ fn save_image(
Ok(())
}

fn partition_table(opts: PartitionTableOpts) -> Result<()> {
if opts.to_binary {
let input = fs::read(&opts.partition_table).into_diagnostic()?;
let part_table = PartitionTable::try_from_str(String::from_utf8(input).into_diagnostic()?)
.into_diagnostic()?;

// Use either stdout or a file if provided for the output.
let mut writer: Box<dyn Write> = if let Some(output) = opts.output {
Box::new(fs::File::create(output).into_diagnostic()?)
} else {
Box::new(std::io::stdout())
};
part_table.save_bin(&mut writer).into_diagnostic()?;
} else if opts.to_csv {
let input = fs::read(&opts.partition_table).into_diagnostic()?;
let part_table = PartitionTable::try_from_bytes(input).into_diagnostic()?;

// Use either stdout or a file if provided for the output.
let mut writer: Box<dyn Write> = if let Some(output) = opts.output {
Box::new(fs::File::create(output).into_diagnostic()?)
} else {
Box::new(std::io::stdout())
};
part_table.save_csv(&mut writer).into_diagnostic()?;
} else if opts.info {
let input = fs::read(&opts.partition_table).into_diagnostic()?;

// Try getting the partition table from either the csv or the binary representation and
// fail otherwise.
let part_table = if let Ok(part_table) =
PartitionTable::try_from_bytes(input.clone()).into_diagnostic()
{
part_table
} else if let Ok(part_table) =
PartitionTable::try_from_str(String::from_utf8(input).into_diagnostic()?)
{
part_table
} else {
return Err((InvalidPartitionTable {}).into());
};

part_table.pretty_print();
}

Ok(())
}

#[cfg(unix)]
fn exit_with_process_status(status: ExitStatus) -> ! {
use std::os::unix::process::ExitStatusExt;
Expand Down
3 changes: 2 additions & 1 deletion espflash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = [
"Jesse Braham <[email protected]>",
]
edition = "2021"
rust-version = "1.56"
rust-version = "1.58"
description = "A command-line tool for flashing Espressif devices over serial"
repository = "https://github.com/esp-rs/espflash"
license = "GPL-2.0"
Expand Down Expand Up @@ -35,6 +35,7 @@ path = "src/main.rs"
binread = "2.2"
bytemuck = { version = "1.9", features = ["derive"] }
clap = { version = "3.1", features = ["derive"] }
comfy-table = "5"
crossterm = "0.23"
csv = "1.1"
dialoguer = "0.10"
Expand Down
32 changes: 32 additions & 0 deletions espflash/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,18 @@ pub enum PartitionTableError {
#[error(transparent)]
#[diagnostic(transparent)]
UnalignedPartitionError(#[from] UnalignedPartitionError),
#[error(transparent)]
#[diagnostic(transparent)]
LengthNotMultipleOf32(#[from] LengthNotMultipleOf32),
#[error(transparent)]
#[diagnostic(transparent)]
InvalidChecksum(#[from] InvalidChecksum),
#[error(transparent)]
#[diagnostic(transparent)]
NoEndMarker(#[from] NoEndMarker),
#[error(transparent)]
#[diagnostic(transparent)]
InvalidPartitionTable(#[from] InvalidPartitionTable),
}

#[derive(Debug, Error, Diagnostic)]
Expand Down Expand Up @@ -535,6 +547,26 @@ impl UnalignedPartitionError {
}
}

#[derive(Debug, Error, Diagnostic)]
#[error("Partition table length not a multiple of 32")]
#[diagnostic(code(espflash::partition_table::invalid_length))]
pub struct LengthNotMultipleOf32;

#[derive(Debug, Error, Diagnostic)]
#[error("Checksum invalid")]
#[diagnostic(code(espflash::partition_table::invalid_checksum))]
pub struct InvalidChecksum;

#[derive(Debug, Error, Diagnostic)]
#[error("No end marker found")]
#[diagnostic(code(espflash::partition_table::no_end_marker))]
pub struct NoEndMarker;

#[derive(Debug, Error, Diagnostic)]
#[error("Invalid partition table")]
#[diagnostic(code(espflash::partition_table::invalid_partition_table))]
pub struct InvalidPartitionTable;

#[derive(Debug, Error)]
#[error("{0}")]
pub struct ElfError(&'static str);
Expand Down
2 changes: 1 addition & 1 deletion espflash/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub use chip::Chip;
pub use cli::config::Config;
pub use elf::{FlashFrequency, FlashMode};
pub use error::Error;
pub use error::{Error, InvalidPartitionTable};
pub use flasher::{FlashSize, Flasher};
pub use image_format::ImageFormatId;
pub use partition_table::PartitionTable;
Expand Down
Loading

0 comments on commit 711039c

Please sign in to comment.