use crate::github::domain::client::run_gh_json;
use crate::projects::domain::types::*;
pub const ITEM_LIMIT: usize = 500;
pub fn repo_info() -> Result<RepoInfo, String> {
run_gh_json(
&["repo", "view", "--json", "nameWithOwner,owner,projectsV2"],
"gh repo view failed",
)
}
pub fn list_fields(owner: &str, number: u64) -> Result<Vec<ProjectField>, String> {
let list: FieldList = run_gh_json(
&[
"project",
"field-list",
&number.to_string(),
"--owner",
owner,
"--format",
"json",
"--limit",
"100",
],
"gh project field-list failed",
)?;
Ok(list.fields)
}
pub fn list_items(owner: &str, number: u64) -> Result<ItemList, String> {
run_gh_json(
&[
"project",
"item-list",
&number.to_string(),
"--owner",
owner,
"--format",
"json",
"--limit",
&ITEM_LIMIT.to_string(),
],
"gh project item-list failed",
)
}
pub fn fetch_board(owner: &str, number: u64) -> Result<Board, String> {
let fields = list_fields(owner, number)?;
let items = list_items(owner, number)?;
Ok(Board {
number,
fields,
items: items.items,
total_count: items.total_count,
})
}
pub fn is_scope_error(msg: &str) -> bool {
let m = msg.to_lowercase();
m.contains("read:project") || (m.contains("scope") && m.contains("project"))
}
pub fn is_gh_missing(msg: &str) -> bool {
msg.contains("gh not found")
|| msg.contains("gh repo view failed: No such file")
|| msg.contains("os error 2")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scope_errors_are_recognised() {
assert!(is_scope_error(
"error: your authentication token is missing required scopes [project]\nTo request it, run: gh auth refresh -s project"
));
assert!(is_scope_error(
"Your token has not been granted the required scopes to execute this query. The 'projectsV2' field requires one of the following scopes: ['read:project']"
));
assert!(!is_scope_error("gh not found: No such file or directory"));
assert!(!is_scope_error(
"Could not resolve to a ProjectV2 with the number 99."
));
assert!(!is_scope_error("HTTP 404: Not Found"));
}
#[test]
fn missing_cli_is_recognised() {
assert!(is_gh_missing(
"gh not found: No such file or directory (os error 2)"
));
assert!(!is_gh_missing("gh project list failed: exit status 1"));
}
}