<commit_before>package main

import (
	"fmt"
	"os"
	"bytes"
	"time"
	"encoding/json"
	"text/template"
	"database/sql"
	"strings"
	_ "github.com/go-sql-driver/mysql"
)

type User struct {
	username string
}

type GithubUser struct {
	Id int
	Login string
	Url string
}

// db thing.
type GithubRepo struct {
	pk int
	User string // should probably be Login
	RepoName string // should probably be Name
}

type GithubApiRepo struct {
	Id int
	Owner GithubUser
	Name string
	Description string
}

type Activity struct {
	id int
	github_id int
	activity_type string // should be enum
	created_at time.Time
	Username string
	repo GithubRepo // this isn't going to be memory efficient
	Meta string // full payload of json object
}

type Treeish struct {
	Label string
	Sha string
	Repo GithubApiRepo
	Html_url string
	User GithubUser
}

type PullRequestPayload struct {
	Payload PullRequestMeta
}

type PullRequestMeta struct {
	Number int
	Action string
	Pull_request PullRequest
}

type PullRequest struct {
	Number int
	State string // enum?
	Title string
	Body string
	Head Treeish
	Base Treeish

	// These are in the PR, but aren't any reasons to capture it.

	// Merged_by GithubUser

	// Created_at time.Time
	// Updated_at time.Time
	// Closed_at time.Time
	// Merged_at time.Time

	// Comments int
	// Commits int
	// Additions int
	// Deletions int
	// Changed_files int
}

type PushPayload struct {
	 Payload PushMeta
}

type PushMeta struct {
	Commits []Commit
	Ref string // eg refs/heads/master
	Head string // head SHA
}

type Commit struct {
	Sha string
	Message string
	Author struct {
		Name string
		Email string
	}
}

func (c *Commit) ShortSha() string {
	return c.Sha[0:6]
}

func (c *Commit) ShortCommit() string {
	msg := strings.Split(c.Message, "\n")[0]
	if len(msg) > 80 {
		return msg[0:77] + "..."
	}
	return msg
}

type ActivityPush struct {
	Pushes []PushMeta
	TotalCommits int
}

const long_push_template = `
{{ range .Pushes }}{{range .Commits}}    {{.ShortSha}} {{ .Author.Name }} -- {{ .ShortCommit }}
{{ end }}
{{ end }}`

const short_push_template = `
{{ .TotalCommits }} commits.
{{range $index, $p := .Pushes}}{{range $p.Commits}}{{if $index}}, {{end}}{{.ShortSha}}{{end}}{{end}}
`

type ActivityPullRequest struct {
	PullRequests map[int]PullRequest // number -> pull request
}

const long_pr_template = `
{{range $num, $pr := .PullRequests}}
    {{.Number}} {{.Head.User.Login}} -- {{.Title}}
{{end}}
`
const short_pr_template = `
{{len .PullRequests}} pull requests.
{{range $num, $pr := .PullRequests}}{{$num}}{{end}}
`

// get user's followed users
// get user's followed repos
// for each ^, pull out activity (goroutine)
//   return rendered template bits
// join template bits

// Does not take over ownership of db.
func get_users_repos(db *sql.DB, user_id int) ([]GithubRepo, error) {
	var repo_count int

	// TODO(justinabrahms): Should really alter the schema such
	// that the join from user <-> repo doesn't go through
	// userprofiles.
	row := db.QueryRow("SELECT count(*) FROM streamer_repo r" +
	" JOIN streamer_userprofile_repos upr ON upr.repo_id = r.id " +
	" JOIN streamer_userprofile up ON up.id = upr.userprofile_id" +
	" WHERE up.user_id = ?;", user_id)

	err := row.Scan(&repo_count)
	if (err != nil) {
		return nil, err
	}
	var repos = make([]GithubRepo, repo_count)

	rows, err := db.Query("SELECT r.id, username, project_name FROM streamer_repo r" +
	" JOIN streamer_userprofile_repos upr ON upr.repo_id = r.id " +
	" JOIN streamer_userprofile up ON up.id = upr.userprofile_id" +
	" WHERE up.user_id = ?;", user_id)
	// what's a good way to handle this not working?
	if (err != nil) {
		return nil, err
	}
	defer rows.Close()

	var username, project_name string
	var pk int
	for rows.Next() {
		err = rows.Scan(&pk, &username, &project_name)
		if (err != nil) {
			fmt.Println("Error!: ", err)
		}
		var repo = GithubRepo{pk, username, project_name}
		repos = append(repos, repo)
	}

	return repos, err
}

func get_repo_activity(db *sql.DB, repo *GithubRepo) (activity_list []Activity, err error){
	rows, err := db.Query(
		"SELECT a.id, a.event_id, a.type, a.created_at, ghu.name, r.username, r.project_name, meta FROM streamer_activity a" +
		" JOIN streamer_repo r on r.id=a.repo_id" +
		" JOIN streamer_githubuser ghu on ghu.id=a.user_id" +
		" WHERE repo_id = ?", repo.pk)
	if (err != nil) {
		return nil, err
	}
	defer rows.Close()

	activity_list = make([]Activity, 0)

	var (
		pk, github_id, repo_id int
		activity_type, username, repo_project, repo_user, meta, created_str string
		created_at time.Time
	)

	for rows.Next() {
		err = rows.Scan(&pk, &github_id, &activity_type, &created_str, &username, &repo_user, &repo_project, &meta)
		if (err != nil) {
			fmt.Println("ERR: ", err)
		}

		created_at, err = time.Parse("2006-01-02 15:04:05", created_str)
		if (err != nil) {
			fmt.Println("Can't parse the format of ", created_str)
			return nil, err
		}

		activity_list = append(activity_list,
			Activity{pk, github_id, activity_type, created_at, username,
			GithubRepo{repo_id, repo_user, repo_project}, meta})
	}

	return
}

func pull_request_render(activities []Activity, long_template bool) string {
	var metas = make(map[int]PullRequest, len(activities))
	for _, activity := range activities {
		var payload PullRequestPayload
		err :=json.Unmarshal([]byte(activity.Meta), &payload)
		if err != nil { fmt.Println("Error decoding meta: ", err) }

		metas[payload.Payload.Number] = payload.Payload.Pull_request
	}

	template_input := ActivityPullRequest{metas}
	tmpl := template.New("PullRequestFragment")

	if long_template {
		_, err := tmpl.Parse(long_pr_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	} else {
		_, err := tmpl.Parse(short_pr_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	}

	var b bytes.Buffer
	err := tmpl.Execute(&b, template_input)
	if err != nil { fmt.Println("Error with activity rendering. ", err) }

	return b.String()
}

// Handles taking a list of Push-type activities and returning a formatted template
func push_render(activities []Activity, long_template bool) string {
	var metas = make([]PushMeta, len(activities))
	var total_commits = 0
	for i, activity := range activities {
		var payload PushPayload
		err :=json.Unmarshal([]byte(activity.Meta), &payload)
		if err != nil { fmt.Println("Error decoding meta: ", err) }

		metas[i] = payload.Payload
		total_commits += len(payload.Payload.Commits)
	}

	template_input := ActivityPush{metas, total_commits}
	tmpl := template.New("ActivityFragment")

	if long_template {
		_, err := tmpl.Parse(long_push_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	} else {
		_, err := tmpl.Parse(short_push_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	}

	var b bytes.Buffer
	err := tmpl.Execute(&b, template_input)
	if err != nil { fmt.Println("Error with activity rendering. ", err) }
	return b.String()
}

func repo_to_template(repo GithubRepo, activities []Activity, render_map map[string]interface{}) string {
	var activity_map = make(map[string][]Activity)
	for _, activity := range activities {
		// This seems like a lot of juggling. Is there a better way?
		arr := activity_map[activity.activity_type]
		if (arr == nil) {
			arr = make([]Activity, 0)
			activity_map[activity.activity_type] = arr
		}
		arr = append(arr, activity)
		activity_map[activity.activity_type] = arr
	}

	// activity_map: activity_type => []activity
	var response = ""
	for activity_type, activities := range activity_map {
		_, known_renderer := render_map[activity_type]
		if known_renderer {
			response += render_map[activity_type].(func([]Activity, bool) string)(activities, true)
		} else {
			fmt.Println("Not sure how to render activites of type ", activity_type)
		}
	}
	return response
}

func main() {
	db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/%s?charset=utf8", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_DB")))
	if (err != nil) {
		fmt.Println("Unable to connect to mysql. ", err)
		os.Exit(1)
	}
	defer db.Close()

	// var user_id = 1;
	// repos, err := get_users_repos(db, user_id)
	repo := GithubRepo{43563, "exitio", "schematics"}
	activities, err := get_repo_activity(db, &repo)
	if (err != nil) {
		fmt.Println("ERR: ", err)
		os.Exit(1)
	}

	activity_type_to_renderer := map[string]interface{} {
		"P": push_render,
		"PR": pull_request_render,
	}

	// build map of repo -> activities
	// go routine w/ channel of activities,
	//   throw down activities on per-repo basis
	//   collect them when done and collate.
	response := repo_to_template(repo, activities, activity_type_to_renderer)
	fmt.Println(response)

	return
}
<commit_msg>apparently there are typed functions! Thanks @cbeck!<commit_after>package main

import (
	"fmt"
	"os"
	"bytes"
	"time"
	"encoding/json"
	"text/template"
	"database/sql"
	"strings"
	_ "github.com/go-sql-driver/mysql"
)

type User struct {
	username string
}

type GithubUser struct {
	Id int
	Login string
	Url string
}

// db thing.
type GithubRepo struct {
	pk int
	User string // should probably be Login
	RepoName string // should probably be Name
}

type GithubApiRepo struct {
	Id int
	Owner GithubUser
	Name string
	Description string
}

type Activity struct {
	id int
	github_id int
	activity_type string // should be enum
	created_at time.Time
	Username string
	repo GithubRepo // this isn't going to be memory efficient
	Meta string // full payload of json object
}

type Treeish struct {
	Label string
	Sha string
	Repo GithubApiRepo
	Html_url string
	User GithubUser
}

type PullRequestPayload struct {
	Payload PullRequestMeta
}

type PullRequestMeta struct {
	Number int
	Action string
	Pull_request PullRequest
}

type PullRequest struct {
	Number int
	State string // enum?
	Title string
	Body string
	Head Treeish
	Base Treeish

	// These are in the PR, but aren't any reasons to capture it.

	// Merged_by GithubUser

	// Created_at time.Time
	// Updated_at time.Time
	// Closed_at time.Time
	// Merged_at time.Time

	// Comments int
	// Commits int
	// Additions int
	// Deletions int
	// Changed_files int
}

type PushPayload struct {
	 Payload PushMeta
}

type PushMeta struct {
	Commits []Commit
	Ref string // eg refs/heads/master
	Head string // head SHA
}

type Commit struct {
	Sha string
	Message string
	Author struct {
		Name string
		Email string
	}
}

func (c *Commit) ShortSha() string {
	return c.Sha[0:6]
}

func (c *Commit) ShortCommit() string {
	msg := strings.Split(c.Message, "\n")[0]
	if len(msg) > 80 {
		return msg[0:77] + "..."
	}
	return msg
}

type ActivityPush struct {
	Pushes []PushMeta
	TotalCommits int
}

const long_push_template = `
{{ range .Pushes }}{{range .Commits}}    {{.ShortSha}} {{ .Author.Name }} -- {{ .ShortCommit }}
{{ end }}
{{ end }}`

const short_push_template = `
{{ .TotalCommits }} commits.
{{range $index, $p := .Pushes}}{{range $p.Commits}}{{if $index}}, {{end}}{{.ShortSha}}{{end}}{{end}}
`

type ActivityPullRequest struct {
	PullRequests map[int]PullRequest // number -> pull request
}

const long_pr_template = `
{{range $num, $pr := .PullRequests}}
    {{.Number}} {{.Head.User.Login}} -- {{.Title}}
{{end}}
`
const short_pr_template = `
{{len .PullRequests}} pull requests.
{{range $num, $pr := .PullRequests}}{{$num}}{{end}}
`

// get user's followed users
// get user's followed repos
// for each ^, pull out activity (goroutine)
//   return rendered template bits
// join template bits

// Does not take over ownership of db.
func get_users_repos(db *sql.DB, user_id int) ([]GithubRepo, error) {
	var repo_count int

	// TODO(justinabrahms): Should really alter the schema such
	// that the join from user <-> repo doesn't go through
	// userprofiles.
	row := db.QueryRow("SELECT count(*) FROM streamer_repo r" +
	" JOIN streamer_userprofile_repos upr ON upr.repo_id = r.id " +
	" JOIN streamer_userprofile up ON up.id = upr.userprofile_id" +
	" WHERE up.user_id = ?;", user_id)

	err := row.Scan(&repo_count)
	if (err != nil) {
		return nil, err
	}
	var repos = make([]GithubRepo, repo_count)

	rows, err := db.Query("SELECT r.id, username, project_name FROM streamer_repo r" +
	" JOIN streamer_userprofile_repos upr ON upr.repo_id = r.id " +
	" JOIN streamer_userprofile up ON up.id = upr.userprofile_id" +
	" WHERE up.user_id = ?;", user_id)
	// what's a good way to handle this not working?
	if (err != nil) {
		return nil, err
	}
	defer rows.Close()

	var username, project_name string
	var pk int
	for rows.Next() {
		err = rows.Scan(&pk, &username, &project_name)
		if (err != nil) {
			fmt.Println("Error!: ", err)
		}
		var repo = GithubRepo{pk, username, project_name}
		repos = append(repos, repo)
	}

	return repos, err
}

func get_repo_activity(db *sql.DB, repo *GithubRepo) (activity_list []Activity, err error){
	rows, err := db.Query(
		"SELECT a.id, a.event_id, a.type, a.created_at, ghu.name, r.username, r.project_name, meta FROM streamer_activity a" +
		" JOIN streamer_repo r on r.id=a.repo_id" +
		" JOIN streamer_githubuser ghu on ghu.id=a.user_id" +
		" WHERE repo_id = ?", repo.pk)
	if (err != nil) {
		return nil, err
	}
	defer rows.Close()

	activity_list = make([]Activity, 0)

	var (
		pk, github_id, repo_id int
		activity_type, username, repo_project, repo_user, meta, created_str string
		created_at time.Time
	)

	for rows.Next() {
		err = rows.Scan(&pk, &github_id, &activity_type, &created_str, &username, &repo_user, &repo_project, &meta)
		if (err != nil) {
			fmt.Println("ERR: ", err)
		}

		created_at, err = time.Parse("2006-01-02 15:04:05", created_str)
		if (err != nil) {
			fmt.Println("Can't parse the format of ", created_str)
			return nil, err
		}

		activity_list = append(activity_list,
			Activity{pk, github_id, activity_type, created_at, username,
			GithubRepo{repo_id, repo_user, repo_project}, meta})
	}

	return
}

func pull_request_render(activities []Activity, long_template bool) string {
	var metas = make(map[int]PullRequest, len(activities))
	for _, activity := range activities {
		var payload PullRequestPayload
		err :=json.Unmarshal([]byte(activity.Meta), &payload)
		if err != nil { fmt.Println("Error decoding meta: ", err) }

		metas[payload.Payload.Number] = payload.Payload.Pull_request
	}

	template_input := ActivityPullRequest{metas}
	tmpl := template.New("PullRequestFragment")

	if long_template {
		_, err := tmpl.Parse(long_pr_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	} else {
		_, err := tmpl.Parse(short_pr_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	}

	var b bytes.Buffer
	err := tmpl.Execute(&b, template_input)
	if err != nil { fmt.Println("Error with activity rendering. ", err) }

	return b.String()
}

// Handles taking a list of Push-type activities and returning a formatted template
func push_render(activities []Activity, long_template bool) string {
	var metas = make([]PushMeta, len(activities))
	var total_commits = 0
	for i, activity := range activities {
		var payload PushPayload
		err :=json.Unmarshal([]byte(activity.Meta), &payload)
		if err != nil { fmt.Println("Error decoding meta: ", err) }

		metas[i] = payload.Payload
		total_commits += len(payload.Payload.Commits)
	}

	template_input := ActivityPush{metas, total_commits}
	tmpl := template.New("ActivityFragment")

	if long_template {
		_, err := tmpl.Parse(long_push_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	} else {
		_, err := tmpl.Parse(short_push_template)
		if err != nil { fmt.Println("Error with activity fragment parsing. ", err) }
	}

	var b bytes.Buffer
	err := tmpl.Execute(&b, template_input)
	if err != nil { fmt.Println("Error with activity rendering. ", err) }
	return b.String()
}

func repo_to_template(repo GithubRepo, activities []Activity, render_map map[string]func([]Activity, bool)string) string {
	var activity_map = make(map[string][]Activity)
	for _, activity := range activities {
		// This seems like a lot of juggling. Is there a better way?
		arr := activity_map[activity.activity_type]
		if (arr == nil) {
			arr = make([]Activity, 0)
			activity_map[activity.activity_type] = arr
		}
		arr = append(arr, activity)
		activity_map[activity.activity_type] = arr
	}

	// activity_map: activity_type => []activity
	var response = ""
	for activity_type, activities := range activity_map {
		fn, ok := render_map[activity_type]
		if ok {
			response += fn(activities, true)
		} else {
			fmt.Println("Not sure how to render activites of type ", activity_type)
		}
	}
	return response
}

func main() {
	db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/%s?charset=utf8", os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_DB")))
	if (err != nil) {
		fmt.Println("Unable to connect to mysql. ", err)
		os.Exit(1)
	}
	defer db.Close()

	// var user_id = 1;
	// repos, err := get_users_repos(db, user_id)
	repo := GithubRepo{43563, "exitio", "schematics"}
	activities, err := get_repo_activity(db, &repo)
	if (err != nil) {
		fmt.Println("ERR: ", err)
		os.Exit(1)
	}

	activity_type_to_renderer := map[string]func([]Activity, bool)string {
		"P": push_render,
		"PR": pull_request_render,
	}

	// build map of repo -> activities
	// go routine w/ channel of activities,
	//   throw down activities on per-repo basis
	//   collect them when done and collate.
	response := repo_to_template(repo, activities, activity_type_to_renderer)
	fmt.Println(response)

	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/binary"
	"fmt"
	"log"
	"net"
	"os"
	"syscall"
	"unsafe"
)

/*
#cgo CFLAGS: -Wall -Wno-unused-variable
#cgo LDFLAGS: -lelf

#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <poll.h>
#include <errno.h>
#include <linux/bpf.h>
#include "libbpf.h"
#include "bpf_load.h"
#include "perf_utils.h"

extern void tcpEventCb();

#define TASK_COMM_LEN 16

struct tcp_event_t {
    char ev_type[12];
    __u32 pid;
    char comm[TASK_COMM_LEN];
    __u32 saddr;
    __u32 daddr;
    __u16 sport;
    __u16 dport;
    __u32 netns;
};
*/
import "C"

var (
	pmuFD C.int
)

/*
type tcpEvent struct {
	pid   uint32
	sIP   net.IP
	dIP   net.IP
	sPort uint16
	dPort uint16
	netns uint32
	comm  [16]byte
}
*/

//export tcpEventCb
func tcpEventCb(data unsafe.Pointer, size int) {
	tcpEvent := (*C.struct_tcp_event_t)(data)

	typ := C.GoString(&tcpEvent.ev_type[0])
	pid := tcpEvent.pid & 0xffffffff

	saddrbuf := make([]byte, 4)
	daddrbuf := make([]byte, 4)

	binary.LittleEndian.PutUint32(saddrbuf, uint32(tcpEvent.saddr))
	binary.LittleEndian.PutUint32(daddrbuf, uint32(tcpEvent.daddr))

	sIP := net.IPv4(saddrbuf[0], saddrbuf[1], saddrbuf[2], saddrbuf[3])
	dIP := net.IPv4(daddrbuf[0], daddrbuf[1], daddrbuf[2], daddrbuf[3])

	sport := tcpEvent.sport
	dport := tcpEvent.dport
	netns := tcpEvent.netns

	fmt.Println(typ)
	fmt.Println(pid)
	fmt.Println(sIP)
	fmt.Println(dIP)
	fmt.Println(sport)
	fmt.Println(dport)
	fmt.Println(netns)
	fmt.Println()
}

func perfEventMmap(fd int) error {
	pageSize := os.Getpagesize()
	mmapSize := pageSize * (C.PAGE_COUNT + 1)

	base, err := syscall.Mmap(fd, 0, mmapSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
	if err != nil {
		return fmt.Errorf("mmap error: %v", err)
	}

	C.header = (*C.struct_perf_event_mmap_page)(unsafe.Pointer(&base[0]))

	return nil
}

func perfEventPoll(fd int) error {
	var pfd C.struct_pollfd

	pfd.fd = C.int(fd)
	pfd.events = C.POLLIN

	_, err := C.poll(&pfd, 1, 20)
	if err != nil {
		return fmt.Errorf("error polling: %v", err.(syscall.Errno))
	}

	return nil
}

func testBpfPerfEvent() {
	var attr C.struct_perf_event_attr

	attr.sample_type = C.PERF_SAMPLE_RAW
	attr._type = C.PERF_TYPE_SOFTWARE
	attr.config = C.PERF_COUNT_SW_BPF_OUTPUT

	key := 0

	pmuFD = C.perf_event_open(&attr, -1 /* pid */, 0 /* cpu */, -1 /* group_fd */, 0)

	ret := C.bpf_update_elem(C.map_fd[0], unsafe.Pointer(&key), unsafe.Pointer(&pmuFD), C.BPF_ANY)
	if ret != 0 {
		log.Fatal("bpf_update_elem error: %d", syscall.Errno(ret))
	}

	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(pmuFD), C.PERF_EVENT_IOC_ENABLE, 0)
	if err != 0 {
		log.Fatal("lol error")
	}
}

func main() {
	fmt.Println("Ready.\n")

	bpfObjectFile := C.CString("kernel/trace_output_kern.o")
	defer C.free(unsafe.Pointer(bpfObjectFile))

	ret := C.load_bpf_file(bpfObjectFile)
	if ret != 0 {
		fmt.Fprintf(os.Stderr, "load_bpf_file error: %v\n", syscall.Errno(ret))
		os.Exit(1)
	}

	testBpfPerfEvent()

	if err := perfEventMmap(int(pmuFD)); err != nil {
		fmt.Fprintf(os.Stderr, "perfEventMmap error: %v\n", ret)
		os.Exit(1)
	}

	for {
		perfEventPoll(int(pmuFD))
		C.perf_event_read((*[0]byte)(C.tcpEventCb))
	}
}
<commit_msg>Don't laugh<commit_after>package main

import (
	"encoding/binary"
	"fmt"
	"log"
	"net"
	"os"
	"syscall"
	"unsafe"
)

/*
#cgo CFLAGS: -Wall -Wno-unused-variable
#cgo LDFLAGS: -lelf

#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <poll.h>
#include <errno.h>
#include <linux/bpf.h>
#include "libbpf.h"
#include "bpf_load.h"
#include "perf_utils.h"

extern void tcpEventCb();

#define TASK_COMM_LEN 16

struct tcp_event_t {
    char ev_type[12];
    __u32 pid;
    char comm[TASK_COMM_LEN];
    __u32 saddr;
    __u32 daddr;
    __u16 sport;
    __u16 dport;
    __u32 netns;
};
*/
import "C"

var (
	pmuFD C.int
)

/*
type tcpEvent struct {
	pid   uint32
	sIP   net.IP
	dIP   net.IP
	sPort uint16
	dPort uint16
	netns uint32
	comm  [16]byte
}
*/

//export tcpEventCb
func tcpEventCb(data unsafe.Pointer, size int) {
	tcpEvent := (*C.struct_tcp_event_t)(data)

	typ := C.GoString(&tcpEvent.ev_type[0])
	pid := tcpEvent.pid & 0xffffffff

	saddrbuf := make([]byte, 4)
	daddrbuf := make([]byte, 4)

	binary.LittleEndian.PutUint32(saddrbuf, uint32(tcpEvent.saddr))
	binary.LittleEndian.PutUint32(daddrbuf, uint32(tcpEvent.daddr))

	sIP := net.IPv4(saddrbuf[0], saddrbuf[1], saddrbuf[2], saddrbuf[3])
	dIP := net.IPv4(daddrbuf[0], daddrbuf[1], daddrbuf[2], daddrbuf[3])

	sport := tcpEvent.sport
	dport := tcpEvent.dport
	netns := tcpEvent.netns

	fmt.Println(typ)
	fmt.Println(pid)
	fmt.Println(sIP)
	fmt.Println(dIP)
	fmt.Println(sport)
	fmt.Println(dport)
	fmt.Println(netns)
	fmt.Println()
}

func perfEventMmap(fd int) error {
	pageSize := os.Getpagesize()
	mmapSize := pageSize * (C.PAGE_COUNT + 1)

	base, err := syscall.Mmap(fd, 0, mmapSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
	if err != nil {
		return fmt.Errorf("mmap error: %v", err)
	}

	C.header = (*C.struct_perf_event_mmap_page)(unsafe.Pointer(&base[0]))

	return nil
}

func perfEventPoll(fd int) error {
	var pfd C.struct_pollfd

	pfd.fd = C.int(fd)
	pfd.events = C.POLLIN

	_, err := C.poll(&pfd, 1, 20)
	if err != nil {
		return fmt.Errorf("error polling: %v", err.(syscall.Errno))
	}

	return nil
}

func testBpfPerfEvent() {
	var attr C.struct_perf_event_attr

	attr.sample_type = C.PERF_SAMPLE_RAW
	attr._type = C.PERF_TYPE_SOFTWARE
	attr.config = C.PERF_COUNT_SW_BPF_OUTPUT

	key := 0

	pmuFD = C.perf_event_open(&attr, -1 /* pid */, 0 /* cpu */, -1 /* group_fd */, 0)

	ret := C.bpf_update_elem(C.map_fd[0], unsafe.Pointer(&key), unsafe.Pointer(&pmuFD), C.BPF_ANY)
	if ret != 0 {
		log.Fatal("bpf_update_elem error: %d", syscall.Errno(ret))
	}

	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(pmuFD), C.PERF_EVENT_IOC_ENABLE, 0)
	if err != 0 {
		log.Fatal("error enabling perf event: %v", err)
	}
}

func main() {
	fmt.Println("Ready.\n")

	bpfObjectFile := C.CString("kernel/trace_output_kern.o")
	defer C.free(unsafe.Pointer(bpfObjectFile))

	ret := C.load_bpf_file(bpfObjectFile)
	if ret != 0 {
		fmt.Fprintf(os.Stderr, "load_bpf_file error: %v\n", syscall.Errno(ret))
		os.Exit(1)
	}

	testBpfPerfEvent()

	if err := perfEventMmap(int(pmuFD)); err != nil {
		fmt.Fprintf(os.Stderr, "perfEventMmap error: %v\n", ret)
		os.Exit(1)
	}

	for {
		perfEventPoll(int(pmuFD))
		C.perf_event_read((*[0]byte)(C.tcpEventCb))
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 crane authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/tsuru/tsuru/cmd"
	"os"
)

const (
	version = "0.5.3"
	header  = "Supported-Crane"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&ServiceCreate{})
	m.Register(&ServiceRemove{})
	m.Register(&ServiceList{})
	m.Register(&ServiceUpdate{})
	m.Register(&ServiceDocGet{})
	m.Register(&ServiceDocAdd{})
	m.Register(&ServiceTemplate{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<commit_msg>main: bump to 0.5.4<commit_after>// Copyright 2014 crane authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/tsuru/tsuru/cmd"
	"os"
)

const (
	version = "0.5.4"
	header  = "Supported-Crane"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&ServiceCreate{})
	m.Register(&ServiceRemove{})
	m.Register(&ServiceList{})
	m.Register(&ServiceUpdate{})
	m.Register(&ServiceDocGet{})
	m.Register(&ServiceDocAdd{})
	m.Register(&ServiceTemplate{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"log"
	"os"
	"strings"
)

func Prompt(prompt string) (ret string) {
	input := bufio.NewReader(os.Stdin)
	os.Stdout.Write([]byte(prompt))
	for {
		line, isPrefix, err := input.ReadLine()
		if err != nil {
			return
		}
		ret += string(line)
		if !isPrefix {
			break
		}
	}
	ret = strings.TrimSpace(ret)
	return
}

func MakeAccount() {
	name := Prompt("Name: ")
	pass := Prompt("Password: ")
	displayName := Prompt("Display name: ")

	account := NewAccount()
	account.Name = name
	account.DisplayName = displayName
	account.SetPassword(pass)
	err := account.Save()
	if err != nil {
		logr.Errln("Error saving new account:", err.Error())
	}
}

func main() {
	var dsn string
	var makeaccount, initdb, upgradedb bool
	var importthinkup, importjson string
	var port int
	flag.StringVar(&dsn, "database", "dbname=cares sslmode=disable", "database connection info")
	flag.BoolVar(&makeaccount, "make-account", false, "create a new account interactively")
	flag.BoolVar(&initdb, "init-db", false, "initialize the database")
	flag.BoolVar(&upgradedb, "upgrade-db", false, "upgrade the database schema")
	flag.StringVar(&importthinkup, "import-thinkup", "", "path to a Thinkup CSV export to import")
	flag.StringVar(&importjson, "import-json", "", "path to a directory of Twitter JSON to import")
	flag.IntVar(&port, "port", 8080, "port on which to serve the web interface")
	flag.Parse()

	err := SetUpLogger()
	if err != nil {
		log.Println("Error setting up logging:", err.Error())
		return
	}
	defer logr.Close()

	err = OpenDatabase(dsn, upgradedb)
	if err != nil {
		logr.Errln("Error connecting to database:", err.Error())
		return
	}

	if initdb {
		InitializeDatabase()
	} else if upgradedb {
		UpgradeDatabase()
	} else if makeaccount {
		MakeAccount()
	} else if importjson != "" {
		ImportJson(importjson)
	} else if importthinkup != "" {
		ImportThinkup(importthinkup)
	} else {
		ServeWeb(port)
	}
}
<commit_msg>Create an author for the owner's account too<commit_after>package main

import (
	"bufio"
	"flag"
	"log"
	"os"
	"strings"
)

func Prompt(prompt string) (ret string) {
	input := bufio.NewReader(os.Stdin)
	os.Stdout.Write([]byte(prompt))
	for {
		line, isPrefix, err := input.ReadLine()
		if err != nil {
			return
		}
		ret += string(line)
		if !isPrefix {
			break
		}
	}
	ret = strings.TrimSpace(ret)
	return
}

func MakeAccount() {
	var err error

	name := Prompt("Name: ")
	pass := Prompt("Password: ")
	displayName := Prompt("Display name: ")

	author := NewAuthor()
	author.Name = displayName
	author.Url = "/"
	err = author.Save()
	if err != nil {
		logr.Errln("Error saving new account:", err.Error())
		return
	}

	account := NewAccount()
	account.Name = name
	account.DisplayName = displayName
	account.SetPassword(pass)
	err = account.Save()
	if err != nil {
		logr.Errln("Error saving new account:", err.Error())
		return
	}
}

func main() {
	var dsn string
	var makeaccount, initdb, upgradedb bool
	var importthinkup, importjson string
	var port int
	flag.StringVar(&dsn, "database", "dbname=cares sslmode=disable", "database connection info")
	flag.BoolVar(&makeaccount, "make-account", false, "create a new account interactively")
	flag.BoolVar(&initdb, "init-db", false, "initialize the database")
	flag.BoolVar(&upgradedb, "upgrade-db", false, "upgrade the database schema")
	flag.StringVar(&importthinkup, "import-thinkup", "", "path to a Thinkup CSV export to import")
	flag.StringVar(&importjson, "import-json", "", "path to a directory of Twitter JSON to import")
	flag.IntVar(&port, "port", 8080, "port on which to serve the web interface")
	flag.Parse()

	err := SetUpLogger()
	if err != nil {
		log.Println("Error setting up logging:", err.Error())
		return
	}
	defer logr.Close()

	err = OpenDatabase(dsn, upgradedb)
	if err != nil {
		logr.Errln("Error connecting to database:", err.Error())
		return
	}

	if initdb {
		InitializeDatabase()
	} else if upgradedb {
		UpgradeDatabase()
	} else if makeaccount {
		MakeAccount()
	} else if importjson != "" {
		ImportJson(importjson)
	} else if importthinkup != "" {
		ImportThinkup(importthinkup)
	} else {
		ServeWeb(port)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

var color = "blue"
var version = os.Getenv("VERSION")
var redisUrl = os.Getenv("REDIS_URL")
var rdb = redis.NewClient(&redis.Options{
	Addr:     redisUrl,
	Password: "", // no password set
	DB:       0,  // use default DB
})
var rdbCtx = context.Background()

func main() {
	port := ":8080"

	flag.Parse()

	r := gin.Default()
	log.Printf("Backend version: %s\n", version)

	r.LoadHTMLGlob("index.html")
	r.GET("/", handleIndex)
	r.GET("/version", handleVersion)
	r.GET("/healthz", handleHealthz)

	srv := &http.Server{
		Addr:    port,
		Handler: r,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with
	// a timeout of 5 seconds.
	quit := make(chan os.Signal, 1)
	// kill (no param) default send syscall.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutting down server...")

	// The context is used to inform the server it has 5 seconds to finish
	// the request it is currently handling
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server forced to shutdown:", err)
	}

	log.Println("Server exiting")
}

func handleIndex(c *gin.Context) {
	log.Printf("Received request from %s at %s", c.Request.RemoteAddr, c.Request.URL.EscapedPath())
	p := PodMetadata{}
	counter, err := incrCounter(c)
	if err != nil {
		c.String(http.StatusInternalServerError, "%v", err)
		return
	}
	err = p.Populate(version, counter, color)
	if err != nil {
		c.String(http.StatusInternalServerError, "%v", err)
		return
	}
	c.HTML(http.StatusOK, "index.html", p)
}

func incrCounter(c *gin.Context) (string, error) {
	err := rdb.Incr(rdbCtx, "counter").Err()
	if err != nil {
		return "", err
	}
	val, err := rdb.Get(rdbCtx, "counter").Result()
	if err != nil {
		return "", err
	}
	return val, nil
}

func handleVersion(c *gin.Context) {
	c.String(http.StatusOK, "%s", c.Value("version"))
}

func handleHealthz(c *gin.Context) {
	c.String(http.StatusOK, "", "")
}

// PodMetadata represents info about an InstanceMetadata in GCE
type PodMetadata struct {
	Name       string
	Namespace  string
	HostIP     string
	PodIP      string
	StartTime  string
	RawRequest string
	Counter    string
	Version    string
	Color      string
}

// Populate creates a new instance with info filled out
func (p *PodMetadata) Populate(version string, counter string, color string) error {
	hostname := os.Getenv("HOSTNAME")
	config, err := rest.InClusterConfig()
	if err != nil {
		return fmt.Errorf("unable to create InClusterConfig client: %v", err)
	}
	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("unable to create kubernetes client: %v", err)
	}

	pod, err := clientset.CoreV1().Pods(getNamespace()).Get(context.TODO(), hostname, v1.GetOptions{})
	if err != nil {
		return fmt.Errorf("unable to find pod %s: %v", hostname, err)
	}
	p.Name = pod.Name
	p.HostIP = pod.Status.HostIP
	p.Namespace = pod.Namespace
	p.PodIP = pod.Status.PodIP
	p.StartTime = pod.Status.StartTime.String()
	p.Counter = counter
	p.Version = version
	p.Color = color
	return nil
}

func getNamespace() string {
	// Fall back to the namespace associated with the service account token, if available
	if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
		if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
			return ns
		}
	}
	return "default"
}
<commit_msg>Make it green<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

var color = "green"
var version = os.Getenv("VERSION")
var redisUrl = os.Getenv("REDIS_URL")
var rdb = redis.NewClient(&redis.Options{
	Addr:     redisUrl,
	Password: "", // no password set
	DB:       0,  // use default DB
})
var rdbCtx = context.Background()

func main() {
	port := ":8080"

	flag.Parse()

	r := gin.Default()
	log.Printf("Backend version: %s\n", version)

	r.LoadHTMLGlob("index.html")
	r.GET("/", handleIndex)
	r.GET("/version", handleVersion)
	r.GET("/healthz", handleHealthz)

	srv := &http.Server{
		Addr:    port,
		Handler: r,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with
	// a timeout of 5 seconds.
	quit := make(chan os.Signal, 1)
	// kill (no param) default send syscall.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutting down server...")

	// The context is used to inform the server it has 5 seconds to finish
	// the request it is currently handling
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server forced to shutdown:", err)
	}

	log.Println("Server exiting")
}

func handleIndex(c *gin.Context) {
	log.Printf("Received request from %s at %s", c.Request.RemoteAddr, c.Request.URL.EscapedPath())
	p := PodMetadata{}
	counter, err := incrCounter(c)
	if err != nil {
		c.String(http.StatusInternalServerError, "%v", err)
		return
	}
	err = p.Populate(version, counter, color)
	if err != nil {
		c.String(http.StatusInternalServerError, "%v", err)
		return
	}
	c.HTML(http.StatusOK, "index.html", p)
}

func incrCounter(c *gin.Context) (string, error) {
	err := rdb.Incr(rdbCtx, "counter").Err()
	if err != nil {
		return "", err
	}
	val, err := rdb.Get(rdbCtx, "counter").Result()
	if err != nil {
		return "", err
	}
	return val, nil
}

func handleVersion(c *gin.Context) {
	c.String(http.StatusOK, "%s", c.Value("version"))
}

func handleHealthz(c *gin.Context) {
	c.String(http.StatusOK, "", "")
}

// PodMetadata represents info about an InstanceMetadata in GCE
type PodMetadata struct {
	Name       string
	Namespace  string
	HostIP     string
	PodIP      string
	StartTime  string
	RawRequest string
	Counter    string
	Version    string
	Color      string
}

// Populate creates a new instance with info filled out
func (p *PodMetadata) Populate(version string, counter string, color string) error {
	hostname := os.Getenv("HOSTNAME")
	config, err := rest.InClusterConfig()
	if err != nil {
		return fmt.Errorf("unable to create InClusterConfig client: %v", err)
	}
	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("unable to create kubernetes client: %v", err)
	}

	pod, err := clientset.CoreV1().Pods(getNamespace()).Get(context.TODO(), hostname, v1.GetOptions{})
	if err != nil {
		return fmt.Errorf("unable to find pod %s: %v", hostname, err)
	}
	p.Name = pod.Name
	p.HostIP = pod.Status.HostIP
	p.Namespace = pod.Namespace
	p.PodIP = pod.Status.PodIP
	p.StartTime = pod.Status.StartTime.String()
	p.Counter = counter
	p.Version = version
	p.Color = color
	return nil
}

func getNamespace() string {
	// Fall back to the namespace associated with the service account token, if available
	if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
		if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
			return ns
		}
	}
	return "default"
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 Chadev. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os"

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

// VERSION contians the current verison number and revison if need be
const VERSION = "2015-03-05"

// handler is an interface for objects to implement in order to respond to messages.
type handler interface {
	Handle(res *hal.Response) error
}

var helpMessages = make(map[string]string)

var pingHandler = hear(`ping`, "ping", "Causes Ash to reply with PONG", func(res *hal.Response) error {
	return res.Send("PONG")
})

var fooHandler = hear(`foo`, "foo", "Causes Ash to reply with a BAR", func(res *hal.Response) error {
	return res.Send("BAR")
})

var synHandler = hear(`SYN`, "SYN", "Causes Ash to reply with ACK", func(res *hal.Response) error {
	return res.Send("ACK")
})

var selfHandler = hear(`who are you`, "self", "", func(res *hal.Response) error {
	return res.Send("I'm Ash, the friendly #chadev bot.  I can preform a variety of tasks, and I am learning new tricks all the time.  I am open source, and pull requests are welcome!")
})

var quitHandler = hear(`(.*)+/quit(.*)+`, "quit", "", func(res *hal.Response) error {
	name := res.UserName()
	return res.Send(fmt.Sprintf("No!  Bad %s!", name))
})

var helpHandler = hear(`help`, "help", "Displays this message", func(res *hal.Response) error {
	helpMsg := []string{
		"HAL Chadev IRC Edition build: " + VERSION + "\n",
		"Supported commands:\n",
	}

	for command, message := range helpMessages {
		if command != "" && message != "" {
			helpMsg = append(helpMsg, command+" - "+message+"\n")
		}
	}

	var text string
	for _, msg := range helpMsg {
		text = text + msg
	}

	text = uploadHelpMsg(text)
	res.Send(fmt.Sprintf("My usage information can be found at %s", text))

	return nil
})

func hear(pattern string, command string, message string, fn func(res *hal.Response) error) handler {
	addHelpMessage(command, message)
	return hal.Hear("^(?i)Ash "+pattern, fn)
}

func addHelpMessage(command string, message string) {
	helpMessages[command] = message
}

func main() {
	os.Exit(run())
}

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

	robot.Handle(
		fooHandler,
		tableFlipHandler,
		eventHandler,
		synHandler,
		helpHandler,
		pingHandler,
		sourceHandler,
		issueHandler,
		cageMeHandler,
		whoisHandler,
		whoamHandler,
		isHandler,
		selfHandler,
		quitHandler,
		fizzBuzzHandler,
		noteStoreHandler,
		noteGetHandler,
		noteRemoveHandler,
		chadevCountHandler,
		chadevListAllHandler,
		chadevInfoHandler,
		fatherHandler,
		partyHandler,
		whoBackHandler,
		whatAreHandler,
		musicHandler,
		lunchHandler,
		talkHandler,
		addTalkHandler,
		devTalkLinkHandler,
		isAliveHandler,
	)

	if err := robot.Run(); err != nil {
		hal.Logger.Error(err)
		return 1
	}
	return 0
}
<commit_msg>Version bump<commit_after>// Copyright 2014-2015 Chadev. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os"

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

// VERSION contians the current verison number and revison if need be
const VERSION = "2015-04-15"

// handler is an interface for objects to implement in order to respond to messages.
type handler interface {
	Handle(res *hal.Response) error
}

var helpMessages = make(map[string]string)

var pingHandler = hear(`ping`, "ping", "Causes Ash to reply with PONG", func(res *hal.Response) error {
	return res.Send("PONG")
})

var fooHandler = hear(`foo`, "foo", "Causes Ash to reply with a BAR", func(res *hal.Response) error {
	return res.Send("BAR")
})

var synHandler = hear(`SYN`, "SYN", "Causes Ash to reply with ACK", func(res *hal.Response) error {
	return res.Send("ACK")
})

var selfHandler = hear(`who are you`, "self", "", func(res *hal.Response) error {
	return res.Send("I'm Ash, the friendly #chadev bot.  I can preform a variety of tasks, and I am learning new tricks all the time.  I am open source, and pull requests are welcome!")
})

var quitHandler = hear(`(.*)+/quit(.*)+`, "quit", "", func(res *hal.Response) error {
	name := res.UserName()
	return res.Send(fmt.Sprintf("No!  Bad %s!", name))
})

var helpHandler = hear(`help`, "help", "Displays this message", func(res *hal.Response) error {
	helpMsg := []string{
		"HAL Chadev IRC Edition build: " + VERSION + "\n",
		"Supported commands:\n",
	}

	for command, message := range helpMessages {
		if command != "" && message != "" {
			helpMsg = append(helpMsg, command+" - "+message+"\n")
		}
	}

	var text string
	for _, msg := range helpMsg {
		text = text + msg
	}

	text = uploadHelpMsg(text)
	res.Send(fmt.Sprintf("My usage information can be found at %s", text))

	return nil
})

func hear(pattern string, command string, message string, fn func(res *hal.Response) error) handler {
	addHelpMessage(command, message)
	return hal.Hear("^(?i)Ash "+pattern, fn)
}

func addHelpMessage(command string, message string) {
	helpMessages[command] = message
}

func main() {
	os.Exit(run())
}

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

	robot.Handle(
		fooHandler,
		tableFlipHandler,
		eventHandler,
		synHandler,
		helpHandler,
		pingHandler,
		sourceHandler,
		issueHandler,
		cageMeHandler,
		whoisHandler,
		whoamHandler,
		isHandler,
		selfHandler,
		quitHandler,
		fizzBuzzHandler,
		noteStoreHandler,
		noteGetHandler,
		noteRemoveHandler,
		chadevCountHandler,
		chadevListAllHandler,
		chadevInfoHandler,
		fatherHandler,
		partyHandler,
		whoBackHandler,
		whatAreHandler,
		musicHandler,
		lunchHandler,
		talkHandler,
		addTalkHandler,
		devTalkLinkHandler,
		isAliveHandler,
	)

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


<commit_before>package main

import (
	"fmt"
	"github.com/jessevdk/go-flags"
	"github.com/martinp/nadapi/api"
	"github.com/martinp/nadapi/nad"
	"log"
	"os"
)

func main() {
	var opts struct {
		Device       string `short:"d" long:"device" description:"Path to serial device" value-name:"FILE" required:"true"`
		EnableVolume bool   `short:"x" long:"volume" description:"Allow volume adjustment. Use with caution!"`
	}

	var server struct {
		Listen string `short:"l" long:"listen" description:"Listen address" value-name:"ADDR" default:":8080"`
	}

	var cli struct {
		Command string `short:"c" long:"command" description:"Command to send" required:"true"`
	}

	p := flags.NewParser(&opts, flags.Default)
	serverCmd, err := p.AddCommand("server", "Serve API",
		"REST API for NAD amplifier.", &server)
	if err != nil {
		log.Fatal(err)
	}
	cliCmd, err := p.AddCommand("cli", "Send command",
		"Send command to a NAD amplifier.", &cli)
	if err != nil {
		log.Fatal(err)
	}

	if _, err := p.Parse(); err != nil {
		os.Exit(1)
	}

	nad, err := nad.New(opts.Device)
	if err != nil {
		log.Fatal(err)
	}
	nad.EnableVolume = opts.EnableVolume

	api := api.New(nad)
	if p.Active == serverCmd {
		log.Printf("Listening on %s", server.Listen)
		if err := api.ListenAndServe(server.Listen); err != nil {
			log.Fatal(err)
		}
	} else if p.Active == cliCmd {
		reply, err := nad.SendString(cli.Command)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(reply)
	}
}
<commit_msg>Cleanup<commit_after>package main

import (
	"fmt"
	"github.com/jessevdk/go-flags"
	"github.com/martinp/nadapi/api"
	"github.com/martinp/nadapi/nad"
	"log"
	"os"
)

func main() {
	var opts struct {
		Device       string `short:"d" long:"device" description:"Path to serial device" value-name:"FILE" required:"true"`
		EnableVolume bool   `short:"x" long:"volume" description:"Allow volume adjustment. Use with caution!"`
	}

	var server struct {
		Listen string `short:"l" long:"listen" description:"Listen address" value-name:"ADDR" default:":8080"`
	}

	var cli struct {
		Command string `short:"c" long:"command" description:"Command to send" required:"true"`
	}

	p := flags.NewParser(&opts, flags.Default)
	if _, err := p.AddCommand("server", "Start API server",
		"REST API for NAD amplifier.", &server); err != nil {
		log.Fatal(err)
	}
	if _, err := p.AddCommand("cli", "Send command",
		"Send command to NAD amplifier.", &cli); err != nil {
		log.Fatal(err)
	}

	if _, err := p.Parse(); err != nil {
		os.Exit(1)
	}

	nad, err := nad.New(opts.Device)
	if err != nil {
		log.Fatal(err)
	}
	nad.EnableVolume = opts.EnableVolume

	switch p.Active.Name {
	case "server":
		api := api.New(nad)
		log.Printf("Listening on %s", server.Listen)
		if err := api.ListenAndServe(server.Listen); err != nil {
			log.Fatal(err)
		}
	case "cli":
		reply, err := nad.SendString(cli.Command)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(reply)
	default:
		log.Fatal("unknown subcommand")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/evolsnow/robot/conn"
	"golang.org/x/net/websocket"
	"io"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func main() {
	var configFile string
	var debug bool
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.BoolVar(&debug, "d", false, "debug mode")

	flag.Parse()
	config, err := ParseConfig(configFile)
	if err != nil {
		log.Fatal("a vailid json config file must exist")
	}

	redisPort := strconv.Itoa(config.RedisPort)
	redisServer := net.JoinHostPort(config.RedisAddress, redisPort)
	if !conn.Ping(redisServer, config.RedisPassword) {
		log.Fatal("connect to redis server failed")
	}
	conn.Pool = conn.NewPool(redisServer, config.RedisPassword, config.RedisDB)
	robot := newRobot(config.RobotToken, config.RobotName, config.WebHookUrl)
	robot.bot.Debug = debug
	go robot.run()
	srvPort := strconv.Itoa(config.Port)
	http.HandleFunc("/ajax", ajax)
	http.Handle("/websocket", websocket.Handler(socketHandler))
	//	log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Server, srvPort), nil))
	log.Fatal(http.ListenAndServeTLS(net.JoinHostPort(config.Server, srvPort), config.Cert, config.CertKey, nil))

}

//used for web samaritan robot
func socketHandler(ws *websocket.Conn) {
	for {
		var in, response string
		var ret []string
		sf := func(c rune) bool {
			return c == ',' || c == '，' || c == ';' || c == '。' || c == '.' || c == '？' || c == '?'
		}
		if err := websocket.Message.Receive(ws, &in); err != nil {
			log.Println(err)
			return
		}
		fmt.Printf("Received: %s\n", in)
		zh := false
		for _, r := range in {
			if unicode.Is(unicode.Scripts["Han"], r) {
				log.Printf(in)
				zh = true
				break
			}
		}
		if zh {
			response = tlAI(in)
			// Separate into fields with func.
			ret = strings.FieldsFunc(response, sf)

		} else {
			response = mitAI(in)
			ret = strings.FieldsFunc(response, sf)
		}
		for i := range ret {
			websocket.Message.Send(ws, ret[i])
			time.Sleep(time.Second)
		}
		websocket.Message.Send(ws, "")
	}
}
func ajax(w http.ResponseWriter, r *http.Request) {
	var messages = make(chan string)
	w.Header().Add("Access-Control-Allow-Origin", "*")
	go func() {
		for {
			time.Sleep(time.Second * 2)
			log.Println("hi")
			messages <- "from ajax"
		}
	}()
	io.WriteString(w, <-messages)
}
<commit_msg>make chan<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/evolsnow/robot/conn"
	"golang.org/x/net/websocket"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func main() {
	var configFile string
	var debug bool
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.BoolVar(&debug, "d", false, "debug mode")

	flag.Parse()
	config, err := ParseConfig(configFile)
	if err != nil {
		log.Fatal("a vailid json config file must exist")
	}

	redisPort := strconv.Itoa(config.RedisPort)
	redisServer := net.JoinHostPort(config.RedisAddress, redisPort)
	if !conn.Ping(redisServer, config.RedisPassword) {
		log.Fatal("connect to redis server failed")
	}
	conn.Pool = conn.NewPool(redisServer, config.RedisPassword, config.RedisDB)
	robot := newRobot(config.RobotToken, config.RobotName, config.WebHookUrl)
	robot.bot.Debug = debug
	go robot.run()
	srvPort := strconv.Itoa(config.Port)
	http.HandleFunc("/ajax", ajax)
	http.Handle("/websocket", websocket.Handler(socketHandler))
	//	log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Server, srvPort), nil))
	log.Fatal(http.ListenAndServeTLS(net.JoinHostPort(config.Server, srvPort), config.Cert, config.CertKey, nil))

}

//used for web samaritan robot
func socketHandler(ws *websocket.Conn) {
	for {
		var in, response string
		var ret []string
		sf := func(c rune) bool {
			return c == ',' || c == '，' || c == ';' || c == '。' || c == '.' || c == '？' || c == '?'
		}
		if err := websocket.Message.Receive(ws, &in); err != nil {
			log.Println(err)
			return
		}
		fmt.Printf("Received: %s\n", in)
		zh := false
		for _, r := range in {
			if unicode.Is(unicode.Scripts["Han"], r) {
				log.Printf(in)
				zh = true
				break
			}
		}
		if zh {
			response = tlAI(in)
			// Separate into fields with func.
			ret = strings.FieldsFunc(response, sf)

		} else {
			response = mitAI(in)
			ret = strings.FieldsFunc(response, sf)
		}
		for i := range ret {
			websocket.Message.Send(ws, ret[i])
			time.Sleep(time.Second)
		}
		websocket.Message.Send(ws, "")
	}
}
func ajax(w http.ResponseWriter, r *http.Request) {
	var messages = make(chan string)
	w.Header().Add("Access-Control-Allow-Origin", "*")
	body, _ := ioutil.ReadAll(r.Body)
	go func([]byte) {
		ret := receive(string(body))
		for i := range ret {
			messages <- ret[i]
		}

	}(body)
	io.WriteString(w, <-messages)
}

func receive(in string) (ret []string) {
	if in == "" {
		return
	}
	fmt.Printf("Received: %s\n", in)
	var response string
	sf := func(c rune) bool {
		return c == ',' || c == '，' || c == ';' || c == '。' || c == '.' || c == '？' || c == '?'
	}
	zh := false
	for _, r := range in {
		if unicode.Is(unicode.Scripts["Han"], r) {
			log.Printf(in)
			zh = true
			break
		}
	}
	if zh {
		response = tlAI(in)
		// Separate into fields with func.
		ret = strings.FieldsFunc(response, sf)

	} else {
		response = mitAI(in)
		ret = strings.FieldsFunc(response, sf)
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2015 Stuart Glenn, OMRF. All rights reserved.
// Use of this code is governed by a 3 clause BSD style license
// Full license details in LICENSE file distributed with this software

package main

import (
	"encoding/csv"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/oklasoft/mmatcher/matcher"
	"gopkg.in/alecthomas/kingpin.v1"
)

func loadData(path string, skipHeader bool) matcher.Records {
	file, err := os.Open(path)
	if nil != err {
		log.Fatal(err)
	}
	defer file.Close()

	data, err := matcher.NewRecordsFromCSV(file, skipHeader)
	if nil != err {
		log.Fatal(err)
	}
	return data
}

func parseKeys(s string) ([]int, []matcher.Atter) {
	parts := strings.Split(s, ",")
	positions := make([]int, len(parts))
	ranges := make([]matcher.Atter, len(parts))
	for i, v := range parts {
		k := strings.Split(v, ":")
		p, err := strconv.ParseInt(k[0], 10, 32)
		if nil != err {
			log.Fatal(err)
		}
		positions[i] = int(p) - 1
		if len(k) > 1 {
			r, err := strconv.ParseFloat(k[1], 32)
			if nil != err {
				log.Fatal(err)
			}
			ranges[i] = matcher.NumericAtt{r}
		}
	}
	return positions, ranges
}

func version() string {
	return fmt.Sprintf("mmatcher - Multi Matcher 0.5.0 (20150401 %s)", build)
}

var (
	verbose      = kingpin.Flag("verbose", "Increase verbosity").Short('v').Bool()
	skipHeaders  = kingpin.Flag("skip-header", "Inputs have header line to be skipped, default is use everyline").Short('h').Bool()
	outFile      = kingpin.Flag("output", "Output file").Short('o').PlaceHolder("STDOUT").OpenFile(os.O_WRONLY|os.O_CREATE, 0660)
	key          = kingpin.Arg("keys", "Keys to compare. A comma separated list of columns starting a 1, with optional :# +/- window").Required().String()
	case_file    = kingpin.Arg("case", "CSV file representing the cases").Required().ExistingFile()
	control_file = kingpin.Arg("controls", "CSV file representing the controls").Required().ExistingFile()
	build        string
)

func main() {
	kingpin.Version(version())
	kingpin.Parse()

	if nil == *outFile {
		outFile = &os.Stdout
	}

	positions, ranges := parseKeys(*key)
	cases := loadData(*case_file, *skipHeaders)
	controls := loadData(*control_file, *skipHeaders)

	all_matches := matcher.NewMatchSet()

	for _, r := range cases {
		spots := r.Matches(controls, positions, ranges...)
		for _, i := range spots {
			all_matches.AddPair(matcher.NewPair(r.ID, controls[i].ID))
		}
	}

	opti := all_matches.QuantityOptimized()

	out := csv.NewWriter(*outFile)
	out.Write([]string{"case", "control"})

	for _, r := range cases {
		m := opti.MatchesFor(r.ID)
		if 0 == len(m) {
			out.Write([]string{r.ID})
			continue
		}
		line := []string{r.ID, m[0]}
		if *verbose {
			control := controls.Get(m[0])
			for _, p := range positions {
				line = append(line, r.Atts[p].String(), control.Atts[p].String())
			}
		}
		out.Write(line)
	}
	out.Flush()
	(*outFile).Close()

}
<commit_msg>Bump version<commit_after>// Copyright 2015 Stuart Glenn, OMRF. All rights reserved.
// Use of this code is governed by a 3 clause BSD style license
// Full license details in LICENSE file distributed with this software

package main

import (
	"encoding/csv"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/oklasoft/mmatcher/matcher"
	"gopkg.in/alecthomas/kingpin.v1"
)

func loadData(path string, skipHeader bool) matcher.Records {
	file, err := os.Open(path)
	if nil != err {
		log.Fatal(err)
	}
	defer file.Close()

	data, err := matcher.NewRecordsFromCSV(file, skipHeader)
	if nil != err {
		log.Fatal(err)
	}
	return data
}

func parseKeys(s string) ([]int, []matcher.Atter) {
	parts := strings.Split(s, ",")
	positions := make([]int, len(parts))
	ranges := make([]matcher.Atter, len(parts))
	for i, v := range parts {
		k := strings.Split(v, ":")
		p, err := strconv.ParseInt(k[0], 10, 32)
		if nil != err {
			log.Fatal(err)
		}
		positions[i] = int(p) - 1
		if len(k) > 1 {
			r, err := strconv.ParseFloat(k[1], 32)
			if nil != err {
				log.Fatal(err)
			}
			ranges[i] = matcher.NumericAtt{r}
		}
	}
	return positions, ranges
}

func version() string {
	return fmt.Sprintf("mmatcher - Multi Matcher 0.6.0 (20150403 %s)", build)
}

var (
	verbose      = kingpin.Flag("verbose", "Increase verbosity").Short('v').Bool()
	skipHeaders  = kingpin.Flag("skip-header", "Inputs have header line to be skipped, default is use everyline").Short('h').Bool()
	outFile      = kingpin.Flag("output", "Output file").Short('o').PlaceHolder("STDOUT").OpenFile(os.O_WRONLY|os.O_CREATE, 0660)
	key          = kingpin.Arg("keys", "Keys to compare. A comma separated list of columns starting a 1, with optional :# +/- window").Required().String()
	case_file    = kingpin.Arg("case", "CSV file representing the cases").Required().ExistingFile()
	control_file = kingpin.Arg("controls", "CSV file representing the controls").Required().ExistingFile()
	build        string
)

func main() {
	kingpin.Version(version())
	kingpin.Parse()

	if nil == *outFile {
		outFile = &os.Stdout
	}

	positions, ranges := parseKeys(*key)
	cases := loadData(*case_file, *skipHeaders)
	controls := loadData(*control_file, *skipHeaders)

	all_matches := matcher.NewMatchSet()

	for _, r := range cases {
		spots := r.Matches(controls, positions, ranges...)
		for _, i := range spots {
			all_matches.AddPair(matcher.NewPair(r.ID, controls[i].ID))
		}
	}

	opti := all_matches.QuantityOptimized()

	out := csv.NewWriter(*outFile)
	out.Write([]string{"case", "control"})

	for _, r := range cases {
		m := opti.MatchesFor(r.ID)
		if 0 == len(m) {
			out.Write([]string{r.ID})
			continue
		}
		line := []string{r.ID, m[0]}
		if *verbose {
			control := controls.Get(m[0])
			for _, p := range positions {
				line = append(line, r.Atts[p].String(), control.Atts[p].String())
			}
		}
		out.Write(line)
	}
	out.Flush()
	(*outFile).Close()

}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/csv"
	"flag"
	"fmt"
	"io/ioutil"

	_ "github.com/mattn/go-sqlite3"

	"bytes"
	"encoding/hex"
	"io"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

func main() {
	// Parse command line opts
	commands := flag.String("sql", "", "SQL Command(s) to run on the data")
	source_text := flag.String("source", "stdin", "Source file to load, or defaults to stdin")
	delimiter := flag.String("dlm", ",", "Delimiter between fields -dlm=tab for tab, -dlm=0x## to specify a character code in hex")
	header := flag.Bool("header", false, "Treat file as having the first row as a header row")
	tableName := flag.String("table-name", "tbl", "Override the default table name (tbl)")
	save_to := flag.String("save-to", "", "If set, sqlite3 db is left on disk at this path")
	console := flag.Bool("console", false, "After all commands are run, open sqlite3 console with this data")
	verbose := flag.Bool("verbose", false, "Enable verbose logging")
	flag.Parse()

	if *console && (*source_text == "stdin") {
		log.Fatalln("Can not open console with pipe input, read a file instead")
	}

	seperator := determineSeperator(delimiter)

	// Open db, in memory if possible
	db, openPath := openDB(save_to, console)

	// Open the input source
	var fp *os.File
	fp = openFileOrStdin(source_text)
	defer fp.Close()

	// Init a structured text reader
	reader := csv.NewReader(fp)
	reader.FieldsPerRecord = 0
	reader.Comma = seperator

	// Read the first row
	first_row, read_err := reader.Read()

	if read_err != nil {
		log.Fatalln(read_err)
	}

	var headerRow []string

	if *header {
		headerRow = first_row
		first_row, read_err = reader.Read()

		if read_err != nil {
			log.Fatalln(read_err)
		}
	} else {
		headerRow = make([]string, len(first_row))
		for i := 0; i < len(first_row); i++ {
			headerRow[i] = "c" + strconv.Itoa(i)
		}
	}

	// Create the table to load to
	createTable(tableName, &headerRow, db)

	// Start the clock for importing
	t0 := time.Now()

	// Create transaction
	tx, tx_err := db.Begin()

	if tx_err != nil {
		log.Fatalln(tx_err)
	}

	// Load first row
	stmt := createLoadStmt(tableName, &headerRow, tx)
	loadRow(tableName, &first_row, tx, stmt, verbose)

	// Read the data
	for {
		row, file_err := reader.Read()
		if file_err == io.EOF {
			break
		} else if file_err != nil {
			log.Println(file_err)
		} else {
			loadRow(tableName, &row, tx, stmt, verbose)
		}
	}
	stmt.Close()
	tx.Commit()

	t1 := time.Now()

	if *verbose {
		fmt.Fprintf(os.Stderr, "Data loaded in: %v\n", t1.Sub(t0))
	}

	// Determine what sql to execute
	sqls_to_execute := strings.Split(*commands, ";")

	t0 = time.Now()

	// Execute given SQL
	for _, sql_cmd := range sqls_to_execute {
		if strings.Trim(sql_cmd, " ") != "" {
			result, err := db.Query(sql_cmd)
			if err != nil {
				log.Fatalln(err)
			}
			displayResult(result)
		}
	}

	t1 = time.Now()

	if *verbose {
		fmt.Fprintf(os.Stderr, "Queries run in: %v\n", t1.Sub(t0))
	}

	// Open console
	if *console {
		db.Close()

		cmd := exec.Command("sqlite3", *openPath)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd_err := cmd.Run()
		if cmd.Process != nil {
			cmd.Process.Release()
		}

		if len(*save_to) == 0 {
			os.RemoveAll(filepath.Dir(*openPath))
		}

		if cmd_err != nil {
			log.Fatalln(cmd_err)
		}
	} else if len(*save_to) == 0 {
		db.Close()
		os.Remove(*openPath)
	} else {
		db.Close()
	}
}

func createTable(tableName *string, columnNames *[]string, db *sql.DB) error {
	var buffer bytes.Buffer
	buffer.WriteString("CREATE TABLE IF NOT EXISTS " + (*tableName) + " (")
	for i, col := range *columnNames {
		buffer.WriteString(col + " TEXT")
		if i != len(*columnNames)-1 {
			buffer.WriteString(", ")
		}
	}
	buffer.WriteString(");")
	_, err := db.Exec(buffer.String())
	if err != nil {
		log.Fatalln(err)
	}
	return err
}

func createLoadStmt(tableName *string, values *[]string, db *sql.Tx) *sql.Stmt {
	if len(*values) == 0 {
		log.Fatalln("Nothing to build insert with!")
	}
	var buffer bytes.Buffer

	buffer.WriteString("INSERT INTO " + (*tableName) + " VALUES (")
	for i := range *values {
		buffer.WriteString("?")
		if i != len(*values)-1 {
			buffer.WriteString(", ")
		}
	}
	buffer.WriteString(");")
	stmt, err := db.Prepare(buffer.String())
	if err != nil {
		log.Fatalln(err)
	}
	return stmt
}

func loadRow(tableName *string, values *[]string, db *sql.Tx, stmt *sql.Stmt, verbose *bool) error {
	if len(*values) == 0 {
		return nil
	}
	vals := make([]interface{}, 0)
	for _, val := range *values {
		vals = append(vals, val)
	}
	_, err := stmt.Exec(vals...)
	if err != nil && *verbose {
		fmt.Fprintln(os.Stderr, "Bad row: ", err)
	}
	return err
}

func displayResult(rows *sql.Rows) {
	cols, cols_err := rows.Columns()

	if cols_err != nil {
		log.Fatalln(cols_err)
	}

	rawResult := make([][]byte, len(cols))
	result := make([]string, len(cols))

	dest := make([]interface{}, len(cols))
	for i, _ := range cols {
		dest[i] = &rawResult[i]
	}

	for rows.Next() {
		rows.Scan(dest...)

		for i, raw := range rawResult {
			result[i] = string(raw)
		}

		for j, v := range result {
			fmt.Printf("%s", v)
			if j != len(result)-1 {
				fmt.Printf(", ")
			}
		}
		fmt.Printf("\n")
	}
}

func openFileOrStdin(path *string) *os.File {
	var fp *os.File
	var err error
	if (*path) == "stdin" {
		fp = os.Stdin
		err = nil
	} else {
		fp, err = os.Open(*cleanPath(path))
	}

	if err != nil {
		log.Fatalln(err)
	}

	return fp
}

func cleanPath(path *string) *string {
	var result string
	usr, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}

	if (*path)[:2] == "~/" {
		dir := usr.HomeDir + "/"
		result = strings.Replace(*path, "~/", dir, 1)
	} else {
		result = (*path)
	}

	abs_result, abs_err := filepath.Abs(result)
	if abs_err != nil {
		log.Fatalln(err)
	}

	clean_result := filepath.Clean(abs_result)

	return &clean_result
}

func openDB(path *string, no_memory *bool) (*sql.DB, *string) {
	openPath := ":memory:"
	if len(*path) != 0 {
		openPath = *cleanPath(path)
	} else if *no_memory {
		outDir, err := ioutil.TempDir(os.TempDir(), "textql")
		if err != nil {
			log.Fatalln(err)
		}
		openPath = filepath.Join(outDir, "textql.db")
	}

	db, err := sql.Open("sqlite3", openPath)

	if err != nil {
		log.Fatalln(err)
	}
	return db, &openPath
}

func determineSeperator(delimiter *string) rune {
	var seperator rune

	if (*delimiter) == "tab" {
		seperator = '\t'
	} else if strings.Index((*delimiter), "0x") == 0 {
		dlm, hex_err := hex.DecodeString((*delimiter)[2:])

		if hex_err != nil {
			log.Fatalln(hex_err)
		}

		seperator, _ = utf8.DecodeRuneInString(string(dlm))
	} else {
		seperator, _ = utf8.DecodeRuneInString(*delimiter)
	}
	return seperator
}
<commit_msg>Replace '-' with '_' in column names while creating tables, to allow for files with '-' in the header to still function.<commit_after>package main

import (
	"database/sql"
	"encoding/csv"
	"flag"
	"fmt"
	"io/ioutil"

	_ "github.com/mattn/go-sqlite3"

	"bytes"
	"encoding/hex"
	"io"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

func main() {
	// Parse command line opts
	commands := flag.String("sql", "", "SQL Command(s) to run on the data")
	source_text := flag.String("source", "stdin", "Source file to load, or defaults to stdin")
	delimiter := flag.String("dlm", ",", "Delimiter between fields -dlm=tab for tab, -dlm=0x## to specify a character code in hex")
	header := flag.Bool("header", false, "Treat file as having the first row as a header row")
	tableName := flag.String("table-name", "tbl", "Override the default table name (tbl)")
	save_to := flag.String("save-to", "", "If set, sqlite3 db is left on disk at this path")
	console := flag.Bool("console", false, "After all commands are run, open sqlite3 console with this data")
	verbose := flag.Bool("verbose", false, "Enable verbose logging")
	flag.Parse()

	if *console && (*source_text == "stdin") {
		log.Fatalln("Can not open console with pipe input, read a file instead")
	}

	seperator := determineSeperator(delimiter)

	// Open db, in memory if possible
	db, openPath := openDB(save_to, console)

	// Open the input source
	var fp *os.File
	fp = openFileOrStdin(source_text)
	defer fp.Close()

	// Init a structured text reader
	reader := csv.NewReader(fp)
	reader.FieldsPerRecord = 0
	reader.Comma = seperator

	// Read the first row
	first_row, read_err := reader.Read()

	if read_err != nil {
		log.Fatalln(read_err)
	}

	var headerRow []string

	if *header {
		headerRow = first_row
		first_row, read_err = reader.Read()

		if read_err != nil {
			log.Fatalln(read_err)
		}
	} else {
		headerRow = make([]string, len(first_row))
		for i := 0; i < len(first_row); i++ {
			headerRow[i] = "c" + strconv.Itoa(i)
		}
	}

	// Create the table to load to
	createTable(tableName, &headerRow, db, verbose)

	// Start the clock for importing
	t0 := time.Now()

	// Create transaction
	tx, tx_err := db.Begin()

	if tx_err != nil {
		log.Fatalln(tx_err)
	}

	// Load first row
	stmt := createLoadStmt(tableName, &headerRow, tx)
	loadRow(tableName, &first_row, tx, stmt, verbose)

	// Read the data
	for {
		row, file_err := reader.Read()
		if file_err == io.EOF {
			break
		} else if file_err != nil {
			log.Println(file_err)
		} else {
			loadRow(tableName, &row, tx, stmt, verbose)
		}
	}
	stmt.Close()
	tx.Commit()

	t1 := time.Now()

	if *verbose {
		fmt.Fprintf(os.Stderr, "Data loaded in: %v\n", t1.Sub(t0))
	}

	// Determine what sql to execute
	sqls_to_execute := strings.Split(*commands, ";")

	t0 = time.Now()

	// Execute given SQL
	for _, sql_cmd := range sqls_to_execute {
		if strings.Trim(sql_cmd, " ") != "" {
			result, err := db.Query(sql_cmd)
			if err != nil {
				log.Fatalln(err)
			}
			displayResult(result)
		}
	}

	t1 = time.Now()

	if *verbose {
		fmt.Fprintf(os.Stderr, "Queries run in: %v\n", t1.Sub(t0))
	}

	// Open console
	if *console {
		db.Close()

		cmd := exec.Command("sqlite3", *openPath)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd_err := cmd.Run()
		if cmd.Process != nil {
			cmd.Process.Release()
		}

		if len(*save_to) == 0 {
			os.RemoveAll(filepath.Dir(*openPath))
		}

		if cmd_err != nil {
			log.Fatalln(cmd_err)
		}
	} else if len(*save_to) == 0 {
		db.Close()
		os.Remove(*openPath)
	} else {
		db.Close()
	}
}

func createTable(tableName *string, columnNames *[]string, db *sql.DB, verbose *bool) error {
	var buffer bytes.Buffer

	buffer.WriteString("CREATE TABLE IF NOT EXISTS " + (*tableName) + " (")

	for i, col := range *columnNames {
		var col_name string

		if strings.ContainsAny(col, "-") {
			col_name = strings.Replace(col, "-", "_", -1)
			if *verbose {
				fmt.Fprintf(os.Stderr, "Column %x renamed to %s\n", col, col_name)
			}
		} else {
			col_name = col
		}

		buffer.WriteString(col_name + " TEXT")

		if i != len(*columnNames)-1 {
			buffer.WriteString(", ")
		}
	}

	buffer.WriteString(");")

	_, err := db.Exec(buffer.String())

	if err != nil {
		log.Fatalln(err)
	}

	return err
}

func createLoadStmt(tableName *string, values *[]string, db *sql.Tx) *sql.Stmt {
	if len(*values) == 0 {
		log.Fatalln("Nothing to build insert with!")
	}
	var buffer bytes.Buffer

	buffer.WriteString("INSERT INTO " + (*tableName) + " VALUES (")
	for i := range *values {
		buffer.WriteString("?")
		if i != len(*values)-1 {
			buffer.WriteString(", ")
		}
	}
	buffer.WriteString(");")
	stmt, err := db.Prepare(buffer.String())
	if err != nil {
		log.Fatalln(err)
	}
	return stmt
}

func loadRow(tableName *string, values *[]string, db *sql.Tx, stmt *sql.Stmt, verbose *bool) error {
	if len(*values) == 0 {
		return nil
	}
	vals := make([]interface{}, 0)
	for _, val := range *values {
		vals = append(vals, val)
	}
	_, err := stmt.Exec(vals...)
	if err != nil && *verbose {
		fmt.Fprintln(os.Stderr, "Bad row: ", err)
	}
	return err
}

func displayResult(rows *sql.Rows) {
	cols, cols_err := rows.Columns()

	if cols_err != nil {
		log.Fatalln(cols_err)
	}

	rawResult := make([][]byte, len(cols))
	result := make([]string, len(cols))

	dest := make([]interface{}, len(cols))
	for i, _ := range cols {
		dest[i] = &rawResult[i]
	}

	for rows.Next() {
		rows.Scan(dest...)

		for i, raw := range rawResult {
			result[i] = string(raw)
		}

		for j, v := range result {
			fmt.Printf("%s", v)
			if j != len(result)-1 {
				fmt.Printf(", ")
			}
		}
		fmt.Printf("\n")
	}
}

func openFileOrStdin(path *string) *os.File {
	var fp *os.File
	var err error
	if (*path) == "stdin" {
		fp = os.Stdin
		err = nil
	} else {
		fp, err = os.Open(*cleanPath(path))
	}

	if err != nil {
		log.Fatalln(err)
	}

	return fp
}

func cleanPath(path *string) *string {
	var result string
	usr, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}

	if (*path)[:2] == "~/" {
		dir := usr.HomeDir + "/"
		result = strings.Replace(*path, "~/", dir, 1)
	} else {
		result = (*path)
	}

	abs_result, abs_err := filepath.Abs(result)
	if abs_err != nil {
		log.Fatalln(err)
	}

	clean_result := filepath.Clean(abs_result)

	return &clean_result
}

func openDB(path *string, no_memory *bool) (*sql.DB, *string) {
	openPath := ":memory:"
	if len(*path) != 0 {
		openPath = *cleanPath(path)
	} else if *no_memory {
		outDir, err := ioutil.TempDir(os.TempDir(), "textql")
		if err != nil {
			log.Fatalln(err)
		}
		openPath = filepath.Join(outDir, "textql.db")
	}

	db, err := sql.Open("sqlite3", openPath)

	if err != nil {
		log.Fatalln(err)
	}
	return db, &openPath
}

func determineSeperator(delimiter *string) rune {
	var seperator rune

	if (*delimiter) == "tab" {
		seperator = '\t'
	} else if strings.Index((*delimiter), "0x") == 0 {
		dlm, hex_err := hex.DecodeString((*delimiter)[2:])

		if hex_err != nil {
			log.Fatalln(hex_err)
		}

		seperator, _ = utf8.DecodeRuneInString(string(dlm))
	} else {
		seperator, _ = utf8.DecodeRuneInString(*delimiter)
	}
	return seperator
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"
)

var (
	inputFile  string
	outputFile string
	pack       string
)

type configType struct {
	InputFile    string
	OutputFile   string
	PackageName  string
	ConstantName string
	InputFileTxt string
}

func (c *configType) Validate() bool {
	return c.InputFile != "" && c.OutputFile != "" && c.PackageName != "" && c.ConstantName != ""
}

var config = configType{}

const tpl = `//Genereated by WGF -- DO NOT EDIT
package {{.PackageName}}

const {{.ConstantName}} = ` + "`{{.InputFileTxt}}`" + `

`

func init() {
	flag.StringVar(&config.InputFile, "i", "", "INPUT: The file to convert to go source")
	flag.StringVar(&config.OutputFile, "o", "", "OUTPUT: The go output file")
	flag.StringVar(&config.PackageName, "p", os.Getenv("$GOPACKAGE"), "Package: The package for the go file")
	flag.StringVar(&config.ConstantName, "c", "", "Constant: The name of the constant")
	flag.Parse()

	if config.Validate() {
		fmt.Println("Please enter the following flags")
		flag.Usage()
		os.Exit(1)
	}
}

func main() {

	log.Println(config.InputFile)
	log.Println(config.OutputFile)
	t := template.Must(template.New("tpl").Parse(tpl))

	in, err := ioutil.ReadFile(config.InputFile)
	config.InputFileTxt = strings.Replace(string(in), "`", "` + \"`", -1)
	checkErr(err)

	f, err := os.Create(config.OutputFile)
	checkErr(err)
	defer f.Close()

	t.Execute(f, config)
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>fixed validation bug<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"
)

var (
	inputFile  string
	outputFile string
	pack       string
)

type configType struct {
	InputFile    string
	OutputFile   string
	PackageName  string
	ConstantName string
	InputFileTxt string
}

func (c *configType) Validate() bool {
	return c.InputFile != "" && c.OutputFile != "" && c.PackageName != "" && c.ConstantName != ""
}

var config = configType{}

const tpl = `//Genereated by WGF -- DO NOT EDIT
package {{.PackageName}}

const {{.ConstantName}} = ` + "`{{.InputFileTxt}}`" + `

`

func init() {
	flag.StringVar(&config.InputFile, "i", "", "INPUT: The file to convert to go source")
	flag.StringVar(&config.OutputFile, "o", "", "OUTPUT: The go output file")
	flag.StringVar(&config.PackageName, "p", os.Getenv("$GOPACKAGE"), "Package: The package for the go file")
	flag.StringVar(&config.ConstantName, "c", "", "Constant: The name of the constant")
	flag.Parse()

	if !config.Validate() {
		fmt.Println("Please enter the following flags")
		flag.Usage()
		os.Exit(1)
	}
}

func main() {

	log.Println(config.InputFile)
	log.Println(config.OutputFile)
	t := template.Must(template.New("tpl").Parse(tpl))

	in, err := ioutil.ReadFile(config.InputFile)
	config.InputFileTxt = strings.Replace(string(in), "`", "` + \"`", -1)
	checkErr(err)

	f, err := os.Create(config.OutputFile)
	checkErr(err)
	defer f.Close()

	t.Execute(f, config)
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 Brian Lachniet. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
Gomir mirrors git repositories

Usage:

	gomir add <fetchURL> <pushURL> [<localDest>]    # Add a repo to mirror
	gomir fetch                                     # Fetch latest updates from source repo
	gomir push                                      # Push updates to mirror destination

TODO:
	- Add support for concurrency during fetch/push
	- Add support for controlling concurrency during fetch/push
	- Add documentation describing where repos are stored
	- Add documentation describing what to do if something goes wrong during a fetch/push
	- Add documentation for a normal synchronization workflow
	- Add usage (gomir -h)
*/
package main

import (
	"fmt"
	"io"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/fatih/color"
	"github.com/pkg/errors"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Not enough arguments")
		os.Exit(1)
	}

	action := strings.ToLower(os.Args[1])
	switch action {
	case "add":
		var fetchURL string
		var pushURL string
		var localDest string
		switch len(os.Args) {
		case 4:
			fetchURL = os.Args[2]
			pushURL = os.Args[3]
		case 5:
			fetchURL = os.Args[2]
			pushURL = os.Args[3]
			localDest = os.Args[4]
		default:
			fmt.Println("Wrong number of arguments")
			os.Exit(1)
		}

		add(fetchURL, pushURL, localDest)
	case "fetch":
		fetch()
	case "push":
		push()
	default:
		fmt.Printf("Unrecognized action '%v'\n", action)
		os.Exit(1)
	}
}

func add(fetchURL, pushURL, localDest string) {
	// Try to generate a localDest
	if localDest == "" {
		u, err := url.Parse(fetchURL)
		if err != nil {
			fmt.Println("Could not generate a localDest")
			os.Exit(1)
		}
		localDest = fmt.Sprintf("%v%v", u.Host, u.Path)
	}

	localDest = ensureGitExt(localDest)

	// Clone
	if err := gitCloneMirror(fetchURL, localDest); err != nil {
		fmt.Println("Error cloning repository")
		os.Exit(1)
	}

	// Set Push URL
	if err := gitSetOriginPushURL(localDest, pushURL); err != nil {
		fmt.Println("Error setting push URL")
		os.Exit(1)
	}
}

func fetch() {
	for _, gitDir := range findGitDirs() {
		if fetchSingle(gitDir) {
			color.Green("[✔] %v", gitDir)
		} else {
			color.Red("[X] %v", gitDir)
		}
	}
}

func fetchSingle(gitDir string) bool {
	logFile, logger, err := getLog(gitDir, "FETCH: ")
	if err != nil {
		color.Red("Error opening log file for %v", gitDir)
		return false
	}
	defer logFile.Close()

	logger.Println("Start")
	success := gitFetchPrune(gitDir, logFile) == nil
	logger.Printf("Done, success:%v", success)
	return success
}

func push() {
	for _, gitDir := range findGitDirs() {
		if pushSingle(gitDir) {
			color.Green("[✔] %v", gitDir)
		} else {
			color.Red("[X] %v", gitDir)
		}
	}
}

func pushSingle(gitDir string) bool {
	logFile, logger, err := getLog(gitDir, "PUSH: ")
	if err != nil {
		color.Red("Error opening log file for %v", gitDir)
		return false
	}
	defer logFile.Close()

	logger.Println("Start")

	// Where are we pushing to?
	pushURL, err := gitGetOriginPushURL(gitDir)
	if err != nil {
		logger.Printf("Error retrieving push URL: %+v", err)
		return false
	}

	// If pushing using file protocol and destination repository does
	// not alread exist, initialize it
	isFileProtocol := pushURL.Scheme == "" || strings.ToLower(pushURL.Scheme) == "file"
	if isFileProtocol {
		_, err := os.Stat(pushURL.Path)
		if err != nil && os.IsNotExist(err) {
			if err := gitInitBareRepo(pushURL.Path, logFile); err != nil {
				logger.Printf("Error initializing bare git repository: %+v", err)
				return false
			}
		}
	}

	// Push
	if err := gitPushMirror(gitDir, logFile); err != nil {
		logger.Printf("Error pushing: %+v", err)
		return false
	}

	// Update server info
	if isFileProtocol {
		if err := gitUpdateServerInfo(pushURL.Path, logFile); err != nil {
			logger.Printf("Error updating server info: %+v", err)
			return false
		}
	}

	logger.Println("Done")
	return true
}

func findGitDirs() []string {
	gitDirs := []string{}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err == nil &&
			info.IsDir() &&
			strings.ToLower(filepath.Base(path)) != ".git" &&
			strings.ToLower(filepath.Ext(path)) == ".git" {
			gitDirs = append(gitDirs, path)
			return filepath.SkipDir
		}
		return nil
	})
	return gitDirs
}

func ensureGitExt(str string) string {
	if strings.ToLower(filepath.Ext(str)) != ".git" {
		return fmt.Sprintf("%v.git", str)
	}
	return str
}

func getLog(gitDir, prefix string) (io.WriteCloser, *log.Logger, error) {
	logPath := fmt.Sprintf("%v.log", gitDir)
	logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, nil, errors.Wrap(err, "Error opening log file")
	}

	// TODO: What flags should I set for the logger?
	logger := log.New(logFile, prefix, log.Ldate|log.Ltime|log.Lshortfile|log.LUTC)
	return logFile, logger, nil
}
<commit_msg>Add concurrency for fetch/push<commit_after>// Copyright 2017 Brian Lachniet. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
Gomir mirrors git repositories

Usage:

	gomir add <fetchURL> <pushURL> [<localDest>]    # Add a repo to mirror
	gomir fetch                                     # Fetch latest updates from source repo
	gomir push                                      # Push updates to mirror destination

TODO:
	- Add support for controlling concurrency during fetch/push
	- Add documentation describing where repos are stored
	- Add documentation describing what to do if something goes wrong during a fetch/push
	- Add documentation for a normal synchronization workflow
	- Add usage (gomir -h)
*/
package main

import (
	"fmt"
	"io"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"

	"github.com/fatih/color"
	"github.com/pkg/errors"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Not enough arguments")
		os.Exit(1)
	}

	action := strings.ToLower(os.Args[1])
	switch action {
	case "add":
		var fetchURL string
		var pushURL string
		var localDest string
		switch len(os.Args) {
		case 4:
			fetchURL = os.Args[2]
			pushURL = os.Args[3]
		case 5:
			fetchURL = os.Args[2]
			pushURL = os.Args[3]
			localDest = os.Args[4]
		default:
			fmt.Println("Wrong number of arguments")
			os.Exit(1)
		}

		add(fetchURL, pushURL, localDest)
	case "fetch":
		fetch()
	case "push":
		push()
	default:
		fmt.Printf("Unrecognized action '%v'\n", action)
		os.Exit(1)
	}
}

func add(fetchURL, pushURL, localDest string) {
	// Try to generate a localDest
	if localDest == "" {
		u, err := url.Parse(fetchURL)
		if err != nil {
			fmt.Println("Could not generate a localDest")
			os.Exit(1)
		}
		localDest = fmt.Sprintf("%v%v", u.Host, u.Path)
	}

	localDest = ensureGitExt(localDest)

	// Clone
	if err := gitCloneMirror(fetchURL, localDest); err != nil {
		fmt.Println("Error cloning repository")
		os.Exit(1)
	}

	// Set Push URL
	if err := gitSetOriginPushURL(localDest, pushURL); err != nil {
		fmt.Println("Error setting push URL")
		os.Exit(1)
	}
}

func fetch() {
	errCount := performOperationAsync(fetchSingle)
	if errCount > 0 {
		color.Red("Fetch failed for %v repos", errCount)
		os.Exit(1)
	}

	os.Exit(0)
}

func fetchSingle(gitDir string) bool {
	logFile, logger, err := getLog(gitDir, "FETCH: ")
	if err != nil {
		color.Red("Error opening log file for %v", gitDir)
		return false
	}
	defer logFile.Close()

	logger.Println("Start")
	success := gitFetchPrune(gitDir, logFile) == nil
	logger.Printf("Done, success:%v", success)
	return success
}

func push() {
	errCount := performOperationAsync(pushSingle)
	if errCount > 0 {
		color.Red("Push failed for %v repos", errCount)
		os.Exit(1)
	}

	os.Exit(0)
}

func pushSingle(gitDir string) bool {
	logFile, logger, err := getLog(gitDir, "PUSH: ")
	if err != nil {
		color.Red("Error opening log file for %v", gitDir)
		return false
	}
	defer logFile.Close()

	logger.Println("Start")

	// Where are we pushing to?
	pushURL, err := gitGetOriginPushURL(gitDir)
	if err != nil {
		logger.Printf("Error retrieving push URL: %+v", err)
		return false
	}

	// If pushing using file protocol and destination repository does
	// not alread exist, initialize it
	isFileProtocol := pushURL.Scheme == "" || strings.ToLower(pushURL.Scheme) == "file"
	if isFileProtocol {
		_, err := os.Stat(pushURL.Path)
		if err != nil && os.IsNotExist(err) {
			if err := gitInitBareRepo(pushURL.Path, logFile); err != nil {
				logger.Printf("Error initializing bare git repository: %+v", err)
				return false
			}
		}
	}

	// Push
	if err := gitPushMirror(gitDir, logFile); err != nil {
		logger.Printf("Error pushing: %+v", err)
		return false
	}

	// Update server info
	if isFileProtocol {
		if err := gitUpdateServerInfo(pushURL.Path, logFile); err != nil {
			logger.Printf("Error updating server info: %+v", err)
			return false
		}
	}

	logger.Println("Done")
	return true
}

func findGitDirs() []string {
	gitDirs := []string{}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err == nil &&
			info.IsDir() &&
			strings.ToLower(filepath.Base(path)) != ".git" &&
			strings.ToLower(filepath.Ext(path)) == ".git" {
			gitDirs = append(gitDirs, path)
			return filepath.SkipDir
		}
		return nil
	})
	return gitDirs
}

func ensureGitExt(str string) string {
	if strings.ToLower(filepath.Ext(str)) != ".git" {
		return fmt.Sprintf("%v.git", str)
	}
	return str
}

func getLog(gitDir, prefix string) (io.WriteCloser, *log.Logger, error) {
	logPath := fmt.Sprintf("%v.log", gitDir)
	logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, nil, errors.Wrap(err, "Error opening log file")
	}

	logger := log.New(logFile, prefix, log.Ldate|log.Ltime|log.Lshortfile|log.LUTC)
	return logFile, logger, nil
}

type gitDirOperation func(gitDir string) bool

func performOperationAsync(op gitDirOperation) int64 {
	var wg sync.WaitGroup
	var errCount int64
	for _, gitDir := range findGitDirs() {
		wg.Add(1)
		go func(gitDir string) {
			defer wg.Done()

			if op(gitDir) {
				color.Green("[✔] %v", gitDir)
			} else {
				atomic.AddInt64(&errCount, 1)
				color.Red("[X] %v", gitDir)
			}
		}(gitDir)
	}

	wg.Wait()
	return errCount
}
<|endoftext|>


<commit_before>package main

import(
	"os/signal"
	"os"
	"fmt"
	"syscall"
	"time"
	"flag"
	"log"
	"github.com/SearchSpring/consul2route53/app"
)

var consulhost string
var consulport string
var zoneid string
var configfile string
var sleeptime int64
var ttl int64
var version bool
var once bool
const (
	versioninfo = "v0.0.1"
)

type loopobject interface{
	Run() error
}

func main() {
	flag.StringVar(&consulhost, "host", "localhost", "Address of consul server")
	flag.StringVar(&consulport, "port", "8500", "Port of consul server")
	flag.StringVar(&zoneid, "zoneid", "", "Route53 ZoneID")
	flag.StringVar(&configfile, "config", "./consul2route53.conf", "Path to configfile")
	flag.Int64Var(&sleeptime, "sleeptime", 1000, "Sleep time in loop")
	flag.BoolVar(&once, "once", false, "Run Once")
	flag.Int64Var(&ttl, "ttl", 300, "TTL")
	flag.BoolVar(&version, "version", false, "consul253 version")
	flag.Parse()

	for {
		config,_ := consul2route53.ReadConfig(configfile)
		config.SetConsulHost(consulhost)
		config.SetConsulPort(consulport)
		config.SetZoneId(zoneid)
		config.SetTTL(ttl)
		consul2route53 := consul2route53.New(config)
		switch {
			case once:
				err := consul2route53.Run()
				if err != nil {
					log.Fatal(err)
				}
				return
			default:
				loop(consul2route53)
		}
	}
}

// Loop until SIGHUP
func loop(obj loopobject) {
	c := make(chan os.Signal, 1)
	r := make(chan bool)

	signal.Notify(c, syscall.SIGHUP)

	go func(){
		for sig := range c {
			fmt.Println(sig)
			r <- true
		}
	}()
	for {
		select {
			case msg := <-r:
				log.Printf("Got A HUP. Reloading: %#v\n", msg)
				return
			default:
		}
		err := obj.Run()
		if err != nil {
			log.Println(err)
		}
		time.Sleep(time.Duration(sleeptime * int64(time.Millisecond)))
	}

}
<commit_msg>Added version flag<commit_after>package main

import(
	"os/signal"
	"os"
	"fmt"
	"syscall"
	"time"
	"flag"
	"log"
	"github.com/SearchSpring/consul2route53/app"
)

var consulhost string
var consulport string
var zoneid string
var configfile string
var sleeptime int64
var ttl int64
var version bool
var once bool
const (
	versioninfo = "v0.0.1"
)

type loopobject interface{
	Run() error
}

func main() {
	flag.StringVar(&consulhost, "host", "localhost", "Address of consul server")
	flag.StringVar(&consulport, "port", "8500", "Port of consul server")
	flag.StringVar(&zoneid, "zoneid", "", "Route53 ZoneID")
	flag.StringVar(&configfile, "config", "./consul2route53.conf", "Path to configfile")
	flag.Int64Var(&sleeptime, "sleeptime", 1000, "Sleep time in loop")
	flag.BoolVar(&once, "once", false, "Run Once")
	flag.Int64Var(&ttl, "ttl", 300, "TTL")
	flag.BoolVar(&version, "version", false, "consul253 version")
	flag.Parse()

	if version {
		fmt.Printf("consul2route53 version %s\n",versioninfo)
		return
	}

	for {
		config,_ := consul2route53.ReadConfig(configfile)
		config.SetConsulHost(consulhost)
		config.SetConsulPort(consulport)
		config.SetZoneId(zoneid)
		config.SetTTL(ttl)
		consul2route53 := consul2route53.New(config)
		switch {
			case once:
				err := consul2route53.Run()
				if err != nil {
					log.Fatal(err)
				}
				return
			default:
				loop(consul2route53)
		}
	}
}

// Loop until SIGHUP
func loop(obj loopobject) {
	c := make(chan os.Signal, 1)
	r := make(chan bool)

	signal.Notify(c, syscall.SIGHUP)

	go func(){
		for sig := range c {
			fmt.Println(sig)
			r <- true
		}
	}()
	for {
		select {
			case msg := <-r:
				log.Printf("Got A HUP. Reloading: %#v\n", msg)
				return
			default:
		}
		err := obj.Run()
		if err != nil {
			log.Println(err)
		}
		time.Sleep(time.Duration(sleeptime * int64(time.Millisecond)))
	}

}
<|endoftext|>


<commit_before>// Copyright 2014 Kelsey Hightower. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"text/template"
)

var (
	dataDir         string
	baseUrl         string
	defaultSSHKeyId = "coreos"
)

const ipxeBootScript = `#!ipxe
set coreos-version {{.Version}}
set base-url http://{{.BaseUrl}}/coreos/amd64-generic/${coreos-version}
kernel ${base-url}/coreos_production_pxe.vmlinuz root=squashfs: {{if not .State}}state=tmpfs: {{end}}sshkey="{{.SSHKey}}"
initrd ${base-url}/coreos_production_pxe_image.cpio.gz
boot
`

// SetDataDir sets the data directory.
func SetDataDir(dir string) {
	dataDir = dir
}

// SetBaseUrl sets the base url.
func SetBaseUrl(url string) {
	baseUrl = url
}

func ipxeBootScriptServer(w http.ResponseWriter, r *http.Request) {
	v := r.URL.Query()
	version := v.Get("version")
	if version == "" {
		version = "latest"
	}
	state := v.Get("state")
	if state != "true" {
		state = ""
	}
	sshKeyId := v.Get("sshkey")
	if sshKeyId == "" {
		sshKeyId = defaultSSHKeyId
	}
	sshKeyPath := filepath.Join(dataDir, fmt.Sprintf("sshkeys/%s.pub", sshKeyId))
	sshKey, err := sshKeyFromFile(sshKeyPath)
	if err != nil {
		log.Printf("Error reading ssh publickey from %s: %s", sshKeyPath, err)
		http.Error(w, err.Error(), 500)
		return
	}

	t, err := template.New("ipxebootscript").Parse(ipxeBootScript)
	if err != nil {
		log.Print("Error generating iPXE boot script: " + err.Error())
		http.Error(w, "Error generating the iPXE boot script", 500)
		return
	}
	data := map[string]string{
		"BaseUrl": baseUrl,
		"SSHKey":  sshKey,
		"State":   state,
		"Version": version,
	}
	err = t.Execute(w, data)
	if err != nil {
		log.Print("Error generating iPXE boot script: " + err.Error())
		http.Error(w, "Error generating the iPXE boot script", 500)
		return
	}
	return
}

func sshKeyFromFile(filename string) (string, error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return "", err
	}
	return string(bytes.TrimSpace(b)), nil
}

func main() {
	// Set the data directory where the coreos directory containing
	// the ssh public key, kernal and boot images.
	dataDir := os.Getenv("COREOS_IPXE_SERVER_DATA_DIR")
	if dataDir == "" {
		log.Fatal("COREOS_IPXE_SERVER_DATA_DIR must be set and non-empty")
	}

	// Set the base URL used by the iPXE boot script.
	baseUrl = os.Getenv("COREOS_IPXE_SERVER_BASE_URL")
	if baseUrl == "" {
		log.Fatal("COREOS_IPXE_SERVER_BASE_URL must be set and non-empty")
	}

	// Set the host:port to listen for HTTP requests.
	listenHost := os.Getenv("COREOS_IPXE_SERVER_LISTEN_HOST")
	listenPort := os.Getenv("COREOS_IPXE_SERVER_LISTEN_PORT")
	if listenPort == "" {
		log.Fatal("COREOS_IPXE_SERVER_LISTEN_PORT must be set and non-empty")
	}
	hostPort := net.JoinHostPort(listenHost, listenPort)

	http.HandleFunc("/", ipxeBootScriptServer)
	// Serve kernel and pxe boot images
	staticFilePath := filepath.Join(dataDir, "coreos")
	http.Handle("/coreos/", http.StripPrefix("/coreos/", http.FileServer(http.Dir(staticFilePath))))
	log.Fatal(http.ListenAndServe(hostPort, nil))
}
<commit_msg>Don't shadow dataDir variable<commit_after>// Copyright 2014 Kelsey Hightower. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"text/template"
)

var (
	dataDir         string
	baseUrl         string
	defaultSSHKeyId = "coreos"
)

const ipxeBootScript = `#!ipxe
set coreos-version {{.Version}}
set base-url http://{{.BaseUrl}}/coreos/amd64-generic/${coreos-version}
kernel ${base-url}/coreos_production_pxe.vmlinuz root=squashfs: {{if not .State}}state=tmpfs: {{end}}sshkey="{{.SSHKey}}"
initrd ${base-url}/coreos_production_pxe_image.cpio.gz
boot
`

// SetDataDir sets the data directory.
func SetDataDir(dir string) {
	dataDir = dir
}

// SetBaseUrl sets the base url.
func SetBaseUrl(url string) {
	baseUrl = url
}

func ipxeBootScriptServer(w http.ResponseWriter, r *http.Request) {
	v := r.URL.Query()
	version := v.Get("version")
	if version == "" {
		version = "latest"
	}
	state := v.Get("state")
	if state != "true" {
		state = ""
	}
	sshKeyId := v.Get("sshkey")
	if sshKeyId == "" {
		sshKeyId = defaultSSHKeyId
	}
	sshKeyPath := filepath.Join(dataDir, fmt.Sprintf("sshkeys/%s.pub", sshKeyId))
	sshKey, err := sshKeyFromFile(sshKeyPath)
	if err != nil {
		log.Printf("Error reading ssh publickey from %s: %s", sshKeyPath, err)
		http.Error(w, err.Error(), 500)
		return
	}

	t, err := template.New("ipxebootscript").Parse(ipxeBootScript)
	if err != nil {
		log.Print("Error generating iPXE boot script: " + err.Error())
		http.Error(w, "Error generating the iPXE boot script", 500)
		return
	}
	data := map[string]string{
		"BaseUrl": baseUrl,
		"SSHKey":  sshKey,
		"State":   state,
		"Version": version,
	}
	err = t.Execute(w, data)
	if err != nil {
		log.Print("Error generating iPXE boot script: " + err.Error())
		http.Error(w, "Error generating the iPXE boot script", 500)
		return
	}
	return
}

func sshKeyFromFile(filename string) (string, error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return "", err
	}
	return string(bytes.TrimSpace(b)), nil
}

func main() {
	// Set the data directory where the coreos directory containing
	// the ssh public key, kernal and boot images.
	dataDir = os.Getenv("COREOS_IPXE_SERVER_DATA_DIR")
	if dataDir == "" {
		log.Fatal("COREOS_IPXE_SERVER_DATA_DIR must be set and non-empty")
	}

	// Set the base URL used by the iPXE boot script.
	baseUrl = os.Getenv("COREOS_IPXE_SERVER_BASE_URL")
	if baseUrl == "" {
		log.Fatal("COREOS_IPXE_SERVER_BASE_URL must be set and non-empty")
	}

	// Set the host:port to listen for HTTP requests.
	listenHost := os.Getenv("COREOS_IPXE_SERVER_LISTEN_HOST")
	listenPort := os.Getenv("COREOS_IPXE_SERVER_LISTEN_PORT")
	if listenPort == "" {
		log.Fatal("COREOS_IPXE_SERVER_LISTEN_PORT must be set and non-empty")
	}
	hostPort := net.JoinHostPort(listenHost, listenPort)

	http.HandleFunc("/", ipxeBootScriptServer)
	// Serve kernel and pxe boot images
	staticFilePath := filepath.Join(dataDir, "coreos")
	http.Handle("/coreos/", http.StripPrefix("/coreos/", http.FileServer(http.Dir(staticFilePath))))
	log.Fatal(http.ListenAndServe(hostPort, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
)

var config struct {
	path    string
	address string
	port    int
}

func main() {
	flag.StringVar(&config.path, "path", "", "Optional path to serve static files from.")
	flag.StringVar(&config.address, "address", "127.0.0.1", "Address to listen on.")
	flag.IntVar(&config.port, "port", 3333, "Port to listen on.")
	flag.Parse()

	stubHandler := NewStubHandler()
	if config.path != "" {
		stubHandler.fallbackHandler = http.FileServer(http.Dir(config.path))
	}
	http.Handle("/", stubHandler)
	http.ListenAndServe(fmt.Sprintf("%s:%d", config.address, config.port), stubHandler)
}
<commit_msg>Add error reporting when web server fails<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
)

var config struct {
	path    string
	address string
	port    int
}

func main() {
	flag.StringVar(&config.path, "path", "", "Optional path to serve static files from.")
	flag.StringVar(&config.address, "address", "127.0.0.1", "Address to listen on.")
	flag.IntVar(&config.port, "port", 3333, "Port to listen on.")
	flag.Parse()

	stubHandler := NewStubHandler()
	if config.path != "" {
		stubHandler.fallbackHandler = http.FileServer(http.Dir(config.path))
	}
	http.Handle("/", stubHandler)

	var err error
	err = http.ListenAndServe(fmt.Sprintf("%s:%d", config.address, config.port), stubHandler)
	if err != nil {
		log.Fatalf("Unable to start server: %v\n", err)
	}
}
<|endoftext|>