feat: working app
This commit is contained in:
parent
344e1693bd
commit
ea70650c45
19 changed files with 653 additions and 197 deletions
|
@ -1,23 +1,28 @@
|
||||||
name = "common"
|
# Crate Manifest for Dotfile Processor
|
||||||
description = "Common set of utilities"
|
|
||||||
|
|
||||||
[pkgs]
|
[crate]
|
||||||
openssh-server = {}
|
name = "dotfile-processor"
|
||||||
openssh-client = {}
|
description = "A versatile crate for managing dotfiles and system configurations."
|
||||||
git = {}
|
author = "Strix"
|
||||||
netselect = { distros = ["debian", "ubuntu"] }
|
|
||||||
reflector = { distros = ["arch"] }
|
|
||||||
|
|
||||||
[actions]
|
# List of packages to be installed
|
||||||
setup_ssh = ["sh", "./scripts/%"]
|
[[packages]]
|
||||||
reflector = { args = ["sh", "./scripts/setup_pm/%"], distro = ["arch"] }
|
name = "git"
|
||||||
netselect = { args = [
|
description = "Version control system"
|
||||||
"sh",
|
|
||||||
"./scripts/setup_pm/%",
|
|
||||||
], distro = [
|
|
||||||
"debian",
|
|
||||||
"ubuntu",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[super_actions]
|
[[packages]]
|
||||||
pam_wheel = ["sh", "./scripts/%"]
|
name = "nvim"
|
||||||
|
description = "Text editor for creating and editing files"
|
||||||
|
distro_name_mapping = { pacman = "neovim" }
|
||||||
|
|
||||||
|
[[packages]]
|
||||||
|
name = "zsh"
|
||||||
|
description = "Shell designed for interactive use"
|
||||||
|
|
||||||
|
[[actions.command]]
|
||||||
|
user = "root"
|
||||||
|
command = "sh ./scripts/pam_wheel.sh"
|
||||||
|
description = "Pam wheel setup"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
repository = "https://git.saluco.nl/strix/dotfiles"
|
||||||
|
|
22
crates/ssh/config
Normal file
22
crates/ssh/config
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
## neb servers
|
||||||
|
|
||||||
|
# hydrogen red helix
|
||||||
|
Host H
|
||||||
|
Hostname hydrogen.red.helix.saluco.nl
|
||||||
|
|
||||||
|
# argon red helix
|
||||||
|
Host A
|
||||||
|
Hostname argon.red.helix.saluco.nl
|
||||||
|
|
||||||
|
# iron red sphere
|
||||||
|
Host I
|
||||||
|
Hostname iron.red.sphere.saluco.nl
|
||||||
|
|
||||||
|
## utility servers
|
||||||
|
Host git
|
||||||
|
Hostname git.saluco.nl
|
||||||
|
User git
|
||||||
|
|
||||||
|
Host github
|
||||||
|
Hostname github.com
|
||||||
|
User git
|
11
crates/ssh/crate.toml
Normal file
11
crates/ssh/crate.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[crate]
|
||||||
|
name = "ssh"
|
||||||
|
author = "Strix"
|
||||||
|
description = "fixes the ssh files"
|
||||||
|
|
||||||
|
[[actions.command]]
|
||||||
|
command = "ls -lah"
|
||||||
|
|
||||||
|
[[actions.link]]
|
||||||
|
src = "./config"
|
||||||
|
dest = "~/.ssh/config"
|
187
sync-runner/Cargo.lock
generated
187
sync-runner/Cargo.lock
generated
|
@ -76,6 +76,12 @@ dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.15"
|
version = "1.2.15"
|
||||||
|
@ -167,6 +173,17 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dbus"
|
||||||
|
version = "0.9.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"libdbus-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
@ -177,13 +194,33 @@ dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys 0.3.7",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys",
|
"dirs-sys 0.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -503,6 +540,16 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -515,6 +562,15 @@ version = "0.2.170"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libdbus-sys"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
version = "0.18.0+1.9.0"
|
version = "0.18.0+1.9.0"
|
||||||
|
@ -643,6 +699,15 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
|
@ -683,6 +748,15 @@ version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "resolve-path"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "321e5e41b3b192dab6f1e75b9deacb6688b4b8c5e68906a78e8f43e7c2887bb5"
|
||||||
|
dependencies = [
|
||||||
|
"dirs 4.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.218"
|
version = "1.0.218"
|
||||||
|
@ -729,7 +803,7 @@ version = "3.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b"
|
checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs 5.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -773,6 +847,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"colored",
|
"colored",
|
||||||
|
"dbus",
|
||||||
"execute",
|
"execute",
|
||||||
"fern",
|
"fern",
|
||||||
"git2",
|
"git2",
|
||||||
|
@ -781,10 +856,12 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
|
"resolve-path",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"toml",
|
"toml",
|
||||||
|
"whoami",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -921,6 +998,112 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasite"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
|
||||||
|
dependencies = [
|
||||||
|
"redox_syscall",
|
||||||
|
"wasite",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.29", features = ["derive"] }
|
clap = { version = "4.5.29", features = ["derive"] }
|
||||||
colored = "3.0.0"
|
colored = "3.0.0"
|
||||||
|
dbus = "0.9.7"
|
||||||
execute = "0.2.13"
|
execute = "0.2.13"
|
||||||
fern = "0.7.1"
|
fern = "0.7.1"
|
||||||
git2 = "0.20.0"
|
git2 = "0.20.0"
|
||||||
|
@ -14,7 +15,9 @@ hex = "0.4.3"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
log = "0.4.26"
|
log = "0.4.26"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
resolve-path = "0.1.0"
|
||||||
serde = { version = "1.0.218", features = ["serde_derive"] }
|
serde = { version = "1.0.218", features = ["serde_derive"] }
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
shellexpand = "3.1.0"
|
shellexpand = "3.1.0"
|
||||||
toml = "0.8.20"
|
toml = "0.8.20"
|
||||||
|
whoami = "1.5.2"
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
install(pacman): pacman -Sy %args
|
|
||||||
uninstall(pacman): pacman -Rn %args
|
|
||||||
|
|
||||||
install(apt): apt install %args
|
|
||||||
uninstall(apt): apt remove %args
|
|
||||||
|
|
||||||
install(dnf): dnf install %args
|
|
||||||
uninstall(dnf): dnf remove %args
|
|
||||||
|
|
||||||
install(yum): yum install %args
|
|
||||||
uninstall(yum): yum remove %args
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, fs::read_to_string};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -13,3 +13,9 @@ pub struct Config {
|
||||||
pub daemon: daemon::Daemon,
|
pub daemon: daemon::Daemon,
|
||||||
pub source: HashMap<String, crate::source::Source>
|
pub source: HashMap<String, crate::source::Source>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn parse(path: &str) -> Result<Config, Box<dyn std::error::Error>> {
|
||||||
|
Ok(toml::from_str::<Config>(&read_to_string(path)?)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
89
sync-runner/src/crates/action.rs
Normal file
89
sync-runner/src/crates/action.rs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
use std::{
|
||||||
|
collections::HashMap, fs, process::{Command, Stdio}, time::Duration
|
||||||
|
};
|
||||||
|
|
||||||
|
use dbus::{
|
||||||
|
arg::Variant,
|
||||||
|
blocking::{BlockingSender, Connection},
|
||||||
|
Message,
|
||||||
|
};
|
||||||
|
use log::{debug, error, info, trace};
|
||||||
|
use resolve_path::PathResolveExt;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{tags::Tag};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Actions {
|
||||||
|
/// command actions
|
||||||
|
#[serde(rename = "command")]
|
||||||
|
pub commands: Option<Vec<CommandAction>>,
|
||||||
|
/// link actions
|
||||||
|
#[serde(rename = "link")]
|
||||||
|
pub links: Option<Vec<LinkAction>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CommandAction {
|
||||||
|
#[serde(default = "whoami::username")]
|
||||||
|
user: String,
|
||||||
|
command: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub require: Option<Vec<Tag>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct LinkAction {
|
||||||
|
pub src: String,
|
||||||
|
pub dest: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandAction {
|
||||||
|
pub fn new<S: Into<String>>(command: S, user: S) -> Self {
|
||||||
|
Self {
|
||||||
|
command: command.into(),
|
||||||
|
user: user.into(),
|
||||||
|
description: None,
|
||||||
|
require: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&self) -> Result<i32, Box<dyn std::error::Error>> {
|
||||||
|
trace!("running \"{}\" as {}...", &self.command, &self.user);
|
||||||
|
if self.user != whoami::username() {
|
||||||
|
Ok(Command::new("sudo")
|
||||||
|
.arg("-u")
|
||||||
|
.arg(&self.user)
|
||||||
|
.arg("--")
|
||||||
|
.arg("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(&self.command)
|
||||||
|
.status()?
|
||||||
|
.code()
|
||||||
|
.unwrap_or(1))
|
||||||
|
} else {
|
||||||
|
Ok(Command::new("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(&self.command)
|
||||||
|
.status()?
|
||||||
|
.code()
|
||||||
|
.unwrap_or(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinkAction {
|
||||||
|
pub fn link(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
trace!("linking from {:?} to {:?}...", &self.src.resolve(), &self.dest.resolve());
|
||||||
|
if let Ok(existing) = fs::read_link(&self.dest.resolve()) {
|
||||||
|
if existing == self.src.resolve() {
|
||||||
|
debug!("link OK");
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
return Err("Destination is linked to a different path".into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::os::unix::fs::symlink(&self.src.resolve(), &self.dest.resolve())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
28
sync-runner/src/crates/manifest.rs
Normal file
28
sync-runner/src/crates/manifest.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::{action::Actions, package::Package};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CrateManifest {
|
||||||
|
#[serde(rename = "crate")]
|
||||||
|
pub crate_info: CrateInfo,
|
||||||
|
pub packages: Option<Vec<Package>>,
|
||||||
|
pub actions: Option<Actions>,
|
||||||
|
pub metadata: Option<Metadata>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CrateInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub author: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub homepage: Option<String>,
|
||||||
|
pub repository: Option<String>,
|
||||||
|
pub issues: Option<String>,
|
||||||
|
}
|
|
@ -1,34 +1,62 @@
|
||||||
use std::collections::HashMap;
|
use log::{error, info, warn};
|
||||||
|
use manifest::CrateManifest;
|
||||||
|
use package::PackageManager;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
mod pm;
|
pub mod action;
|
||||||
|
pub mod manifest;
|
||||||
|
pub mod package;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Package {
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Package {
|
|
||||||
pub fn install(&self) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn uninstall(&self) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct CrateAction {
|
|
||||||
pub name: String,
|
|
||||||
pub command: String,
|
|
||||||
pub args: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Crate {
|
pub struct Crate {
|
||||||
pub pkgs: HashMap<String, Package>,
|
pub manifest: CrateManifest,
|
||||||
pub actions: HashMap<String, CrateAction>,
|
}
|
||||||
pub super_actions: HashMap<String, CrateAction>,
|
|
||||||
|
impl Crate {
|
||||||
|
pub fn from_toml_str(string: &str) -> Result<Self, toml::de::Error> {
|
||||||
|
Ok(Crate {
|
||||||
|
manifest: toml::from_str::<manifest::CrateManifest>(string)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install_packages(&self) -> bool {
|
||||||
|
if let Some(packages) = &self.manifest.packages {
|
||||||
|
info!("Installing packages...");
|
||||||
|
let pkgs: Vec<String> = packages
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.get_correct_package_name())
|
||||||
|
.collect();
|
||||||
|
info!(target: "item", "pkgs: {}", pkgs.join(", "));
|
||||||
|
if let Some(pm) = PackageManager::get_available() {
|
||||||
|
pm.install(pkgs).is_ok()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_actions(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if let Some(actions) = &self.manifest.actions {
|
||||||
|
if let Some(commands) = &actions.commands {
|
||||||
|
for command in commands {
|
||||||
|
info!(
|
||||||
|
"Running {}...",
|
||||||
|
&command.description.clone().unwrap_or("action".to_string())
|
||||||
|
);
|
||||||
|
command.run()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(links) = &actions.links {
|
||||||
|
for link in links {
|
||||||
|
info!("Link {} -> {}...", link.src, link.dest);
|
||||||
|
if let Err(e) = link.link() {
|
||||||
|
error!("could not link: {e}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
78
sync-runner/src/crates/package.rs
Normal file
78
sync-runner/src/crates/package.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use std::{collections::HashMap, io};
|
||||||
|
|
||||||
|
use log::{error, info};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::action::CommandAction;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum PackageManager {
|
||||||
|
#[serde(rename = "pacman")]
|
||||||
|
Pacman,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Package {
|
||||||
|
pub name: String,
|
||||||
|
pub distro_name_mapping: Option<HashMap<PackageManager, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PackageManager {
|
||||||
|
pub fn install(&self, packages: Vec<String>) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
|
match &self {
|
||||||
|
PackageManager::Pacman => {
|
||||||
|
CommandAction::new(
|
||||||
|
format!("pacman -S --noconfirm {}", packages.join(" ")),
|
||||||
|
"root".to_string(),
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_available() -> Option<Self> {
|
||||||
|
Self::from_str(match whoami::distro().as_str() {
|
||||||
|
"Manjaro Linux" => "pacman",
|
||||||
|
_ => "unknown"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_str(distro: &str) -> Option<Self> {
|
||||||
|
match distro {
|
||||||
|
"pacman" => Some(PackageManager::Pacman),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Package {
|
||||||
|
pub fn get_correct_package_name(&self) -> String {
|
||||||
|
if let Some(pm) = PackageManager::get_available() {
|
||||||
|
if let Some(mappings) = &self.distro_name_mapping {
|
||||||
|
if let Some(name) = mappings.get(&pm) {
|
||||||
|
name.to_string()
|
||||||
|
} else {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
|
if let Some(pm) = PackageManager::get_available() {
|
||||||
|
pm.install(vec![self.get_correct_package_name()])?;
|
||||||
|
} else {
|
||||||
|
error!("no package manager found...");
|
||||||
|
return Err(Box::new(io::Error::new(
|
||||||
|
io::ErrorKind::NotFound,
|
||||||
|
"package manager not found",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,90 +0,0 @@
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use regex::Regex;
|
|
||||||
use std::{process::Command, str::FromStr};
|
|
||||||
|
|
||||||
const pm_cfg: &str = include_str!("../../package_manager.list");
|
|
||||||
|
|
||||||
/// regex: `(?<pm>[a-z]+)>(?<action>(?:un)?install+): (?<command>.*)`
|
|
||||||
/// example: pacman>install: pacman -Sy %args
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref PM_REGEX: Regex =
|
|
||||||
Regex::new(r"(?P<pm>[a-z]+)>(?P<action>(?:un)?install+): (?P<command>.*)").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct PackageManager {
|
|
||||||
name: String,
|
|
||||||
command: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PackageManager {
|
|
||||||
fn new(name: &str, command: &str, args: Vec<String>) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.to_string(),
|
|
||||||
command: command.to_string(),
|
|
||||||
args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn install(&self, packages: Vec<String>) -> Result<(), Vec<String>> {
|
|
||||||
Command::new(&self.command)
|
|
||||||
.args(&self.args)
|
|
||||||
.args(packages)
|
|
||||||
.spawn()
|
|
||||||
.expect("err");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub fn uninstall(&self, packages: Vec<String>) -> Result<(), Vec<String>> {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl FromStr for PackageManager {
|
|
||||||
type Err = String;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let caps = PM_REGEX.captures(s).ok_or("invalid package manager")?;
|
|
||||||
let name = caps.name("pm").ok_or("invalid package manager")?.as_str();
|
|
||||||
let command = caps
|
|
||||||
.name("command")
|
|
||||||
.ok_or("invalid package manager")?
|
|
||||||
.as_str();
|
|
||||||
let args = caps
|
|
||||||
.name("args")
|
|
||||||
.ok_or("invalid package manager")?
|
|
||||||
.as_str()
|
|
||||||
.split_whitespace()
|
|
||||||
.map(|s| s.to_string())
|
|
||||||
.collect();
|
|
||||||
Ok(Self::new(name, command, args))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Package {
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
impl FromStr for Package {
|
|
||||||
type Err = String;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let caps = PM_REGEX.captures(s).ok_or("invalid package")?;
|
|
||||||
let name = caps.name("name").ok_or("invalid package")?.as_str();
|
|
||||||
Ok(Self::new(name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Package {
|
|
||||||
fn new(name: &str) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn package_managers() -> Vec<PackageManager> {
|
|
||||||
pm_cfg
|
|
||||||
.lines()
|
|
||||||
.map(|s| s.to_string())
|
|
||||||
.map(|s| s.parse::<PackageManager>())
|
|
||||||
.collect::<Result<Vec<PackageManager>, String>>()
|
|
||||||
.expect("invalid package manager")
|
|
||||||
}
|
|
|
@ -19,16 +19,13 @@ mod crates;
|
||||||
mod logging;
|
mod logging;
|
||||||
mod prelude;
|
mod prelude;
|
||||||
mod source;
|
mod source;
|
||||||
|
mod tags;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
logging::setup_logger()?;
|
logging::setup_logger()?;
|
||||||
|
|
||||||
let git_sha1 = String::from_utf8(
|
info!(target: "item", "user: {}", whoami::username());
|
||||||
command_args!("git", "rev-parse", "HEAD")
|
info!(target: "item", "distro: {}", whoami::distro());
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.execute_output()?
|
|
||||||
.stdout,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let action = Action::parse();
|
let action = Action::parse();
|
||||||
match action {
|
match action {
|
||||||
|
@ -38,8 +35,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
trace!("setting config dir as cwd... {config_path}");
|
trace!("setting config dir as cwd... {config_path}");
|
||||||
set_current_dir(config_path)?;
|
set_current_dir(config_path)?;
|
||||||
}
|
}
|
||||||
let config =
|
let config = Config::parse(&abspath("./syncr.toml").unwrap())?;
|
||||||
toml::from_str::<Config>(&read_to_string(abspath("./syncr.toml").unwrap())?)?;
|
|
||||||
info!("syncing \"{}\"...", config.title.bold());
|
info!("syncing \"{}\"...", config.title.bold());
|
||||||
|
|
||||||
info!("updating sources...");
|
info!("updating sources...");
|
||||||
|
@ -63,10 +59,24 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
for source in available_sources {
|
for source in available_sources {
|
||||||
// cd to source dir
|
// cd to source dir
|
||||||
source.go_to_dir()?;
|
source.go_to_dir()?;
|
||||||
for c in source.get_crates()? {
|
for (mut path, c) in source.get_crates()? {
|
||||||
info!("{} pkgs", c.pkgs.len())
|
path.pop();
|
||||||
|
set_current_dir(absolute(path)?)?;
|
||||||
|
info!("Syncing crate: {}...", c.manifest.crate_info.name);
|
||||||
|
|
||||||
|
c.install_packages();
|
||||||
|
|
||||||
|
if let Err(e) = c.run_actions() {
|
||||||
|
error!("action failed: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
set_current_dir(&oldpwd)?; // i hate this but im lazy okay
|
||||||
|
source.go_to_dir()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_current_dir(oldpwd)?;
|
||||||
|
|
||||||
|
info!("Completed sync.");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("{action:#?}");
|
println!("{action:#?}");
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
pub fn abspath(p: &str) -> Option<String> {
|
pub fn abspath(p: &str) -> Option<String> {
|
||||||
let exp_path = shellexpand::full(p).ok()?;
|
let exp_path = shellexpand::full(p).ok()?;
|
||||||
let can_path = std::fs::canonicalize(exp_path.as_ref()).ok()?;
|
let can_path = std::fs::canonicalize(exp_path.as_ref()).ok()?;
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::{
|
use std::{
|
||||||
env::current_dir, fs::{self, create_dir_all, exists}, io::Write, path::{Path, PathBuf}
|
env::current_dir,
|
||||||
|
fs::{self, create_dir_all, exists},
|
||||||
|
io::Write,
|
||||||
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use git2::Repository;
|
use git2::{build::RepoBuilder, Repository};
|
||||||
use log::{debug, info, trace, warn};
|
use log::{debug, info, trace, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256, Sha512};
|
use sha2::{Digest, Sha256, Sha512};
|
||||||
|
@ -30,13 +33,13 @@ impl Git {
|
||||||
|
|
||||||
fn branch_hash(&self) -> String {
|
fn branch_hash(&self) -> String {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(&self.url);
|
hasher.update(&self.branch);
|
||||||
let hash = hasher.finalize();
|
let hash = hasher.finalize();
|
||||||
hex::encode(hash)
|
hex::encode(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repository_path_str(&self) -> String {
|
pub fn repository_path_str(&self) -> String {
|
||||||
format!(".data/git/{}{}", self.url_hash(), self.branch_hash())
|
format!(".data/git/{}.{}", self.url_hash(), self.branch_hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repository_path(&self) -> Result<PathBuf, std::io::Error> {
|
pub fn repository_path(&self) -> Result<PathBuf, std::io::Error> {
|
||||||
|
@ -48,7 +51,9 @@ impl Git {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_repository(&self) -> Result<Repository, git2::Error> {
|
pub fn clone_repository(&self) -> Result<Repository, git2::Error> {
|
||||||
Repository::clone_recurse(&self.url, Path::new(&self.repository_path_str()))
|
RepoBuilder::new()
|
||||||
|
.branch(&self.branch)
|
||||||
|
.clone(&self.url, Path::new(&self.repository_path_str()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repository(&self) -> Result<Repository, git2::Error> {
|
pub fn repository(&self) -> Result<Repository, git2::Error> {
|
||||||
|
@ -61,7 +66,7 @@ impl Git {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn up_to_date(&self) -> Result<bool, Box<dyn std::error::Error>>{
|
fn up_to_date(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
debug!("checking repo up to date...");
|
debug!("checking repo up to date...");
|
||||||
let repo = self.repository()?;
|
let repo = self.repository()?;
|
||||||
let mut remote = repo.find_remote("origin")?;
|
let mut remote = repo.find_remote("origin")?;
|
||||||
|
@ -72,7 +77,6 @@ impl Git {
|
||||||
let fetch_head = repo.refname_to_id(&format!("refs/remotes/origin/{}", self.branch))?;
|
let fetch_head = repo.refname_to_id(&format!("refs/remotes/origin/{}", self.branch))?;
|
||||||
let local_head = repo.refname_to_id(&format!("refs/heads/{}", self.branch))?;
|
let local_head = repo.refname_to_id(&format!("refs/heads/{}", self.branch))?;
|
||||||
|
|
||||||
|
|
||||||
Ok(fetch_head == local_head)
|
Ok(fetch_head == local_head)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use std::{env::{current_dir, set_current_dir}, fs::{create_dir_all, read_to_string}, path::PathBuf};
|
use std::{
|
||||||
|
env::{current_dir, set_current_dir},
|
||||||
|
fs::{create_dir_all, exists, read_to_string},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
use log::{debug, info, trace};
|
use log::{debug, info, trace};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -12,6 +16,7 @@ pub mod git;
|
||||||
pub struct Source {
|
pub struct Source {
|
||||||
interval: u64,
|
interval: u64,
|
||||||
git: Option<git::Git>,
|
git: Option<git::Git>,
|
||||||
|
dir: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Source {
|
impl Default for Source {
|
||||||
|
@ -19,6 +24,7 @@ impl Default for Source {
|
||||||
Source {
|
Source {
|
||||||
interval: 60,
|
interval: 60,
|
||||||
git: None,
|
git: None,
|
||||||
|
dir: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,40 +35,44 @@ impl Source {
|
||||||
trace!("checking git...");
|
trace!("checking git...");
|
||||||
return git.ensure().is_ok();
|
return git.ensure().is_ok();
|
||||||
}
|
}
|
||||||
|
if let Some(dir) = &self.dir {
|
||||||
|
return exists(dir).is_ok();
|
||||||
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn go_to_dir(&self) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn go_to_dir(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if let Some(git) = &self.git {
|
if let Some(git) = &self.git {
|
||||||
if PathBuf::from(git.repository_path_str()) == current_dir()? {
|
if PathBuf::from(git.repository_path_str()) == current_dir()? {
|
||||||
return Ok(())
|
return Ok(());
|
||||||
}
|
}
|
||||||
let dir = git.ensure()?.repository_path()?;
|
let dir = git.ensure()?.repository_path()?;
|
||||||
trace!("setting git dir as cwd... ({}@{}, {})", git.url, git.branch, dir.display());
|
trace!(
|
||||||
|
"setting git dir as cwd... ({}@{}, {})",
|
||||||
|
git.url,
|
||||||
|
git.branch,
|
||||||
|
dir.display()
|
||||||
|
);
|
||||||
set_current_dir(dir)?;
|
set_current_dir(dir)?;
|
||||||
}
|
}
|
||||||
|
if let Some(path) = &self.dir {
|
||||||
|
set_current_dir(path)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_crates(&self) -> Result<Vec<Crate>, Box<dyn std::error::Error>> {
|
pub fn get_crates(&self) -> Result<Vec<(PathBuf, Crate)>, Box<dyn std::error::Error>> {
|
||||||
let mut crates = vec![];
|
let mut crates = vec![];
|
||||||
if let Some(git) = &self.git {
|
|
||||||
trace!("getting crates from git...");
|
|
||||||
debug!("{}", current_dir()?.display());
|
|
||||||
|
|
||||||
// get crates (read dir, crates/*/crate.toml)
|
// get crates (read dir, crates/*/crate.toml)
|
||||||
for crate_file in glob::glob("crates/*/crate.toml").expect("err") {
|
for crate_file in glob::glob("crates/*/crate.toml").expect("err") {
|
||||||
debug!("{crate_file:#?}");
|
|
||||||
match crate_file {
|
match crate_file {
|
||||||
Ok(cd) =>{
|
Ok(cd) => {
|
||||||
debug!("{}", cd.display());
|
debug!("found {}", cd.display());
|
||||||
crates.push(toml::from_str(&read_to_string(cd)?)?)
|
crates.push((cd.clone(), Crate::from_toml_str(&read_to_string(cd)?)?))
|
||||||
},
|
}
|
||||||
_ => continue
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
debug!("{:#?}", crates);
|
|
||||||
Ok(crates)
|
Ok(crates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
71
sync-runner/src/tags.rs
Normal file
71
sync-runner/src/tags.rs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Tag {
|
||||||
|
pub category: String,
|
||||||
|
pub value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Tag {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
// First, deserialize the string
|
||||||
|
let s: String = Deserialize::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
// Split the string into category and value by ":"
|
||||||
|
let parts: Vec<&str> = s.splitn(2, ':').collect();
|
||||||
|
if parts.len() != 2 {
|
||||||
|
return Err(serde::de::Error::invalid_value(
|
||||||
|
serde::de::Unexpected::Str(&s),
|
||||||
|
&"a string in the format 'category:value'",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a Tag with the split parts
|
||||||
|
Ok(Tag {
|
||||||
|
category: parts[0].to_string(),
|
||||||
|
value: parts[1].to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Tag {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&format!("{}:{}", self.category, self.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<String> for Tag {
|
||||||
|
fn into(self) -> String {
|
||||||
|
self.category + " : " + &self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for Tag {
|
||||||
|
type Error = std::io::Error;
|
||||||
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
|
let parts: Vec<&str> = value.split(':').collect();
|
||||||
|
if parts.len() != 2 {
|
||||||
|
Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "could not match string to tag"))
|
||||||
|
} else {
|
||||||
|
Ok(Self {
|
||||||
|
category: parts[0].into(),
|
||||||
|
value: parts[1].into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tag {
|
||||||
|
pub fn distro() -> Tag {
|
||||||
|
Tag {
|
||||||
|
category: "distro".into(),
|
||||||
|
value: whoami::distro()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
sync.sh
7
sync.sh
|
@ -1 +1,6 @@
|
||||||
node sync-runner/index.js
|
if ! [ -f /tmp/sync-runner ]; then
|
||||||
|
curl -O /tmp/sync-runner https://git.saluco.nl/repos/strix/releases/download/latest/sync-runner
|
||||||
|
chmod +x /tmp/sync-runner
|
||||||
|
fi
|
||||||
|
|
||||||
|
/tmp/sync-runner
|
14
syncr.toml
14
syncr.toml
|
@ -7,11 +7,11 @@ title = "strix's syncr config"
|
||||||
# unit = minutes
|
# unit = minutes
|
||||||
interval = 60
|
interval = 60
|
||||||
|
|
||||||
[source.personal.git] # default is the uid
|
[source.personal]
|
||||||
url = "https://git.saluco.nl/strix/dotfiles.git"
|
dir = "."
|
||||||
crate_dir = "./crates" # default
|
|
||||||
cfg_toml = "./syncr.toml" # default
|
|
||||||
|
|
||||||
[source.work.git]
|
# [source.personal.git] # default is the uid
|
||||||
url = "https://git.saluco.nl/dotfiles.git"
|
# url = "https://git.saluco.nl/strix/dotfiles.git"
|
||||||
branch = "work"
|
# branch = "syncr"
|
||||||
|
# crate_dir = "./crates" # default
|
||||||
|
# cfg_toml = "./syncr.toml" # default
|
||||||
|
|
Loading…
Reference in a new issue