add(taskwarrior): pull implementation for new tasks

This implements the pull functionality for new tasks, which are not yet
in the local taskwarrior instance created. WIP for #3.
This commit is contained in:
2023-10-21 12:43:41 +02:00
parent 3ed3c53854
commit ba9683f290
5 changed files with 113 additions and 14 deletions

View File

@@ -23,11 +23,11 @@ func main() {
}
project := gitw.NewProject(server, repository)
if err = project.Fetch(); err != nil {
fmt.Printf("Pulling changes from %s\n", repository.Full_name)
if err = project.Pull(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(-1)
}
fmt.Printf("%#v\n", project)
// NOTE: this can be used to add / modify tasks
// var update_tasks []taskwarrior.Task

View File

@@ -13,6 +13,11 @@ type PullRequest struct {
Merged_at time.Time `json:"merged_at"`
}
type IssueState string
const CLOSED IssueState = "closed"
const OPEN IssueState = "open"
type Issue struct {
Id uint `json:"id"`
Url string `json:"url"`
@@ -104,7 +109,7 @@ func (gitea *Gitea) NewIssue(repo Repository, issue Issue) (Issue, error) {
payload["assignee"] = issue.Assignee
payload["assignees"] = issue.Assignees
payload["body"] = issue.Body
payload["closed"] = issue.State == "closed"
payload["closed"] = issue.State == string(CLOSED)
payload["due_date"] = issue.Due_date
payload["lables"] = issue.Labels
payload["milestone"] = issue.Milestone.Title != ""

View File

@@ -6,6 +6,8 @@ import (
"fmt"
"net/http"
"time"
"gitea.yves-biener.de/yves-biener/gitwarrior/internal/taskwarrior"
)
type Milestone struct {
@@ -21,6 +23,11 @@ type Milestone struct {
Closed_at time.Time `json:"closed_at"`
}
// TODO: implement merge for milestone tasks
func (milestone *Milestone) Merge(task taskwarrior.Task) taskwarrior.Task {
return task
}
func (gitea *Gitea) GetMilestones(repo Repository) ([]Milestone, error) {
url := fmt.Sprintf("%s/repos/%s/milestones?state=all", gitea.Url(), repo.Full_name)
response, err := http.Get(url)

View File

@@ -2,6 +2,7 @@ package gitw
import (
"errors"
"fmt"
"gitea.yves-biener.de/yves-biener/gitwarrior/internal/gitea"
"gitea.yves-biener.de/yves-biener/gitwarrior/internal/taskwarrior"
@@ -52,38 +53,115 @@ func (project *Project) Fetch() error {
}
}
project.issues = append(project.issues, Issue{
issue: issue,
comments: issue_comments,
git_issue: issue,
comments: issue_comments,
})
}
return nil
}
// TODO: tasks should include the corresponding time's of the git related issues and milestones
func (project *Project) merge() error {
// TODO: run merge to update the local taskwarrior tasks into the state of the
// issues and milestones
var tasks []taskwarrior.Task
var filter taskwarrior.Filter
// TODO: merge milestones
for _, milestone := range project.milestones {
filter.Reset()
filter.IncludeGitId(milestone.Id)
filter.IncludeGitType(taskwarrior.MILESTONE)
git_tasks, err := taskwarrior.GetTasks(filter)
if err != nil {
return err
}
var task taskwarrior.Task
if len(git_tasks) > 1 {
return errors.New("Git milestone id was at least used twice in taskwarrior tasks.")
} else if len(git_tasks) == 0 {
// NOTE: ignore closed milestones which do not have a taskwarrior task
if milestone.State == string(gitea.CLOSED) {
continue
}
// NOTE: this milestone does not yet exist
task = taskwarrior.NewTask(
milestone.Title,
project.repository.Name,
milestone.Id,
taskwarrior.MILESTONE,
)
task.AppendComment(milestone.Description, milestone.Updated_at)
fmt.Printf("\tCreated milestone: '%s'\n", task.Description)
tasks = append(tasks, task)
} else {
// NOTE: there is exactly one git_task
task = milestone.Merge(git_tasks[0])
fmt.Printf("\tUpdated milestone: '%s'\n", task.Description)
tasks = append(tasks, task)
}
}
// NOTE: merge tasks
// TODO: link milestones into tasks
for _, issue := range project.issues {
filter.Reset()
filter.IncludeGitId(issue.git_issue.Id)
filter.IncludeGitType(taskwarrior.ISSUE)
git_tasks, err := taskwarrior.GetTasks(filter)
if err != nil {
return err
}
var task taskwarrior.Task
if len(git_tasks) > 1 {
return errors.New("Git issue id was at least used twice in taskwarrior tasks.")
} else if len(git_tasks) == 0 {
// NOTE: ignore closed issues which do not have a taskwarrior task
if issue.git_issue.State == string(gitea.CLOSED) {
continue
}
// NOTE: this task does not yet exist
task = taskwarrior.NewTask(
issue.git_issue.Title,
project.repository.Name,
issue.git_issue.Id,
taskwarrior.ISSUE,
issue.git_issue.Labels...,
)
for _, comment := range issue.comments {
task.AppendComment(comment.Body, comment.Updated_at)
}
fmt.Printf("\tCreated task: '%s'\n", task.Description)
tasks = append(tasks, task)
} else {
// NOTE: there is excactly one git_task
task = issue.merge(git_tasks[0])
fmt.Printf("\tUpdated task: '%s'\n", task.Description)
tasks = append(tasks, task)
}
}
// TODO: dry-run switch
if false {
return taskwarrior.UpdateTasks(tasks)
}
return nil
}
type Issue struct {
issue gitea.Issue
comments []gitea.Comment
git_issue gitea.Issue
comments []gitea.Comment
}
func (i *Issue) into() (taskwarrior.Task, error) {
// TODO: identify if issue is already an existing task
var filter taskwarrior.Filter
filter.IncludeGitId(i.issue.Id)
filter.IncludeGitId(i.git_issue.Id)
filter.IncludeGitType(taskwarrior.ISSUE)
tasks, err := taskwarrior.GetTasks(filter)
if err != nil {
// this means that a task for this issue does not exist yet
return taskwarrior.NewTask(
i.issue.Title,
i.issue.Repository.Name,
i.issue.Id,
i.git_issue.Title,
i.git_issue.Repository.Name,
i.git_issue.Id,
taskwarrior.ISSUE,
i.issue.Labels...,
i.git_issue.Labels...,
), nil
} else {
// this means that a task exists and it needs to be merged
@@ -94,6 +172,7 @@ func (i *Issue) into() (taskwarrior.Task, error) {
}
}
// TODO: implement merging of git issue or milestone into a taskwarrior task
func (i *Issue) merge(task taskwarrior.Task) taskwarrior.Task {
// TODO: issue values into task:
// - is the issue more recent than the task?

View File

@@ -35,6 +35,14 @@ type Annotation struct {
Entry string `json:"entry,omitempty"`
}
func (task *Task) AppendComment(description string, time time.Time) {
annotation := Annotation{
Description: description,
Entry: GoTimeToTaskTime(time),
}
task.Annotations = append(task.Annotations, annotation)
}
func NewTask(description string, project string, git_id uint, git_type Type, tags ...string) Task {
// TODO: update task struct to include the new user defined value, which shall
// also be provided as an argument