diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..9703fba40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*~ +pullrequester +.test + +testing \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..737eada5f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: go + +go: + - 1.9 + +branches: + only: + - master + +before_install: +- ./look_for_logs.sh +- go get github.com/axw/gocov/gocov +- go get github.com/mattn/goveralls +- go get golang.org/x/lint/golint +- go get github.com/GeertJohan/fgt +- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; + fi + +script: +- fgt golint $(find . | grep .go$ | grep -v pullrequester.pb.go) +- $HOME/gopath/bin/goveralls -service=travis-ci -ignore=pullrequester.go -package github.com/brotherlogic/pullrequester diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..88ec4f811 --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +protoc --proto_path ../../../ -I=./proto --go_out=plugins=grpc:./proto proto/pullrequester.proto diff --git a/look_for_logs.sh b/look_for_logs.sh new file mode 100755 index 000000000..a158bbef9 --- /dev/null +++ b/look_for_logs.sh @@ -0,0 +1,20 @@ +#!/bin/bash +grep log.Print * -Rl | grep .go$ | grep -v _test.go +RESULT=$? +if [ $RESULT != 1 ]; then + exit 1 +fi + +grep context.Background * -Rl | grep .go$ | grep -v _test.go +RESULT=$? +if [ $RESULT != 1 ]; then + exit 1 +fi + +RESULT1=$(grep "conn, err" *.go -R | wc | awk '{print $1}') +RESULT2=$(grep "conn.Close" *.go -R | wc| awk '{print $1}') + +if [ $RESULT1 != $RESULT2 ]; then + echo "Missing Closes!" + exit 1 +fi diff --git a/proto/pullrequester.pb.go b/proto/pullrequester.pb.go new file mode 100644 index 000000000..44b24a81f --- /dev/null +++ b/proto/pullrequester.pb.go @@ -0,0 +1,76 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: pullrequester.proto + +package pullrequester + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Config struct { + LastRun int64 `protobuf:"varint,1,opt,name=last_run,json=lastRun,proto3" json:"last_run,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Config) Reset() { *m = Config{} } +func (m *Config) String() string { return proto.CompactTextString(m) } +func (*Config) ProtoMessage() {} +func (*Config) Descriptor() ([]byte, []int) { + return fileDescriptor_bebe1259dc1913b7, []int{0} +} + +func (m *Config) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Config.Unmarshal(m, b) +} +func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Config.Marshal(b, m, deterministic) +} +func (m *Config) XXX_Merge(src proto.Message) { + xxx_messageInfo_Config.Merge(m, src) +} +func (m *Config) XXX_Size() int { + return xxx_messageInfo_Config.Size(m) +} +func (m *Config) XXX_DiscardUnknown() { + xxx_messageInfo_Config.DiscardUnknown(m) +} + +var xxx_messageInfo_Config proto.InternalMessageInfo + +func (m *Config) GetLastRun() int64 { + if m != nil { + return m.LastRun + } + return 0 +} + +func init() { + proto.RegisterType((*Config)(nil), "pullrequester.Config") +} + +func init() { proto.RegisterFile("pullrequester.proto", fileDescriptor_bebe1259dc1913b7) } + +var fileDescriptor_bebe1259dc1913b7 = []byte{ + // 89 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xcd, 0xc9, + 0x29, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, + 0xe2, 0x45, 0x11, 0x54, 0x52, 0xe6, 0x62, 0x73, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0x17, 0x92, 0xe4, + 0xe2, 0xc8, 0x49, 0x2c, 0x2e, 0x89, 0x2f, 0x2a, 0xcd, 0x93, 0x60, 0x54, 0x60, 0xd4, 0x60, 0x0e, + 0x62, 0x07, 0xf1, 0x83, 0x4a, 0xf3, 0x92, 0xd8, 0xc0, 0x5a, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xa6, 0x71, 0x6c, 0xb7, 0x51, 0x00, 0x00, 0x00, +} diff --git a/proto/pullrequester.proto b/proto/pullrequester.proto new file mode 100644 index 000000000..3fa87eaf5 --- /dev/null +++ b/proto/pullrequester.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package pullrequester; + +message Config { + int64 last_run = 1; +} + diff --git a/pullrequester.go b/pullrequester.go new file mode 100644 index 000000000..01b3b6f00 --- /dev/null +++ b/pullrequester.go @@ -0,0 +1,114 @@ +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "time" + + "github.com/brotherlogic/goserver" + "github.com/brotherlogic/keystore/client" + "golang.org/x/net/context" + "google.golang.org/grpc" + + pbg "github.com/brotherlogic/goserver/proto" + "github.com/brotherlogic/goserver/utils" + pb "github.com/brotherlogic/pullrequester/proto" +) + +const ( + // KEY - where we store sale info + KEY = "/github.com/brotherlogic/pullrequester/config" +) + +//Server main server type +type Server struct { + *goserver.GoServer + config *pb.Config +} + +// Init builds the server +func Init() *Server { + s := &Server{ + GoServer: &goserver.GoServer{}, + config: &pb.Config{}, + } + return s +} + +func (s *Server) save(ctx context.Context) { + s.KSclient.Save(ctx, KEY, s.config) +} + +func (s *Server) load(ctx context.Context) error { + config := &pb.Config{} + data, _, err := s.KSclient.Read(ctx, KEY, config) + + if err != nil { + return err + } + + s.config = data.(*pb.Config) + return nil +} + +// DoRegister does RPC registration +func (s *Server) DoRegister(server *grpc.Server) { + // Pass +} + +// ReportHealth alerts if we're not healthy +func (s *Server) ReportHealth() bool { + return true +} + +// Shutdown the server +func (s *Server) Shutdown(ctx context.Context) error { + s.save(ctx) + return nil +} + +// Mote promotes/demotes this server +func (s *Server) Mote(ctx context.Context, master bool) error { + if master { + err := s.load(ctx) + return err + } + + return nil +} + +// GetState gets the state of the server +func (s *Server) GetState() []*pbg.State { + return []*pbg.State{ + &pbg.State{Key: "last_run", Value: s.config.LastRun}, + } +} + +func main() { + var quiet = flag.Bool("quiet", false, "Show all output") + var init = flag.Bool("init", false, "Prep server") + flag.Parse() + + //Turn off logging + if *quiet { + log.SetFlags(0) + log.SetOutput(ioutil.Discard) + } + server := Init() + server.GoServer.KSclient = *keystoreclient.GetClient(server.DialMaster) + server.PrepServer() + server.Register = server + server.RegisterServer("pullrequester", false) + + if *init { + ctx, cancel := utils.BuildContext("pullrequester", "pullrequester") + defer cancel() + server.config.LastRun = time.Now().Unix() + server.save(ctx) + return + } + + fmt.Printf("%v", server.Serve()) +} diff --git a/pullrequesterutils.go b/pullrequesterutils.go new file mode 100644 index 000000000..25bc368ce --- /dev/null +++ b/pullrequesterutils.go @@ -0,0 +1,4 @@ +package main + +func doNothing() { +} diff --git a/pullrequesterutils_test.go b/pullrequesterutils_test.go new file mode 100644 index 000000000..4a48905c1 --- /dev/null +++ b/pullrequesterutils_test.go @@ -0,0 +1,7 @@ +package main + +import "testing" + +func TestBasic(t *testing.T) { + doNothing() +}