Add first pass of documentation around the library.
parent
4c27331ac0
commit
c1476f3412
|
@ -133,6 +133,12 @@ Refer to `:h backupcopy` for details on how this works.
|
|||
|
||||
## Contribution
|
||||
|
||||
To get started, we recommend reviewing the documentation:
|
||||
|
||||
```bash
|
||||
cargo doc --open
|
||||
```
|
||||
|
||||
Install git hooks as follows:
|
||||
|
||||
```bash
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
//! The in-memory representation of the homesync config. Refer to
|
||||
//! [homesync/template.yml](https://github.com/jrpotter/homesync/blob/main/rsrc/template.yml)
|
||||
//! (copied below) for an example of what this config might look like.
|
||||
//!
|
||||
//! ```yaml
|
||||
//! ---
|
||||
//! user:
|
||||
//! name: name
|
||||
//! email: email@email.com
|
||||
//! ssh:
|
||||
//! public: $HOME/.ssh/id_ed25519.pub
|
||||
//! private: $HOME/.ssh/id_ed25519
|
||||
//! repos:
|
||||
//! local: $HOME/.homesync
|
||||
//! remote:
|
||||
//! name: origin
|
||||
//! branch: master
|
||||
//! url: "https://github.com/owner/repo.git"
|
||||
//! packages:
|
||||
//! homesync:
|
||||
//! - $HOME/.homesync.yml
|
||||
//! - $HOME/.config/homesync/homesync.yml
|
||||
//! - $XDG_CONFIG_HOME/homesync.yml
|
||||
//! - $XDG_CONFIG_HOME/homesync/homesync.yml
|
||||
//! ```
|
||||
|
||||
use super::{path, path::ResPathBuf};
|
||||
use paris::formatter::colorize_string;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
@ -134,6 +160,7 @@ impl PathConfig {
|
|||
// Loading
|
||||
// ========================================
|
||||
|
||||
/// The paths our homesync configuration may live in, ordered by priority.
|
||||
pub const DEFAULT_PATHS: &[&str] = &[
|
||||
"$HOME/.homesync.yml",
|
||||
"$HOME/.config/homesync/homesync.yml",
|
||||
|
@ -141,10 +168,13 @@ pub const DEFAULT_PATHS: &[&str] = &[
|
|||
"$XDG_CONFIG_HOME/homesync/homesync.yml",
|
||||
];
|
||||
|
||||
/// The paths our homesync configuration may live in, ordered by priority.
|
||||
pub fn default_paths() -> Vec<PathBuf> {
|
||||
DEFAULT_PATHS.iter().map(|s| PathBuf::from(s)).collect()
|
||||
}
|
||||
|
||||
/// Reads in the homesync configuration file into a [PathConfig](struct.PathConfig.html)
|
||||
/// instance.
|
||||
pub fn load(candidates: &Vec<ResPathBuf>) -> Result<PathConfig> {
|
||||
// When trying our paths, the only acceptable error is a `NotFound` file.
|
||||
// Anything else should be surfaced to the end user.
|
||||
|
@ -161,6 +191,11 @@ pub fn load(candidates: &Vec<ResPathBuf>) -> Result<PathConfig> {
|
|||
Err(Error::MissingConfig)
|
||||
}
|
||||
|
||||
/// Reads in the homesync configuration file into a [PathConfig](struct.PathConfig.html)
|
||||
/// instance.
|
||||
///
|
||||
/// Useful in cases where we notice the homesync config itself has changed while
|
||||
/// homesync is running.
|
||||
pub fn reload(pc: &PathConfig) -> Result<PathConfig> {
|
||||
info!(
|
||||
"<bold>Reloaded:</> Configuration <cyan>{}</>.",
|
||||
|
@ -173,6 +208,7 @@ pub fn reload(pc: &PathConfig) -> Result<PathConfig> {
|
|||
// Listing
|
||||
// ========================================
|
||||
|
||||
/// Prints the list of packages found in a [PathConfig](struct.PathConfig.html).
|
||||
pub fn list_packages(pc: PathConfig) {
|
||||
println!(
|
||||
"Listing packages in {}...\n",
|
||||
|
|
11
src/copy.rs
11
src/copy.rs
|
@ -1,3 +1,5 @@
|
|||
//! Utilities for traversing directories and copying files around.
|
||||
|
||||
use super::{config::PathConfig, path, path::ResPathBuf};
|
||||
use git2::Repository;
|
||||
use simplelog::{info, paris, warn};
|
||||
|
@ -122,6 +124,13 @@ fn apply_one(pc: &PathConfig, package: &str) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Copy files from the local repository to the corresponding file location on
|
||||
/// the current machine.
|
||||
///
|
||||
/// By default we are required to specify which package we want to apply. If
|
||||
/// we'd like, we can choose to apply all files found in the local repository.
|
||||
/// Warning! You should probably `pull` first to ensure your local repository is
|
||||
/// synced with the remote one, especially if running with `--all`.
|
||||
pub fn apply(pc: &PathConfig, package: Option<&str>) -> Result<()> {
|
||||
if let Some(package) = package {
|
||||
apply_one(pc, package)
|
||||
|
@ -134,6 +143,8 @@ pub fn apply(pc: &PathConfig, package: Option<&str>) -> Result<()> {
|
|||
// Staging
|
||||
// ========================================
|
||||
|
||||
/// Finds all files specified in the homesync config and copies them (if they
|
||||
/// exist) into the local repo.
|
||||
pub fn stage(pc: &PathConfig) -> Result<()> {
|
||||
let workdir = get_workdir(pc)?;
|
||||
let repo_files = walk_repo(workdir.as_ref())?;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
//! Utilites around launching a filewatcher daemon service.
|
||||
//!
|
||||
//! This is intended to be the primary use case of Homesync once stable. The
|
||||
//! daemon is responsible for loading in the homesync config (reloading as it
|
||||
//! changes) and monitoring any files/file paths specified within. On changes,
|
||||
//! it will automatically stage the files to the local repository.
|
||||
|
||||
use super::{config, config::PathConfig, copy, path, path::ResPathBuf};
|
||||
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use simplelog::{error, paris, trace, warn};
|
||||
|
@ -137,6 +144,10 @@ impl<'a> WatchState<'a> {
|
|||
// Daemon
|
||||
// ========================================
|
||||
|
||||
/// Launches a daemon service that monitors changes to files specified in the
|
||||
/// config and stages them for changes in the local repository.
|
||||
///
|
||||
/// Warning! This service is still under development.
|
||||
pub fn launch(mut pc: PathConfig, freq_secs: u64) -> Result<(), Box<dyn Error>> {
|
||||
let (poll_tx, poll_rx) = channel();
|
||||
let (watch_tx, watch_rx) = channel();
|
||||
|
|
17
src/git.rs
17
src/git.rs
|
@ -1,3 +1,7 @@
|
|||
//! Utilities around git
|
||||
//! [plumbing](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain)
|
||||
//! commands.
|
||||
|
||||
use super::{config::PathConfig, path};
|
||||
use git2::{
|
||||
BranchType, Commit, Cred, DiffOptions, Direction, FetchOptions, Index, IndexAddOption,
|
||||
|
@ -83,7 +87,8 @@ fn clone(pc: &PathConfig, expanded: &Path) -> Result<Repository> {
|
|||
// for both ensuring any remote repositories are already managed by homesync and
|
||||
// for storing any persisted configurations.
|
||||
|
||||
/// Sets up a local github repository all configuration files will be synced to.
|
||||
/// Sets up a local git repository all configuration files will be synced to.
|
||||
///
|
||||
/// If there does not exist a local repository at the requested location, we
|
||||
/// attempt to make it via cloning or initializing.
|
||||
pub fn init(pc: &PathConfig) -> Result<Repository> {
|
||||
|
@ -153,6 +158,11 @@ fn create_readme(repo: &Repository) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Take the current state of the local repository and push changes to the
|
||||
/// remote.
|
||||
///
|
||||
/// This method will always pull before pushing to make sure there are no
|
||||
/// conflicts that should be resolved.
|
||||
pub fn push(pc: &PathConfig, repo: &mut Repository) -> Result<()> {
|
||||
// First pull to make sure there are no conflicts when we push our changes.
|
||||
// This will also perform validation and construct our local and remote
|
||||
|
@ -260,6 +270,11 @@ fn local_rebase_remote(pc: &PathConfig, repo: &Repository) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Take the current state of the remote repository and pull changes to the
|
||||
/// local.
|
||||
///
|
||||
/// Using git parlance, this method will stash any changes that currently exist
|
||||
/// and reapply the changes after in case of merge conflicts.
|
||||
pub fn pull(pc: &PathConfig, repo: &mut Repository) -> Result<()> {
|
||||
repo.workdir().ok_or(Error::InvalidBareRepo)?;
|
||||
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -1,3 +1,17 @@
|
|||
//! [homesync](https://github.com/jrpotter/homesync) is a project for collecting
|
||||
//! various files strewn across your computer and consolidating them
|
||||
//! automatically into a local git repository. It has the means of pushing those
|
||||
//! changes to a remote git repository for syncing to other machines. Homesync
|
||||
//! can pull in these changes on a different machine and *apply* the files,
|
||||
//! putting them all in the correct spot.
|
||||
//!
|
||||
//! Throughout this documentation the "local repository" always refers to the
|
||||
//! git repository homesync is managing (and potentially created on start). The
|
||||
//! remote repository refers to the git repo hosted at the URL specified in the
|
||||
//! homesync config.
|
||||
//!
|
||||
//! Thank you for your interest in contributing!
|
||||
|
||||
pub mod config;
|
||||
pub mod copy;
|
||||
pub mod daemon;
|
||||
|
@ -9,33 +23,39 @@ use std::error::Error;
|
|||
|
||||
type Result = std::result::Result<(), Box<dyn Error>>;
|
||||
|
||||
/// Refer to [copy::apply](copy/fn.apply.html).
|
||||
pub fn run_apply(config: PathConfig, package: Option<&str>) -> Result {
|
||||
copy::apply(&config, package)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Refer to [daemon::launch](daemon/fn.launch.html).
|
||||
pub fn run_daemon(config: PathConfig, freq_secs: u64) -> Result {
|
||||
daemon::launch(config, freq_secs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Refer to [config::list_packages](config/fn.list_packages.html).
|
||||
pub fn run_list(config: PathConfig) -> Result {
|
||||
config::list_packages(config);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Refer to [git::push](git/fn.run_push.html).
|
||||
pub fn run_push(config: PathConfig) -> Result {
|
||||
let mut repo = git::init(&config)?;
|
||||
git::push(&config, &mut repo)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Refer to [git::pull](git/fn.run_pull.html).
|
||||
pub fn run_pull(config: PathConfig) -> Result {
|
||||
let mut repo = git::init(&config)?;
|
||||
git::pull(&config, &mut repo)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Refer to [copy::stage](copy/fn.stage.html).
|
||||
pub fn run_stage(config: PathConfig) -> Result {
|
||||
copy::stage(&config)?;
|
||||
Ok(())
|
||||
|
|
|
@ -42,7 +42,7 @@ fn main() {
|
|||
)
|
||||
.subcommand(
|
||||
App::new("apply")
|
||||
.about("Copy files from local repository to rest of desktop")
|
||||
.about("Copy files from local repository to corresponding location")
|
||||
.arg(
|
||||
Arg::new("package")
|
||||
.value_name("PACKAGE")
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Utilities for resolving paths.
|
||||
|
||||
use serde::{
|
||||
de,
|
||||
de::{Unexpected, Visitor},
|
||||
|
@ -54,6 +56,10 @@ impl error::Error for Error {}
|
|||
// Path
|
||||
// ========================================
|
||||
|
||||
/// A "resolved" `PathBuf` that takes in the originally supplied (potentially
|
||||
/// relative) path and annotates it with the absolute path. A `ResPathBuf`
|
||||
/// instance cannot be made if the relative path supplied to it does not refer
|
||||
/// to an actual file.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ResPathBuf {
|
||||
inner: PathBuf,
|
||||
|
|
Loading…
Reference in New Issue