summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <g.giovanini@gridx.de>2023-04-27 11:29:53 +0200
committerGabriel A. Giovanini <g.giovanini@gridx.de>2023-11-07 11:33:04 +0100
commit4246ea81d56c93c1df2954e34cc33fb6e6524f49 (patch)
treef6ce5b4a65648a10897029777f79916f1803ddfd
downloadworkctl-4246ea81d56c93c1df2954e34cc33fb6e6524f49.tar.gz
workctl-4246ea81d56c93c1df2954e34cc33fb6e6524f49.tar.bz2
workctl-4246ea81d56c93c1df2954e34cc33fb6e6524f49.zip
feat: Initial commitHEADmaster
-rw-r--r--.gitignore1
-rw-r--r--Makefile19
-rw-r--r--go.mod11
-rw-r--r--go.sum8
-rw-r--r--main.go169
-rw-r--r--main_test.go127
6 files changed, 335 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e660fd9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+bin/
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..07d33df
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+PREFIX?=/usr/local
+OUTPUT?=bin/workctl
+
+all: build
+
+install: build
+ install -m755 $(OUTPUT) $(PREFIX)/bin/workctl
+
+build:
+ go build -v -o $(OUTPUT) .
+
+test:
+ go test -v ./...
+
+run:
+ go run -v .
+
+tiny:
+ tinygo build .
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..6729bc6
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,11 @@
+module git.sr.ht/~gabrielgio/workctl
+
+go 1.20
+
+require github.com/urfave/cli/v2 v2.25.1
+
+require (
+ github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..f003bf9
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,8 @@
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw=
+github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..cd143db
--- /dev/null
+++ b/main.go
@@ -0,0 +1,169 @@
+package main
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "regexp"
+)
+
+const (
+ prLinkRegex = `https://github.com/.+/.+/(pull|issues)/[0-9]*`
+ version = "0.0.1"
+)
+
+var (
+ prRegex = regexp.MustCompile(prLinkRegex)
+)
+
+func extractPRLink(text string) string {
+ return prRegex.FindString(text)
+}
+
+func getLinkFromSTDIn() (string, error) {
+ in, err := io.ReadAll(os.Stdin)
+ if err != nil {
+ return "", err
+ }
+
+ if err != nil {
+ return "", err
+ }
+
+ prLink := extractPRLink(string(in))
+ if prLink == "" {
+ return "", fmt.Errorf("Unable to find link")
+ }
+
+ return prLink, nil
+}
+
+func pipeTo(app string, args ...string) error {
+ prLink, err := getLinkFromSTDIn()
+ if err != nil {
+ return err
+ }
+
+ args = append(args, prLink)
+
+ _, err = execCommand(app, args...)
+ return err
+}
+
+func execCommand(app string, args ...string) (string, error) {
+ cmd := exec.Command(app, args...)
+ stdout, err := cmd.Output()
+
+ if err != nil {
+ return "", err
+ }
+
+ return string(stdout), nil
+}
+
+func shellIn(app string, args ...string) error {
+ cmd := exec.Command(app, args...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+
+ return cmd.Run()
+}
+
+func merge() error {
+ return pipeTo("gh", "pr", "merge", "--merge")
+}
+
+func approve() error {
+ return pipeTo("gh", "pr", "review", "--approve")
+}
+
+func dependabot() error {
+ return pipeTo("gh", "pr", "comment", "--body", "@dependabot rebase\n@dependabot merge")
+}
+
+func open() error {
+ return pipeTo("qutebrowser", "-l", "critical")
+}
+
+func edit() error {
+ file, err := os.CreateTemp("", "workctl")
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ defer os.Remove(file.Name())
+
+ prLink, err := getLinkFromSTDIn()
+ if err != nil {
+ return err
+ }
+
+ out, err := execCommand("gh", "pr", "diff", "--patch", prLink)
+ if err != nil {
+ return err
+ }
+
+ _, err = file.WriteString(out)
+ if err != nil {
+ return err
+ }
+
+ return shellIn("nvim", "-c", "setlocal filetype=gitcommit", file.Name())
+}
+
+func printVersion() {
+ fmt.Print("workctl ", version)
+}
+
+func help() {
+ fmt.Printf(`workctl %s
+Extract a general link from a given "text/plain" email from github and append
+it to another commands.
+
+USAGE:
+ workctl [COMMAND]
+
+COMMAND:
+ vimfy edit a file with vim and trim breaking lines so it fits textboxes with easy
+ open open a given link on qutebrowser
+ merge issue a merge request for a given link
+ approve approve PR from a given link
+ dependabot comment dependabot to rebase and merge for given link
+ edit open the patch file from a given link`, version)
+}
+
+func printIfError(err error) {
+ if err != nil {
+ fmt.Println("Error running the command:")
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+}
+
+func main() {
+ if len(os.Args) > 2 {
+ fmt.Println("Invalid number of param")
+ help()
+ os.Exit(1)
+ }
+
+ action := os.Args[1]
+
+ switch action {
+ case "open":
+ printIfError(open())
+ case "merge":
+ printIfError(merge())
+ case "edit":
+ printIfError(edit())
+ case "approve":
+ printIfError(approve())
+ case "dependabot":
+ printIfError(dependabot())
+ case "version", "--version":
+ printVersion()
+ default:
+ help()
+ }
+}
diff --git a/main_test.go b/main_test.go
new file mode 100644
index 0000000..6d0d59f
--- /dev/null
+++ b/main_test.go
@@ -0,0 +1,127 @@
+//go:build unit
+
+package main
+
+import (
+ "testing"
+)
+
+func TestExtractPR(t *testing.T) {
+
+ testCases := []struct {
+ name string
+ mail string
+ want string
+ }{
+ {
+ name: "pr created",
+ want: "https://github.com/grid-x/dploy/pull/9",
+ mail: `This will allow the change log to directly link the PR making a bit easier to check the summary of those PR.
+
+Ex.:
+
+![image](https://user-images.githubusercontent.com/4411113/234298782-30d154bd-540c-483f-87d1-0d28fb76f0c2.png)
+
+You can view, comment on, or merge this pull request online at:
+
+ https://github.com/grid-x/dploy/pull/9
+
+-- Commit Summary --
+
+ * feat(main): allow link pr instead of message
+
+-- File Changes --
+
+ M main.go (61)
+
+-- Patch Links --
+
+https://github.com/grid-x/dploy/pull/9.patch
+https://github.com/grid-x/dploy/pull/9.diff
+
+--
+Reply to this email directly or view it on GitHub:
+https://github.com/grid-x/dploy/pull/9
+You are receiving this because you are subscribed to this thread.
+
+Message ID: &lt;grid-x/dploy/pull/9@github.com&gt;`,
+ },
+ {
+ name: "request review",
+ want: "https://github.com/grid-x/edge-connector/pull/319",
+ mail: `@juliusmh requested review from @grid-x/edge-connector-team on: grid-x/edge-connector#319 fix(api/manage): write system controls to response after set as a code owner.
+
+--
+Reply to this email directly or view it on GitHub:
+https://github.com/grid-x/edge-connector/pull/319#event-9104760420
+You are receiving this because your review was requested.
+
+Message ID: <grid-x/edge-connector/pull/319/issue_event/9104760420@github.com>`,
+ },
+ {
+ name: "pr merged",
+ want: "https://github.com/grid-x/edge-connector/pull/319",
+ mail: `Merged #319 into main.
+
+--
+Reply to this email directly or view it on GitHub:
+https://github.com/grid-x/edge-connector/pull/319#event-9112252051
+You are receiving this because your review was requested.
+
+Message ID: <grid-x/edge-connector/pull/319/issue_event/9112252051@github.com>`,
+ },
+ {
+ name: "pr pushed",
+ want: "https://github.com/grid-x/edge-connector/pull/313",
+ mail: `@juliusmh pushed 1 commit.
+
+a0557c770be6d9c2b6070c4fd6a69c68c5e3996f feat(feature/service): accept feature names in kebab-case
+
+--
+View it on GitHub:
+https://github.com/grid-x/edge-connector/pull/313/files/dfdd5081691056150ace71dfb5d11265593c561e..a0557c770be6d9c2b6070c4fd6a69c68c5e3996f
+You are receiving this because you are subscribed to this thread.
+
+Message ID: <grid-x/edge-connector/pull/313/push/13418764381@github.com>`,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ prLink := extractPRLink(tc.mail)
+
+ if prLink != tc.want {
+ t.Error("Invalid link returned: " + prLink)
+ }
+ })
+ }
+}
+
+func TestExec(t *testing.T) {
+ testCases := []struct {
+ name string
+ app string
+ args []string
+ want string
+ }{
+ {
+ name: "echo",
+ app: "echo",
+ args: []string{"this", "is", "a", "phrase"},
+ want: "this is a phrase\n",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ out, err := execCommand(tc.app, tc.args...)
+ if err != nil {
+ t.Fatal("Failed " + err.Error())
+ }
+
+ if out != tc.want {
+ t.Error("Invalid stdout returned: " + out)
+ }
+ })
+ }
+}