Skip to content

Commit

Permalink
feat:(jx step chart) lets add slack member tracking
Browse files Browse the repository at this point in the history
for chat servers that don't allow bots lets allow manual supply of the metrics from the CLI
  • Loading branch information
jstrachan committed Apr 11, 2018
1 parent 7870ce0 commit a701977
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 38 deletions.
2 changes: 1 addition & 1 deletion jenkins-x.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
chat:
kind: slack
url: http://slack.k8s.io/
url: http://kubernetes.slack.com/
developerChannel: '#jenkins-x-dev'
userChannel: '#jenkins-x-user'
2 changes: 2 additions & 0 deletions pkg/chats/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ type ChatProvider interface {

// ChannelMetrics metrics for a channel
type ChannelMetrics struct {
ID string
Name string
URL string
MemberCount int
Members []string
}

func (m *ChannelMetrics) ToMarkdown() string {
Expand Down
24 changes: 21 additions & 3 deletions pkg/chats/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chats

import (
"fmt"
"strings"

"github.com/jenkins-x/jx/pkg/auth"
"github.com/jenkins-x/jx/pkg/util"
Expand Down Expand Up @@ -35,11 +36,28 @@ func (c *SlackChatProvider) GetChannelMetrics(name string) (*ChannelMetrics, err
metrics := &ChannelMetrics{
Name: name,
}
ch, err := c.SlackClient.GetChannelInfo(name)
name = strings.TrimPrefix(name, "#")
id := name

channels, err := c.SlackClient.GetChannels(true)
if err != nil {
return metrics, err
}
for _, ch := range channels {
fmt.Printf("Found channel %s with id %s\n", ch.Name, ch.ID)
if ch.Name == name {
id = ch.ID
break
}
}
info, err := c.SlackClient.GetChannelInfo(id)
if err != nil {
return metrics, err
}
metrics.MemberCount = ch.NumMembers
metrics.URL = util.UrlJoin(c.Server.URL, "messages", ch.ID)
metrics.MemberCount = info.NumMembers
metrics.ID = info.ID
metrics.Name = info.Name
metrics.Members = info.Members
metrics.URL = util.UrlJoin(c.Server.URL, "messages", info.ID)
return metrics, nil
}
124 changes: 104 additions & 20 deletions pkg/jx/cmd/step_chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"time"

"github.com/jenkins-x/jx/pkg/apis/jenkins.io/v1"
"github.com/jenkins-x/jx/pkg/chats"
"github.com/jenkins-x/jx/pkg/config"
"github.com/jenkins-x/jx/pkg/gits"
"github.com/jenkins-x/jx/pkg/issues"
"github.com/jenkins-x/jx/pkg/jx/cmd/templates"
Expand Down Expand Up @@ -43,28 +45,32 @@ var (
type StepChartOptions struct {
StepOptions

FromDate string
ToDate string
Dir string
BlogOutputDir string
BlogName string
CombineMinorReleases bool
FromDate string
ToDate string
Dir string
BlogOutputDir string
BlogName string
CombineMinorReleases bool
DeveloperChannelMemberCount int
UserChannelMemberCount int

State StepChartState
}

type StepChartState struct {
GitInfo *gits.GitRepositoryInfo
GitProvider gits.GitProvider
Tracker issues.IssueProvider
Release *v1.Release
BlogFileName string
Buffer *bytes.Buffer
Writer *bufio.Writer
HistoryService *reports.ProjectHistoryService
History *reports.ProjectHistory
NewContributors map[string]*v1.UserDetails
NewCommitters map[string]*v1.UserDetails
GitInfo *gits.GitRepositoryInfo
GitProvider gits.GitProvider
Tracker issues.IssueProvider
Release *v1.Release
BlogFileName string
DeveloperChatMetricsName string
UserChatMetricsName string
Buffer *bytes.Buffer
Writer *bufio.Writer
HistoryService *reports.ProjectHistoryService
History *reports.ProjectHistory
NewContributors map[string]*v1.UserDetails
NewCommitters map[string]*v1.UserDetails
}

// NewCmdStepChart Creates a new Command object
Expand Down Expand Up @@ -99,6 +105,8 @@ func NewCmdStepChart(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
cmd.Flags().StringVarP(&options.BlogOutputDir, "blog-dir", "", "", "The Hugo-style blog source code to generate the charts into")
cmd.Flags().StringVarP(&options.BlogName, "blog-name", "n", "", "The blog name")
cmd.Flags().BoolVarP(&options.CombineMinorReleases, "combine-minor", "c", true, "If enabled lets combine minor releases together to simplify the charts")
cmd.Flags().IntVarP(&options.DeveloperChannelMemberCount, "dev-channel-members", "", 0, "If no chat bots can connect to your chat server you can pass in the counts for the developer channel here")
cmd.Flags().IntVarP(&options.UserChannelMemberCount, "user-channel-members", "", 0, "If no chat bots can connect to your chat server you can pass in the counts for the user channel here")
return cmd
}

Expand All @@ -108,7 +116,10 @@ func (o *StepChartOptions) Run() error {
NewContributors: map[string]*v1.UserDetails{},
NewCommitters: map[string]*v1.UserDetails{},
}
var err error
pc, _, err := config.LoadProjectConfig(o.Dir)
if err != nil {
return err
}
outDir := o.BlogOutputDir
if outDir != "" {
if o.BlogName == "" {
Expand Down Expand Up @@ -142,6 +153,12 @@ func (o *StepChartOptions) Run() error {
if err != nil {
return err
}
if pc.Chat != nil {
err = o.loadChatMetrics(pc.Chat)
if err != nil {
return err
}
}
return o.addReportsToBlog()
}

Expand Down Expand Up @@ -317,7 +334,10 @@ This blog outlines the changes on the project from ` + fromDate + ` to ` + toDat
## Charts
` + state.Buffer.String()
` + state.Buffer.String() + `
This blog post was generated via the [jx step blog]() command.
`

}
changelog := strings.TrimSpace(string(data))
Expand All @@ -340,12 +360,23 @@ func (o *StepChartOptions) createMetricsSummary() string {
out := bufio.NewWriter(&buffer)
_, report := o.report()
if report != nil {
developerChatMetricsName := o.State.DeveloperChatMetricsName
if developerChatMetricsName == "" {
developerChatMetricsName = "Developer Chat Members"
}
userChatMetricsName := o.State.UserChatMetricsName
if userChatMetricsName == "" {
userChatMetricsName = "User Chat Members"
}

fmt.Fprintf(out, "| Metric | Recent | Total |\n")
fmt.Fprintf(out, "| :--------- | ------:| -----:|\n")
o.printMetrics(out, "Downloads", &report.DownloadMetrics)
o.printMetrics(out, "Stars", &report.StarsMetrics)
o.printMetrics(out, "New Committers", &report.NewCommitterMetrics)
o.printMetrics(out, "New Contributors", &report.NewContributorMetrics)
o.printMetrics(out, "Stars", &report.StarsMetrics)
o.printMetrics(out, developerChatMetricsName, &report.DeveloperChatMetrics)
o.printMetrics(out, userChatMetricsName, &report.UserChatMetrics)
o.printMetrics(out, "Issues Closed", &report.IssueMetrics)
o.printMetrics(out, "Pull Requests Merged", &report.PullRequestMetrics)
o.printMetrics(out, "Commits", &report.CommitMetrics)
Expand Down Expand Up @@ -513,3 +544,56 @@ func (o *StepChartOptions) formatUser(user *v1.UserDetails) string {
}
return label
}

func (o *StepChartOptions) loadChatMetrics(chatConfig *config.ChatConfig) error {
u := chatConfig.URL
if u == "" {
return nil
}
history, _ := o.report()
if history == nil {
return nil
}
const membersPostfix = " members"
devChannel := chatConfig.DeveloperChannel
if devChannel != "" {
count := o.DeveloperChannelMemberCount
if count > 0 {
o.State.DeveloperChatMetricsName = devChannel + membersPostfix
} else {
metrics, err := o.getChannelMetrics(chatConfig, devChannel)
if err != nil {
o.warnf("Failed to get chat metrics for channel %s: %s\n", devChannel, err)
return nil
}
count = metrics.MemberCount
o.State.DeveloperChatMetricsName = metrics.ToMarkdown() + membersPostfix
}
history.DeveloperChatMetrics(o.ToDate, count)
}
userChannel := chatConfig.UserChannel
if userChannel != "" {
count := o.UserChannelMemberCount
if count > 0 {
o.State.UserChatMetricsName = userChannel + membersPostfix
} else {
metrics, err := o.getChannelMetrics(chatConfig, userChannel)
if err != nil {
o.warnf("Failed to get chat metrics for channel %s: %s\n", userChannel, err)
return nil
}
count = metrics.MemberCount
o.State.UserChatMetricsName = metrics.ToMarkdown() + membersPostfix
}
history.UserChatMetrics(o.ToDate, count)
}
return nil
}

func (o *StepChartOptions) getChannelMetrics(chatConfig *config.ChatConfig, channelName string) (*chats.ChannelMetrics, error) {
provider, err := o.createChatProvider(chatConfig)
if err != nil {
return nil, err
}
return provider.GetChannelMetrics(channelName)
}
44 changes: 30 additions & 14 deletions pkg/reports/project_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
)

type ProjectHistory struct {
LastReportDate string `json:"lastReportDate,omitempty"`
Reports []*ProjectReport `json:"reports,omitempty"`
Contributors []string `json:"contributors,omitempty"`
Committers []string `json:"committers,omitempty"`
LastReportDate string `yaml:"lastReportDate,omitempty"`
Reports []*ProjectReport `yaml:"reports,omitempty"`
Contributors []string `yaml:"contributors,omitempty"`
Committers []string `yaml:"committers,omitempty"`
}

func (h *ProjectHistory) GetOrCreateReport(reportDate string) *ProjectReport {
Expand Down Expand Up @@ -97,6 +97,20 @@ func (h *ProjectHistory) StarsMetrics(reportDate string, total int) *ProjectRepo
return report
}

func (h *ProjectHistory) DeveloperChatMetrics(reportDate string, total int) *ProjectReport {
report := h.GetOrCreateReport(reportDate)
previous := h.FindPreviousReport(reportDate)
updateMetrics(&report.DeveloperChatMetrics, &previous.DeveloperChatMetrics, total)
return report
}

func (h *ProjectHistory) UserChatMetrics(reportDate string, total int) *ProjectReport {
report := h.GetOrCreateReport(reportDate)
previous := h.FindPreviousReport(reportDate)
updateMetrics(&report.UserChatMetrics, &previous.UserChatMetrics, total)
return report
}

func updateMetrics(current *CountMetrics, previous *CountMetrics, total int) {
current.Total += total
previousTotal := 0
Expand All @@ -108,19 +122,21 @@ func updateMetrics(current *CountMetrics, previous *CountMetrics, total int) {
}

type CountMetrics struct {
Count int `json:"count,omitempty"`
Total int `json:"total,omitempty"`
Count int `yaml:"count,omitempty"`
Total int `yaml:"total,omitempty"`
}

type ProjectReport struct {
ReportDate string `json:"reportDate,omitempty"`
StarsMetrics CountMetrics `json:"starsMetrics,omitempty"`
DownloadMetrics CountMetrics `json:"downloadMetrics,omitempty"`
IssueMetrics CountMetrics `json:"issueMetrics,omitempty"`
PullRequestMetrics CountMetrics `json:"pullRequestMetrics,omitempty"`
CommitMetrics CountMetrics `json:"commitMetrics,omitempty"`
NewCommitterMetrics CountMetrics `json:"newCommitterMetrics,omitempty"`
NewContributorMetrics CountMetrics `json:"newContributorMetrics,omitempty"`
ReportDate string `yaml:"reportDate,omitempty"`
StarsMetrics CountMetrics `yaml:"starsMetrics,omitempty"`
DownloadMetrics CountMetrics `yaml:"downloadMetrics,omitempty"`
IssueMetrics CountMetrics `yaml:"issueMetrics,omitempty"`
PullRequestMetrics CountMetrics `yaml:"pullRequestMetrics,omitempty"`
CommitMetrics CountMetrics `yaml:"commitMetrics,omitempty"`
NewCommitterMetrics CountMetrics `yaml:"newCommitterMetrics,omitempty"`
NewContributorMetrics CountMetrics `yaml:"newContributorMetrics,omitempty"`
DeveloperChatMetrics CountMetrics `yaml:"developerChatMetrics,omitempty"`
UserChatMetrics CountMetrics `yaml:"userChatMetrics,omitempty"`
}

type ProjectHistoryService struct {
Expand Down

0 comments on commit a701977

Please sign in to comment.