<commit_before>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"time"
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	prgnames := ""
	prgs := ResolveDependencies([]string{prgnames})
	for _, prg := range prgs {
		install(prg)
	}
}

type Prg struct {
	name       string
	extractVer Extractor
	extractUrl Extractor
	folder     string
	cache      CacheGetter
}

type Arch struct {
	win32 string
	win64 string
}

func (a *Arch) Arch() string {
	// http://stackoverflow.com/questions/601089/detect-whether-current-windows-version-is-32-bit-or-64-bit
	if isdir, err := exists("C:\\Program Files (x86)"); isdir && err == nil {
		return a.win64
	} else if err != nil {
		fmt.Printf("Error checking C:\\Program Files (x86): '%v'", err)
		return ""
	}
	return a.win32
}

type fextract func(str string) string

type Extractor interface {
	ExtractFrom(str string) string
	Extract() string
	Next() Extractor
}

type CacheGetter interface {
	Get(resource string, name string) string
	Folder(name string) string
	Next() CacheGetter
}

type Cache struct {
	root string
}

func (c *Cache) Get(resource string, name string) string {
	dir := c.root + name
	if isdir, err := exists(dir); !isdir && err == nil {
		err := os.Mkdir(dir, 0755)
		if err != nil {
			fmt.Printf("Error creating cache folder for name '%v': '%v'\n", dir, err)
		}
		return ""
	} else if err != nil {
		fmt.Println("Error while testing dir existence '%v': '%v'\n", dir, err)
		return ""
	}
	filepath := dir + "/" + getLastModifiedFile(dir)
	if f, err := os.Open(filepath); err != nil {
		fmt.Println("Error while reading content of '%v': '%v'\n", filepath, err)
		return ""
	} else {
		defer f.Close()
		content := ""
		reader := bufio.NewReader(f)
		if contents, err := ioutil.ReadAll(reader); err != nil {
			fmt.Println("Error while reading content of '%v': '%v'\n", filepath, err)
			return ""
		} else {
			content = string(contents)
		}
		return content
	}
}

func (c *Cache) Next() CacheGetter {
	return nil
}
func (c *Cache) Folder(name string) string {
	return c.root + name + "/"
}

type Extractable struct {
	data  string
	name  string
	self  Extractor
	next  Extractor
	cache CacheGetter
	arch  *Arch
}

func (e *Extractable) Next() Extractor {
	return e.next
}

func (e *Extractable) Extract() string {
	res := e.self.ExtractFrom(e.data)
	if e.Next() != nil {
		res = e.Next().ExtractFrom(res)
	}
	return res
}

type ExtractorUrl struct {
	Extractable
}

func (eu *ExtractorUrl) ExtractFrom(url string) string {
	fmt.Println("ok! " + url)
	page := eu.cache.Get(url, eu.name)
	if page == "" {
		t := time.Now()
		filename := eu.cache.Folder(eu.name) + "_" + t.Format("20060102") + "_" + t.Format("150405")
		fmt.Println(filename)
		fmt.Println("empty page for " + url)
		response, err := http.Get(url)
		if err != nil {
			fmt.Println("Error while downloading", url, "-", err)
			return ""
		}
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			fmt.Println("Error while reading downloaded", url, "-", err)
			return ""
		}
		err = ioutil.WriteFile(filename, body, 0666)
		if err != nil {
			fmt.Printf("Error while writing downloaded '%v': '%v'\n", url, err)
			return ""
		}
		defer response.Body.Close()
		page = string(body)
		fmt.Printf("downloaded '%v' to cache '%v'\n", url, filename)
	} else {
		fmt.Printf("Got '%v' from cache\n", url)
	}
	fmt.Println(len(page))
	return page
}

func NewExtractorUrl(uri string, cache CacheGetter, name string, arch *Arch) *ExtractorUrl {
	res := &ExtractorUrl{Extractable{data: uri, cache: cache, name: name, arch: arch}}
	res.self = res
	return res
}

type ExtractorMatch struct {
	Extractable
	regexp *regexp.Regexp
}

func (eu *ExtractorMatch) ExtractFrom(content string) string {
	rx := eu.Regexp()
	matches := rx.FindAllStringSubmatchIndex(content, -1)
	res := ""
	if len(matches) >= 1 && len(matches[0]) >= 4 {
		res = content[matches[0][2]:matches[0][3]]
		fmt.Printf("RES='%v'\n", res)
	}
	return res
}

func (em *ExtractorMatch) Regexp() *regexp.Regexp {
	if em.regexp == nil {
		rx := em.data
		if em.arch != nil {
			rx := strings.Replace(rx, "_$arch_", em.arch.Arch(), -1)
			var err error = nil
			if em.regexp, err = regexp.Compile(rx); err != nil {
				em.regexp = nil
				fmt.Printf("Error compiling Regexp for '%v': '%v' => err '%v'", em.name, rx, err)
			}
		}

	}
	return em.regexp
}

func ResolveDependencies(prgnames []string) []*Prg {
	cache := &Cache{root: "test/_cache/"}
	if isdir, err := exists("test/_cache/"); !isdir && err == nil {
		err := os.Mkdir(cache.root, 0755)
		if err != nil {
			fmt.Printf("Error creating cache root folder: '%v'\n", err)
		}
	} else if err != nil {
		fmt.Printf("Error while checking existence of cache root folder: '%v'\n", err)
	}
	arch := &Arch{win32: "WINDOWS", win64: "WIN64"}
	dwnl := NewExtractorUrl("http://peazip.sourceforge.net/peazip-portable.html", cache, "peazip", arch)
	rx := &ExtractorMatch{Extractable{data: `/(peazip_portable-.*?\._$arch_).zip/download`, cache: cache, name: "peazip", arch: arch}, nil}
	dwnl.next = rx
	prgPeazip := &Prg{name: "peazip", extractVer: dwnl, cache: cache}
	prgGit := &Prg{name: "git"}
	prgInvalid := &Prg{name: "invalid"}
	return []*Prg{prgPeazip, prgGit, prgInvalid}
}

func install(prg *Prg) {
	folder := prg.GetFolder()
	if folder == "" {
		return
	}
	folder = "test/" + prg.name + "/" + folder
	if hasFolder, err := exists(folder); !hasFolder && err == nil {
		fmt.Printf("Need to install %v in '%v'\n", prg.name, folder)
		archive := prg.ArchiveName()
		fmt.Printf("Archive name: '%v'\n", archive)
	}
}

func (prg *Prg) ArchiveName() string {
	res := ""
	if prg.extractUrl != nil {
		res = prg.extractUrl.Extract()
	}
	return res
}

func (prg *Prg) GetFolder() string {
	if prg.folder == "" {
		if prg.extractVer != nil {
			prg.folder = prg.extractVer.Extract()
		}
	}
	return prg.folder
}

// exists returns whether the given file or directory exists or not
// http://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-denoted-by-a-path-exists-in-golang
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// https://groups.google.com/forum/#!topic/golang-nuts/Q7hYQ9GdX9Q

type byDate []os.FileInfo

func (f byDate) Len() int {
	return len(f)
}
func (f byDate) Less(i, j int) bool {
	return f[i].ModTime().Unix() > f[j].ModTime().Unix()
}
func (f byDate) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}

func getLastModifiedFile(dir string) string {
	f, err := os.Open(dir)
	if err != nil {
		fmt.Printf("Error while opening dir '%v': '%v'\n", dir, err)
		return ""
	}
	list, err := f.Readdir(-1)
	if err != nil {
		fmt.Printf("Error while reading dir '%v': '%v'\n", dir, err)
		return ""
	}
	if len(list) == 0 {
		return ""
	}
	fmt.Printf("t: '%v' => '%v'\n", list, list[0])
	sort.Sort(byDate(list))
	fmt.Printf("t: '%v' => '%v'\n", list, list[0])
	return list[0].Name()
}
<commit_msg>uses os.MkdirAll() instead of os.Mkdir().<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"time"
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	prgnames := ""
	prgs := ResolveDependencies([]string{prgnames})
	for _, prg := range prgs {
		install(prg)
	}
}

type Prg struct {
	name       string
	extractVer Extractor
	extractUrl Extractor
	folder     string
	cache      CacheGetter
}

type Arch struct {
	win32 string
	win64 string
}

func (a *Arch) Arch() string {
	// http://stackoverflow.com/questions/601089/detect-whether-current-windows-version-is-32-bit-or-64-bit
	if isdir, err := exists("C:\\Program Files (x86)"); isdir && err == nil {
		return a.win64
	} else if err != nil {
		fmt.Printf("Error checking C:\\Program Files (x86): '%v'", err)
		return ""
	}
	return a.win32
}

type fextract func(str string) string

type Extractor interface {
	ExtractFrom(str string) string
	Extract() string
	Next() Extractor
}

type CacheGetter interface {
	Get(resource string, name string) string
	Folder(name string) string
	Next() CacheGetter
}

type Cache struct {
	root string
}

func (c *Cache) Get(resource string, name string) string {
	dir := c.root + name
	if isdir, err := exists(dir); !isdir && err == nil {
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			fmt.Printf("Error creating cache folder for name '%v': '%v'\n", dir, err)
		}
		return ""
	} else if err != nil {
		fmt.Println("Error while testing dir existence '%v': '%v'\n", dir, err)
		return ""
	}
	filepath := dir + "/" + getLastModifiedFile(dir)
	if f, err := os.Open(filepath); err != nil {
		fmt.Println("Error while reading content of '%v': '%v'\n", filepath, err)
		return ""
	} else {
		defer f.Close()
		content := ""
		reader := bufio.NewReader(f)
		if contents, err := ioutil.ReadAll(reader); err != nil {
			fmt.Println("Error while reading content of '%v': '%v'\n", filepath, err)
			return ""
		} else {
			content = string(contents)
		}
		return content
	}
}

func (c *Cache) Next() CacheGetter {
	return nil
}
func (c *Cache) Folder(name string) string {
	return c.root + name + "/"
}

type Extractable struct {
	data  string
	name  string
	self  Extractor
	next  Extractor
	cache CacheGetter
	arch  *Arch
}

func (e *Extractable) Next() Extractor {
	return e.next
}

func (e *Extractable) Extract() string {
	res := e.self.ExtractFrom(e.data)
	if e.Next() != nil {
		res = e.Next().ExtractFrom(res)
	}
	return res
}

type ExtractorUrl struct {
	Extractable
}

func (eu *ExtractorUrl) ExtractFrom(url string) string {
	fmt.Println("ok! " + url)
	page := eu.cache.Get(url, eu.name)
	if page == "" {
		t := time.Now()
		filename := eu.cache.Folder(eu.name) + "_" + t.Format("20060102") + "_" + t.Format("150405")
		fmt.Println(filename)
		fmt.Println("empty page for " + url)
		response, err := http.Get(url)
		if err != nil {
			fmt.Println("Error while downloading", url, "-", err)
			return ""
		}
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			fmt.Println("Error while reading downloaded", url, "-", err)
			return ""
		}
		err = ioutil.WriteFile(filename, body, 0666)
		if err != nil {
			fmt.Printf("Error while writing downloaded '%v': '%v'\n", url, err)
			return ""
		}
		defer response.Body.Close()
		page = string(body)
		fmt.Printf("downloaded '%v' to cache '%v'\n", url, filename)
	} else {
		fmt.Printf("Got '%v' from cache\n", url)
	}
	fmt.Println(len(page))
	return page
}

func NewExtractorUrl(uri string, cache CacheGetter, name string, arch *Arch) *ExtractorUrl {
	res := &ExtractorUrl{Extractable{data: uri, cache: cache, name: name, arch: arch}}
	res.self = res
	return res
}

type ExtractorMatch struct {
	Extractable
	regexp *regexp.Regexp
}

func (eu *ExtractorMatch) ExtractFrom(content string) string {
	rx := eu.Regexp()
	matches := rx.FindAllStringSubmatchIndex(content, -1)
	res := ""
	if len(matches) >= 1 && len(matches[0]) >= 4 {
		res = content[matches[0][2]:matches[0][3]]
		fmt.Printf("RES='%v'\n", res)
	}
	return res
}

func (em *ExtractorMatch) Regexp() *regexp.Regexp {
	if em.regexp == nil {
		rx := em.data
		if em.arch != nil {
			rx := strings.Replace(rx, "_$arch_", em.arch.Arch(), -1)
			var err error = nil
			if em.regexp, err = regexp.Compile(rx); err != nil {
				em.regexp = nil
				fmt.Printf("Error compiling Regexp for '%v': '%v' => err '%v'", em.name, rx, err)
			}
		}

	}
	return em.regexp
}

func ResolveDependencies(prgnames []string) []*Prg {
	cache := &Cache{root: "test/_cache/"}
	if isdir, err := exists("test/_cache/"); !isdir && err == nil {
		err := os.MkdirAll(cache.root, 0755)
		if err != nil {
			fmt.Printf("Error creating cache root folder: '%v'\n", err)
		}
	} else if err != nil {
		fmt.Printf("Error while checking existence of cache root folder: '%v'\n", err)
	}
	arch := &Arch{win32: "WINDOWS", win64: "WIN64"}
	dwnl := NewExtractorUrl("http://peazip.sourceforge.net/peazip-portable.html", cache, "peazip", arch)
	rx := &ExtractorMatch{Extractable{data: `/(peazip_portable-.*?\._$arch_).zip/download`, cache: cache, name: "peazip", arch: arch}, nil}
	dwnl.next = rx
	prgPeazip := &Prg{name: "peazip", extractVer: dwnl, cache: cache}
	prgGit := &Prg{name: "git"}
	prgInvalid := &Prg{name: "invalid"}
	return []*Prg{prgPeazip, prgGit, prgInvalid}
}

func install(prg *Prg) {
	folder := prg.GetFolder()
	if folder == "" {
		return
	}
	folder = "test/" + prg.name + "/" + folder
	if hasFolder, err := exists(folder); !hasFolder && err == nil {
		fmt.Printf("Need to install %v in '%v'\n", prg.name, folder)
		archive := prg.ArchiveName()
		fmt.Printf("Archive name: '%v'\n", archive)
	}
}

func (prg *Prg) ArchiveName() string {
	res := ""
	if prg.extractUrl != nil {
		res = prg.extractUrl.Extract()
	}
	return res
}

func (prg *Prg) GetFolder() string {
	if prg.folder == "" {
		if prg.extractVer != nil {
			prg.folder = prg.extractVer.Extract()
		}
	}
	return prg.folder
}

// exists returns whether the given file or directory exists or not
// http://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-denoted-by-a-path-exists-in-golang
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// https://groups.google.com/forum/#!topic/golang-nuts/Q7hYQ9GdX9Q

type byDate []os.FileInfo

func (f byDate) Len() int {
	return len(f)
}
func (f byDate) Less(i, j int) bool {
	return f[i].ModTime().Unix() > f[j].ModTime().Unix()
}
func (f byDate) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}

func getLastModifiedFile(dir string) string {
	f, err := os.Open(dir)
	if err != nil {
		fmt.Printf("Error while opening dir '%v': '%v'\n", dir, err)
		return ""
	}
	list, err := f.Readdir(-1)
	if err != nil {
		fmt.Printf("Error while reading dir '%v': '%v'\n", dir, err)
		return ""
	}
	if len(list) == 0 {
		return ""
	}
	fmt.Printf("t: '%v' => '%v'\n", list, list[0])
	sort.Sort(byDate(list))
	fmt.Printf("t: '%v' => '%v'\n", list, list[0])
	return list[0].Name()
}
<|endoftext|>


<commit_before>// Force12.io is a package that monitors demand for resource in a system and then scales and repurposes
// containers, based on agreed "quality of service" contracts, to best handle that demand within the constraints of your existing VM
// or physical infrastructure (for v1).
//
// Force12 is defined to optimize the use of existing physical and VM resources instantly. VMs cannot be scaled in real time (it takes
// several minutes) and new physical machines take even longer. However, containers can be started or stopped at sub second speeds,
// allowing your infrastructure to adapt itself in real time to meet system demands.
//
// Force12 is aimed at effectively using the resources you have right now - your existing VMs or physical servers - by using them as
// optimally as possible.
//
// The Force12 approach is analogous to the way that a router dynamically optimises the use of a physical network. A router is limited
// by the capacity of the lines physically connected to it. Adding additional capacity is a physical process and takes time. Routers
// therefore make decisions in real time about which packets will be prioritized on a particular line based on the packet's priority
// (defined by a "quality of service" contract).
//
// For example, at times of high bandwidth usage a router might prioritize VOIP traffic over web browsing in real time.
//
// Containers allow Force12 to make similar "instant" judgements on service prioritisation within your existing infrastructure. Routers
// make very simplistic judgments because they have limited time and cpu and they act at a per packet level. Force12 has the capability
// of making far more sophisticated judgements, although even fairly simple ones will still provide a significant new service.
//
// This prototype is a bare bones implementation of Force12.io that recognises only 1 demand type:
// randomised demand for a priority 1 service. Resources are allocated to meet this demand for priority 1, and spare resource can
// be used for a priority 2 service.
//
// These demand type examples have been chosen purely for simplicity of demonstration. In the future more demand types
// will be offered
//
// V1 - Force12.io reacts to increased demand by starting/stopping containers on the slaves already in play.
//
// This version of Force12 starts and stops containers on a Mesos cluser using Marathon as the scheduler
package main

import (
	"log"
	"os"
	"time"

	"bitbucket.org/force12io/force12-scheduler/api"
	"bitbucket.org/force12io/force12-scheduler/compose"
	"bitbucket.org/force12io/force12-scheduler/consul"
	"bitbucket.org/force12io/force12-scheduler/demand"
	"bitbucket.org/force12io/force12-scheduler/marathon"
	"bitbucket.org/force12io/force12-scheduler/rng"
	"bitbucket.org/force12io/force12-scheduler/scheduler"
	"bitbucket.org/force12io/force12-scheduler/toy_scheduler"
)

const const_sleep = 100           // milliseconds
const const_sendstate_sleeps = 5  // number of sleeps before we send state on the API
const const_stopsleep = 250       // milliseconds pause between stopping and restarting containers
const const_p1demandstart int = 1 // The yaml file will automatically start one of each
const const_p2demandstart int = 1
const const_maxcontainers int = 9

var p1TaskName string = "priority1"
var p2TaskName string = "priority2"
var p1FamilyName string = "p1-family"
var p2FamilyName string = "p2-family"

var tasks map[string]demand.Task

// handleDemandChange checks the new demand
func handleDemandChange(input demand.Input, s scheduler.Scheduler) error {
	var err error = nil
	var demandChanged bool
	var t demand.Task

	demandChanged, err = update(input)
	if err != nil {
		log.Printf("Failed to get new demand. %v", err)
		return err
	}

	if demandChanged {
		// Ask the scheduler to make the changes
		for name, task := range tasks {
			t = task
			err = s.StopStartNTasks(name, task.FamilyName, t.Demand, &t.Requested)
			if err != nil {
				log.Printf("Failed to start %s tasks. %v", name, err)
				break
			}

			tasks[name] = t
		}
	}

	return err
}

// update checks for changes in demand, returning true if demand changed
func update(input demand.Input) (bool, error) {
	var err error = nil
	var demandchange bool

	// TODO! Make this less tied to the p1 / p2 simple model
	var p1 demand.Task = tasks[p1TaskName]
	var p2 demand.Task = tasks[p2TaskName]

	// Save the old demand
	oldP1Demand := p1.Demand
	oldP2Demand := p2.Demand

	p1.Demand, err = input.GetDemand(p1TaskName)
	if err != nil {
		log.Printf("Failed to get new demand for task %s. %v", p1TaskName, err)
		return false, err
	}
	//log.Printf("container count %v\n", container_count)
	p2.Demand = const_maxcontainers - p1.Demand

	//Has the demand changed?
	demandchange = (p1.Demand != oldP1Demand) || (p2.Demand != oldP2Demand)

	// Update tsaks map
	tasks[p1TaskName] = p1
	tasks[p2TaskName] = p2

	// This is where we could decide whether this is a significant enough
	// demand change to do anything

	log.Println(tasks)

	return demandchange, err
}

func getEnvOrDefault(name string, defaultValue string) string {
	v := os.Getenv(name)
	if v == "" {
		v = defaultValue
	}

	return v
}

// For the simple prototype, Force12.io sits in a loop checking for demand changes every X milliseconds
// In phase 2 we'll add a reactive mode where appropriate.
//
// Note - we don't route messages from demandcheckers to demandhandlers using channels because we want new values
// to override old values. Queued history is of no importance here.
//
// Also for simplicity this first release is concurrency free (single threaded)
func main() {
	var err error
	// TODO! Make it so you can send in settings on the command line
	var demandModelType string = getEnvOrDefault("F12_DEMAND_MODEL", "RNG")
	var schedulerType string = getEnvOrDefault("F12_SCHEDULER", "COMPOSE")
	var sendstateString string = getEnvOrDefault("F12_SEND_STATE_TO_API", "true")
	var sendstate bool = (sendstateString == "true")
	p1TaskName = getEnvOrDefault("F12_PRIORITY1_TASK", p1TaskName)
	p2TaskName = getEnvOrDefault("F12_PRIORITY2_TASK", p2TaskName)
	// TODO!! FInd out what CLIENT/SERVER_FAMILY should default to
	p1FamilyName = getEnvOrDefault("F12_PRIORITY1_FAMILY", p1FamilyName)
	p2FamilyName = getEnvOrDefault("F12_PRIORITY2_FAMILY", p2FamilyName)

	var di demand.Input
	var s scheduler.Scheduler

	switch demandModelType {
	case "CONSUL":
		log.Println("Getting demand metric from Consul")
		di = consul.NewDemandModel()
	case "RNG":
		log.Println("Random demand generation")
		di = rng.NewDemandModel()
	default:
		log.Printf("Bad value for F12_DEMAND_MODEL: %s", demandModelType)
		return
	}

	switch schedulerType {
	case "COMPOSE":
		log.Println("Scheduling with Docker compose")
		s = compose.NewScheduler()
	case "ECS":
		log.Println("Scheduling with ECS not yet supported")
		return
	case "MESOS":
		log.Println("Scheduling with Mesos / Marathon")
		s = marathon.NewScheduler()
	case "TOY":
		log.Println("Scheduling with toy scheduler")
		s = toy_scheduler.NewScheduler()
	default:
		log.Printf("Bad value for F12_SCHEDULER: %s", schedulerType)
		return
	}

	// Initialise task types
	tasks = make(map[string]demand.Task)

	tasks[p1TaskName] = demand.Task{
		FamilyName: p1FamilyName,
		Demand:     const_p1demandstart,
		Requested:  0,
	}

	tasks[p2TaskName] = demand.Task{
		FamilyName: p2FamilyName,
		Demand:     const_p2demandstart,
		Requested:  0,
	}

	// Let the scheduler know about these task types. For the moment the actual container information is hard-coded
	for name, _ := range tasks {
		err = s.InitScheduler(name)
		if err != nil {
			log.Printf("Failed to start task %s: %v", name, err)
			return
		}
	}

	var sleepcount int = 0
	var sleep time.Duration = const_sleep * time.Millisecond

	// Loop, continually checking for changes in demand that need to be scheduled
	// At the moment we plough on regardless in the face of errors, simply logging them out
	for {
		err = handleDemandChange(di, s)
		if err != nil {
			log.Printf("Failed to handle demand change. %v", err)
		}

		time.Sleep(sleep)
		sleepcount++
		if sleepcount == const_sendstate_sleeps {
			sleepcount = 0

			//Periodically send state to the API if required
			if sendstate {
				// TODO! User ID needs to be not hardcoded
				err = api.SendState("5k5gk", s, tasks)
				if err != nil {
					log.Printf("Failed to send state. %v", err)
				}
			}
		}
	}
}
<commit_msg>User ID not hardcoded<commit_after>// Force12.io is a package that monitors demand for resource in a system and then scales and repurposes
// containers, based on agreed "quality of service" contracts, to best handle that demand within the constraints of your existing VM
// or physical infrastructure (for v1).
//
// Force12 is defined to optimize the use of existing physical and VM resources instantly. VMs cannot be scaled in real time (it takes
// several minutes) and new physical machines take even longer. However, containers can be started or stopped at sub second speeds,
// allowing your infrastructure to adapt itself in real time to meet system demands.
//
// Force12 is aimed at effectively using the resources you have right now - your existing VMs or physical servers - by using them as
// optimally as possible.
//
// The Force12 approach is analogous to the way that a router dynamically optimises the use of a physical network. A router is limited
// by the capacity of the lines physically connected to it. Adding additional capacity is a physical process and takes time. Routers
// therefore make decisions in real time about which packets will be prioritized on a particular line based on the packet's priority
// (defined by a "quality of service" contract).
//
// For example, at times of high bandwidth usage a router might prioritize VOIP traffic over web browsing in real time.
//
// Containers allow Force12 to make similar "instant" judgements on service prioritisation within your existing infrastructure. Routers
// make very simplistic judgments because they have limited time and cpu and they act at a per packet level. Force12 has the capability
// of making far more sophisticated judgements, although even fairly simple ones will still provide a significant new service.
//
// This prototype is a bare bones implementation of Force12.io that recognises only 1 demand type:
// randomised demand for a priority 1 service. Resources are allocated to meet this demand for priority 1, and spare resource can
// be used for a priority 2 service.
//
// These demand type examples have been chosen purely for simplicity of demonstration. In the future more demand types
// will be offered
//
// V1 - Force12.io reacts to increased demand by starting/stopping containers on the slaves already in play.
//
// This version of Force12 starts and stops containers on a Mesos cluser using Marathon as the scheduler
package main

import (
	"log"
	"os"
	"time"

	"bitbucket.org/force12io/force12-scheduler/api"
	"bitbucket.org/force12io/force12-scheduler/compose"
	"bitbucket.org/force12io/force12-scheduler/consul"
	"bitbucket.org/force12io/force12-scheduler/demand"
	"bitbucket.org/force12io/force12-scheduler/marathon"
	"bitbucket.org/force12io/force12-scheduler/rng"
	"bitbucket.org/force12io/force12-scheduler/scheduler"
	"bitbucket.org/force12io/force12-scheduler/toy_scheduler"
)

const const_sleep = 100           // milliseconds
const const_sendstate_sleeps = 5  // number of sleeps before we send state on the API
const const_stopsleep = 250       // milliseconds pause between stopping and restarting containers
const const_p1demandstart int = 1 // The yaml file will automatically start one of each
const const_p2demandstart int = 1
const const_maxcontainers int = 9

var p1TaskName string = "priority1"
var p2TaskName string = "priority2"
var p1FamilyName string = "p1-family"
var p2FamilyName string = "p2-family"

var tasks map[string]demand.Task

// handleDemandChange checks the new demand
func handleDemandChange(input demand.Input, s scheduler.Scheduler) error {
	var err error = nil
	var demandChanged bool
	var t demand.Task

	demandChanged, err = update(input)
	if err != nil {
		log.Printf("Failed to get new demand. %v", err)
		return err
	}

	if demandChanged {
		// Ask the scheduler to make the changes
		for name, task := range tasks {
			t = task
			err = s.StopStartNTasks(name, task.FamilyName, t.Demand, &t.Requested)
			if err != nil {
				log.Printf("Failed to start %s tasks. %v", name, err)
				break
			}

			tasks[name] = t
		}
	}

	return err
}

// update checks for changes in demand, returning true if demand changed
func update(input demand.Input) (bool, error) {
	var err error = nil
	var demandchange bool

	// TODO! Make this less tied to the p1 / p2 simple model
	var p1 demand.Task = tasks[p1TaskName]
	var p2 demand.Task = tasks[p2TaskName]

	// Save the old demand
	oldP1Demand := p1.Demand
	oldP2Demand := p2.Demand

	p1.Demand, err = input.GetDemand(p1TaskName)
	if err != nil {
		log.Printf("Failed to get new demand for task %s. %v", p1TaskName, err)
		return false, err
	}
	//log.Printf("container count %v\n", container_count)
	p2.Demand = const_maxcontainers - p1.Demand

	//Has the demand changed?
	demandchange = (p1.Demand != oldP1Demand) || (p2.Demand != oldP2Demand)

	// Update tsaks map
	tasks[p1TaskName] = p1
	tasks[p2TaskName] = p2

	// This is where we could decide whether this is a significant enough
	// demand change to do anything

	log.Println(tasks)

	return demandchange, err
}

func getEnvOrDefault(name string, defaultValue string) string {
	v := os.Getenv(name)
	if v == "" {
		v = defaultValue
	}

	return v
}

// For the simple prototype, Force12.io sits in a loop checking for demand changes every X milliseconds
// In phase 2 we'll add a reactive mode where appropriate.
//
// Note - we don't route messages from demandcheckers to demandhandlers using channels because we want new values
// to override old values. Queued history is of no importance here.
//
// Also for simplicity this first release is concurrency free (single threaded)
func main() {
	var err error
	// TODO! Make it so you can send in settings on the command line
	var demandModelType string = getEnvOrDefault("F12_DEMAND_MODEL", "RNG")
	var schedulerType string = getEnvOrDefault("F12_SCHEDULER", "COMPOSE")
	var sendstateString string = getEnvOrDefault("F12_SEND_STATE_TO_API", "true")
	var sendstate bool = (sendstateString == "true")
	var userID string = getEnvOrDefault("F12_USER_ID", "5k5gk")
	p1TaskName = getEnvOrDefault("F12_PRIORITY1_TASK", p1TaskName)
	p2TaskName = getEnvOrDefault("F12_PRIORITY2_TASK", p2TaskName)
	// TODO!! FInd out what CLIENT/SERVER_FAMILY should default to
	p1FamilyName = getEnvOrDefault("F12_PRIORITY1_FAMILY", p1FamilyName)
	p2FamilyName = getEnvOrDefault("F12_PRIORITY2_FAMILY", p2FamilyName)

	var di demand.Input
	var s scheduler.Scheduler

	switch demandModelType {
	case "CONSUL":
		log.Println("Getting demand metric from Consul")
		di = consul.NewDemandModel()
	case "RNG":
		log.Println("Random demand generation")
		di = rng.NewDemandModel()
	default:
		log.Printf("Bad value for F12_DEMAND_MODEL: %s", demandModelType)
		return
	}

	switch schedulerType {
	case "COMPOSE":
		log.Println("Scheduling with Docker compose")
		s = compose.NewScheduler()
	case "ECS":
		log.Println("Scheduling with ECS not yet supported")
		return
	case "MESOS":
		log.Println("Scheduling with Mesos / Marathon")
		s = marathon.NewScheduler()
	case "TOY":
		log.Println("Scheduling with toy scheduler")
		s = toy_scheduler.NewScheduler()
	default:
		log.Printf("Bad value for F12_SCHEDULER: %s", schedulerType)
		return
	}

	// Initialise task types
	tasks = make(map[string]demand.Task)

	tasks[p1TaskName] = demand.Task{
		FamilyName: p1FamilyName,
		Demand:     const_p1demandstart,
		Requested:  0,
	}

	tasks[p2TaskName] = demand.Task{
		FamilyName: p2FamilyName,
		Demand:     const_p2demandstart,
		Requested:  0,
	}

	// Let the scheduler know about these task types. For the moment the actual container information is hard-coded
	for name, _ := range tasks {
		err = s.InitScheduler(name)
		if err != nil {
			log.Printf("Failed to start task %s: %v", name, err)
			return
		}
	}

	var sleepcount int = 0
	var sleep time.Duration = const_sleep * time.Millisecond

	// Loop, continually checking for changes in demand that need to be scheduled
	// At the moment we plough on regardless in the face of errors, simply logging them out
	for {
		err = handleDemandChange(di, s)
		if err != nil {
			log.Printf("Failed to handle demand change. %v", err)
		}

		time.Sleep(sleep)
		sleepcount++
		if sleepcount == const_sendstate_sleeps {
			sleepcount = 0

			//Periodically send state to the API if required
			if sendstate {
				err = api.SendState(userID, s, tasks)
				if err != nil {
					log.Printf("Failed to send state. %v", err)
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

// I want to install glide, I don't remember its full packagename, how to not google?

// Search packages base on name
// Then use result as output for go get -u
// Somewhat like ``pip search PACKAGE``
import (
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
)

var found bool
var wanted string
var categoryFlag = flag.String("c", "", "Show packages in `category`. Use `all` for list of all categories.")
var rawFlag = flag.Bool("r", false, "Show the raw data of Awesome-go")

type Package struct {
	name     string
	pkg      string
	desc     string
	category string
}

func getNameAndDesc(left string, right string) Package {
	// use LastIndex as string inside [name] can contain (), e.g hipchat (xmpp)
	open := strings.LastIndex(left, "(")
	close := strings.LastIndex(left, ")")
	pkg := left[open+1 : close]
	pkg = strings.Trim(pkg, "/")
	pkg = pkg[strings.Index(pkg, "://")+3:]

	name := pkg[strings.LastIndex(pkg, "/")+1:]
	return Package{pkg: pkg, name: name, desc: right}
}

var (
	reContainsLink        = regexp.MustCompile(`\* \[.*\]\(.*\)`)
	reOnlyLink            = regexp.MustCompile(`\* \[.*\]\(.*\)$`)
	reLinkWithDescription = regexp.MustCompile(`\* (\[.*\]\(.*\)) - (\S.*)`)
)

// TODO handles
/*
gocql.github.io
godoc.org/labix.org/v2/mgo
mattn.github.io/go-gtk
eclipse.org/paho/clients/golang
www.consul.io
nsq.io
onsi.github.io/ginkgo
labix.org/gocheck
onsi.github.io/gomega
aahframework.org
gobuffalo.io
rest-layer.io
*/
func rawData() (rawdata []byte, err error) {
	rawdata, err = Asset("data/README.md")
	return rawdata, err
}
func myUsage() {
	fmt.Printf("Usage: %s packagename \n", os.Args[0])
	fmt.Printf("       %s [OPTIONS] [OPTIONS arguments] \n\n", os.Args[0])
	fmt.Printf("Options:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = myUsage
	rawdata, err := rawData()
	if err != nil {
		log.Fatal("Cannot read file")
	}

	flag.Parse()

	var matched, containsLink, noDescription bool
	var category string
	var categories = map[string]int{}

	lines := strings.Split(string(rawdata), "\n")
	if *rawFlag {
		for _, line := range lines {
			fmt.Println(line)
		}
		return
	}

	for _, line := range lines {
		line = strings.Trim(line, " ")
		if strings.HasPrefix(line, "## ") {
			category = strings.ToLower(line[3:])
			categories[category] = 0
		}
		containsLink = reContainsLink.MatchString(line)
		if containsLink {
			noDescription = reOnlyLink.MatchString(line)
			if noDescription {
				continue
			}

			matched = reLinkWithDescription.MatchString(line)
			if !matched {
				// fmt.Printf("WARNING bad entry %s\n", line)
			} else {
				// * [zeus](https://github.com/daryl/zeus)
				tmp := reLinkWithDescription.FindAllStringSubmatch(line, 3)
				left := tmp[0][1]
				right := tmp[0][2]
				pkg := getNameAndDesc(left, right)
				pkg.category = category

				categories[pkg.category] += 1

				if *categoryFlag != "" {
					if *categoryFlag == "all" {
						found = true
						// defer print result before exitting
					}
					if *categoryFlag == pkg.category {
						fmt.Printf("%s - %s\n", pkg.pkg, pkg.desc)
						found = true
					}
				} else {

					if flag.NArg() == 0 {
						flag.Usage()
						os.Exit(1)
					}
					wanted = flag.Args()[0]

					if wanted == pkg.name {
						fmt.Printf("Package: %s\n", pkg.pkg)
						fmt.Printf("Category: %s\n", pkg.category)
						fmt.Printf("Description-en: %s\n", pkg.desc)

						found = true
					}
				}
			}

		}
	}

	if *categoryFlag == "all" {
		var cats []string

		for k, _ := range categories {
			cats = append(cats, k)
		}
		sort.Strings(cats)

		for _, k := range cats {
			fmt.Printf("%s: %d packages\n", k, categories[k])

		}

	}

	if !found {
		fmt.Printf("Not found `%s`\n", wanted)
		os.Exit(1)
	}
}
<commit_msg>This is bindata, not file<commit_after>package main

// I want to install glide, I don't remember its full packagename, how to not google?

// Search packages base on name
// Then use result as output for go get -u
// Somewhat like ``pip search PACKAGE``
import (
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
)

var found bool
var wanted string
var categoryFlag = flag.String("c", "", "Show packages in `category`. Use `all` for list of all categories.")
var rawFlag = flag.Bool("r", false, "Show the raw data of Awesome-go")

type Package struct {
	name     string
	pkg      string
	desc     string
	category string
}

func getNameAndDesc(left string, right string) Package {
	// use LastIndex as string inside [name] can contain (), e.g hipchat (xmpp)
	open := strings.LastIndex(left, "(")
	close := strings.LastIndex(left, ")")
	pkg := left[open+1 : close]
	pkg = strings.Trim(pkg, "/")
	pkg = pkg[strings.Index(pkg, "://")+3:]

	name := pkg[strings.LastIndex(pkg, "/")+1:]
	return Package{pkg: pkg, name: name, desc: right}
}

var (
	reContainsLink        = regexp.MustCompile(`\* \[.*\]\(.*\)`)
	reOnlyLink            = regexp.MustCompile(`\* \[.*\]\(.*\)$`)
	reLinkWithDescription = regexp.MustCompile(`\* (\[.*\]\(.*\)) - (\S.*)`)
)

// TODO handles
/*
gocql.github.io
godoc.org/labix.org/v2/mgo
mattn.github.io/go-gtk
eclipse.org/paho/clients/golang
www.consul.io
nsq.io
onsi.github.io/ginkgo
labix.org/gocheck
onsi.github.io/gomega
aahframework.org
gobuffalo.io
rest-layer.io
*/
func rawData() (rawdata []byte, err error) {
	rawdata, err = Asset("data/README.md")
	return rawdata, err
}
func myUsage() {
	fmt.Printf("Usage: %s packagename \n", os.Args[0])
	fmt.Printf("       %s [OPTIONS] [OPTIONS arguments] \n\n", os.Args[0])
	fmt.Printf("Options:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = myUsage
	rawdata, err := rawData()
	if err != nil {
		log.Fatal("Cannot read data")
	}

	flag.Parse()

	var matched, containsLink, noDescription bool
	var category string
	var categories = map[string]int{}

	lines := strings.Split(string(rawdata), "\n")
	if *rawFlag {
		for _, line := range lines {
			fmt.Println(line)
		}
		return
	}

	for _, line := range lines {
		line = strings.Trim(line, " ")
		if strings.HasPrefix(line, "## ") {
			category = strings.ToLower(line[3:])
			categories[category] = 0
		}
		containsLink = reContainsLink.MatchString(line)
		if containsLink {
			noDescription = reOnlyLink.MatchString(line)
			if noDescription {
				continue
			}

			matched = reLinkWithDescription.MatchString(line)
			if !matched {
				// fmt.Printf("WARNING bad entry %s\n", line)
			} else {
				// * [zeus](https://github.com/daryl/zeus)
				tmp := reLinkWithDescription.FindAllStringSubmatch(line, 3)
				left := tmp[0][1]
				right := tmp[0][2]
				pkg := getNameAndDesc(left, right)
				pkg.category = category

				categories[pkg.category] += 1

				if *categoryFlag != "" {
					if *categoryFlag == "all" {
						found = true
						// defer print result before exitting
					}
					if *categoryFlag == pkg.category {
						fmt.Printf("%s - %s\n", pkg.pkg, pkg.desc)
						found = true
					}
				} else {

					if flag.NArg() == 0 {
						flag.Usage()
						os.Exit(1)
					}
					wanted = flag.Args()[0]

					if wanted == pkg.name {
						fmt.Printf("Package: %s\n", pkg.pkg)
						fmt.Printf("Category: %s\n", pkg.category)
						fmt.Printf("Description-en: %s\n", pkg.desc)

						found = true
					}
				}
			}

		}
	}

	if *categoryFlag == "all" {
		var cats []string

		for k, _ := range categories {
			cats = append(cats, k)
		}
		sort.Strings(cats)

		for _, k := range cats {
			fmt.Printf("%s: %d packages\n", k, categories[k])

		}

	}

	if !found {
		fmt.Printf("Not found `%s`\n", wanted)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"time"

	"github.com/AlexanderThaller/logger"
	"github.com/juju/errgo"
	"github.com/julienschmidt/httprouter"
	"github.com/spf13/viper"
)

const (
	// Name is the name of the application. Used in logging.
	Name = "wikgo"
)

var (
	BuildHash string
	BuildTime string
)

func init() {
	err := configure()
	if err != nil {
		panic(err)
	}

	loglevel, err := logger.ParsePriority(viper.GetString("LogLevel"))
	if err != nil {
		panic(err)
	}

	err = logger.SetLevel(".", loglevel)
	if err != nil {
		panic(err)
	}
}

func main() {
	l := logger.New(Name, "main")
	l.Info("Version: ", fmt.Sprintf("%v-b%v", BuildHash, BuildTime))

	pagesFolder := viper.GetString("PagesFolder")
	binding := viper.GetString("Binding")

	router := httprouter.New()
	router.GET("/", rootHandler)
	router.GET("/"+pagesFolder+"/*path", pagesHandler)

	l.Notice("Listening on ", binding)
	err := http.ListenAndServe(binding, router)
	if err != nil {
		l.Alert(errgo.Notef(err, "can not listen on binding"))
		os.Exit(1)
	}
}

func rootHandler(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	pagesFolder := viper.GetString("PagesFolder")
	http.Redirect(wr, re, "/"+pagesFolder+"/", 301)
}

func pagesHandler(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandler")
	timestart := time.Now()
	ip, _, _ := net.SplitHostPort(re.RemoteAddr)

	path := path.Clean("./" + re.URL.Path)
	l.Notice("Sending ", path, " to ", ip)

	stat, err := os.Stat(path)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not stat path"))
		return
	}

	if stat.Mode().IsDir() {
		l.Trace("Filetype: Directory")
		pagesHandlerDirectory(wr, re, ps)
	}

	if stat.Mode().IsRegular() {
		l.Trace("Filetype: File")
		pagesHandlerFile(wr, re, ps)
	}

	if !stat.Mode().IsDir() && !stat.Mode().IsRegular() {
		l.Error("Filetype is not a directory and not a regular file. Something is strange.")
	}

	l.Debug("Sent ", path, " (", time.Since(timestart), ")")
}

func pagesHandlerDirectory(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandlerDirectory")

	urlpath := "./" + re.URL.Path
	files, err := ioutil.ReadDir(urlpath)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not read from directory"))
		return
	}

	fmt.Fprintf(wr, `<!DOCTYPE html>

  <meta charset="utf-8">
  <title>title</title>

  `)
	for _, file := range files {
		filepath := path.Clean(re.URL.Path + "/" + file.Name())
		fmt.Fprintf(wr, ""+file.Name()+"")
		fmt.Fprintf(wr, "
\n")
	}
	fmt.Fprintf(wr, `
  `)
}

func pagesHandlerFile(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandlerDirectory")

	path := "./" + re.URL.Path
	file, err := os.Open(path)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not open file for reading"))
		return
	}
	defer file.Close()

	l.Trace("Filepath Extention: ", filepath.Ext(path))
	switch filepath.Ext(path) {
	case ".asciidoc":
		err = asciiDoctor(file, wr)
		if err != nil {
			printerr(l, wr, errgo.Notef(err, "can not format file with asciidoctor"))
			return
		}

	default:
		_, err = io.Copy(wr, file)
		if err != nil {
			printerr(l, wr, errgo.Notef(err, "can not copy file to response writer"))
			return
		}
	}
}

func printerr(l logger.Logger, wr http.ResponseWriter, err error) {
	l.Error(errgo.Details(err))
	fmt.Fprintf(wr, errgo.Details(err))

	return
}

func asciiDoctor(reader io.Reader, writer io.Writer) error {
	stderr := new(bytes.Buffer)

	command := exec.Command("asciidoctor", "-")
	command.Stdin = reader
	command.Stdout = writer
	command.Stderr = stderr

	err := command.Run()
	if err != nil {
		return errgo.Notef(errgo.Notef(err, "can not run asciidoctor"),
			stderr.String())
	}

	return nil
}
<commit_msg>Added query parameter to show the raw page source if specified in url.<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"time"

	"github.com/AlexanderThaller/logger"
	"github.com/juju/errgo"
	"github.com/julienschmidt/httprouter"
	"github.com/spf13/viper"
)

const (
	// Name is the name of the application. Used in logging.
	Name = "wikgo"
)

var (
	BuildHash string
	BuildTime string
)

func init() {
	err := configure()
	if err != nil {
		panic(err)
	}

	loglevel, err := logger.ParsePriority(viper.GetString("LogLevel"))
	if err != nil {
		panic(err)
	}

	err = logger.SetLevel(".", loglevel)
	if err != nil {
		panic(err)
	}
}

func main() {
	l := logger.New(Name, "main")
	l.Info("Version: ", fmt.Sprintf("%v-b%v", BuildHash, BuildTime))

	pagesFolder := viper.GetString("PagesFolder")
	binding := viper.GetString("Binding")

	router := httprouter.New()
	router.GET("/", rootHandler)
	router.GET("/"+pagesFolder+"/*path", pagesHandler)

	l.Notice("Listening on ", binding)
	err := http.ListenAndServe(binding, router)
	if err != nil {
		l.Alert(errgo.Notef(err, "can not listen on binding"))
		os.Exit(1)
	}
}

func rootHandler(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	pagesFolder := viper.GetString("PagesFolder")
	http.Redirect(wr, re, "/"+pagesFolder+"/", 301)
}

func pagesHandler(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandler")
	timestart := time.Now()
	ip, _, _ := net.SplitHostPort(re.RemoteAddr)

	path := path.Clean("./" + re.URL.Path)
	l.Notice("Sending ", path, " to ", ip)

	stat, err := os.Stat(path)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not stat path"))
		return
	}

	if stat.Mode().IsDir() {
		l.Trace("Filetype: Directory")
		pagesHandlerDirectory(wr, re, ps)
	}

	if stat.Mode().IsRegular() {
		l.Trace("Filetype: File")
		pagesHandlerFile(wr, re, ps)
	}

	if !stat.Mode().IsDir() && !stat.Mode().IsRegular() {
		l.Error("Filetype is not a directory and not a regular file. Something is strange.")
	}

	l.Debug("Sent ", path, " (", time.Since(timestart), ")")
}

func pagesHandlerDirectory(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandlerDirectory")

	urlpath := "./" + re.URL.Path
	files, err := ioutil.ReadDir(urlpath)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not read from directory"))
		return
	}

	fmt.Fprintf(wr, `<!DOCTYPE html>

  <meta charset="utf-8">
  <title>title</title>

  `)
	for _, file := range files {
		filepath := path.Clean(re.URL.Path + "/" + file.Name())
		fmt.Fprintf(wr, ""+file.Name()+"")
		fmt.Fprintf(wr, "
\n")
	}
	fmt.Fprintf(wr, `
  `)
}

func pagesHandlerFile(wr http.ResponseWriter, re *http.Request, ps httprouter.Params) {
	l := logger.New(Name, "pagesHandlerDirectory")

	path := "./" + re.URL.Path
	file, err := os.Open(path)
	if err != nil {
		printerr(l, wr, errgo.Notef(err, "can not open file for reading"))
		return
	}
	defer file.Close()

	queries := re.URL.Query()

	ext := filepath.Ext(path)

	_, sendraw := queries["raw"]

	if sendraw {
		ext = ""
	}

	l.Trace("Filepath Extention: ", ext)

	switch ext {
	case ".asciidoc":
		err = asciiDoctor(file, wr)
		if err != nil {
			printerr(l, wr, errgo.Notef(err, "can not format file with asciidoctor"))
			return
		}

	default:
		_, err = io.Copy(wr, file)
		if err != nil {
			printerr(l, wr, errgo.Notef(err, "can not copy file to response writer"))
			return
		}
	}
}

func printerr(l logger.Logger, wr http.ResponseWriter, err error) {
	l.Error(errgo.Details(err))
	fmt.Fprintf(wr, errgo.Details(err))

	return
}

func asciiDoctor(reader io.Reader, writer io.Writer) error {
	stderr := new(bytes.Buffer)

	command := exec.Command("asciidoctor", "-")
	command.Stdin = reader
	command.Stdout = writer
	command.Stderr = stderr

	err := command.Run()
	if err != nil {
		return errgo.Notef(errgo.Notef(err, "can not run asciidoctor"),
			stderr.String())
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import "flag"

var ip = flag.String("ip", "0.0.0.0", "servser IP")
var port = flag.String("port", "9099", "servser port")

func main() {
	flag.Parse()
	server := NewServer()
	server.Run(*ip, *port)
}
<commit_msg>Issue #3. Move flag init<commit_after>package main

import "flag"

func main() {
	var ip = flag.String("ip", "0.0.0.0", "servser IP")
	var port = flag.String("port", "9099", "servser port")

	flag.Parse()
	server := NewServer()
	server.Run(*ip, *port)
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Sean Malloy
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
//    may be used to endorse or promote products derived from this software without
//    specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	//
	// https://blog.komand.com/build-a-simple-cli-tool-with-golang
	//

	flag.Usage = func() {
		os.Stderr.WriteString("Commands:\n")
		os.Stderr.WriteString("  spark help [COMMAND]\n")
		os.Stderr.WriteString("  spark msg [OPTION...] MESSAGE\n")
	}

	flag.Parse()

	helpCommand := flag.NewFlagSet("help", flag.ExitOnError)

	helpCommand.Usage = func() {
		os.Stderr.WriteString("Print help messages\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark help COMMAND\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark help msg\n")
	}

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)
	msgPersonOpt := msgCommand.String("p", "", "send message to `PERSON`")
	msgSpaceOpt := msgCommand.String("s", "", "send message to `SPACE`")
	msgFileOpt := msgCommand.String("f", "", "send `FILE` as an attachment")

	msgCommand.Usage = func() {
		os.Stderr.WriteString("Send message to a person or a space\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark msg -p PERSON [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("  spark msg -s SPACE [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("OPTIONS\n")
		msgCommand.PrintDefaults()
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark msg -p joe.smith@example.com 'hello world'\n")
	}

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		flag.Usage()
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "help":
		if len(os.Args) <= 2 {
			flag.Usage()
			os.Exit(0)
		}
		helpCommand.Parse(os.Args[2:])
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.Usage()
		os.Exit(1)
	}

	if helpCommand.Parsed() {
		if os.Args[2] == "msg" {
			msgCommand.Usage()
		} else {
			flag.Usage()
			os.Exit(1)
		}
	}

	if msgCommand.Parsed() {
		if msgCommand.Arg(0) == "" {
			// missing message
			os.Stderr.WriteString("Error: missing MESSAGE\n")
			os.Stderr.WriteString("\n")
			msgCommand.Usage()
			os.Exit(1)
		}

		if *msgPersonOpt == "" && *msgSpaceOpt == "" {
			// neither -p or -s were given
			msgCommand.Usage()
			os.Exit(1)
		}
		if *msgPersonOpt != "" && *msgSpaceOpt != "" {
			// -p and -s were both given
			msgCommand.Usage()
			os.Exit(1)
		}

		// -f is optional
		if *msgFileOpt == "" {
			if *msgPersonOpt != "" {
				// send message to a person
				fmt.Println("send message to a person")
			}

			if *msgSpaceOpt != "" {
				// send message to a space
				fmt.Println("send message to a space")
			}
		} else {
			if *msgPersonOpt != "" {
				// send file to a person
				fmt.Println("send file to a person")
			}

			if *msgSpaceOpt != "" {
				// send file to a space
				fmt.Println("send file to a space")
			}
		}

	}

	os.Exit(0)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Auth Token: ")
	token, _ := reader.ReadString('\n')
	token = strings.TrimSuffix(token, "\n")
	sparkClient.Authorization = "Bearer " + token

	myPersonID := "722bb271-d7ca-4bce-a9e3-471e4412fa77"

	// POST messages - Text Message
	message := &ciscospark.MessageRequest{
		Text:       "This is a text message",
		ToPersonID: myPersonID,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(message)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}
<commit_msg>Add comment to track next steps<commit_after>// Copyright (c) 2017, Sean Malloy
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
//    may be used to endorse or promote products derived from this software without
//    specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	//
	// https://blog.komand.com/build-a-simple-cli-tool-with-golang
	//

	flag.Usage = func() {
		os.Stderr.WriteString("Commands:\n")
		os.Stderr.WriteString("  spark help [COMMAND]\n")
		os.Stderr.WriteString("  spark msg [OPTION...] MESSAGE\n")
	}

	flag.Parse()

	helpCommand := flag.NewFlagSet("help", flag.ExitOnError)

	helpCommand.Usage = func() {
		os.Stderr.WriteString("Print help messages\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark help COMMAND\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark help msg\n")
	}

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)
	msgPersonOpt := msgCommand.String("p", "", "send message to `PERSON`")
	msgSpaceOpt := msgCommand.String("s", "", "send message to `SPACE`")
	msgFileOpt := msgCommand.String("f", "", "send `FILE` as an attachment")

	msgCommand.Usage = func() {
		os.Stderr.WriteString("Send message to a person or a space\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark msg -p PERSON [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("  spark msg -s SPACE [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("OPTIONS\n")
		msgCommand.PrintDefaults()
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark msg -p joe.smith@example.com 'hello world'\n")
	}

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		flag.Usage()
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "help":
		if len(os.Args) <= 2 {
			flag.Usage()
			os.Exit(0)
		}
		helpCommand.Parse(os.Args[2:])
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.Usage()
		os.Exit(1)
	}

	if helpCommand.Parsed() {
		if os.Args[2] == "msg" {
			msgCommand.Usage()
		} else {
			flag.Usage()
			os.Exit(1)
		}
	}

	if msgCommand.Parsed() {
		if msgCommand.Arg(0) == "" {
			// missing message
			os.Stderr.WriteString("Error: missing MESSAGE\n")
			os.Stderr.WriteString("\n")
			msgCommand.Usage()
			os.Exit(1)
		}

		if *msgPersonOpt == "" && *msgSpaceOpt == "" {
			// neither -p or -s were given
			msgCommand.Usage()
			os.Exit(1)
		}
		if *msgPersonOpt != "" && *msgSpaceOpt != "" {
			// -p and -s were both given
			msgCommand.Usage()
			os.Exit(1)
		}

		// -f is optional
		if *msgFileOpt == "" {
			if *msgPersonOpt != "" {
				// send message to a person
				fmt.Println("send message to a person")
			}

			if *msgSpaceOpt != "" {
				// send message to a space
				fmt.Println("send message to a space")
			}
		} else {
			if *msgPersonOpt != "" {
				// send file to a person
				fmt.Println("send file to a person")
			}

			if *msgSpaceOpt != "" {
				// send file to a space
				fmt.Println("send file to a space")
			}
		}

	}

	os.Exit(0)

	//
	// START: create functions to send messages to people and spaces
	//

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Auth Token: ")
	token, _ := reader.ReadString('\n')
	token = strings.TrimSuffix(token, "\n")
	sparkClient.Authorization = "Bearer " + token

	myPersonID := "722bb271-d7ca-4bce-a9e3-471e4412fa77"

	// POST messages - Text Message
	message := &ciscospark.MessageRequest{
		Text:       "This is a text message",
		ToPersonID: myPersonID,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(message)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}
<|endoftext|>


<commit_before>package main

import "log"
import "fmt"
import "os"

import "github.com/weirdtales/senor-rosado/slack"
import "github.com/weirdtales/senor-rosado/cmds"

var cmdMap = map[string]slack.ChatFn{
    "weather": func(m slack.Message, r *slack.Reply) error { return cmds.Weather(m, r) },
    "hello":   func(m slack.Message, r *slack.Reply) error { return cmds.Hello(m, r) },
}

func main() {
    // TODO: signals
    if len(os.Args) < 2 {
        fmt.Fprintf(os.Stderr, "usage: %s <TOKEN>\n", os.Args[0])
        os.Exit(1)
    }

    conn, err := slack.Connect(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    os.Exit(slack.ChatLoop(conn, cmdMap))
}
<commit_msg>add a TODO<commit_after>package main

import "log"
import "fmt"
import "os"

import "github.com/weirdtales/senor-rosado/slack"
import "github.com/weirdtales/senor-rosado/cmds"

// TODO goroutines for these
var cmdMap = map[string]slack.ChatFn{
    "weather": func(m slack.Message, r *slack.Reply) error { return cmds.Weather(m, r) },
    "hello":   func(m slack.Message, r *slack.Reply) error { return cmds.Hello(m, r) },
}

func main() {
    // TODO: signals
    if len(os.Args) < 2 {
        fmt.Fprintf(os.Stderr, "usage: %s <TOKEN>\n", os.Args[0])
        os.Exit(1)
    }

    conn, err := slack.Connect(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    os.Exit(slack.ChatLoop(conn, cmdMap))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"
	"os/exec"
	"log"
	"io/ioutil"

	"github.com/drone/drone-plugin-go/plugin"
)

type Fabric struct {
	Commands  []string `json:"commands"`
}

func main() {
	workspace := plugin.Workspace{}
	vargs := Fabric{}

	plugin.Param("workspace", &workspace)
	plugin.Param("vargs", &vargs)

	// parse the parameters
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	err := ioutil.WriteFile("/tmp/private_key", []byte(workspace.Keys.Private), 0644)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(99)
	}

	fabfile := fmt.Sprintf("--fabfile=%s/fabfile.py", workspace.Path)

	for _, c := range vargs.Commands {
		command := fmt.Sprintf("%s %s", fabfile, c)
		fabArgs := strings.Split(command, " ")
		fabArgs = append(fabArgs, "-i", "/tmp/private_key")

		c := exec.Command("fab", fabArgs...)
		c.Stdout = os.Stdout
		c.Stderr = os.Stderr
		err := c.Run()
		if err != nil {
			log.Println(err)
			os.Exit(101)
		}
	}
}
<commit_msg>Write private key<commit_after>package main

import (
	"fmt"
	"os"
	"strings"
	"os/exec"
	"os/user"
	"log"
	"io/ioutil"
	"path/filepath"

	"github.com/drone/drone-plugin-go/plugin"
)

type Fabric struct {
	Commands  []string `json:"commands"`
}

func main() {
	workspace := plugin.Workspace{}
	vargs := Fabric{}

	plugin.Param("workspace", &workspace)
	plugin.Param("vargs", &vargs)

	// parse the parameters
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	err := writeKey(workspace)

	fabfile := fmt.Sprintf("--fabfile=%s/fabfile.py", workspace.Path)

	for _, c := range vargs.Commands {
		command := fmt.Sprintf("%s %s", fabfile, c)
		fabArgs := strings.Split(command, " ")

		c := exec.Command("fab", fabArgs...)
		c.Stdout = os.Stdout
		c.Stderr = os.Stderr
		err := c.Run()
		if err != nil {
			log.Println(err)
			os.Exit(101)
		}
	}
}

func writeKey(in *plugin.Workspace) error {
	if in.Keys == nil || len(in.Keys.Private) == 0 {
		return nil
	}
	home := "/root"
	u, err := user.Current()
	if err == nil {
		home = u.HomeDir
	}
	sshpath := filepath.Join(home, ".ssh")
	if err := os.MkdirAll(sshpath, 0700); err != nil {
		return err
	}
	confpath := filepath.Join(sshpath, "config")
	privpath := filepath.Join(sshpath, "id_rsa")
	ioutil.WriteFile(confpath, []byte("StrictHostKeyChecking no\n"), 0700)
	return ioutil.WriteFile(privpath, []byte(in.Keys.Private), 0600)
}
<|endoftext|>


<commit_before>package main

import (
  "encoding/json"
  "fmt"
  "github.com/gorilla/mux"
  "io"
  "net"
  "net/http"
  "strings"
)

type Response struct {
  Service string     `json:"Service"`
  Srvs    []*net.SRV `json:"Targets"`
}

func TrimSuffix(s, suffix string) string {
  if strings.HasSuffix(s, suffix) {
    s = s[:len(s)-len(suffix)]
  }
  return s
}

func ToJson(service string, srvs []*net.SRV) string {
  response := &Response{
    Service: service,
    Srvs:    srvs,
  }
  jsonResponse, _ := json.Marshal(response)
  return string(jsonResponse)
}

func lookup(w http.ResponseWriter, r *http.Request) {
  var host = "marathon.mesos."
  if strings.HasPrefix(r.Host, "localhost") { // to locally test this i've added 2 srv records to my domain
    host = "addictivesoftware.net."
  }

  service := mux.Vars(r)["service"]

  if _, srvs, err := net.LookupSRV(service, "tcp", host); err != nil {
    w.Header().Set("Content-Type", "text/plain")
    io.WriteString(w, fmt.Sprintf("ERROR:%s", err))
  } else {
    w.Header().Set("Content-Type", "application/json")
    io.WriteString(w, ToJson(service, srvs))
  }
}

func status(w http.ResponseWriter, r *http.Request) {
  io.WriteString(w, "OK")
}

func main() {
  rtr := mux.NewRouter()
  rtr.HandleFunc("/service/{service}", lookup).Methods("GET")
  rtr.HandleFunc("/status", status).Methods("GET")

  http.Handle("/", rtr)
  http.ListenAndServe(":8000", nil)
}
<commit_msg>error now also is returned as json<commit_after>package main

import (
	"encoding/json"
	"github.com/gorilla/mux"
	"io"
	"net"
	"net/http"
	"strings"
)

type Response struct {
	Service string     `json:"Service"`
	Srvs    []*net.SRV `json:"Targets"`
}

type ErrorResponse struct {
	Error string
}

func TrimSuffix(s, suffix string) string {
	if strings.HasSuffix(s, suffix) {
		s = s[:len(s)-len(suffix)]
	}
	return s
}

func ToJson(service string, srvs []*net.SRV) string {
	response := &Response{
		Service: service,
		Srvs:    srvs,
	}
	jsonResponse, _ := json.Marshal(response)
	return string(jsonResponse)
}

func lookup(w http.ResponseWriter, r *http.Request) {
	var host = "marathon.mesos."
	if strings.HasPrefix(r.Host, "localhost") { // to locally test this i've added 2 srv records to my domain
		host = "addictivesoftware.net."
	}

	service := mux.Vars(r)["service"]

	w.Header().Set("Content-Type", "application/json")
	if _, srvs, err := net.LookupSRV(service, "tcp", host); err != nil {
		errorResponse, _ := json.Marshal(&ErrorResponse{
			Error: err.Error(),
		})
		io.WriteString(w, string(errorResponse))
	} else {
		io.WriteString(w, ToJson(service, srvs))
	}
}

func status(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "OK")
}

func main() {
	rtr := mux.NewRouter()
	rtr.HandleFunc("/service/{service}", lookup).Methods("GET")
	rtr.HandleFunc("/status", status).Methods("GET")

	http.Handle("/", rtr)
	http.ListenAndServe(":8000", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
)

var (
	name    = "vub"
	version = "0.3.1"

	flagset    = flag.NewFlagSet(name, flag.ContinueOnError)
	filetype   = flagset.String("filetype", "", "")
	listMode   = flagset.Bool("list", false, "")
	removeMode = flagset.Bool("remove", false, "")
	updateMode = flagset.Bool("update", false, "")
	isHelp     = flagset.Bool("help", false, "")
	isVersion  = flagset.Bool("version", false, "")
)

func init() {
	flagset.SetOutput(ioutil.Discard)
	flagset.StringVar(filetype, "f", "", "")
	flagset.BoolVar(listMode, "l", false, "")
	flagset.BoolVar(removeMode, "r", false, "")
	flagset.BoolVar(updateMode, "u", false, "")
	flagset.BoolVar(isHelp, "h", false, "")
}

func countTrue(bls ...bool) int {
	cnt := 0
	for _, b := range bls {
		if b {
			cnt++
		}
	}
	return cnt
}

func printShortUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %[1]s [OPTION]... URI...
Try '%[1]s --help' for more information.
`[1:], name)
}

func printUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %s [OPTION]... URI...
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -l, --list                change the behavior to list packages
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to update
      --help                show this help message and exit
      --version             output version information and exit
`[1:], name)
}

func printVersion() {
	fmt.Fprintln(os.Stderr, version)
}

func printErr(err interface{}) {
	fmt.Fprintf(os.Stderr, "%s: %s\n", name, err)
}

func main() {
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		os.Exit(2)
	}
	switch {
	case *isHelp:
		printUsage()
		os.Exit(0)
	case *isVersion:
		printVersion()
		os.Exit(0)
	case !*listMode && flagset.NArg() < 1:
		printShortUsage()
		os.Exit(2)
	case countTrue(*listMode, *removeMode, *updateMode) > 1:
		printErr("cannot specify multiple mode")
		os.Exit(2)
	}

	switch {
	case *listMode:
		ListPackages(*filetype)
	default:
		var err error
		for _, uri := range flagset.Args() {
			p := NewPackage(uri, *filetype)
			switch {
			case *removeMode:
				err = p.Remove()
			case *updateMode:
				err = p.Update()
			default:
				err = p.Install()
			}
			if err != nil {
				printErr(err)
				os.Exit(1)
			}
		}
	}
}
<commit_msg>Use "if" instead of "switch" basically<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
)

var (
	name    = "vub"
	version = "0.3.1"

	flagset    = flag.NewFlagSet(name, flag.ContinueOnError)
	filetype   = flagset.String("filetype", "", "")
	listMode   = flagset.Bool("list", false, "")
	removeMode = flagset.Bool("remove", false, "")
	updateMode = flagset.Bool("update", false, "")
	isHelp     = flagset.Bool("help", false, "")
	isVersion  = flagset.Bool("version", false, "")
)

func init() {
	flagset.SetOutput(ioutil.Discard)
	flagset.StringVar(filetype, "f", "", "")
	flagset.BoolVar(listMode, "l", false, "")
	flagset.BoolVar(removeMode, "r", false, "")
	flagset.BoolVar(updateMode, "u", false, "")
	flagset.BoolVar(isHelp, "h", false, "")
}

func countTrue(bls ...bool) int {
	cnt := 0
	for _, b := range bls {
		if b {
			cnt++
		}
	}
	return cnt
}

func printShortUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %[1]s [OPTION]... URI...
Try '%[1]s --help' for more information.
`[1:], name)
}

func printUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %s [OPTION]... URI...
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -l, --list                change the behavior to list packages
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to update
      --help                show this help message and exit
      --version             output version information and exit
`[1:], name)
}

func printVersion() {
	fmt.Fprintln(os.Stderr, version)
}

func printErr(err interface{}) {
	fmt.Fprintf(os.Stderr, "%s: %s\n", name, err)
}

func main() {
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		os.Exit(2)
	}
	if *isHelp {
		printUsage()
		os.Exit(0)
	}
	if *isVersion {
		printVersion()
		os.Exit(0)
	}

	if !*listMode && flagset.NArg() < 1 {
		printShortUsage()
		os.Exit(2)
	}
	if countTrue(*listMode, *removeMode, *updateMode) > 1 {
		printErr("cannot specify multiple mode")
		os.Exit(2)
	}

	if *listMode {
		ListPackages(*filetype)
		os.Exit(0)
	} else {
		var err error
		for _, uri := range flagset.Args() {
			p := NewPackage(uri, *filetype)
			switch {
			case *removeMode:
				err = p.Remove()
			case *updateMode:
				err = p.Update()
			default:
				err = p.Install()
			}
			if err != nil {
				printErr(err)
				os.Exit(1)
			}
		}
		os.Exit(0)
	}
}
<|endoftext|>


<commit_before>// A command line tool that shows the status of (many) Go packages.
package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/gostatus/status"

	"github.com/shurcooL/go/gists/gist7480523"
	"github.com/shurcooL/go/gists/gist7651991"
)

const numWorkers = 8

var vFlag = flag.Bool("v", false, "Verbose output: show all Go packages, not just ones with notable status.")
var stdinFlag = flag.Bool("stdin", false, "Read the list of newline separated Go packages from stdin.")
var plumbingFlag = flag.Bool("plumbing", false, "Give the output in an easy-to-parse format for scripts.")
var debugFlag = flag.Bool("debug", false, "Give the output with verbose debug information.")

func init() {
	flag.BoolVar(&status.FFlag, "f", false, "Force not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.")
}

func usage() {
	fmt.Fprint(os.Stderr, "Usage: gostatus [flags] [packages]\n")
	fmt.Fprint(os.Stderr, "       [newline separated packages] | gostatus --stdin [flags]\n")
	flag.PrintDefaults()
	fmt.Fprint(os.Stderr, `
Examples:
  # Show status of package in current directory, if notable.
  gostatus .

  # Show status of all packages with notable status.
  gostatus all

  # Show status of all dependencies (recursive) of package in cur working dir.
  go list -f '{{join .Deps "\n"}}' . | gostatus --stdin -v

Legend:
  ???? - Not under (recognized) version control
  b - Non-master branch checked out
  * - Uncommited changes in working dir
  + - Update available
  - - Local revision is ahead of remote (need to push?)
  ! - No remote
  # - Remote path doesn't match import path
  $ - Stash exists
`)
	os.Exit(2)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Usage = usage
	flag.Parse()

	// Get current directory.
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	shouldShow := func(goPackage *gist7480523.GoPackage) bool {
		// Check for notable status.
		return status.PorcelainPresenter(goPackage)[:4] != "    "
	}
	if *vFlag == true {
		shouldShow = func(_ *gist7480523.GoPackage) bool { return true }
	}

	var presenter gist7480523.GoPackageStringer = status.PorcelainPresenter
	if *debugFlag == true {
		presenter = status.DebugPresenter
	} else if *plumbingFlag == true {
		presenter = status.PlumbingPresenter
	}

	// A map of repos that have been checked, to avoid doing same repo more than once.
	var lock sync.Mutex
	checkedRepos := map[string]bool{}

	// Input: Go package Import Path
	// Output: If a valid Go package and not inside GOROOT, output a status string, else nil.
	reduceFunc := func(in string) interface{} {
		goPackage, err := gist7480523.GoPackageFromPath(in, wd)
		if err != nil {
			fmt.Fprintf(os.Stderr, "can't load package: %s\n", err)
			return nil
		}
		if goPackage == nil {
			return nil
		}
		if goPackage.Bpkg.Goroot {
			return nil
		}

		goPackage.UpdateVcs()
		// Check that the same repo hasn't already been done.
		if goPackage.Dir.Repo != nil {
			rootPath := goPackage.Dir.Repo.Vcs.RootPath()
			lock.Lock()
			if !checkedRepos[rootPath] {
				checkedRepos[rootPath] = true
				lock.Unlock()
			} else {
				lock.Unlock()
				// Skip repos that were done.
				return nil
			}
		}

		goPackage.UpdateVcsFields()

		if shouldShow(goPackage) == false {
			return nil
		}
		return presenter(goPackage)
	}

	// Run reduceFunc on all import paths in parallel.
	var outChan <-chan interface{}
	switch *stdinFlag {
	case false:
		importPathPatterns := flag.Args()
		importPaths := gotool.ImportPaths(importPathPatterns)
		outChan = gist7651991.GoReduceLinesFromSlice(importPaths, numWorkers, reduceFunc)
	case true:
		outChan = gist7651991.GoReduceLinesFromReader(os.Stdin, numWorkers, reduceFunc)
	}

	// Output results.
	for out := range outChan {
		fmt.Println(out.(string))
	}
}
<commit_msg>Refactor invalid flag handling to be more idiomatic.<commit_after>// A command line tool that shows the status of (many) Go packages.
package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/gostatus/status"

	"github.com/shurcooL/go/gists/gist7480523"
	"github.com/shurcooL/go/gists/gist7651991"
)

const numWorkers = 8

var vFlag = flag.Bool("v", false, "Verbose output: show all Go packages, not just ones with notable status.")
var stdinFlag = flag.Bool("stdin", false, "Read the list of newline separated Go packages from stdin.")
var plumbingFlag = flag.Bool("plumbing", false, "Give the output in an easy-to-parse format for scripts.")
var debugFlag = flag.Bool("debug", false, "Give the output with verbose debug information.")

func init() {
	flag.BoolVar(&status.FFlag, "f", false, "Force not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.")
}

func usage() {
	fmt.Fprint(os.Stderr, "Usage: gostatus [flags] [packages]\n")
	fmt.Fprint(os.Stderr, "       [newline separated packages] | gostatus --stdin [flags]\n")
	flag.PrintDefaults()
	fmt.Fprint(os.Stderr, `
Examples:
  # Show status of package in current directory, if notable.
  gostatus .

  # Show status of all packages with notable status.
  gostatus all

  # Show status of all dependencies (recursive) of package in cur working dir.
  go list -f '{{join .Deps "\n"}}' . | gostatus --stdin -v

Legend:
  ???? - Not under (recognized) version control
  b - Non-master branch checked out
  * - Uncommited changes in working dir
  + - Update available
  - - Local revision is ahead of remote (need to push?)
  ! - No remote
  # - Remote path doesn't match import path
  $ - Stash exists
`)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Usage = usage
	flag.Parse()

	// Get current directory.
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	shouldShow := func(goPackage *gist7480523.GoPackage) bool {
		// Check for notable status.
		return status.PorcelainPresenter(goPackage)[:4] != "    "
	}
	if *vFlag == true {
		shouldShow = func(_ *gist7480523.GoPackage) bool { return true }
	}

	var presenter gist7480523.GoPackageStringer = status.PorcelainPresenter
	if *debugFlag == true {
		presenter = status.DebugPresenter
	} else if *plumbingFlag == true {
		presenter = status.PlumbingPresenter
	}

	// A map of repos that have been checked, to avoid doing same repo more than once.
	var lock sync.Mutex
	checkedRepos := map[string]bool{}

	// Input: Go package Import Path
	// Output: If a valid Go package and not inside GOROOT, output a status string, else nil.
	reduceFunc := func(in string) interface{} {
		goPackage, err := gist7480523.GoPackageFromPath(in, wd)
		if err != nil {
			fmt.Fprintf(os.Stderr, "can't load package: %s\n", err)
			return nil
		}
		if goPackage == nil {
			return nil
		}
		if goPackage.Bpkg.Goroot {
			return nil
		}

		goPackage.UpdateVcs()
		// Check that the same repo hasn't already been done.
		if goPackage.Dir.Repo != nil {
			rootPath := goPackage.Dir.Repo.Vcs.RootPath()
			lock.Lock()
			if !checkedRepos[rootPath] {
				checkedRepos[rootPath] = true
				lock.Unlock()
			} else {
				lock.Unlock()
				// Skip repos that were done.
				return nil
			}
		}

		goPackage.UpdateVcsFields()

		if shouldShow(goPackage) == false {
			return nil
		}
		return presenter(goPackage)
	}

	// Run reduceFunc on all import paths in parallel.
	var outChan <-chan interface{}
	switch *stdinFlag {
	case false:
		importPathPatterns := flag.Args()
		importPaths := gotool.ImportPaths(importPathPatterns)
		outChan = gist7651991.GoReduceLinesFromSlice(importPaths, numWorkers, reduceFunc)
	case true:
		outChan = gist7651991.GoReduceLinesFromReader(os.Stdin, numWorkers, reduceFunc)
	}

	// Output results.
	for out := range outChan {
		fmt.Println(out.(string))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net/http"
	"regexp"
	"strconv"
	"sync"
	"text/template"

	"github.com/gorilla/websocket"
)

var (
	debug    = flag.Bool("debug", false, "Debug allow serve index page")
	ssl      = flag.Bool("ssl", true, "SSL usage")
	addr     = flag.String("addr", ":5000", "ws service address")
	rabbit   = flag.String("rabbit", "amqp://guest:guest@localhost:5672/", "AMQP URI")
	exchange = flag.String("exchange", "notifications", "Durable, non-auto-deleted AMQP exchange name")
	queue    = flag.String("queue", "notifications", "Queue name")
	routing  = flag.String("routing key", "user.*", "Routing key for queue")
	certFile = flag.String("cert", "", "Cert for TLS")
	keyFile  = flag.String("keyfile", "", "Key for TLS")
	re       = regexp.MustCompile("user.(\\d+)")

	homeTempl = template.Must(template.ParseFiles("index.html"))
	upgrader  = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			log.Printf("Request url %v", r.URL)
			return true
		},
	}
)

type UserConnection struct {
	UserId int
	ws     *websocket.Conn
}

func (user_connection *UserConnection) Listen() {
	defer func() {
		user_connection.ws.Close()
		if user_connection.UserId != 0 {
			registry.Unregister(user_connection)
			log.Printf("User %d leave ", user_connection.UserId)
		}
	}()

	for {
		_, message, err := user_connection.ws.ReadMessage()
		if err != nil {
			break
		}
		user_connection.UserId, err = strconv.Atoi(string(message))
		if err != nil {
			continue
		}
		registry.Register(user_connection)
		log.Printf("User %d registred ", user_connection.UserId)
	}
}

type Regestry struct {
	sync.RWMutex
	connections map[int][]*UserConnection
}

func (registry Regestry) ListenRabbit() {
	for message := range GetMessagesChannel() {
		message.Ack(false)
		matches := re.FindStringSubmatch(message.RoutingKey)
		if len(matches) == 0 {
			continue
		}
		user_id, _ := strconv.Atoi(matches[len(matches)-1])
		log.Printf("Message for user  %d: '%s'", user_id, string(message.Body))
		ws_connection, ok := registry.GetConnection(user_id)
		if ok == false {
			log.Printf("But user %d not connected", user_id)
			continue
		}
		ws_connection.ws.WriteMessage(websocket.TextMessage, message.Body)
	}
}

func (registry Regestry) GetConnection(user_id int) (*UserConnection, bool) {
	registry.Lock()
	defer registry.Unlock()
	ws_connections, ok := registry.connections[user_id]
	if ok == false || len(ws_connections) == 0 {
		return nil, false
	}
	return ws_connections[0], true
}

func (registry Regestry) Register(uc *UserConnection) {
	registry.Lock()
	defer registry.Unlock()
	if _, ok := registry.connections[uc.UserId]; ok == false {
		registry.connections[uc.UserId] = make([]*UserConnection, 0)
	}
	registry.connections[uc.UserId] = append(registry.connections[uc.UserId], uc)
}

func (registry Regestry) Unregister(uc *UserConnection) {
	registry.Lock()
	var index int = 0
	for i := 0; i < len(registry.connections[uc.UserId]); i++ {
		if registry.connections[uc.UserId][i] == uc {
			index = i
			break
		}
	}
	registry.connections[uc.UserId] = append(registry.connections[uc.UserId][:index], registry.connections[uc.UserId][index+1:]...)
	registry.Unlock()
}

var registry = Regestry{connections: make(map[int][]*UserConnection)}

func serveWs(w http.ResponseWriter, r *http.Request) {
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	user_connection := &UserConnection{ws: ws}
	go user_connection.Listen()
}

func serveMain(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	homeTempl.Execute(w, r.Host)
}

func main() {
	flag.Parse()
	go registry.ListenRabbit()
	if *debug {
		http.HandleFunc("/", serveMain)
	}
	http.HandleFunc("/ws", serveWs)
	if *ssl {
		http.ListenAndServeTLS(*addr, *certFile, *keyFile, nil)
	} else {
		http.ListenAndServe(*addr, nil)
	}
}
<commit_msg>logging<commit_after>package main

import (
	"flag"
	"log"
	"net/http"
	"regexp"
	"strconv"
	"sync"
	"text/template"

	"github.com/gorilla/websocket"
)

var (
	debug    = flag.Bool("debug", false, "Debug allow serve index page")
	ssl      = flag.Bool("ssl", true, "SSL usage")
	addr     = flag.String("addr", ":5000", "ws service address")
	rabbit   = flag.String("rabbit", "amqp://guest:guest@localhost:5672/", "AMQP URI")
	exchange = flag.String("exchange", "notifications", "Durable, non-auto-deleted AMQP exchange name")
	queue    = flag.String("queue", "notifications", "Queue name")
	routing  = flag.String("routing key", "user.*", "Routing key for queue")
	certFile = flag.String("cert", "", "Cert for TLS")
	keyFile  = flag.String("keyfile", "", "Key for TLS")
	re       = regexp.MustCompile("user.(\\d+)")

	homeTempl = template.Must(template.ParseFiles("index.html"))
	upgrader  = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

type UserConnection struct {
	UserId int
	ws     *websocket.Conn
}

func (user_connection *UserConnection) Listen() {
	defer func() {
		user_connection.ws.Close()
		if user_connection.UserId != 0 {
			registry.Unregister(user_connection)
			log.Printf("User %d leave ", user_connection.UserId)
		}
	}()

	for {
		_, message, err := user_connection.ws.ReadMessage()
		if err != nil {
			break
		}
		user_connection.UserId, err = strconv.Atoi(string(message))
		if err != nil {
			continue
		}
		registry.Register(user_connection)
		log.Printf("User %d registred ", user_connection.UserId)
	}
}

type Regestry struct {
	sync.RWMutex
	connections map[int][]*UserConnection
}

func (registry Regestry) ListenRabbit() {
	for message := range GetMessagesChannel() {
		message.Ack(false)
		matches := re.FindStringSubmatch(message.RoutingKey)
		if len(matches) == 0 {
			continue
		}
		user_id, _ := strconv.Atoi(matches[len(matches)-1])
		ws_connection, ok := registry.GetConnection(user_id)
		log.Printf("Message for user(online - %v) %d: '%s'", ok, user_id, string(message.Body))
		if ok == false {
			continue
		}
		ws_connection.ws.WriteMessage(websocket.TextMessage, message.Body)
	}
}

func (registry Regestry) GetConnection(user_id int) (*UserConnection, bool) {
	registry.Lock()
	defer registry.Unlock()
	ws_connections, ok := registry.connections[user_id]
	if ok == false || len(ws_connections) == 0 {
		return nil, false
	}
	return ws_connections[0], true
}

func (registry Regestry) Register(uc *UserConnection) {
	registry.Lock()
	defer registry.Unlock()
	if _, ok := registry.connections[uc.UserId]; ok == false {
		registry.connections[uc.UserId] = make([]*UserConnection, 0)
	}
	registry.connections[uc.UserId] = append(registry.connections[uc.UserId], uc)
}

func (registry Regestry) Unregister(uc *UserConnection) {
	registry.Lock()
	var index int = 0
	for i := 0; i < len(registry.connections[uc.UserId]); i++ {
		if registry.connections[uc.UserId][i] == uc {
			index = i
			break
		}
	}
	registry.connections[uc.UserId] = append(registry.connections[uc.UserId][:index], registry.connections[uc.UserId][index+1:]...)
	registry.Unlock()
}

var registry = Regestry{connections: make(map[int][]*UserConnection)}

func serveWs(w http.ResponseWriter, r *http.Request) {
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	user_connection := &UserConnection{ws: ws}
	go user_connection.Listen()
}

func serveMain(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	homeTempl.Execute(w, r.Host)
}

func main() {
	flag.Parse()
	go registry.ListenRabbit()
	if *debug {
		http.HandleFunc("/", serveMain)
	}
	http.HandleFunc("/ws", serveWs)
	if *ssl {
		http.ListenAndServeTLS(*addr, *certFile, *keyFile, nil)
	} else {
		http.ListenAndServe(*addr, nil)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"github.com/ogier/pflag"
)

var (
	cmdName    = "alita"
	cmdVersion = "0.7.1"
)

type CLI struct {
	stdin  io.Reader
	stdout io.Writer
	stderr io.Writer

	delimiter string
	useRegexp bool
	count     int
	margin    string
	justify   string
	isHelp    bool
	isVersion bool
}

func NewCLI(stdin io.Reader, stdout io.Writer, stderr io.Writer) *CLI {
	return &CLI{
		stdin:  stdin,
		stdout: stdout,
		stderr: stderr,
	}
}

func (c *CLI) printUsage() {
	fmt.Fprintf(c.stderr, `
Usage: %s [OPTION]... [FILE]...
Align FILE(s), or standard input.

Delimiter control:
  -d, --delimiter=DELIM      separate lines by DELIM
  -r, --regexp               DELIM is a regular expression
  -c, --count=COUNT          separate lines only COUNT times

Output control:
  -m, --margin=N[:M]         put N or N and M spaces at both ends of DELIM
  -j, --justify=[l|c|r]...   justify cells to the left, center, or right

Miscellaneous:
  -h, --help                 display this help and exit
      --version              display version information and exit
`[1:], cmdName)
}

func (c *CLI) printVersion() {
	fmt.Fprintf(c.stderr, "%s\n", cmdVersion)
}

func (c *CLI) printErr(err interface{}) {
	fmt.Fprintf(c.stderr, "%s: %s\n", cmdName, err)
}

func (c *CLI) guideToHelp() {
	fmt.Fprintf(c.stderr, "Try '%s --help' for more information.\n", cmdName)
}

func (c *CLI) parseOption(args []string) (argFiles []string, err error) {
	f := pflag.NewFlagSet(cmdName, pflag.ContinueOnError)
	f.SetOutput(ioutil.Discard)

	f.StringVarP(&c.delimiter, "delimiter", "d", "", "")
	f.BoolVarP(&c.useRegexp, "regexp", "r", false, "")
	f.IntVarP(&c.count, "count", "c", -1, "")
	f.StringVarP(&c.margin, "margin", "m", "", "")
	f.StringVarP(&c.justify, "justify", "j", "", "")
	f.BoolVarP(&c.isHelp, "help", "h", false, "")
	f.BoolVarP(&c.isVersion, "version", "", false, "")

	if err := f.Parse(args); err != nil {
		return nil, err
	}
	return f.Args(), nil
}

func (c *CLI) newAligner() (a *Aligner, err error) {
	return NewAligner(&Option{
		Delimiter: c.delimiter,
		UseRegexp: c.useRegexp,
		Count:     c.count,
		Margin:    c.margin,
		Justify:   c.justify,
	})
}

func (c *CLI) newArgf(argFiles []string) (r io.Reader, err error) {
	switch len(argFiles) {
	case 0:
		return c.stdin, nil
	default:
		rs := make([]io.Reader, len(argFiles))
		for i, argFile := range argFiles {
			f, err := os.Open(argFile)
			if err != nil {
				return nil, err
			}
			rs[i] = f
		}
		return io.MultiReader(rs...), nil
	}
}

func (c *CLI) do(a *Aligner, r io.Reader) error {
	if err := a.ReadAll(r); err != nil {
		return err
	}
	if err := a.Flush(c.stdout); err != nil {
		return err
	}
	return nil
}

func (c *CLI) Run(args []string) int {
	f, err := c.parseOption(args)
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}
	if c.isHelp {
		c.printUsage()
		return 0
	}
	if c.isVersion {
		c.printVersion()
		return 0
	}

	a, err := c.newAligner()
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}
	r, err := c.newArgf(f)
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}

	if err = c.do(a, r); err != nil {
		c.printErr(err)
		return 1
	}
	return 0
}

func main() {
	c := NewCLI(os.Stdin, os.Stdout, os.Stderr)
	e := c.Run(os.Args[1:])
	os.Exit(e)
}
<commit_msg>Upgrade to support mixed flag<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"github.com/ogier/pflag"
)

var (
	cmdName    = "alita"
	cmdVersion = "0.8.0"
)

type CLI struct {
	stdin  io.Reader
	stdout io.Writer
	stderr io.Writer

	delimiter string
	useRegexp bool
	count     int
	margin    string
	justify   string
	isHelp    bool
	isVersion bool
}

func NewCLI(stdin io.Reader, stdout io.Writer, stderr io.Writer) *CLI {
	return &CLI{
		stdin:  stdin,
		stdout: stdout,
		stderr: stderr,
	}
}

func (c *CLI) printUsage() {
	fmt.Fprintf(c.stderr, `
Usage: %s [OPTION]... [FILE]...
Align FILE(s), or standard input.

Delimiter control:
  -d, --delimiter=DELIM      separate lines by DELIM
  -r, --regexp               DELIM is a regular expression
  -c, --count=COUNT          separate lines only COUNT times

Output control:
  -m, --margin=N[:M]         put N or N and M spaces at both ends of DELIM
  -j, --justify=[l|c|r]...   justify cells to the left, center, or right

Miscellaneous:
  -h, --help                 display this help and exit
      --version              display version information and exit
`[1:], cmdName)
}

func (c *CLI) printVersion() {
	fmt.Fprintf(c.stderr, "%s\n", cmdVersion)
}

func (c *CLI) printErr(err interface{}) {
	fmt.Fprintf(c.stderr, "%s: %s\n", cmdName, err)
}

func (c *CLI) guideToHelp() {
	fmt.Fprintf(c.stderr, "Try '%s --help' for more information.\n", cmdName)
}

func (c *CLI) parseOption(args []string) (argFiles []string, err error) {
	f := pflag.NewFlagSet(cmdName, pflag.ContinueOnError)
	f.SetOutput(ioutil.Discard)

	f.StringVarP(&c.delimiter, "delimiter", "d", "", "")
	f.BoolVarP(&c.useRegexp, "regexp", "r", false, "")
	f.IntVarP(&c.count, "count", "c", -1, "")
	f.StringVarP(&c.margin, "margin", "m", "", "")
	f.StringVarP(&c.justify, "justify", "j", "", "")
	f.BoolVarP(&c.isHelp, "help", "h", false, "")
	f.BoolVarP(&c.isVersion, "version", "", false, "")

	if err := f.Parse(args); err != nil {
		return nil, err
	}
	return f.Args(), nil
}

func (c *CLI) newAligner() (a *Aligner, err error) {
	return NewAligner(&Option{
		Delimiter: c.delimiter,
		UseRegexp: c.useRegexp,
		Count:     c.count,
		Margin:    c.margin,
		Justify:   c.justify,
	})
}

func (c *CLI) newArgf(argFiles []string) (r io.Reader, err error) {
	switch len(argFiles) {
	case 0:
		return c.stdin, nil
	default:
		rs := make([]io.Reader, len(argFiles))
		for i, argFile := range argFiles {
			f, err := os.Open(argFile)
			if err != nil {
				return nil, err
			}
			rs[i] = f
		}
		return io.MultiReader(rs...), nil
	}
}

func (c *CLI) do(a *Aligner, r io.Reader) error {
	if err := a.ReadAll(r); err != nil {
		return err
	}
	if err := a.Flush(c.stdout); err != nil {
		return err
	}
	return nil
}

func (c *CLI) Run(args []string) int {
	f, err := c.parseOption(args)
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}
	if c.isHelp {
		c.printUsage()
		return 0
	}
	if c.isVersion {
		c.printVersion()
		return 0
	}

	a, err := c.newAligner()
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}
	r, err := c.newArgf(f)
	if err != nil {
		c.printErr(err)
		c.guideToHelp()
		return 2
	}

	if err = c.do(a, r); err != nil {
		c.printErr(err)
		return 1
	}
	return 0
}

func main() {
	c := NewCLI(os.Stdin, os.Stdout, os.Stderr)
	e := c.Run(os.Args[1:])
	os.Exit(e)
}
<|endoftext|>


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

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}
<commit_msg>Return user data<commit_after>// main.go
//
// Copyright 2015, Evan Prodromou <evan@e14n.com>
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
    "fmt"
    "net/http"
    "encoding/json"
)

var users map[string]map[string]string

func userHandler(w http.ResponseWriter, r *http.Request) {
  nick := r.URL.Path[6:]
  fmt.Printf("Request for user %s\n", nick)
  user := users[nick]
  if user == nil {
    http.Error(w, "No such user", 404)
  } else {
    b, err := json.Marshal(user)
    marshalled := string(b)
    fmt.Printf("User: '%s'", marshalled)
    if err != nil {
      http.Error(w, "Error encoding data", 500)
    } else {
      w.Header().Set("Content-Type", "application/activitystreams+json")
      fmt.Fprintf(w, marshalled)
    }
  }
}

func main() {
  http.HandleFunc("/user/", userHandler)
  users = make(map[string]map[string]string)
  users["evan"] = map[string]string {
    "preferredUsername": "evan",
    "displayName": "Evan Prodromou",
    "summary": "A person",
    "icon": "https://e14n.com/uploads/evan/2014/9/24/knyf1g_thumb.jpg",
  }
  http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

const version = "0.0.3"

// Metric holds the details of a metric
type Metric struct {
	Name      string            `json:"name"`
	Timestamp int               `json:"timestamp"`
	Value     float64           `json:"value"`
	Tags      map[string]string `json:"tags"`
}

// Send writes the metric m into conn in the format expected by kairosdb's tcp api
func Send(w io.Writer, m Metric) {
	fmt.Fprintf(w, "put %s %d %f", m.Name, m.Timestamp, m.Value)

	for name, value := range m.Tags {
		//empty tags will generate an error on ingest
		if value != "" && name != "" {
			fmt.Fprintf(w, " %s=%s", name, value)
		}
	}

	fmt.Fprint(w, "\n")
}

func main() {
	host := flag.String("host", "localhost:4242", "The host:port to connect to. Defaults to 'localhost:4242'")
	ver := flag.Bool("version", false, "Print the version number and exit")
	flag.Parse()

	if *ver {
		fmt.Printf("%v version: %s\n", os.Args[0], version)
		os.Exit(0)
	}

	inputFilename := flag.Arg(0)

	var input io.Reader

	if len(inputFilename) > 0 {
		var err error

		input, err = os.Open(inputFilename)

		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

	} else {
		input = os.Stdin
	}

	scanner := bufio.NewScanner(input)
	conn, err := net.Dial("tcp", *host)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer conn.Close()

	for scanner.Scan() {
		var m Metric

		if err := json.Unmarshal(scanner.Bytes(), &m); err != nil {
			fmt.Fprintf(os.Stderr, "unable to decode line: %s: '%s'\n", err.Error(), scanner.Text())
			continue
		}

		Send(conn, m)
	}

	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "error reading input:", err)
		os.Exit(1)
	}
}
<commit_msg>Pulls out picking the input reader into a function<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

const version = "0.0.3"

// Metric holds the details of a metric
type Metric struct {
	Name      string            `json:"name"`
	Timestamp int               `json:"timestamp"`
	Value     float64           `json:"value"`
	Tags      map[string]string `json:"tags"`
}

// Send writes the metric m into conn in the format expected by kairosdb's tcp api
func Send(w io.Writer, m Metric) {
	fmt.Fprintf(w, "put %s %d %f", m.Name, m.Timestamp, m.Value)

	for name, value := range m.Tags {
		//empty tags will generate an error on ingest
		if value != "" && name != "" {
			fmt.Fprintf(w, " %s=%s", name, value)
		}
	}

	fmt.Fprint(w, "\n")
}

// getInputReader opens a filename located at the argnum'th argument or so.Stdin if
// the argument does not exist
func getInputReader(argnum int) (io.ReadCloser, error) {
	if flag.NArg() > argnum {
		return os.Open(flag.Arg(argnum))
	}
	return os.Stdin, nil
}

func main() {
	host := flag.String("host", "localhost:4242", "The host:port to connect to. Defaults to 'localhost:4242'")
	ver := flag.Bool("version", false, "Print the version number and exit")
	flag.Parse()

	if *ver {
		fmt.Printf("%v version: %s\n", os.Args[0], version)
		os.Exit(0)
	}

	input, err := getInputReader(0)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer input.Close()

	scanner := bufio.NewScanner(input)
	conn, err := net.Dial("tcp", *host)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer conn.Close()

	for scanner.Scan() {
		var m Metric

		if err := json.Unmarshal(scanner.Bytes(), &m); err != nil {
			fmt.Fprintf(os.Stderr, "unable to decode line: %s: '%s'\n", err.Error(), scanner.Text())
			continue
		}

		Send(conn, m)
	}

	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "error reading input:", err)
		os.Exit(1)
	}
}
<|endoftext|>