This also fixes an issue with the taskwarrior filters to not overwrite existing other tasks from other repositories.
175 lines
5.9 KiB
Go
175 lines
5.9 KiB
Go
package gitea
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"gitea.yves-biener.de/yves-biener/gitwarrior/internal/diff"
|
|
"gitea.yves-biener.de/yves-biener/gitwarrior/internal/taskwarrior"
|
|
)
|
|
|
|
type Milestone struct {
|
|
Id uint `json:"id"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
State string `json:"state"`
|
|
Open_issues uint `json:"open_issues"`
|
|
Closed_issues uint `json:"closed_issues"`
|
|
Created_at time.Time `json:"created_at"`
|
|
Updated_at time.Time `json:"updated_at"`
|
|
Due_on time.Time `json:"due_on"`
|
|
Closed_at time.Time `json:"closed_at"`
|
|
}
|
|
|
|
func (milestone *Milestone) IntoTask(repository Repository) (task taskwarrior.Task) {
|
|
task = taskwarrior.NewTask(
|
|
milestone.Title,
|
|
repository.Name,
|
|
milestone.Id,
|
|
taskwarrior.MILESTONE,
|
|
)
|
|
task.Due = taskwarrior.GoTimeToTaskTime(milestone.Due_on)
|
|
task.Entry = taskwarrior.GoTimeToTaskTime(milestone.Created_at)
|
|
task.Modified = taskwarrior.GoTimeToTaskTime(milestone.Updated_at)
|
|
task.AppendComment(0, milestone.Description, milestone.Updated_at)
|
|
return
|
|
}
|
|
|
|
// TODO: implement merge for milestone tasks
|
|
func (milestone *Milestone) MergeTask(task taskwarrior.Task) taskwarrior.Task {
|
|
last_update := taskwarrior.TaskTimeToGoTime(task.Last_gitw_update)
|
|
if milestone.Updated_at.After(last_update) {
|
|
// there are changes we need to merge
|
|
if taskwarrior.TaskTimeToGoTime(task.Modified).After(last_update) {
|
|
// NOTE: this means that there are lacal modifications which are not yet pushed
|
|
if task.Description != milestone.Title {
|
|
task.Description = diff.Prompt(task.Description, milestone.Title, task.Description)
|
|
}
|
|
if task.Status == "completed" || milestone.State == "closed" {
|
|
if !(task.Status == "completed" && milestone.State == "closed" || task.Status != "completed" && milestone.State != "closed") {
|
|
task.Status = diff.Prompt(task.Status, milestone.State, task.Status)
|
|
}
|
|
}
|
|
if len(task.Annotations) < 1 {
|
|
task.AppendComment(0, milestone.Description, milestone.Created_at)
|
|
} else {
|
|
task.Annotations[0].Description = diff.Prompt(task.Annotations[0].Description, milestone.Description, task.Annotations[0].Description)
|
|
task.Annotations[0].Entry = taskwarrior.GoTimeToTaskTime(time.Now().In(time.Local))
|
|
}
|
|
} else {
|
|
// NOTE: there are no modifications between the last received update and the current version, hence we just accept theirs fully
|
|
task.Description = milestone.Title
|
|
if milestone.State == string(CLOSED) {
|
|
// otherwise do not update the value
|
|
task.Status = "completed"
|
|
task.End = taskwarrior.GoTimeToTaskTime(milestone.Closed_at)
|
|
}
|
|
if len(task.Annotations) == 1 {
|
|
task.Annotations[0].Description = milestone.Description
|
|
task.Annotations[0].Entry = taskwarrior.GoTimeToTaskTime(milestone.Updated_at)
|
|
} else {
|
|
task.AppendComment(0, milestone.Description, milestone.Updated_at)
|
|
}
|
|
}
|
|
task.Last_gitw_update = taskwarrior.GoTimeToTaskTime(time.Now().In(time.Local))
|
|
}
|
|
return task
|
|
}
|
|
|
|
func (gitea *Gitea) GetMilestones(repo Repository) ([]Milestone, error) {
|
|
client := &http.Client{}
|
|
url := fmt.Sprintf("%s/repos/%s/milestones?state=all", gitea.Url(), repo.Full_name)
|
|
request, err := http.NewRequest(http.MethodGet, url, nil)
|
|
request.SetBasicAuth(gitea.User_name, gitea.Access_code)
|
|
response, err := client.Do(request)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer response.Body.Close()
|
|
var data []Milestone
|
|
decoder := json.NewDecoder(response.Body)
|
|
if err = decoder.Decode(&data); err != nil {
|
|
return nil, err
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
func (gitea *Gitea) GetMilestone(repo Repository, id uint) (Milestone, error) {
|
|
client := &http.Client{}
|
|
url := fmt.Sprintf("%s/repos/%s/milestones/%d", gitea.Url(), repo.Full_name, id)
|
|
request, err := http.NewRequest(http.MethodGet, url, nil)
|
|
request.SetBasicAuth(gitea.User_name, gitea.Access_code)
|
|
response, err := client.Do(request)
|
|
var milestone Milestone
|
|
if err != nil {
|
|
return milestone, err
|
|
}
|
|
defer response.Body.Close()
|
|
decoder := json.NewDecoder(response.Body)
|
|
if err = decoder.Decode(&milestone); err != nil {
|
|
return milestone, err
|
|
}
|
|
return milestone, nil
|
|
}
|
|
|
|
func (gitea *Gitea) UpdateMilestone(repo Repository, milestone Milestone) error {
|
|
url := fmt.Sprintf("%s/repos/%s/milestones/%d", gitea.Url(), repo.Full_name, milestone.Id)
|
|
payload := make(map[string]interface{})
|
|
payload["description"] = milestone.Description
|
|
payload["due_on"] = milestone.Due_on
|
|
payload["state"] = milestone.State
|
|
payload["title"] = milestone.Title
|
|
json, err := json.Marshal(&payload)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
client := &http.Client{}
|
|
request, err := http.NewRequest(http.MethodPatch, url, bytes.NewBuffer(json))
|
|
request.SetBasicAuth(gitea.User_name, gitea.Access_code)
|
|
request.Header.Set("content-type", "application/json")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
result, err := client.Do(request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer result.Body.Close()
|
|
if result.StatusCode != 200 {
|
|
return errors.New(fmt.Sprintf("\tRequest returned status: %s\n", result.Status))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (gitea *Gitea) NewMilestone(repo Repository, milestone Milestone) (Milestone, error) {
|
|
url := fmt.Sprintf("%s/repos/%s/milestones", gitea.Url(), repo.Full_name)
|
|
payload, err := json.Marshal(&map[string]interface{}{
|
|
"description": milestone.Description,
|
|
"due_on": milestone.Due_on,
|
|
"state": milestone.State,
|
|
"title": milestone.Title,
|
|
})
|
|
var res Milestone
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
client := &http.Client{}
|
|
request, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payload))
|
|
request.SetBasicAuth(gitea.User_name, gitea.Access_code)
|
|
request.Header.Set("content-type", "application/json")
|
|
response, err := client.Do(request)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
defer response.Body.Close()
|
|
decoder := json.NewDecoder(response.Body)
|
|
if err = decoder.Decode(&res); err != nil {
|
|
return res, err
|
|
}
|
|
return res, nil
|
|
}
|