Skip to content

Commit

Permalink
Override default REGExes used by core lookup_command (#64)
Browse files Browse the repository at this point in the history
lookup command default matchers can be overriden by
passing additional params in the config.

in order to support multiple T/D tickets we can use
FindAllStringSubmatch to extract all matches and then use map
function to de-dupe matches to avoid posting the same ticket
more than once

Fixes #59
  • Loading branch information
farshidce authored and schemar committed Feb 9, 2018
1 parent 5e85f57 commit bef1f2d
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
main.production.yml
dist
.idea
30 changes: 22 additions & 8 deletions app/connectors/common.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package connectors

import "github.com/etcinit/phabulous/app/interfaces"
import (
"github.com/etcinit/phabulous/app/interfaces"
"github.com/etcinit/phabulous/app/modules/utilities"
)

// processMessage processes incoming messages events and calls the appropriate
// handlers.
Expand All @@ -17,12 +20,17 @@ func processMessage(conn interfaces.Bot, msg interfaces.Message) {
handled := false

for _, tuple := range conn.GetIMHandlers() {
var handledResults = []string{}
pattern := tuple.GetPattern()

if result := pattern.FindStringSubmatch(content); result != nil {
go tuple.GetHandler()(conn, msg, result)

handled = true
if results := pattern.FindAllStringSubmatch(content, -1); results != nil {

for _, result := range results {
if !utilities.Contains(handledResults, result) {
go tuple.GetHandler()(conn, msg, result)
handledResults = append(handledResults, utilities.UniqueItemsOf(result)...)
handled = true
}
}
}
}

Expand All @@ -36,9 +44,15 @@ func processMessage(conn interfaces.Bot, msg interfaces.Message) {

for _, tuple := range conn.GetHandlers() {
pattern := tuple.GetPattern()
var handledResults []string

if result := pattern.FindStringSubmatch(content); result != nil {
go tuple.GetHandler()(conn, msg, result)
if results := pattern.FindAllStringSubmatch(content, -1); results != nil {
for _, result := range results {
if !utilities.Contains(handledResults, result) {
go tuple.GetHandler()(conn, msg, result)

}
}
}
}
}
5 changes: 3 additions & 2 deletions app/connectors/irc_bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import (

func Test_IRCConnector_LoadModules(t *testing.T) {
connector := IRCConnector{}
connector.LoadModules([]interfaces.Module{&core.Module{}})
connector.LoadModules([]interfaces.Module{&core.Module{Config:connector.config}})
connector.config = confer.NewConfig()

assert.Equal(t, 0, len(connector.GetHandlers()))
assert.Equal(t, 0, len(connector.GetIMHandlers()))

modules := []interfaces.Module{&core.Module{}}
modules := []interfaces.Module{&core.Module{Config:connector.config}}

connector.client = client.SimpleClient("phabulous")
connector.LoadModules(modules)
Expand Down
52 changes: 28 additions & 24 deletions app/modules/core/command_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package core

import (
"fmt"

"github.com/etcinit/phabulous/app/interfaces"
"github.com/etcinit/phabulous/app/messages"
"github.com/etcinit/phabulous/app/modules/utilities"
)

// LookupCommand allows users to lookup objects from Phabricator.
type LookupCommand struct{}
type LookupCommand struct{
AdditionalMatchers []string
}

// GetUsage returns the usage of this command.
func (c *LookupCommand) GetUsage() string {
Expand All @@ -22,9 +24,11 @@ func (c *LookupCommand) GetDescription() string {

// GetMatchers returns the matchers for this command.
func (c *LookupCommand) GetMatchers() []string {
return []string{
"^([T|D][0-9]{1,16})$",
defaultMatchers := []string{"^([T|D][0-9]{1,16})$"}
if c.AdditionalMatchers != nil {
return append(defaultMatchers, c.AdditionalMatchers...)
}
return defaultMatchers
}

// GetIMMatchers returns IM matchers for this command.
Expand Down Expand Up @@ -54,27 +58,27 @@ func (c *LookupCommand) GetHandler() interfaces.Handler {
return
}

res, err := conn.PHIDLookupSingle(matches[1])
if err != nil {
s.Excuse(m, err)
return
}
uniqueMatches := utilities.UniqueItemsOf(matches)

if res == nil {
s.Post(
m.GetChannel(),
fmt.Sprintf("I couldn't find %s", matches[1]),
messages.IconDefault,
true,
)
return
for _, match := range uniqueMatches {
res, err := conn.PHIDLookupSingle(match)
if err != nil {
s.Excuse(m, err)
} else if res == nil {
s.Post(
m.GetChannel(),
fmt.Sprintf("I couldn't find %s", match),
messages.IconDefault,
true,
)
} else {
s.Post(
m.GetChannel(),
fmt.Sprintf("*%s* (%s): %s", res.FullName, res.Status, res.URI),
messages.IconTasks,
true,
)
}
}

s.Post(
m.GetChannel(),
fmt.Sprintf("*%s* (%s): %s", res.FullName, res.Status, res.URI),
messages.IconTasks,
true,
)
}
}
18 changes: 18 additions & 0 deletions app/modules/core/command_lookup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package core

import (
"testing"
"github.com/stretchr/testify/assert"
)

func Test_additionalMatchersNil(t *testing.T) {
lookup_command := LookupCommand{AdditionalMatchers: nil}
assert.NotEmpty(t, lookup_command.GetMatchers())
}

func Test_additionalMatchers(t *testing.T) {
additionalMatchers := []string{"([D][0-9]{1,16})", "([D][0-1]{1,16})"}
lookupCommand := LookupCommand{AdditionalMatchers: additionalMatchers}
assert.Contains(t, lookupCommand.GetMatchers(), "([D][0-9]{1,16})")
assert.Contains(t, lookupCommand.GetMatchers(), "([D][0-1]{1,16})")
}
16 changes: 13 additions & 3 deletions app/modules/core/module.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package core

import "github.com/etcinit/phabulous/app/interfaces"
import (
"github.com/etcinit/phabulous/app/interfaces"
"github.com/jacobstr/confer"
)

// Module provides development/debugging commands.
type Module struct{}
type Module struct{
Config *confer.Config
}

// GetName returns the name of this module.
func (m *Module) GetName() string {
Expand All @@ -12,8 +17,13 @@ func (m *Module) GetName() string {

// GetCommands returns the commands provided by this module.
func (m *Module) GetCommands() []interfaces.Command {
var lookupCommandAdditionalMatchers []string
if m.Config.InConfig("commands.lookup.matchers") {
lookupCommandAdditionalMatchers = m.Config.GetStringSlice("commands.lookup.matchers")
}
return []interfaces.Command{
&LookupCommand{},

&LookupCommand{AdditionalMatchers:lookupCommandAdditionalMatchers},
&SummonCommand{},
&MemeCommand{},
&ModulesCommand{},
Expand Down
9 changes: 7 additions & 2 deletions app/modules/dev/module.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package dev

import "github.com/etcinit/phabulous/app/interfaces"
import (
"github.com/etcinit/phabulous/app/interfaces"
"github.com/jacobstr/confer"
)

// Module provides development/debugging commands.
type Module struct{}
type Module struct{
Config *confer.Config
}

// GetName returns the name of this module.
func (m *Module) GetName() string {
Expand Down
9 changes: 7 additions & 2 deletions app/modules/extension/module.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package extension

import "github.com/etcinit/phabulous/app/interfaces"
import (
"github.com/etcinit/phabulous/app/interfaces"
"github.com/jacobstr/confer"
)

// Module provides development/debugging commands.
type Module struct{}
type Module struct{
Config *confer.Config
}

// GetName returns the name of this module.
func (m *Module) GetName() string {
Expand Down
6 changes: 3 additions & 3 deletions app/modules/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func (f *ModuleFactory) Make() []interfaces.Module {
}

if moduleName == "core" {
moduleMap["core"] = &core.Module{}
moduleMap["core"] = &core.Module{f.config}
} else if moduleName == "dev" {
moduleMap["dev"] = &dev.Module{}
moduleMap["dev"] = &dev.Module{f.config}
} else if moduleName == "extension" {
moduleMap["extension"] = &extension.Module{}
moduleMap["extension"] = &extension.Module{f.config}
} else {
f.logger.Panicf(
"Unable to load modules. Unknown module '%s'.",
Expand Down
32 changes: 32 additions & 0 deletions app/modules/utilities/listutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package utilities

func UniqueItemsOf(s []string) []string {
unique := make(map[string]bool, len(s))
uniques := make([]string, len(unique))
for _, elem := range s {
if len(elem) != 0 {
if !unique[elem] {
uniques = append(uniques, elem)
unique[elem] = true
}
}
}
return uniques
}

func Contains(slice1 []string, slice2 []string) bool {
slice1Uniques := UniqueItemsOf(slice1)
slice2Uniques := UniqueItemsOf(slice2)
for _, value2 := range slice2Uniques {
var slice2ItemInSlice1 = false
for _, value1 := range slice1Uniques {
if value1 == value2 {
slice2ItemInSlice1 = true
}
}
if !slice2ItemInSlice1 {
return false
}
}
return true
}
8 changes: 7 additions & 1 deletion config/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ slack:
# When set to false, the bot will post like any other integration (like
# webhooks). This allows it to post on almost any channel without having to
# be invited.
as-user: true
as-user: false
irc:
# Use this flag to enable/disable the IRC connector.
enable: false
Expand Down Expand Up @@ -105,3 +105,9 @@ core:
includeSelf: true
misc:
ignore-ca: false

commands:
lookup:
# override set of REGEXes used by lookup commands
matchers:
- ([T|D][0-9]{1,16})+

0 comments on commit bef1f2d

Please sign in to comment.