From 398b6a1992aee39377ca6e0478192fdf2e5f7610 Mon Sep 17 00:00:00 2001 From: Yves Biener Date: Tue, 17 Oct 2023 23:15:29 +0200 Subject: [PATCH] add(gitea-api): issues and milestones getters This implements the api getters for extracting the issues and milestones for a given gitea repository. WIP for #1. --- README.md | 12 +++++++- cmd/gitw/main.go | 36 ++++++++++++++++++++++- internal/gitea/gitea.go | 16 ++++++++++ internal/gitea/issue.go | 57 ++++++++++++++++++++++++++++++++++++ internal/gitea/milestone.go | 37 +++++++++++++++++++++++ internal/gitea/repository.go | 17 +++++++++++ internal/gitea/user.go | 27 +++++++++++++++++ 7 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 internal/gitea/gitea.go create mode 100644 internal/gitea/repository.go create mode 100644 internal/gitea/user.go diff --git a/README.md b/README.md index 4162cf7..a5aee9a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ # gitwarrior -Cli tool to sync git issues and milstones with taskwarrior tasks. \ No newline at end of file +Cli tool to sync git issues and milstones with taskwarrior tasks. + +## Building + +This project uses `make` to build. You can run `make` to build the application. You can run `make run` to start the cli after building the application. `make install` will require previledges to install the created binary and documentation to the corresponding places. The variable `INSTALL_PATH` in the [Makefile](Makefile) contains the directory used for the installation of the application. + +## Dependencies + +The goal should be to use to as least as possible external packages. + +- [urfave/cli](https://github.com/urfave/cli): cli building package diff --git a/cmd/gitw/main.go b/cmd/gitw/main.go index 7905807..b9f80a5 100644 --- a/cmd/gitw/main.go +++ b/cmd/gitw/main.go @@ -1,5 +1,39 @@ package main -func main() { +import ( + "fmt" + "os" + "gitea.yves-biener.de/yves-biener/gitwarrior/internal/gitea" +) + +func main() { + repository := gitea.NewRepository("gitwarrior", "yves-biener") + server := gitea.NewGitea("https://gitea.yves-biener.de") + issues, err := server.GetIssues(repository) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + milestones, err := server.GetMilestones(repository) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + + for _, issue := range issues { + fmt.Printf("%#v\n", issue) + } + fmt.Println("---") + for _, issue := range milestones { + fmt.Printf("%#v\n", issue) + } + + // necessary configurations (see config file gitw.json) + // - access code for gitea + // - configuration for taskwarrior settings? + + // cli actions and parameters + // - action: diff (i.e. what has changed between the current state of the taskwarrior tasks and the git issues / milestones) + // - action: status (are there changes between the taskwarrior tasks and the gitea issues / milestones, that would require a sync) + // - action: sync (synch diffs between taskwarrior tasks and gitea issues / milestones) + // - parameter: --dry-run (do only show changes that would be applied but do not apply them) } diff --git a/internal/gitea/gitea.go b/internal/gitea/gitea.go new file mode 100644 index 0000000..5d44c39 --- /dev/null +++ b/internal/gitea/gitea.go @@ -0,0 +1,16 @@ +package gitea + +var API_PATH = "/api/v1" + +type Gitea struct { + base_url string +} + +func NewGitea(base_url string) (gitea Gitea) { + gitea.base_url = base_url + return +} + +func (gitea *Gitea) Url() string { + return gitea.base_url + API_PATH +} diff --git a/internal/gitea/issue.go b/internal/gitea/issue.go index 3ac0cb7..970efb9 100644 --- a/internal/gitea/issue.go +++ b/internal/gitea/issue.go @@ -1 +1,58 @@ package gitea + +import ( + "encoding/json" + "fmt" + "net/http" + "time" +) + +type PullRequest struct { + Merged bool + Merged_at time.Time +} + +type Issue struct { + Id uint + Url string + Html_url string + Number uint + User User + Original_author string + Original_author_id uint + Title string + Body string + Ref string + Assets []string + Labels []string + Milestone Milestone + Assignee User + Assignees []User + State string + Is_locked bool + Comments uint + Created_at time.Time + Updated_at time.Time + Closed_at time.Time + Due_date time.Time + Pull_request PullRequest + Repository Repository + Pin_order uint +} + +func (gitea *Gitea) GetIssues(repo Repository) ([]Issue, error) { + url := fmt.Sprintf("%s/repos/%s/issues?state=all", gitea.Url(), repo.Full_name) + response, err := http.Get(url) + if err != nil { + return nil, err + } + defer response.Body.Close() + var data []Issue + decoder := json.NewDecoder(response.Body) + // NOTE: remove this if I do not want to store everything from the json result in the struct + decoder.DisallowUnknownFields() // remain if every field shall be extracted + if err = decoder.Decode(&data); err != nil { + return nil, err + } + return data, nil +} diff --git a/internal/gitea/milestone.go b/internal/gitea/milestone.go index 3ac0cb7..99bd834 100644 --- a/internal/gitea/milestone.go +++ b/internal/gitea/milestone.go @@ -1 +1,38 @@ package gitea + +import ( + "encoding/json" + "fmt" + "net/http" + "time" +) + +type Milestone struct { + Id uint + Title string + Description string + State string + Open_issues uint + Closed_issues uint + Created_at time.Time + Updated_at time.Time + Due_on time.Time + Closed_at time.Time +} + +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) + if err != nil { + return nil, err + } + defer response.Body.Close() + var data []Milestone + decoder := json.NewDecoder(response.Body) + // NOTE: remove this if I do not want to store everything from the json result in the struct + decoder.DisallowUnknownFields() // remain if every field shall be extracted + if err = decoder.Decode(&data); err != nil { + return nil, err + } + return data, nil +} diff --git a/internal/gitea/repository.go b/internal/gitea/repository.go new file mode 100644 index 0000000..6cd5f68 --- /dev/null +++ b/internal/gitea/repository.go @@ -0,0 +1,17 @@ +package gitea + +import "fmt" + +type Repository struct { + Id uint + Name string + Owner string + Full_name string +} + +func NewRepository(name, owner string) (repo Repository) { + repo.Name = name + repo.Owner = owner + repo.Full_name = fmt.Sprintf("%s/%s", owner, name) + return +} diff --git a/internal/gitea/user.go b/internal/gitea/user.go new file mode 100644 index 0000000..1265ee8 --- /dev/null +++ b/internal/gitea/user.go @@ -0,0 +1,27 @@ +package gitea + +import "time" + +type User struct { + Id uint + Login string + Login_name string + Full_name string + Email string + Avatar_url string + Language string + Is_admin bool + Last_login time.Time + Created time.Time + Restricted bool + Active bool + Prohibit_login bool + Location string + Website string + Description string + Visibility string + Followers_count uint + Following_count uint + Starred_repos_count uint + Username string +}