| |
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,
|
| + |
})
|
| |
}
|
| |
}
|
| |
|