wtf/travisci/
None.
+Key: [return]
+Action: Open the selected build in the browser.
Key: j
+Action: Select the next build in the list.
Key: k
+Action: Select the previous build in the list.
Key: r
+Action: Refresh the data.
Key: ↓
+Action: Select the next build in the list.
Key: ↑
+Action: Select the previous build in the list.
travisci:
diff --git a/gerrit/display.go b/gerrit/display.go
index 895b8fda..6a9cd499 100644
--- a/gerrit/display.go
+++ b/gerrit/display.go
@@ -66,10 +66,7 @@ func (widget *Widget) displayStats(project *GerritProject) string {
func (widget *Widget) rowColor(index int) string {
if widget.View.HasFocus() && (index == widget.selected) {
- foreColor := wtf.Config.UString("wtf.colors.highlight.fore", "black")
- backColor := wtf.Config.UString("wtf.colors.highlight.back", "orange")
-
- return fmt.Sprintf("%s:%s", foreColor, backColor)
+ return wtf.DefaultFocussedRowColor()
}
return wtf.RowColor("gerrit", index)
}
diff --git a/jira/widget.go b/jira/widget.go
index 29d536d1..4fcac8ab 100644
--- a/jira/widget.go
+++ b/jira/widget.go
@@ -130,10 +130,7 @@ func (widget *Widget) contentFrom(searchResult *SearchResult) string {
func (widget *Widget) rowColor(idx int) string {
if widget.View.HasFocus() && (idx == widget.selected) {
- foreColor := wtf.Config.UString("wtf.colors.highlight.fore", "black")
- backColor := wtf.Config.UString("wtf.colors.highlight.back", "orange")
-
- return fmt.Sprintf("%s:%s", foreColor, backColor)
+ return wtf.DefaultFocussedRowColor()
}
return wtf.RowColor("jira", idx)
}
diff --git a/main.go b/main.go
index 19176323..b5da66cb 100644
--- a/main.go
+++ b/main.go
@@ -232,7 +232,7 @@ func addWidget(app *tview.Application, pages *tview.Pages, widgetName string) {
case "todoist":
widgets = append(widgets, todoist.NewWidget(app, pages))
case "travisci":
- widgets = append(widgets, travisci.NewWidget())
+ widgets = append(widgets, travisci.NewWidget(app, pages))
case "trello":
widgets = append(widgets, trello.NewWidget())
case "twitter":
diff --git a/travisci/client.go b/travisci/client.go
index 1e66cb41..6a88e5b3 100644
--- a/travisci/client.go
+++ b/travisci/client.go
@@ -15,11 +15,16 @@ import (
const APIEnvToken = "WTF_TRAVIS_API_TOKEN"
+var TRAVIS_HOSTS = map[bool]string{
+ false: "travis-ci.org",
+ true: "travis-ci.com",
+}
+
func BuildsFor() (*Builds, error) {
builds := &Builds{}
pro := wtf.Config.UBool("wtf.mods.travisci.pro", false)
- travisAPIURL.Host = hosts[pro]
+ travisAPIURL.Host = "api." + TRAVIS_HOSTS[pro]
resp, err := travisRequest("builds")
if err != nil {
@@ -35,19 +40,15 @@ func BuildsFor() (*Builds, error) {
var (
travisAPIURL = &url.URL{Scheme: "https", Path: "/"}
- hosts = map[bool]string{
- false: "api.travis-ci.org",
- true: "api.travis-ci.com",
- }
)
func travisRequest(path string) (*http.Response, error) {
params := url.Values{}
params.Add("limit", "10")
- url := travisAPIURL.ResolveReference(&url.URL{Path: path, RawQuery: params.Encode()})
+ requestUrl := travisAPIURL.ResolveReference(&url.URL{Path: path, RawQuery: params.Encode()})
- req, err := http.NewRequest("GET", url.String(), nil)
+ req, err := http.NewRequest("GET", requestUrl.String(), nil)
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Travis-API-Version", "3")
diff --git a/travisci/travis.go b/travisci/travis.go
index 47f619e6..aca03616 100644
--- a/travisci/travis.go
+++ b/travisci/travis.go
@@ -5,10 +5,12 @@ type Builds struct {
}
type Build struct {
+ ID int `json:"id"`
CreatedBy Owner `json:"created_by"`
Branch Branch `json:"branch"`
Number string `json:"number"`
Repository Repository `json:"repository"`
+ Commit Commit `json:"commit"`
State string `json:"state"`
}
@@ -22,4 +24,9 @@ type Branch struct {
type Repository struct {
Name string `json:"name"`
+ Slug string `json:"slug"`
+}
+
+type Commit struct {
+ Message string `json:"message"`
}
diff --git a/travisci/widget.go b/travisci/widget.go
index a22bdf3c..170e548b 100644
--- a/travisci/widget.go
+++ b/travisci/widget.go
@@ -2,18 +2,45 @@ package travisci
import (
"fmt"
+ "github.com/gdamore/tcell"
+ "github.com/rivo/tview"
"github.com/senorprogrammer/wtf/wtf"
+ "strings"
)
+const HelpText = `
+ Keyboard commands for Travis CI:
+
+ /: Show/hide this help window
+ j: Select the next build in the list
+ k: Select the previous build in the list
+ r: Refresh the data
+
+ arrow down: Select the next build in the list
+ arrow up: Select the previous build in the list
+
+ return: Open the selected build in a browser
+`
+
type Widget struct {
+ wtf.HelpfulWidget
wtf.TextWidget
+
+ builds *Builds
+ selected int
}
-func NewWidget() *Widget {
+func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
widget := Widget{
- TextWidget: wtf.NewTextWidget("TravisCI", "travisci", false),
+ HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
+ TextWidget: wtf.NewTextWidget("TravisCI", "travisci", true),
}
+ widget.HelpfulWidget.SetView(widget.View)
+ widget.unselect()
+
+ widget.View.SetInputCapture(widget.keyboardIntercept)
+
return &widget
}
@@ -28,31 +55,43 @@ func (widget *Widget) Refresh() {
widget.UpdateRefreshedAt()
- widget.View.SetTitle(fmt.Sprintf("%s - Builds", widget.Name))
-
- var content string
if err != nil {
widget.View.SetWrap(true)
- content = err.Error()
+ widget.View.SetTitle(widget.Name)
+ widget.View.SetText(err.Error())
} else {
- widget.View.SetWrap(false)
- content = widget.contentFrom(builds)
+ widget.builds = builds
}
- widget.View.SetText(content)
+ widget.display()
}
/* -------------------- Unexported Functions -------------------- */
+func (widget *Widget) display() {
+ if widget.builds == nil {
+ return
+ }
+
+ widget.View.SetWrap(false)
+
+ widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - Builds", widget.Name)))
+ widget.View.SetText(widget.contentFrom(widget.builds))
+}
+
func (widget *Widget) contentFrom(builds *Builds) string {
var str string
- for _, build := range builds.Builds {
+ for idx, build := range builds.Builds {
+
str = str + fmt.Sprintf(
- "[%s] %s-%s (%s) [white]%s\n",
+ "[%s] [%s] %s-%s (%s) [%s]%s - [blue]%s\n",
+ widget.rowColor(idx),
buildColor(&build),
build.Repository.Name,
build.Number,
build.Branch.Name,
+ widget.rowColor(idx),
+ strings.Split(build.Commit.Message, "\n")[0],
build.CreatedBy.Login,
)
}
@@ -60,6 +99,13 @@ func (widget *Widget) contentFrom(builds *Builds) string {
return str
}
+func (widget *Widget) rowColor(idx int) string {
+ if widget.View.HasFocus() && (idx == widget.selected) {
+ return wtf.DefaultFocussedRowColor()
+ }
+ return "White"
+}
+
func buildColor(build *Build) string {
switch build.State {
case "broken":
@@ -80,3 +126,69 @@ func buildColor(build *Build) string {
return "white"
}
}
+
+func (widget *Widget) next() {
+ widget.selected++
+ if widget.builds != nil && widget.selected >= len(widget.builds.Builds) {
+ widget.selected = 0
+ }
+
+ widget.display()
+}
+
+func (widget *Widget) prev() {
+ widget.selected--
+ if widget.selected < 0 && widget.builds != nil {
+ widget.selected = len(widget.builds.Builds) - 1
+ }
+
+ widget.display()
+}
+
+func (widget *Widget) openBuild() {
+ sel := widget.selected
+ if sel >= 0 && widget.builds != nil && sel < len(widget.builds.Builds) {
+ build := &widget.builds.Builds[widget.selected]
+ travisHost := TRAVIS_HOSTS[wtf.Config.UBool("wtf.mods.travisci.pro", false)]
+ wtf.OpenFile(fmt.Sprintf("https://%s/%s/%s/%d", travisHost, build.Repository.Slug, "builds", build.ID))
+ }
+}
+
+func (widget *Widget) unselect() {
+ widget.selected = -1
+ widget.display()
+}
+
+func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
+ switch string(event.Rune()) {
+ case "/":
+ widget.ShowHelp()
+ case "j":
+ widget.next()
+ return nil
+ case "k":
+ widget.prev()
+ return nil
+ case "r":
+ widget.Refresh()
+ return nil
+ }
+
+ switch event.Key() {
+ case tcell.KeyDown:
+ widget.next()
+ return nil
+ case tcell.KeyEnter:
+ widget.openBuild()
+ return nil
+ case tcell.KeyEsc:
+ widget.unselect()
+ return event
+ case tcell.KeyUp:
+ widget.prev()
+ widget.display()
+ return nil
+ default:
+ return event
+ }
+}
diff --git a/wtf/utils.go b/wtf/utils.go
index 01f351f3..a2bb778e 100644
--- a/wtf/utils.go
+++ b/wtf/utils.go
@@ -113,6 +113,13 @@ func RightAlignFormat(view *tview.TextView) string {
return fmt.Sprintf("%%%ds", w-1)
}
+func DefaultFocussedRowColor() string {
+ foreColor := Config.UString("wtf.colors.highlight.fore", "black")
+ backColor := Config.UString("wtf.colors.highlight.back", "orange")
+
+ return fmt.Sprintf("%s:%s", foreColor, backColor)
+}
+
func RowColor(module string, idx int) string {
evenKey := fmt.Sprintf("wtf.mods.%s.colors.row.even", module)
oddKey := fmt.Sprintf("wtf.mods.%s.colors.row.odd", module)