From 33b9d30858f19d6e7fb9873693ce9c52f4917ff0 Mon Sep 17 00:00:00 2001 From: Joshua Potter Date: Wed, 29 Dec 2021 08:15:19 -0500 Subject: [PATCH] Read in config file or search appropriate places. Add rough README and dependencies along with basic command line arguments. --- .githooks/pre-commit | 13 ++++++++++ Cargo.toml | 9 +++++++ README.md | 41 +++++++++++++++++++++++++++++++ examples/config.yaml | 9 +++++++ flake.nix | 2 ++ src/lib.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 18 ++++++++++++-- 7 files changed, 147 insertions(+), 2 deletions(-) create mode 100755 .githooks/pre-commit create mode 100644 examples/config.yaml create mode 100644 src/lib.rs diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..b5ceec3 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +filesToFormat=$( + git --no-pager diff --name-status --no-color --cached | \ + awk '$1 != "D" && $2 ~ /\.rs/ {print $2}' +) + +for path in $filesToFormat +do + rustfmt $path + git add $path +done; diff --git a/Cargo.toml b/Cargo.toml index 13c8503..97ae528 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,15 @@ [package] name = "homesync" +authors = ["Joshua Potter "] +description = """ + +Homesync provides a way of automatically syncing config files across various\ +applications you may use. +""" version = "0.1.0" edition = "2021" [dependencies] +clap = { version = "3.0.0-rc.9", features = ["derive"] } +notify = "4.0.16" +yaml-rust = "0.4" diff --git a/README.md b/README.md index 28c6dc7..ae19d39 100644 --- a/README.md +++ b/README.md @@ -1 +1,42 @@ # homesync + +**Caution! This is unstable code!** + +## Introduction + +Homesync provides a way of automatically syncing config files across various +applications you may use. It works by establishing a file watcher on all the +configs specified in the primary `homesync` config. As files are changed, they +are copied to a local git repository to eventually be pushed by the user. +Likewise, at any point, the user can sync against the remote repository, +overwriting local configurations for one or more packages. + +## Installation + +TODO + +## Configuration + +Homesync uses a YAML file, to be found in anyone of the following locations. +Locations are searched in the following order: + +• `$XDG_CONFIG_HOME/homesync/homesync.yml` +• `$XDG_CONFIG_HOME/homesync.yml` +• `$HOME/.config/homesync/homesync.yml` +• `$HOME/.homesync.yml` + +That said, it is recommended to modify this config solely from the exposed +homesync CLI. Homesync will take responsibility ensuring how the config is +modified based on your package manager, platform, etc. + +## Usage + +TODO + +## Contribution + +Install git hooks as follows: + +```bash +git config --local core.hooksPath .githooks/ +``` diff --git a/examples/config.yaml b/examples/config.yaml new file mode 100644 index 0000000..ae726c0 --- /dev/null +++ b/examples/config.yaml @@ -0,0 +1,9 @@ +remote: +system: +packages: + homesync: + configs: + - $XDG_CONFIG_HOME/homesync/homesync.yml + - $XDG_CONFIG_HOME/homesync.yml + - $HOME/.config/homesync/homesync.yml + - $HOME/.homesync.yml diff --git a/flake.nix b/flake.nix index 2b1e673..9d8a8fa 100644 --- a/flake.nix +++ b/flake.nix @@ -14,7 +14,9 @@ devShell = with pkgs; mkShell { buildInputs = [ cargo + rls rustc + rustfmt ] ++ lib.optionals stdenv.isDarwin [ libiconv ]; }; }); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..2270557 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,57 @@ +use std::env; +use std::error::Error; +use std::fs; +use std::io; +use std::path::PathBuf; +use yaml_rust::{Yaml, YamlLoader}; + +fn read_config(path: &PathBuf) -> io::Result> { + match fs::read_to_string(path) { + Err(err) => match err.kind() { + // Ignore not found since we may try multiple paths. + io::ErrorKind::NotFound => Ok(None), + _ => Err(err), + }, + Ok(contents) => Ok(Some(contents)), + } +} + +fn find_config() -> Result, Box> { + let mut paths: Vec = Vec::new(); + if let Ok(xdg_config_home) = env::var("XDG_CONFIG_HOME") { + paths.push( + [&xdg_config_home, "homesync", "homesync.yml"] + .iter() + .collect(), + ); + paths.push([&xdg_config_home, "homesync.yml"].iter().collect()); + } + if let Ok(home) = env::var("HOME") { + paths.push( + [&home, ".config", "homesync", "homesync.yml"] + .iter() + .collect(), + ); + paths.push([&home, ".homesync.yml"].iter().collect()); + } + for path in paths { + if let Ok(Some(contents)) = read_config(&path) { + return Ok(YamlLoader::load_from_str(&contents)?); + } + } + Err(Box::new(io::Error::new( + io::ErrorKind::NotFound, + "Could not find a homesync config.", + ))) +} + +pub fn run(config: Option) -> Result<(), Box> { + let _loaded = match config { + Some(path) => { + let contents = fs::read_to_string(path)?; + YamlLoader::load_from_str(&contents)? + } + None => find_config()?, + }; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..cae4882 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,17 @@ -fn main() { - println!("Hello, world!"); +use clap::Parser; +use std::process; + +#[derive(Parser, Debug)] +#[clap(about, version, author)] +struct Args { + #[clap(short, long)] + config: Option, +} + +fn main() { + let args = Args::parse(); + homesync::run(args.config).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); }