From 00f2057ae488c75b656326c73e6fbda6963c585e Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:52:06 +0900 Subject: [PATCH 01/58] Create rust.yml --- .github/workflows/rust.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..31000a2 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,22 @@ +name: Rust + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose From 462c34cf96c21231457129cae9d1fe4c9315b1f0 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Thu, 25 Apr 2024 16:46:59 +0900 Subject: [PATCH 02/58] [fix] test: setup gitconfig at repo init --- tests/cli.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/cli.rs b/tests/cli.rs index f27e1bd..de3bf6e 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -1,5 +1,8 @@ mod integrated_test { - use std::fs::DirBuilder; + use std::{ + fs::{DirBuilder, File}, + io::{BufWriter, Write}, path::Path, + }; use anyhow::{Ok, Result}; use assert_cmd::{assert::OutputAssertExt, Command}; @@ -7,9 +10,27 @@ mod integrated_test { use log::trace; use predicates::prelude::predicate; + fn setup_gitconfig(dir_path: &Path) -> Result<()> { + DirBuilder::new().create(dir_path.join(".git"))?; + { + let f = File::create(dir_path.join(".git/config"))?; + let mut buf = BufWriter::new(f); + buf.write_all( + r#" + [user] + email = "test@example.com" + name = "testuser" + "# + .as_bytes(), + )?; + } + Ok(()) + } + #[test] fn single_device() -> Result<()> { let config_dir = assert_fs::TempDir::new()?; + setup_gitconfig(&config_dir)?; // init let mut cmd = Command::cargo_bin("xdbm")?; cmd.arg("-c") @@ -103,6 +124,7 @@ mod integrated_test { fn two_devices_with_same_name() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; + setup_gitconfig(&config_dir_1)?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) @@ -127,6 +149,7 @@ mod integrated_test { // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; + setup_gitconfig(&config_dir_2)?; let mut cmd2 = Command::cargo_bin("xdbm")?; cmd2.arg("-c") .arg(config_dir_2.path()) @@ -142,6 +165,7 @@ mod integrated_test { fn directory_without_parent() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; + setup_gitconfig(&config_dir_1)?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) @@ -174,6 +198,7 @@ mod integrated_test { fn two_devices() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; + setup_gitconfig(&config_dir_1)?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) From 30ae6a6417a6810be70bbc04d2f581c60a5d63ac Mon Sep 17 00:00:00 2001 From: qwjyh Date: Thu, 25 Apr 2024 17:01:34 +0900 Subject: [PATCH 03/58] fixup! [fix] test: setup gitconfig at repo init --- tests/cli.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index de3bf6e..b1b8fe9 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -1,7 +1,8 @@ mod integrated_test { use std::{ fs::{DirBuilder, File}, - io::{BufWriter, Write}, path::Path, + io::{BufWriter, Write}, + path::Path, }; use anyhow::{Ok, Result}; @@ -17,10 +18,10 @@ mod integrated_test { let mut buf = BufWriter::new(f); buf.write_all( r#" - [user] - email = "test@example.com" - name = "testuser" - "# +[user] + email = "test@example.com" + name = "testuser" +"# .as_bytes(), )?; } From 607013c6499b528db73a68547b7cec06a2c0c01f Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 26 Apr 2024 00:21:42 +0900 Subject: [PATCH 04/58] fixup! [fix] test: setup gitconfig at repo init --- tests/cli.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cli.rs b/tests/cli.rs index b1b8fe9..f3cd9d1 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -3,6 +3,8 @@ mod integrated_test { fs::{DirBuilder, File}, io::{BufWriter, Write}, path::Path, + thread, + time::Duration, }; use anyhow::{Ok, Result}; @@ -118,6 +120,12 @@ mod integrated_test { .assert() .success(); + let out = std::process::Command::new("git") + .arg("config") + .arg("--get") + .arg("user.email") + .output()?; + panic!("{}", String::from_utf8_lossy(&out.stdout)); Ok(()) } From 4fcb7fc354faefe900725ac48574c83369ae7e03 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 26 Apr 2024 01:35:42 +0900 Subject: [PATCH 05/58] fixup! [fix] test: setup gitconfig at repo init --- tests/cli.rs | 54 +++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index f3cd9d1..4b2ff14 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -1,39 +1,47 @@ mod integrated_test { use std::{ fs::{DirBuilder, File}, - io::{BufWriter, Write}, - path::Path, - thread, - time::Duration, + io::{self, BufWriter, Write}, }; - use anyhow::{Ok, Result}; + use anyhow::{Context, Ok, Result}; use assert_cmd::{assert::OutputAssertExt, Command}; + use dirs::home_dir; use git2::Repository; use log::trace; use predicates::prelude::predicate; - fn setup_gitconfig(dir_path: &Path) -> Result<()> { - DirBuilder::new().create(dir_path.join(".git"))?; - { - let f = File::create(dir_path.join(".git/config"))?; - let mut buf = BufWriter::new(f); - buf.write_all( - r#" + /// Setup global gitconfig if it doesn't exist. + /// + /// # Errors + /// + /// This function will return an error if it failed to get home directory. + fn setup_gitconfig() -> Result<()> { + let f = match File::create_new( + home_dir() + .context("Failed to find home directory")? + .join(".gitconfig"), + ) { + io::Result::Ok(f) => f, + io::Result::Err(_err) => return Ok(()), + }; + let mut buf = BufWriter::new(f); + buf.write_all( + r#" [user] email = "test@example.com" name = "testuser" "# - .as_bytes(), - )?; - } + .as_bytes(), + )?; + Ok(()) } #[test] fn single_device() -> Result<()> { let config_dir = assert_fs::TempDir::new()?; - setup_gitconfig(&config_dir)?; + setup_gitconfig()?; // init let mut cmd = Command::cargo_bin("xdbm")?; cmd.arg("-c") @@ -120,12 +128,6 @@ mod integrated_test { .assert() .success(); - let out = std::process::Command::new("git") - .arg("config") - .arg("--get") - .arg("user.email") - .output()?; - panic!("{}", String::from_utf8_lossy(&out.stdout)); Ok(()) } @@ -133,7 +135,7 @@ mod integrated_test { fn two_devices_with_same_name() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; - setup_gitconfig(&config_dir_1)?; + setup_gitconfig()?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) @@ -158,7 +160,7 @@ mod integrated_test { // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; - setup_gitconfig(&config_dir_2)?; + setup_gitconfig()?; let mut cmd2 = Command::cargo_bin("xdbm")?; cmd2.arg("-c") .arg(config_dir_2.path()) @@ -174,7 +176,7 @@ mod integrated_test { fn directory_without_parent() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; - setup_gitconfig(&config_dir_1)?; + setup_gitconfig()?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) @@ -207,7 +209,7 @@ mod integrated_test { fn two_devices() -> Result<()> { // 1st device let config_dir_1 = assert_fs::TempDir::new()?; - setup_gitconfig(&config_dir_1)?; + setup_gitconfig()?; let mut cmd1 = Command::cargo_bin("xdbm")?; cmd1.arg("-c") .arg(config_dir_1.path()) From c9eb34aa69fb07f41b176eaf448557cd41996bfa Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sat, 4 May 2024 14:55:00 +0900 Subject: [PATCH 06/58] fix test to fetch refspecs from the git2 --- tests/cli.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index 4b2ff14..3bf833f 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -151,12 +151,13 @@ mod integrated_test { let upstream_name = "remote"; let mut repo_1_remote = repo_1.remote(upstream_name, bare_repo_dir.path().to_str().unwrap())?; - repo_1_remote.push(&["refs/heads/main"], None)?; + repo_1_remote.push(&[repo_1.head().unwrap().name().unwrap()] as &[&str], None)?; trace!("bare repo {:?}", bare_repo_dir.display()); println!("{:?}", bare_repo_dir.read_dir()?); // set up upstream branch let (mut repo_1_branch, _branch_type) = repo_1.branches(None)?.next().unwrap()?; - repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, "main").as_str()))?; + println!("head {}", repo_1.head().unwrap().name().unwrap()); + repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, repo_1_branch.name().unwrap().unwrap()).as_str()))?; // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; @@ -225,12 +226,12 @@ mod integrated_test { let upstream_name = "remote"; let mut repo_1_remote = repo_1.remote(upstream_name, bare_repo_dir.path().to_str().unwrap())?; - repo_1_remote.push(&["refs/heads/main"], None)?; + repo_1_remote.push(&[repo_1.head().unwrap().name().unwrap()], None)?; trace!("bare repo {:?}", bare_repo_dir.display()); println!("{:?}", bare_repo_dir.read_dir()?); // set up upstream branch let (mut repo_1_branch, _branch_type) = repo_1.branches(None)?.next().unwrap()?; - repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, "main").as_str()))?; + repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, repo_1_branch.name().unwrap().unwrap()).as_str()))?; // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; From 51fd4207ea7924df861e8258a05f05d3f092dae5 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sat, 4 May 2024 15:03:02 +0900 Subject: [PATCH 07/58] fixup! fix test to fetch refspecs from the git2 --- tests/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cli.rs b/tests/cli.rs index 3bf833f..45bc945 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -151,7 +151,7 @@ mod integrated_test { let upstream_name = "remote"; let mut repo_1_remote = repo_1.remote(upstream_name, bare_repo_dir.path().to_str().unwrap())?; - repo_1_remote.push(&[repo_1.head().unwrap().name().unwrap()] as &[&str], None)?; + repo_1_remote.push(&[repo_1.head().unwrap().name().unwrap()], None)?; trace!("bare repo {:?}", bare_repo_dir.display()); println!("{:?}", bare_repo_dir.read_dir()?); // set up upstream branch From feb51a56537cbf9ac40a1f3fa2fa070c68e4be5d Mon Sep 17 00:00:00 2001 From: qwjyh Date: Tue, 21 May 2024 14:34:30 +0900 Subject: [PATCH 08/58] replace HashMap with BTreeMap in Storages and Backups to produce cleaner git log --- src/backups.rs | 6 +++--- src/storages.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backups.rs b/src/backups.rs index c312949..fbb4c1f 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -3,7 +3,7 @@ use core::panic; use std::{ - collections::HashMap, + collections::BTreeMap, fs, io, path::{Path, PathBuf}, }; @@ -202,14 +202,14 @@ impl Backup { #[derive(Debug, Serialize, Deserialize)] pub struct Backups { - pub list: HashMap, + pub list: BTreeMap, } impl Backups { /// Empty [`Backups`]. pub fn new() -> Backups { Backups { - list: HashMap::new(), + list: BTreeMap::new(), } } diff --git a/src/storages.rs b/src/storages.rs index b67b9cf..fd02ef3 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -9,7 +9,7 @@ use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; use core::panic; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt, fs, io, path, u64}; +use std::{collections::BTreeMap, fmt, fs, io, path, u64}; /// YAML file to store known storages.. pub const STORAGESFILE: &str = "storages.yml"; @@ -157,14 +157,14 @@ pub mod physical_drive_partition; #[derive(Debug, Serialize, Deserialize)] pub struct Storages { - pub list: HashMap, + pub list: BTreeMap, } impl Storages { /// Construct empty [`Storages`] pub fn new() -> Storages { Storages { - list: HashMap::new(), + list: BTreeMap::new(), } } From df0ce53d8400bb4fa98d75759f4f240ddb5bc1df Mon Sep 17 00:00:00 2001 From: qwjyh Date: Tue, 21 May 2024 14:44:53 +0900 Subject: [PATCH 09/58] fixup! replace HashMap with BTreeMap in Storages and Backups --- src/storages.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storages.rs b/src/storages.rs index fd02ef3..8137546 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -135,7 +135,7 @@ pub trait StorageExt { fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo>; /// Get mount path of `self` on `device`. - /// `storages` is a `HashMap` with key of storage name and value of the storage. + /// `storages` is a `BTreeMap` with key of storage name and value of the storage. fn mount_path(&self, device: &devices::Device) -> Result; /// Add local info of `device` to `self`. From 87b73bd125c709eff00ece679cefe8d96e1a8ea0 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Tue, 21 May 2024 14:45:20 +0900 Subject: [PATCH 10/58] change types for localinfos --- src/cmd_backup.rs | 12 ++++++------ src/storages/directory.rs | 12 ++++++------ src/storages/online_storage.rs | 6 +++--- src/storages/physical_drive_partition.rs | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index 90c909f..618ad6c 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -1,5 +1,5 @@ use std::{ - collections::HashMap, + collections::BTreeMap, io::{self, stdout, Write}, path::{Path, PathBuf}, }; @@ -103,14 +103,14 @@ pub fn cmd_backup_list( storages: &Storages, ) -> Result<()> { let devices = devices::get_devices(config_dir)?; - let backups: HashMap<(String, String), Backup> = match device_name { + let backups: BTreeMap<(String, String), Backup> = match device_name { Some(device_name) => { let device = devices .iter() .find(|dev| dev.name() == device_name) .context(format!("Device with name {} doesn't exist", device_name))?; let backups = Backups::read(config_dir, device)?; - let mut allbackups = HashMap::new(); + let mut allbackups = BTreeMap::new(); for (name, backup) in backups.list { if allbackups.insert((device.name(), name), backup).is_some() { return Err(anyhow!("unexpected duplication in backups hashmap")); @@ -119,7 +119,7 @@ pub fn cmd_backup_list( allbackups } None => { - let mut allbackups = HashMap::new(); + let mut allbackups = BTreeMap::new(); for device in &devices { let backups = Backups::read(config_dir, device)?; for (name, backup) in backups.list { @@ -132,7 +132,7 @@ pub fn cmd_backup_list( } }; // source/destination filtering - let backups: HashMap<(String, String), Backup> = backups + let backups: BTreeMap<(String, String), Backup> = backups .into_iter() .filter(|((_dev, _name), backup)| { let src_matched = match &src_storage { @@ -156,7 +156,7 @@ pub fn cmd_backup_list( /// TODO: status printing fn write_backups_list( mut writer: impl io::Write, - backups: HashMap<(String, String), Backup>, + backups: BTreeMap<(String, String), Backup>, longprint: bool, storages: &Storages, devices: &[Device], diff --git a/src/storages/directory.rs b/src/storages/directory.rs index e78e2c9..7887c7b 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt, path}; +use std::{collections::BTreeMap, fmt, path}; use crate::devices; use crate::util; @@ -20,7 +20,7 @@ pub struct Directory { relative_path: path::PathBuf, pub notes: String, /// Device and localinfo pairs. - local_infos: HashMap, + local_infos: BTreeMap, } impl Directory { @@ -33,7 +33,7 @@ impl Directory { parent: String, relative_path: path::PathBuf, notes: String, - local_infos: HashMap, + local_infos: BTreeMap, ) -> Directory { Directory { name, @@ -61,7 +61,7 @@ impl Directory { parent.name().to_string(), diff_path, notes, - HashMap::from([(device.name(), local_info)]), + BTreeMap::from([(device.name(), local_info)]), )) } @@ -142,7 +142,7 @@ impl fmt::Display for Directory { #[cfg(test)] mod test { - use std::{collections::HashMap, path::PathBuf}; + use std::{collections::BTreeMap, path::PathBuf}; use crate::{ devices::Device, @@ -161,7 +161,7 @@ mod test { let local_info_dir = LocalInfo::new("dir_alias".to_string(), PathBuf::from("/mnt/sample/subdir")); let device = Device::new("test_device".to_string()); - let mut local_infos = HashMap::new(); + let mut local_infos = BTreeMap::new(); local_infos.insert(device.name(), local_info_dir); let physical = PhysicalDrivePartition::new( "parent".to_string(), diff --git a/src/storages/online_storage.rs b/src/storages/online_storage.rs index 8ffafde..810600d 100644 --- a/src/storages/online_storage.rs +++ b/src/storages/online_storage.rs @@ -3,7 +3,7 @@ use anyhow::{Context, Result}; use byte_unit::Byte; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::fmt; use std::path; @@ -23,7 +23,7 @@ pub struct OnlineStorage { /// Capacity in bytes. capacity: u64, /// Device and local info pairs. - local_infos: HashMap, + local_infos: BTreeMap, } impl OnlineStorage { @@ -42,7 +42,7 @@ impl OnlineStorage { name, provider, capacity, - local_infos: HashMap::from([(device.name(), local_info)]), + local_infos: BTreeMap::from([(device.name(), local_info)]), } } } diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index b3fb531..1ad79bb 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, Context, Result}; use byte_unit::Byte; use serde::{Deserialize, Serialize}; use std::path::{self, Path}; -use std::{collections::HashMap, fmt}; +use std::{collections::BTreeMap, fmt}; use sysinfo::{Disk, DiskExt, SystemExt}; use super::local_info::{self, LocalInfo}; @@ -20,8 +20,8 @@ pub struct PhysicalDrivePartition { capacity: u64, fs: String, is_removable: bool, - // system_names: HashMap, - local_infos: HashMap, + // system_names: BTreeMap, + local_infos: BTreeMap, } impl PhysicalDrivePartition { @@ -40,7 +40,7 @@ impl PhysicalDrivePartition { capacity, fs, is_removable, - local_infos: HashMap::from([(device.name(), local_info)]), + local_infos: BTreeMap::from([(device.name(), local_info)]), } } @@ -65,8 +65,8 @@ impl PhysicalDrivePartition { capacity: disk.total_space(), fs: fs.to_string(), is_removable: disk.is_removable(), - // system_names: HashMap::from([(device.name(), alias)]), - local_infos: HashMap::from([(device.name(), local_info)]), + // system_names: BTreeMap::from([(device.name(), alias)]), + local_infos: BTreeMap::from([(device.name(), local_info)]), }) } From d64cf6e255a6813d1eeeba97cd46715ab4a30627 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Tue, 21 May 2024 17:59:28 +0900 Subject: [PATCH 11/58] Updated CHANGELOG regarding #10 and #11 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4ad16..69a056a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [unreleased] + +### Changed +- Added CI on GitHub Actions (#10). +- Replaced `HashMap` with `BTreeMap` to produce cleaner diff (#11). + ## [0.1.0] - 2024-03-18 ### Added @@ -15,4 +21,5 @@ - `backup done` subcommand - `completion` subcommand +[unreleased]: https://github.com/qwjyh/xdbm/compare/v0.1.0...HEAD [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 From fe2847ba5b6cc7285728eb1b2fc627c28b4ba7e7 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Tue, 21 May 2024 18:02:39 +0900 Subject: [PATCH 12/58] bump version to v0.2.0 --- CHANGELOG.md | 4 ++-- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a056a..45a900a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [unreleased] +## [0.2.0] - 2024-05-21 ### Changed - Added CI on GitHub Actions (#10). @@ -21,5 +21,5 @@ - `backup done` subcommand - `completion` subcommand -[unreleased]: https://github.com/qwjyh/xdbm/compare/v0.1.0...HEAD +[0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index d587138..1c72acc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1438,7 +1438,7 @@ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "xdbm" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index bee6887..84026ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xdbm" -version = "0.1.0" +version = "0.2.0" authors = ["qwjyh "] edition = "2021" description = "Cross device backup manager, which manages backups on several storages mounted on multiple devices." From 0f7095b229d7554772adf56c3beb6d0d48b05670 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 16:08:11 +0900 Subject: [PATCH 13/58] update libgit2-sys for dependabot alerts #2 https://github.com/qwjyh/xdbm/security/dependabot/2 --- Cargo.lock | 332 ++++++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- 2 files changed, 174 insertions(+), 160 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c72acc..c1db760 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -28,47 +28,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -76,9 +77,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "assert_cmd" @@ -112,9 +113,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" @@ -124,9 +125,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bstr" @@ -141,9 +142,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-unit" @@ -157,12 +158,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -173,9 +175,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -183,14 +185,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "clap" -version = "4.5.3" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -208,9 +210,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", @@ -220,18 +222,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.1" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" +checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.3" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", "proc-macro2", @@ -241,15 +243,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "core-foundation-sys" @@ -278,9 +280,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" @@ -354,9 +356,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "env_logger" @@ -379,9 +381,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -389,9 +391,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "float-cmp" @@ -413,9 +415,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -424,11 +426,11 @@ dependencies = [ [[package]] name = "git2" -version = "0.17.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "libc", "libgit2-sys", "log", @@ -456,16 +458,16 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "ignore", "walkdir", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -536,9 +538,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -572,16 +574,22 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.10" +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -603,15 +611,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libgit2-sys" -version = "0.15.2+1.6.4" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", @@ -623,13 +631,12 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] @@ -648,9 +655,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -660,15 +667,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -682,9 +689,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mio" @@ -724,9 +731,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -745,9 +752,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -763,9 +770,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -773,15 +780,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -834,27 +841,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -872,18 +879,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -892,9 +899,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -904,9 +911,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -915,17 +922,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -934,9 +941,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -955,18 +962,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -975,9 +982,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.33" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", "itoa", @@ -1009,30 +1016,30 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.53" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -1084,18 +1091,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -1146,9 +1153,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unsafe-libyaml" @@ -1158,9 +1165,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -1175,9 +1182,9 @@ checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vcpkg" @@ -1282,11 +1289,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -1301,7 +1308,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1319,7 +1326,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1339,17 +1346,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1360,9 +1368,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -1372,9 +1380,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -1384,9 +1392,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -1396,9 +1410,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -1408,9 +1422,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -1420,9 +1434,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -1432,9 +1446,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "xdbm" diff --git a/Cargo.toml b/Cargo.toml index 84026ab..1421af8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ clap_complete = "4.5.1" chrono = { version = "0.4.35", features = ["serde"] } env_logger = "0.10.0" inquire = "0.6.2" -git2 = "0.17.2" +git2 = "0.19" dirs = "5.0" dunce = "1.0.4" serde = { version = "1.0", features = ["derive"] } From 78b3d0d30887630080520f352b000867ca6a2700 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 17:33:58 +0900 Subject: [PATCH 14/58] update dependency: sysinfo 0.29 -> 0.30 --- Cargo.lock | 16 +++++++++++--- Cargo.toml | 2 +- src/devices.rs | 9 ++++---- src/storages/physical_drive_partition.rs | 28 ++++++++++-------------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1db760..7212ee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1048,9 +1048,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.11" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" dependencies = [ "cfg-if", "core-foundation-sys", @@ -1059,7 +1059,7 @@ dependencies = [ "once_cell", "rayon", "serde", - "winapi", + "windows", ] [[package]] @@ -1302,6 +1302,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 1421af8..9e0501f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["cli", "backup"] [dependencies] clap = { version = "4.4.0", features = ["cargo", "derive"] } -sysinfo = { version = "0.29.8", features = ["serde"] } +sysinfo = { version = "0.30", features = ["serde"] } log = "0.4" clap-verbosity-flag = "2.0.1" clap_complete = "4.5.1" diff --git a/src/devices.rs b/src/devices.rs index ab400a0..be81adb 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use std::fs::{File, OpenOptions}; use std::io::{BufRead, BufReader, BufWriter}; use std::path::Path; -use sysinfo::{System, SystemExt}; +use sysinfo::System; /// YAML file to store known devices. pub const DEVICESFILE: &str = "devices.yml"; @@ -25,18 +25,17 @@ impl Device { /// Create new `Device` of name `name`. Additional data is obtained via sysinfo. /// Filling fields which one failed to get is filled with "unknown". pub fn new(name: String) -> Device { - let sys = System::new(); Device { name, - os_name: sys.name().unwrap_or_else(|| { + os_name: System::name().unwrap_or_else(|| { warn!("Failed to get OS name. Saving as \"unknown\"."); "unknown".to_string() }), - os_version: sys.os_version().unwrap_or_else(|| { + os_version: System::os_version().unwrap_or_else(|| { warn!("Failed to get OS version. Saving as \"unknown\"."); "unknown".to_string() }), - hostname: sys.host_name().unwrap_or_else(|| { + hostname: System::host_name().unwrap_or_else(|| { warn!("Failed to get hostname. Saving as \"unknown\"."); "unknown".to_string() }), diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 1ad79bb..021b64b 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -8,7 +8,7 @@ use byte_unit::Byte; use serde::{Deserialize, Serialize}; use std::path::{self, Path}; use std::{collections::BTreeMap, fmt}; -use sysinfo::{Disk, DiskExt, SystemExt}; +use sysinfo::{Disk, Disks}; use super::local_info::{self, LocalInfo}; @@ -57,7 +57,10 @@ impl PhysicalDrivePartition { .to_string(); let fs = disk.file_system(); trace!("fs: {:?}", fs); - let fs = std::str::from_utf8(fs)?; + let fs: String = fs + .to_str() + .context("Failed to convert file_system osstr")? + .to_owned(); let local_info = LocalInfo::new(alias, disk.mount_point().to_path_buf()); Ok(PhysicalDrivePartition { name, @@ -161,13 +164,9 @@ pub fn select_physical_storage( ) -> Result { trace!("select_physical_storage"); // get disk info from sysinfo - let sys_disks = - sysinfo::System::new_with_specifics(sysinfo::RefreshKind::new().with_disks_list()); - trace!("refresh"); - // sys_disks.refresh_disks_list(); - // sys_disks.refresh_disks(); + let sys_disks = Disks::new_with_refreshed_list(); trace!("Available disks"); - for disk in sys_disks.disks() { + for disk in &sys_disks { trace!("{:?}", disk) } let disk = select_sysinfo_disk(&sys_disks)?; @@ -175,14 +174,13 @@ pub fn select_physical_storage( Ok(storage) } -fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> { - let available_disks = sysinfo - .disks() +fn select_sysinfo_disk(disks: &sysinfo::Disks) -> Result<&Disk> { + let available_disks = disks .iter() .enumerate() .map(|(i, disk)| { let name = disk.name().to_str().unwrap_or(""); - let fs: &str = std::str::from_utf8(disk.file_system()).unwrap_or("unknown"); + let fs: &str = disk.file_system().to_str().unwrap_or("unknown"); let kind = format!("{:?}", disk.kind()); let mount_path = disk.mount_point(); let total_space = byte_unit::Byte::from_bytes(disk.total_space().into()) @@ -203,10 +201,8 @@ fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> { let disk = inquire::Select::new("Select drive:", available_disks).prompt()?; let disk_num: usize = disk.split(':').next().unwrap().parse().unwrap(); trace!("disk_num: {}", disk_num); - let disk = sysinfo - .disks() - .iter() - .nth(disk_num) + let disk = disks + .get(disk_num) .context("no disk matched with selected one.")?; trace!("selected disk: {:?}", disk); Ok(disk) From 155992d1cc0c1dc524a23ff7e1c79a6bfc9b973e Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 17:37:19 +0900 Subject: [PATCH 15/58] fix clippy warnings --- src/cmd_init.rs | 2 +- src/devices.rs | 1 + src/inquire_filepath_completer.rs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cmd_init.rs b/src/cmd_init.rs index 7872aa2..415489a 100644 --- a/src/cmd_init.rs +++ b/src/cmd_init.rs @@ -44,7 +44,7 @@ fn clone_repo( .context("No username found from the url") .unwrap(), None, - &key as &Path, + key as &Path, passwd.as_deref(), ) } else if use_sshagent { diff --git a/src/devices.rs b/src/devices.rs index be81adb..8aba252 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -88,6 +88,7 @@ pub fn write_devices(config_dir: &Path, devices: Vec) -> Result<()> { trace!("write_devices"); let f = OpenOptions::new() .create(true) + .truncate(true) .write(true) .open(config_dir.join(DEVICESFILE))?; let writer = BufWriter::new(f); diff --git a/src/inquire_filepath_completer.rs b/src/inquire_filepath_completer.rs index d63fd24..9c8c905 100644 --- a/src/inquire_filepath_completer.rs +++ b/src/inquire_filepath_completer.rs @@ -17,7 +17,7 @@ impl FilePathCompleter { return Ok(()); } - self.input = input.to_owned(); + input.clone_into(&mut self.input); self.paths.clear(); let input_path = std::path::PathBuf::from(input); From a389935819fa3f1957336ae4d2858151be4163ad Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 17:37:42 +0900 Subject: [PATCH 16/58] update clap-verbosity-flag --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9e0501f..b0097d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["cli", "backup"] clap = { version = "4.4.0", features = ["cargo", "derive"] } sysinfo = { version = "0.30", features = ["serde"] } log = "0.4" -clap-verbosity-flag = "2.0.1" +clap-verbosity-flag = "2.2" clap_complete = "4.5.1" chrono = { version = "0.4.35", features = ["serde"] } env_logger = "0.10.0" From 44674262a622dc68a391605f27f287e0a3174220 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 18:07:31 +0900 Subject: [PATCH 17/58] update dependencies (especially byte_unit) - update formatting byte units --- Cargo.lock | 469 ++++++++++++++++++++--- Cargo.toml | 10 +- src/cmd_storage.rs | 13 +- src/storages/online_storage.rs | 8 +- src/storages/physical_drive_partition.rs | 8 +- 5 files changed, 435 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7212ee6..8b744bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -81,6 +92,12 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "assert_cmd" version = "2.0.14" @@ -129,6 +146,42 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "borsh" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.66", + "syn_derive", +] + [[package]] name = "bstr" version = "1.9.1" @@ -148,14 +201,49 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-unit" -version = "4.0.19" +version = "5.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" dependencies = [ + "rust_decimal", "serde", "utf8-width", ] +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + [[package]] name = "cc" version = "1.0.99" @@ -173,6 +261,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.38" @@ -238,7 +332,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.66", ] [[package]] @@ -361,16 +455,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] -name = "env_logger" -version = "0.10.2" +name = "env_filter" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" dependencies = [ - "humantime", - "is-terminal", "log", "regex", - "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", ] [[package]] @@ -413,6 +517,30 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -463,6 +591,15 @@ dependencies = [ "walkdir", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -475,12 +612,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "humantime" version = "2.1.0" @@ -543,36 +674,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] name = "inquire" -version = "0.6.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33e7c1ddeb15c9abcbfef6029d8e29f69b52b6d6c891031b88ed91b5065803b" +checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "crossterm", "dyn-clone", - "lazy_static", + "fuzzy-matcher", + "fxhash", "newline-converter", - "thiserror", + "once_cell", "unicode-segmentation", "unicode-width", ] -[[package]] -name = "is-terminal" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.0" @@ -603,12 +724,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.155" @@ -707,9 +822,9 @@ dependencies = [ [[package]] name = "newline-converter" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f" +checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" dependencies = [ "unicode-segmentation", ] @@ -809,6 +924,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "predicates" version = "3.1.0" @@ -839,6 +960,38 @@ dependencies = [ "termtree", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.85" @@ -848,6 +1001,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quote" version = "1.0.36" @@ -857,6 +1030,42 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -926,6 +1135,60 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustix" version = "0.38.34" @@ -960,6 +1223,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "serde" version = "1.0.203" @@ -977,7 +1246,18 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.66", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", ] [[package]] @@ -1023,6 +1303,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "smallvec" version = "1.13.2" @@ -1035,6 +1321,17 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.66" @@ -1046,6 +1343,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "sysinfo" version = "0.30.12" @@ -1062,6 +1371,12 @@ dependencies = [ "windows", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.10.1" @@ -1074,15 +1389,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "termtree" version = "0.4.1" @@ -1106,7 +1412,17 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.66", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", ] [[package]] @@ -1124,6 +1440,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -1186,12 +1519,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wait-timeout" version = "0.2.0" @@ -1238,7 +1583,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -1260,7 +1605,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1460,6 +1805,24 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "xdbm" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index b0097d6..d8151bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,16 +17,16 @@ clap = { version = "4.4.0", features = ["cargo", "derive"] } sysinfo = { version = "0.30", features = ["serde"] } log = "0.4" clap-verbosity-flag = "2.2" -clap_complete = "4.5.1" -chrono = { version = "0.4.35", features = ["serde"] } -env_logger = "0.10.0" -inquire = "0.6.2" +clap_complete = "4.5" +chrono = { version = "0.4", features = ["serde"] } +env_logger = "0.11.3" +inquire = "0.7.5" git2 = "0.19" dirs = "5.0" dunce = "1.0.4" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" -byte-unit = "4.0.19" +byte-unit = "5.1.4" anyhow = "1.0" pathdiff = "0.2.1" unicode-width = "0.1.11" diff --git a/src/cmd_storage.rs b/src/cmd_storage.rs index fb4194e..038a5fd 100644 --- a/src/cmd_storage.rs +++ b/src/cmd_storage.rs @@ -6,7 +6,7 @@ use std::{ }; use anyhow::{anyhow, Context, Result}; -use byte_unit::Byte; +use byte_unit::{Byte, UnitType}; use dunce::canonicalize; use git2::Repository; use inquire::{Confirm, CustomType, Text}; @@ -197,10 +197,11 @@ fn write_storages_list( trace!("name widths: {}", name_width); for storage in storages.list.values() { let size_str = match storage.capacity() { - Some(b) => Byte::from_bytes(b.into()) - .get_appropriate_unit(true) - .format(0) - .to_string(), + Some(b) => { + let size = Byte::from_u64(b).get_appropriate_unit(UnitType::Binary); + // TODO: split case for 500GB and 1.5TB? + format!("{:>+5.1}", size) + } None => "".to_string(), }; let isremovable = if let Storage::Physical(s) = storage { @@ -228,7 +229,7 @@ fn write_storages_list( }; writeln!( writer, - "{stype}{isremovable}: {name:8} {parent:10} {parent: Result { + fn mount_path(&self, device: &devices::Device) -> Result { Ok(self .local_infos .get(&device.name()) @@ -98,7 +96,7 @@ impl fmt::Display for OnlineStorage { f, "O {name:<10} {size:<10} {provider:<10}", name = self.name(), - size = Byte::from_bytes(self.capacity.into()).get_appropriate_unit(true), + size = Byte::from_u64(self.capacity).get_appropriate_unit(UnitType::Binary), provider = self.provider, ) } diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 021b64b..e1f97a9 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -4,7 +4,7 @@ use crate::devices; use crate::devices::Device; use crate::storages::{Storage, StorageExt, Storages}; use anyhow::{anyhow, Context, Result}; -use byte_unit::Byte; +use byte_unit::{Byte, UnitType}; use serde::{Deserialize, Serialize}; use std::path::{self, Path}; use std::{collections::BTreeMap, fmt}; @@ -148,7 +148,7 @@ impl fmt::Display for PhysicalDrivePartition { f, "P {name:<10} {size:<10} {removable:<1} {kind:<6} {fs:<5}", name = self.name(), - size = Byte::from_bytes(self.capacity.into()).get_appropriate_unit(true), + size = Byte::from_u64(self.capacity).get_appropriate_unit(UnitType::Binary), removable = removable_indicator, kind = self.kind, fs = self.fs, @@ -183,8 +183,8 @@ fn select_sysinfo_disk(disks: &sysinfo::Disks) -> Result<&Disk> { let fs: &str = disk.file_system().to_str().unwrap_or("unknown"); let kind = format!("{:?}", disk.kind()); let mount_path = disk.mount_point(); - let total_space = byte_unit::Byte::from_bytes(disk.total_space().into()) - .get_appropriate_unit(true) + let total_space = byte_unit::Byte::from_u64(disk.total_space()) + .get_appropriate_unit(UnitType::Binary) .to_string(); format!( "{}: {} {} ({}, {}) {}", From 46ffab3425bfb4f448fced8c595dea74de35a62f Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 18:09:20 +0900 Subject: [PATCH 18/58] update unicode-width --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d8151bf..3148273 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ serde_yaml = "0.9" byte-unit = "5.1.4" anyhow = "1.0" pathdiff = "0.2.1" -unicode-width = "0.1.11" +unicode-width = "0.1.13" [dev-dependencies] assert_cmd = "2.0.14" From f43b5088195094120a3f5a9f9c5f128dd86d9230 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 18:19:35 +0900 Subject: [PATCH 19/58] update byte formatting --- src/storages/online_storage.rs | 2 +- src/storages/physical_drive_partition.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/storages/online_storage.rs b/src/storages/online_storage.rs index 150f440..4ce2459 100644 --- a/src/storages/online_storage.rs +++ b/src/storages/online_storage.rs @@ -94,7 +94,7 @@ impl fmt::Display for OnlineStorage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "O {name:<10} {size:<10} {provider:<10}", + "O {name:<10} {size:<10.2} {provider:<10}", name = self.name(), size = Byte::from_u64(self.capacity).get_appropriate_unit(UnitType::Binary), provider = self.provider, diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index e1f97a9..95dec3f 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -146,7 +146,7 @@ impl fmt::Display for PhysicalDrivePartition { let removable_indicator = if self.is_removable { "+" } else { "-" }; write!( f, - "P {name:<10} {size:<10} {removable:<1} {kind:<6} {fs:<5}", + "P {name:<10} {size:<10.2} {removable:<1} {kind:<6} {fs:<5}", name = self.name(), size = Byte::from_u64(self.capacity).get_appropriate_unit(UnitType::Binary), removable = removable_indicator, @@ -184,10 +184,9 @@ fn select_sysinfo_disk(disks: &sysinfo::Disks) -> Result<&Disk> { let kind = format!("{:?}", disk.kind()); let mount_path = disk.mount_point(); let total_space = byte_unit::Byte::from_u64(disk.total_space()) - .get_appropriate_unit(UnitType::Binary) - .to_string(); + .get_appropriate_unit(UnitType::Binary); format!( - "{}: {} {} ({}, {}) {}", + "{}: {} {:>+5.1} ({}, {}) {}", i, name, total_space, From 1f7b992010a80e35649402c37e3059be8eaf4321 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 18:24:36 +0900 Subject: [PATCH 20/58] update changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a900a..7000c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [Unreleased] + +### Changed +- Dependencies are updated. +- Format of storage size printing has been changed due to the update of byte-unit. + +### Fixed +- `libgit2-sys` was updated due to the security issue. + ## [0.2.0] - 2024-05-21 ### Changed @@ -21,5 +30,6 @@ - `backup done` subcommand - `completion` subcommand +[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.2.0...HEAD [0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 From a7c81d59767236706c28a58137adf8c03312bf4d Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 19 Jun 2024 18:31:29 +0900 Subject: [PATCH 21/58] bump to v0.2.1 --- CHANGELOG.md | 4 ++-- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7000c8b..982082d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [0.2.1] - 2024-06-19 ### Changed - Dependencies are updated. @@ -30,6 +30,6 @@ - `backup done` subcommand - `completion` subcommand -[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.2.0...HEAD +[0.2.1]: https://github.com/qwjyh/xdbm/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index 8b744bd..efc48ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1825,7 +1825,7 @@ dependencies = [ [[package]] name = "xdbm" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index 3148273..8c7aa5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xdbm" -version = "0.2.0" +version = "0.2.1" authors = ["qwjyh "] edition = "2021" description = "Cross device backup manager, which manages backups on several storages mounted on multiple devices." From ea0acf177ce1f4caec7fb07bebedbe42f8299c4b Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:06:27 +0900 Subject: [PATCH 22/58] pretty printing (#15) * pretty printing for `backup list` and `backup list --long` * switch coloring crate from colored to console - console can handle Style separately * Style for storage list --- Cargo.lock | 26 +++++++++++++++ Cargo.toml | 1 + src/cmd_backup.rs | 80 +++++++++++++++++++++++++++++++++++----------- src/cmd_storage.rs | 20 ++++++------ src/storages.rs | 11 ++++++- src/util.rs | 1 + 6 files changed, 111 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efc48ce..acb12dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,6 +347,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -454,6 +467,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "env_filter" version = "0.1.0" @@ -724,6 +743,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -1835,6 +1860,7 @@ dependencies = [ "clap", "clap-verbosity-flag", "clap_complete", + "console", "dirs", "dunce", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index 8c7aa5a..c11d975 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ byte-unit = "5.1.4" anyhow = "1.0" pathdiff = "0.2.1" unicode-width = "0.1.13" +console = "0.15" [dev-dependencies] assert_cmd = "2.0.14" diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index 618ad6c..bcfd42b 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -5,7 +5,8 @@ use std::{ }; use anyhow::{anyhow, Context, Ok, Result}; -use chrono::Local; +use chrono::{Local, TimeDelta}; +use console::Style; use dunce::canonicalize; use git2::Repository; use unicode_width::UnicodeWidthStr; @@ -153,6 +154,17 @@ pub fn cmd_backup_list( Ok(()) } +fn duration_style(time: TimeDelta) -> Style { + match time { + x if x < TimeDelta::days(7) => Style::new().green(), + x if x < TimeDelta::days(14) => Style::new().yellow(), + x if x < TimeDelta::days(28) => Style::new().magenta(), + x if x < TimeDelta::days(28 * 3) => Style::new().red(), + x if x < TimeDelta::days(180) => Style::new().red().bold(), + _ => Style::new().on_red().black(), + } +} + /// TODO: status printing fn write_backups_list( mut writer: impl io::Write, @@ -188,39 +200,71 @@ fn write_backups_list( // main printing for ((dev, _name), backup) in &backups { let device = backup.device(devices).context(format!( - "Couldn't find device specified in backup config {}", + "Couldn't find the device specified in the backup config: {}", backup.name() ))?; let src = backup.source().path(storages, device)?; let dest = backup.destination().path(storages, device)?; let cmd_name = backup.command().name(); - let last_backup_elapsed = match backup.last_backup() { + let (last_backup_elapsed, style_on_time_elapsed) = match backup.last_backup() { Some(log) => { let time = Local::now() - log.datetime; - util::format_summarized_duration(time) + let s = util::format_summarized_duration(time); + let style = duration_style(time); + (style.apply_to(s), style) } - None => "---".to_string(), + None => { + let style = Style::new().red(); + (style.apply_to("---".to_string()), style) + }, }; - writeln!( - writer, - "{name: date.datetime.format("%Y-%m-%d %T").to_string(), + None => "never".to_string(), + }; + let cmd_note = backup.command().note(); + writeln!( + writer, + "{s_src} {src}", + s_src = console::style("src :").italic().bright().black(), + src = src.display() + )?; + writeln!( + writer, + "{s_dest} {dest}", + s_dest = console::style("dest:").italic().bright().black(), dest = dest.display() )?; writeln!( writer, - " {cmd_name:10} {parent:10} {parent: s.kind(), - Storage::SubDirectory(s) => &s.notes, - Storage::Online(s) => &s.provider, + Storage::Physical(s) => format!("kind: {}", s.kind()), + Storage::SubDirectory(s) => s.notes.clone(), + Storage::Online(s) => s.provider.clone(), }; - writeln!(writer, " {}", note)?; + writeln!(writer, " {}", style(note).italic())?; } } Ok(()) diff --git a/src/storages.rs b/src/storages.rs index 8137546..7562b0e 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -1,5 +1,6 @@ //! Manipulates storages. +use console::{style, Style, StyledObject}; use crate::devices; use crate::storages::{ directory::Directory, online_storage::OnlineStorage, @@ -9,7 +10,7 @@ use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; use core::panic; use serde::{Deserialize, Serialize}; -use std::{collections::BTreeMap, fmt, fs, io, path, u64}; +use std::{collections::BTreeMap, fmt, fs, io, path}; /// YAML file to store known storages.. pub const STORAGESFILE: &str = "storages.yml"; @@ -50,6 +51,14 @@ impl Storage { Self::Online(_) => "O", } } + + pub fn typestyle(&self) -> Style { + match self { + Storage::Physical(_) => Style::new().cyan(), + Storage::SubDirectory(_) => Style::new().yellow(), + Storage::Online(_) => Style::new().green(), + } + } } impl StorageExt for Storage { diff --git a/src/util.rs b/src/util.rs index 36c6714..820de33 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,7 @@ use std::path::{self, PathBuf}; use anyhow::{Context, Result}; +use console::Style; use crate::{ devices::Device, From 3b7e2387bdee8579bc802172c0b545342f43a9c7 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Thu, 27 Jun 2024 20:41:54 +0900 Subject: [PATCH 23/58] update CHANGELOG & README for #15 --- CHANGELOG.md | 6 ++++++ README.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 982082d..685004c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [Unreleased] + +### Changed +- Colored output for `storage list` and `backup list` ([#15](https://github.com/qwjyh/xdbm/pull/15)) + ## [0.2.1] - 2024-06-19 ### Changed @@ -30,6 +35,7 @@ - `backup done` subcommand - `completion` subcommand +[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.2.1...HEAD [0.2.1]: https://github.com/qwjyh/xdbm/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 diff --git a/README.md b/README.md index 15010ee..c626656 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ which manages backups on several storages mounted on multiple devices with a sin - [x] backup list - [x] status printing - [x] backup done -- [ ] fancy display +- [x] fancy display - [ ] json output - [ ] no commit option From b9bb207f35c6f5fb1af96866d06d36098618c7fa Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 28 Jun 2024 00:32:49 +0900 Subject: [PATCH 24/58] add integrated test --- tests/cli.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index 45bc945..ae5bd81 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -5,11 +5,11 @@ mod integrated_test { }; use anyhow::{Context, Ok, Result}; - use assert_cmd::{assert::OutputAssertExt, Command}; + use assert_cmd::{assert::OutputAssertExt, cargo::CommandCargoExt, Command}; use dirs::home_dir; use git2::Repository; use log::trace; - use predicates::prelude::predicate; + use predicates::{boolean::PredicateBooleanExt, prelude::predicate}; /// Setup global gitconfig if it doesn't exist. /// @@ -157,7 +157,14 @@ mod integrated_test { // set up upstream branch let (mut repo_1_branch, _branch_type) = repo_1.branches(None)?.next().unwrap()?; println!("head {}", repo_1.head().unwrap().name().unwrap()); - repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, repo_1_branch.name().unwrap().unwrap()).as_str()))?; + repo_1_branch.set_upstream(Some( + format!( + "{}/{}", + upstream_name, + repo_1_branch.name().unwrap().unwrap() + ) + .as_str(), + ))?; // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; @@ -231,7 +238,14 @@ mod integrated_test { println!("{:?}", bare_repo_dir.read_dir()?); // set up upstream branch let (mut repo_1_branch, _branch_type) = repo_1.branches(None)?.next().unwrap()?; - repo_1_branch.set_upstream(Some(format!("{}/{}", upstream_name, repo_1_branch.name().unwrap().unwrap()).as_str()))?; + repo_1_branch.set_upstream(Some( + format!( + "{}/{}", + upstream_name, + repo_1_branch.name().unwrap().unwrap() + ) + .as_str(), + ))?; // 2nd device let config_dir_2 = assert_fs::TempDir::new()?; @@ -358,6 +372,7 @@ mod integrated_test { .assert() .success(); + // storage list Command::cargo_bin("xdbm")? .arg("-c") .arg(config_dir_2.path()) @@ -365,7 +380,9 @@ mod integrated_test { .arg("list") .arg("-l") .assert() - .success(); + .success() + .stdout(predicate::str::contains("gdrive_docs").and(predicate::str::contains("nas"))); + // backup add let backup_src = &sample_storage_2.join("foo").join("bar"); DirBuilder::new().recursive(true).create(backup_src)?; @@ -387,6 +404,7 @@ mod integrated_test { .assert() .success(); + // backup add but with existing name Command::cargo_bin("xdbm")? .arg("-c") .arg(config_dir_2.path()) @@ -404,6 +422,32 @@ mod integrated_test { .failure() .stderr(predicate::str::contains("already")); + // backup list + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("backup") + .arg("list") + .assert() + .success() + .stdout( + predicate::str::contains("foodoc") + .and(predicate::str::contains("nas")) + .and(predicate::str::contains("gdrive_docs")) + .and(predicate::str::contains("---")), + ); + + // backup done + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("backup") + .arg("done") + .arg("foodoc") + .arg("0") + .assert() + .success(); + Ok(()) } } From 6e1619aa18f9fc40d5b9b7ed6ee9a1f9856f4444 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 28 Jun 2024 00:33:45 +0900 Subject: [PATCH 25/58] fmt --- src/cmd_args.rs | 4 +--- src/cmd_backup.rs | 2 +- src/storages.rs | 2 +- src/storages/directory.rs | 4 +--- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/cmd_args.rs b/src/cmd_args.rs index 28a41ec..70a8033 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -57,9 +57,7 @@ pub(crate) enum Commands { Check {}, /// Generate completion script. - Completion { - shell: clap_complete::Shell, - } + Completion { shell: clap_complete::Shell }, } #[derive(Args, Debug)] diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index bcfd42b..7ae9767 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -216,7 +216,7 @@ fn write_backups_list( None => { let style = Style::new().red(); (style.apply_to("---".to_string()), style) - }, + } }; if !longprint { writeln!( diff --git a/src/storages.rs b/src/storages.rs index 7562b0e..4031d61 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -1,6 +1,5 @@ //! Manipulates storages. -use console::{style, Style, StyledObject}; use crate::devices; use crate::storages::{ directory::Directory, online_storage::OnlineStorage, @@ -8,6 +7,7 @@ use crate::storages::{ }; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; +use console::{style, Style, StyledObject}; use core::panic; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, fmt, fs, io, path}; diff --git a/src/storages/directory.rs b/src/storages/directory.rs index 7887c7b..4cd7803 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -180,9 +180,7 @@ mod test { local_infos, ); let mut storages = Storages::new(); - storages - .add(storages::Storage::Physical(physical)) - .unwrap(); + storages.add(storages::Storage::Physical(physical)).unwrap(); storages.add(Storage::SubDirectory(directory)).unwrap(); // assert_eq!(directory.name(), "test_name"); assert_eq!( From 0abf9c0693e9c6210c3ffbb7fb8126b3a0579cb0 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 15 Jul 2024 12:12:38 +0900 Subject: [PATCH 26/58] update readme --- README.md | 5 ++++- tests/cli.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c626656..8dd916f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ _Cross device backup manager_, which manages backups on several storages mounted on multiple devices with a single repository. +## Install +- `git` is required for sync + ## Usage 1. `xdbm init` to setup new device(i.e. PC). 2. `xdbm storage add` to add storages, or `xdbm storage bind` to make existing storages available on new device. @@ -24,7 +27,7 @@ which manages backups on several storages mounted on multiple devices with a sin - [ ] write test for storage subcommand - [x] storage add online - [x] storage add directory - - [ ] storage list + - [x] storage list - [x] update storage bind command - [ ] add storage remove command - [ ] add sync subcommand diff --git a/tests/cli.rs b/tests/cli.rs index ae5bd81..4dd4fe6 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -5,7 +5,7 @@ mod integrated_test { }; use anyhow::{Context, Ok, Result}; - use assert_cmd::{assert::OutputAssertExt, cargo::CommandCargoExt, Command}; + use assert_cmd::{assert::OutputAssertExt, Command}; use dirs::home_dir; use git2::Repository; use log::trace; From 37782c934c2b76f8319e8d83a9c0d284fbb04ed3 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 7 Aug 2024 11:39:58 +0200 Subject: [PATCH 27/58] (WIP) new: implement `status` subcommand - Error while getting mount path of Storages - Need to redesign the API of LocalInfo or something --- src/cmd_args.rs | 12 +++++++ src/cmd_status.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 6 ++++ src/storages.rs | 1 - 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/cmd_status.rs diff --git a/src/cmd_args.rs b/src/cmd_args.rs index 70a8033..4627f97 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -44,6 +44,18 @@ pub(crate) enum Commands { #[command(subcommand)] Backup(BackupSubCommands), + /// Print status for the given path. + Status { + /// Target path. Default is the current directory. + path: Option, + /// Show storage which the path belongs to. + #[arg(short)] + storage: bool, + /// Show backup config covering the path. + #[arg(short)] + backup: bool, + }, + /// Print config dir. Path {}, diff --git a/src/cmd_status.rs b/src/cmd_status.rs new file mode 100644 index 0000000..eebc2cc --- /dev/null +++ b/src/cmd_status.rs @@ -0,0 +1,81 @@ +use anyhow::{Context, Result}; +use console::Style; +use std::{ + env, + path::{self, Path, PathBuf}, +}; + +use crate::{ + backups::Backups, + devices::{self, Device}, + storages::{self, StorageExt, Storages}, + util, +}; + +// TODO: fine styling like `backup list`, or should I just use the same style? +pub(crate) fn cmd_status( + path: Option, + show_storage: bool, + show_backup: bool, + config_dir: &Path, +) -> Result<()> { + let path = path.unwrap_or(env::current_dir().context("Failed to get current directory.")?); + let device = devices::get_device(config_dir)?; + + if show_storage { + let storages = storages::Storages::read(config_dir)?; + let storage = util::min_parent_storage(&path, &storages, &device); + + match storage { + Some(storage) => { + println!("Storage: {}", storage.0.name()) + } + None => { + println!("Storage: None"); + } + } + } + if show_backup { + let devices = devices::get_devices(config_dir)?; + let storages = storages::Storages::read(config_dir)?; + let backups = Backups::read(config_dir, &device)?; + let covering_backup = devices + .iter() + .map(|device| (device, parent_backups(&path, &backups, &storages, device))); + + for (backup_device, covering_backups) in covering_backup { + println!("Device: {}", backup_device.name()); + for backup in covering_backups { + println!(" {}", console::style(backup.0).bold()); + } + } + } + todo!() +} + +fn parent_backups<'a>( + target_path: &'a PathBuf, + backups: &'a Backups, + storages: &'a Storages, + device: &'a Device, +) -> Vec<(&'a String, PathBuf)> { + backups + .list + .iter() + .filter_map(|(k, v)| { + let backup_path = match v.source().path(storages, device) { + Ok(path) => path, + Err(e) => { + error!("Error while getting backup source path: {}", e); + return None; + } + }; + let diff = pathdiff::diff_paths(target_path, backup_path)?; + if diff.components().any(|c| c == path::Component::ParentDir) { + None + } else { + Some((k, diff)) + } + }) + .collect() +} diff --git a/src/main.rs b/src/main.rs index 18e332d..23dadcd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,6 +31,7 @@ mod cmd_backup; mod cmd_check; mod cmd_completion; mod cmd_init; +mod cmd_status; mod cmd_storage; mod cmd_sync; mod devices; @@ -91,6 +92,11 @@ fn main() -> Result<()> { println!("{}", &config_dir.display()); } Commands::Sync { remote_name } => cmd_sync::cmd_sync(&config_dir, remote_name)?, + Commands::Status { + path, + storage, + backup, + } => cmd_status::cmd_status(path, storage, backup, &config_dir)?, Commands::Check {} => cmd_check::cmd_check(&config_dir)?, Commands::Backup(backup) => { trace!("backup subcommand with args: {:?}", backup); diff --git a/src/storages.rs b/src/storages.rs index 4031d61..b80536e 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -144,7 +144,6 @@ pub trait StorageExt { fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo>; /// Get mount path of `self` on `device`. - /// `storages` is a `BTreeMap` with key of storage name and value of the storage. fn mount_path(&self, device: &devices::Device) -> Result; /// Add local info of `device` to `self`. From a409a439061e3ccd6687b8ef2456937445337f84 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 9 Aug 2024 21:45:44 +0200 Subject: [PATCH 28/58] (WIP) feat: stat for backup with name - replace path funcs return from Result to Option - add tests for `parent_backups` --- src/backups.rs | 8 +- src/cmd_backup.rs | 20 ++- src/cmd_status.rs | 217 ++++++++++++++++++++--- src/cmd_storage.rs | 4 +- src/storages.rs | 5 +- src/storages/directory.rs | 13 +- src/storages/online_storage.rs | 8 +- src/storages/physical_drive_partition.rs | 9 +- src/util.rs | 5 +- 9 files changed, 236 insertions(+), 53 deletions(-) diff --git a/src/backups.rs b/src/backups.rs index fbb4c1f..896fcd9 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -44,10 +44,12 @@ impl BackupTarget { } } - pub fn path(&self, storages: &Storages, device: &Device) -> Result { + /// Get full path of the [`BackupTarget`]. + pub fn path(&self, storages: &Storages, device: &Device) -> Option { let parent = storages.get(&self.storage).unwrap(); - let parent_path = parent.mount_path(device)?; - Ok(parent_path.join(self.path.clone())) + let parent_path = parent + .mount_path(device)?; + Some(parent_path.join(self.path.clone())) } } diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index 7ae9767..df6d13d 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -188,10 +188,16 @@ fn write_backups_list( ))?; name_width = name_width.max(backup.name().width()); dev_width = dev_width.max(dev.width()); - let src = backup.source().path(storages, device)?; + let src = backup + .source() + .path(storages, device) + .context("Couldn't get path for source")?; src_width = src_width.max(format!("{}", src.display()).width()); src_storage_width = src_storage_width.max(backup.source().storage.width()); - let dest = backup.destination().path(storages, device)?; + let dest = backup + .destination() + .path(storages, device) + .context("Couldn't get path for destination")?; dest_width = dest_width.max(format!("{}", dest.display()).width()); dest_storage_width = dest_storage_width.max(backup.destination().storage.width()); let cmd_name = backup.command().name(); @@ -203,8 +209,14 @@ fn write_backups_list( "Couldn't find the device specified in the backup config: {}", backup.name() ))?; - let src = backup.source().path(storages, device)?; - let dest = backup.destination().path(storages, device)?; + let src = backup + .source() + .path(storages, device) + .context("Couldn't get path for source")?; + let dest = backup + .destination() + .path(storages, device) + .context("Couldn't get path for destination")?; let cmd_name = backup.command().name(); let (last_backup_elapsed, style_on_time_elapsed) = match backup.last_backup() { Some(log) => { diff --git a/src/cmd_status.rs b/src/cmd_status.rs index eebc2cc..cd90860 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -6,9 +6,9 @@ use std::{ }; use crate::{ - backups::Backups, + backups::{Backup, Backups}, devices::{self, Device}, - storages::{self, StorageExt, Storages}, + storages::{self, Storage, StorageExt, Storages}, util, }; @@ -20,12 +20,14 @@ pub(crate) fn cmd_status( config_dir: &Path, ) -> Result<()> { let path = path.unwrap_or(env::current_dir().context("Failed to get current directory.")?); - let device = devices::get_device(config_dir)?; + let currrent_device = devices::get_device(config_dir)?; if show_storage { let storages = storages::Storages::read(config_dir)?; - let storage = util::min_parent_storage(&path, &storages, &device); + let storage = util::min_parent_storage(&path, &storages, &currrent_device); + trace!("storage {:?}", storage); + // TODO: recursively trace all storages for subdirectory? match storage { Some(storage) => { println!("Storage: {}", storage.0.name()) @@ -38,44 +40,217 @@ pub(crate) fn cmd_status( if show_backup { let devices = devices::get_devices(config_dir)?; let storages = storages::Storages::read(config_dir)?; - let backups = Backups::read(config_dir, &device)?; - let covering_backup = devices + let backups = Backups::read(config_dir, &currrent_device)?; + + let (target_storage, target_diff_from_storage) = + util::min_parent_storage(&path, &storages, &currrent_device) + .context("Target path is not covered in any storage")?; + + let covering_backup: Vec<_> = devices .iter() - .map(|device| (device, parent_backups(&path, &backups, &storages, device))); + .map(|device| { + ( + device, + parent_backups( + &target_diff_from_storage, + target_storage, + &backups, + &storages, + device, + ), + ) + }) + .collect(); + trace!("{:?}", covering_backup.first()); + + let name_len = &covering_backup + .iter() + .map(|(_, backups)| { + backups + .iter() + .map(|(backup, _path)| backup.name().len()) + .max() + .unwrap_or(0) + }) + .max() + .unwrap_or(5); for (backup_device, covering_backups) in covering_backup { println!("Device: {}", backup_device.name()); - for backup in covering_backups { - println!(" {}", console::style(backup.0).bold()); + for (backup, path_from_backup) in covering_backups { + println!( + " {:( - target_path: &'a PathBuf, + target_path_from_storage: &'a Path, + target_storage: &'a Storage, backups: &'a Backups, storages: &'a Storages, device: &'a Device, -) -> Vec<(&'a String, PathBuf)> { +) -> Vec<(&'a Backup, PathBuf)> { + trace!("Dev {:?}", device.name()); + let target_path = match target_storage.mount_path(device) { + Some(target_path) => target_path.join(target_path_from_storage), + None => return vec![], + }; + trace!("Path on the device {:?}", target_path); backups .list .iter() - .filter_map(|(k, v)| { - let backup_path = match v.source().path(storages, device) { - Ok(path) => path, - Err(e) => { - error!("Error while getting backup source path: {}", e); - return None; - } - }; - let diff = pathdiff::diff_paths(target_path, backup_path)?; + .filter_map(|(_k, backup)| { + let backup_path = backup.source().path(storages, device)?; + let diff = pathdiff::diff_paths(&target_path, backup_path)?; if diff.components().any(|c| c == path::Component::ParentDir) { None } else { - Some((k, diff)) + Some((backup, diff)) } }) .collect() } + +#[cfg(test)] +mod test { + use std::path::PathBuf; + + use crate::{ + backups::{self, ExternallyInvoked}, + devices, + storages::{self, online_storage::OnlineStorage, StorageExt}, + util, + }; + + use super::parent_backups; + + #[test] + fn test_parent_backups() { + let device1 = devices::Device::new("device_1".to_string()); + let mut storage1 = storages::Storage::Online(OnlineStorage::new( + "storage_1".to_string(), + "smb".to_string(), + 1_000_000, + "str1".to_string(), + PathBuf::from("/home/foo/"), + &device1, + )); + let storage2 = storages::Storage::Online(OnlineStorage::new( + "storage_2".to_string(), + "smb".to_string(), + 1_000_000_000, + "str2".to_string(), + PathBuf::from("/"), + &device1, + )); + let device2 = devices::Device::new("device_2".to_string()); + storage1 + .bound_on_device("alias".to_string(), PathBuf::from("/mnt/dev"), &device2) + .unwrap(); + let storage3 = storages::Storage::Online(OnlineStorage::new( + "storage_3".to_string(), + "smb".to_string(), + 2_000_000_000, + "str2".to_string(), + PathBuf::from("/"), + &device2, + )); + let storages = { + let mut storages = storages::Storages::new(); + storages.add(storage1).unwrap(); + storages.add(storage2).unwrap(); + storages.add(storage3).unwrap(); + storages + }; + + let backup1 = backups::Backup::new( + "backup_1".to_string(), + device1.name().to_string(), + backups::BackupTarget { + storage: "storage_1".to_string(), + path: PathBuf::from("bar"), + }, + backups::BackupTarget { + storage: "storage_1".to_string(), + path: PathBuf::from("hoge"), + }, + backups::BackupCommand::ExternallyInvoked(ExternallyInvoked::new( + "cmd".to_string(), + "".to_string(), + )), + ); + let backup2 = backups::Backup::new( + "backup_2".to_string(), + device2.name().to_string(), + backups::BackupTarget { + storage: "storage_1".to_string(), + path: PathBuf::from(""), + }, + backups::BackupTarget { + storage: "storage_3".to_string(), + path: PathBuf::from("foo"), + }, + backups::BackupCommand::ExternallyInvoked(ExternallyInvoked::new( + "cmd".to_string(), + "".to_string(), + )), + ); + + let backups = { + let mut backups = backups::Backups::new(); + backups.add(backup1).unwrap(); + backups.add(backup2).unwrap(); + backups + }; + + let target_path1 = PathBuf::from("/home/foo/bar/hoo"); + let (target_storage1, target_path_from_storage1) = + util::min_parent_storage(&target_path1, &storages, &device1) + .expect("Failed to get storage"); + let covering_backups_1 = parent_backups( + &target_path_from_storage1, + target_storage1, + &backups, + &storages, + &device1, + ); + assert_eq!(covering_backups_1.len(), 2); + + let target_path2 = PathBuf::from("/mnt/"); + let (target_storage2, target_path_from_storage2) = + util::min_parent_storage(&target_path2, &storages, &device2) + .expect("Failed to get storage"); + let covering_backups_2 = parent_backups( + &target_path_from_storage2, + target_storage2, + &backups, + &storages, + &device2, + ); + assert_eq!(covering_backups_2.len(), 0); + + let target_path3 = PathBuf::from("/mnt/dev/foo"); + let (target_storage3, target_path_from_storage3) = + util::min_parent_storage(&target_path3, &storages, &device2) + .expect("Failed to get storage"); + let covering_backups_3 = parent_backups( + &target_path_from_storage3, + target_storage3, + &backups, + &storages, + &device2, + ); + assert_eq!(covering_backups_3.len(), 1); + let mut covering_backup_names_3 = covering_backups_3.iter().map(|(backup, _)| backup.name()); + assert_eq!(covering_backup_names_3.next().unwrap(), "backup_2"); + assert!(covering_backup_names_3.next().is_none()); + } +} diff --git a/src/cmd_storage.rs b/src/cmd_storage.rs index 8c39646..2cb9414 100644 --- a/src/cmd_storage.rs +++ b/src/cmd_storage.rs @@ -215,8 +215,8 @@ fn write_storages_list( "" }; let path = storage.mount_path(device).map_or_else( - |e| { - info!("Not found: {}", e); + || { + info!("Mount path not found"); "".to_string() }, |v| v.display().to_string(), diff --git a/src/storages.rs b/src/storages.rs index b80536e..d4b9dd4 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -78,7 +78,7 @@ impl StorageExt for Storage { } } - fn mount_path(&self, device: &devices::Device) -> Result { + fn mount_path(&self, device: &devices::Device) -> Option { match self { Self::Physical(s) => s.mount_path(device), Self::SubDirectory(s) => s.mount_path(device), @@ -144,7 +144,8 @@ pub trait StorageExt { fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo>; /// Get mount path of `self` on `device`. - fn mount_path(&self, device: &devices::Device) -> Result; + /// Return [`None`] if the storage([`self`]) is not configured for the `device`. + fn mount_path(&self, device: &devices::Device) -> Option; /// Add local info of `device` to `self`. fn bound_on_device( diff --git a/src/storages/directory.rs b/src/storages/directory.rs index 4cd7803..f1e460c 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -19,7 +19,7 @@ pub struct Directory { /// Relative path to the parent storage. relative_path: path::PathBuf, pub notes: String, - /// Device and localinfo pairs. + /// [`devices::Device`] name and localinfo pairs. local_infos: BTreeMap, } @@ -80,7 +80,8 @@ impl Directory { let parent_mount_path = self .parent(storages) .context("Can't find parent storage")? - .mount_path(device)?; + .mount_path(device) + .context("Can't find mount path")?; Ok(parent_mount_path.join(self.relative_path.clone())) } } @@ -98,12 +99,10 @@ impl StorageExt for Directory { self.local_infos.get(&device.name()) } - fn mount_path(&self, device: &devices::Device) -> Result { - Ok(self - .local_infos + fn mount_path(&self, device: &devices::Device) -> Option { + self.local_infos .get(&device.name()) - .context(format!("LocalInfo for storage: {} not found", &self.name()))? - .mount_path()) + .map(|info| info.mount_path()) } /// This method doesn't use `mount_path`. diff --git a/src/storages/online_storage.rs b/src/storages/online_storage.rs index 4ce2459..6c4d62c 100644 --- a/src/storages/online_storage.rs +++ b/src/storages/online_storage.rs @@ -61,12 +61,10 @@ impl StorageExt for OnlineStorage { self.local_infos.get(&device.name()) } - fn mount_path(&self, device: &devices::Device) -> Result { - Ok(self - .local_infos + fn mount_path(&self, device: &devices::Device) -> Option { + self.local_infos .get(&device.name()) - .context(format!("LocalInfo for storage: {} not found", &self.name()))? - .mount_path()) + .map(|info| info.mount_path()) } fn bound_on_device( diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 95dec3f..14a35a6 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -21,6 +21,7 @@ pub struct PhysicalDrivePartition { fs: String, is_removable: bool, // system_names: BTreeMap, + /// [`Device`] name and [`LocalInfo`] mapping. local_infos: BTreeMap, } @@ -112,12 +113,10 @@ impl StorageExt for PhysicalDrivePartition { self.local_infos.get(&device.name()) } - fn mount_path(&self, device: &devices::Device) -> Result { - Ok(self - .local_infos + fn mount_path(&self, device: &devices::Device) -> Option { + self.local_infos .get(&device.name()) - .context(format!("LocalInfo for storage: {} not found", &self.name()))? - .mount_path()) + .map(|info| info.mount_path()) } fn bound_on_device( diff --git a/src/util.rs b/src/util.rs index 820de33..8f27bc4 100644 --- a/src/util.rs +++ b/src/util.rs @@ -18,10 +18,7 @@ pub fn min_parent_storage<'a>( .list .iter() .filter_map(|(k, storage)| { - let storage_path = match storage.mount_path(device) { - Ok(path) => path, - Err(_) => return None, - }; + let storage_path = storage.mount_path(device)?; let diff = pathdiff::diff_paths(path, storage_path)?; if diff.components().any(|c| c == path::Component::ParentDir) { None From bc3939c9bc09bee4e5b0c943e6ecde3f652aa947 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Fri, 8 Nov 2024 06:09:04 +0900 Subject: [PATCH 29/58] (WIP): implementing multi device backup search --- src/backups.rs | 17 ++++++++-------- src/cmd_backup.rs | 15 ++------------ src/cmd_status.rs | 52 +++++++++++++++++++++++++++++++++++------------ src/util.rs | 12 +++++++++++ 4 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/backups.rs b/src/backups.rs index 896fcd9..5b39e61 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -27,7 +27,7 @@ pub fn backups_file(device: &Device) -> PathBuf { } /// Targets for backup source or destination. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BackupTarget { /// `name()` of [`crate::storages::Storage`]. /// Use `String` for serialization/deserialization. @@ -47,14 +47,13 @@ impl BackupTarget { /// Get full path of the [`BackupTarget`]. pub fn path(&self, storages: &Storages, device: &Device) -> Option { let parent = storages.get(&self.storage).unwrap(); - let parent_path = parent - .mount_path(device)?; + let parent_path = parent.mount_path(device)?; Some(parent_path.join(self.path.clone())) } } /// Type of backup commands. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum BackupCommand { ExternallyInvoked(ExternallyInvoked), } @@ -81,7 +80,7 @@ impl BackupCommandExt for BackupCommand { /// Backup commands which is not invoked from xdbm itself. /// Call xdbm externally to record backup datetime and status. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExternallyInvoked { name: String, pub note: String, @@ -104,7 +103,7 @@ impl BackupCommandExt for ExternallyInvoked { } /// Backup execution log. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BackupLog { pub datetime: DateTime, status: BackupResult, @@ -124,7 +123,7 @@ impl BackupLog { } /// Result of backup. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum BackupResult { Success, Failure, @@ -141,7 +140,7 @@ impl BackupResult { } /// Backup source, destination, command and logs. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Backup { /// must be unique name: String, @@ -202,7 +201,7 @@ impl Backup { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Backups { pub list: BTreeMap, } diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index df6d13d..9c58378 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -5,7 +5,7 @@ use std::{ }; use anyhow::{anyhow, Context, Ok, Result}; -use chrono::{Local, TimeDelta}; +use chrono::Local; use console::Style; use dunce::canonicalize; use git2::Repository; @@ -154,17 +154,6 @@ pub fn cmd_backup_list( Ok(()) } -fn duration_style(time: TimeDelta) -> Style { - match time { - x if x < TimeDelta::days(7) => Style::new().green(), - x if x < TimeDelta::days(14) => Style::new().yellow(), - x if x < TimeDelta::days(28) => Style::new().magenta(), - x if x < TimeDelta::days(28 * 3) => Style::new().red(), - x if x < TimeDelta::days(180) => Style::new().red().bold(), - _ => Style::new().on_red().black(), - } -} - /// TODO: status printing fn write_backups_list( mut writer: impl io::Write, @@ -222,7 +211,7 @@ fn write_backups_list( Some(log) => { let time = Local::now() - log.datetime; let s = util::format_summarized_duration(time); - let style = duration_style(time); + let style = util::duration_style(time); (style.apply_to(s), style) } None => { diff --git a/src/cmd_status.rs b/src/cmd_status.rs index cd90860..ba1ad87 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result}; -use console::Style; +use chrono::Local; use std::{ env, path::{self, Path, PathBuf}, @@ -40,7 +40,11 @@ pub(crate) fn cmd_status( if show_backup { let devices = devices::get_devices(config_dir)?; let storages = storages::Storages::read(config_dir)?; - let backups = Backups::read(config_dir, &currrent_device)?; + let backups = devices.iter().map(|device| { + Backups::read(config_dir, device) + .context("Backups were not found") + .unwrap() + }); let (target_storage, target_diff_from_storage) = util::min_parent_storage(&path, &storages, &currrent_device) @@ -48,13 +52,27 @@ pub(crate) fn cmd_status( let covering_backup: Vec<_> = devices .iter() - .map(|device| { + .zip(backups) + .map(|(device, backups)| { + debug!( + "dev {}, storage {:?}", + device.name(), + backups + .list + .iter() + .map(|(backup_name, backup)| format!( + "{} {}", + backup_name, + backup.source().storage + )) + .collect::>() + ); ( device, parent_backups( &target_diff_from_storage, target_storage, - &backups, + backups, &storages, device, ), @@ -78,9 +96,14 @@ pub(crate) fn cmd_status( for (backup_device, covering_backups) in covering_backup { println!("Device: {}", backup_device.name()); for (backup, path_from_backup) in covering_backups { + let last_backup = match backup.last_backup() { + Some(log) => util::format_summarized_duration(Local::now() - log.datetime), + None => "---".to_string(), + }; println!( - " {:( target_path_from_storage: &'a Path, target_storage: &'a Storage, - backups: &'a Backups, + backups: Backups, storages: &'a Storages, device: &'a Device, -) -> Vec<(&'a Backup, PathBuf)> { +) -> Vec<(Backup, PathBuf)> { trace!("Dev {:?}", device.name()); let target_path = match target_storage.mount_path(device) { Some(target_path) => target_path.join(target_path_from_storage), @@ -106,10 +129,12 @@ fn parent_backups<'a>( trace!("Path on the device {:?}", target_path); backups .list - .iter() + .into_iter() .filter_map(|(_k, backup)| { let backup_path = backup.source().path(storages, device)?; - let diff = pathdiff::diff_paths(&target_path, backup_path)?; + trace!("{:?}", backup_path.components()); + let diff = pathdiff::diff_paths(&target_path, backup_path.clone())?; + trace!("Backup: {:?}, Diff: {:?}", backup_path, diff); if diff.components().any(|c| c == path::Component::ParentDir) { None } else { @@ -218,7 +243,7 @@ mod test { let covering_backups_1 = parent_backups( &target_path_from_storage1, target_storage1, - &backups, + backups.clone(), &storages, &device1, ); @@ -231,7 +256,7 @@ mod test { let covering_backups_2 = parent_backups( &target_path_from_storage2, target_storage2, - &backups, + backups.clone(), &storages, &device2, ); @@ -244,12 +269,13 @@ mod test { let covering_backups_3 = parent_backups( &target_path_from_storage3, target_storage3, - &backups, + backups, &storages, &device2, ); assert_eq!(covering_backups_3.len(), 1); - let mut covering_backup_names_3 = covering_backups_3.iter().map(|(backup, _)| backup.name()); + let mut covering_backup_names_3 = + covering_backups_3.iter().map(|(backup, _)| backup.name()); assert_eq!(covering_backup_names_3.next().unwrap(), "backup_2"); assert!(covering_backup_names_3.next().is_none()); } diff --git a/src/util.rs b/src/util.rs index 8f27bc4..5730dc7 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,7 @@ use std::path::{self, PathBuf}; use anyhow::{Context, Result}; +use chrono::TimeDelta; use console::Style; use crate::{ @@ -59,6 +60,17 @@ pub fn format_summarized_duration(dt: chrono::Duration) -> String { } } +pub fn duration_style(time: TimeDelta) -> Style { + match time { + x if x < TimeDelta::days(7) => Style::new().green(), + x if x < TimeDelta::days(14) => Style::new().yellow(), + x if x < TimeDelta::days(28) => Style::new().magenta(), + x if x < TimeDelta::days(28 * 3) => Style::new().red(), + x if x < TimeDelta::days(180) => Style::new().red().bold(), + _ => Style::new().on_red().black(), + } +} + #[cfg(test)] mod test { use anyhow::Result; From 772689ab6af36974df642e4a7e326c358e33cdd5 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 19:14:57 +0900 Subject: [PATCH 30/58] change: change type of relative path shared on multiple platforms to Vector Parsers for path on Windows and Unix are different on separator character treatment. Replacing to Vector avoids this differenct for cross-platform compatibility. --- src/backups.rs | 15 ++++++++++----- src/cmd_backup.rs | 8 ++++---- src/cmd_status.rs | 10 +++++----- src/storages/directory.rs | 37 ++++++++++++++++++++++--------------- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/backups.rs b/src/backups.rs index 5b39e61..2816a6a 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -33,22 +33,27 @@ pub struct BackupTarget { /// Use `String` for serialization/deserialization. pub storage: String, /// Relative path to the `storage`. - pub path: PathBuf, + pub path: Vec, } impl BackupTarget { - pub fn new(storage_name: String, relative_path: PathBuf) -> Self { - BackupTarget { + pub fn new(storage_name: String, relative_path: PathBuf) -> Result { + let relative_path = relative_path + .components() + .map(|c| c.as_os_str().to_str().map(|s| s.to_owned())) + .collect::>() + .context("Path contains non-utf8 character")?; + Ok(BackupTarget { storage: storage_name, path: relative_path, - } + }) } /// Get full path of the [`BackupTarget`]. pub fn path(&self, storages: &Storages, device: &Device) -> Option { let parent = storages.get(&self.storage).unwrap(); let parent_path = parent.mount_path(device)?; - Some(parent_path.join(self.path.clone())) + Some(parent_path.join(self.path.clone().iter().collect::())) } } diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index 9c58378..cab7a9e 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -89,8 +89,8 @@ fn new_backup( Ok(Backup::new( name, device.name(), - src_target, - dest_target, + src_target?, + dest_target?, command, )) } @@ -361,9 +361,9 @@ mod test { &storages, )?; assert!(backup.source().storage == "online"); - assert_eq!(backup.source().path, PathBuf::from("docs")); + assert_eq!(backup.source().path, vec!["docs"]); assert!(backup.destination().storage == "online"); - assert!(backup.destination().path == PathBuf::from("tmp")); + assert!(backup.destination().path == vec!["tmp"]); Ok(()) } } diff --git a/src/cmd_status.rs b/src/cmd_status.rs index ba1ad87..c93e641 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -146,7 +146,7 @@ fn parent_backups<'a>( #[cfg(test)] mod test { - use std::path::PathBuf; + use std::{path::PathBuf, vec}; use crate::{ backups::{self, ExternallyInvoked}, @@ -201,11 +201,11 @@ mod test { device1.name().to_string(), backups::BackupTarget { storage: "storage_1".to_string(), - path: PathBuf::from("bar"), + path: vec!["bar".to_string()], }, backups::BackupTarget { storage: "storage_1".to_string(), - path: PathBuf::from("hoge"), + path: vec!["hoge".to_string()], }, backups::BackupCommand::ExternallyInvoked(ExternallyInvoked::new( "cmd".to_string(), @@ -217,11 +217,11 @@ mod test { device2.name().to_string(), backups::BackupTarget { storage: "storage_1".to_string(), - path: PathBuf::from(""), + path: vec!["".to_string()], }, backups::BackupTarget { storage: "storage_3".to_string(), - path: PathBuf::from("foo"), + path: vec!["foo".to_string()], }, backups::BackupCommand::ExternallyInvoked(ExternallyInvoked::new( "cmd".to_string(), diff --git a/src/storages/directory.rs b/src/storages/directory.rs index f1e460c..1777ec3 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -2,6 +2,7 @@ use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; +use std::path::PathBuf; use std::{collections::BTreeMap, fmt, path}; use crate::devices; @@ -17,7 +18,7 @@ pub struct Directory { /// ID of parent storage. parent: String, /// Relative path to the parent storage. - relative_path: path::PathBuf, + relative_path: Vec, pub notes: String, /// [`devices::Device`] name and localinfo pairs. local_infos: BTreeMap, @@ -34,14 +35,19 @@ impl Directory { relative_path: path::PathBuf, notes: String, local_infos: BTreeMap, - ) -> Directory { - Directory { + ) -> Result { + let relative_path = relative_path + .components() + .map(|c| c.as_os_str().to_str().map(|s| s.to_owned())) + .collect::>>() + .context("Path contains non-utf8 character")?; + Ok(Directory { name, parent, relative_path, notes, local_infos, - } + }) } pub fn try_from_device_path( @@ -56,23 +62,23 @@ impl Directory { .context("Failed to compare diff of paths")?; trace!("Selected parent: {}", parent.name()); let local_info = LocalInfo::new(alias, path); - Ok(Directory::new( + Directory::new( name, parent.name().to_string(), diff_path, notes, BTreeMap::from([(device.name(), local_info)]), - )) + ) } pub fn update_note(self, notes: String) -> Directory { - Directory::new( - self.name, - self.parent, - self.relative_path, + Directory { + name: self.name, + parent: self.parent, + relative_path: self.relative_path, notes, - self.local_infos, - ) + local_infos: self.local_infos, + } } /// Resolve mount path of directory with current device. @@ -82,7 +88,7 @@ impl Directory { .context("Can't find parent storage")? .mount_path(device) .context("Can't find mount path")?; - Ok(parent_mount_path.join(self.relative_path.clone())) + Ok(parent_mount_path.join(self.relative_path.clone().iter().collect::())) } } @@ -133,7 +139,7 @@ impl fmt::Display for Directory { "S {name:<10} < {parent:<10}{relative_path:<10} : {notes}", name = self.name(), parent = self.parent, - relative_path = self.relative_path.display(), + relative_path = self.relative_path.iter().collect::().display(), notes = self.notes, ) } @@ -177,7 +183,8 @@ mod test { "subdir".into(), "some note".to_string(), local_infos, - ); + ) + .unwrap(); let mut storages = Storages::new(); storages.add(storages::Storage::Physical(physical)).unwrap(); storages.add(Storage::SubDirectory(directory)).unwrap(); From 8b0dbb2314d2ab3cd9081163899ea4e52a193e4d Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 19:19:28 +0900 Subject: [PATCH 31/58] fix: add lifetime annotation (clippy) --- src/backups.rs | 2 +- src/storages/directory.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backups.rs b/src/backups.rs index 2816a6a..8f70509 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -180,7 +180,7 @@ impl Backup { &self.name } - pub fn device<'a>(&'a self, devices: &'a [Device]) -> Option<&Device> { + pub fn device<'a>(&'a self, devices: &'a [Device]) -> Option<&'a Device> { devices.iter().find(|dev| dev.name() == self.device) } diff --git a/src/storages/directory.rs b/src/storages/directory.rs index 1777ec3..1642518 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -127,7 +127,7 @@ impl StorageExt for Directory { } // Get parent `&Storage` of directory. - fn parent<'a>(&'a self, storages: &'a Storages) -> Option<&Storage> { + fn parent<'a>(&'a self, storages: &'a Storages) -> Option<&'a Storage> { storages.get(&self.parent) } } From dbc0d78f99de53077ebf3c3577b779e35a39fc50 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 19:36:33 +0900 Subject: [PATCH 32/58] update: CHANGELOG on path type change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 685004c..dd526a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Changed - Colored output for `storage list` and `backup list` ([#15](https://github.com/qwjyh/xdbm/pull/15)) +- **BREAKING** Relative path is changed from `PathBuf` to `Vector` for portability. This means that existing config files need to be changed. ## [0.2.1] - 2024-06-19 From ced354bf583425a0f7fe6d38b5b283a04e2da2d7 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 20:37:23 +0900 Subject: [PATCH 33/58] fix: sub directory decision logic on windows Diff of "C:\foo" from "D:\" is "C:\foo" and doesn't contain "..". In old logic, "C:\foo" is treated as subpath of "D:\" but this is not intuitive. --- src/cmd_status.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cmd_status.rs b/src/cmd_status.rs index c93e641..c80ff89 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -135,7 +135,11 @@ fn parent_backups<'a>( trace!("{:?}", backup_path.components()); let diff = pathdiff::diff_paths(&target_path, backup_path.clone())?; trace!("Backup: {:?}, Diff: {:?}", backup_path, diff); - if diff.components().any(|c| c == path::Component::ParentDir) { + // note: Should `RootDir` is included in this list? + if diff + .components() + .any(|c| matches!(c, path::Component::ParentDir | path::Component::Prefix(_))) + { None } else { Some((backup, diff)) From 6a0abd03d5843fc6432d28523eeb49bfe1ca2447 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 20:55:49 +0900 Subject: [PATCH 34/58] fix: apply subpath logic patch to `util::min_parent_storage` --- src/util.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/util.rs b/src/util.rs index 5730dc7..ea2c947 100644 --- a/src/util.rs +++ b/src/util.rs @@ -21,7 +21,10 @@ pub fn min_parent_storage<'a>( .filter_map(|(k, storage)| { let storage_path = storage.mount_path(device)?; let diff = pathdiff::diff_paths(path, storage_path)?; - if diff.components().any(|c| c == path::Component::ParentDir) { + if diff + .components() + .any(|c| matches!(c, path::Component::ParentDir | path::Component::Prefix(_))) + { None } else { Some((k, diff)) From 8fc8029435eac304098b4164344f5279de783836 Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Sun, 1 Dec 2024 21:13:42 +0900 Subject: [PATCH 35/58] Update CI and add lint (#18) * fix: update actions/checkout from v3 to v4 * update(CI): add clippy --- .github/workflows/rust.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 31000a2..7cee19b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,13 +10,17 @@ env: CARGO_TERM_COLOR: always jobs: - build: + build-and-lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - name: Setup + run: rustup component add clippy - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verbose + - name: Lint + run: cargo clippy --all-targets --all-features From d743e607accea646a41c56f9a7e3cbd7ca9ede57 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 23:14:50 +0900 Subject: [PATCH 36/58] update: remove todo!() at the end of cmd_status --- src/cmd_status.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmd_status.rs b/src/cmd_status.rs index c80ff89..ebc61d2 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -109,7 +109,8 @@ pub(crate) fn cmd_status( } } } - todo!() + + Ok(()) } /// Get [`Backup`]s for `device` which covers `target_path`. From 315a75424aded1688c97ea9a716927c2b50f8428 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 23:31:58 +0900 Subject: [PATCH 37/58] add(test): command backup after done doesn't include --- --- tests/cli.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/cli.rs b/tests/cli.rs index 4dd4fe6..3c399cd 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -448,6 +448,21 @@ mod integrated_test { .assert() .success(); + // backup list after backup done + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("backup") + .arg("list") + .assert() + .success() + .stdout( + predicate::str::contains("foodoc") + .and(predicate::str::contains("nas")) + .and(predicate::str::contains("gdrive_docs")) + .and(predicate::str::contains("---").not()), + ); + Ok(()) } } From bce9f3710c001964eca9a720464cf6776507bf0b Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 23:32:36 +0900 Subject: [PATCH 38/58] add(test): command status test --- tests/cli.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/cli.rs b/tests/cli.rs index 3c399cd..bad49e8 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -463,6 +463,49 @@ mod integrated_test { .and(predicate::str::contains("---").not()), ); + // status + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .assert() + .success(); + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .arg("-s") + .arg(backup_src.clone().join("foo")) + .assert() + .success() + .stdout(predicate::str::contains("nas").and(predicate::str::contains("foodoc").not())); + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .arg("-sb") + .arg(backup_src.clone().join("foo")) + .assert() + .success() + .stdout( + predicate::str::contains("nas") + .and(predicate::str::contains("second")) + .and(predicate::str::contains("foodoc")), + ); + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .arg("-sb") + .arg(backup_src.clone().parent().unwrap()) + .assert() + .success() + .stdout( + predicate::str::contains("nas") + .and(predicate::str::contains("second")) + .and(predicate::str::contains("foodoc").not()), + ); + Ok(()) } } From 697c9c0712ce7958f08aeaa4636ed14e5fc3845c Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 1 Dec 2024 23:33:24 +0900 Subject: [PATCH 39/58] add(test): test for multiple backups and status & add comment comment for current config --- tests/cli.rs | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) diff --git a/tests/cli.rs b/tests/cli.rs index bad49e8..b082182 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -216,6 +216,8 @@ mod integrated_test { #[test] fn two_devices() -> Result<()> { // 1st device + // + // devices: first let config_dir_1 = assert_fs::TempDir::new()?; setup_gitconfig()?; let mut cmd1 = Command::cargo_bin("xdbm")?; @@ -248,6 +250,8 @@ mod integrated_test { ))?; // 2nd device + // + // devices: first, second let config_dir_2 = assert_fs::TempDir::new()?; let mut cmd2 = Command::cargo_bin("xdbm")?; cmd2.arg("-c") @@ -271,6 +275,7 @@ mod integrated_test { assert!(config_dir_2.join("backups").join("first.yml").exists()); assert!(config_dir_2.join("backups").join("second.yml").exists()); + // sync std::process::Command::new("git") .arg("push") .current_dir(&config_dir_2) @@ -287,6 +292,11 @@ mod integrated_test { .success(); // Add storage + // + // devices: first, second + // storages: + // - gdrive @ sample_storage (online) + // - first: sample_storage let sample_storage = assert_fs::TempDir::new()?; let mut cmd_add_storage_1 = Command::cargo_bin("xdbm")?; cmd_add_storage_1 @@ -308,6 +318,13 @@ mod integrated_test { .success() .stdout(predicate::str::contains("")); // Add storage (directory) + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first let sample_directory = &sample_storage.join("foo").join("bar"); DirBuilder::new().recursive(true).create(sample_directory)?; Command::cargo_bin("xdbm")? @@ -339,6 +356,14 @@ mod integrated_test { .success(); // bind + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory Command::cargo_bin("xdbm")? .arg("-c") .arg(config_dir_2.path()) @@ -354,6 +379,16 @@ mod integrated_test { .stdout(predicate::str::contains("")); // storage 3 + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - second: sample_storage_2 let sample_storage_2 = assert_fs::TempDir::new()?; Command::cargo_bin("xdbm")? .arg("-c") @@ -384,6 +419,19 @@ mod integrated_test { .stdout(predicate::str::contains("gdrive_docs").and(predicate::str::contains("nas"))); // backup add + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs let backup_src = &sample_storage_2.join("foo").join("bar"); DirBuilder::new().recursive(true).create(backup_src)?; let backup_dest = &sample_directory.join("docs"); @@ -438,6 +486,19 @@ mod integrated_test { ); // backup done + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs (done 1) Command::cargo_bin("xdbm")? .arg("-c") .arg(config_dir_2.path()) @@ -506,6 +567,219 @@ mod integrated_test { .and(predicate::str::contains("foodoc").not()), ); + std::process::Command::new("git") + .arg("push") + .current_dir(&config_dir_2) + .assert() + .success(); + std::process::Command::new("git") + .arg("pull") + .current_dir(&config_dir_1) + .assert() + .success(); + + // bind + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - first: sample_storage_2_first_path + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs (done 1) + let sample_storage_2_first_path = assert_fs::TempDir::new()?; + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_1.path()) + .arg("storage") + .arg("bind") + .arg("--alias") + .arg("sample2") + .arg("--path") + .arg(sample_storage_2_first_path.path()) + .arg("nas") + .assert() + .success() + .stdout(predicate::str::contains("")); + + // backup add + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - first: sample_storage_2_first_path + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs (done 1) + // - abcdbackup: first + // - sample_storage_2_first_path/abcd/efgh -> sample_storage/Downloads/abcd/efgh + let backup_src = &sample_storage_2_first_path.join("abcd").join("efgh"); + DirBuilder::new().recursive(true).create(backup_src)?; + let backup_dest = &sample_storage.join("Downloads").join("abcd").join("efgh"); + DirBuilder::new().recursive(true).create(backup_dest)?; + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_1.path()) + .arg("backup") + .arg("add") + .arg("--src") + .arg(backup_src) + .arg("--dest") + .arg(backup_dest) + .arg("abcdbackup") + .arg("external") + .arg("rsync") + .arg("note: nonsense") + .assert() + .success(); + + // backup add + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - first: sample_storage_2_first_path + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs (done 1) + // - abcdbackup: first + // - sample_storage_2_first_path/abcd/efgh -> sample_storage/Downloads/abcd/efgh + // - abcdsubbackup: first + // - sample_storage_2_first_path/abcd/efgh/sub -> sample_storage/Downloads/abcd/efgh/sub + let backup_src = &sample_storage_2_first_path + .join("abcd") + .join("efgh") + .join("sub"); + DirBuilder::new().recursive(true).create(backup_src)?; + let backup_dest = &sample_storage + .join("Downloads") + .join("abcd") + .join("efgh") + .join("sub"); + DirBuilder::new().recursive(true).create(backup_dest)?; + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_1.path()) + .arg("backup") + .arg("add") + .arg("--src") + .arg(backup_src) + .arg("--dest") + .arg(backup_dest) + .arg("abcdsubbackup") + .arg("external") + .arg("rsync") + .arg("note: only subdirectory") + .assert() + .success(); + + std::process::Command::new("git") + .arg("push") + .current_dir(&config_dir_1) + .assert() + .success(); + std::process::Command::new("git") + .arg("pull") + .current_dir(&config_dir_2) + .assert() + .success(); + + // backup add + // + // devices: first, second + // storages: + // - gdrive (online) + // - first: sample_storage + // - gdrive_docs (subdir of sample_storage/foo/bar) + // - first + // - second: sample_directory + // - nas (online) + // - first: sample_storage_2_first_path + // - second: sample_storage_2 + // backups: + // - foodoc: second + // - sample_storage_2/foo/bar -> sample_directory/docs (done 1) + // - abcdbackup: first + // - sample_storage_2_first_path/abcd/efgh -> sample_storage/Downloads/abcd/efgh + // - abcdsubbackup: first + // - sample_storage_2_first_path/abcd/efgh/sub -> sample_storage/Downloads/abcd/efgh/sub + // - abcdbackup2: second + // - sample_storage_2/abcd/efgh -> sample_directory/Downloads/abcd/efgh + let backup_src = &sample_storage_2.join("abcd").join("efgh"); + DirBuilder::new().recursive(true).create(backup_src)?; + let backup_dest = &sample_directory + .join("Downloads") + .join("abcd") + .join("efgh"); + DirBuilder::new().recursive(true).create(backup_dest)?; + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("backup") + .arg("add") + .arg("--src") + .arg(backup_src) + .arg("--dest") + .arg(backup_dest) + .arg("abcdbackup2") + .arg("external") + .arg("rsync") + .arg("note: only subdirectory") + .assert() + .success(); + + // status + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .arg("-sb") + .arg(backup_src) + .assert() + .success() + .stdout( + predicate::str::contains("nas") + .and(predicate::str::contains("first")) + .and(predicate::str::contains("abcdbackup")) + .and(predicate::str::contains("abcdsubbackup").not()) + .and(predicate::str::contains("second")) + .and(predicate::str::contains("abcdbackup2")), + ); + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("status") + .arg("-sb") + .arg(backup_src.join("sub")) + .assert() + .success() + .stdout( + predicate::str::contains("nas") + .and(predicate::str::contains("first")) + .and(predicate::str::contains("abcdbackup")) + .and(predicate::str::contains("abcdsubbackup")) + .and(predicate::str::contains("second")) + .and(predicate::str::contains("abcdbackup2")), + ); + Ok(()) } } From c4aa76d1251301dd815ed298de9cb59ff2e820ef Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 02:15:49 +0900 Subject: [PATCH 40/58] update(test): add prefix '_' to unused variables --- tests/cli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index b082182..3407c86 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -145,7 +145,7 @@ mod integrated_test { // bare-repo let bare_repo_dir = assert_fs::TempDir::new()?; - let bare_repo = Repository::init_bare(&bare_repo_dir)?; + let _bare_repo = Repository::init_bare(&bare_repo_dir)?; // push to bare repository let repo_1 = Repository::open(&config_dir_1)?; let upstream_name = "remote"; @@ -229,7 +229,7 @@ mod integrated_test { // bare-repo let bare_repo_dir = assert_fs::TempDir::new()?; - let bare_repo = Repository::init_bare(&bare_repo_dir)?; + let _bare_repo = Repository::init_bare(&bare_repo_dir)?; // push to bare repository let repo_1 = Repository::open(&config_dir_1)?; let upstream_name = "remote"; From af1b56eee21a151ebdf5e2f51352db48bb3a6b47 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 02:52:53 +0900 Subject: [PATCH 41/58] add: style to cmd_status --- src/cmd_status.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd_status.rs b/src/cmd_status.rs index ebc61d2..7c7f7f2 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Result}; use chrono::Local; +use console::Style; use std::{ env, path::{self, Path, PathBuf}, @@ -96,14 +97,20 @@ pub(crate) fn cmd_status( for (backup_device, covering_backups) in covering_backup { println!("Device: {}", backup_device.name()); for (backup, path_from_backup) in covering_backups { - let last_backup = match backup.last_backup() { - Some(log) => util::format_summarized_duration(Local::now() - log.datetime), - None => "---".to_string(), + let (last_backup, style) = match backup.last_backup() { + Some(log) => { + let timediff = Local::now() - log.datetime; + ( + util::format_summarized_duration(timediff), + util::duration_style(timediff), + ) + } + None => ("---".to_string(), Style::new().red()), }; println!( " {: Date: Mon, 2 Dec 2024 02:53:30 +0900 Subject: [PATCH 42/58] update: don't display devices with no backups in cmd_status --- src/cmd_status.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cmd_status.rs b/src/cmd_status.rs index 7c7f7f2..5215ac7 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -95,6 +95,10 @@ pub(crate) fn cmd_status( .unwrap_or(5); for (backup_device, covering_backups) in covering_backup { + if covering_backups.is_empty() { + continue; + } + println!("Device: {}", backup_device.name()); for (backup, path_from_backup) in covering_backups { let (last_backup, style) = match backup.last_backup() { From 24f13566854805b0bd3105642554b9ba34a48a37 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 02:59:34 +0900 Subject: [PATCH 43/58] fix(test): for commit 7e043a652ca7a9c48582e8a7ed784715d3eaa1aa --- tests/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cli.rs b/tests/cli.rs index 3407c86..fe9a837 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -563,7 +563,7 @@ mod integrated_test { .success() .stdout( predicate::str::contains("nas") - .and(predicate::str::contains("second")) + .and(predicate::str::contains("second").not()) .and(predicate::str::contains("foodoc").not()), ); From 996ca7e4b3af0c8acd2933fca1d4a43c6d2ccf1f Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 03:00:56 +0900 Subject: [PATCH 44/58] run fmt --- tests/cli.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index fe9a837..929a74e 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -725,10 +725,7 @@ mod integrated_test { // - sample_storage_2/abcd/efgh -> sample_directory/Downloads/abcd/efgh let backup_src = &sample_storage_2.join("abcd").join("efgh"); DirBuilder::new().recursive(true).create(backup_src)?; - let backup_dest = &sample_directory - .join("Downloads") - .join("abcd") - .join("efgh"); + let backup_dest = &sample_directory.join("Downloads").join("abcd").join("efgh"); DirBuilder::new().recursive(true).create(backup_dest)?; Command::cargo_bin("xdbm")? .arg("-c") From 3d8aa7bca0ecf1bb745d4733cea7c56e7bad2dfb Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 03:05:43 +0900 Subject: [PATCH 45/58] update: CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd526a2..16a827f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - Colored output for `storage list` and `backup list` ([#15](https://github.com/qwjyh/xdbm/pull/15)) - **BREAKING** Relative path is changed from `PathBuf` to `Vector` for portability. This means that existing config files need to be changed. +- Add `status` subcommand to see storage and backup on given path or current working directory ([#17](https://github.com/qwjyh/xdbm/pull/17)). ## [0.2.1] - 2024-06-19 From 07ef49ca7b203b995823fb3fb0f91b5bc052495e Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 03:07:25 +0900 Subject: [PATCH 46/58] add: long argument option to cmd_status --- src/cmd_args.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd_args.rs b/src/cmd_args.rs index 4627f97..c0b46b7 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -49,10 +49,10 @@ pub(crate) enum Commands { /// Target path. Default is the current directory. path: Option, /// Show storage which the path belongs to. - #[arg(short)] + #[arg(short, long)] storage: bool, /// Show backup config covering the path. - #[arg(short)] + #[arg(short, long)] backup: bool, }, From 4e8387e3b05477db78288b0dd27a10ab000f82c5 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 03:07:48 +0900 Subject: [PATCH 47/58] fix typo --- src/cmd_status.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cmd_status.rs b/src/cmd_status.rs index 5215ac7..560c02f 100644 --- a/src/cmd_status.rs +++ b/src/cmd_status.rs @@ -21,11 +21,11 @@ pub(crate) fn cmd_status( config_dir: &Path, ) -> Result<()> { let path = path.unwrap_or(env::current_dir().context("Failed to get current directory.")?); - let currrent_device = devices::get_device(config_dir)?; + let current_device = devices::get_device(config_dir)?; if show_storage { let storages = storages::Storages::read(config_dir)?; - let storage = util::min_parent_storage(&path, &storages, &currrent_device); + let storage = util::min_parent_storage(&path, &storages, ¤t_device); trace!("storage {:?}", storage); // TODO: recursively trace all storages for subdirectory? @@ -48,7 +48,7 @@ pub(crate) fn cmd_status( }); let (target_storage, target_diff_from_storage) = - util::min_parent_storage(&path, &storages, &currrent_device) + util::min_parent_storage(&path, &storages, ¤t_device) .context("Target path is not covered in any storage")?; let covering_backup: Vec<_> = devices From 51e90b28cd2bfcd26e81b80e0bcad991c352c1f6 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 12:26:02 +0900 Subject: [PATCH 48/58] Update dependencies cargo update update clap update sysinfo 0.30 to 0.31 update sysninfo 0.31 to 0.32 update clap-verbosity-flag 2.2 -> 3.0 update env_logger 0.11.3 -> 0.11.5 update dependencies(unicode-width, dunce, pathdiff, byte-unit) update test dependencies --- Cargo.lock | 879 ++++++++++++++++++++++++++++++++++++----------------- Cargo.toml | 22 +- 2 files changed, 603 insertions(+), 298 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acb12dd..57deb60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ahash" @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -54,59 +54,60 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert_cmd" -version = "2.0.14" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" +checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" dependencies = [ "anstyle", "bstr", "doc-comment", + "libc", "predicates", "predicates-core", "predicates-tree", @@ -115,9 +116,9 @@ dependencies = [ [[package]] name = "assert_fs" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd762e110c8ed629b11b6cde59458cc1c71de78ebbcc30099fc8e0403a2a2ec" +checksum = "7efdb1fdb47602827a342857666feb372712cbc64b414172bd6b167a02927674" dependencies = [ "anstyle", "doc-comment", @@ -130,9 +131,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -142,9 +143,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -160,9 +161,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ "borsh-derive", "cfg_aliases", @@ -170,23 +171,22 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.66", - "syn_derive", + "syn 2.0.90", ] [[package]] name = "bstr" -version = "1.9.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "regex-automata", @@ -201,9 +201,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-unit" -version = "5.1.4" +version = "5.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" +checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" dependencies = [ "rust_decimal", "serde", @@ -240,19 +240,19 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.0.99" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -279,14 +279,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "clap" -version = "4.5.7" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -294,9 +294,9 @@ dependencies = [ [[package]] name = "clap-verbosity-flag" -version = "2.2.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9b20c0dd58e4c2e991c8d203bbeb76c11304d1011659686b5b644bc29aa478" +checksum = "54381ae56ad222eea3f529c692879e9c65e07945ae48d3dc4d1cb18dbec8cf44" dependencies = [ "clap", "log", @@ -304,9 +304,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -316,36 +316,36 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.5" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" +checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "console" @@ -356,15 +356,15 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.14", "windows-sys 0.52.0", ] [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crossbeam-deque" @@ -443,6 +443,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -451,9 +462,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" @@ -463,9 +474,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -475,9 +486,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -485,9 +496,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -504,19 +515,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "float-cmp" @@ -577,7 +588,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", "libgit2-sys", "log", @@ -588,9 +599,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", @@ -605,7 +616,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "ignore", "walkdir", ] @@ -621,9 +632,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -639,16 +650,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -661,20 +672,149 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", @@ -688,12 +828,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", ] [[package]] @@ -702,7 +842,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm", "dyn-clone", "fuzzy-matcher", @@ -710,36 +850,37 @@ dependencies = [ "newline-converter", "once_cell", "unicode-segmentation", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -751,9 +892,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libgit2-sys" @@ -775,7 +916,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -795,9 +936,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.18" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -811,6 +952,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -823,9 +970,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" @@ -880,9 +1027,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl-probe" @@ -892,9 +1039,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -928,14 +1075,14 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" @@ -945,21 +1092,24 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "predicates" -version = "3.1.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" dependencies = [ "anstyle", "difflib", @@ -971,15 +1121,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", @@ -987,41 +1137,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1048,9 +1175,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1113,18 +1240,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -1133,9 +1260,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1145,9 +1272,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1156,9 +1283,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" @@ -1171,9 +1298,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -1189,9 +1316,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -1200,9 +1327,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", "borsh", @@ -1216,11 +1343,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1256,31 +1383,32 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1298,6 +1426,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.17" @@ -1310,9 +1444,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", @@ -1330,9 +1464,9 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "smallvec" @@ -1340,6 +1474,12 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.11.1" @@ -1359,9 +1499,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1369,28 +1509,26 @@ dependencies = [ ] [[package]] -name = "syn_derive" -version = "0.1.8" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", ] [[package]] name = "sysinfo" -version = "0.30.12" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" dependencies = [ - "cfg-if", "core-foundation-sys", "libc", + "memchr", "ntapi", - "once_cell", "rayon", "serde", "windows", @@ -1404,14 +1542,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1422,22 +1561,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", ] [[package]] @@ -1451,10 +1590,20 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1467,53 +1616,44 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", "winnow", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unsafe-libyaml" @@ -1523,21 +1663,33 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1546,9 +1698,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "vcpkg" @@ -1558,9 +1710,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" @@ -1589,34 +1741,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1624,22 +1777,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "winapi" @@ -1659,11 +1812,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1674,12 +1827,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core", - "windows-targets 0.52.5", + "windows-core 0.57.0", + "windows-targets 0.52.6", ] [[package]] @@ -1688,7 +1841,50 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1706,7 +1902,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1726,18 +1931,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1748,9 +1953,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -1760,9 +1965,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -1772,15 +1977,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -1790,9 +1995,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -1802,9 +2007,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -1814,9 +2019,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -1826,19 +2031,31 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -1872,5 +2089,93 @@ dependencies = [ "serde", "serde_yaml", "sysinfo", - "unicode-width", + "unicode-width 0.2.0", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] diff --git a/Cargo.toml b/Cargo.toml index c11d975..e573c59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,26 +13,26 @@ keywords = ["cli", "backup"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.4.0", features = ["cargo", "derive"] } -sysinfo = { version = "0.30", features = ["serde"] } +clap = { version = "4.5", features = ["cargo", "derive"] } +sysinfo = { version = "0.32", features = ["serde"] } log = "0.4" -clap-verbosity-flag = "2.2" +clap-verbosity-flag = "3.0" clap_complete = "4.5" chrono = { version = "0.4", features = ["serde"] } -env_logger = "0.11.3" +env_logger = "0.11.5" inquire = "0.7.5" git2 = "0.19" dirs = "5.0" -dunce = "1.0.4" +dunce = "1.0.5" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" -byte-unit = "5.1.4" +byte-unit = "5.1" anyhow = "1.0" -pathdiff = "0.2.1" -unicode-width = "0.1.13" +pathdiff = "0.2.3" +unicode-width = "0.2.0" console = "0.15" [dev-dependencies] -assert_cmd = "2.0.14" -assert_fs = "1.1.1" -predicates = "3.1.0" +assert_cmd = "2.0.16" +assert_fs = "1.1.2" +predicates = "3.1.2" From 877410cd1949f37017b2f0cb7060cceaf25039ea Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 13:07:40 +0900 Subject: [PATCH 49/58] fix: some clippy warnings --- src/storages.rs | 4 ++-- src/storages/online_storage.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storages.rs b/src/storages.rs index d4b9dd4..69bdcfa 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -7,7 +7,7 @@ use crate::storages::{ }; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; -use console::{style, Style, StyledObject}; +use console::Style; use core::panic; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, fmt, fs, io, path}; @@ -156,7 +156,7 @@ pub trait StorageExt { ) -> Result<()>; /// Get parent - fn parent<'a>(&'a self, storages: &'a Storages) -> Option<&Storage>; + fn parent<'a>(&'a self, storages: &'a Storages) -> Option<&'a Storage>; } pub mod directory; diff --git a/src/storages/online_storage.rs b/src/storages/online_storage.rs index 6c4d62c..afedf16 100644 --- a/src/storages/online_storage.rs +++ b/src/storages/online_storage.rs @@ -1,6 +1,6 @@ //! Online storage which is not a children of any physical drive. -use anyhow::{Context, Result}; +use anyhow::Result; use byte_unit::Byte; use byte_unit::UnitType; use serde::{Deserialize, Serialize}; From 1d6c0eb75d4437f36678e58ace91b0508b5ef7c8 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 13:08:23 +0900 Subject: [PATCH 50/58] update: CHANGELOG (change category of notes on adding status subcommand) --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16a827f..a0a57b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ ## [Unreleased] +### Added +- Add `status` subcommand to see storage and backup on given path or current working directory ([#17](https://github.com/qwjyh/xdbm/pull/17)). + ### Changed - Colored output for `storage list` and `backup list` ([#15](https://github.com/qwjyh/xdbm/pull/15)) - **BREAKING** Relative path is changed from `PathBuf` to `Vector` for portability. This means that existing config files need to be changed. -- Add `status` subcommand to see storage and backup on given path or current working directory ([#17](https://github.com/qwjyh/xdbm/pull/17)). ## [0.2.1] - 2024-06-19 From 90cebed15fa0ba8e6d2b5692d2594a929f4eacbd Mon Sep 17 00:00:00 2001 From: qwjyh Date: Mon, 2 Dec 2024 13:10:28 +0900 Subject: [PATCH 51/58] bump to v0.3.0 --- CHANGELOG.md | 5 +++-- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0a57b9..77119fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [0.3.0] - 2024-12-02 ### Added - Add `status` subcommand to see storage and backup on given path or current working directory ([#17](https://github.com/qwjyh/xdbm/pull/17)). @@ -39,7 +39,8 @@ - `backup done` subcommand - `completion` subcommand -[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.2.1...HEAD +[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.3.0...HEAD +[0.3.0]: https://github.com/qwjyh/xdbm/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/qwjyh/xdbm/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 [0.1.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index 57deb60..0f749cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2067,7 +2067,7 @@ dependencies = [ [[package]] name = "xdbm" -version = "0.2.1" +version = "0.3.0" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index e573c59..4530408 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xdbm" -version = "0.2.1" +version = "0.3.0" authors = ["qwjyh "] edition = "2021" description = "Cross device backup manager, which manages backups on several storages mounted on multiple devices." From 47b3a5e69dc90d4e47f34b5949fec6a17e0d64bb Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Sun, 9 Feb 2025 08:39:57 +0900 Subject: [PATCH 52/58] fix: polluting gitconfig in integrated test (#20) * fix: polluting gitconfig in integrated test * debug(CI): add eprintln * debug(CI): git config * debug(CI): git init test * fix(CI): command construction * debug(CI): change workdir & add same config setup * debug(CI): use libgit2 * debug(CI): return err at the end of test using libgit2 * debug(CI): change current_dir in git config * fix(git): git config now gets local config CI was failing since xdbm init didn't get local git config. * debug: add trace log * debug: increase log level in CI * fix: getting gitconfig now respects local config * debug(CI): clean up debugging codes * fix(CI): add setup_gitconfig to two_devices test * debug(CI): inspect git config * fix(CI): add env var to allow setting git global config * refactor(CI): remove unnecessary arg for setup_gitconfig * update changelog --- .github/workflows/rust.yml | 1 + CHANGELOG.md | 6 ++++ src/main.rs | 2 +- tests/cli.rs | 59 +++++++++++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7cee19b..c307ec5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -8,6 +8,7 @@ on: env: CARGO_TERM_COLOR: always + XDBM_ENABLE_OVERWRITE_GITCONFIG: true jobs: build-and-lint: diff --git a/CHANGELOG.md b/CHANGELOG.md index 77119fe..4a1a66f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Fixed +- Git local config is now looked up. (#20) +- Git global config will not be polluted in test by default. (#20) + ## [0.3.0] - 2024-12-02 ### Added diff --git a/src/main.rs b/src/main.rs index 23dadcd..32cf7d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,7 +156,7 @@ fn add_and_commit(repo: &Repository, path: &Path, message: &str) -> Result Result<()> { - let f = match File::create_new( - home_dir() - .context("Failed to find home directory")? - .join(".gitconfig"), - ) { + let config = git2::Config::open_default().expect("failed to get default"); + if config.get_string("user.name").is_ok() && config.get_string("user.email").is_ok() { + return Ok(()); + }; + + match std::env::var_os(IS_GIT_CONFIG_WRITABLE) { + Some(_) => { + debug!( + "global git config not found & env var `{}` found", + IS_GIT_CONFIG_WRITABLE + ); + } + None => { + eprintln!("Failed to get git global config"); + eprintln!( + "Set env var `{}` to set automatically (mainly for CI)", + IS_GIT_CONFIG_WRITABLE + ); + return Err(anyhow!("failed to get git global config")); + } + }; + + let config_file = git2::Config::find_global().map_or_else( + |e| { + trace!("global git config file not found: {e:?}"); + Ok(dirs::home_dir() + .context("Failed to get home dir")? + .join(".gitconfig")) + }, + Ok, + )?; + let f = match File::options() + .create(true) + .truncate(true) + .write(true) + .open(config_file) + { io::Result::Ok(f) => f, io::Result::Err(_err) => return Ok(()), }; @@ -47,8 +81,10 @@ mod integrated_test { cmd.arg("-c") .arg(config_dir.path()) .arg("init") - .arg("testdev"); + .arg("testdev") + .arg("-vvvv"); cmd.assert().success().stdout(predicate::str::contains("")); + eprintln!("{:?}", fs::read_dir(config_dir.path())?.collect::>()); assert_eq!( std::fs::read_to_string(config_dir.path().join("devname"))?, "testdev\n" @@ -253,6 +289,7 @@ mod integrated_test { // // devices: first, second let config_dir_2 = assert_fs::TempDir::new()?; + setup_gitconfig()?; let mut cmd2 = Command::cargo_bin("xdbm")?; cmd2.arg("-c") .arg(config_dir_2.path()) From bd8e2019febebbbddedd6727bb6bdcdc7e729ac5 Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Thu, 27 Feb 2025 02:56:39 +0900 Subject: [PATCH 53/58] implement sync subcommand (#21) * new(sync): implement sync subcommand (WIP) TODO - update CHANGELOG - refactor sync func * fix(sync): add pull (only fast forward) * update(test): use sync command The first sync from 2nd device didn't work, maybe due to that it is the first push. * refactor: separate push and pull to funcs * refactor: change merge analysis match order * refactor: add logs * update: CHANGELOG * fix: CHANGELOG was wrong --- CHANGELOG.md | 3 + src/cmd_args.rs | 6 ++ src/cmd_init.rs | 8 +- src/cmd_sync.rs | 265 ++++++++++++++++++++++++++++++++++++++++++++++-- src/git.rs | 40 ++++++++ src/main.rs | 7 +- tests/cli.rs | 62 +++++------ 7 files changed, 340 insertions(+), 51 deletions(-) create mode 100644 src/git.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1a66f..575d09b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +### Added +- `sync` subcommand, which performs git pull (fast-forward) and push (#21) + ### Fixed - Git local config is now looked up. (#20) - Git global config will not be polluted in test by default. (#20) diff --git a/src/cmd_args.rs b/src/cmd_args.rs index c0b46b7..1c3eb3c 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -63,6 +63,12 @@ pub(crate) enum Commands { Sync { /// Remote name to sync. remote_name: Option, + /// Whether to use ssh-agent + #[arg(long)] + use_sshagent: bool, + /// Manually specify ssh key + #[arg(long)] + ssh_key: Option, }, /// Check config files validity. diff --git a/src/cmd_init.rs b/src/cmd_init.rs index 415489a..7207202 100644 --- a/src/cmd_init.rs +++ b/src/cmd_init.rs @@ -40,9 +40,7 @@ fn clone_repo( } }; Cred::ssh_key( - username_from_url - .context("No username found from the url") - .unwrap(), + username_from_url.ok_or(git2::Error::from_str("No username found from the url"))?, None, key as &Path, passwd.as_deref(), @@ -51,9 +49,7 @@ fn clone_repo( // use ssh agent info!("Using ssh agent to access the repository"); Cred::ssh_key_from_agent( - username_from_url - .context("No username found from the url") - .unwrap(), + username_from_url.ok_or(git2::Error::from_str("No username found from the url"))?, ) } else { error!("no ssh_key and use_sshagent"); diff --git a/src/cmd_sync.rs b/src/cmd_sync.rs index eb477ca..9611c7a 100644 --- a/src/cmd_sync.rs +++ b/src/cmd_sync.rs @@ -1,10 +1,18 @@ -use std::path::PathBuf; +use std::{ + io::{self, Write}, + path::{Path, PathBuf}, +}; -use anyhow::{anyhow, Result}; -use git2::Repository; +use anyhow::{anyhow, Context, Result}; +use git2::{build::CheckoutBuilder, Cred, FetchOptions, PushOptions, RemoteCallbacks, Repository}; -pub(crate) fn cmd_sync(config_dir: &PathBuf, remote_name: Option) -> Result<()> { - warn!("Experimental"); +pub(crate) fn cmd_sync( + config_dir: &PathBuf, + remote_name: Option, + use_sshagent: bool, + ssh_key: Option, +) -> Result<()> { + info!("cmd_sync"); let repo = Repository::open(config_dir)?; let remote_name = match remote_name { Some(remote_name) => remote_name, @@ -16,7 +24,252 @@ pub(crate) fn cmd_sync(config_dir: &PathBuf, remote_name: Option) -> Res remotes.get(0).unwrap().to_string() } }; + debug!("resolved remote name: {remote_name}"); + let mut remote = repo.find_remote(&remote_name)?; - remote.push(&[] as &[&str], None)?; + + pull( + &repo, + &mut remote, + remote_name, + &use_sshagent, + ssh_key.as_ref(), + )?; + + push(&repo, &mut remote, &use_sshagent, ssh_key.as_ref())?; + Ok(()) +} + +fn remote_callback<'b, 'a>( + use_sshagent: &'a bool, + ssh_key: Option<&'a PathBuf>, +) -> RemoteCallbacks<'a> +where + 'b: 'a, +{ + // using credentials + let mut callbacks = RemoteCallbacks::new(); + callbacks + .credentials(move |_url, username_from_url, _allowed_types| { + if let Some(key) = ssh_key { + info!("Using provided ssh key to access the repository"); + let passwd = match inquire::Password::new("SSH passphrase").prompt() { + std::result::Result::Ok(s) => Some(s), + Err(err) => { + error!("Failed to get ssh passphrase: {:?}", err); + None + } + }; + Cred::ssh_key( + username_from_url + .ok_or(git2::Error::from_str("No username found from the url"))?, + None, + key as &Path, + passwd.as_deref(), + ) + } else if *use_sshagent { + // use ssh agent + info!("Using ssh agent to access the repository"); + Cred::ssh_key_from_agent( + username_from_url + .ok_or(git2::Error::from_str("No username found from the url"))?, + ) + } else { + error!("no ssh_key and use_sshagent"); + panic!("This option must be unreachable.") + } + }) + .transfer_progress(|progress| { + if progress.received_objects() == progress.total_objects() { + print!( + "Resolving deltas {}/{}\r", + progress.indexed_deltas(), + progress.total_deltas() + ); + } else { + print!( + "Received {}/{} objects ({}) in {} bytes\r", + progress.received_objects(), + progress.total_objects(), + progress.indexed_objects(), + progress.received_bytes(), + ); + } + io::stdout().flush().unwrap(); + true + }) + .sideband_progress(|text| { + let msg = String::from_utf8_lossy(text); + eprintln!("remote: {msg}"); + true + }) + .push_transfer_progress(|current, total, bytes| { + trace!("{current}/{total} files sent \t{bytes} bytes"); + }) + .push_update_reference(|reference_name, status_msg| { + debug!("remote reference_name {reference_name}"); + match status_msg { + None => { + info!("successfully pushed"); + eprintln!("successfully pushed to {}", reference_name); + Ok(()) + } + Some(status) => { + error!("failed to push: {}", status); + Err(git2::Error::from_str(&format!( + "failed to push to {}: {}", + reference_name, status + ))) + } + } + }); + callbacks +} + +fn pull( + repo: &Repository, + remote: &mut git2::Remote, + remote_name: String, + use_sshagent: &bool, + ssh_key: Option<&PathBuf>, +) -> Result<()> { + debug!("pull"); + let callbacks = remote_callback(use_sshagent, ssh_key); + let mut fetchoptions = FetchOptions::new(); + fetchoptions.remote_callbacks(callbacks); + let fetch_refspec: Vec = remote + .refspecs() + .filter_map(|rs| match rs.direction() { + git2::Direction::Fetch => rs.str().map(|s| s.to_string()), + git2::Direction::Push => None, + }) + .collect(); + remote + .fetch(&fetch_refspec, Some(&mut fetchoptions), None) + .context("Failed to fetch (pull)")?; + let stats = remote.stats(); + if stats.local_objects() > 0 { + println!( + "\rReceived {}/{} objects in {} bytes (used {} local objects)", + stats.indexed_objects(), + stats.total_objects(), + stats.received_bytes(), + stats.local_objects(), + ); + } else { + println!( + "\rReceived {}/{} objects in {} bytes", + stats.indexed_objects(), + stats.total_objects(), + stats.received_bytes(), + ); + } + let fetch_head = repo + .reference_to_annotated_commit( + &repo + .resolve_reference_from_short_name(&remote_name) + .context("failed to get reference from fetch refspec")?, + ) + .context("failed to get annotated commit")?; + let (merge_analysis, merge_preference) = repo + .merge_analysis(&[&fetch_head]) + .context("failed to do merge_analysis")?; + + trace!("merge analysis: {:?}", merge_analysis); + trace!("merge preference: {:?}", merge_preference); + match merge_analysis { + ma if ma.is_up_to_date() => { + info!("HEAD is up to date. skip merging"); + } + ma if ma.is_fast_forward() => { + // https://github.com/rust-lang/git2-rs/blob/master/examples/pull.rs + info!("fast forward is available"); + let mut ref_remote = repo + .find_reference( + remote + .default_branch() + .context("failed to get remote default branch")? + .as_str() + .unwrap(), + ) + .context("failed to get remote reference")?; + let name = match ref_remote.name() { + Some(s) => s.to_string(), + None => String::from_utf8_lossy(ref_remote.name_bytes()).to_string(), + }; + let msg = format!("Fast-Forward: Setting {} to id: {}", name, fetch_head.id()); + println!("{}", msg); + ref_remote + .set_target(fetch_head.id(), &msg) + .context("failed to set target")?; + repo.checkout_head(Some(CheckoutBuilder::default().force())) + .context("failed to checkout")?; + } + ma if ma.is_unborn() => { + warn!("HEAD is invalid (unborn)"); + return Err(anyhow!( + "HEAD is invalid: merge_analysis: {:?}", + merge_analysis + )); + } + ma if ma.is_none() => { + error!("no merge is possible"); + return Err(anyhow!("no merge is possible")); + } + ma if ma.is_normal() => { + error!("unable to fast-forward. manual merge is required"); + return Err(anyhow!("unable to fast-forward. manual merge is required")); + } + _ma => { + error!( + "this code must not reachable: merge_analysis {:?}", + merge_analysis + ); + return Err(anyhow!("must not be reachabel (uncovered merge_analysis)")); + } + } + Ok(()) +} + +fn push( + repo: &Repository, + remote: &mut git2::Remote, + use_sshagent: &bool, + ssh_key: Option<&PathBuf>, +) -> Result<()> { + debug!("push"); + let callbacks = remote_callback(&use_sshagent, ssh_key); + let mut push_options = PushOptions::new(); + push_options.remote_callbacks(callbacks); + let num_push_refspecs = remote + .refspecs() + .filter(|rs| rs.direction() == git2::Direction::Push) + .count(); + if num_push_refspecs > 1 { + warn!("more than one push refspecs are configured"); + warn!("using the first one"); + } + let head = repo.head().context("Failed to get HEAD")?; + if num_push_refspecs >= 1 { + trace!("using push refspec"); + let push_refspec = remote + .refspecs() + .filter_map(|rs| match rs.direction() { + git2::Direction::Fetch => None, + git2::Direction::Push => Some(rs), + }) + .next() + .expect("this must be unreachabe") + .str() + .context("failed to get valid utf8 push refspec")? + .to_string(); + remote.push(&[push_refspec.as_str()] as &[&str], Some(&mut push_options))?; + } else { + trace!("using head as push refspec"); + trace!("head is branch: {:?}", head.is_branch()); + trace!("head is remote: {:?}", head.is_remote()); + let push_refspec = head.name().context("failed to get head name")?; + remote.push(&[push_refspec] as &[&str], Some(&mut push_options))?; + }; Ok(()) } diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 0000000..4ff8970 --- /dev/null +++ b/src/git.rs @@ -0,0 +1,40 @@ +use std::path::{Path, PathBuf}; + +use git2::{Cred, RemoteCallbacks}; +use inquire::Password; + +pub(crate) fn get_credential<'a>( + use_sshagent: bool, + ssh_key: Option, +) -> RemoteCallbacks<'a> { + // using credentials + let mut callbacks = RemoteCallbacks::new(); + callbacks.credentials(move |_url, username_from_url, _allowed_types| { + if let Some(key) = &ssh_key { + info!("Using provided ssh key to access the repository"); + let passwd = match Password::new("SSH passphrase").prompt() { + std::result::Result::Ok(s) => Some(s), + Err(err) => { + error!("Failed to get ssh passphrase: {:?}", err); + None + } + }; + Cred::ssh_key( + username_from_url.ok_or(git2::Error::from_str("No username found from the url"))?, + None, + key as &Path, + passwd.as_deref(), + ) + } else if use_sshagent { + // use ssh agent + info!("Using ssh agent to access the repository"); + Cred::ssh_key_from_agent( + username_from_url.ok_or(git2::Error::from_str("No username found from the url"))?, + ) + } else { + error!("no ssh_key and use_sshagent"); + panic!("This option must be unreachable.") + } + }); + callbacks +} diff --git a/src/main.rs b/src/main.rs index 32cf7d6..41aab33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,7 @@ mod cmd_status; mod cmd_storage; mod cmd_sync; mod devices; +mod git; mod inquire_filepath_completer; mod storages; mod util; @@ -91,7 +92,11 @@ fn main() -> Result<()> { Commands::Path {} => { println!("{}", &config_dir.display()); } - Commands::Sync { remote_name } => cmd_sync::cmd_sync(&config_dir, remote_name)?, + Commands::Sync { + remote_name, + use_sshagent, + ssh_key, + } => cmd_sync::cmd_sync(&config_dir, remote_name, use_sshagent, ssh_key)?, Commands::Status { path, storage, diff --git a/tests/cli.rs b/tests/cli.rs index 06e3890..b282410 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -2,6 +2,7 @@ mod integrated_test { use std::{ fs::{self, DirBuilder, File}, io::{self, BufWriter, Write}, + path, }; use anyhow::{anyhow, Context, Ok, Result}; @@ -72,6 +73,16 @@ mod integrated_test { Ok(()) } + fn run_sync_cmd(config_dir: &path::Path) -> Result<()> { + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir) + .args(["sync", "-vvvv"]) + .assert() + .success(); + Ok(()) + } + #[test] fn single_device() -> Result<()> { let config_dir = assert_fs::TempDir::new()?; @@ -313,15 +324,14 @@ mod integrated_test { assert!(config_dir_2.join("backups").join("second.yml").exists()); // sync - std::process::Command::new("git") - .arg("push") - .current_dir(&config_dir_2) + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir_2.path()) + .arg("sync") + .arg("-vvvv") .assert() - .success(); - // let repo_2 = Repository::open(config_dir_2)?; - // // return Err(anyhow!("{:?}", repo_2.remotes()?.iter().collect::>())); - // let mut repo_2_remote = repo_2.find_remote(repo_2.remotes()?.get(0).unwrap())?; - // repo_2_remote.push(&[] as &[&str], None)?; + .success() + .stderr(predicate::str::contains("successfully pushed")); std::process::Command::new("git") .arg("pull") .current_dir(&config_dir_1) @@ -381,16 +391,8 @@ mod integrated_test { std::fs::read_to_string(config_dir_1.join("storages.yml"))?.contains("parent: gdrive1") ); - std::process::Command::new("git") - .arg("push") - .current_dir(&config_dir_1) - .assert() - .success(); - std::process::Command::new("git") - .arg("pull") - .current_dir(&config_dir_2) - .assert() - .success(); + run_sync_cmd(&config_dir_1)?; + run_sync_cmd(&config_dir_2)?; // bind // @@ -604,16 +606,8 @@ mod integrated_test { .and(predicate::str::contains("foodoc").not()), ); - std::process::Command::new("git") - .arg("push") - .current_dir(&config_dir_2) - .assert() - .success(); - std::process::Command::new("git") - .arg("pull") - .current_dir(&config_dir_1) - .assert() - .success(); + run_sync_cmd(&config_dir_2)?; + run_sync_cmd(&config_dir_1)?; // bind // @@ -728,16 +722,8 @@ mod integrated_test { .assert() .success(); - std::process::Command::new("git") - .arg("push") - .current_dir(&config_dir_1) - .assert() - .success(); - std::process::Command::new("git") - .arg("pull") - .current_dir(&config_dir_2) - .assert() - .success(); + run_sync_cmd(&config_dir_1)?; + run_sync_cmd(&config_dir_2)?; // backup add // From e3b1e77f7d4b91ab681a2275580a2df784ab0987 Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Fri, 28 Feb 2025 01:13:38 +0900 Subject: [PATCH 54/58] feat: add option to statically link openssl (#22) * feat: add feature to statically link openssl and libgit2 * update CHANGELOG * update CHANGELOG --- CHANGELOG.md | 1 + Cargo.lock | 10 ++++++++++ Cargo.toml | 3 +++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 575d09b..5d3b984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added - `sync` subcommand, which performs git pull (fast-forward) and push (#21) +- Feature `vendored-openssl` to statically link openssl and libgit2 (#22) ### Fixed - Git local config is now looked up. (#20) diff --git a/Cargo.lock b/Cargo.lock index 0f749cd..8ee5e5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1037,6 +1037,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.4.2+3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.104" @@ -1045,6 +1054,7 @@ checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] diff --git a/Cargo.toml b/Cargo.toml index 4530408..45c625b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,3 +36,6 @@ console = "0.15" assert_cmd = "2.0.16" assert_fs = "1.1.2" predicates = "3.1.2" + +[features] +vendored-openssl = ["git2/vendored-openssl"] From cdb01ee708eb973c4fab55b1e4bacacbfc93bbbf Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Sat, 1 Mar 2025 09:57:08 +0900 Subject: [PATCH 55/58] release 0.4.0 (#23) * bump versions * run cargo update * update: rust edition to 2024 * update: CHANGELOG --- CHANGELOG.md | 4 +- Cargo.lock | 384 ++++++++++++++++++++++++++++----------------------- Cargo.toml | 4 +- 3 files changed, 212 insertions(+), 180 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d3b984..7a40d09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [0.4.0] - 2025-03-01 ### Added - `sync` subcommand, which performs git pull (fast-forward) and push (#21) @@ -49,7 +49,7 @@ - `backup done` subcommand - `completion` subcommand -[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.3.0...HEAD +[0.4.0]: https://github.com/qwjyh/xdbm/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/qwjyh/xdbm/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/qwjyh/xdbm/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/qwjyh/xdbm/releases/tag/v0.2.0 diff --git a/Cargo.lock b/Cargo.lock index 8ee5e5c..6dd362c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -78,19 +78,20 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "arrayvec" @@ -143,9 +144,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bitvec" @@ -161,9 +162,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" dependencies = [ "borsh-derive", "cfg_aliases", @@ -171,22 +172,22 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" +checksum = "f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "regex-automata", @@ -195,9 +196,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byte-unit" @@ -240,15 +241,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" dependencies = [ "jobserver", "libc", @@ -269,9 +270,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -279,14 +280,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "clap" -version = "4.5.21" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", @@ -294,9 +295,9 @@ dependencies = [ [[package]] name = "clap-verbosity-flag" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54381ae56ad222eea3f529c692879e9c65e07945ae48d3dc4d1cb18dbec8cf44" +checksum = "2678fade3b77aa3a8ff3aae87e9c008d3fb00473a41c71fbf74e91c8c7b37e84" dependencies = [ "clap", "log", @@ -304,9 +305,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", @@ -316,30 +317,30 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.38" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" +checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" @@ -349,15 +350,15 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width 0.1.14", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -368,9 +369,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -387,9 +388,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -451,7 +452,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -468,27 +469,27 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "feeef44e73baff3a26d371801df019877a9866a8c493d315ab00177843314f35" [[package]] name = "either" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "env_filter" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", "regex", @@ -496,9 +497,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" dependencies = [ "anstream", "anstyle", @@ -509,9 +510,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -525,15 +526,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "float-cmp" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ "num-traits", ] @@ -579,7 +580,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", ] [[package]] @@ -588,7 +601,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "libc", "libgit2-sys", "log", @@ -616,7 +629,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "ignore", "walkdir", ] @@ -786,7 +799,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -828,9 +841,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -842,7 +855,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "crossterm", "dyn-clone", "fuzzy-matcher", @@ -876,25 +889,19 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.167" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libgit2-sys" @@ -916,15 +923,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "libc", ] [[package]] name = "libssh2-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" dependencies = [ "cc", "libc", @@ -936,9 +943,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.20" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" dependencies = [ "cc", "libc", @@ -948,9 +955,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -970,9 +977,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" @@ -988,7 +995,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -1027,15 +1034,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" @@ -1048,9 +1055,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -1117,9 +1124,9 @@ dependencies = [ [[package]] name = "predicates" -version = "3.1.2" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" dependencies = [ "anstyle", "difflib", @@ -1131,15 +1138,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" [[package]] name = "predicates-tree" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" dependencies = [ "predicates-core", "termtree", @@ -1156,9 +1163,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -1185,9 +1192,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1225,7 +1232,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -1250,11 +1257,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", ] [[package]] @@ -1263,7 +1270,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror", ] @@ -1353,22 +1360,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] -name = "ryu" -version = "1.0.18" +name = "rustversion" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "same-file" @@ -1393,29 +1406,29 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", @@ -1480,9 +1493,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "stable_deref_trait" @@ -1509,9 +1522,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1526,7 +1539,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -1552,12 +1565,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.14.0" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.3.1", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1565,9 +1579,9 @@ dependencies = [ [[package]] name = "termtree" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "thiserror" @@ -1586,7 +1600,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -1611,9 +1625,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -1632,9 +1646,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "toml_datetime", @@ -1643,9 +1657,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-segmentation" @@ -1708,9 +1722,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "bd8dcafa1ca14750d8d7a05aa05988c17aab20886e1f3ae33a40223c58d92ef7" [[package]] name = "vcpkg" @@ -1726,9 +1740,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -1750,36 +1764,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.97" +name = "wasi" +version = "0.13.3+wasi-0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1787,22 +1810,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "winapi" @@ -1874,7 +1900,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -1885,9 +1911,15 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + [[package]] name = "windows-result" version = "0.1.2" @@ -1906,15 +1938,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" @@ -2047,13 +2070,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -2077,7 +2109,7 @@ dependencies = [ [[package]] name = "xdbm" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "assert_cmd", @@ -2122,7 +2154,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", "synstructure", ] @@ -2144,7 +2176,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] [[package]] @@ -2164,7 +2196,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", "synstructure", ] @@ -2187,5 +2219,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.98", ] diff --git a/Cargo.toml b/Cargo.toml index 45c625b..1daa11c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "xdbm" -version = "0.3.0" +version = "0.4.0" authors = ["qwjyh "] -edition = "2021" +edition = "2024" description = "Cross device backup manager, which manages backups on several storages mounted on multiple devices." readme = "README.md" homepage = "https://github.com/qwjyh/xdbm" From 851c0259a1088703fd68e7a1e1c5e5aa24ebe25d Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sat, 1 Mar 2025 10:19:59 +0900 Subject: [PATCH 56/58] post v0.4.0 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a40d09..322bfbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## [Unreleased] + ## [0.4.0] - 2025-03-01 ### Added @@ -49,6 +51,7 @@ - `backup done` subcommand - `completion` subcommand +[Unreleased]: https://github.com/qwjyh/xdbm/compare/v0.4.0...HEAD [0.4.0]: https://github.com/qwjyh/xdbm/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/qwjyh/xdbm/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/qwjyh/xdbm/compare/v0.2.0...v0.2.1 From e9c1872d791f54bb7f3522877665f7405be54430 Mon Sep 17 00:00:00 2001 From: qwjyh <62229267+qwjyh@users.noreply.github.com> Date: Sun, 2 Mar 2025 11:20:19 +0900 Subject: [PATCH 57/58] Use git cli in sync subcommand, and make custom implementation optional (#27) * new: add use_cl option and separate to function * refactor: format * new(sync): add option to use git cli * change(sync)!: now it use git cli by default * lint: remove unnecessary ref * fix(sync): use stderr for log prints * update: CHANGELOG --- CHANGELOG.md | 3 ++ src/cmd_args.rs | 5 +++- src/cmd_init.rs | 8 +++-- src/cmd_sync.rs | 79 +++++++++++++++++++++++++++++++++++++++++++------ src/main.rs | 5 ++-- tests/cli.rs | 40 +++++++++++++++---------- 6 files changed, 110 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 322bfbe..d9d354d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +### Added +- Option to use `git` cli in `sync` subcommand. This is now the default (#27) + ## [0.4.0] - 2025-03-01 ### Added diff --git a/src/cmd_args.rs b/src/cmd_args.rs index 1c3eb3c..82debe6 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -1,7 +1,7 @@ //! CLI arguments -use crate::path; use crate::PathBuf; +use crate::path; use clap::Args; use clap::{Parser, Subcommand}; use clap_verbosity_flag::Verbosity; @@ -63,6 +63,9 @@ pub(crate) enum Commands { Sync { /// Remote name to sync. remote_name: Option, + /// Use custom git implementation. + #[arg(short, long)] + use_libgit2: bool, /// Whether to use ssh-agent #[arg(long)] use_sshagent: bool, diff --git a/src/cmd_init.rs b/src/cmd_init.rs index 7207202..c9d6d8a 100644 --- a/src/cmd_init.rs +++ b/src/cmd_init.rs @@ -2,11 +2,13 @@ //! Initialize xdbm for the device. use crate::backups::Backups; -use crate::storages::{Storages, STORAGESFILE}; +use crate::storages::{STORAGESFILE, Storages}; use crate::{ - add_and_commit, backups, full_status, get_devices, write_devices, Device, DEVICESFILE, + DEVICESFILE, Device, add_and_commit, backups, + devices::{get_devices, write_devices}, + full_status, }; -use anyhow::{anyhow, Context, Ok, Result}; +use anyhow::{Context, Ok, Result, anyhow}; use core::panic; use git2::{Cred, RemoteCallbacks, Repository}; use inquire::Password; diff --git a/src/cmd_sync.rs b/src/cmd_sync.rs index 9611c7a..d6186f5 100644 --- a/src/cmd_sync.rs +++ b/src/cmd_sync.rs @@ -1,16 +1,77 @@ use std::{ io::{self, Write}, path::{Path, PathBuf}, + process, }; -use anyhow::{anyhow, Context, Result}; -use git2::{build::CheckoutBuilder, Cred, FetchOptions, PushOptions, RemoteCallbacks, Repository}; +use anyhow::{Context, Result, anyhow}; +use git2::{Cred, FetchOptions, PushOptions, RemoteCallbacks, Repository, build::CheckoutBuilder}; pub(crate) fn cmd_sync( config_dir: &PathBuf, remote_name: Option, use_sshagent: bool, ssh_key: Option, + use_libgit2: bool, +) -> Result<()> { + if use_libgit2 { + cmd_sync_custom(config_dir, remote_name, use_sshagent, ssh_key) + } else { + cmd_sync_cl(config_dir, remote_name, ssh_key) + } +} + +fn cmd_sync_cl( + config_dir: &PathBuf, + remote_name: Option, + ssh_key: Option, +) -> Result<()> { + info!("cmd_sync (command line version)"); + + trace!("pull"); + let args = |cmd| { + let mut args = vec![cmd]; + if let Some(ref remote_name) = remote_name { + args.push(remote_name.clone()); + } + if let Some(ref ssh_key) = ssh_key { + args.push("-i".to_string()); + args.push(ssh_key.to_str().unwrap().to_owned()); + } + args + }; + let git_pull_result = process::Command::new("git") + .args(args("pull".to_owned())) + .current_dir(config_dir) + .status() + .context("error while executing git pull")? + .success(); + if git_pull_result { + eprintln!("git pull completed"); + } else { + return Err(anyhow!("failed to complete git pull")); + } + + trace!("push"); + let git_push_result = process::Command::new("git") + .args(args("push".to_owned())) + .current_dir(config_dir) + .status() + .context("error while executing git push")? + .success(); + if git_push_result { + eprintln!("git push completed"); + } else { + return Err(anyhow!("failed to complete git push")); + } + Ok(()) +} + +fn cmd_sync_custom( + config_dir: &PathBuf, + remote_name: Option, + use_sshagent: bool, + ssh_key: Option, ) -> Result<()> { info!("cmd_sync"); let repo = Repository::open(config_dir)?; @@ -81,13 +142,13 @@ where }) .transfer_progress(|progress| { if progress.received_objects() == progress.total_objects() { - print!( + eprint!( "Resolving deltas {}/{}\r", progress.indexed_deltas(), progress.total_deltas() ); } else { - print!( + eprint!( "Received {}/{} objects ({}) in {} bytes\r", progress.received_objects(), progress.total_objects(), @@ -95,7 +156,7 @@ where progress.received_bytes(), ); } - io::stdout().flush().unwrap(); + io::stderr().flush().unwrap(); true }) .sideband_progress(|text| { @@ -149,7 +210,7 @@ fn pull( .context("Failed to fetch (pull)")?; let stats = remote.stats(); if stats.local_objects() > 0 { - println!( + eprintln!( "\rReceived {}/{} objects in {} bytes (used {} local objects)", stats.indexed_objects(), stats.total_objects(), @@ -157,7 +218,7 @@ fn pull( stats.local_objects(), ); } else { - println!( + eprintln!( "\rReceived {}/{} objects in {} bytes", stats.indexed_objects(), stats.total_objects(), @@ -198,7 +259,7 @@ fn pull( None => String::from_utf8_lossy(ref_remote.name_bytes()).to_string(), }; let msg = format!("Fast-Forward: Setting {} to id: {}", name, fetch_head.id()); - println!("{}", msg); + eprintln!("{}", msg); ref_remote .set_target(fetch_head.id(), &msg) .context("failed to set target")?; @@ -238,7 +299,7 @@ fn push( ssh_key: Option<&PathBuf>, ) -> Result<()> { debug!("push"); - let callbacks = remote_callback(&use_sshagent, ssh_key); + let callbacks = remote_callback(use_sshagent, ssh_key); let mut push_options = PushOptions::new(); push_options.remote_callbacks(callbacks); let num_push_refspecs = remote diff --git a/src/main.rs b/src/main.rs index 41aab33..7c8d47e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ use std::path::{self, PathBuf}; use storages::Storages; use crate::cmd_args::{BackupSubCommands, Cli, Commands, StorageCommands}; -use devices::{Device, DEVICESFILE, *}; +use devices::{DEVICESFILE, Device}; mod backups; mod cmd_args; @@ -94,9 +94,10 @@ fn main() -> Result<()> { } Commands::Sync { remote_name, + use_libgit2, use_sshagent, ssh_key, - } => cmd_sync::cmd_sync(&config_dir, remote_name, use_sshagent, ssh_key)?, + } => cmd_sync::cmd_sync(&config_dir, remote_name, use_sshagent, ssh_key, use_libgit2)?, Commands::Status { path, storage, diff --git a/tests/cli.rs b/tests/cli.rs index b282410..4582915 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -5,8 +5,8 @@ mod integrated_test { path, }; - use anyhow::{anyhow, Context, Ok, Result}; - use assert_cmd::{assert::OutputAssertExt, Command}; + use anyhow::{Context, Ok, Result, anyhow}; + use assert_cmd::{Command, assert::OutputAssertExt}; use git2::Repository; use log::{debug, trace}; use predicates::{boolean::PredicateBooleanExt, prelude::predicate}; @@ -73,13 +73,22 @@ mod integrated_test { Ok(()) } - fn run_sync_cmd(config_dir: &path::Path) -> Result<()> { - Command::cargo_bin("xdbm")? - .arg("-c") - .arg(config_dir) - .args(["sync", "-vvvv"]) - .assert() - .success(); + fn run_sync_cmd(config_dir: &path::Path, use_cl: bool) -> Result<()> { + if use_cl { + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir) + .args(["sync", "-vvvv"]) + .assert() + .success(); + } else { + Command::cargo_bin("xdbm")? + .arg("-c") + .arg(config_dir) + .args(["sync", "-vvvv", "-u"]) + .assert() + .success(); + } Ok(()) } @@ -329,6 +338,7 @@ mod integrated_test { .arg(config_dir_2.path()) .arg("sync") .arg("-vvvv") + .arg("-u") .assert() .success() .stderr(predicate::str::contains("successfully pushed")); @@ -391,8 +401,8 @@ mod integrated_test { std::fs::read_to_string(config_dir_1.join("storages.yml"))?.contains("parent: gdrive1") ); - run_sync_cmd(&config_dir_1)?; - run_sync_cmd(&config_dir_2)?; + run_sync_cmd(&config_dir_1, false)?; + run_sync_cmd(&config_dir_2, false)?; // bind // @@ -606,8 +616,8 @@ mod integrated_test { .and(predicate::str::contains("foodoc").not()), ); - run_sync_cmd(&config_dir_2)?; - run_sync_cmd(&config_dir_1)?; + run_sync_cmd(&config_dir_2, true)?; + run_sync_cmd(&config_dir_1, true)?; // bind // @@ -722,8 +732,8 @@ mod integrated_test { .assert() .success(); - run_sync_cmd(&config_dir_1)?; - run_sync_cmd(&config_dir_2)?; + run_sync_cmd(&config_dir_1, false)?; + run_sync_cmd(&config_dir_2, false)?; // backup add // From 31e76661f49876aa5c77c623af54003ed3df1712 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 9 Apr 2025 23:49:55 +0900 Subject: [PATCH 58/58] fix(cmd_sync): progress handler printing --- src/cmd_sync.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cmd_sync.rs b/src/cmd_sync.rs index d6186f5..6318e59 100644 --- a/src/cmd_sync.rs +++ b/src/cmd_sync.rs @@ -142,14 +142,14 @@ where }) .transfer_progress(|progress| { if progress.received_objects() == progress.total_objects() { - eprint!( - "Resolving deltas {}/{}\r", + print!( + "\rResolving deltas {}/{}", progress.indexed_deltas(), progress.total_deltas() ); } else { - eprint!( - "Received {}/{} objects ({}) in {} bytes\r", + print!( + "\rReceived {}/{} objects ({}) in {} bytes", progress.received_objects(), progress.total_objects(), progress.indexed_objects(),