From 0afcb65950147e9672c041c7177f12a37b96101e Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Mon, 27 Mar 2023 12:58:52 -0700 Subject: [PATCH] feat: Add patch command for use by cli (#179) --- Cargo.toml | 2 +- library/src/config.rs | 2 ++ patch/Cargo.toml | 15 +++++++++++++ patch/README.md | 13 +++++++++++ patch/src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 patch/Cargo.toml create mode 100644 patch/README.md create mode 100644 patch/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index bcbfce6..ee7db42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["cli", "library"] \ No newline at end of file +members = ["cli", "library", "patch"] \ No newline at end of file diff --git a/library/src/config.rs b/library/src/config.rs index 7dbaeb6..fb52b41 100644 --- a/library/src/config.rs +++ b/library/src/config.rs @@ -96,6 +96,8 @@ pub fn current_arch() -> &'static str { static ARCH: &str = "x86_64"; #[cfg(target_arch = "aarch64")] static ARCH: &str = "aarch64"; + #[cfg(target_arch = "arm")] + static ARCH: &str = "arm"; return ARCH; } diff --git a/patch/Cargo.toml b/patch/Cargo.toml new file mode 100644 index 0000000..62295a4 --- /dev/null +++ b/patch/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "patch" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# Compression and decompression of patch files. +bidiff = "1.0.0" +# Pipe is a simple in-memory pipe implementation, there might be a std way too? +pipe = "0.4.0" +# comde is a wrapper around several compression libraries. +# We only use zstd and could depend on it directly instead. +comde = {version = "0.2.3", default-features = false, features = ["zstandard"]} diff --git a/patch/README.md b/patch/README.md new file mode 100644 index 0000000..394c6ff --- /dev/null +++ b/patch/README.md @@ -0,0 +1,13 @@ +# patch command line tool + +This is the tool used by the `shorebird` command line to compute the patch +file for uploading to the server. + +This currently uses the rust `bidiff` crate to compute the patch file. +and could just use the `bic` command line tool included in that crate. However +we're explicitly writing our own command line to allow us to change the +underlying compression without affecting the `shorebird` command line callers. + +## Usage + + patch diff --git a/patch/src/main.rs b/patch/src/main.rs new file mode 100644 index 0000000..bf58a5e --- /dev/null +++ b/patch/src/main.rs @@ -0,0 +1,52 @@ +use bidiff::DiffParams; +use std::{ + fs::{self, File}, + io::{BufWriter, Write}, + time::Instant, +}; + +use comde::com::Compressor; +use comde::zstd::ZstdCompressor; + +// Originally inspired from example in: +// https://github.com/divvun/bidiff/blob/main/crates/bic/src/main.rs +// and then hacked down to just service our needs. + +// comde is just a wrapper around various compression/decompression libraries. +// and we could just depend on the zstd crate directly if we end up using +// zstd long term. + +fn main() { + let mut args = std::env::args(); + args.next(); // skip program name + let older = args.next().expect("path to base file"); + let newer = args.next().expect("path to new file"); + let patch = args.next().expect("path to output file"); + + let start = Instant::now(); + + let older_contents = fs::read(older).expect("read base file"); + let newer_contents = fs::read(newer).expect("read new file"); + + let (mut patch_r, mut patch_w) = pipe::pipe(); + let diff_params = DiffParams::new(1, None).unwrap(); + std::thread::spawn(move || { + bidiff::simple_diff_with_params( + &older_contents[..], + &newer_contents[..], + &mut patch_w, + &diff_params, + ) + .unwrap(); + }); + + let compressor = ZstdCompressor::new(); + + let mut compatch_w = BufWriter::new(File::create(patch).expect("create patch file")); + compressor + .compress(&mut compatch_w, &mut patch_r) + .expect("compress patch"); + compatch_w.flush().expect("flush patch"); + + println!("Completed in {:?}", start.elapsed()); +}