shenanigans

This commit is contained in:
2026-06-04 23:21:39 +01:00
parent 395da19f0f
commit 74be11bf42
5 changed files with 186 additions and 176 deletions

View File

@@ -318,8 +318,8 @@ impl query::QueryFn for ListPullRequests {
} }
let query_string = match self.filter { let query_string = match self.filter {
| Some(filter) => format!("is:pr archived:false sort:updated-desc {}", filter), | Some(filter) => format!("is:pr archived:false sort:updated-desc {}", filter),
| None => "is:pr archived:false sort:updated-desc".into(), | None => "is:pr archived:false sort:updated-desc".into(),
}; };
let gql = let gql =
@@ -341,20 +341,20 @@ impl query::QueryFn for ListPullRequests {
.flatten() .flatten()
.filter_map(|edge| { .filter_map(|edge| {
edge.node.and_then(|n| match n { edge.node.and_then(|n| match n {
| PullRequestPaginationQuerySearchEdgesNode::PullRequest(p) => { | PullRequestPaginationQuerySearchEdgesNode::PullRequest(p) => {
Some(PullRequest { Some(PullRequest {
id: p.id.into(), id: p.id.into(),
title: p.title.into(), title: p.title.into(),
state: p.state, state: p.state,
is_draft: p.is_draft, is_draft: p.is_draft,
repo_slug: format!( repo_slug: format!(
"{}/{}", "{}/{}",
p.repository.owner.login, p.repository.name p.repository.owner.login, p.repository.name
) )
.into(), .into(),
}) })
} }
| _ => None, | _ => None,
}) })
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@@ -399,43 +399,43 @@ impl query::QueryFn for FetchPullRequest {
"missing 'node' field on PullRequestQuery response".into(), "missing 'node' field on PullRequestQuery response".into(),
)) ))
.and_then(|n| match n { .and_then(|n| match n {
| PullRequestQueryNode::PullRequest(p) => { | PullRequestQueryNode::PullRequest(p) => {
let created_at = let created_at =
chrono::DateTime::parse_from_rfc3339(&p.created_at).map_err(|err| { chrono::DateTime::parse_from_rfc3339(&p.created_at).map_err(|err| {
api::Error::MalformedResponse(format!( api::Error::MalformedResponse(format!(
"invalid pull request createdAt {:?}: {err}", "invalid pull request createdAt {:?}: {err}",
p.created_at p.created_at
)) ))
})?; })?;
Ok(DetailedPullRequest { Ok(DetailedPullRequest {
id: Id(p.id.into()), id: Id(p.id.into()),
title: p.title.into(), title: p.title.into(),
state: p.state, state: p.state,
is_draft: p.is_draft, is_draft: p.is_draft,
body: p.body.into(), body: p.body.into(),
author: p.author.map(|it| api::user::Actor { author: p.author.map(|it| api::user::Actor {
login: it.login.into(), login: it.login.into(),
avatar_url: it.avatar_url.into(), avatar_url: it.avatar_url.into(),
}), }),
base_repo_slug: p base_repo_slug: p
.base_repository .base_repository
.map(|it| it.name_with_owner.into()) .map(|it| it.name_with_owner.into())
.unwrap_or_default(), .unwrap_or_default(),
base_branch_name: p.base_ref_name.into(), base_branch_name: p.base_ref_name.into(),
base_ref: p.base_ref_oid.into(), base_ref: p.base_ref_oid.into(),
head_repo_slug: p head_repo_slug: p
.head_repository .head_repository
.map(|it| it.name_with_owner.into()) .map(|it| it.name_with_owner.into())
.unwrap_or_default(), .unwrap_or_default(),
head_branch_name: p.head_ref_name.into(), head_branch_name: p.head_ref_name.into(),
head_ref: p.head_ref_oid.into(), head_ref: p.head_ref_oid.into(),
created_at: Some(created_at), created_at: Some(created_at),
}) })
} }
| _ => Err(api::Error::MalformedResponse( | _ => Err(api::Error::MalformedResponse(
"unexpected node type on PullRequestQuery".into(), "unexpected node type on PullRequestQuery".into(),
)), )),
}) })
} }
} }
@@ -477,7 +477,7 @@ impl query::QueryFn for FetchPullRequestFileTree {
let data = { let data = {
let gql = let gql =
PullRequestFileTreeQuery::build_query(pull_request_file_tree_query::Variables { PullRequestFileTreeQuery::build_query(pull_request_file_tree_query::Variables {
id: self.id.clone().into(), id: self.id.to_string(),
first: self.first, first: self.first,
}); });
@@ -494,12 +494,12 @@ impl query::QueryFn for FetchPullRequestFileTree {
"missing 'node' field on PullRequestFileTreeQuery response".into(), "missing 'node' field on PullRequestFileTreeQuery response".into(),
)) ))
.and_then(|node| match node { .and_then(|node| match node {
| pull_request_file_tree_query::PullRequestFileTreeQueryNode::PullRequest( | pull_request_file_tree_query::PullRequestFileTreeQueryNode::PullRequest(
pull_request, pull_request,
) => Ok(pull_request), ) => Ok(pull_request),
| _ => Err(api::Error::MalformedResponse( | _ => Err(api::Error::MalformedResponse(
"unexpected node type on PullRequestFileTreeQuery".into(), "unexpected node type on PullRequestFileTreeQuery".into(),
)), )),
})?; })?;
Ok(pull_request Ok(pull_request
@@ -513,25 +513,23 @@ impl query::QueryFn for FetchPullRequestFileTree {
edge.node.map(|node| ChangedFile { edge.node.map(|node| ChangedFile {
cursor, cursor,
change_type: match node.change_type { change_type: match node.change_type {
| pull_request_file_tree_query::PatchStatus::ADDED => { | pull_request_file_tree_query::PatchStatus::ADDED => ChangeType::Added,
ChangeType::Added | pull_request_file_tree_query::PatchStatus::MODIFIED => {
} ChangeType::Modified
| pull_request_file_tree_query::PatchStatus::MODIFIED => { }
ChangeType::Modified | pull_request_file_tree_query::PatchStatus::DELETED => {
} ChangeType::Deleted
| pull_request_file_tree_query::PatchStatus::DELETED => { }
ChangeType::Deleted | pull_request_file_tree_query::PatchStatus::RENAMED => {
} ChangeType::Renamed
| pull_request_file_tree_query::PatchStatus::RENAMED => { }
ChangeType::Renamed | pull_request_file_tree_query::PatchStatus::COPIED => {
} ChangeType::Copied
| pull_request_file_tree_query::PatchStatus::COPIED => { }
ChangeType::Copied | pull_request_file_tree_query::PatchStatus::CHANGED => {
} ChangeType::Changed
| pull_request_file_tree_query::PatchStatus::CHANGED => { }
ChangeType::Changed | _ => ChangeType::Changed,
}
| _ => ChangeType::Changed,
}, },
additions: node.additions, additions: node.additions,
deletions: node.deletions, deletions: node.deletions,
@@ -578,11 +576,11 @@ impl query::QueryFn for FetchPullRequestTimeline {
TimelineActor { TimelineActor {
kind: match on { kind: match on {
| actorFieldsOn::Bot => "Bot", | actorFieldsOn::Bot => "Bot",
| actorFieldsOn::EnterpriseUserAccount => "EnterpriseUserAccount", | actorFieldsOn::EnterpriseUserAccount => "EnterpriseUserAccount",
| actorFieldsOn::Mannequin => "Mannequin", | actorFieldsOn::Mannequin => "Mannequin",
| actorFieldsOn::Organization => "Organization", | actorFieldsOn::Organization => "Organization",
| actorFieldsOn::User => "User", | actorFieldsOn::User => "User",
} }
.into(), .into(),
name: login, name: login,
@@ -592,62 +590,62 @@ impl query::QueryFn for FetchPullRequestTimeline {
fn normalize_assignee(actor: assigneeFields) -> TimelineActor { fn normalize_assignee(actor: assigneeFields) -> TimelineActor {
match actor { match actor {
| assigneeFields::Bot(actor) => TimelineActor { | assigneeFields::Bot(actor) => TimelineActor {
kind: "Bot".into(), kind: "Bot".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
| assigneeFields::Mannequin(actor) => TimelineActor { | assigneeFields::Mannequin(actor) => TimelineActor {
kind: "Mannequin".into(), kind: "Mannequin".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
| assigneeFields::Organization(actor) => TimelineActor { | assigneeFields::Organization(actor) => TimelineActor {
kind: "Organization".into(), kind: "Organization".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
| assigneeFields::User(actor) => TimelineActor { | assigneeFields::User(actor) => TimelineActor {
kind: "User".into(), kind: "User".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
} }
} }
fn normalize_requested_reviewer(actor: requestedReviewerFields) -> TimelineActor { fn normalize_requested_reviewer(actor: requestedReviewerFields) -> TimelineActor {
match actor { match actor {
| requestedReviewerFields::Bot(actor) => TimelineActor { | requestedReviewerFields::Bot(actor) => TimelineActor {
kind: "Bot".into(), kind: "Bot".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
| requestedReviewerFields::Mannequin(actor) => TimelineActor { | requestedReviewerFields::Mannequin(actor) => TimelineActor {
kind: "Mannequin".into(), kind: "Mannequin".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
| requestedReviewerFields::Team(actor) => TimelineActor { | requestedReviewerFields::Team(actor) => TimelineActor {
kind: "Team".into(), kind: "Team".into(),
name: actor.name, name: actor.name,
avatar_url: None, avatar_url: None,
}, },
| requestedReviewerFields::User(actor) => TimelineActor { | requestedReviewerFields::User(actor) => TimelineActor {
kind: "User".into(), kind: "User".into(),
name: actor.login, name: actor.login,
avatar_url: Some(actor.avatar_url), avatar_url: Some(actor.avatar_url),
}, },
} }
} }
fn normalize_review_state(state: PullRequestReviewState) -> String { fn normalize_review_state(state: PullRequestReviewState) -> String {
match state { match state {
| PullRequestReviewState::PENDING => "PENDING", | PullRequestReviewState::PENDING => "PENDING",
| PullRequestReviewState::COMMENTED => "COMMENTED", | PullRequestReviewState::COMMENTED => "COMMENTED",
| PullRequestReviewState::APPROVED => "APPROVED", | PullRequestReviewState::APPROVED => "APPROVED",
| PullRequestReviewState::CHANGES_REQUESTED => "CHANGES_REQUESTED", | PullRequestReviewState::CHANGES_REQUESTED => "CHANGES_REQUESTED",
| PullRequestReviewState::DISMISSED => "DISMISSED", | PullRequestReviewState::DISMISSED => "DISMISSED",
| _ => "OTHER", | _ => "OTHER",
} }
.into() .into()
} }
@@ -849,9 +847,9 @@ impl query::QueryFn for FetchPullRequestTimeline {
let data = { let data = {
let gql = let gql =
PullRequestTimelineQuery::build_query(pull_request_timeline_query::Variables { PullRequestTimelineQuery::build_query(pull_request_timeline_query::Variables {
id: self.id.clone().into(), id: self.id.to_string(),
first: self.first, first: self.first,
after: self.after.clone(), after: self.after.as_ref().map(|it| it.to_string()),
}); });
let res = c.github_graphql_request(&gql)?.send().await?; let res = c.github_graphql_request(&gql)?.send().await?;
@@ -867,10 +865,10 @@ impl query::QueryFn for FetchPullRequestTimeline {
"missing 'node' field on PullRequestTimelineQuery response".into(), "missing 'node' field on PullRequestTimelineQuery response".into(),
)) ))
.and_then(|node| match node { .and_then(|node| match node {
| PullRequestTimelineQueryNode::PullRequest(pull_request) => Ok(pull_request), | PullRequestTimelineQueryNode::PullRequest(pull_request) => Ok(pull_request),
| _ => Err(api::Error::MalformedResponse( | _ => Err(api::Error::MalformedResponse(
"unexpected node type on PullRequestTimelineQuery".into(), "unexpected node type on PullRequestTimelineQuery".into(),
)), )),
})?; })?;
let timeline = pull_request.timeline_items; let timeline = pull_request.timeline_items;

View File

@@ -81,19 +81,19 @@ fn setup_application(cx: &mut gpui::App) {
let start = resume_application_state(cx); let start = resume_application_state(cx);
match start { match start {
| Start::FromScratch => { | Start::FromScratch => {
let screen = setup_wizard::new(); let screen = setup_wizard::new();
_ = setup_wizard::open_window(screen, cx); _ = setup_wizard::open_window(screen, cx);
} }
| Start::FromSetup(state) => { | Start::FromSetup(state) => {
let screen = setup_wizard::from_saved(state); let screen = setup_wizard::from_saved(state);
_ = setup_wizard::open_window(screen, cx); _ = setup_wizard::open_window(screen, cx);
} }
| Start::FromSaved(_) => { | Start::FromSaved(_) => {
_ = dashboard::open_window(cx); _ = dashboard::open_window(cx);
} }
}; };
} }
@@ -128,11 +128,9 @@ fn resume_application_state(cx: &mut gpui::App) -> Start {
let setup_status = setup_wizard::read_setup_status(); let setup_status = setup_wizard::read_setup_status();
println!("[main] setup status: {:?}", setup_status);
match setup_status { match setup_status {
| setup_wizard::SetupStatus::NotStarted => Start::FromScratch, | setup_wizard::SetupStatus::NotStarted => Start::FromScratch,
| setup_wizard::SetupStatus::InProgress(state) => Start::FromSetup(state), | setup_wizard::SetupStatus::InProgress(state) => Start::FromSetup(state),
| setup_wizard::SetupStatus::Completed => Start::FromSaved(state), | setup_wizard::SetupStatus::Completed => Start::FromSaved(state),
} }
} }

View File

@@ -68,20 +68,20 @@ impl PullRequestChangeView {
) { ) {
let item = &self.file_tree_items[i]; let item = &self.file_tree_items[i];
match item.kind { match item.kind {
| FileTreeItemKind::Directory => { | FileTreeItemKind::Directory => {
self.file_tree_state self.file_tree_state
.toggle_directory(&item.full_path, &self.file_tree_items); .toggle_directory(&item.full_path, &self.file_tree_items);
cx.notify(); cx.notify();
} }
| FileTreeItemKind::File => { | FileTreeItemKind::File => {
self.selected_file_path = Some(Arc::clone(&item.full_path)); self.selected_file_path = Some(Arc::clone(&item.full_path));
self.file_tree_state.highlight_item(i); self.file_tree_state.highlight_item(i);
self.diff_view.update(cx, |diff_view, cx| { self.diff_view.update(cx, |diff_view, cx| {
diff_view.show_diff_for_file(&item.full_path, cx); diff_view.show_diff_for_file(&item.full_path, cx);
}); });
cx.focus_view(&self.diff_view, window); cx.focus_view(&self.diff_view, window);
cx.notify(); cx.notify();
} }
} }
} }
} }
@@ -107,7 +107,6 @@ impl gpui::Render for PullRequestChangeView {
.bg(theme.colors.surface_chrome) .bg(theme.colors.surface_chrome)
.border_r_1() .border_r_1()
.border_color(theme.colors.border_muted) .border_color(theme.colors.border_muted)
.p_1()
.child( .child(
file_tree(self.file_tree_state.clone(), move |i, _, cx| { file_tree(self.file_tree_state.clone(), move |i, _, cx| {
weak.read(cx).file_tree_items[i].clone() weak.read(cx).file_tree_items[i].clone()

View File

@@ -15,6 +15,13 @@ use crate::{
util::diff::{ContentDiff, DiffLine, Op, diff_content}, util::diff::{ContentDiff, DiffLine, Op, diff_content},
}; };
const PR_KWDONOVEM85_API_REPO_BASE: &str = include_str!(
"../../fixtures/github/repo.file_content/kennethnym/novem/5e8745bfcc0c90c226d3c6af84226d6d4a5ec2d1/src/api/repo.rs"
);
const PR_KWDONOVEM85_API_REPO_HEAD: &str = include_str!(
"../../fixtures/github/repo.file_content/kennethnym/novem/13af7d0b48a6ce0b22d48c9b6c1c78dfcd94e6a0/src/api/repo.rs"
);
pub(crate) fn is_enabled() -> bool { pub(crate) fn is_enabled() -> bool {
match std::env::var("NOVEM_DIFFOPS_PLAYGROUND") { match std::env::var("NOVEM_DIFFOPS_PLAYGROUND") {
| Ok(value) => matches!(value.as_str(), "1" | "true" | "TRUE" | "yes" | "on"), | Ok(value) => matches!(value.as_str(), "1" | "true" | "TRUE" | "yes" | "on"),
@@ -361,6 +368,12 @@ fn fetch() {
} }
"#, "#,
), ),
DiffCase::new(
"PR_kwDONovem85 src/api/repo.rs",
"Fixture diff for feat(repo): add cached repository query for titlebar picker. Base 5e8745bfcc0c90c226d3c6af84226d6d4a5ec2d1 to head 13af7d0b48a6ce0b22d48c9b6c1c78dfcd94e6a0.",
PR_KWDONOVEM85_API_REPO_BASE,
PR_KWDONOVEM85_API_REPO_HEAD,
),
] ]
} }

View File

@@ -16,15 +16,15 @@ pub(crate) struct PersistedState {
pub(crate) fn data_dir_path() -> std::path::PathBuf { pub(crate) fn data_dir_path() -> std::path::PathBuf {
match std::env::consts::OS { match std::env::consts::OS {
| "macos" => std::env::home_dir() | "macos" => std::env::home_dir()
.unwrap() .unwrap()
.join("Library") .join("Library")
.join("Application Support") .join("Application Support")
.join("novem"), .join("novem"),
| _ => unimplemented!( | _ => unimplemented!(
"data_dir_path is unimplemented for OS: {}", "data_dir_path is unimplemented for OS: {}",
std::env::consts::OS std::env::consts::OS
), ),
} }
} }
@@ -67,7 +67,9 @@ pub(crate) async fn load_auth_tokens(
.await .await
.ok()? .ok()?
.and_then(|(_, password)| String::from_utf8(password).ok()) .and_then(|(_, password)| String::from_utf8(password).ok())
.map(|access_token| api::AuthTokens { access_token }) .map(|access_token| api::AuthTokens {
access_token: access_token.into(),
})
} }
} }