Skip to content

Commit

Permalink
Add support for filtering by author (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaishavGandhi authored May 2, 2020
1 parent 3371105 commit 7470e05
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ pub fn build_cli(preferences: &Preferences) -> App {
.short('n')
.long("needs-review")
.help("Show diffs that need your review"),
)
.arg(
Arg::with_name("author")
.short('a')
.long("author")
.required(false)
.takes_value(true)
.help(
"Find diffs with given author name. This is the Phabricator username",
),
),
)
.subcommand(
Expand Down
53 changes: 52 additions & 1 deletion src/diffs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::auth;
use crate::structs::{FabConfig, Revision, RevisionData};
use crate::NO_BORDER_PRESET;
use crate::{auth, users};
use clap::ArgMatches;
use comfy_table::{Attribute, Cell, CellAlignment, ContentArrangement, Table};
use failure::Error;
use serde_json::{Map, Value};
use tokio::runtime::Runtime;

const DIFFERENTIAL_SEARCH_URL: &str = "api/differential.revision.search";
Expand Down Expand Up @@ -32,6 +33,45 @@ pub async fn get_authored_diffs(config: &FabConfig) -> Result<Vec<Revision>, Err
Ok(result)
}

/// Get diffs authored by given author
pub async fn get_diffs(config: &FabConfig, author: &Option<&str>) -> Result<Vec<Revision>, Error> {
if author.is_none() {
return Err(failure::err_msg("No author specified"));
}

let author = author.unwrap();

let user = users::get_user(&author, config).await?;

let url = format!(
"{}{}",
&config.hosted_instance,
DIFFERENTIAL_SEARCH_URL.to_string()
);

let mut map = Map::new();
map.insert(
"api.token".to_string(),
Value::from(config.api_token.clone()),
);
map.insert(
"constraints[authorPHIDs][0]".to_string(),
Value::from(user.phid.clone()),
);

let json_body = Value::Object(map);

let result =
auth::send::<RevisionData>(config, reqwest::Client::new().post(&url).form(&json_body))
.await?
.data
.into_iter()
.filter(|rev| !rev.fields.status.closed)
.collect();

Ok(result)
}

/// Get the diffs that needs review from the user.
pub async fn get_needs_review_diffs(config: &FabConfig) -> Result<Vec<Revision>, Error> {
let json_body = json!({
Expand Down Expand Up @@ -78,6 +118,10 @@ pub fn process_diff_command(_matches: &ArgMatches, config: &FabConfig) -> Result
process_diffs_needs_review(config)?;
return Ok(());
}
if _matches.is_present("author") {
process_authored_diffs(config, _matches.value_of("author"))?;
return Ok(());
}

let result = Runtime::new()?.block_on(get_authored_diffs(config))?;

Expand All @@ -91,3 +135,10 @@ fn process_diffs_needs_review(config: &FabConfig) -> Result<(), Error> {
render_diffs(config, &revisions);
Ok(())
}

fn process_authored_diffs(config: &FabConfig, author: Option<&str>) -> Result<(), Error> {
let revisions = Runtime::new()?.block_on(get_diffs(config, &author))?;

render_diffs(config, &revisions);
Ok(())
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod preferences;
mod structs;
mod summary;
mod tasks;
mod users;

const WHO_AM_I: &str = "api/user.whoami";
/// Preset for comfy-table so that it styles the table for no borders
Expand Down
42 changes: 42 additions & 0 deletions src/users.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::auth;
use crate::structs::FabConfig;
use failure::Error;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};

pub async fn get_user(username: &str, config: &FabConfig) -> Result<User, Error> {
let mut map = Map::new();
map.insert(
"api.token".to_string(),
Value::from(config.api_token.clone()),
);
map.insert(
"constraints[usernames][0]".to_string(),
Value::from(username),
);

let url = format!("{}{}", &config.hosted_instance, "api/user.search");

let json_body = Value::Object(map);

let result =
auth::send::<UserSearchData>(config, reqwest::Client::new().post(&url).form(&json_body))
.await?
.data
.into_iter()
.next()
.unwrap();

Ok(result)
}

#[derive(Deserialize, Serialize, Debug)]
struct UserSearchData {
data: Vec<User>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct User {
pub id: i32,
pub phid: String,
}

0 comments on commit 7470e05

Please sign in to comment.