diff options
| -rw-r--r-- | github-suggestion/src/client.rs | 4 | ||||
| -rw-r--r-- | github-suggestion/src/suggestion.rs | 6 | ||||
| -rw-r--r-- | github-suggestion/src/url.rs | 4 | ||||
| -rw-r--r-- | src/arg.rs | 1 | ||||
| -rw-r--r-- | src/config.rs | 18 | ||||
| -rw-r--r-- | src/error.rs | 1 | ||||
| -rw-r--r-- | src/owner_repo.rs | 9 | ||||
| -rw-r--r-- | src/suggestion.rs | 2 | 
8 files changed, 45 insertions, 0 deletions
| diff --git a/github-suggestion/src/client.rs b/github-suggestion/src/client.rs index c6ae1f1..eb81fbc 100644 --- a/github-suggestion/src/client.rs +++ b/github-suggestion/src/client.rs @@ -5,6 +5,7 @@ use thiserror::Error;  use crate::suggestion::Suggestion; +/// Client and network errors.  #[derive(Debug, Error)]  pub enum Error {      #[error("GitHub client error: {0}")] @@ -15,6 +16,7 @@ pub enum Error {  } +/// A GitHub client wrapper for a specific repository.  pub struct Client<'a> {      client: Github,      owner: &'a str, @@ -22,6 +24,7 @@ pub struct Client<'a> {  }  impl<'a> Client<'a> { +    /// Create a new GitHub client.      pub fn new(          token: &str,          owner: &'a str, repo: &'a str, @@ -34,6 +37,7 @@ impl<'a> Client<'a> {          Ok(Client { client, owner, repo })      } +    /// Fetch a suggestion comment from GitHub by its ID.      pub fn fetch(&self, id: &str) -> Result<Suggestion, Error> {          let response = self.client              .get() diff --git a/github-suggestion/src/suggestion.rs b/github-suggestion/src/suggestion.rs index 2c92e6a..48fcb0c 100644 --- a/github-suggestion/src/suggestion.rs +++ b/github-suggestion/src/suggestion.rs @@ -40,6 +40,7 @@ enum LineEnding {      CrLf,  } +/// A suggestion comment extracted from the GitHub API.  #[derive(Debug, Deserialize)]  pub struct Suggestion {      #[serde(rename = "diff_hunk")] @@ -60,12 +61,14 @@ pub struct Suggestion {  }  impl Suggestion { +    /// Get the suggestion diff for the current repository.      pub fn diff(&self) -> Result<String, Error> {          let repo = Repository::open(".")?;          self.diff_with_repo(&repo)      } +    /// Get the suggestion diff for `repo`.      fn diff_with_repo(&self, repo: &Repository) -> Result<String, Error> {          let commit = repo.find_commit(self.commit.parse()?)?; @@ -104,6 +107,7 @@ impl Suggestion {          )      } +    /// Extract suggestion code from a comment body.      fn suggestion_with_line_ending(          &self,          line_ending: &LineEnding, @@ -120,6 +124,7 @@ impl Suggestion {          Ok(s)      } +    /// Apply the suggestion to the current repository.      pub fn apply(&self) -> Result<(), Error> {          let repo = Repository::open(".")?; @@ -135,6 +140,7 @@ impl Suggestion {          Ok(())      } +    /// Apply the patch in `reader` to `writer`.      fn apply_to<R: BufRead, W: Write>(          &self,          reader: R, diff --git a/github-suggestion/src/url.rs b/github-suggestion/src/url.rs index 60a3d0e..48da7d2 100644 --- a/github-suggestion/src/url.rs +++ b/github-suggestion/src/url.rs @@ -6,6 +6,7 @@ use url;  use url::Url; +/// Errors parsing a suggestion URL.  #[derive(Debug, Error)]  pub enum Error {      #[error("Unable to parse URL")] @@ -21,6 +22,7 @@ pub enum Error {      NoOwnerRepo,  } +/// The important parts of a suggestion comment URL.  #[derive(Debug)]  pub struct SuggestionUrl {      pub owner: String, @@ -28,6 +30,8 @@ pub struct SuggestionUrl {      pub comment_id: String,  } +/// Parses a URL with the format +/// `https://github.com/teddywing/github-suggestion/pull/1#discussion_r459691747`.  impl FromStr for SuggestionUrl {      type Err = Error; @@ -1,6 +1,7 @@  use regex::{self, Regex}; +/// Check if `s` is a numeric ID.  pub fn is_suggestion_id(s: &str) -> Result<bool, regex::Error> {      let re = Regex::new(r"^\d+$")?; diff --git a/src/config.rs b/src/config.rs index e605439..39a8158 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,8 +8,10 @@ use thiserror::Error;  use crate::owner_repo::{self, OwnerRepo}; +/// Program-specific prefix for Git config values.  const GIT_CONFIG_PREFIX: &'static str = "githubSuggestion."; +/// Configuration errors.  #[derive(Debug, Error)]  pub enum Error {      #[error("Unable to parse arguments: {0}")] @@ -28,6 +30,7 @@ pub enum Error {      Git(#[from] git2::Error),  } +/// Configuration extracted from config files and command line arguments.  pub struct Config {      pub github_token: String,      pub o_r: Result<OwnerRepo, owner_repo::Error>, @@ -35,6 +38,8 @@ pub struct Config {  }  impl Config { +    /// Set up command line arguments. Extract configuration values from command +    /// line arguments, Git config, and environment variables.      pub fn get(args: &[String], usage_brief: &str) -> Result<Self, Error> {          let mut opts = Options::new(); @@ -79,6 +84,11 @@ impl Config {          })      } +    /// Get a GitHub token, checking the following places in order: +    /// +    /// 1. Command line argument +    /// 2. Git config +    /// 3. Environment variable      fn github_token(          opt_matches: &getopts::Matches,          git_config: &git2::Config, @@ -101,6 +111,12 @@ impl Config {          }      } +    /// Get the Git remote name from the following places in order: +    /// +    /// 1. Command line argument +    /// 2. Git config +    /// +    /// If the value wasn't set, return `Ok(None)`.      fn remote(          opt_matches: &getopts::Matches,          git_config: &git2::Config, @@ -115,10 +131,12 @@ impl Config {      }  } +/// Print command line usage information to standard output.  fn print_usage(opts: &Options, brief: &str) {      print!("{}", opts.usage(brief));  } +/// Build a Git config key using the program-specific prefix and a subkey.  fn git_config_key(key: &str) -> String {      format!("{}.{}", GIT_CONFIG_PREFIX, key)  } diff --git a/src/error.rs b/src/error.rs index bcca3e1..6b369f0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,6 +9,7 @@ pub enum Error {  } +/// Print to standard error with a program-specific prefix.  #[macro_export]  macro_rules! gseprintln {      ($arg:expr) => ({ diff --git a/src/owner_repo.rs b/src/owner_repo.rs index a94c67f..6098ff0 100644 --- a/src/owner_repo.rs +++ b/src/owner_repo.rs @@ -6,6 +6,7 @@ use url;  use url::Url; +/// Errors getting an `OwnerRepo` from a remote in a Git repository.  #[derive(Debug, Error)]  pub enum Error {      #[error(transparent)] @@ -18,6 +19,7 @@ pub enum Error {      NoRemote(String),  } +/// Errors parsing an `OwnerRepo`.  #[derive(Debug, Error)]  pub enum OwnerRepoError {      #[error("Unable to parse URL")] @@ -37,6 +39,9 @@ pub struct OwnerRepo {      pub repo: String,  } +/// Parse an owner-repo pair from a Git remote. Can be either an HTTP URL +/// (`https://github.com/teddywing/github-suggestion.git`) or an SSH-style +/// reference (`git@github.com:teddywing/github-suggestion.git`).  impl FromStr for OwnerRepo {      type Err = OwnerRepoError; @@ -63,6 +68,8 @@ impl FromStr for OwnerRepo {  }  impl OwnerRepo { +    /// Parse an `OwnerRepo` from the URL for `remote_name` in the current +    /// repository.      pub fn from_remote(          remote_name: Option<&str>,      ) -> Result<OwnerRepo, Error> { @@ -80,6 +87,8 @@ impl OwnerRepo {          Ok(url.parse()?)      } +    /// Parse an `OwnerRepo` from an SSH-style reference +    /// (`git@github.com:teddywing/github-suggestion.git`).      pub fn from_ssh(ssh: &str) -> Result<Self, OwnerRepoError> {          let address_path: Vec<_> = ssh.splitn(2, ':').collect();          let path = address_path.get(1) diff --git a/src/suggestion.rs b/src/suggestion.rs index fc22a7c..9f23a0d 100644 --- a/src/suggestion.rs +++ b/src/suggestion.rs @@ -9,6 +9,8 @@ use crate::arg::is_suggestion_id;  use crate::config::Config; +/// For all suggestions in `config.suggestions`, fetch the suggestion from the +/// API and call `f` with it.  pub fn for_suggestion<F>(config: &Config, f: F)  where F: Fn(&Suggestion)  { | 
