Radish alpha
r
rad:zwTxygwuz5LDGBq255RA2CbNGrz8
Radicle CI broker
Radicle
Git
refactor: RequestBuilder::build_trigger
Merged liw opened 1 year ago

I want to debug the trigger message creation, and the build_trigger method is long, and hard to follow. So I’ll refactor it to be easier for me to understand.

Signed-off-by: Lars Wirzenius liw@liw.fi

1 file changed +133 -136 96499aa1 1010100c
modified src/msg.rs
@@ -16,7 +16,6 @@ use std::{
    io::{BufRead, BufReader, Read, Write},
};

-
use log::debug;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

@@ -122,11 +121,8 @@ impl<'a> RequestBuilder<'a> {

    /// Create a [`Request::Trigger`] message.
    pub fn build_trigger(self) -> Result<Request, MessageError> {
-
        debug!("build_trigger: called");
        let profile = self.profile.ok_or(MessageError::NoProfile)?;
-
        debug!("build_trigger: got profile");
        let event = self.event.ok_or(MessageError::NoEvent)?;
-
        debug!("build_trigger: got event");

        let (rid, name, oid, old) = match event {
            BrokerEvent::Shutdown => panic!("got shutdown"),
@@ -137,144 +133,149 @@ impl<'a> RequestBuilder<'a> {
                old,
            } => (rid, name, oid, old),
        };
-
        debug!("build_trigger: unpacked event");
-
        let repository = profile.storage.repository(*rid)?;
-
        debug!("build_trigger: got repository");
-
        let storage = &profile.storage;
-
        let repo = radicle_surf::Repository::open(paths::repository(storage, rid))?;
-
        debug!("build_trigger: opened repository");
-
        let repo_project = repository.project()?;
-
        debug!("build_trigger: got project");
-
        let repo_identity = repository.identity()?;
-
        debug!("build_trigger: got identity");
+

+
        let rad_repo = profile.storage.repository(*rid)?;
+
        let git_repo = radicle_surf::Repository::open(paths::repository(&profile.storage, rid))?;
+
        let project_info = rad_repo.project()?;
+
        let msg_repository = Repository {
+
            id: *rid,
+
            name: project_info.name().to_string(),
+
            description: project_info.description().to_string(),
+
            private: !rad_repo.identity()?.visibility.is_public(),
+
            default_branch: project_info.default_branch().to_string(),
+
            delegates: rad_repo.delegates()?.iter().copied().collect(),
+
        };
+

        let author = match extract_author(profile, event) {
            Ok(author) => author,
            Err(err) => {
-
                debug!("build_trigger: author lookup failed: {err}");
                return Err(err);
            }
        };
-
        debug!("build_trigger: got author");
-
        let push_info: Option<PushEvent>;
-
        let patch_info: Option<PatchEvent>;
-
        let event_type: EventType;
-
        debug!("build_trigger: checking if patch or push");
-
        if let Some(parsed_ref) = parse_ref(name) {
-
            match parsed_ref {
-
                ParsedRef::Patch(_oid) => {
-
                    debug!("build_trigger: is patch");
-
                    event_type = EventType::Patch;
-
                    let patch_id = event.patch_id().ok_or(MessageError::Trigger)?;
-
                    let patch = patch::Patches::open(&repository)?
-
                        .get(&patch_id.into())?
-
                        .ok_or(MessageError::Trigger)?;
-
                    push_info = None;
-

-
                    let revs: Vec<Revision> = patch
-
                        .revisions()
-
                        .map(|(rid, r)| {
-
                            Ok::<Revision, MessageError>(Revision {
-
                                id: rid.into(),
-
                                author: did_to_author(profile, r.author().id())?,
-
                                description: r.description().to_string(),
-
                                base: *r.base(),
-
                                oid: r.head(),
-
                                timestamp: r.timestamp().as_secs(),
-
                            })
-
                        })
-
                        .collect::<Result<Vec<Revision>, MessageError>>()?;
-
                    let patch_author_pk = radicle::crypto::PublicKey::from(author.id);
-
                    let patch_latest_revision = patch
-
                        .latest_by(&patch_author_pk)
-
                        .ok_or(MessageError::Trigger)?;
-
                    let patch_head = patch_latest_revision.1.head();
-
                    let patch_base = patch_latest_revision.1.base();
-
                    let patch_commits: Vec<Oid> = repo
-
                        .history(patch_head)?
-
                        .take_while(|c| {
-
                            if let Ok(c) = c {
-
                                c.id != *patch_base
-
                            } else {
-
                                false
-
                            }
-
                        })
-
                        .map(|r| r.map(|c| c.id))
-
                        .collect::<Result<Vec<Oid>, _>>()?;
-
                    let patch_action = if patch.revisions().count() > 1 {
-
                        "updated"
-
                    } else {
-
                        "created"
-
                    };
-
                    patch_info = Some(PatchEvent {
-
                        action: PatchAction::try_from(patch_action)?,
-
                        patch: Patch {
-
                            id: patch_id,
-
                            author,
-
                            title: patch.title().to_string(),
-
                            state: State {
-
                                status: patch.state().to_string(),
-
                                conflicts: match patch.state() {
-
                                    patch::State::Open { conflicts, .. } => conflicts.to_vec(),
-
                                    _ => vec![],
-
                                },
-
                            },
-
                            before: *patch_base,
-
                            after: patch_head,
-
                            commits: patch_commits,
-
                            target: patch.target().head(&repository)?,
-
                            labels: patch.labels().map(|l| l.name().to_string()).collect(),
-
                            assignees: patch.assignees().collect(),
-
                            revisions: revs,
-
                        },
-
                    });
-
                }
-
                ParsedRef::Push(_branch) => {
-
                    debug!("build_trigger: is push");
-
                    event_type = EventType::Push;
-
                    let before_oid: Oid = old.unwrap_or(*oid);
-
                    let push_commits: Vec<Oid> = repo
-
                        .history(oid)?
-
                        .take_while(|c| {
-
                            if let Ok(c) = c {
-
                                c.id != before_oid
-
                            } else {
-
                                false
-
                            }
-
                        })
-
                        .map(|r| r.map(|c| c.id))
-
                        .collect::<Result<Vec<Oid>, _>>()?;
-
                    push_info = Some(PushEvent {
-
                        pusher: author,
-
                        before: before_oid,
-
                        after: *oid,
-
                        branch: push_branch(name),
-
                        commits: push_commits,
-
                    });
-
                    patch_info = None;
-
                }
-
            }
-
            let common = EventCommonFields {
-
                version: PROTOCOL_VERSION,
-
                event_type,
-
                repository: Repository {
-
                    id: *rid,
-
                    name: repo_project.name().to_string(),
-
                    description: repo_project.description().to_string(),
-
                    private: !repo_identity.visibility.is_public(),
-
                    default_branch: repo_project.default_branch().to_string(),
-
                    delegates: repository.delegates()?.iter().copied().collect(),
+

+
        match parse_ref(name) {
+
            None => Err(MessageError::NoEventHandler),
+
            Some(ParsedRef::Patch(_oid)) => Ok(Request::Trigger {
+
                common: EventCommonFields {
+
                    version: PROTOCOL_VERSION,
+
                    event_type: EventType::Patch,
+
                    repository: msg_repository,
+
                },
+
                push: None,
+
                patch: Some(
+
                    self.build_trigger_from_patch(event, rad_repo, &git_repo, profile, author)?,
+
                ),
+
            }),
+
            Some(ParsedRef::Push(_branch)) => Ok(Request::Trigger {
+
                common: EventCommonFields {
+
                    version: PROTOCOL_VERSION,
+
                    event_type: EventType::Push,
+
                    repository: msg_repository,
                },
-
            };
+
                push: Some(self.build_trigger_from_push(
+
                    git_repo,
+
                    author,
+
                    name,
+
                    old.unwrap_or(*oid),
+
                    *oid,
+
                )?),
+
                patch: None,
+
            }),
+
        }
+
    }

-
            debug!("build_trigger: return Ok");
-
            Ok(Request::Trigger {
-
                common,
-
                push: push_info,
-
                patch: patch_info,
+
    fn build_trigger_from_patch(
+
        &self,
+
        event: &BrokerEvent,
+
        repository: radicle::storage::git::Repository,
+
        repo: &radicle_surf::Repository,
+
        profile: &Profile,
+
        author: Author,
+
    ) -> Result<PatchEvent, MessageError> {
+
        let patch_id = event.patch_id().ok_or(MessageError::Trigger)?;
+
        let patch = patch::Patches::open(&repository)?
+
            .get(&patch_id.into())?
+
            .ok_or(MessageError::Trigger)?;
+

+
        let revs: Vec<Revision> = patch
+
            .revisions()
+
            .map(|(rid, r)| {
+
                Ok::<Revision, MessageError>(Revision {
+
                    id: rid.into(),
+
                    author: did_to_author(profile, r.author().id())?,
+
                    description: r.description().to_string(),
+
                    base: *r.base(),
+
                    oid: r.head(),
+
                    timestamp: r.timestamp().as_secs(),
+
                })
            })
+
            .collect::<Result<Vec<Revision>, MessageError>>()?;
+
        let patch_author_pk = radicle::crypto::PublicKey::from(author.id);
+
        let patch_latest_revision = patch
+
            .latest_by(&patch_author_pk)
+
            .ok_or(MessageError::Trigger)?;
+
        let patch_head = patch_latest_revision.1.head();
+
        let patch_base = patch_latest_revision.1.base();
+
        let patch_commits: Vec<Oid> = repo
+
            .history(patch_head)?
+
            .take_while(|c| {
+
                if let Ok(c) = c {
+
                    c.id != *patch_base
+
                } else {
+
                    false
+
                }
+
            })
+
            .map(|r| r.map(|c| c.id))
+
            .collect::<Result<Vec<Oid>, _>>()?;
+
        let action = if patch.revisions().count() > 1 {
+
            PatchAction::Updated
        } else {
-
            Err(MessageError::NoEventHandler)
-
        }
+
            PatchAction::Created
+
        };
+
        Ok(PatchEvent {
+
            action,
+
            patch: Patch {
+
                id: patch_id,
+
                author,
+
                title: patch.title().to_string(),
+
                state: State {
+
                    status: patch.state().to_string(),
+
                    conflicts: match patch.state() {
+
                        patch::State::Open { conflicts, .. } => conflicts.to_vec(),
+
                        _ => vec![],
+
                    },
+
                },
+
                before: *patch_base,
+
                after: patch_head,
+
                commits: patch_commits,
+
                target: patch.target().head(&repository)?,
+
                labels: patch.labels().map(|l| l.name().to_string()).collect(),
+
                assignees: patch.assignees().collect(),
+
                revisions: revs,
+
            },
+
        })
+
    }
+

+
    fn build_trigger_from_push(
+
        &self,
+
        repo: radicle_surf::Repository,
+
        pusher: Author,
+
        branch: &str,
+
        before: Oid,
+
        after: Oid,
+
    ) -> Result<PushEvent, MessageError> {
+
        let push_commits: Vec<Oid> = repo
+
            .history(after)?
+
            .take_while(|c| if let Ok(c) = c { c.id != before } else { false })
+
            .map(|r| r.map(|c| c.id))
+
            .collect::<Result<Vec<Oid>, _>>()?;
+
        Ok(PushEvent {
+
            pusher,
+
            before,
+
            after,
+
            branch: push_branch(branch),
+
            commits: push_commits,
+
        })
    }
}

@@ -368,16 +369,12 @@ fn did_to_author(profile: &Profile, did: &Did) -> Result<Author, MessageError> {
}

fn extract_author(profile: &Profile, event: &BrokerEvent) -> Result<Author, MessageError> {
-
    debug!("extract_author: called");
-
    debug!("extract_author: {event:#?}");
    let nid = match event.nid() {
        Some(nid) => nid,
        None => {
-
            debug!("extract_author: nid lookup failed");
            return Err(MessageError::Trigger);
        }
    };
-
    debug!("extract_author: got nid {nid}");
    did_to_author(profile, &Did::from(nid))
}