Compare commits
10 commits
165d577a3d
...
bbe193139c
Author | SHA1 | Date | |
---|---|---|---|
bbe193139c | |||
7b7df65b13 | |||
4b31fd60c0 | |||
bd5217bbd4 | |||
50d7df08be | |||
2c3fb1b133 | |||
2d092ea70d | |||
f29388f42b | |||
|
a2eb830dd5 | ||
|
e171f348f7 |
13 changed files with 740 additions and 630 deletions
37
.gitea/workflows/build.yaml
Normal file
37
.gitea/workflows/build.yaml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
name: build
|
||||||
|
|
||||||
|
on: push
|
||||||
|
env:
|
||||||
|
DEV_SHELL_NAME: CI
|
||||||
|
CI: true
|
||||||
|
jobs:
|
||||||
|
build-cargo:
|
||||||
|
runs-on: flakes-action
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- name:
|
||||||
|
run: |
|
||||||
|
nix develop -c cargo build --release
|
||||||
|
build-nix:
|
||||||
|
runs-on: flakes-action
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- name:
|
||||||
|
run: |
|
||||||
|
nix build
|
||||||
|
check-nix:
|
||||||
|
runs-on: flakes-action
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- name: Metadata
|
||||||
|
run: |
|
||||||
|
nix flake metadata
|
||||||
|
- name: Statix
|
||||||
|
run: |
|
||||||
|
nix develop -c statix check
|
||||||
|
- name: Flake check
|
||||||
|
run: |
|
||||||
|
nix flake check
|
1018
Cargo.lock
generated
1018
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
21
Cargo.toml
21
Cargo.toml
|
@ -3,31 +3,36 @@ name = "bakare"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Cyryl Płotnicki <cyplo@cyplo.dev>"]
|
authors = ["Cyryl Płotnicki <cyplo@cyplo.dev>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56"
|
rust-version = "1.63"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
description = "modern and simple, yet efficient backup solution"
|
description = "modern and simple, yet efficient backup solution"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
base64 = "0.13"
|
base64 = "0.21"
|
||||||
blake = "2"
|
blake = "2"
|
||||||
chacha20poly1305 = "0.9"
|
chacha20poly1305 = "0.10"
|
||||||
fail = "0.4"
|
fail = "0.5"
|
||||||
femme = "2"
|
femme = "2"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nix = "0.23"
|
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
reed-solomon = "0.2"
|
reed-solomon = "0.2"
|
||||||
|
seahorse = "2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
sha2 = "0.9"
|
sha2 = "0.10"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "1", features = ["v4"] }
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
|
|
||||||
|
[dependencies.nix]
|
||||||
|
version = "0.27"
|
||||||
|
default-features = false
|
||||||
|
features = ["process"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.5"
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
proptest = "1"
|
proptest = "1"
|
||||||
two-rusty-forks = "0.4"
|
two-rusty-forks = "0.4"
|
||||||
|
|
100
flake.lock
100
flake.lock
|
@ -1,29 +1,13 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"crate2nix": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1634898841,
|
|
||||||
"narHash": "sha256-CZgjBo0rYeQHiIfnFD5wj9vmI/O24IaCT0yzPnW0FSQ=",
|
|
||||||
"owner": "kolloch",
|
|
||||||
"repo": "crate2nix",
|
|
||||||
"rev": "d8566765a23c5f8f8e50a726bb0db7957452b5e8",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "kolloch",
|
|
||||||
"repo": "crate2nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1627913399,
|
"lastModified": 1696426674,
|
||||||
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -32,87 +16,85 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils": {
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1623875721,
|
"lastModified": 1698420672,
|
||||||
"narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
|
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
|
||||||
"owner": "numtide",
|
"owner": "nix-community",
|
||||||
"repo": "flake-utils",
|
"repo": "naersk",
|
||||||
"rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
|
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"owner": "nix-community",
|
||||||
"repo": "flake-utils",
|
"repo": "naersk",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1634758644,
|
"lastModified": 1699065553,
|
||||||
"narHash": "sha256-H3UW/msC6wadg28lcgZv2Ge/P7dWxesL6i37a0GOeyM=",
|
"narHash": "sha256-j8UmH8fqXcOgL6WrlMcvV2m2XQ6OzU0IBucyuJ0vnyQ=",
|
||||||
"owner": "nixos",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "70904d4a9927a4d6e05c72c4aaac4370e05107f3",
|
"rev": "8ab9c53eee434651ce170dee1d9727b974e9a6b6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"id": "nixpkgs",
|
||||||
"ref": "nixos-21.05",
|
"type": "indirect"
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1628186154,
|
"lastModified": 1699065553,
|
||||||
"narHash": "sha256-r2d0wvywFnL9z4iptztdFMhaUIAaGzrSs7kSok0PgmE=",
|
"narHash": "sha256-j8UmH8fqXcOgL6WrlMcvV2m2XQ6OzU0IBucyuJ0vnyQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "06552b72346632b6943c8032e57e702ea12413bf",
|
"rev": "8ab9c53eee434651ce170dee1d9727b974e9a6b6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"id": "nixpkgs",
|
||||||
"repo": "nixpkgs",
|
"type": "indirect"
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"crate2nix": "crate2nix",
|
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"nixpkgs": "nixpkgs",
|
"naersk": "naersk",
|
||||||
"rust-overlay": "rust-overlay",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-overlay": {
|
"systems": {
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1634869268,
|
"lastModified": 1681028828,
|
||||||
"narHash": "sha256-RVAcEFlFU3877Mm4q/nbXGEYTDg/wQNhzmXGMTV6wBs=",
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
"owner": "oxalica",
|
"owner": "nix-systems",
|
||||||
"repo": "rust-overlay",
|
"repo": "default",
|
||||||
"rev": "c02c2d86354327317546501af001886fbb53d374",
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "oxalica",
|
"owner": "nix-systems",
|
||||||
"repo": "rust-overlay",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1634851050,
|
"lastModified": 1694529238,
|
||||||
"narHash": "sha256-N83GlSGPJJdcqhUxSCS/WwW5pksYf3VP1M13cDRTSVA=",
|
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "c91f3de5adaf1de973b797ef7485e441a65b8935",
|
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
118
flake.nix
118
flake.nix
|
@ -1,95 +1,59 @@
|
||||||
{
|
{
|
||||||
description = "A simple yet robust commandline random password generator.";
|
description = "Bakare: modern and simple, yet efficient backup solution";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
|
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils.url = "github:numtide/flake-utils";
|
||||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
naersk.url = "github:nix-community/naersk";
|
||||||
crate2nix = {
|
|
||||||
url = "github:kolloch/crate2nix";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
flake-compat = {
|
flake-compat = {
|
||||||
url = "github:edolstra/flake-compat";
|
url = "github:edolstra/flake-compat";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, utils, rust-overlay, crate2nix, ... }:
|
outputs = {
|
||||||
let
|
self,
|
||||||
name = "bakare";
|
nixpkgs,
|
||||||
rustChannel = "stable";
|
utils,
|
||||||
in
|
naersk,
|
||||||
utils.lib.eachDefaultSystem
|
flake-compat,
|
||||||
(system:
|
}:
|
||||||
let
|
utils.lib.eachDefaultSystem (system: let
|
||||||
# Imports
|
pkgs = nixpkgs.legacyPackages."${system}";
|
||||||
pkgs = import nixpkgs {
|
naersk-lib = naersk.lib."${system}";
|
||||||
inherit system;
|
in rec {
|
||||||
overlays = [
|
|
||||||
rust-overlay.overlay
|
|
||||||
(self: super: {
|
|
||||||
# Because rust-overlay bundles multiple rust packages into one
|
|
||||||
# derivation, specify that mega-bundle here, so that crate2nix
|
|
||||||
# will use them automatically.
|
|
||||||
rustc = self.rust-bin.${rustChannel}.latest.default;
|
|
||||||
cargo = self.rust-bin.${rustChannel}.latest.default;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
inherit (import "${crate2nix}/tools.nix" { inherit pkgs; })
|
|
||||||
generatedCargoNix;
|
|
||||||
|
|
||||||
# Create the cargo2nix project
|
|
||||||
project = pkgs.callPackage
|
|
||||||
(generatedCargoNix {
|
|
||||||
inherit name;
|
|
||||||
src = ./.;
|
|
||||||
})
|
|
||||||
{
|
|
||||||
# Individual crate overrides go here
|
|
||||||
# Example: https://github.com/balsoft/simple-osd-daemons/blob/6f85144934c0c1382c7a4d3a2bbb80106776e270/flake.nix#L28-L50
|
|
||||||
defaultCrateOverrides = pkgs.defaultCrateOverrides // {
|
|
||||||
# The himalaya crate itself is overriden here. Typically we
|
|
||||||
# configure non-Rust dependencies (see below) here.
|
|
||||||
${name} = oldAttrs: {
|
|
||||||
inherit buildInputs nativeBuildInputs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
buildInputs = with pkgs; [ openssl.dev cacert openssh zlib ];
|
|
||||||
nativeBuildInputs = with pkgs; [ rustc cargo pkgconfig git ];
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
packages.${name} = project.rootCrate.build;
|
|
||||||
|
|
||||||
# `nix build`
|
# `nix build`
|
||||||
defaultPackage = packages.${name};
|
packages.bakare = naersk-lib.buildPackage {
|
||||||
|
pname = "bakare";
|
||||||
|
root = ./.;
|
||||||
|
};
|
||||||
|
defaultPackage = packages.bakare;
|
||||||
|
|
||||||
# `nix run`
|
# `nix run`
|
||||||
apps.${name} = utils.lib.mkApp {
|
apps.bakare = utils.lib.mkApp {drv = packages.bakare;};
|
||||||
inherit name;
|
defaultApp = apps.bakare;
|
||||||
drv = packages.${name};
|
|
||||||
};
|
|
||||||
defaultApp = apps.${name};
|
|
||||||
|
|
||||||
# `nix develop`
|
# `nix develop`
|
||||||
devShell = pkgs.mkShell
|
devShell = pkgs.mkShell {
|
||||||
{
|
nativeBuildInputs = with pkgs; [
|
||||||
inputsFrom = builtins.attrValues self.packages.${system};
|
cacert
|
||||||
buildInputs = buildInputs ++ (with pkgs;
|
cargo
|
||||||
[
|
|
||||||
nixpkgs-fmt
|
|
||||||
cargo-watch
|
|
||||||
cargo-edit
|
cargo-edit
|
||||||
|
cargo-mutants
|
||||||
|
cargo-nextest
|
||||||
cargo-outdated
|
cargo-outdated
|
||||||
pkgs.rust-bin.${rustChannel}.latest.rust-analysis
|
cargo-release
|
||||||
pkgs.rust-bin.${rustChannel}.latest.rls
|
cargo-watch
|
||||||
]);
|
clippy
|
||||||
RUST_SRC_PATH = "${pkgs.rust-bin.${rustChannel}.latest.rust-src}/lib/rustlib/src/rust/library";
|
git
|
||||||
|
llvmPackages_13.llvm
|
||||||
|
nixpkgs-fmt
|
||||||
|
openssh
|
||||||
|
openssl
|
||||||
|
pkg-config
|
||||||
|
rustc
|
||||||
|
rustfmt
|
||||||
|
statix
|
||||||
|
];
|
||||||
|
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||||
};
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,8 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use chacha20poly1305::aead::{Aead, NewAead};
|
use chacha20poly1305::{aead::Aead, Key, KeyInit, XChaCha20Poly1305, XNonce};
|
||||||
use chacha20poly1305::{Key, XChaCha20Poly1305, XNonce}; // Or `XChaCha20Poly1305`
|
use nix::unistd::getpid;
|
||||||
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::index::item::IndexItem;
|
use crate::index::item::IndexItem;
|
||||||
|
@ -18,7 +17,6 @@ use crate::repository::ItemId;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
use lock::Lock;
|
use lock::Lock;
|
||||||
use nix::unistd::getpid;
|
|
||||||
use std::{cmp::max, io::Write};
|
use std::{cmp::max, io::Write};
|
||||||
|
|
||||||
impl Index {
|
impl Index {
|
||||||
|
|
|
@ -96,14 +96,14 @@ impl Lock {
|
||||||
let lock_file_path = Lock::lock_file_path(index_directory, lock_id)?;
|
let lock_file_path = Lock::lock_file_path(index_directory, lock_id)?;
|
||||||
fail_point!("create-lock-file", |e: Option<String>| Err(anyhow!(e.unwrap())));
|
fail_point!("create-lock-file", |e: Option<String>| Err(anyhow!(e.unwrap())));
|
||||||
let mut file = File::create(lock_file_path)?;
|
let mut file = File::create(lock_file_path)?;
|
||||||
let lock_id_text = lock_id.to_hyphenated().to_string();
|
let lock_id_text = lock_id.as_hyphenated().to_string();
|
||||||
let lock_id_bytes = lock_id_text.as_bytes();
|
let lock_id_bytes = lock_id_text.as_bytes();
|
||||||
Ok(file.write_all(lock_id_bytes)?)
|
Ok(file.write_all(lock_id_bytes)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock_file_path(path: &Path, lock_id: Uuid) -> Result<PathBuf> {
|
fn lock_file_path(path: &Path, lock_id: Uuid) -> Result<PathBuf> {
|
||||||
let file_name = format!("{}{}", lock_id, FILE_EXTENSION);
|
let file_name = format!("{}{}", lock_id, FILE_EXTENSION);
|
||||||
Ok(path.join(&file_name))
|
Ok(path.join(file_name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1 +1,13 @@
|
||||||
fn main() {}
|
use seahorse::App;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let app = App::new(env!("CARGO_PKG_NAME"))
|
||||||
|
.description(env!("CARGO_PKG_DESCRIPTION"))
|
||||||
|
.author(env!("CARGO_PKG_AUTHORS"))
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.action(|c| println!("Hello, {:?}", c.args));
|
||||||
|
|
||||||
|
app.run(args);
|
||||||
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl RepositoryItem {
|
||||||
let original_source_path = Path::new(self.original_source_path());
|
let original_source_path = Path::new(self.original_source_path());
|
||||||
let source_path_relative = original_source_path.strip_prefix("/")?;
|
let source_path_relative = original_source_path.strip_prefix("/")?;
|
||||||
|
|
||||||
let target_path = save_to.join(&source_path_relative);
|
let target_path = save_to.join(source_path_relative);
|
||||||
let parent = target_path
|
let parent = target_path
|
||||||
.parent()
|
.parent()
|
||||||
.ok_or_else(|| anyhow!("cannot compute parent path for {}", &target_path.to_string_lossy()))?;
|
.ok_or_else(|| anyhow!("cannot compute parent path for {}", &target_path.to_string_lossy()))?;
|
||||||
|
|
|
@ -43,13 +43,15 @@ pub struct RepositoryItemIterator<'a> {
|
||||||
//TODO: move to serializers::base64
|
//TODO: move to serializers::base64
|
||||||
mod base64 {
|
mod base64 {
|
||||||
use ::base64;
|
use ::base64;
|
||||||
|
use base64::{engine::general_purpose, Engine};
|
||||||
use serde::{de, Deserialize, Deserializer, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(&base64::encode(bytes))
|
let encoded = general_purpose::STANDARD.encode(bytes);
|
||||||
|
serializer.serialize_str(&encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||||
|
@ -57,7 +59,7 @@ mod base64 {
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let s = <&str>::deserialize(deserializer)?;
|
let s = <&str>::deserialize(deserializer)?;
|
||||||
base64::decode(s).map_err(de::Error::custom)
|
general_purpose::STANDARD.decode(s).map_err(de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +99,7 @@ impl Debug for ItemId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Repository {
|
impl Repository {
|
||||||
pub fn init(path: &Path, secret: &str) -> Result<Repository> {
|
pub fn init(path: &Path, secret: &str) -> Result<Repository> {
|
||||||
fs::create_dir_all(path)?;
|
fs::create_dir_all(path)?;
|
||||||
let mut index = Index::new()?;
|
let mut index = Index::new()?;
|
||||||
|
@ -129,7 +131,7 @@ impl<'a> Repository {
|
||||||
pub fn store(&mut self, source_path: &Path) -> Result<()> {
|
pub fn store(&mut self, source_path: &Path) -> Result<()> {
|
||||||
let id = Repository::calculate_id(source_path)?;
|
let id = Repository::calculate_id(source_path)?;
|
||||||
let destination = self.data_dir()?;
|
let destination = self.data_dir()?;
|
||||||
let destination = destination.join(&id.to_string());
|
let destination = destination.join(id.to_string());
|
||||||
|
|
||||||
if !source_path.metadata()?.is_file() {
|
if !source_path.metadata()?.is_file() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -139,9 +141,9 @@ impl<'a> Repository {
|
||||||
.ok_or_else(|| anyhow!("cannot compute parent path for {}", &destination.to_string_lossy()))?;
|
.ok_or_else(|| anyhow!("cannot compute parent path for {}", &destination.to_string_lossy()))?;
|
||||||
fs::create_dir_all(parent)?;
|
fs::create_dir_all(parent)?;
|
||||||
if !destination.exists() {
|
if !destination.exists() {
|
||||||
fs::copy(&source_path, &destination)?;
|
fs::copy(source_path, &destination)?;
|
||||||
}
|
}
|
||||||
let relative_path = destination.strip_prefix(&self.path())?;
|
let relative_path = destination.strip_prefix(self.path())?;
|
||||||
self.index.remember(source_path, &relative_path.to_string_lossy(), id);
|
self.index.remember(source_path, &relative_path.to_string_lossy(), id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub mod in_memory {
|
||||||
|
|
||||||
restore_engine.restore(&item.unwrap())?;
|
restore_engine.restore(&item.unwrap())?;
|
||||||
let source_file_relative_path = Path::new(source_file_full_path).strip_prefix("/")?;
|
let source_file_relative_path = Path::new(source_file_full_path).strip_prefix("/")?;
|
||||||
let restored_file_path = restore_target.path().join(&source_file_relative_path);
|
let restored_file_path = restore_target.path().join(source_file_relative_path);
|
||||||
assert_target_file_contents(&restored_file_path, contents)
|
assert_target_file_contents(&restored_file_path, contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ pub mod in_memory {
|
||||||
let restore_engine = restore::Engine::new(&mut restore_repository, restore_target.path())?;
|
let restore_engine = restore::Engine::new(&mut restore_repository, restore_target.path())?;
|
||||||
restore_engine.restore(&old_item.unwrap())?;
|
restore_engine.restore(&old_item.unwrap())?;
|
||||||
let source_file_relative_path = Path::new(source_file_full_path).strip_prefix("/")?;
|
let source_file_relative_path = Path::new(source_file_full_path).strip_prefix("/")?;
|
||||||
let restored_file_path = restore_target.path().join(&source_file_relative_path);
|
let restored_file_path = restore_target.path().join(source_file_relative_path);
|
||||||
assert_target_file_contents(&restored_file_path, old_contents)
|
assert_target_file_contents(&restored_file_path, old_contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ mod must {
|
||||||
|
|
||||||
let dir = tempdir()?;
|
let dir = tempdir()?;
|
||||||
let repository_path = dir.path();
|
let repository_path = dir.path();
|
||||||
let repository_path = repository_path.join(&format!("repository-{}", getpid()));
|
let repository_path = repository_path.join(format!("repository-{}", getpid()));
|
||||||
let secret = "some secret";
|
let secret = "some secret";
|
||||||
Repository::init(&repository_path, secret)?;
|
Repository::init(&repository_path, secret)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue