diff --git a/cmd/main.go b/cmd/main.go index a063e51..a62db91 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -16,7 +16,7 @@ import ( func main() { log.Print("started") - env(".env") + env(".dev.env") ctx := context.Background() ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill, syscall.SIGTERM) @@ -36,12 +36,24 @@ func env(envFilePath string) { } func run(ctx context.Context) error { + client := tg.New(os.Getenv("TG_API")) + h := handler.NewHandler( + os.Getenv("GIT_BASE_URL"), + os.Getenv("GIT_TOKEN"), + os.Getenv("CLOUD_BASE_URL"), + os.Getenv("CLOUD_USER"), + os.Getenv("CLOUD_PASS"), + os.Getenv("YT_URL"), + os.Getenv("YT_TOKEN"), + ) + router := tgb.NewRouter(). - Message(handler.NewTicketHandler, tgb.TextHasPrefix("/new")). - Message(handler.PingHandler, tgb.Command("ping")). - Message(handler.NewRepoHandler, tgb.TextHasPrefix("/repo")) + Message(h.NewTicketHandler, tgb.TextHasPrefix("/new")). + Message(h.PingHandler, tgb.Command("ping")). + Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")). + Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")) return tgb.NewPoller( router, diff --git a/controller/controller.go b/controller/controller.go index aabf8bd..0e66f3f 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -2,13 +2,40 @@ package controller import ( "fmt" - "os" "sync" "ticket-pimp/ext" ) -func Workflow(name string) (string, error) { - yt := ext.NewYT(os.Getenv("YT_URL"), os.Getenv("YT_TOKEN")) +type WorkflowController struct { + iGit ext.IGit + iCloud ext.ICloud + iYouTrack ext.IYouTrack +} + +type IWorkflowController interface { + Workflow(name string) (string, error) + CreateRepo(name string, param uint) (string, error) + CreateFolder(name string) (string, string, error) +} + +func NewWorkflowController( + gitBaseURL, + gitToken, + cloudBaseURL, + cloudAuthUser, + cloudAuthPass, + ytBaseURL, + ytToken string, +) *WorkflowController { + return &WorkflowController{ + iGit: ext.NewGit(gitBaseURL, gitToken), + iCloud: ext.NewCloud(cloudBaseURL, cloudAuthUser, cloudAuthPass), + iYouTrack: ext.NewYT(ytBaseURL, ytToken), + } +} + +func (wc *WorkflowController) Workflow(name string) (string, error) { + yt := wc.iYouTrack projects, err := yt.GetProjects() @@ -16,7 +43,7 @@ func Workflow(name string) (string, error) { return "", err } - issue, err := yt.CreateIssue(projects[0].ID, name) + issue, err := yt.CreateIssue(projects[1].ID, name) if err != nil { return "", err @@ -32,17 +59,17 @@ func Workflow(name string) (string, error) { go func() { defer wg.Done() - git, _ = CreateRepo(issue.Key, 0) + git, _ = wc.CreateRepo(issue.Key, 0) }() go func() { defer wg.Done() - gitBuild, _ = CreateRepo(issue.Key+"-build", 1) + gitBuild, _ = wc.CreateRepo(issue.Key+"-build", 1) }() go func() { defer wg.Done() - folder = CreateFolder(issue.Key + " - " + issue.Summary) + _, folder, _ = wc.CreateFolder(issue.Key + " - " + issue.Summary) }() wg.Wait() @@ -52,10 +79,12 @@ func Workflow(name string) (string, error) { return issue.Key, nil } -func CreateRepo(name string, param uint) (string, error) { - gb := ext.NewGit(os.Getenv("GIT_BASE_URL"), os.Getenv("GIT_TOKEN")) - repo, err := gb.NewRepo(name) - gb.AppsAsCollaboratorTo(repo) +func (wc *WorkflowController) CreateRepo(name string, param uint) (string, error) { + //Create git repository with iGit interface; + repo, err := wc.iGit.NewRepo(name) + + //Set 'apps' as collaborator to created repository; + wc.iGit.AppsAsCollaboratorTo(repo) // Result string formatting: if repo != nil { @@ -72,12 +101,13 @@ func CreateRepo(name string, param uint) (string, error) { return "", err } -func CreateFolder(name string) string { - oc := ext.NewCloud(os.Getenv("CLOUD_BASE_URL"), os.Getenv("CLOUD_USER"), os.Getenv("CLOUD_PASS")) +func (wc *WorkflowController) CreateFolder(name string) (string, string, error) { - cloud, _ := oc.CreateFolder(name) - if cloud != nil { - return cloud.FolderPath + //Create ownCloud folder w/ iCloud interface; + cloud, err := wc.iCloud.CreateFolder(name) + if cloud == nil { + return "", "", err } - return "no-folder" + + return cloud.FolderName, cloud.FolderPath, err } diff --git a/ext/cloud.go b/ext/cloud.go index 54d4add..834d817 100644 --- a/ext/cloud.go +++ b/ext/cloud.go @@ -2,27 +2,40 @@ package ext import ( "os" + "ticket-pimp/helpers" "time" ) -func NewCloud(base, user, pass string) *Client { +type Cloud struct { + //[ ] out in separate domain struct + FolderName string + FolderPath string + *Client +} + +type ICloud interface { + CreateFolder(name string) (*Cloud, error) +} + +func NewCloud(base, user, pass string) *Cloud { client := NewClient(). SetTimeout(5*time.Second). SetCommonBasicAuth(user, pass). SetBaseURL(base) - return &Client{ - client, + return &Cloud{ + FolderName: "", + FolderPath: "", + Client: &Client{ + client, + }, } } -type Cloud struct { - FolderName string - FolderPath string -} +func (c *Cloud) CreateFolder(name string) (*Cloud, error) { -func (c *Client) CreateFolder(name string) (*Cloud, error) { + name = helpers.GitNaming(name) cloud := Cloud{ FolderName: name, @@ -36,6 +49,7 @@ func (c *Client) CreateFolder(name string) (*Cloud, error) { if resp.IsSuccessState() { cloud.FolderPath = c.BaseURL + os.Getenv("FOLDER_PATH") + name + } return &cloud, err diff --git a/ext/git.go b/ext/git.go index f6bc9cf..a798ada 100644 --- a/ext/git.go +++ b/ext/git.go @@ -13,6 +13,11 @@ type Git struct { *domain.Git } +type IGit interface { + NewRepo(string) (*domain.Git, error) + AppsAsCollaboratorTo(*domain.Git) (*domain.Git, error) +} + func NewGit(base, token string) *Git { headers := map[string]string{ "Accept": "application/vnd.github+json", @@ -63,7 +68,6 @@ func (gb *Git) NewRepo(name string) (*domain.Git, error) { SetBody(&payload). SetSuccessResult(&git). Post("/user/repos") - //Post("/orgs/apps/repos") if err != nil { log.Print(resp) @@ -72,7 +76,7 @@ func (gb *Git) NewRepo(name string) (*domain.Git, error) { return &git, err } -func (gb *Client) AppsAsCollaboratorTo(git *domain.Git) (*domain.Git, error) { +func (gb *Git) AppsAsCollaboratorTo(git *domain.Git) (*domain.Git, error) { payloadPermission := permissionRequest{ Perm: "admin", } diff --git a/ext/yt.go b/ext/yt.go index 92e89c3..7f54fb9 100644 --- a/ext/yt.go +++ b/ext/yt.go @@ -12,6 +12,12 @@ type youtrack struct { *req.Client } +type IYouTrack interface { + GetProjects() ([]Project, error) + CreateIssue(projectID, name string) (*IssueCreateRequest, error) + UpdateIssue(issue *IssueCreateRequest, folder, git, gitBuild string) (*IssueUpdateRequest, error) +} + func NewYT(base, token string) *youtrack { headers := map[string]string{ "Accept": "application/json", diff --git a/handler/handler.go b/handler/handler.go index ef86364..f134246 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -11,6 +11,73 @@ import ( "github.com/mr-linch/go-tg/tgb" ) +type Handler struct { + workflow controller.IWorkflowController +} + +func NewHandler(gitBaseURL, gitToken, cloudBaseURL, cloudAuthUser, cloudAuthPass, ytBaseURL, ytToken string) *Handler { + return &Handler{ + workflow: controller.NewWorkflowController(gitBaseURL, gitToken, cloudBaseURL, cloudAuthUser, cloudAuthPass, ytBaseURL, ytToken), + } +} + +func (h *Handler) PingHandler(ctx context.Context, mu *tgb.MessageUpdate) error { + return mu.Answer("pong").DoVoid(ctx) +} + +func newRepoAnswer(name string) string { + return tg.HTML.Text( + tg.HTML.Line( + "Repo ", + name, + "has been created!", + ), + ) +} + +func (h *Handler) NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) error { + + str := strings.Replace(mu.Text, "/repo", "", 1) + + if str == "" { + return errors.New("empty command provided") + } + + repoStr, err := h.workflow.CreateRepo(str, 0) + + if err != nil { + return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx) + } + + return mu.Answer(newRepoAnswer(repoStr)).ParseMode(tg.HTML).DoVoid(ctx) +} + +func newFolderAnswer(name string) string { + return tg.HTML.Text( + tg.HTML.Line( + "Folder ", + name, + "has been created!", + ), + ) +} +func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) error { + + str := strings.Replace(mu.Text, "/folder", "", 1) + + if str == "" { + return errors.New("empty command provided") + } + + nameStr, _, err := h.workflow.CreateFolder(str) + + if err != nil { + return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx) + } + + return mu.Answer(newFolderAnswer(nameStr)).ParseMode(tg.HTML).DoVoid(ctx) +} + func errorAnswer(errorMsg string) string { return tg.HTML.Text( tg.HTML.Line( @@ -19,7 +86,7 @@ func errorAnswer(errorMsg string) string { ) } -func NewTicketHandler(ctx context.Context, mu *tgb.MessageUpdate) error { +func (h *Handler) NewTicketHandler(ctx context.Context, mu *tgb.MessageUpdate) error { str := strings.Replace(mu.Text, "/new", "", 1) @@ -27,7 +94,7 @@ func NewTicketHandler(ctx context.Context, mu *tgb.MessageUpdate) error { return errors.New("empty command provided") } - issueKeyStr, err := controller.Workflow(str) + issueKeyStr, err := h.workflow.Workflow(str) if err != nil { return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx) @@ -45,34 +112,3 @@ func newTicketAnswer(name string) string { ), ) } - -func NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) error { - - str := strings.Replace(mu.Text, "/repo", "", 1) - - if str == "" { - return errors.New("empty command provided") - } - - repoStr, err := controller.CreateRepo(str, 0) - - if err != nil { - return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx) - } - - return mu.Answer(newRepoAnswer(repoStr)).ParseMode(tg.HTML).DoVoid(ctx) -} - -func newRepoAnswer(name string) string { - return tg.HTML.Text( - tg.HTML.Line( - "Repo ", - name, - "has been created!", - ), - ) -} - -func PingHandler(ctx context.Context, mu *tgb.MessageUpdate) error { - return mu.Answer("pong").DoVoid(ctx) -}