Read in config file or search appropriate places.

Add rough README and dependencies along with basic command line
arguments.
pull/3/head
Joshua Potter 2021-12-29 08:15:19 -05:00
parent fff5d4183f
commit 33b9d30858
7 changed files with 147 additions and 2 deletions

13
.githooks/pre-commit Executable file
View File

@ -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;

View File

@ -1,6 +1,15 @@
[package]
name = "homesync"
authors = ["Joshua Potter <jrpotter.github.io>"]
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"

View File

@ -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/
```

9
examples/config.yaml Normal file
View File

@ -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

View File

@ -14,7 +14,9 @@
devShell = with pkgs; mkShell {
buildInputs = [
cargo
rls
rustc
rustfmt
] ++ lib.optionals stdenv.isDarwin [ libiconv ];
};
});

57
src/lib.rs Normal file
View File

@ -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<Option<String>> {
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<Vec<Yaml>, Box<dyn Error>> {
let mut paths: Vec<PathBuf> = 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<String>) -> Result<(), Box<dyn Error>> {
let _loaded = match config {
Some(path) => {
let contents = fs::read_to_string(path)?;
YamlLoader::load_from_str(&contents)?
}
None => find_config()?,
};
Ok(())
}

View File

@ -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<String>,
}
fn main() {
let args = Args::parse();
homesync::run(args.config).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {}", err);
process::exit(1);
});
}