///| Git-native Pull Request and Issue system types
///|
/// State of a Pull Request
pub(all) enum PrState {
Open
Merged
Closed
} derive(Eq, Debug)
///|
/// State of an Issue
pub(all) enum IssueState {
Open
Closed
} derive(Eq, Debug)
///|
/// Unified state of an Issue/PullRequest work item
pub(all) enum WorkItemState {
Open
Merged
Closed
} derive(Eq, Debug)
///|
/// Work item kind
pub(all) enum WorkItemKind {
Issue
PullRequest
} derive(Eq, Debug)
///|
pub fn IssueState::to_string(self : IssueState) -> String {
match self {
Open => "open"
Closed => "closed"
}
}
///|
pub impl Show for IssueState with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub fn PrState::to_string(self : PrState) -> String {
match self {
Open => "open"
Merged => "merged"
Closed => "closed"
}
}
///|
pub impl Show for PrState with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub fn WorkItemState::to_string(self : WorkItemState) -> String {
match self {
Open => "open"
Merged => "merged"
Closed => "closed"
}
}
///|
pub impl Show for WorkItemState with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub fn WorkItemKind::to_string(self : WorkItemKind) -> String {
match self {
Issue => "issue"
PullRequest => "pull-request"
}
}
///|
pub impl Show for WorkItemKind with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub fn PrState::to_work_item_state(self : PrState) -> WorkItemState {
match self {
Open => WorkItemState::Open
Merged => WorkItemState::Merged
Closed => WorkItemState::Closed
}
}
///|
pub fn IssueState::to_work_item_state(self : IssueState) -> WorkItemState {
match self {
Open => WorkItemState::Open
Closed => WorkItemState::Closed
}
}
///|
pub fn WorkItemState::to_pr_state(self : WorkItemState) -> PrState {
match self {
Open => PrState::Open
Merged => PrState::Merged
Closed => PrState::Closed
}
}
///|
pub fn WorkItemState::to_issue_state(self : WorkItemState) -> IssueState? {
match self {
Open => Some(IssueState::Open)
Closed => Some(IssueState::Closed)
Merged => None
}
}
///|
/// Pull Request data
pub struct PullRequest {
id : String
title : String
body : String
source_branch : String // refs/heads/feature-x
source_repo : String? // owner/repo of source branch
source_ref : String? // refs/heads/feature-x in source repo
source_commit : @bit.ObjectId
target_branch : String // refs/heads/main
target_commit : @bit.ObjectId
author : String
created_at : Int64
updated_at : Int64
state : PrState
labels : Array[String]
closes_issues : Array[String] // Issues this PR closes
merge_commit : @bit.ObjectId?
}
///|
pub fn PullRequest::new(
id : String,
title : String,
body : String,
source_branch : String,
source_commit : @bit.ObjectId,
target_branch : String,
target_commit : @bit.ObjectId,
author : String,
created_at : Int64,
updated_at : Int64,
state : PrState,
labels : Array[String],
closes_issues? : Array[String] = [],
merge_commit? : @bit.ObjectId? = None,
source_repo? : String? = None,
source_ref? : String? = None,
) -> PullRequest {
{
id,
title,
body,
source_branch,
source_repo,
source_ref,
source_commit,
target_branch,
target_commit,
author,
created_at,
updated_at,
state,
labels,
closes_issues,
merge_commit,
}
}
///|
pub fn PullRequest::id(self : PullRequest) -> String {
self.id
}
///|
pub fn PullRequest::title(self : PullRequest) -> String {
self.title
}
///|
pub fn PullRequest::body(self : PullRequest) -> String {
self.body
}
///|
pub fn PullRequest::source_branch(self : PullRequest) -> String {
self.source_branch
}
///|
pub fn PullRequest::source_repo(self : PullRequest) -> String? {
self.source_repo
}
///|
pub fn PullRequest::source_ref(self : PullRequest) -> String? {
self.source_ref
}
///|
pub fn PullRequest::source_commit(self : PullRequest) -> @bit.ObjectId {
self.source_commit
}
///|
pub fn PullRequest::target_branch(self : PullRequest) -> String {
self.target_branch
}
///|
pub fn PullRequest::target_commit(self : PullRequest) -> @bit.ObjectId {
self.target_commit
}
///|
pub fn PullRequest::author(self : PullRequest) -> String {
self.author
}
///|
pub fn PullRequest::created_at(self : PullRequest) -> Int64 {
self.created_at
}
///|
pub fn PullRequest::updated_at(self : PullRequest) -> Int64 {
self.updated_at
}
///|
pub fn PullRequest::state(self : PullRequest) -> PrState {
self.state
}
///|
pub fn PullRequest::labels(self : PullRequest) -> Array[String] {
self.labels
}
///|
pub fn PullRequest::closes_issues(self : PullRequest) -> Array[String] {
self.closes_issues
}
///|
pub fn PullRequest::merge_commit(self : PullRequest) -> @bit.ObjectId? {
self.merge_commit
}
///|
/// Patch capability of a work item
pub struct WorkItemPatch {
source_branch : String
source_repo : String?
source_ref : String?
source_commit : @bit.ObjectId
target_branch : String
target_commit : @bit.ObjectId
closes_issues : Array[String]
merge_commit : @bit.ObjectId?
}
///|
pub fn WorkItemPatch::new(
source_branch : String,
source_commit : @bit.ObjectId,
target_branch : String,
target_commit : @bit.ObjectId,
closes_issues? : Array[String] = [],
merge_commit? : @bit.ObjectId? = None,
source_repo? : String? = None,
source_ref? : String? = None,
) -> WorkItemPatch {
{
source_branch,
source_repo,
source_ref,
source_commit,
target_branch,
target_commit,
closes_issues,
merge_commit,
}
}
///|
pub fn WorkItemPatch::source_branch(self : WorkItemPatch) -> String {
self.source_branch
}
///|
pub fn WorkItemPatch::source_repo(self : WorkItemPatch) -> String? {
self.source_repo
}
///|
pub fn WorkItemPatch::source_ref(self : WorkItemPatch) -> String? {
self.source_ref
}
///|
pub fn WorkItemPatch::source_commit(self : WorkItemPatch) -> @bit.ObjectId {
self.source_commit
}
///|
pub fn WorkItemPatch::target_branch(self : WorkItemPatch) -> String {
self.target_branch
}
///|
pub fn WorkItemPatch::target_commit(self : WorkItemPatch) -> @bit.ObjectId {
self.target_commit
}
///|
pub fn WorkItemPatch::closes_issues(self : WorkItemPatch) -> Array[String] {
self.closes_issues
}
///|
pub fn WorkItemPatch::merge_commit(self : WorkItemPatch) -> @bit.ObjectId? {
self.merge_commit
}
///|
/// Unified work item view of issue and pull request
pub struct WorkItem {
id : String
title : String
body : String
author : String
created_at : Int64
updated_at : Int64
state : WorkItemState
labels : Array[String]
assignees : Array[String]
linked_prs : Array[String]
linked_issues : Array[String]
patch : WorkItemPatch?
parent_id : String?
blocked_by : Array[String]
blocking : Array[String]
}
///|
pub fn WorkItem::new(
id : String,
title : String,
body : String,
author : String,
created_at : Int64,
updated_at : Int64,
state : WorkItemState,
labels? : Array[String] = [],
assignees? : Array[String] = [],
linked_prs? : Array[String] = [],
linked_issues? : Array[String] = [],
patch? : WorkItemPatch? = None,
parent_id? : String? = None,
blocked_by? : Array[String] = [],
blocking? : Array[String] = [],
) -> WorkItem {
{
id,
title,
body,
author,
created_at,
updated_at,
state,
labels,
assignees,
linked_prs,
linked_issues,
patch,
parent_id,
blocked_by,
blocking,
}
}
///|
pub fn WorkItem::id(self : WorkItem) -> String {
self.id
}
///|
pub fn WorkItem::title(self : WorkItem) -> String {
self.title
}
///|
pub fn WorkItem::body(self : WorkItem) -> String {
self.body
}
///|
pub fn WorkItem::author(self : WorkItem) -> String {
self.author
}
///|
pub fn WorkItem::created_at(self : WorkItem) -> Int64 {
self.created_at
}
///|
pub fn WorkItem::updated_at(self : WorkItem) -> Int64 {
self.updated_at
}
///|
pub fn WorkItem::state(self : WorkItem) -> WorkItemState {
self.state
}
///|
pub fn WorkItem::kind(self : WorkItem) -> WorkItemKind {
match self.patch {
Some(_) => WorkItemKind::PullRequest
None => WorkItemKind::Issue
}
}
///|
pub fn WorkItem::labels(self : WorkItem) -> Array[String] {
self.labels
}
///|
pub fn WorkItem::assignees(self : WorkItem) -> Array[String] {
self.assignees
}
///|
pub fn WorkItem::linked_prs(self : WorkItem) -> Array[String] {
self.linked_prs
}
///|
pub fn WorkItem::linked_issues(self : WorkItem) -> Array[String] {
self.linked_issues
}
///|
pub fn WorkItem::blocked_by(self : WorkItem) -> Array[String] {
self.blocked_by
}
///|
pub fn WorkItem::blocking(self : WorkItem) -> Array[String] {
self.blocking
}
///|
pub fn WorkItem::patch(self : WorkItem) -> WorkItemPatch? {
self.patch
}
///|
pub fn WorkItem::to_pull_request(self : WorkItem) -> PullRequest? {
match self.patch {
None => None
Some(patch) =>
Some(
PullRequest::new(
self.id,
self.title,
self.body,
patch.source_branch,
patch.source_commit,
patch.target_branch,
patch.target_commit,
self.author,
self.created_at,
self.updated_at,
self.state.to_pr_state(),
self.labels,
closes_issues=patch.closes_issues,
merge_commit=patch.merge_commit,
source_repo=patch.source_repo,
source_ref=patch.source_ref,
),
)
}
}
///|
pub fn WorkItem::to_issue(self : WorkItem) -> Issue? {
match self.patch {
Some(_) => None
None =>
match self.state.to_issue_state() {
None => None
Some(issue_state) =>
Some(
Issue::new(
self.id,
self.title,
self.body,
self.author,
self.created_at,
self.updated_at,
issue_state,
labels=self.labels,
assignees=self.assignees,
linked_prs=self.linked_prs,
linked_issues=self.linked_issues,
parent_id=self.parent_id,
blocked_by=self.blocked_by,
blocking=self.blocking,
),
)
}
}
}
///|
pub fn PullRequest::to_work_item(self : PullRequest) -> WorkItem {
let patch = WorkItemPatch::new(
self.source_branch,
self.source_commit,
self.target_branch,
self.target_commit,
closes_issues=self.closes_issues,
merge_commit=self.merge_commit,
source_repo=self.source_repo,
source_ref=self.source_ref,
)
WorkItem::new(
self.id,
self.title,
self.body,
self.author,
self.created_at,
self.updated_at,
self.state.to_work_item_state(),
labels=self.labels,
patch=Some(patch),
)
}
///|
/// Comment on a Pull Request
pub struct PrComment {
id : String
pr_id : String
author : String
body : String
created_at : Int64
reply_to : String? // threading
file_path : String? // file-level comment
line_number : Int? // line-level comment
commit_id : @bit.ObjectId?
}
///|
pub fn PrComment::new(
id : String,
pr_id : String,
author : String,
body : String,
created_at : Int64,
reply_to? : String? = None,
file_path? : String? = None,
line_number? : Int? = None,
commit_id? : @bit.ObjectId? = None,
) -> PrComment {
{
id,
pr_id,
author,
body,
created_at,
reply_to,
file_path,
line_number,
commit_id,
}
}
///|
pub fn PrComment::id(self : PrComment) -> String {
self.id
}
///|
pub fn PrComment::pr_id(self : PrComment) -> String {
self.pr_id
}
///|
pub fn PrComment::author(self : PrComment) -> String {
self.author
}
///|
pub fn PrComment::body(self : PrComment) -> String {
self.body
}
///|
pub fn PrComment::created_at(self : PrComment) -> Int64 {
self.created_at
}
///|
pub fn PrComment::reply_to(self : PrComment) -> String? {
self.reply_to
}
///|
pub fn PrComment::file_path(self : PrComment) -> String? {
self.file_path
}
///|
pub fn PrComment::line_number(self : PrComment) -> Int? {
self.line_number
}
///|
pub fn PrComment::commit_id(self : PrComment) -> @bit.ObjectId? {
self.commit_id
}
///|
/// Review verdict
pub(all) enum ReviewVerdict {
Approved
RequestChanges
Comment
} derive(Eq, Debug)
///|
pub fn ReviewVerdict::to_string(self : ReviewVerdict) -> String {
match self {
Approved => "approved"
RequestChanges => "request-changes"
Comment => "comment"
}
}
///|
pub impl Show for ReviewVerdict with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
/// Review on a Pull Request
pub struct PrReview {
id : String
pr_id : String
author : String
verdict : ReviewVerdict
body : String
created_at : Int64
commit_id : @bit.ObjectId
}
///|
pub fn PrReview::new(
id : String,
pr_id : String,
author : String,
verdict : ReviewVerdict,
body : String,
created_at : Int64,
commit_id : @bit.ObjectId,
) -> PrReview {
{ id, pr_id, author, verdict, body, created_at, commit_id }
}
///|
pub fn PrReview::id(self : PrReview) -> String {
self.id
}
///|
pub fn PrReview::pr_id(self : PrReview) -> String {
self.pr_id
}
///|
pub fn PrReview::author(self : PrReview) -> String {
self.author
}
///|
pub fn PrReview::verdict(self : PrReview) -> ReviewVerdict {
self.verdict
}
///|
pub fn PrReview::body(self : PrReview) -> String {
self.body
}
///|
pub fn PrReview::created_at(self : PrReview) -> Int64 {
self.created_at
}
///|
pub fn PrReview::commit_id(self : PrReview) -> @bit.ObjectId {
self.commit_id
}
///|
/// PR operation error
pub(all) suberror PrError {
NotFound(String)
InvalidFormat(String)
InvalidState(String)
MergeConflict(Array[String])
} derive(Debug, Eq)
///|
/// Issue data
pub struct Issue {
id : String
title : String
body : String
author : String
created_at : Int64
updated_at : Int64
state : IssueState
labels : Array[String]
assignees : Array[String]
linked_prs : Array[String] // Related PRs
linked_issues : Array[String] // Cross-repo issue references
parent_id : String?
blocked_by : Array[String] // Issues that block this one
blocking : Array[String] // Issues this one blocks
}
///|
pub fn Issue::new(
id : String,
title : String,
body : String,
author : String,
created_at : Int64,
updated_at : Int64,
state : IssueState,
labels? : Array[String] = [],
assignees? : Array[String] = [],
linked_prs? : Array[String] = [],
linked_issues? : Array[String] = [],
parent_id? : String? = None,
blocked_by? : Array[String] = [],
blocking? : Array[String] = [],
) -> Issue {
{
id,
title,
body,
author,
created_at,
updated_at,
state,
labels,
assignees,
linked_prs,
linked_issues,
parent_id,
blocked_by,
blocking,
}
}
///|
pub fn Issue::id(self : Issue) -> String {
self.id
}
///|
pub fn Issue::title(self : Issue) -> String {
self.title
}
///|
pub fn Issue::body(self : Issue) -> String {
self.body
}
///|
pub fn Issue::author(self : Issue) -> String {
self.author
}
///|
pub fn Issue::created_at(self : Issue) -> Int64 {
self.created_at
}
///|
pub fn Issue::updated_at(self : Issue) -> Int64 {
self.updated_at
}
///|
pub fn Issue::state(self : Issue) -> IssueState {
self.state
}
///|
pub fn Issue::labels(self : Issue) -> Array[String] {
self.labels
}
///|
pub fn Issue::assignees(self : Issue) -> Array[String] {
self.assignees
}
///|
pub fn Issue::linked_prs(self : Issue) -> Array[String] {
self.linked_prs
}
///|
pub fn Issue::linked_issues(self : Issue) -> Array[String] {
self.linked_issues
}
///|
pub fn Issue::blocked_by(self : Issue) -> Array[String] {
self.blocked_by
}
///|
pub fn Issue::blocking(self : Issue) -> Array[String] {
self.blocking
}
///|
pub fn Issue::to_work_item(self : Issue) -> WorkItem {
WorkItem::new(
self.id,
self.title,
self.body,
self.author,
self.created_at,
self.updated_at,
self.state.to_work_item_state(),
labels=self.labels,
assignees=self.assignees,
linked_prs=self.linked_prs,
linked_issues=self.linked_issues,
parent_id=self.parent_id,
blocked_by=self.blocked_by,
blocking=self.blocking,
)
}
///|
/// Comment on an Issue
pub struct IssueComment {
id : String
issue_id : String
author : String
body : String
created_at : Int64
reply_to : String? // threading
}
///|
pub fn IssueComment::new(
id : String,
issue_id : String,
author : String,
body : String,
created_at : Int64,
reply_to? : String? = None,
) -> IssueComment {
{ id, issue_id, author, body, created_at, reply_to }
}
///|
pub fn IssueComment::id(self : IssueComment) -> String {
self.id
}
///|
pub fn IssueComment::issue_id(self : IssueComment) -> String {
self.issue_id
}
///|
pub fn IssueComment::author(self : IssueComment) -> String {
self.author
}
///|
pub fn IssueComment::body(self : IssueComment) -> String {
self.body
}
///|
pub fn IssueComment::created_at(self : IssueComment) -> Int64 {
self.created_at
}
///|
pub fn IssueComment::reply_to(self : IssueComment) -> String? {
self.reply_to
}
///|
/// Note attached to a commit (Git notes compatible)
pub struct Note {
commit_id : @bit.ObjectId // The commit this note is attached to
body : String
author : String
created_at : Int64
ns : String // e.g., "commits", "review", "tips"
}
///|
pub fn Note::new(
commit_id : @bit.ObjectId,
body : String,
author : String,
created_at : Int64,
ns? : String = "commits",
) -> Note {
{ commit_id, body, author, created_at, ns }
}
///|
pub fn Note::commit_id(self : Note) -> @bit.ObjectId {
self.commit_id
}
///|
pub fn Note::body(self : Note) -> String {
self.body
}
///|
pub fn Note::author(self : Note) -> String {
self.author
}
///|
pub fn Note::created_at(self : Note) -> Int64 {
self.created_at
}
///|
pub fn Note::ns(self : Note) -> String {
self.ns
}