1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

implemented azure devops widget

This commit is contained in:
Viktor Braun (v_b) 2019-09-19 10:11:59 +02:00
parent 4c3abf5aca
commit 64985c3beb
7 changed files with 210 additions and 0 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/wtfutil/wtf/modules/datadog"
"github.com/wtfutil/wtf/modules/digitalclock"
"github.com/wtfutil/wtf/modules/docker"
"github.com/wtfutil/wtf/modules/azuredevops"
"github.com/wtfutil/wtf/modules/feedreader"
"github.com/wtfutil/wtf/modules/gcal"
"github.com/wtfutil/wtf/modules/gerrit"
@ -112,6 +113,9 @@ func MakeWidget(
case "docker":
settings := docker.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = docker.NewWidget(app, pages, settings)
case "azuredevops":
settings := azuredevops.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = azuredevops.NewWidget(app, pages, settings)
case "feedreader":
settings := feedreader.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = feedreader.NewWidget(app, pages, settings)

2
go.mod
View File

@ -48,6 +48,8 @@ require (
github.com/magiconair/properties v1.8.1 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.9 // indirect
github.com/microsoft/azure-devops-go-api v0.0.0-20190912142452-3207b4a469d3 // indirect
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20190912142452-3207b4a469d3
github.com/mmcdole/gofeed v1.0.0-beta2.0.20190420154928-0e68beaf6fdf
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/olebedev/config v0.0.0-20190528211619-364964f3a8e4

5
go.sum
View File

@ -154,6 +154,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI
github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
@ -222,6 +223,10 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microsoft/azure-devops-go-api v0.0.0-20190912142452-3207b4a469d3 h1:FhI3QJOcd1CaXz2+DeFHUNEsS47+gxDERzVhexlTGvg=
github.com/microsoft/azure-devops-go-api v0.0.0-20190912142452-3207b4a469d3/go.mod h1:HfrxIH2ObkhL6NepJKAuEwUYY8kNvspOWDp6HDRIRQs=
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20190912142452-3207b4a469d3 h1:Q42uNxLRytr5ynbRkqspq37TjcfnuXwKmrS9APJv/Bw=
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20190912142452-3207b4a469d3/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mmcdole/gofeed v1.0.0-beta2.0.20190420154928-0e68beaf6fdf h1:poo3e5STwUVGyyUX0e3fHQUwT1tV8IYEFUUpYd/7LuA=

View File

@ -0,0 +1,59 @@
package azuredevops
import (
"fmt"
"strings"
azrBuild "github.com/microsoft/azure-devops-go-api/azuredevops/build"
"github.com/pkg/errors"
)
func (widget *Widget) getBuildStats() string {
projName := widget.settings.projectName
statusFilter := azrBuild.BuildStatusValues.All
top := widget.settings.maxRows
builds, err := widget.cli.GetBuilds(widget.ctx, azrBuild.GetBuildsArgs{Project: &projName, StatusFilter: &statusFilter, Top: &top})
if err != nil {
return errors.Wrap(err, "could not get builds").Error()
}
result := ""
for _, build := range builds.Value {
num := *build.BuildNumber
branch := *build.SourceBranch
reason := *build.Reason
triggers := *build.TriggerInfo
if reason == azrBuild.BuildReasonValues.PullRequest {
branch = triggers["pr.sourceBranch"]
}
branch = strings.TrimPrefix(branch, "refs/heads/")
status := *build.Status
statusDisplay := "[white:grey]unknown"
if status == azrBuild.BuildStatusValues.InProgress {
statusDisplay = "[white:blue]in progress"
} else if status == azrBuild.BuildStatusValues.Cancelling {
statusDisplay = "[white:orange]in cancelling"
} else if (status == azrBuild.BuildStatusValues.Postponed) || (status == azrBuild.BuildStatusValues.NotStarted) {
statusDisplay = "[white:blue]waiting"
} else if status == azrBuild.BuildStatusValues.Completed {
buildResult := *build.Result
if buildResult == azrBuild.BuildResultValues.Succeeded {
statusDisplay = "[white:green]succeeded"
} else if buildResult == azrBuild.BuildResultValues.Failed {
statusDisplay = "[white:red]failed"
} else if buildResult == azrBuild.BuildResultValues.Canceled {
statusDisplay = "[white:darkgrey]cancelled"
} else if buildResult == azrBuild.BuildResultValues.PartiallySucceeded {
statusDisplay = "[white:magenta]partially"
}
}
result += fmt.Sprintf("%s[-:-:-] #%s %s (%s) \n", statusDisplay, num, branch, reason)
}
if result == "" {
result = "no builds found"
}
return result
}

View File

@ -0,0 +1,42 @@
wtf:
colors:
# background: black
# foreground: blue
border:
focusable: darkslateblue
focused: orange
normal: gray
checked: yellow
highlight:
fore: black
back: gray
rows:
even: yellow
odd: white
grid:
# How _wide_ the columns are, in terminal characters. In this case we have
# four columns, each of which are 35 characters wide.
# columns: [50, ]
# How _high_ the rows are, in terminal lines. In this case we have four rows
# that support ten line of text and one of four.
# rows: [50]
refreshInterval: 1
openFileUtil: "open"
mods:
azuredevops:
type: azuredevops
title: "💻"
enabled: true
position:
top: 0
left: 0
height: 3
width: 3
refreshInterval: 1
labelColor: lightblue # title label color (optional / default: white)
apiToken: "mysecret api token" # api key (required)
orgUrl: "https://dev.azure.com/myawesomecompany/" # url to your azure devops project (required)
prjectName: "the awesome project" # name of your project (required)
maxRows: 3 #max rows to show (optional / default 3)

View File

@ -0,0 +1,32 @@
package azuredevops
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const defaultTitle = "azuredevops"
// Settings defines the configuration options for this module
type Settings struct {
common *cfg.Common
labelColor string
apiToken string
orgURL string
projectName string
maxRows int
}
// NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig),
labelColor: ymlConfig.UString("labelColor", "white"),
apiToken: ymlConfig.UString("apiToken", "api token not specified"),
orgURL: ymlConfig.UString("orgURL", "org url not specified"),
projectName: ymlConfig.UString("projectName", "project name not specified"),
maxRows: ymlConfig.UInt("maxRows", 3),
}
return &settings
}

View File

@ -0,0 +1,66 @@
package azuredevops
import (
"context"
"fmt"
azr "github.com/microsoft/azure-devops-go-api/azuredevops"
azrBuild "github.com/microsoft/azure-devops-go-api/azuredevops/build"
"github.com/pkg/errors"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/view"
)
type Widget struct {
view.TextWidget
cli *azrBuild.Client
settings *Settings
displayBuffer string
ctx context.Context
}
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{
TextWidget: view.NewTextWidget(app, settings.common, false),
settings: settings,
}
widget.View.SetScrollable(true)
connection := azr.NewPatConnection(settings.orgURL, settings.apiToken)
ctx := context.Background()
cli, err := azrBuild.NewClient(ctx, connection)
if err != nil {
widget.displayBuffer = errors.Wrap(err, "could not create client 2").Error()
} else {
widget.cli = cli
widget.ctx = ctx
}
widget.refreshDisplayBuffer()
return &widget
}
func (widget *Widget) Refresh() {
widget.refreshDisplayBuffer()
widget.Redraw(widget.display)
}
func (widget *Widget) display() (string, string, bool) {
return widget.CommonSettings().Title, widget.displayBuffer, true
}
func (widget *Widget) refreshDisplayBuffer() {
if widget.cli == nil {
return
}
widget.displayBuffer = ""
widget.displayBuffer += fmt.Sprintf("[%s::bul] build status - %s\n",
widget.settings.labelColor,
widget.settings.projectName)
widget.displayBuffer += widget.getBuildStats()
}