<commit_before>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"net/http"

	"github.com/techjanitor/pram-libs/auth"
	"github.com/techjanitor/pram-libs/config"
	"github.com/techjanitor/pram-libs/cors"
	"github.com/techjanitor/pram-libs/db"
	"github.com/techjanitor/pram-libs/validate"

	local "github.com/techjanitor/pram-post/config"
	c "github.com/techjanitor/pram-post/controllers"
	m "github.com/techjanitor/pram-post/middleware"
	u "github.com/techjanitor/pram-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	dbase := db.Database{
		// Database connection settings
		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// Set up Redis connection
	u.NewRedisCache()

	// set auth middleware secret
	auth.Secret = local.Settings.Session.Secret

	// set cors domains
	cors.Domains = local.Settings.CORS.Sites

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(auth.Auth(auth.All))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(auth.Auth(auth.Registered))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	// requires mod perms
	mod := r.Group("/mod")
	mod.Use(validate.ValidateParams())
	mod.Use(auth.Auth(auth.Moderators))

	mod.DELETE("/tag/:id", c.DeleteTagController)
	mod.DELETE("/imagetag/:image/:tag", c.DeleteImageTagController)
	mod.DELETE("/thread/:id", c.DeleteThreadController)
	mod.DELETE("/post/:thread/:id", c.DeletePostController)
	mod.POST("/sticky/:thread", c.StickyThreadController)
	mod.POST("/close/:thread", c.CloseThreadController)

	// requires admin perms
	admin := r.Group("/admin")
	admin.Use(validate.ValidateParams())
	admin.Use(auth.Auth(auth.Admins))

	admin.DELETE("/thread/:id", c.PurgeThreadController)
	admin.DELETE("/post/:thread/:id", c.PurgePostController)
	//admin.POST("/ban/:ip", c.BanIpController)
	//admin.DELETE("/flushcache", c.DeleteCacheController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v\n\n", "Information")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<commit_msg>enhance print config<commit_after>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"

	"github.com/techjanitor/pram-libs/auth"
	"github.com/techjanitor/pram-libs/config"
	"github.com/techjanitor/pram-libs/cors"
	"github.com/techjanitor/pram-libs/db"
	"github.com/techjanitor/pram-libs/validate"

	local "github.com/techjanitor/pram-post/config"
	c "github.com/techjanitor/pram-post/controllers"
	m "github.com/techjanitor/pram-post/middleware"
	u "github.com/techjanitor/pram-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	dbase := db.Database{
		// Database connection settings
		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// Set up Redis connection
	u.NewRedisCache()

	// set auth middleware secret
	auth.Secret = local.Settings.Session.Secret

	// set cors domains
	cors.Domains = local.Settings.CORS.Sites

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(auth.Auth(auth.All))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(auth.Auth(auth.Registered))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	// requires mod perms
	mod := r.Group("/mod")
	mod.Use(validate.ValidateParams())
	mod.Use(auth.Auth(auth.Moderators))

	mod.DELETE("/tag/:id", c.DeleteTagController)
	mod.DELETE("/imagetag/:image/:tag", c.DeleteImageTagController)
	mod.DELETE("/thread/:id", c.DeleteThreadController)
	mod.DELETE("/post/:thread/:id", c.DeletePostController)
	mod.POST("/sticky/:thread", c.StickyThreadController)
	mod.POST("/close/:thread", c.CloseThreadController)

	// requires admin perms
	admin := r.Group("/admin")
	admin.Use(validate.ValidateParams())
	admin.Use(auth.Auth(auth.Admins))

	admin.DELETE("/thread/:id", c.PurgeThreadController)
	admin.DELETE("/post/:thread/:id", c.PurgePostController)
	//admin.POST("/ban/:ip", c.BanIpController)
	//admin.DELETE("/flushcache", c.DeleteCacheController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v\n\n", "Information")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net"
	"net/url"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/belogik/goes"
)

var (
	interval    = flag.String("interval", "5m", "Reporting interval")
	index       = flag.String("index", "euronas", "Elasticsearch index to write to")
	es_type     = flag.String("type", "euronas", "Elasticsearch type to use")
	destination = flag.String("destination", "localhost:9200", "Output destination")
	cli_path    = flag.String("cli", "/opt/MegaRAID/MegaCli/MegaCli64", "Location of the MegaCli binary")
	matcher     = regexp.MustCompile(`^(Slot Number|Inquiry Data|Media Error Count|Other Error Count|Firmware state|Drive has flagged a S.M.A.R.T alert ):`)
)

type SlotStatus struct {
	Number          int
	MediaErrorCount int
	OtherErrorCount int
	SerialNumber    string
	ModelNumber     string
	FirmwareVersion string
	SmartAlert      bool
	State           string
}

func (s *SlotStatus) SplitInquiryData(inquiry string) {
	fields := strings.Fields(strings.Split(inquiry, ":")[1])
	s.SerialNumber = fields[0]
	s.ModelNumber = fields[1]
	s.FirmwareVersion = fields[2]
}

func (s *SlotStatus) Document() goes.Document {
	return goes.Document{
		Index: *index,
		Type:  *es_type,
		Fields: map[string]interface{}{
			"@timestamp":        time.Now(),
			"slot_number":       s.Number,
			"media_error_count": s.MediaErrorCount,
			"other_error_count": s.OtherErrorCount,
			"serial_number":     s.SerialNumber,
			"model_number":      s.ModelNumber,
			"firmware_version":  s.FirmwareVersion,
			"smart_alert":       s.SmartAlert,
			"state":             s.State,
		},
	}
}

func SplitFieldValue(s string) (string, string) {
	splits := strings.Split(s, ":")
	return strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1])
}

func FormatNumber(value string) int {
	number, err := strconv.Atoi(value)

	if err != nil {
		log.Fatalf("Parsing Slot Number failed: %v", err)
	}

	return number
}

func main() {
	flag.Parse()

	host, port, err := net.SplitHostPort(*destination)

	if err != nil {
		log.Fatalf("Error parsing destination: %v", err)
	}

	es := goes.NewConnection(host, port)

	d, err := time.ParseDuration(*interval)

	if err != nil {
		log.Fatalf("Error parsing interval: %v", err)
	}

	for {
		out, err := exec.Command(*cli_path, "-PDList", "-a0").Output()
		if err != nil {
			log.Fatalf("Running LSI command failed: %v", err)
		}

		var (
			slots []SlotStatus
			slot  SlotStatus
		)

		for _, l := range regexp.MustCompile("\r?\n").Split(string(out), -1) {
			if !matcher.Match([]byte(l)) {
				continue
			}

			field, value := SplitFieldValue(l)

			switch field {
			case "Slot Number":
				number := FormatNumber(value)

				if number > 0 {
					slots = append(slots, slot)
				}
				slot = SlotStatus{Number: number}
			case "Inquiry Data":
				slot.SplitInquiryData(l)
			case "Media Error Count":
				number := FormatNumber(value)
				slot.MediaErrorCount = number
			case "Other Error Count":
				number := FormatNumber(value)
				slot.OtherErrorCount = number
			case "Firmware state":
				slot.State = value
			case "Drive has flagged a S.M.A.R.T alert":
				if value == "No" {
					slot.SmartAlert = false
				} else {
					slot.SmartAlert = true
				}

			}
		}

		for _, s := range slots {
			_, err = es.Index(s.Document(), url.Values{})

			if err != nil {
				log.Fatalf("Error indexing results: %s", err)
			}
		}

		log.Printf("Done indexing. Sleeping for %s", *interval)
		time.Sleep(d)
	}
}
<commit_msg>Don't skip last slot, fix model numbers with spaces<commit_after>package main

import (
	"flag"
	"log"
	"net"
	"net/url"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/belogik/goes"
)

var (
	interval    = flag.String("interval", "5m", "Reporting interval")
	index       = flag.String("index", "euronas", "Elasticsearch index to write to")
	es_type     = flag.String("type", "euronas", "Elasticsearch type to use")
	destination = flag.String("destination", "localhost:9200", "Output destination")
	cli_path    = flag.String("cli", "/opt/MegaRAID/MegaCli/MegaCli64", "Location of the MegaCli binary")
	matcher     = regexp.MustCompile(`^(Slot Number|Inquiry Data|Media Error Count|Other Error Count|Firmware state|Drive has flagged a S.M.A.R.T alert ):`)
)

type SlotStatus struct {
	Number          int
	MediaErrorCount int
	OtherErrorCount int
	SerialNumber    string
	ModelNumber     string
	FirmwareVersion string
	SmartAlert      bool
	State           string
}

func (s *SlotStatus) SplitInquiryData(inquiry string) {
	data := strings.Split(inquiry, ":")[1]
	fields := strings.Fields(data)
	s.SerialNumber = fields[0]
	s.FirmwareVersion = fields[len(fields)-1]
	s.ModelNumber = strings.TrimSpace(
		strings.Replace(strings.Replace(data, s.SerialNumber, "", -1),
			s.FirmwareVersion, "", -1))
}

func (s *SlotStatus) Document() goes.Document {
	return goes.Document{
		Index: *index,
		Type:  *es_type,
		Fields: map[string]interface{}{
			"@timestamp":        time.Now(),
			"slot_number":       s.Number,
			"media_error_count": s.MediaErrorCount,
			"other_error_count": s.OtherErrorCount,
			"serial_number":     s.SerialNumber,
			"model_number":      s.ModelNumber,
			"firmware_version":  s.FirmwareVersion,
			"smart_alert":       s.SmartAlert,
			"state":             s.State,
		},
	}
}

func SplitFieldValue(s string) (string, string) {
	splits := strings.Split(s, ":")
	return strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1])
}

func FormatNumber(value string) int {
	number, err := strconv.Atoi(value)

	if err != nil {
		log.Fatalf("Parsing Slot Number failed: %v", err)
	}

	return number
}

func main() {
	flag.Parse()

	host, port, err := net.SplitHostPort(*destination)

	if err != nil {
		log.Fatalf("Error parsing destination: %v", err)
	}

	es := goes.NewConnection(host, port)

	d, err := time.ParseDuration(*interval)

	if err != nil {
		log.Fatalf("Error parsing interval: %v", err)
	}

	for {
		out, err := exec.Command(*cli_path, "-PDList", "-a0").Output()
		if err != nil {
			log.Fatalf("Running LSI command failed: %v", err)
		}

		var (
			slots []SlotStatus
			slot  SlotStatus
		)

		for _, l := range regexp.MustCompile("\r?\n").Split(string(out), -1) {
			if !matcher.Match([]byte(l)) {
				continue
			}

			field, value := SplitFieldValue(l)

			switch field {
			case "Slot Number":
				number := FormatNumber(value)

				if number > 0 {
					slots = append(slots, slot)
				}
				slot = SlotStatus{Number: number}
			case "Inquiry Data":
				slot.SplitInquiryData(l)
			case "Media Error Count":
				number := FormatNumber(value)
				slot.MediaErrorCount = number
			case "Other Error Count":
				number := FormatNumber(value)
				slot.OtherErrorCount = number
			case "Firmware state":
				slot.State = value
			case "Drive has flagged a S.M.A.R.T alert":
				if value == "No" {
					slot.SmartAlert = false
				} else {
					slot.SmartAlert = true
				}

			}
		}

		// Append last slot
		slots = append(slots, slot)

		for _, s := range slots {
			_, err = es.Index(s.Document(), url.Values{})

			if err != nil {
				log.Fatalf("Error indexing results: %s", err)
			}
		}

		log.Printf("Done indexing. Sleeping for %s", *interval)
		time.Sleep(d)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"time"

	"github.com/boltdb/bolt"
	"github.com/zenazn/goji"

	"github.com/csaunders/giftd/gifs"
)

const gifsDatabase string = "giftd.db"
const gifsConfigDb string = "giftd-config.db"

var permissions map[string]string = map[string]string{
	`/gifs/[a-z]+/random`:             "public",
	`/gifs/.{8}-.{4}-.{4}-.{4}-.{12}`: "public",
	`/gifs.*`:                         "gifs-api",
}

func dbConnect(name string) *bolt.DB {
	db, err := bolt.Open(name, 0600, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		log.Fatal(err)
	}
	return db
}

func setupPermissionsDb() {
	db := dbConnect(gifsConfigDb)
	defer db.Close()
	for path, scope := range permissions {
		err := setPermissions(db, path, scope)
		if err != nil {
			log.Fatal(err)
		}
	}
	hasAdminToken, err := HasAdministratorToken(db)
	if err != nil {
		log.Fatal("has admin token:", err)
	}

	if !hasAdminToken {
		opts := TokenOptions{Permissions: "admin"}
		token, err := GenerateToken(db, opts)
		if err != nil {
			log.Fatal("generate token:", err)
		}
		fmt.Println("Administrator API Token:", token)
	}
}

func main() {
	setupPermissionsDb()
	db := dbConnect("giftd.db")
	defer db.Close()

	if err := gifs.Register("/gifs", db); err != nil {
		log.Fatal(err)
	}

	goji.Use(APIAccessManagement)
	goji.Serve()
}
<commit_msg>data dir command line support<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/boltdb/bolt"
	"github.com/zenazn/goji"

	"github.com/csaunders/giftd/gifs"
)

const gifsDatabase string = "giftd.db"
const gifsConfigDb string = "giftd-config.db"

var permissions map[string]string = map[string]string{
	`/gifs/[a-z]+/random`:             "public",
	`/gifs/.{8}-.{4}-.{4}-.{4}-.{12}`: "public",
	`/gifs.*`:                         "gifs-api",
}

func dbConnect(name string) *bolt.DB {
	db, err := bolt.Open(name, 0600, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		log.Fatal(err)
	}
	return db
}

func initialize() error {
	var dataDir string
	flag.StringVar(&dataDir, "datadir", "/var/lib/giftd", "Location where giftd data should be stored")
	flag.Parse()

	return os.Chdir(dataDir)
}

func setupPermissionsDb() {
	db := dbConnect(gifsConfigDb)
	defer db.Close()
	for path, scope := range permissions {
		err := setPermissions(db, path, scope)
		if err != nil {
			log.Fatal(err)
		}
	}
	hasAdminToken, err := HasAdministratorToken(db)
	if err != nil {
		log.Fatal("has admin token:", err)
	}

	if !hasAdminToken {
		opts := TokenOptions{Permissions: "admin"}
		token, err := GenerateToken(db, opts)
		if err != nil {
			log.Fatal("generate token:", err)
		}
		fmt.Println("Administrator API Token:", token)
	}
}

func main() {
	if err := initialize(); err != nil {
		log.Fatal(err)
	}
	setupPermissionsDb()
	db := dbConnect("giftd.db")
	defer db.Close()

	if err := gifs.Register("/gifs", db); err != nil {
		log.Fatal(err)
	}

	goji.Use(APIAccessManagement)
	goji.Serve()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/gophergala/go_report/check"
	"gopkg.in/mgo.v2"
	"labix.org/v2/mgo/bson"
)

var (
	mongoURL        = "mongodb://localhost:27017"
	mongoDatabase   = "goreportcard"
	mongoCollection = "reports"
)

func getMongoCollection() (*mgo.Collection, error) {
	session, err := mgo.Dial(mongoURL)
	if err != nil {
		return nil, err
	}
	c := session.DB(mongoDatabase).C(mongoCollection)
	return c, nil
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Serving home page")
	if r.URL.Path[1:] == "" {
		http.ServeFile(w, r, "templates/home.html")
	} else {
		http.NotFound(w, r)
	}
}

func assetsHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Serving " + r.URL.Path[1:])
	http.ServeFile(w, r, r.URL.Path[1:])
}

func orgRepoNames(url string) (string, string) {
	dir := strings.TrimSuffix(url, ".git")
	split := strings.Split(dir, "/")
	org := split[len(split)-2]
	repoName := split[len(split)-1]

	return org, repoName
}

func dirName(url string) string {
	org, repoName := orgRepoNames(url)

	return fmt.Sprintf("repos/src/github.com/%s/%s", org, repoName)
}

func clone(url string) error {
	org, _ := orgRepoNames(url)
	if err := os.Mkdir(fmt.Sprintf("repos/src/github.com/%s", org), 0755); err != nil && !os.IsExist(err) {
		return fmt.Errorf("could not create dir: %v", err)
	}
	dir := dirName(url)
	_, err := os.Stat(dir)
	if os.IsNotExist(err) {
		cmd := exec.Command("git", "clone", "--depth", "1", "--single-branch", url, dir)
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("could not run git clone: %v", err)
		}
	} else if err != nil {
		return fmt.Errorf("could not stat dir: %v", err)
	} else {
		cmd := exec.Command("git", "-C", dir, "pull")
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("could not pull repo: %v", err)
		}
	}

	return nil
}

type score struct {
	Name          string              `json:"name"`
	Description   string              `json:"description"`
	FileSummaries []check.FileSummary `json:"file_summaries"`
	Percentage    float64             `json:"percentage"`
}

type checksResp struct {
	Checks      []score   `json:"checks"`
	Average     float64   `json:"average"`
	Files       int       `json:"files"`
	Issues      int       `json:"issues"`
	Repo        string    `json:"repo"`
	LastRefresh time.Time `json:"last_refresh"`
}

func checkHandler(w http.ResponseWriter, r *http.Request) {
	repo := r.FormValue("repo")
	url := repo
	if !strings.HasPrefix(url, "https://github.com/") {
		url = "https://github.com/" + url
	}

	w.Header().Set("Content-Type", "application/json")

	// if this is a GET request, fetch from cached version in mongo
	if r.Method == "GET" {
		// try and fetch from mongo
		coll, err := getMongoCollection()
		if err != nil {
			log.Println("Failed to get mongo collection during GET: ", err)
		} else {
			resp := checksResp{}
			err := coll.Find(bson.M{"repo": repo}).One(&resp)
			if err != nil {
				log.Printf("Failed to fetch %q from mongo: %v", repo, err)
			} else {
				resp.LastRefresh = resp.LastRefresh.UTC()
				b, err := json.Marshal(resp)
				if err != nil {
					log.Println("ERROR: could not marshal json:", err)
					http.Error(w, err.Error(), 500)
					return
				}
				w.Write(b)
				log.Println("Loaded from cache!", repo)
				return
			}
		}
	}

	err := clone(url)
	if err != nil {
		log.Println("ERROR: could not clone repo: ", err)
		http.Error(w, fmt.Sprintf("Could not clone repo: %v", err), 500)
		return
	}

	dir := dirName(url)
	filenames, err := check.GoFiles(dir)
	if err != nil {
		log.Println("ERROR: could not get filenames: ", err)
		http.Error(w, fmt.Sprintf("Could not get filenames: %v", err), 500)
		return
	}
	checks := []check.Check{check.GoFmt{Dir: dir, Filenames: filenames},
		check.GoVet{Dir: dir, Filenames: filenames},
		check.GoLint{Dir: dir, Filenames: filenames},
		check.GoCyclo{Dir: dir, Filenames: filenames},
	}

	ch := make(chan score)
	for _, c := range checks {
		go func(c check.Check) {
			p, summaries, err := c.Percentage()
			if err != nil {
				log.Printf("ERROR: (%s) %v", c.Name(), err)
			}
			s := score{
				Name:          c.Name(),
				Description:   c.Description(),
				FileSummaries: summaries,
				Percentage:    p,
			}
			ch <- s
		}(c)
	}

	resp := checksResp{Repo: repo,
		Files:       len(filenames),
		LastRefresh: time.Now().UTC()}
	var avg float64
	var issues = make(map[string]bool)
	for i := 0; i < len(checks); i++ {
		s := <-ch
		resp.Checks = append(resp.Checks, s)
		avg += s.Percentage
		for _, fs := range s.FileSummaries {
			issues[fs.Filename] = true
		}
	}

	resp.Average = avg / float64(len(checks))
	resp.Issues = len(issues)

	b, err := json.Marshal(resp)
	if err != nil {
		log.Println("ERROR: could not marshal json:", err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.Write(b)

	// write to mongo
	coll, err := getMongoCollection()
	if err != nil {
		log.Println("Failed to get mongo collection: ", err)
	} else {
		log.Println("Writing to mongo...")
		_, err := coll.Upsert(bson.M{"Repo": repo}, resp)
		if err != nil {
			log.Println("Mongo writing error:", err)
		}
	}
}

func reportHandler(w http.ResponseWriter, r *http.Request, org, repo string) {
	http.ServeFile(w, r, "templates/home.html")
}

func makeReportHandler(fn func(http.ResponseWriter, *http.Request, string, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		validPath := regexp.MustCompile(`^/report/([a-zA-Z0-9\-_]+)/([a-zA-Z0-9\-_]+)$`)

		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[1], m[2])
	}
}

func main() {
	if err := os.MkdirAll("repos/src/github.com", 0755); err != nil && !os.IsExist(err) {
		log.Fatal("ERROR: could not create repos dir: ", err)
	}

	http.HandleFunc("/assets/", assetsHandler)
	http.HandleFunc("/checks", checkHandler)
	http.HandleFunc("/report/", makeReportHandler(reportHandler))
	http.HandleFunc("/", homeHandler)

	fmt.Println("Running on 127.0.01:8080...")
	log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
}
<commit_msg>split get from cache logic into separate function<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/gophergala/go_report/check"
	"gopkg.in/mgo.v2"
	"labix.org/v2/mgo/bson"
)

var (
	mongoURL        = "mongodb://localhost:27017"
	mongoDatabase   = "goreportcard"
	mongoCollection = "reports"
)

func getMongoCollection() (*mgo.Collection, error) {
	session, err := mgo.Dial(mongoURL)
	if err != nil {
		return nil, err
	}
	c := session.DB(mongoDatabase).C(mongoCollection)
	return c, nil
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Serving home page")
	if r.URL.Path[1:] == "" {
		http.ServeFile(w, r, "templates/home.html")
	} else {
		http.NotFound(w, r)
	}
}

func assetsHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Serving " + r.URL.Path[1:])
	http.ServeFile(w, r, r.URL.Path[1:])
}

func orgRepoNames(url string) (string, string) {
	dir := strings.TrimSuffix(url, ".git")
	split := strings.Split(dir, "/")
	org := split[len(split)-2]
	repoName := split[len(split)-1]

	return org, repoName
}

func dirName(url string) string {
	org, repoName := orgRepoNames(url)

	return fmt.Sprintf("repos/src/github.com/%s/%s", org, repoName)
}

func clone(url string) error {
	org, _ := orgRepoNames(url)
	if err := os.Mkdir(fmt.Sprintf("repos/src/github.com/%s", org), 0755); err != nil && !os.IsExist(err) {
		return fmt.Errorf("could not create dir: %v", err)
	}
	dir := dirName(url)
	_, err := os.Stat(dir)
	if os.IsNotExist(err) {
		cmd := exec.Command("git", "clone", "--depth", "1", "--single-branch", url, dir)
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("could not run git clone: %v", err)
		}
	} else if err != nil {
		return fmt.Errorf("could not stat dir: %v", err)
	} else {
		cmd := exec.Command("git", "-C", dir, "pull")
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("could not pull repo: %v", err)
		}
	}

	return nil
}

type score struct {
	Name          string              `json:"name"`
	Description   string              `json:"description"`
	FileSummaries []check.FileSummary `json:"file_summaries"`
	Percentage    float64             `json:"percentage"`
}

type checksResp struct {
	Checks      []score   `json:"checks"`
	Average     float64   `json:"average"`
	Files       int       `json:"files"`
	Issues      int       `json:"issues"`
	Repo        string    `json:"repo"`
	LastRefresh time.Time `json:"last_refresh"`
}

func getFromCache(repo string) (checksResp, error) {
	// try and fetch from mongo
	coll, err := getMongoCollection()
	if err != nil {
		return checksResp{}, fmt.Errorf("Failed to get mongo collection during GET: %v", err)
	}
	resp := checksResp{}
	err = coll.Find(bson.M{"repo": repo}).One(&resp)
	if err != nil {
		return checksResp{}, fmt.Errorf("Failed to fetch %q from mongo: %v", repo, err)
	}

	resp.LastRefresh = resp.LastRefresh.UTC()

	return resp, nil
}

func checkHandler(w http.ResponseWriter, r *http.Request) {
	repo := r.FormValue("repo")
	url := repo
	if !strings.HasPrefix(url, "https://github.com/") {
		url = "https://github.com/" + url
	}

	w.Header().Set("Content-Type", "application/json")

	// if this is a GET request, fetch from cached version in mongo
	if r.Method == "GET" {
		resp, err := getFromCache(repo)
		if err != nil {
			// just log the error and continue
			log.Println(err)
		} else {
			b, err := json.Marshal(resp)
			if err != nil {
				log.Println("ERROR: could not marshal json:", err)
				http.Error(w, err.Error(), 500)
				return
			}
			w.Write(b)
			log.Println("Loaded from cache!", repo)
			return
		}
	}

	err := clone(url)
	if err != nil {
		log.Println("ERROR: could not clone repo: ", err)
		http.Error(w, fmt.Sprintf("Could not clone repo: %v", err), 500)
		return
	}

	dir := dirName(url)
	filenames, err := check.GoFiles(dir)
	if err != nil {
		log.Println("ERROR: could not get filenames: ", err)
		http.Error(w, fmt.Sprintf("Could not get filenames: %v", err), 500)
		return
	}
	checks := []check.Check{check.GoFmt{Dir: dir, Filenames: filenames},
		check.GoVet{Dir: dir, Filenames: filenames},
		check.GoLint{Dir: dir, Filenames: filenames},
		check.GoCyclo{Dir: dir, Filenames: filenames},
	}

	ch := make(chan score)
	for _, c := range checks {
		go func(c check.Check) {
			p, summaries, err := c.Percentage()
			if err != nil {
				log.Printf("ERROR: (%s) %v", c.Name(), err)
			}
			s := score{
				Name:          c.Name(),
				Description:   c.Description(),
				FileSummaries: summaries,
				Percentage:    p,
			}
			ch <- s
		}(c)
	}

	resp := checksResp{Repo: repo,
		Files:       len(filenames),
		LastRefresh: time.Now().UTC()}
	var avg float64
	var issues = make(map[string]bool)
	for i := 0; i < len(checks); i++ {
		s := <-ch
		resp.Checks = append(resp.Checks, s)
		avg += s.Percentage
		for _, fs := range s.FileSummaries {
			issues[fs.Filename] = true
		}
	}

	resp.Average = avg / float64(len(checks))
	resp.Issues = len(issues)

	b, err := json.Marshal(resp)
	if err != nil {
		log.Println("ERROR: could not marshal json:", err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.Write(b)

	// write to mongo
	coll, err := getMongoCollection()
	if err != nil {
		log.Println("Failed to get mongo collection: ", err)
	} else {
		log.Println("Writing to mongo...")
		_, err := coll.Upsert(bson.M{"Repo": repo}, resp)
		if err != nil {
			log.Println("Mongo writing error:", err)
		}
	}
}

func reportHandler(w http.ResponseWriter, r *http.Request, org, repo string) {
	http.ServeFile(w, r, "templates/home.html")
}

func makeReportHandler(fn func(http.ResponseWriter, *http.Request, string, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		validPath := regexp.MustCompile(`^/report/([a-zA-Z0-9\-_]+)/([a-zA-Z0-9\-_]+)$`)

		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[1], m[2])
	}
}

func main() {
	if err := os.MkdirAll("repos/src/github.com", 0755); err != nil && !os.IsExist(err) {
		log.Fatal("ERROR: could not create repos dir: ", err)
	}

	http.HandleFunc("/assets/", assetsHandler)
	http.HandleFunc("/checks", checkHandler)
	http.HandleFunc("/report/", makeReportHandler(reportHandler))
	http.HandleFunc("/", homeHandler)

	fmt.Println("Running on 127.0.01:8080...")
	log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
}
<|endoftext|>


<commit_before>// Copyright 2017 The GoReporter Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// GoReporter is a Golang tool that does static analysis, unit testing, code
// review and generate code quality report.

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/360EntSecGroup-Skylar/goreporter/engine"
	"github.com/360EntSecGroup-Skylar/goreporter/engine/processbar"
	"github.com/facebookgo/inject"
)

// Received parameters, you can control some features using:
//
// -p:Specify the relative path of your project(Must Be Relative path),
//    by default, the current path is used
// -r:Specifies the save path for the generated report,
//    by default, the current path is used
// -e:Ignored detection of packages and multiple packages separated by commas.
// -t:Customize the path of the report template, not necessarily using the
//    default report template
// -f:Set the format to generate reports, support text, html and json,not
//    necessarily using the default formate-html.

const VERSION = "3.0.0-dev"

var (
	version        = flag.Bool("version", false, "print GoReporter version.")
	projectPath    = flag.String("p", "", "path of project.")
	reportPath     = flag.String("r", "", "path of report.")
	exceptPackages = flag.String("e", "", "except packages.")
	templatePath   = flag.String("t", "", "report html template path.")
	reportFormat   = flag.String("f", "", "project report format(text/json/html).")
)

func main() {
	flag.Parse()

	if *version {
		fmt.Printf("GoReporter %s\r\n", VERSION)
		os.Exit(0)
	}

	if *projectPath == "" {
		log.Fatal("The project path is not specified")
	} else {
		_, err := os.Stat(*projectPath)
		if err != nil {
			log.Fatal("project path is invalid")
		}
	}

	var templateHtml string
	if *templatePath == "" {
		templateHtml = engine.DefaultTpl
		log.Println("The template path is not specified,and will use the default template")
	} else {
		if !strings.HasSuffix(*templatePath, ".html") {
			log.Println("The template file is not a html template")
		}
		fileData, err := ioutil.ReadFile(*templatePath)
		if err != nil {
			log.Fatal(err)
		} else {
			templateHtml = string(fileData)
		}
	}

	if *reportPath == "" {
		log.Println("The report path is not specified, and the current path is used by default")
	} else {
		_, err := os.Stat(*reportPath)
		if err != nil {
			log.Fatal("report path is invalid:", err)
		}
	}

	if *exceptPackages == "" {
		log.Println("There are no packages that are excepted, review all items of the package")
	}

	synchronizer := &engine.Synchronizer{
		LintersProcessChans:   make(chan int64, 20),
		LintersFinishedSignal: make(chan string, 10),
	}
	syncRW := &sync.RWMutex{}
	waitGW := &engine.WaitGroupWrapper{}

	reporter := engine.NewReporter(*projectPath, *reportPath, *reportFormat, templateHtml)
	strategyCountCode := &engine.StrategyCountCode{}
	strategyCyclo := &engine.StrategyCyclo{}
	strategyDeadCode := &engine.StrategyDeadCode{}
	strategyDependGraph := &engine.StrategyDependGraph{}
	strategyDepth := &engine.StrategyDepth{}
	strategyImportPackages := &engine.StrategyImportPackages{}
	strategyInterfacer := &engine.StrategyInterfacer{}
	strategySimpleCode := &engine.StrategySimpleCode{}
	strategySpellCheck := &engine.StrategySpellCheck{}
	strategyUnitTest := &engine.StrategyUnitTest{}
	strategyLint := &engine.StrategyLint{}
	strategyGoVet := &engine.StrategyGoVet{}
	strategyGoFmt := &engine.StrategyGoFmt{}

	if err := inject.Populate(
		reporter,
		synchronizer,
		strategyCountCode,
		strategyCyclo,
		strategyDeadCode,
		strategyDependGraph,
		strategyDepth,
		strategyImportPackages,
		strategyInterfacer,
		strategySimpleCode,
		strategySpellCheck,
		strategyUnitTest,
		strategyLint,
		strategyGoVet,
		strategyGoFmt,
		syncRW,
		waitGW,
	); err != nil {
		log.Fatal(err)
	}

	reporter.AddLinters(strategyCountCode, strategyCyclo, strategyDeadCode, strategyDependGraph,
		strategyDepth, strategyImportPackages, strategyInterfacer, strategySimpleCode,
		strategySpellCheck, strategyUnitTest, strategyLint, strategyGoVet, strategyGoFmt)

	go processbar.LinterProcessBar(synchronizer.LintersProcessChans, synchronizer.LintersFinishedSignal)

	if err := reporter.Report(); err != nil {
		log.Fatal(err)
	}

	if err := reporter.Render(); err != nil {
		log.Fatal(err)
	}

	log.Println(fmt.Sprintf("GoReporter Finished,time consuming %vs", time.Since(reporter.StartTime).Seconds()))
}
<commit_msg>-Fix goreporter version<commit_after>// Copyright 2017 The GoReporter Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// GoReporter is a Golang tool that does static analysis, unit testing, code
// review and generate code quality report.

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/360EntSecGroup-Skylar/goreporter/engine"
	"github.com/360EntSecGroup-Skylar/goreporter/engine/processbar"
	"github.com/facebookgo/inject"
)

// Received parameters, you can control some features using:
//
// -p:Specify the relative path of your project(Must Be Relative path),
//    by default, the current path is used
// -r:Specifies the save path for the generated report,
//    by default, the current path is used
// -e:Ignored detection of packages and multiple packages separated by commas.
// -t:Customize the path of the report template, not necessarily using the
//    default report template
// -f:Set the format to generate reports, support text, html and json,not
//    necessarily using the default formate-html.

const VERSION = "v3.0.0"

var (
	version        = flag.Bool("version", false, "print GoReporter version.")
	projectPath    = flag.String("p", "", "path of project.")
	reportPath     = flag.String("r", "", "path of report.")
	exceptPackages = flag.String("e", "", "except packages.")
	templatePath   = flag.String("t", "", "report html template path.")
	reportFormat   = flag.String("f", "", "project report format(text/json/html).")
)

func main() {
	flag.Parse()

	if *version {
		fmt.Printf("GoReporter %s\r\n", VERSION)
		os.Exit(0)
	}

	if *projectPath == "" {
		log.Fatal("The project path is not specified")
	} else {
		_, err := os.Stat(*projectPath)
		if err != nil {
			log.Fatal("project path is invalid")
		}
	}

	var templateHtml string
	if *templatePath == "" {
		templateHtml = engine.DefaultTpl
		log.Println("The template path is not specified,and will use the default template")
	} else {
		if !strings.HasSuffix(*templatePath, ".html") {
			log.Println("The template file is not a html template")
		}
		fileData, err := ioutil.ReadFile(*templatePath)
		if err != nil {
			log.Fatal(err)
		} else {
			templateHtml = string(fileData)
		}
	}

	if *reportPath == "" {
		log.Println("The report path is not specified, and the current path is used by default")
	} else {
		_, err := os.Stat(*reportPath)
		if err != nil {
			log.Fatal("report path is invalid:", err)
		}
	}

	if *exceptPackages == "" {
		log.Println("There are no packages that are excepted, review all items of the package")
	}

	synchronizer := &engine.Synchronizer{
		LintersProcessChans:   make(chan int64, 20),
		LintersFinishedSignal: make(chan string, 10),
	}
	syncRW := &sync.RWMutex{}
	waitGW := &engine.WaitGroupWrapper{}

	reporter := engine.NewReporter(*projectPath, *reportPath, *reportFormat, templateHtml)
	strategyCountCode := &engine.StrategyCountCode{}
	strategyCyclo := &engine.StrategyCyclo{}
	strategyDeadCode := &engine.StrategyDeadCode{}
	strategyDependGraph := &engine.StrategyDependGraph{}
	strategyDepth := &engine.StrategyDepth{}
	strategyImportPackages := &engine.StrategyImportPackages{}
	strategyInterfacer := &engine.StrategyInterfacer{}
	strategySimpleCode := &engine.StrategySimpleCode{}
	strategySpellCheck := &engine.StrategySpellCheck{}
	strategyUnitTest := &engine.StrategyUnitTest{}
	strategyLint := &engine.StrategyLint{}
	strategyGoVet := &engine.StrategyGoVet{}
	strategyGoFmt := &engine.StrategyGoFmt{}

	if err := inject.Populate(
		reporter,
		synchronizer,
		strategyCountCode,
		strategyCyclo,
		strategyDeadCode,
		strategyDependGraph,
		strategyDepth,
		strategyImportPackages,
		strategyInterfacer,
		strategySimpleCode,
		strategySpellCheck,
		strategyUnitTest,
		strategyLint,
		strategyGoVet,
		strategyGoFmt,
		syncRW,
		waitGW,
	); err != nil {
		log.Fatal(err)
	}

	reporter.AddLinters(strategyCountCode, strategyCyclo, strategyDeadCode, strategyDependGraph,
		strategyDepth, strategyImportPackages, strategyInterfacer, strategySimpleCode,
		strategySpellCheck, strategyUnitTest, strategyLint, strategyGoVet, strategyGoFmt)

	go processbar.LinterProcessBar(synchronizer.LintersProcessChans, synchronizer.LintersFinishedSignal)

	if err := reporter.Report(); err != nil {
		log.Fatal(err)
	}

	if err := reporter.Render(); err != nil {
		log.Fatal(err)
	}

	log.Println(fmt.Sprintf("GoReporter Finished,time consuming %vs", time.Since(reporter.StartTime).Seconds()))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/zorkian/go-datadog-api"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"path/filepath"
	"strconv"
	"time"
)

var gitHash = "No hash provided"
var buildTime = "No build time provided"

var apiKey = flag.String("api-key", "", "Datadog api key")
var appKey = flag.String("app-key", "", "Datadog app key")
var logIntervalInSeconds = flag.Int64("interval", 10, "Log interval in seconds.")
var configDirPath string

func init() {
	const (
		helpUsage = "Directory to metric files."
	)
	flag.StringVar(&configDirPath, "config-dir", "./metrics.d", helpUsage)
	flag.StringVar(&configDirPath, "c", "./metrics.d", helpUsage+" (shorthand)")
}

type metric struct {
	Name  string
	Value string
	Tags  []string
}

func main() {
	flag.Parse()

	log.Println("Git Commit Hash: ", gitHash)
	log.Println("UTC Build Time : ", buildTime)
	log.Println("Using API KEY ", *apiKey)
	log.Println("Using APP KEY ", *appKey)

	configuredMetrics := readMetricsFromFiles()
	datadogClient := datadog.NewClient(*apiKey, *appKey)

	ddmetrics := createDDMetrics(configuredMetrics)
	for {
		updateTimstampInDDMetrics(ddmetrics)
		postMetrics(datadogClient, ddmetrics)
		time.Sleep(time.Duration(*logIntervalInSeconds) * time.Second)
	}

}

func readMetricsFromFiles() []metric {
	log.Println("Parsing files from directory ", configDirPath)
	configDir, _ := filepath.Abs(configDirPath)
	files, err := ioutil.ReadDir(configDir)
	if err != nil {
		log.Fatalln("Dir [", configDirPath, "] not found: ", err)
	}
	configuredMetrics := []metric{}
	for _, file := range files {
		fileMetrics := []metric{}
		filePath := fmt.Sprintf("%s/%s", configDir, file.Name())
		fileContent, _ := ioutil.ReadFile(filePath)
		if err := yaml.Unmarshal(fileContent, &fileMetrics); err != nil {
			log.Fatalln("Unmarshalling error in ", filePath, ": ", err)
		}
		configuredMetrics = append(configuredMetrics, fileMetrics...)
	}
	return configuredMetrics
}

func updateTimstampInDDMetrics(ddmetrics []datadog.Metric) {
	timestamp := time.Now().Unix()
	for _, metric := range ddmetrics {
		for i := range metric.Points {
			metric.Points[i][0] = float64(timestamp)
		}
	}
}

func createDDMetrics(configuredMetrics []metric) []datadog.Metric {
	ddmetrics := []datadog.Metric{}
	timestamp := time.Now().Unix()
	for _, metric := range configuredMetrics {
		value, _ := strconv.ParseFloat(metric.Value, 64)
		ddmetric := datadog.Metric{
			Metric: metric.Name,
			Points: []datadog.DataPoint{
				{float64(timestamp), value},
			},
			Tags: metric.Tags,
		}
		ddmetrics = append(ddmetrics, ddmetric)
		createdMetric := fmt.Sprintf("%#v", ddmetric)
		log.Println("Will report the following metric: ", createdMetric)
	}
	return ddmetrics
}

func postMetrics(datadogClient *datadog.Client, metrics []datadog.Metric) {
	log.Println("Updating", len(metrics), "metrics.")
	if err := datadogClient.PostMetrics(metrics); err != nil {
		log.Println("ERROR: Cannot log to datadog: ", err)
	}
}
<commit_msg>some formatting<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/zorkian/go-datadog-api"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"path/filepath"
	"strconv"
	"time"
)

var gitHash = "No hash provided"
var buildTime = "No build time provided"

var apiKey = flag.String("api-key", "", "Datadog api key")
var appKey = flag.String("app-key", "", "Datadog app key")
var logIntervalInSeconds = flag.Int64("interval", 10, "Log interval in seconds.")
var configDirPath string

func init() {
	const (
		helpUsage = "Directory to metric files."
	)
	flag.StringVar(&configDirPath, "config-dir", "./metrics.d", helpUsage)
	flag.StringVar(&configDirPath, "c", "./metrics.d", helpUsage+" (shorthand)")
}

type metric struct {
	Name  string
	Value string
	Tags  []string
}

func main() {
	flag.Parse()

	log.Println("")
	log.Println("----------------------------------------------------------------")
	log.Println("datadog-metrics-tuner")
	log.Println("")
	log.Println("Git Commit Hash: \t", gitHash)
	log.Println("UTC Build Time: \t", buildTime)
	log.Println("Using API KEY: \t", *apiKey)
	log.Println("Using APP KEY: \t", *appKey)
	log.Println("----------------------------------------------------------------")
	log.Println("")

	configuredMetrics := readMetricsFromFiles()
	datadogClient := datadog.NewClient(*apiKey, *appKey)

	ddmetrics := createDDMetrics(configuredMetrics)
	for {
		updateTimstampInDDMetrics(ddmetrics)
		postMetrics(datadogClient, ddmetrics)
		time.Sleep(time.Duration(*logIntervalInSeconds) * time.Second)
	}

}

func readMetricsFromFiles() []metric {
	configDir, _ := filepath.Abs(configDirPath)
	log.Println("Parsing files from directory ", configDir)
	files, err := ioutil.ReadDir(configDir)
	if err != nil {
		log.Fatalln("Dir [", configDirPath, "] not found: ", err)
	}
	configuredMetrics := []metric{}
	for _, file := range files {
		fileMetrics := []metric{}
		filePath := fmt.Sprintf("%s/%s", configDir, file.Name())
		fileContent, _ := ioutil.ReadFile(filePath)
		if err := yaml.Unmarshal(fileContent, &fileMetrics); err != nil {
			log.Fatalln("Unmarshalling error in ", filePath, ": ", err)
		}
		configuredMetrics = append(configuredMetrics, fileMetrics...)
	}
	return configuredMetrics
}

func updateTimstampInDDMetrics(ddmetrics []datadog.Metric) {
	timestamp := time.Now().Unix()
	for _, metric := range ddmetrics {
		for i := range metric.Points {
			metric.Points[i][0] = float64(timestamp)
		}
	}
}

func createDDMetrics(configuredMetrics []metric) []datadog.Metric {
	ddmetrics := []datadog.Metric{}
	timestamp := time.Now().Unix()
	for _, metric := range configuredMetrics {
		value, _ := strconv.ParseFloat(metric.Value, 64)
		ddmetric := datadog.Metric{
			Metric: metric.Name,
			Points: []datadog.DataPoint{
				{float64(timestamp), value},
			},
			Tags: metric.Tags,
		}
		ddmetrics = append(ddmetrics, ddmetric)
		createdMetric := fmt.Sprintf("%#v", ddmetric)
		log.Println("Will report the following metric: ", createdMetric)
	}
	return ddmetrics
}

func postMetrics(datadogClient *datadog.Client, metrics []datadog.Metric) {
	log.Println("Updating", len(metrics), "metrics.")
	if err := datadogClient.PostMetrics(metrics); err != nil {
		log.Println("ERROR: Cannot log to datadog: ", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/codegangsta/cli"
	"github.com/opencredo/terrahelp/terrahelp"
)

func main() {

	app := cli.NewApp()
	app.Name = "terrahelp"
	app.Usage = "Provides additional functions helpful with terraform development"
	app.Version = "0.2.1"
	app.Author = "https://github.com/opencredo (Nicki Watt)"
	app.Commands = []cli.Command{
		{
			Name:  "tfstate",
			Usage: "Options for performing actions on the local tfstate files.",
			Subcommands: []cli.Command{
				vaultPrepSubCommand(newTerraHelperFunc()),
				encryptSubCommand(newTerraHelperFunc()),
				decryptSubCommand(newTerraHelperFunc()),
			},
		},
	}
	app.Run(os.Args)
}

func newTerraHelperFunc() func(provider string) *terrahelp.Tfstate {
	return func(provider string) *terrahelp.Tfstate {

		switch {
		case (provider == terrahelp.ThEncryptProviderSimple):
			e := terrahelp.NewSimpleEncrypter()
			return &terrahelp.Tfstate{Encrypter: e}
		case (provider == terrahelp.ThEncryptProviderVault):
			e, err := terrahelp.NewVaultEncrypter()
			if err != nil {
				exitIfError(err)
			}
			return &terrahelp.Tfstate{Encrypter: e}
		}

		exitIfError(fmt.Errorf("Invalid provider %s specified ", provider))
		return nil
	}
}
<commit_msg>Bumped version number up to 0.2.2-dev<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/codegangsta/cli"
	"github.com/opencredo/terrahelp/terrahelp"
)

func main() {

	app := cli.NewApp()
	app.Name = "terrahelp"
	app.Usage = "Provides additional functions helpful with terraform development"
	app.Version = "0.2.2-dev"
	app.Author = "https://github.com/opencredo (Nicki Watt)"
	app.Commands = []cli.Command{
		{
			Name:  "tfstate",
			Usage: "Options for performing actions on the local tfstate files.",
			Subcommands: []cli.Command{
				vaultPrepSubCommand(newTerraHelperFunc()),
				encryptSubCommand(newTerraHelperFunc()),
				decryptSubCommand(newTerraHelperFunc()),
			},
		},
	}
	app.Run(os.Args)
}

func newTerraHelperFunc() func(provider string) *terrahelp.Tfstate {
	return func(provider string) *terrahelp.Tfstate {

		switch {
		case (provider == terrahelp.ThEncryptProviderSimple):
			e := terrahelp.NewSimpleEncrypter()
			return &terrahelp.Tfstate{Encrypter: e}
		case (provider == terrahelp.ThEncryptProviderVault):
			e, err := terrahelp.NewVaultEncrypter()
			if err != nil {
				exitIfError(err)
			}
			return &terrahelp.Tfstate{Encrypter: e}
		}

		exitIfError(fmt.Errorf("Invalid provider %s specified ", provider))
		return nil
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"qaz/commands"
)

func main() {
	if err := commands.RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<commit_msg>Update main.go<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/daidokoro/qaz/commands"
)

func main() {
	if err := commands.RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	gltext "github.com/4ydx/gltext"
	glfw "github.com/go-gl/glfw3"
	gl32 "github.com/go-gl/glow/gl-core/3.2/gl"
	"github.com/go-gl/glow/gl-core/3.3/gl"
	"os"
	"runtime"
)

var useStrictCoreProfile = (runtime.GOOS == "darwin")

func errorCallback(err glfw.ErrorCode, desc string) {
	fmt.Printf("%v: %v\n", err, desc)
}

func findCenter(windowWidth int, windowHeight int, x1, x2 gltext.Point) (lowerLeft gltext.Point) {
	widthHalf := windowWidth / 2
	heightHalf := windowHeight / 2

	lineWidthHalf := (x2.X - x1.X) / 2
	lineHeightHalf := (x2.Y - x1.Y) / 2

	lowerLeft.X = float32(widthHalf) - lineWidthHalf
	lowerLeft.Y = float32(heightHalf) - lineHeightHalf
	return
}

func main() {
	runtime.LockOSThread()

	glfw.SetErrorCallback(errorCallback)
	if !glfw.Init() {
		panic("glfw error")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	if useStrictCoreProfile {
		glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)
		glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	}
	glfw.WindowHint(glfw.OpenglDebugContext, glfw.True)

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	if err := gl.Init(); err != nil {
		panic(err)
	}
	if err := gl32.Init(); err != nil {
		fmt.Println("could not initialize GL 3.2")
	}
	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("Opengl version", version)

	fd, err := os.Open("font/luximr.ttf")
	if err != nil {
		panic(err)
	}
	defer fd.Close()

	scale := int32(32)
	font, err := gltext.LoadTruetype(fd, scale, 32, 127)
	if err != nil {
		panic(err)
	}
	width, height := window.GetSize()

	font.ResizeWindow(float32(width), float32(height))
	font.SetTextLowerBound(0.5)

	text := gltext.LoadText(font)
	str := "ABCDEFG"

	// return values can be used to position on the screen
	_, _ = text.SetString(str)

	xPos := float32(0)
	flow := float32(1)
	color := float32(0)
	gl.ClearColor(0.4, 0.4, 0.4, 0.0)
	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT)

		color += flow * 0.01
		if color > 1.0 {
			color = 1
			flow = -1
		}
		if color < 0.0 {
			color = 0
			flow = +1
		}
		xPos += flow * 0.001
		text.SetPosition(xPos, 0)
		text.SetColor(color, color, color, 1)
		text.SetScale(color + 0.5)
		text.Draw()

		window.SwapBuffers()
		glfw.PollEvents()
	}
	text.Release()
	font.Release()
}
<commit_msg>Removed unused function.<commit_after>package main

import (
	"fmt"
	gltext "github.com/4ydx/gltext"
	glfw "github.com/go-gl/glfw3"
	gl32 "github.com/go-gl/glow/gl-core/3.2/gl"
	"github.com/go-gl/glow/gl-core/3.3/gl"
	"os"
	"runtime"
)

var useStrictCoreProfile = (runtime.GOOS == "darwin")

func errorCallback(err glfw.ErrorCode, desc string) {
	fmt.Printf("%v: %v\n", err, desc)
}

func main() {
	runtime.LockOSThread()

	glfw.SetErrorCallback(errorCallback)
	if !glfw.Init() {
		panic("glfw error")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	if useStrictCoreProfile {
		glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)
		glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	}
	glfw.WindowHint(glfw.OpenglDebugContext, glfw.True)

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	if err := gl.Init(); err != nil {
		panic(err)
	}
	if err := gl32.Init(); err != nil {
		fmt.Println("could not initialize GL 3.2")
	}
	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("Opengl version", version)

	fd, err := os.Open("font/luximr.ttf")
	if err != nil {
		panic(err)
	}
	defer fd.Close()

	scale := int32(32)
	font, err := gltext.LoadTruetype(fd, scale, 32, 127)
	if err != nil {
		panic(err)
	}
	width, height := window.GetSize()

	font.ResizeWindow(float32(width), float32(height))
	font.SetTextLowerBound(0.5)

	text := gltext.LoadText(font)
	str := "ABCDEFG"

	// return values can be used to position on the screen
	_, _ = text.SetString(str)

	xPos := float32(0)
	flow := float32(1)
	color := float32(0)
	gl.ClearColor(0.4, 0.4, 0.4, 0.0)
	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT)

		color += flow * 0.01
		if color > 1.0 {
			color = 1
			flow = -1
		}
		if color < 0.0 {
			color = 0
			flow = +1
		}
		xPos += flow * 0.001
		text.SetPosition(xPos, 0)
		text.SetColor(color, color, color, 1)
		text.SetScale(color + 0.5)
		text.Draw()

		window.SwapBuffers()
		glfw.PollEvents()
	}
	text.Release()
	font.Release()
}
<|endoftext|>


<commit_before>package main

// TODO: check that we're running with mount priv

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/calavera/docker-volume-api"
)

var (
	root = flag.String("root", volumeapi.DefaultDockerRootDirectory, "Docker volumes root directory")
)

type garbageDriver struct {
	root string
}

func (g garbageDriver) Create(r volumeapi.VolumeRequest) volumeapi.VolumeResponse {
	fmt.Printf("Create %v\n", r)
	return volumeapi.VolumeResponse{}
}

func (g garbageDriver) Remove(r volumeapi.VolumeRequest) volumeapi.VolumeResponse {
	fmt.Printf("Remove %v\n", r)
	return volumeapi.VolumeResponse{}
}

func (g garbageDriver) Path(r volumeapi.VolumeRequest) volumeapi.VolumeResponse {
	fmt.Printf("Path %v\n", r)
	return volumeapi.VolumeResponse{Mountpoint: filepath.Join(g.root, r.Name)}
}

func (g garbageDriver) Mount(r volumeapi.VolumeRequest) volumeapi.VolumeResponse {
	p := filepath.Join(g.root, r.Name)

	v := strings.Split(r.Name, "/")
	v[0] = v[0]+":"
	source := strings.Join(v, "/")

	fmt.Printf("Mount %s at %s\n", source, p)

	if err := os.MkdirAll(p, 0755); err != nil {
		return volumeapi.VolumeResponse{Err: err}
	}

	//if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte("TESTTEST"), 0644); err != nil {
	//fmt.Printf("wrote %s\n", filepath.Join(p, "test"))
	// if err := run("mount", "--bind", "/data/ISOs", p); err != nil {
	if err := run("mount", source, p); err != nil {
		return volumeapi.VolumeResponse{Err: err}
	}

	return volumeapi.VolumeResponse{Mountpoint: p}
}

func (g garbageDriver) Unmount(r volumeapi.VolumeRequest) volumeapi.VolumeResponse {
	p := filepath.Join(g.root, r.Name)
	fmt.Printf("Unmount %s\n", p)

	if err := run("umount", p); err != nil {
		return volumeapi.VolumeResponse{Err: err}
	}

	err := os.RemoveAll(p)
	return volumeapi.VolumeResponse{Err: err}
}

func main() {
	d := garbageDriver{*root}
	h := volumeapi.NewVolumeHandler(d)
	fmt.Println(h.ListenAndServe("unix", "/usr/share/docker/plugins/nfs.sock", ""))
}

var (
	verbose = true
)

func run(exe string, args ...string) error {
        cmd := exec.Command(exe, args...)
        if verbose {
                cmd.Stdout = os.Stdout
                cmd.Stderr = os.Stderr
                fmt.Printf("executing: %v %v", exe, strings.Join(args, " "))
        }
        if err := cmd.Run(); err != nil {
                return err
        }
        return nil
}

<commit_msg>support for new dkvolume api.<commit_after>package main

// TODO: check that we're running with mount priv

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/calavera/dkvolume"
)

var (
	root = flag.String("root", dkvolume.DefaultDockerRootDirectory, "Docker volumes root directory")
)

type garbageDriver struct {
	root string
}

func (g garbageDriver) Create(r dkvolume.Request) dkvolume.Response {
	fmt.Printf("Create %v\n", r)
	return dkvolume.Response{}
}

func (g garbageDriver) Remove(r dkvolume.Request) dkvolume.Response {
	fmt.Printf("Remove %v\n", r)
	return dkvolume.Response{}
}

func (g garbageDriver) Path(r dkvolume.Request) dkvolume.Response {
	fmt.Printf("Path %v\n", r)
	return dkvolume.Response{Mountpoint: filepath.Join(g.root, r.Name)}
}

func (g garbageDriver) Mount(r dkvolume.Request) dkvolume.Response {
	p := filepath.Join(g.root, r.Name)

	// Docker volumes syntax doesn't allow
	//  using ":" so we should specify nfs mounts
	//  as "host_or_ip/path/to/nfs". Here we
	//  rebuild the right address host_or_ip:/path/to/nfs
	v := strings.Split(r.Name, "/")
	v[0] = v[0] + ":"
	source := strings.Join(v, "/")

	fmt.Printf("Mount %s at %s\n", source, p)

	if err := os.MkdirAll(p, 0755); err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	//if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte("TESTTEST"), 0644); err != nil {
	//fmt.Printf("wrote %s\n", filepath.Join(p, "test"))
	// if err := run("mount", "--bind", "/data/ISOs", p); err != nil {
	if err := run("mount", source, p); err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	return dkvolume.Response{Mountpoint: p}
}

func (g garbageDriver) Unmount(r dkvolume.Request) dkvolume.Response {
	p := filepath.Join(g.root, r.Name)
	fmt.Printf("Unmount %s\n", p)

	if err := run("umount", p); err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	err := os.RemoveAll(p)
	return dkvolume.Response{Err: err.Error()}
}

func main() {
	d := garbageDriver{*root}
	h := dkvolume.NewHandler(d)
	fmt.Println(h.ServeUnix("", "/usr/share/docker/plugins/nfs.sock"))
}

var (
	verbose = true
)

func run(exe string, args ...string) error {
	cmd := exec.Command(exe, args...)
	if verbose {
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		fmt.Printf("executing: %v %v", exe, strings.Join(args, " "))
	}
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 Pauline Middelink. All rights reserved.
// Use of this source code is governed by a Apache 2.0 license that can be
// found in the LICENSE file.

// Command mikrotik-fwban acts as a syslog receiver and tries to extract an
// IP address out of the messages received. It then adds the IPs to the
// banlist on the configured Mikrotiks. In essence it is a Fail2Ban done the
// lazy way. Since it leverages the filtering mechanisms of rsyslog to do the
// pre-filtering, it should be able to handle large sets of publicly
// accessible machines (famous last words, I know).
//
// It handles both IPv4 and IPv6 addresses and banlists.
//
// It can handle multiple Mikrotiks, keeping the banned IPs in their
// respective banlists in sync.
package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/google/gops/agent"
	"github.com/howeyc/fsnotify"
	"github.com/jeromer/syslogparser"
	"github.com/jeromer/syslogparser/rfc3164"
	"github.com/jeromer/syslogparser/rfc5424"
)

var (
	filename      = flag.String("filename", "/etc/mikrotik-fwban.cfg", "Path of the configuration file to read.")
	port          = flag.Uint("port", 0, "UDP port we listen on for syslog formatted messages.")
	autodelete    = flag.Bool("autodelete", false, "Autodelete entries when they expire. Aka, don't trust Mikrotik to do it for us.")
	blocktime     = flag.Duration("blocktime", 0, "Set the life time for dynamically managed entries.")
	debug         = flag.Bool("debug", false, "Be absolutely staggering in our logging.")
	verbose       = flag.Bool("verbose", false, "Be more verbose in our logging.")
	configchanged = flag.Bool("configchange", false, "Exit process when config file changes.")

	cfg Config
)

func setFlags(flags ...string) error {
	if len(flags) != 0 {
		// Some complicated shit to reset the flags to their default values.
		// Make sure not to touch the test.* flags as that will inhibit any profiling.
		flag.VisitAll(func(flg *flag.Flag) {
			if !strings.HasPrefix(flg.Name, "test.") {
				flg.Value.Set(flg.DefValue)
			}
		})
		return flag.CommandLine.Parse(flags)
	}
	return flag.CommandLine.Parse(os.Args[1:])
}

func main() {
	setFlags()
	var err error
	cfg, err = newConfigFile(*filename, uint16(*port), Duration(*blocktime), *autodelete, *verbose)
	if err != nil {
		log.Fatal(err)
	}

	// Start the gops diagnostic agent.
	if err := agent.Listen(agent.Options{}); err != nil {
		log.Fatal(err)
	}

	if *configchanged {
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			for {
				select {
				case <-watcher.Event:
					os.Exit(0)
				case <-watcher.Error:
					os.Exit(1)
				}
			}
		}()
		if err = watcher.Watch(*filename); err != nil {
			log.Fatal(err)
		}
	}

	// Open connections to each mikrotik and build a list of the unique
	// IPs they all have.
	var mts []*Mikrotik
	mergeIP := make(map[string]BlackIP)
	for k, v := range cfg.Mikrotik {
		if v.Disabled {
			log.Printf("%s: definition disabled, skipping\n", k)
			continue
		}
		mt, err := NewMikrotik(k, v)
		if err != nil {
			log.Fatalln(err)
		}
		defer mt.Close()
		for _, ip := range mt.GetIPs() {
			if _, ok := mergeIP[ip.Net.String()]; !ok {
				mergeIP[ip.Net.String()] = ip
			}
		}
		mts = append(mts, mt)
	}

	// Distribute the missing dynamic IPs to the mikrotiks.
	for _, mt := range mts {
		ips := mt.GetIPs()
		for k, ip := range mergeIP {
			found := false
			for _, ip2 := range ips {
				if k == ip2.Net.String() {
					found = true
					break
				}
			}
			if !found {
				mt.AddIP(ip.Net, Duration(ip.Dead.Sub(time.Now())), "")
			}
		}
	}

	sigs := make(chan os.Signal, 1)
	go func() {
		for range sigs {
			log.Printf("Got signal, dumping dynlists")
			for _, mt := range mts {
				for i, ip := range mt.GetIPs() {
					log.Printf("%s(%d): %s\n", mt.Name, i, ip)
				}
			}
		}
	}()
	signal.Notify(sigs, syscall.SIGUSR1)

	// Start listening to the socket for syslog messages.
	listener, err := net.ListenPacket("udp", fmt.Sprintf(":%d", cfg.Settings.Port))
	if err != nil {
		log.Fatalln(err)
	}
	pkt := make([]byte, 4096)
	for {
		n, _, err := listener.ReadFrom(pkt)
		if err != nil {
			log.Fatalln(err)
		}

		var parser syslogparser.LogParser
		parser = rfc3164.NewParser(pkt[:n])
		msg := "content"
		if err = parser.Parse(); err != nil {
			parser = rfc5424.NewParser(pkt[:n])
			if err = parser.Parse(); err != nil {
				log.Println(err)
				continue
			}
			msg = "message"
		}
		logparts := parser.Dump()
		for _, re := range cfg.re {
			if res := re.RE.FindStringSubmatch(logparts[msg].(string)); len(res) > 0 {
				if *debug {
					log.Printf("MATCH!!! %s\n", string(pkt[:n]))
					log.Printf("%#v\n", res[1:])
				}
				if ip := parseCIDR(res[re.IPIndex], cfg.Settings.Verbose); ip != nil {
					for _, mt := range mts {
						if err = mt.AddIP(*ip, cfg.Settings.BlockTime, logparts[msg].(string)); err != nil {
							log.Fatalln(err)
							continue
						}
					}
				}
				break
			}
		}
	}
}
<commit_msg>Trim the syslog message of whitespace, mainly newlines before adding it as a comment.<commit_after>// Copyright 2016 Pauline Middelink. All rights reserved.
// Use of this source code is governed by a Apache 2.0 license that can be
// found in the LICENSE file.

// Command mikrotik-fwban acts as a syslog receiver and tries to extract an
// IP address out of the messages received. It then adds the IPs to the
// banlist on the configured Mikrotiks. In essence it is a Fail2Ban done the
// lazy way. Since it leverages the filtering mechanisms of rsyslog to do the
// pre-filtering, it should be able to handle large sets of publicly
// accessible machines (famous last words, I know).
//
// It handles both IPv4 and IPv6 addresses and banlists.
//
// It can handle multiple Mikrotiks, keeping the banned IPs in their
// respective banlists in sync.
package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/google/gops/agent"
	"github.com/howeyc/fsnotify"
	"github.com/jeromer/syslogparser"
	"github.com/jeromer/syslogparser/rfc3164"
	"github.com/jeromer/syslogparser/rfc5424"
)

var (
	filename      = flag.String("filename", "/etc/mikrotik-fwban.cfg", "Path of the configuration file to read.")
	port          = flag.Uint("port", 0, "UDP port we listen on for syslog formatted messages.")
	autodelete    = flag.Bool("autodelete", false, "Autodelete entries when they expire. Aka, don't trust Mikrotik to do it for us.")
	blocktime     = flag.Duration("blocktime", 0, "Set the life time for dynamically managed entries.")
	debug         = flag.Bool("debug", false, "Be absolutely staggering in our logging.")
	verbose       = flag.Bool("verbose", false, "Be more verbose in our logging.")
	configchanged = flag.Bool("configchange", false, "Exit process when config file changes.")

	cfg Config
)

func setFlags(flags ...string) error {
	if len(flags) != 0 {
		// Some complicated shit to reset the flags to their default values.
		// Make sure not to touch the test.* flags as that will inhibit any profiling.
		flag.VisitAll(func(flg *flag.Flag) {
			if !strings.HasPrefix(flg.Name, "test.") {
				flg.Value.Set(flg.DefValue)
			}
		})
		return flag.CommandLine.Parse(flags)
	}
	return flag.CommandLine.Parse(os.Args[1:])
}

func main() {
	setFlags()
	var err error
	cfg, err = newConfigFile(*filename, uint16(*port), Duration(*blocktime), *autodelete, *verbose)
	if err != nil {
		log.Fatal(err)
	}

	// Start the gops diagnostic agent.
	if err := agent.Listen(agent.Options{}); err != nil {
		log.Fatal(err)
	}

	if *configchanged {
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			for {
				select {
				case <-watcher.Event:
					os.Exit(0)
				case <-watcher.Error:
					os.Exit(1)
				}
			}
		}()
		if err = watcher.Watch(*filename); err != nil {
			log.Fatal(err)
		}
	}

	// Open connections to each mikrotik and build a list of the unique
	// IPs they all have.
	var mts []*Mikrotik
	mergeIP := make(map[string]BlackIP)
	for k, v := range cfg.Mikrotik {
		if v.Disabled {
			log.Printf("%s: definition disabled, skipping\n", k)
			continue
		}
		mt, err := NewMikrotik(k, v)
		if err != nil {
			log.Fatalln(err)
		}
		defer mt.Close()
		for _, ip := range mt.GetIPs() {
			if _, ok := mergeIP[ip.Net.String()]; !ok {
				mergeIP[ip.Net.String()] = ip
			}
		}
		mts = append(mts, mt)
	}

	// Distribute the missing dynamic IPs to the mikrotiks.
	for _, mt := range mts {
		ips := mt.GetIPs()
		for k, ip := range mergeIP {
			found := false
			for _, ip2 := range ips {
				if k == ip2.Net.String() {
					found = true
					break
				}
			}
			if !found {
				mt.AddIP(ip.Net, Duration(ip.Dead.Sub(time.Now())), "")
			}
		}
	}

	sigs := make(chan os.Signal, 1)
	go func() {
		for range sigs {
			log.Printf("Got signal, dumping dynlists")
			for _, mt := range mts {
				for i, ip := range mt.GetIPs() {
					log.Printf("%s(%d): %s\n", mt.Name, i, ip)
				}
			}
		}
	}()
	signal.Notify(sigs, syscall.SIGUSR1)

	// Start listening to the socket for syslog messages.
	listener, err := net.ListenPacket("udp", fmt.Sprintf(":%d", cfg.Settings.Port))
	if err != nil {
		log.Fatalln(err)
	}
	pkt := make([]byte, 4096)
	for {
		n, _, err := listener.ReadFrom(pkt)
		if err != nil {
			log.Fatalln(err)
		}

		var parser syslogparser.LogParser
		parser = rfc3164.NewParser(pkt[:n])
		msg := "content"
		if err = parser.Parse(); err != nil {
			parser = rfc5424.NewParser(pkt[:n])
			if err = parser.Parse(); err != nil {
				log.Println(err)
				continue
			}
			msg = "message"
		}
		logparts := parser.Dump()
		for _, re := range cfg.re {
			text := strings.TrimSpace(logparts[msg].(string))
			if res := re.RE.FindStringSubmatch(text); len(res) > 0 {
				if *debug {
					log.Printf("MATCH!!! %s\n", string(pkt[:n]))
					log.Printf("%#v\n", res[1:])
				}
				if ip := parseCIDR(res[re.IPIndex], cfg.Settings.Verbose); ip != nil {
					for _, mt := range mts {
						if err = mt.AddIP(*ip, cfg.Settings.BlockTime, text); err != nil {
							log.Fatalln(err)
							continue
						}
					}
				}
				break
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/danryan/hal"
	_ "github.com/danryan/hal/adapter/irc"
	_ "github.com/danryan/hal/adapter/shell"
	_ "github.com/danryan/hal/store/memory"
)

var pingHandler = hal.Hear(`.ping`, func(res *hal.Response) error {
	return res.Send("PONG")
})

var fooHandler = hal.Hear(`.foo`, func(res *hal.Response) error {
	return res.Send("BAR")
})

var synHandler = hal.Hear(`.SYN`, func(res *hal.Response) error {
	return res.Send("ACK")
})

func run() int {
	robot, err := hal.NewRobot()
	if err != nil {
		hal.Logger.Error(err)
		return 1
	}

	robot.Handle(
		pingHandler,
		fooHandler,
		tableFlipHandler,
		eventHandler,
	)

	if err := robot.Run(); err != nil {
		hal.Logger.Error(err)
		return 1
	}
	return 0
}

func main() {
	os.Exit(run())
}
<commit_msg>Enable synHandler<commit_after>package main

import (
	"os"

	"github.com/danryan/hal"
	_ "github.com/danryan/hal/adapter/irc"
	_ "github.com/danryan/hal/adapter/shell"
	_ "github.com/danryan/hal/store/memory"
)

var pingHandler = hal.Hear(`.ping`, func(res *hal.Response) error {
	return res.Send("PONG")
})

var fooHandler = hal.Hear(`.foo`, func(res *hal.Response) error {
	return res.Send("BAR")
})

var synHandler = hal.Hear(`.SYN`, func(res *hal.Response) error {
	return res.Send("ACK")
})

func run() int {
	robot, err := hal.NewRobot()
	if err != nil {
		hal.Logger.Error(err)
		return 1
	}

	robot.Handle(
		pingHandler,
		fooHandler,
		tableFlipHandler,
		eventHandler,
		synHandler,
	)

	if err := robot.Run(); err != nil {
		hal.Logger.Error(err)
		return 1
	}
	return 0
}

func main() {
	os.Exit(run())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	log "github.com/Sirupsen/logrus"
	"github.com/gaia-docker/tugbot-result-service/dataupload"
	"github.com/gaia-docker/tugbot-result-service/pool"
	"github.com/gaia-docker/tugbot-result-service/websocket"
	"github.com/gorilla/mux"
	"html/template"
	"net/http"
	"net/url"
)

const defaultLogLevel = log.DebugLevel

var address = flag.String("address", "localhost:8080", "http service address")

var loglevel = flag.String("loglevel", defaultLogLevel.String(), "log level")

var homeTemplate = template.Must(template.ParseFiles("views/home.html"))

var hub = pool.NewHub()

func init() {

	flag.Parse()
	level, err := log.ParseLevel(*loglevel)
	if err != nil {
		level = defaultLogLevel
	}
	log.SetLevel(level)
}

func main() {

	log.Info("Starting tugbot-result-service...")
	go hub.Run()
	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", home).Methods("GET")
	router.Handle("/echo", websocket.NewEchoHandler(hub)).Methods("GET")
	router.Handle("/results", dataupload.NewUploadHandler(hub)).Methods("POST").
		Headers("Content-Type", "application/gzip")
	log.Infof("Listening on %s", *address)
	log.Fatal(http.ListenAndServe(*address, router))
}

func home(w http.ResponseWriter, r *http.Request) {

	if r.URL.Path != "/" {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}
	if r.Method != "GET" {
		http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
		return
	}
	var wsAddress = url.URL{Scheme: "ws", Host: *address, Path: "/echo"}
	homeTemplate.Execute(w, wsAddress.String())
}
<commit_msg>added cli<commit_after>package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/gaia-docker/tugbot-result-service/dataupload"
	"github.com/gaia-docker/tugbot-result-service/pool"
	"github.com/gaia-docker/tugbot-result-service/websocket"
	"github.com/gorilla/mux"
	"github.com/urfave/cli"
	"html/template"
	"net/http"
	"net/url"
	"os"
)

const defaultLogLevel = log.DebugLevel

var address string

var loglevel string

var homeTemplate = template.Must(template.ParseFiles("views/home.html"))

var hub = pool.NewHub()

func main() {

	app := cli.NewApp()
	app.Version = "1.0.0"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "address, a",
			Value:       "localhost:8080",
			Usage:       "http service address",
			Destination: &address,
		},
		cli.StringFlag{
			Name:        "loglevel, l",
			Value:       defaultLogLevel.String(),
			Usage:       "log level",
			Destination: &loglevel,
		},
	}

	app.Name = "tugbot-result-service"
	app.Usage = "Implements Result Service API and exposes websocket which present live stream of test results."
	app.Action = start

	if err := app.Run(os.Args); err != nil {
		log.Error("exiting from main: ", err)
	}
}

func start(c *cli.Context) error {

	log.Info("Starting tugbot-result-service...")
	go hub.Run()
	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", home).Methods("GET")
	router.Handle("/echo", websocket.NewEchoHandler(hub)).Methods("GET")
	router.Handle("/results", dataupload.NewUploadHandler(hub)).Methods("POST").
		Headers("Content-Type", "application/gzip")
	log.Infof("Listening on %s", address)

	return http.ListenAndServe(address, router)
}

func home(w http.ResponseWriter, r *http.Request) {

	if r.URL.Path != "/" {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}
	if r.Method != "GET" {
		http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
		return
	}
	var wsAddress = url.URL{Scheme: "ws", Host: address, Path: "/echo"}
	homeTemplate.Execute(w, wsAddress.String())
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.tools/go/types"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
)

var (
	universe string
	own      string
)

func init() {
	flag.StringVar(&universe, "universe", "std", "Comma-separated list of Which packages to scan for interfaces. Defaults to std.")
	flag.StringVar(&own, "own", "", "Comma-separated list of packages whose types to check for implemented interfaces.")

	flag.Parse()
}

type Interface struct {
	Name       string
	Underlying *types.Interface
	Obj        types.Object
}

type Type struct {
	Object   types.Object
	TypeName *types.TypeName
	Pointer  *types.Pointer
}

// getInterfaces extracts all the interfaces from the objects we
// parsed.
func getInterfaces(typs []Type) []Interface {
	var interfaces []Interface

	for _, typ := range typs {
		// Only types, not variables/constants
		// Only interfaces
		if iface, ok := typ.TypeName.Type().Underlying().(*types.Interface); ok {
			interfaces = append(interfaces, Interface{typ.Object.Name(), iface, typ.Object})
		}
	}

	return interfaces
}

func parseFile(fset *token.FileSet, fileName string) (f *ast.File, err error) {
	astFile, err := parser.ParseFile(fset, fileName, nil, 0)
	if err != nil {
		return f, fmt.Errorf("could not parse: %s", err)
	}

	return astFile, nil
}

type Context struct {
	allImports map[string]*types.Package
	context    types.Context
}

func NewContext() *Context {
	ctx := &Context{
		allImports: make(map[string]*types.Package),
	}

	ctx.context = types.Context{
		Import: ctx.importer,
	}

	return ctx
}

func (ctx *Context) importer(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// types.Importer does not seem to be designed for recursive
	// parsing like we're doing here. Specifically, each nested import
	// will maintain its own imports map. This will lead to duplicate
	// imports and in turn packages, which will lead to funny errors
	// such as "cannot pass argument ip (variable of type net.IP) to
	// variable of type net.IP"
	//
	// To work around this, we keep a global imports map, allImports,
	// to which we add all nested imports, and which we use as the
	// cache, instead of imports.
	//
	// Since all nested imports will also use this importer, there
	// should be no way to end up with duplicate imports.

	// We first try to use GcImport directly. This has the downside of
	// using possibly out-of-date packages, but it has the upside of
	// not having to parse most of the Go standard library.

	buildPkg, buildErr := build.Import(path, ".", 0)
	// If we found no build dir, assume we're dealing with installed
	// but no source. If we found a build dir, only use GcImport if
	// it's in GOROOT. This way we always use up-to-date code for
	// normal packages but avoid parsing the standard library.
	if (buildErr == nil && buildPkg.Goroot) || buildErr != nil {
		pkg, err = types.GcImport(ctx.allImports, path)
		if err == nil {
			// We don't use imports, but per API we have to add the package.
			imports[pkg.Path()] = pkg
			ctx.allImports[pkg.Path()] = pkg
			return pkg, nil
		}
	}

	// See if we already imported this package
	if pkg = ctx.allImports[path]; pkg != nil && pkg.Complete() {
		return pkg, nil
	}

	// allImports failed, try to use go/build
	if buildErr != nil {
		return nil, buildErr
	}

	// TODO check if the .a file is up to date and use it instead
	fileSet := token.NewFileSet()

	isGoFile := func(d os.FileInfo) bool {
		allFiles := make([]string, 0, len(buildPkg.GoFiles)+len(buildPkg.CgoFiles))
		allFiles = append(allFiles, buildPkg.GoFiles...)
		allFiles = append(allFiles, buildPkg.CgoFiles...)

		for _, file := range allFiles {
			if file == d.Name() {
				return true
			}
		}
		return false
	}
	pkgs, err := parser.ParseDir(fileSet, buildPkg.Dir, isGoFile, 0)
	if err != nil {
		return nil, err
	}

	delete(pkgs, "documentation")
	var astPkg *ast.Package
	var name string
	for name, astPkg = range pkgs {
		// Use the first non-main package, or the only package we
		// found.
		//
		// NOTE(dh) I can't think of a reason why there should be
		// multiple packages in a single directory, but ParseDir
		// accommodates for that possibility.
		if len(pkgs) == 1 || name != "main" {
			break
		}
	}

	if astPkg == nil {
		return nil, fmt.Errorf("can't find import: %s", name)
	}

	var ff []*ast.File
	for _, f := range astPkg.Files {
		ff = append(ff, f)
	}

	context := types.Context{
		Import: ctx.importer,
	}

	pkg, err = context.Check(name, fileSet, ff...)
	if err != nil {
		return pkg, err
	}
	if !pkg.Complete() {
		pkg = types.NewPackage(pkg.Pos(), pkg.Path(), pkg.Name(), pkg.Scope(), pkg.Imports(), true)
	}

	imports[path] = pkg
	ctx.allImports[path] = pkg
	return pkg, nil
}

func (ctx *Context) getTypes(paths ...string) ([]Type, []error) {
	var errors []error
	var typs []Type

	for _, path := range paths {
		buildPkg, err := build.Import(path, ".", 0)
		if err != nil {
			errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
			continue
		}
		fset := token.NewFileSet()
		var astFiles []*ast.File
		var pkg *types.Package
		if buildPkg.Goroot {
			// TODO what if the compiled package in GoRoot is
			// outdated?
			pkg, err = types.GcImport(ctx.allImports, path)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
				continue
			}
		} else {
			if len(buildPkg.GoFiles) == 0 {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: No go files", path))
				continue
			}
			for _, file := range buildPkg.GoFiles {
				astFile, err := parseFile(fset, filepath.Join(buildPkg.Dir, file))
				if err != nil {
					errors = append(errors, fmt.Errorf("Couldn't parse %s: %s", err))
					continue
				}
				astFiles = append(astFiles, astFile)
			}

			pkg, err = check(ctx, astFiles[0].Name.Name, fset, astFiles)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: %s\n", path, err))
				continue
			}
		}

		scope := pkg.Scope()
		for i := 0; i < scope.NumEntries(); i++ {
			obj := scope.At(i)

			// Only types, not variables/constants
			if typ, ok := obj.(*types.TypeName); ok {
				typs = append(typs, Type{
					Object:   obj,
					TypeName: typ,
					Pointer:  types.NewPointer(typ.Type()),
				})
			}

		}
	}
	return typs, errors
}

func check(ctx *Context, name string, fset *token.FileSet, astFiles []*ast.File) (pkg *types.Package, err error) {
	return ctx.context.Check(name, fset, astFiles...)
}

func listErrors(errors []error) {
	for _, err := range errors {
		fmt.Println(err)
	}
}

func main() {
	if own == "" {
		flag.Usage()
		os.Exit(1)
	}

	ctx := NewContext()
	stdlib, errs := ctx.getTypes(matchPackages(universe)...)
	listErrors(errs)
	toCheck, errs := ctx.getTypes(matchPackages(own)...)
	listErrors(errs)

	interfaces := getInterfaces(stdlib)

	for _, typ := range toCheck {
		var implements []string
		var implementsPointer []string
		for _, iface := range interfaces {
			if iface.Underlying.NumMethods() == 0 {
				// Everything implements empty interfaces, skip those
				continue
			}

			if typ.Object.Pkg() == iface.Obj.Pkg() && typ.Object.Name() == iface.Name {
				// An interface will always implement itself, so skip those
				continue
			}

			if fnc, _ := types.MissingMethod(typ.Object.Type(), iface.Underlying); fnc == nil {
				s := fmt.Sprintf("%s.%s",
					iface.Obj.Pkg().Name(), iface.Name)
				implements = append(implements, s)
			}

			// TODO DRY
			if _, ok := typ.TypeName.Type().Underlying().(*types.Interface); !ok {
				if fnc, _ := types.MissingMethod(typ.Pointer.Underlying(), iface.Underlying); fnc == nil {
					s := fmt.Sprintf("%s.%s",
						iface.Obj.Pkg().Name(), iface.Name)
					implementsPointer = append(implementsPointer, s)
				}
			}
		}

		if len(implements) > 0 {
			fmt.Printf("%s.%s implements...\n", typ.TypeName.Pkg().Name(), typ.Object.Name())
			for _, impl := range implements {
				fmt.Printf("\t%s\n", impl)
			}
		}
		// TODO DRY
		if len(implementsPointer) > 0 {
			fmt.Printf("*%s.%s implements...\n", typ.TypeName.Pkg().Name(), typ.Object.Name())
			for _, impl := range implementsPointer {
				fmt.Printf("\t%s\n", impl)
			}
		}
	}
}
<commit_msg>clean up some code<commit_after>package main

import (
	"code.google.com/p/go.tools/go/types"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
)

var (
	universe string
	own      string
)

func init() {
	flag.StringVar(&universe, "universe", "std", "Comma-separated list of Which packages to scan for interfaces. Defaults to std.")
	flag.StringVar(&own, "own", "", "Comma-separated list of packages whose types to check for implemented interfaces.")

	flag.Parse()
}

type Interface struct {
	Name       string
	Underlying *types.Interface
	Obj        types.Object
}

type Type struct {
	Object   types.Object
	TypeName *types.TypeName
	Pointer  *types.Pointer
}

// getInterfaces extracts all the interfaces from the objects we
// parsed.
func getInterfaces(typs []Type) []Interface {
	var interfaces []Interface

	for _, typ := range typs {
		// Only types, not variables/constants
		// Only interfaces
		if iface, ok := typ.TypeName.Type().Underlying().(*types.Interface); ok {
			interfaces = append(interfaces, Interface{typ.Object.Name(), iface, typ.Object})
		}
	}

	return interfaces
}

func parseFile(fset *token.FileSet, fileName string) (f *ast.File, err error) {
	astFile, err := parser.ParseFile(fset, fileName, nil, 0)
	if err != nil {
		return f, fmt.Errorf("could not parse: %s", err)
	}

	return astFile, nil
}

type Context struct {
	allImports map[string]*types.Package
	context    types.Context
}

func NewContext() *Context {
	ctx := &Context{
		allImports: make(map[string]*types.Package),
	}

	ctx.context = types.Context{
		Import: ctx.importer,
	}

	return ctx
}

func (ctx *Context) importer(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// types.Importer does not seem to be designed for recursive
	// parsing like we're doing here. Specifically, each nested import
	// will maintain its own imports map. This will lead to duplicate
	// imports and in turn packages, which will lead to funny errors
	// such as "cannot pass argument ip (variable of type net.IP) to
	// variable of type net.IP"
	//
	// To work around this, we keep a global imports map, allImports,
	// to which we add all nested imports, and which we use as the
	// cache, instead of imports.
	//
	// Since all nested imports will also use this importer, there
	// should be no way to end up with duplicate imports.

	// We first try to use GcImport directly. This has the downside of
	// using possibly out-of-date packages, but it has the upside of
	// not having to parse most of the Go standard library.

	buildPkg, buildErr := build.Import(path, ".", 0)
	// If we found no build dir, assume we're dealing with installed
	// but no source. If we found a build dir, only use GcImport if
	// it's in GOROOT. This way we always use up-to-date code for
	// normal packages but avoid parsing the standard library.
	if (buildErr == nil && buildPkg.Goroot) || buildErr != nil {
		pkg, err = types.GcImport(ctx.allImports, path)
		if err == nil {
			// We don't use imports, but per API we have to add the package.
			imports[pkg.Path()] = pkg
			ctx.allImports[pkg.Path()] = pkg
			return pkg, nil
		}
	}

	// See if we already imported this package
	if pkg = ctx.allImports[path]; pkg != nil && pkg.Complete() {
		return pkg, nil
	}

	// allImports failed, try to use go/build
	if buildErr != nil {
		return nil, buildErr
	}

	// TODO check if the .a file is up to date and use it instead
	fileSet := token.NewFileSet()

	isGoFile := func(d os.FileInfo) bool {
		allFiles := make([]string, 0, len(buildPkg.GoFiles)+len(buildPkg.CgoFiles))
		allFiles = append(allFiles, buildPkg.GoFiles...)
		allFiles = append(allFiles, buildPkg.CgoFiles...)

		for _, file := range allFiles {
			if file == d.Name() {
				return true
			}
		}
		return false
	}
	pkgs, err := parser.ParseDir(fileSet, buildPkg.Dir, isGoFile, 0)
	if err != nil {
		return nil, err
	}

	delete(pkgs, "documentation")
	var astPkg *ast.Package
	var name string
	for name, astPkg = range pkgs {
		// Use the first non-main package, or the only package we
		// found.
		//
		// NOTE(dh) I can't think of a reason why there should be
		// multiple packages in a single directory, but ParseDir
		// accommodates for that possibility.
		if len(pkgs) == 1 || name != "main" {
			break
		}
	}

	if astPkg == nil {
		return nil, fmt.Errorf("can't find import: %s", name)
	}

	var ff []*ast.File
	for _, f := range astPkg.Files {
		ff = append(ff, f)
	}

	context := types.Context{
		Import: ctx.importer,
	}

	pkg, err = context.Check(name, fileSet, ff...)
	if err != nil {
		return pkg, err
	}
	if !pkg.Complete() {
		pkg = types.NewPackage(pkg.Pos(), pkg.Path(), pkg.Name(), pkg.Scope(), pkg.Imports(), true)
	}

	imports[path] = pkg
	ctx.allImports[path] = pkg
	return pkg, nil
}

func (ctx *Context) getTypes(paths ...string) ([]Type, []error) {
	var errors []error
	var typs []Type

	for _, path := range paths {
		buildPkg, err := build.Import(path, ".", 0)
		if err != nil {
			errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
			continue
		}
		fset := token.NewFileSet()
		var astFiles []*ast.File
		var pkg *types.Package
		if buildPkg.Goroot {
			// TODO what if the compiled package in GoRoot is
			// outdated?
			pkg, err = types.GcImport(ctx.allImports, path)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't import %s: %s", path, err))
				continue
			}
		} else {
			if len(buildPkg.GoFiles) == 0 {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: No go files", path))
				continue
			}
			for _, file := range buildPkg.GoFiles {
				astFile, err := parseFile(fset, filepath.Join(buildPkg.Dir, file))
				if err != nil {
					errors = append(errors, fmt.Errorf("Couldn't parse %s: %s", err))
					continue
				}
				astFiles = append(astFiles, astFile)
			}

			pkg, err = check(ctx, astFiles[0].Name.Name, fset, astFiles)
			if err != nil {
				errors = append(errors, fmt.Errorf("Couldn't parse %s: %s\n", path, err))
				continue
			}
		}

		scope := pkg.Scope()
		for i := 0; i < scope.NumEntries(); i++ {
			obj := scope.At(i)

			// Only types, not variables/constants
			if typ, ok := obj.(*types.TypeName); ok {
				typs = append(typs, Type{
					Object:   obj,
					TypeName: typ,
					Pointer:  types.NewPointer(typ.Type()),
				})
			}

		}
	}
	return typs, errors
}

func check(ctx *Context, name string, fset *token.FileSet, astFiles []*ast.File) (pkg *types.Package, err error) {
	return ctx.context.Check(name, fset, astFiles...)
}

func listErrors(errors []error) {
	for _, err := range errors {
		fmt.Println(err)
	}
}

func doesImplement(typ types.Type, iface *types.Interface) bool {
	fnc, _ := types.MissingMethod(typ, iface)
	return fnc == nil
}

func main() {
	if own == "" {
		flag.Usage()
		os.Exit(1)
	}

	ctx := NewContext()
	stdlib, errs := ctx.getTypes(matchPackages(universe)...)
	listErrors(errs)
	toCheck, errs := ctx.getTypes(matchPackages(own)...)
	listErrors(errs)

	interfaces := getInterfaces(stdlib)

	for _, typ := range toCheck {
		var implements []Interface
		var implementsPointer []Interface
		for _, iface := range interfaces {
			if iface.Underlying.NumMethods() == 0 {
				// Everything implements empty interfaces, skip those
				continue
			}

			if typ.Object.Pkg() == iface.Obj.Pkg() && typ.Object.Name() == iface.Name {
				// An interface will always implement itself, so skip those
				continue
			}

			if doesImplement(typ.Object.Type(), iface.Underlying) {
				implements = append(implements, iface)
			}

			if _, ok := typ.TypeName.Type().Underlying().(*types.Interface); !ok {
				if doesImplement(typ.Pointer.Underlying(), iface.Underlying) {
					implementsPointer = append(implementsPointer, iface)
				}
			}
		}

		if len(implements) > 0 {
			fmt.Printf("%s.%s implements...\n", typ.TypeName.Pkg().Name(), typ.Object.Name())
			for _, iface := range implements {
				fmt.Printf("\t%s.%s\n", iface.Obj.Pkg().Name(), iface.Name)
			}
		}
		// TODO DRY
		if len(implementsPointer) > 0 {
			fmt.Printf("*%s.%s implements...\n", typ.TypeName.Pkg().Name(), typ.Object.Name())
			for _, iface := range implementsPointer {
				fmt.Printf("\t%s.%s\n", iface.Obj.Pkg().Name(), iface.Name)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"runtime/pprof"

	"github.com/otoolep/rqlite/server"

	log "code.google.com/p/log4go"
)

var host string
var port int
var join string
var dbfile string
var cpuprofile string
var logFile string
var logLevel string
var snapAfter int

func init() {
	flag.StringVar(&host, "h", "localhost", "hostname")
	flag.IntVar(&port, "p", 4001, "port")
	flag.StringVar(&join, "join", "", "host:port of leader to join")
	flag.StringVar(&dbfile, "dbfile", "db.sqlite", "sqlite filename")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "write CPU profile to file")
	flag.StringVar(&logFile, "logfile", "stdout", "log file path")
	flag.StringVar(&logLevel, "loglevel", "INFO", "log level (ERROR|WARN|INFO|DEBUG|TRACE)")
	flag.IntVar(&snapAfter, "s", 1000, "Snapshot and compact after this number of new log entries")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [arguments] <data-path> \n", os.Args[0])
		flag.PrintDefaults()
	}
}

func setupLogging(loggingLevel, logFile string) {
	level := log.DEBUG
	switch loggingLevel {
	case "TRACE":
		level = log.TRACE
	case "DEBUG":
		level = log.DEBUG
	case "INFO":
		level = log.INFO
	case "WARN":
		level = log.WARNING
	case "ERROR":
		level = log.ERROR
	}

	log.Global = make(map[string]*log.Filter)

	if logFile == "stdout" {
		flw := log.NewConsoleLogWriter()
		log.AddFilter("stdout", level, flw)

	} else {
		logFileDir := filepath.Dir(logFile)
		os.MkdirAll(logFileDir, 0744)

		flw := log.NewFileLogWriter(logFile, false)
		log.AddFilter("file", level, flw)

		flw.SetFormat("[%D %T] [%L] (%S) %M")
		flw.SetRotate(true)
		flw.SetRotateSize(0)
		flw.SetRotateLines(0)
		flw.SetRotateDaily(true)
	}

	log.Info("Redirectoring logging to %s", logFile)
}

func main() {
	flag.Parse()

	// Set up profiling, if requested.
	if cpuprofile != "" {
		log.Info("Profiling enabled")
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Error("Unable to create path: %w", err)
		}
		defer f.Close()

		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	setupLogging(logLevel, logFile)

	// Set the data directory.
	if flag.NArg() == 0 {
		flag.Usage()
		println("Data path argument required")
		log.Error("No data path supplied -- aborting")
		os.Exit(1)
	}
	path := flag.Arg(0)
	if err := os.MkdirAll(path, 0744); err != nil {
		log.Error("Unable to create path: %v", err)
	}

	s := server.NewServer(path, dbfile, snapAfter, host, port)
	go func() {
		log.Error(s.ListenAndServe(join))
	}()

	terminate := make(chan os.Signal, 1)
	signal.Notify(terminate, os.Interrupt)
	<-terminate
	log.Info("rqlite server stopped")
}
<commit_msg>Add simple copyright to main<commit_after>// rqlite -- a replicated SQLite database.
//
// Copyright (c) 2014 Philip O'Toole
// http://www.philipotoole.com

package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"runtime/pprof"

	"github.com/otoolep/rqlite/server"

	log "code.google.com/p/log4go"
)

var host string
var port int
var join string
var dbfile string
var cpuprofile string
var logFile string
var logLevel string
var snapAfter int

func init() {
	flag.StringVar(&host, "h", "localhost", "hostname")
	flag.IntVar(&port, "p", 4001, "port")
	flag.StringVar(&join, "join", "", "host:port of leader to join")
	flag.StringVar(&dbfile, "dbfile", "db.sqlite", "sqlite filename")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "write CPU profile to file")
	flag.StringVar(&logFile, "logfile", "stdout", "log file path")
	flag.StringVar(&logLevel, "loglevel", "INFO", "log level (ERROR|WARN|INFO|DEBUG|TRACE)")
	flag.IntVar(&snapAfter, "s", 1000, "Snapshot and compact after this number of new log entries")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [arguments] <data-path> \n", os.Args[0])
		flag.PrintDefaults()
	}
}

func setupLogging(loggingLevel, logFile string) {
	level := log.DEBUG
	switch loggingLevel {
	case "TRACE":
		level = log.TRACE
	case "DEBUG":
		level = log.DEBUG
	case "INFO":
		level = log.INFO
	case "WARN":
		level = log.WARNING
	case "ERROR":
		level = log.ERROR
	}

	log.Global = make(map[string]*log.Filter)

	if logFile == "stdout" {
		flw := log.NewConsoleLogWriter()
		log.AddFilter("stdout", level, flw)

	} else {
		logFileDir := filepath.Dir(logFile)
		os.MkdirAll(logFileDir, 0744)

		flw := log.NewFileLogWriter(logFile, false)
		log.AddFilter("file", level, flw)

		flw.SetFormat("[%D %T] [%L] (%S) %M")
		flw.SetRotate(true)
		flw.SetRotateSize(0)
		flw.SetRotateLines(0)
		flw.SetRotateDaily(true)
	}

	log.Info("Redirectoring logging to %s", logFile)
}

func main() {
	flag.Parse()

	// Set up profiling, if requested.
	if cpuprofile != "" {
		log.Info("Profiling enabled")
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Error("Unable to create path: %w", err)
		}
		defer f.Close()

		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	setupLogging(logLevel, logFile)

	// Set the data directory.
	if flag.NArg() == 0 {
		flag.Usage()
		println("Data path argument required")
		log.Error("No data path supplied -- aborting")
		os.Exit(1)
	}
	path := flag.Arg(0)
	if err := os.MkdirAll(path, 0744); err != nil {
		log.Error("Unable to create path: %v", err)
	}

	s := server.NewServer(path, dbfile, snapAfter, host, port)
	go func() {
		log.Error(s.ListenAndServe(join))
	}()

	terminate := make(chan os.Signal, 1)
	signal.Notify(terminate, os.Interrupt)
	<-terminate
	log.Info("rqlite server stopped")
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	prefixer "github.com/x-cray/logrus-prefixed-formatter"
	"gopkg.in/urfave/cli.v1"
)

var log = logrus.New()
var homedir string

func init() {
	var err error
	log.Formatter = new(prefixer.TextFormatter)
	homedir, err = os.Getwd()
	check(err)
}

func main() {
	app := cli.NewApp()
	app.Name = "Composer - MIT"
	app.Version = "0.0.1"
	app.Author = "mdouchement"
	app.Usage = "Usage:"
	app.Flags = globalFlags
	app.Before = beforeAction

	commands(app)

	err := app.Run(os.Args)
	check(err)
}

var globalFlags = []cli.Flag{
	cli.BoolFlag{
		Name:  "D, verbose",
		Usage: "Increase logger level",
	},
}

func beforeAction(context *cli.Context) error {
	if context.Bool("D") || os.Getenv("APP_DEBUG") == "1" {
		log.Level = logrus.DebugLevel
	}
	return nil
}

func check(err error) {
	if err != nil {
		fail(err.Error())
	}
}
func fail(err string) {
	log.Error(err)
	time.Sleep(100 * time.Millisecond) // Wait logger outputing
	os.Exit(1)
}
<commit_msg>Bump version (0.1.0)<commit_after>package main

import (
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	prefixer "github.com/x-cray/logrus-prefixed-formatter"
	"gopkg.in/urfave/cli.v1"
)

var log = logrus.New()
var homedir string

func init() {
	var err error
	log.Formatter = new(prefixer.TextFormatter)
	homedir, err = os.Getwd()
	check(err)
}

func main() {
	app := cli.NewApp()
	app.Name = "Composer - MIT"
	app.Version = "0.1.0"
	app.Author = "mdouchement"
	app.Usage = "Usage:"
	app.Flags = globalFlags
	app.Before = beforeAction

	commands(app)

	err := app.Run(os.Args)
	check(err)
}

var globalFlags = []cli.Flag{
	cli.BoolFlag{
		Name:  "D, verbose",
		Usage: "Increase logger level",
	},
}

func beforeAction(context *cli.Context) error {
	if context.Bool("D") || os.Getenv("APP_DEBUG") == "1" {
		log.Level = logrus.DebugLevel
	}
	return nil
}

func check(err error) {
	if err != nil {
		fail(err.Error())
	}
}
func fail(err string) {
	log.Error(err)
	time.Sleep(100 * time.Millisecond) // Wait logger outputing
	os.Exit(1)
}
<|endoftext|>