<commit_before>package gcsproxy

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
	"url"

	"golang.org/x/net/context"

	pubsub "google.golang.org/api/pubsub/v1"
)

type (
	JobConfig struct {
		Template []string
		Commands map[string][]string
		Dryrun bool
	}

	Job struct {
		config *JobConfig
		message *pubsub.ReceivedMessage
		notification *ProgressNotification
		storage Storage
	}
)

func (job *Job) execute(ctx context.Context) error {
	return job.setupWorkspace(ctx, func(workspace, downloads_dir, uploads_dir string) error {
		_, err := job.downloadFiles(downloads_dir)
		if err != nil {
			return err
		}

		cmd, err := job.build(ctx)
		if err != nil {
			log.Printf("Command build Error template: %v msg: %v cause of %v\n", job.config.Template, job.message, err)
			return err
		}
		err = cmd.Run()
		if err != nil {
			log.Printf("Command Error: cmd: %v cause of %v\n", cmd, err)
			// return err // Don't return this err
		}

		err = job.uploadFiles(uploads_dir)
		if err != nil {
			return err
		}

		return nil
	})
}

func (job *Job) setupWorkspace(ctx  context.Context, f func(workspace, downloads_dir, uploads_dir string) error) error {
	dir, err := ioutil.TempDir("", "workspace")
	if err != nil {
		log.Fatal(err)
		return err
	}
	defer os.RemoveAll(dir) // clean up

	subdirs := []string{
		filepath.Join(dir, "downloads"),
		filepath.Join(dir, "uploads"),
	}
	for _, subdir := range subdirs {
		err := os.MkdirAll(subdir, 0700)
		if err != nil {
			return err
		}
	}
	return f(dir, subdirs[0], subdirs[1])
}

func (job *Job) build(ctx context.Context) (*exec.Cmd, error) {
	values, err := job.extract(ctx, job.config.Template)
	if err != nil {
		return nil, err
	}
	if len(job.config.Commands) > 0 {
		key := strings.Join(values, " ")
		t := job.config.Commands[key]
		if t == nil { t = job.config.Commands["default"] }
		if t != nil {
			values, err = job.extract(ctx, t)
			if err != nil {
				return nil, err
			}
		}
	}
	cmd := exec.Command(values[0], values[1:]...)
	return cmd, nil
}

func (job *Job) extract(ctx context.Context, values []string) ([]string, error) {
	result := []string{}
	for _, src := range values {
		extracted := src
		result = append(result, extracted)
	}
	return result, nil
}

func (job *Job) downloadFiles(dir string) (map[string]string, error) {
	result := map[string]string{}
	objects := job.flatten(job.parseJson(job.message.Message.Attributes["download_files"]))
	remote_urls := []string{}
	for _, obj := range objects {
		switch obj.(type) {
		case string:
			remote_urls = append(remote_urls, obj.(string))
		default:
			log.Printf("Invalid download file URL: %v [%T]", obj, obj)
		}
	}
	for _, remote_url := range remote_urls {
		url, err := url.Parse(remote_url)
		if err != nil {
			log.Fatalf("Invalid URL: %v because of %v\n", remote_url, err)
			return nil, err
		}
		urlstr := fmt.Sprintf("gs://%v/%v", url.Host, url.Path)
		destPath := filepath.Join(dir, url.Host, url.Path)
		err = job.storage.Download(url.Host, url.Path, destPath)
		if err != nil {
			return nil, err
		}
		result[urlstr] = destPath
	}
	return result, nil
}

func (job *Job) uploadFiles(dir string) error {
	return nil
}

func (job *Job) parseJson(str string) interface{} {
	matched, err := regexp.MatchString(`\A\[.*\]\z|\A\{.*\}\z|`, str)
	if err != nil {
		return str
	}
	if !matched {
		return str
	}
	var dest interface{}
	err = json.Unmarshal([]byte(str), &dest)
	if err != nil {
		return str
	}
	return dest
}

func (job *Job) flatten(obj interface{}) []interface{} {
	// Support only unmarshalled object from JSON
	// See https://golang.org/pkg/encoding/json/#Unmarshal also
	switch obj.(type) {
	case []interface{}:
		res := []interface{}{}
		for _, i := range obj.([]interface{}) {
			switch i.(type) {
			case bool, float64, string, nil:
				res = append(res, i)
			default:
				for _, j := range job.flatten(i) {
					res = append(res, j)
				}
			}
		}
		return res
	case map[string]interface{}:
		values := []interface{}{}
		for _, val := range obj.(map[string]interface{}) {
			values = append(values, val)
		}
		return job.flatten(values)
	default:
		return []interface{}{obj}
	}
}
<commit_msg>:+1: Implement upload function<commit_after>package gcsproxy

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
	"net/url"

	"golang.org/x/net/context"

	pubsub "google.golang.org/api/pubsub/v1"
)

type (
	JobConfig struct {
		Template []string
		Commands map[string][]string
		Dryrun bool
	}

	Job struct {
		config *JobConfig
		message *pubsub.ReceivedMessage
		notification *ProgressNotification
		storage Storage
	}
)

func (job *Job) execute(ctx context.Context) error {
	return job.setupWorkspace(ctx, func(workspace, downloads_dir, uploads_dir string) error {
		_, err := job.downloadFiles(downloads_dir)
		if err != nil {
			return err
		}

		cmd, err := job.build(ctx)
		if err != nil {
			log.Printf("Command build Error template: %v msg: %v cause of %v\n", job.config.Template, job.message, err)
			return err
		}
		err = cmd.Run()
		if err != nil {
			log.Printf("Command Error: cmd: %v cause of %v\n", cmd, err)
			// return err // Don't return this err
		}

		err = job.uploadFiles(uploads_dir)
		if err != nil {
			return err
		}

		return nil
	})
}

func (job *Job) setupWorkspace(ctx  context.Context, f func(workspace, downloads_dir, uploads_dir string) error) error {
	dir, err := ioutil.TempDir("", "workspace")
	if err != nil {
		log.Fatal(err)
		return err
	}
	defer os.RemoveAll(dir) // clean up

	subdirs := []string{
		filepath.Join(dir, "downloads"),
		filepath.Join(dir, "uploads"),
	}
	for _, subdir := range subdirs {
		err := os.MkdirAll(subdir, 0700)
		if err != nil {
			return err
		}
	}
	return f(dir, subdirs[0], subdirs[1])
}

func (job *Job) build(ctx context.Context) (*exec.Cmd, error) {
	values, err := job.extract(ctx, job.config.Template)
	if err != nil {
		return nil, err
	}
	if len(job.config.Commands) > 0 {
		key := strings.Join(values, " ")
		t := job.config.Commands[key]
		if t == nil { t = job.config.Commands["default"] }
		if t != nil {
			values, err = job.extract(ctx, t)
			if err != nil {
				return nil, err
			}
		}
	}
	cmd := exec.Command(values[0], values[1:]...)
	return cmd, nil
}

func (job *Job) extract(ctx context.Context, values []string) ([]string, error) {
	result := []string{}
	for _, src := range values {
		extracted := src
		result = append(result, extracted)
	}
	return result, nil
}

func (job *Job) downloadFiles(dir string) (map[string]string, error) {
	result := map[string]string{}
	objects := job.flatten(job.parseJson(job.message.Message.Attributes["download_files"]))
	remote_urls := []string{}
	for _, obj := range objects {
		switch obj.(type) {
		case string:
			remote_urls = append(remote_urls, obj.(string))
		default:
			log.Printf("Invalid download file URL: %v [%T]", obj, obj)
		}
	}
	for _, remote_url := range remote_urls {
		url, err := url.Parse(remote_url)
		if err != nil {
			log.Fatalf("Invalid URL: %v because of %v\n", remote_url, err)
			return nil, err
		}
		urlstr := fmt.Sprintf("gs://%v/%v", url.Host, url.Path)
		destPath := filepath.Join(dir, url.Host, url.Path)
		err = job.storage.Download(url.Host, url.Path, destPath)
		if err != nil {
			return nil, err
		}
		result[urlstr] = destPath
	}
	return result, nil
}

func (job *Job) uploadFiles(dir string) error {
	localPaths, err := job.listFiles(dir)
	if err != nil {
		return err
	}
	for _, localPath := range localPaths {
		relPath, err := filepath.Rel(dir, localPath)
		if err != nil {
			log.Fatalf("Error getting relative path of %v: %v\n", localPath, err)
			return err
		}
		sep := string([]rune{os.PathSeparator})
		parts := strings.Split(relPath, sep)
		bucket := parts[0]
		object := strings.Join(parts[1:], sep)
		err = job.storage.Upload(bucket, object, localPath)
		if err != nil {
			log.Fatalf("Error uploading %v to gs://%v/%v: %v\n", localPath, bucket, object, err)
			return err
		}
	}
	return nil
}

func (job *Job) listFiles(dir string) ([]string, error) {
	result := []string{}
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			result = append(result, path)
		}
		return nil
	})
	if err != nil {
		log.Fatalf("Error listing upload files: %v\n", err)
		return nil, err
	}
	return result, nil
}

func (job *Job) parseJson(str string) interface{} {
	matched, err := regexp.MatchString(`\A\[.*\]\z|\A\{.*\}\z|`, str)
	if err != nil {
		return str
	}
	if !matched {
		return str
	}
	var dest interface{}
	err = json.Unmarshal([]byte(str), &dest)
	if err != nil {
		return str
	}
	return dest
}

func (job *Job) flatten(obj interface{}) []interface{} {
	// Support only unmarshalled object from JSON
	// See https://golang.org/pkg/encoding/json/#Unmarshal also
	switch obj.(type) {
	case []interface{}:
		res := []interface{}{}
		for _, i := range obj.([]interface{}) {
			switch i.(type) {
			case bool, float64, string, nil:
				res = append(res, i)
			default:
				for _, j := range job.flatten(i) {
					res = append(res, j)
				}
			}
		}
		return res
	case map[string]interface{}:
		values := []interface{}{}
		for _, val := range obj.(map[string]interface{}) {
			values = append(values, val)
		}
		return job.flatten(values)
	default:
		return []interface{}{obj}
	}
}
<|endoftext|>


<commit_before>package main

import (
  "flag"
  "log"

  "github.com/fimad/ggircd/irc"
)

var configFile = flag.String("config", "/etc/ggircd.conf",
  "Path to a file containing the irc daemon's configuration.")

func main() {
  flag.Parse()
  log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

  cfg := irc.ConfigFromJSONFile(*configFile)
  server := irc.NewDispatcher(cfg)
  server.Loop()
}
<commit_msg>Set max procs to num cpus.<commit_after>package main

import (
  "flag"
  "log"
  "runtime"

  "github.com/fimad/ggircd/irc"
)

var configFile = flag.String("config", "/etc/ggircd.conf",
  "Path to a file containing the irc daemon's configuration.")

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

  flag.Parse()
  log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

  cfg := irc.ConfigFromJSONFile(*configFile)
  server := irc.NewDispatcher(cfg)
  server.Loop()
}
<|endoftext|>


<commit_before>package parser

import (
	"io"
	"path/filepath"
	"net"
	"net/mail"
	"os"
	"regexp"
	"strconv"
	"text/scanner"
	"unicode"

	"github.com/yuuki1/gokc/log"
)

var SYMBOL_TABLES = map[string]int{
	"{": LB,
	"}": RB,

	"global_defs": GLOBALDEFS,
	"notification_email": NOTIFICATION_EMAIL,
	"notification_email_from": NOTIFICATION_EMAIL_FROM,
	"smtp_server": SMTP_SERVER,
	"smtp_connect_timeout": SMTP_CONNECT_TIMEOUT,
	"router_id": ROUTER_ID,
	"lvs_id": LVS_ID,

	"vrrp_sync_group": VRRP_SYNC_GROUP,
	"group": GROUP,

	"vrrp_instance": VRRP_INSTANCE,
	"interface": INTERFACE,
	"lvs_sync_daemon_interface": LVS_SYNC_DAEMON_INTERFACE,
	"virtual_router_id": VIRTUAL_ROUTER_ID,
	"nopreempt": NOPREEMPT,
	"priority": PRIORITY,
	"advert_int": ADVERT_INT,
	"virtual_ipaddress": VIRTUAL_IPADDRESS,
	"state": STATE,
	"MASTER": MASTER,
	"BACKUP": BACKUP,
	"garp_master_delay": GARP_MASTER_DELAY,
	"smtp_alert": SMTP_ALERT,
	"authentication": AUTHENTICATION,
	"auth_type": AUTH_TYPE,
	"auth_pass": AUTH_PASS,
	"PASS": PASS,
	"AH": AH,
	"label": LABEL,
	"dev": DEV,
	"brd": BRD,
	"track_interface": TRACK_INTERFACE,
	"track_script": TRACK_SCRIPT,
	"notify_master": NOTIFY_MASTER,
	"notify_backup": NOTIFY_BACKUP,
	"notify_fault": NOTIFY_FAULT,
	"notify_stop": NOTIFY_STOP,
	"notify": NOTIFY,

	"vrrp_script": VRRP_SCRIPT,
	"script": SCRIPT,
	"interval": INTERVAL,
	"fall": FALL,
	"rise": RISE,

	"virtual_server": VIRTUAL_SERVER,
	"delay_loop": DELAY_LOOP,
	"lb_algo": LB_ALGO,
	"lb_kind": LB_KIND,
	"lvs_sched": LVS_SCHED,
	"lvs_method": LVS_METHOD,
	"rr": RR,
	"wrr": WRR,
	"lc": LC,
	"wlc": WLC,
	"lblc": LBLC,
	"sh": SH,
	"dh": DH,
	"NAT": NAT,
	"TUN": TUN,
	"persistence_timeout": PERSISTENCE_TIMEOUT,
	"protocol": PROTOCOL,
	"TCP": TCP,
	"UDP": UDP,
	"sorry_server": SORRY_SERVER,
	"real_server": REAL_SERVER,
	"weight": WEIGHT,
	"inhibit_on_failure": INHIBIT_ON_FAILURE,
	"HTTP_GET": HTTP_GET,
	"url": URL,
	"path": PATH,
	"digest": DIGEST,
	"status_code": STATUS_CODE,
	"connect_timeout": CONNECT_TIMEOUT,
	"nb_get_retry": NB_GET_RETRY,
	"delay_before_retry": DELAY_BEFORE_RETRY,
	"virtualhost": VIRTUALHOST,
}

type Lexer struct {
	scanner.Scanner
	filename string
	emitter chan int
	e *Error
}

type Error struct {
	Message string
	Filename string
	Line int
	Column int
}

func (e *Error) Error() string {
	return e.Message
}

func NewLexer(src io.Reader, filename string) *Lexer {
	var lex Lexer
	lex.scannerInit(src, filename)
	lex.emitter = make(chan int)
	return &lex
}

func isIdentRune(ch rune, i int) bool {
	return ch == '_' || ch == '.' || ch == '/' || ch == ':' || ch == '-' || ch == '+' || ch == '*' || ch == '@' || unicode.IsLetter(ch) || unicode.IsDigit(ch)
}

func (l *Lexer) scannerInit(src io.Reader, filename string) {
	l.Init(src)
	l.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
	l.IsIdentRune = isIdentRune
	l.filename = filename
}

func (l *Lexer) scanNextToken() (int, string) {
	token := int(l.Scan())
	s := l.TokenText()

	for s == "!" || s == "#" {
		l.skipComments()

		token = int(l.Scan())
		s = l.TokenText()
	}

	log.Debugf("token text: %s\n", s)

	return token, s
}

func (l *Lexer) skipComments() {
	ch := l.Next()
	for ch != '\n' && ch >= 0 {
		ch = l.Next()
	}
}

func (l *Lexer) scanInclude(filename string) error {
	curDir, err := filepath.Abs(".")
	if err != nil {
		return err
	}

	baseDir := filepath.Dir(l.filename)
	os.Chdir(baseDir)
	defer os.Chdir(curDir)

	paths, err := filepath.Glob(filename)
	if err != nil {
		return err
	}

	for _, p := range paths {
		path := filepath.Join(baseDir, p)
		f, err := os.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()

		l.scannerInit(f, path)
		l.run()
	}

	return nil
}

func (l *Lexer) Lex(lval *yySymType) int {
	return <-l.emitter
}

func (l *Lexer) run() {
	var startInclude bool

	for {
		token, s := l.scanNextToken()

		// True end
		// Ignore include file's EOF
		if token == scanner.EOF && startInclude == false {
			l.emitter <- token
			close(l.emitter)
			break
		}

		if s == "include" {
			startInclude = true
			token, s = l.scanNextToken()

			if err := l.scanInclude(s); err != nil {
				l.Error(err.Error())
			}

			token, s = l.scanNextToken()
			startInclude = false
		}

		if token == scanner.Ident || token == scanner.String {
			token = STRING
		}

		if _, err := strconv.Atoi(s); err == nil {
			token = NUMBER
		}

		if net.ParseIP(s) != nil {
			token = IPADDR
		}

		if _, _, err := net.ParseCIDR(s); err == nil {
			token = IP_CIDR
		}

		if ok, _ := regexp.MatchString("[[:xdigit:]]{32}", s); ok {
			token = HEX32
		}

		if ok, _ := regexp.MatchString("/^([[:alnum:]./-_])*", s); ok {
			token = PATHSTR
		}

		if _, err := mail.ParseAddress(s); err == nil {
			token = EMAIL
		}

		if _, ok := SYMBOL_TABLES[s]; ok {
			token = SYMBOL_TABLES[s]
		}

		l.emitter <- token
	}
}

func (l *Lexer) Error(msg string) {
	l.e = &Error{Filename: l.filename, Line: l.Line, Column: l.Column, Message: msg}
}

func Parse(src io.Reader, filename string) error {
	yyErrorVerbose = true
	l := NewLexer(src, filename)
	go l.run()
	if ret := yyParse(l); ret != 0 {
		return l.e
	}
	return nil
}

<commit_msg>Fix panic bug 'send on closed channel'. Improve cleaning process<commit_after>package parser

import (
	"io"
	"path/filepath"
	"net"
	"net/mail"
	"os"
	"regexp"
	"strconv"
	"text/scanner"
	"unicode"

	"github.com/yuuki1/gokc/log"
)

var SYMBOL_TABLES = map[string]int{
	"{": LB,
	"}": RB,

	"global_defs": GLOBALDEFS,
	"notification_email": NOTIFICATION_EMAIL,
	"notification_email_from": NOTIFICATION_EMAIL_FROM,
	"smtp_server": SMTP_SERVER,
	"smtp_connect_timeout": SMTP_CONNECT_TIMEOUT,
	"router_id": ROUTER_ID,
	"lvs_id": LVS_ID,

	"vrrp_sync_group": VRRP_SYNC_GROUP,
	"group": GROUP,

	"vrrp_instance": VRRP_INSTANCE,
	"interface": INTERFACE,
	"lvs_sync_daemon_interface": LVS_SYNC_DAEMON_INTERFACE,
	"virtual_router_id": VIRTUAL_ROUTER_ID,
	"nopreempt": NOPREEMPT,
	"priority": PRIORITY,
	"advert_int": ADVERT_INT,
	"virtual_ipaddress": VIRTUAL_IPADDRESS,
	"state": STATE,
	"MASTER": MASTER,
	"BACKUP": BACKUP,
	"garp_master_delay": GARP_MASTER_DELAY,
	"smtp_alert": SMTP_ALERT,
	"authentication": AUTHENTICATION,
	"auth_type": AUTH_TYPE,
	"auth_pass": AUTH_PASS,
	"PASS": PASS,
	"AH": AH,
	"label": LABEL,
	"dev": DEV,
	"brd": BRD,
	"track_interface": TRACK_INTERFACE,
	"track_script": TRACK_SCRIPT,
	"notify_master": NOTIFY_MASTER,
	"notify_backup": NOTIFY_BACKUP,
	"notify_fault": NOTIFY_FAULT,
	"notify_stop": NOTIFY_STOP,
	"notify": NOTIFY,

	"vrrp_script": VRRP_SCRIPT,
	"script": SCRIPT,
	"interval": INTERVAL,
	"fall": FALL,
	"rise": RISE,

	"virtual_server": VIRTUAL_SERVER,
	"delay_loop": DELAY_LOOP,
	"lb_algo": LB_ALGO,
	"lb_kind": LB_KIND,
	"lvs_sched": LVS_SCHED,
	"lvs_method": LVS_METHOD,
	"rr": RR,
	"wrr": WRR,
	"lc": LC,
	"wlc": WLC,
	"lblc": LBLC,
	"sh": SH,
	"dh": DH,
	"NAT": NAT,
	"TUN": TUN,
	"persistence_timeout": PERSISTENCE_TIMEOUT,
	"protocol": PROTOCOL,
	"TCP": TCP,
	"UDP": UDP,
	"sorry_server": SORRY_SERVER,
	"real_server": REAL_SERVER,
	"weight": WEIGHT,
	"inhibit_on_failure": INHIBIT_ON_FAILURE,
	"HTTP_GET": HTTP_GET,
	"url": URL,
	"path": PATH,
	"digest": DIGEST,
	"status_code": STATUS_CODE,
	"connect_timeout": CONNECT_TIMEOUT,
	"nb_get_retry": NB_GET_RETRY,
	"delay_before_retry": DELAY_BEFORE_RETRY,
	"virtualhost": VIRTUALHOST,
}

type Lexer struct {
	scanner.Scanner
	filename string
	emitter chan int
	e *Error
}

type Error struct {
	Message string
	Filename string
	Line int
	Column int
}

func (e *Error) Error() string {
	return e.Message
}

func NewLexer(src io.Reader, filename string) *Lexer {
	var lex Lexer
	lex.scannerInit(src, filename)
	lex.emitter = make(chan int)
	return &lex
}

func isIdentRune(ch rune, i int) bool {
	return ch == '_' || ch == '.' || ch == '/' || ch == ':' || ch == '-' || ch == '+' || ch == '*' || ch == '@' || unicode.IsLetter(ch) || unicode.IsDigit(ch)
}

func (l *Lexer) scannerInit(src io.Reader, filename string) {
	l.Init(src)
	l.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
	l.IsIdentRune = isIdentRune
	l.filename = filename
}

func (l *Lexer) scanNextToken() (int, string) {
	token := int(l.Scan())
	s := l.TokenText()

	for s == "!" || s == "#" {
		l.skipComments()

		token = int(l.Scan())
		s = l.TokenText()
	}

	log.Debugf("token text: %s\n", s)

	return token, s
}

func (l *Lexer) skipComments() {
	ch := l.Next()
	for ch != '\n' && ch >= 0 {
		ch = l.Next()
	}
}

func (l *Lexer) scanInclude(filename string) error {
	curDir, err := filepath.Abs(".")
	if err != nil {
		return err
	}

	baseDir := filepath.Dir(l.filename)
	os.Chdir(baseDir)
	defer os.Chdir(curDir)

	paths, err := filepath.Glob(filename)
	if err != nil {
		return err
	}

	for _, p := range paths {
		path := filepath.Join(baseDir, p)
		f, err := os.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()

		l.scannerInit(f, path)
		l.run()
	}

	return nil
}

func (l *Lexer) Lex(lval *yySymType) int {
	return <-l.emitter
}

func (l *Lexer) run() {
	for {
		token, s := l.scanNextToken()

		if token == scanner.EOF {
			l.emitter <- token
			break
		}

		if s == "include" {
			token, s = l.scanNextToken()

			if err := l.scanInclude(s); err != nil {
				l.Error(err.Error())
			}

			token, s = l.scanNextToken()
		}

		if token == scanner.Ident || token == scanner.String {
			token = STRING
		}

		if _, err := strconv.Atoi(s); err == nil {
			token = NUMBER
		}

		if net.ParseIP(s) != nil {
			token = IPADDR
		}

		if _, _, err := net.ParseCIDR(s); err == nil {
			token = IP_CIDR
		}

		if ok, _ := regexp.MatchString("[[:xdigit:]]{32}", s); ok {
			token = HEX32
		}

		if ok, _ := regexp.MatchString("/^([[:alnum:]./-_])*", s); ok {
			token = PATHSTR
		}

		if _, err := mail.ParseAddress(s); err == nil {
			token = EMAIL
		}

		if _, ok := SYMBOL_TABLES[s]; ok {
			token = SYMBOL_TABLES[s]
		}

		l.emitter <- token
	}
}

func (l *Lexer) Error(msg string) {
	l.e = &Error{Filename: l.filename, Line: l.Line, Column: l.Column, Message: msg}
}

func Parse(src io.Reader, filename string) error {
	yyErrorVerbose = true
	l := NewLexer(src, filename)
	go l.run()
	defer close(l.emitter)
	if ret := yyParse(l); ret != 0 {
		return l.e
	}
	return nil
}

<|endoftext|>


<commit_before>// Copyright (c) 2015 Pagoda Box Inc
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
//
package handlers

import (
	"fmt"
	"github.com/nanobox-io/golang-discovery"
	"github.com/nanopack/mist/core"
	"github.com/nanopack/mist/subscription"
	"io"
	"time"
)

type (
	Looper interface {
		Loop(time.Duration) error
	}

	replicate struct {
		mist          *mist.Mist
		clients       []mist.Client
		newClient     chan mist.Client
		doneClient    chan mist.Client
		subscriptions mist.Subscriptions
	}
)

func EnableReplication(server *mist.Mist, discover discovery.Discover) *replicate {

	replicate := &replicate{
		mist:          server,
		newClient:     make(chan mist.Client),
		doneClient:    make(chan mist.Client),
		subscriptions: subscription.NewNode(),
	}

	discover.Handle("mist", replicate)

	return replicate
}

func (rep *replicate) Monitor() {
	// we want to catch all subscription/unsubscription changes.
	// this should at least give a good safety zone.
	client := mist.NewLocalClient(rep.mist, 100)
	defer client.Close()

	// set the client to be in internal mode
	// now only internal message will be received
	client.(mist.EnableInternal).EnableInternal()

	for {
		select {
		case msg, ok := <-client.Messages():
			if !ok {
				return
			}
			switch msg.Data {
			case "subscribe":
				rep.subscriptions.Add(msg.Tags)
			case "unsubscribe":
				rep.subscriptions.Remove(msg.Tags)
			default:
				// we ignore all other messages
				continue
			}
			rep.forwardAll(msg.Data, msg.Tags)
		case remote := <-rep.doneClient:
			// very innefficeint, really shouldn't be a slice
			// shouldn't matter unless we have a cluster of over 100
			// machines
			for i := len(rep.clients) - 1; i >= 0; i-- {
				if rep.clients[i] == remote {
					rep.clients = append(rep.clients[:i], rep.clients[i+1:]...)
				}
			}
		case remote := <-rep.newClient:
			rep.clients = append(rep.clients, remote)

			// forward all published messages to the local mist server
			go func() {
				for msg := range remote.Messages() {
					rep.mist.Replicate(msg.Tags, msg.Data)
				}
				rep.doneClient <- remote
			}()

			// send all subscriptions across the connection.
			for _, subscription := range rep.subscriptions.ToSlice() {
				forward(remote, "subscribe", subscription)
			}
		}
	}
}

func (rep replicate) forwardAll(fun string, subscription []string) {
	perform := getFunc(fun)
	for _, client := range rep.clients {
		if err := perform(client, subscription); err != nil {
			// should we log this error?
		}
	}
}

func forward(client mist.Client, fun string, subscription []string) {
	perform := getFunc(fun)
	if err := perform(client, subscription); err != nil {
		// should we log this error?
	}
}

func getFunc(fun string) func(mist.Client, []string) error {
	if fun == "subscribe" {
		return mist.Client.Subscribe
	}
	return mist.Client.Unsubscribe
}

func (rep *replicate) New(address string) io.Closer {
	client, err := mist.NewRemoteClient(address)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	client.(mist.EnableReplication).EnableReplication()

	// add this client to the list of all clients
	rep.newClient <- client

	return client
}
<commit_msg>removing unessecary logging<commit_after>// Copyright (c) 2015 Pagoda Box Inc
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not distributed with this file, You can obtain one
// at http://mozilla.org/MPL/2.0/.
//
package handlers

import (
	"github.com/nanobox-io/golang-discovery"
	"github.com/nanopack/mist/core"
	"github.com/nanopack/mist/subscription"
	"io"
	"time"
)

type (
	Looper interface {
		Loop(time.Duration) error
	}

	replicate struct {
		mist          *mist.Mist
		clients       []mist.Client
		newClient     chan mist.Client
		doneClient    chan mist.Client
		subscriptions mist.Subscriptions
	}
)

func EnableReplication(server *mist.Mist, discover discovery.Discover) *replicate {

	replicate := &replicate{
		mist:          server,
		newClient:     make(chan mist.Client),
		doneClient:    make(chan mist.Client),
		subscriptions: subscription.NewNode(),
	}

	discover.Handle("mist", replicate)

	return replicate
}

func (rep *replicate) Monitor() {
	// we want to catch all subscription/unsubscription changes.
	// this should at least give a good safety zone.
	client := mist.NewLocalClient(rep.mist, 100)
	defer client.Close()

	// set the client to be in internal mode
	// now only internal message will be received
	client.(mist.EnableInternal).EnableInternal()

	for {
		select {
		case msg, ok := <-client.Messages():
			if !ok {
				return
			}
			switch msg.Data {
			case "subscribe":
				rep.subscriptions.Add(msg.Tags)
			case "unsubscribe":
				rep.subscriptions.Remove(msg.Tags)
			default:
				// we ignore all other messages
				continue
			}
			rep.forwardAll(msg.Data, msg.Tags)
		case remote := <-rep.doneClient:
			// very innefficeint, really shouldn't be a slice
			// shouldn't matter unless we have a cluster of over 100
			// machines
			for i := len(rep.clients) - 1; i >= 0; i-- {
				if rep.clients[i] == remote {
					rep.clients = append(rep.clients[:i], rep.clients[i+1:]...)
				}
			}
		case remote := <-rep.newClient:
			rep.clients = append(rep.clients, remote)

			// forward all published messages to the local mist server
			go func() {
				for msg := range remote.Messages() {
					rep.mist.Replicate(msg.Tags, msg.Data)
				}
				rep.doneClient <- remote
			}()

			// send all subscriptions across the connection.
			for _, subscription := range rep.subscriptions.ToSlice() {
				forward(remote, "subscribe", subscription)
			}
		}
	}
}

func (rep replicate) forwardAll(fun string, subscription []string) {
	perform := getFunc(fun)
	for _, client := range rep.clients {
		if err := perform(client, subscription); err != nil {
			// should we log this error?
		}
	}
}

func forward(client mist.Client, fun string, subscription []string) {
	perform := getFunc(fun)
	if err := perform(client, subscription); err != nil {
		// should we log this error?
	}
}

func getFunc(fun string) func(mist.Client, []string) error {
	if fun == "subscribe" {
		return mist.Client.Subscribe
	}
	return mist.Client.Unsubscribe
}

func (rep *replicate) New(address string) io.Closer {
	client, err := mist.NewRemoteClient(address)
	if err != nil {
		return nil
	}

	client.(mist.EnableReplication).EnableReplication()

	// add this client to the list of all clients
	rep.newClient <- client

	return client
}
<|endoftext|>


<commit_before>package handlers

import (
	"fmt"
	"net/http"
	"strings"

	"appengine"

	"github.com/icco/natnatnat/models"
	"github.com/pilu/traffic"
)

type TagData struct {
	Posts interface{}
	Tag   string
}

func TagHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	tag := r.Param("id")

	if tag == "" {
		http.Redirect(w, r.Request, "/tags", 301)
	}

	if tag != strings.ToLower(tag) {
		http.Redirect(w, r.Request, fmt.Sprintf("/tags/%s", strings.ToLower(tag)), 301)
	}

	entries, err := models.PostsWithTag(c, tag)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	data := &TagData{Posts: entries, Tag: tag}
	w.Render("tag", data)
}

func TagsHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	models.AllTags(c)

	http.Error(w, "", 500)
}
<commit_msg>new tags<commit_after>package handlers

import (
	"fmt"
	"net/http"
	"strings"

	"appengine"

	"github.com/icco/natnatnat/models"
	"github.com/pilu/traffic"
)

type TagData struct {
	Posts interface{}
	Tag   string
}

func TagHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	tag := r.Param("id")

	if tag == "" {
		http.Redirect(w, r.Request, "/tags", 301)
	}

	if tag != strings.ToLower(tag) {
		http.Redirect(w, r.Request, fmt.Sprintf("/tags/%s", strings.ToLower(tag)), 301)
	}

	entries, err := models.PostsWithTag(c, tag)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	data := &TagData{Posts: entries, Tag: tag}
	w.Render("tag", data)
}

type TagsData struct {
	Tags map[string]int
}

func TagsHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	w.Render("tags", &TagsData{Tags: models.AllTags(c)})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"
)

func collatz(n, count int) int {
	count++
	if n%2 == 0 {
		return collatz(n/2, count)
	} else if n != 1 {
		return collatz((3*n)+1, count)
	}
	return count
}
func main() {
	n, err := strconv.Atoi(os.Args[1])
	if err != nil {
		panic(err)
	}
	biggest := 0
	tmp := 0
	for i := 1; i < n; i++ {
		tmp = collatz(i, 0)
		if tmp > biggest {
			biggest = tmp
			fmt.Println(biggest, i)
		}
	}
}
<commit_msg>I prefer this if style I guess<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"
)

func collatz(n, count int) int {
	count++
	if n%2 == 0 {
		return collatz(n/2, count)
	} else if n != 1 {
		return collatz((3*n)+1, count)
	}
	return count
}
func main() {
	n, err := strconv.Atoi(os.Args[1])
	if err != nil {
		panic(err)
	}
	biggest := 0
	tmp := 0
	for i := 1; i < n; i++ {
		if tmp = collatz(i, 0); tmp > biggest {
			biggest = tmp
			fmt.Println(biggest, i)
		}
	}
}
<|endoftext|>


<commit_before>package jwt

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"strings"
)

var (
	ErrMissingConfig      = errors.New("missing configuration")
	ErrMissingSecret      = errors.New("please provide a shared secret")
	ErrMissingAuthFunc    = errors.New("please provide an auth function")
	ErrMissingClaimsFunc  = errors.New("please provide a claims function")
	ErrEncoding           = errors.New("error encoding value")
	ErrMissingToken       = errors.New("please provide a token")
	ErrMalformedToken     = errors.New("please provide a valid token")
	ErrDecodingHeader     = errors.New("could not decode JOSE header")
	ErrInvalidSignature   = errors.New("signature could not be verified")
	ErrParsingCredentials = errors.New("error parsing credentials")
)

type Config struct {
	Secret string
	Auth   AuthFunc
	Claims ClaimsFunc
}

type AuthFunc func(string, string) error

type ClaimsFunc func(string) (map[string]interface{}, error)

type VerifyClaimsFunc func([]byte) error

type JWTMiddleware struct {
	secret string
	auth   AuthFunc
	claims ClaimsFunc
}

func NewMiddleware(c *Config) (*JWTMiddleware, error) {
	if c == nil {
		return nil, ErrMissingConfig
	}
	if c.Secret == "" {
		return nil, ErrMissingSecret
	}
	if c.Auth == nil {
		return nil, ErrMissingAuthFunc
	}
	if c.Claims == nil {
		return nil, ErrMissingClaimsFunc
	}
	m := &JWTMiddleware{
		secret: c.Secret,
		auth:   c.Auth,
		claims: c.Claims,
	}
	return m, nil
}

func (m *JWTMiddleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		authHeader := r.Header.Get("Authorization")
		if authHeader == "" {
			http.Error(w, ErrMissingToken.Error(), http.StatusUnauthorized)
			return
		}
		token := strings.Split(authHeader, " ")[1]
		tokenParts := strings.Split(token, ".")
		if len(tokenParts) != 3 {
			http.Error(w, ErrMalformedToken.Error(), http.StatusUnauthorized)
			return
		}

		// First, verify JOSE header
		var t struct {
			Typ string
			Alg string
		}
		header, err := decode(tokenParts[0])
		if err != nil {
			log.Printf("error (%v) while decoding header (%v)", err, tokenParts[0])
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		err = json.Unmarshal(header, &t)
		if err != nil {
			log.Printf("error (%v) while unmarshalling header (%s)", err, header)
			http.Error(w, ErrMalformedToken.Error(), http.StatusInternalServerError)
			return
		}

		// Then, verify signature
		mac := hmac.New(sha256.New, []byte(m.secret))
		message := []byte(strings.Join([]string{tokenParts[0], tokenParts[1]}, "."))
		mac.Write(message)
		expectedMac, err := encode(mac.Sum(nil))
		if err != nil {
			panic(err)
			return
		}
		if !hmac.Equal([]byte(tokenParts[2]), []byte(expectedMac)) {
			log.Printf("invalid signature: %v", tokenParts[2])
			http.Error(w, ErrInvalidSignature.Error(), http.StatusUnauthorized)
			return
		}

		// Finally, check claims
		claimSet, err := decode(tokenParts[1])
		if err != nil {
			panic(err)
			return
		}
		err = v(claimSet)
		if err != nil {
			log.Printf("claims error: %v", err)
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}

		// If we make it this far, process the downstream handler
		h.ServeHTTP(w, r)
	})
}

func (m *JWTMiddleware) GenerateToken(w http.ResponseWriter, r *http.Request) {
	var b map[string]string
	err := json.NewDecoder(r.Body).Decode(&b)
	if err != nil {
		log.Printf("error (%v) while parsing authorization", err)
		http.Error(w, ErrParsingCredentials.Error(), http.StatusInternalServerError)
		return
	}
	err = m.auth(b["email"], b["password"])
	if err != nil {
		log.Printf("error (%v) while performing authorization", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// For now, the header will be static
	header, err := encode(`{"typ":"JWT","alg":"HS256"}`)
	if err != nil {
		panic(err)
	}

	claims, err := m.claims(b["email"])
	if err != nil {
		panic(err)
	}

	claimsJson, err := json.Marshal(claims)
	if err != nil {
		panic(err)
	}

	claimsSet, err := encode(claimsJson)
	if err != nil {
		panic(err)
	}

	toSig := strings.Join([]string{header, claimsSet}, ".")

	h := hmac.New(sha256.New, []byte(m.secret))
	h.Write([]byte(toSig))
	sig, err := encode(h.Sum(nil))
	if err != nil {
		panic(err)
	}

	response := strings.Join([]string{toSig, sig}, ".")
	w.Write([]byte(response))
}

func encode(s interface{}) (string, error) {
	var r []byte
	switch v := s.(type) {
	case string:
		r = []byte(v)
	case []byte:
		r = v
	default:
		return "", ErrEncoding
	}
	return base64.StdEncoding.EncodeToString(r), nil
}

func decode(s string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(s)
}
<commit_msg>No more panics<commit_after>package jwt

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"strings"
)

const (
	typ = "JWT"
	alg = "HS256"
)

var (
	ErrMissingConfig      = errors.New("missing configuration")
	ErrMissingSecret      = errors.New("please provide a shared secret")
	ErrMissingAuthFunc    = errors.New("please provide an auth function")
	ErrMissingClaimsFunc  = errors.New("please provide a claims function")
	ErrEncoding           = errors.New("error encoding value")
	ErrDecoding           = errors.New("error decoding value")
	ErrMissingToken       = errors.New("please provide a token")
	ErrMalformedToken     = errors.New("please provide a valid token")
	ErrInvalidSignature   = errors.New("signature could not be verified")
	ErrParsingCredentials = errors.New("error parsing credentials")
)

type Config struct {
	Secret string
	Auth   AuthFunc
	Claims ClaimsFunc
}

type AuthFunc func(string, string) error

type ClaimsFunc func(string) (map[string]interface{}, error)

type VerifyClaimsFunc func([]byte) error

type JWTMiddleware struct {
	secret string
	auth   AuthFunc
	claims ClaimsFunc
}

func NewMiddleware(c *Config) (*JWTMiddleware, error) {
	if c == nil {
		return nil, ErrMissingConfig
	}
	if c.Secret == "" {
		return nil, ErrMissingSecret
	}
	if c.Auth == nil {
		return nil, ErrMissingAuthFunc
	}
	if c.Claims == nil {
		return nil, ErrMissingClaimsFunc
	}
	m := &JWTMiddleware{
		secret: c.Secret,
		auth:   c.Auth,
		claims: c.Claims,
	}
	return m, nil
}

func (m *JWTMiddleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		authHeader := r.Header.Get("Authorization")
		if authHeader == "" {
			http.Error(w, ErrMissingToken.Error(), http.StatusUnauthorized)
			return
		}
		token := strings.Split(authHeader, " ")[1]
		tokenParts := strings.Split(token, ".")
		if len(tokenParts) != 3 {
			http.Error(w, ErrMalformedToken.Error(), http.StatusUnauthorized)
			return
		}

		// First, verify JOSE header
		var t struct {
			Typ string
			Alg string
		}
		header, err := decode(tokenParts[0])
		if err != nil {
			log.Printf("error (%v) while decoding header (%v)", err, tokenParts[0])
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		err = json.Unmarshal(header, &t)
		if err != nil {
			log.Printf("error (%v) while unmarshalling header (%s)", err, header)
			http.Error(w, ErrMalformedToken.Error(), http.StatusInternalServerError)
			return
		}

		// Then, verify signature
		mac := hmac.New(sha256.New, []byte(m.secret))
		message := []byte(strings.Join([]string{tokenParts[0], tokenParts[1]}, "."))
		mac.Write(message)
		expectedMac, err := encode(mac.Sum(nil))
		if err != nil {
			panic(err)
			return
		}
		if !hmac.Equal([]byte(tokenParts[2]), []byte(expectedMac)) {
			log.Printf("invalid signature: %v", tokenParts[2])
			http.Error(w, ErrInvalidSignature.Error(), http.StatusUnauthorized)
			return
		}

		// Finally, check claims
		claimSet, err := decode(tokenParts[1])
		if err != nil {
			log.Printf("error (%v) while decoding claims", err)
			http.Error(w, ErrDecoding.Error(), http.StatusInternalServerError)
			return
		}
		err = v(claimSet)
		if err != nil {
			log.Printf("claims handler error: %v", err)
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}

		// If we make it this far, process the downstream handler
		h.ServeHTTP(w, r)
	})
}

func (m *JWTMiddleware) GenerateToken(w http.ResponseWriter, r *http.Request) {
	var b map[string]string
	err := json.NewDecoder(r.Body).Decode(&b)
	if err != nil {
		log.Printf("error (%v) while parsing authorization", err)
		http.Error(w, ErrParsingCredentials.Error(), http.StatusInternalServerError)
		return
	}
	err = m.auth(b["email"], b["password"])
	if err != nil {
		log.Printf("error (%v) while performing authorization", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// For now, the header will be static
	header, err := encode(fmt.Sprintf(`{"typ":%q,"alg":%q}`, typ, alg))
	if err != nil {
		log.Printf("error (%v) while encoding header", err)
		http.Error(w, ErrEncoding.Error(), http.StatusInternalServerError)
		return
	}

	// Generate claims for user
	claims, err := m.claims(b["email"])
	if err != nil {
		log.Printf("error (%v) while generating claims", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	claimsJson, err := json.Marshal(claims)
	if err != nil {
		log.Printf("error (%v) while marshalling claims")
		http.Error(w, ErrEncoding.Error(), http.StatusInternalServerError)
		return
	}

	claimsSet, err := encode(claimsJson)
	if err != nil {
		log.Printf("error (%v) while encoding claims")
		http.Error(w, ErrEncoding.Error(), http.StatusInternalServerError)
		return
	}

	toSig := strings.Join([]string{header, claimsSet}, ".")

	h := hmac.New(sha256.New, []byte(m.secret))
	h.Write([]byte(toSig))
	sig, err := encode(h.Sum(nil))
	if err != nil {
		log.Printf("error (%v) while encoding signature")
		http.Error(w, ErrEncoding.Error(), http.StatusInternalServerError)
		return
	}

	response := strings.Join([]string{toSig, sig}, ".")
	w.Write([]byte(response))
}

func encode(s interface{}) (string, error) {
	var r []byte
	switch v := s.(type) {
	case string:
		r = []byte(v)
	case []byte:
		r = v
	default:
		return "", ErrEncoding
	}
	return base64.StdEncoding.EncodeToString(r), nil
}

func decode(s string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(s)
}
<|endoftext|>


<commit_before>// Package jwt implements a simple, opinionated net/http-compatible middleware for
// integrating JSON Web Tokens (JWT).
package jwt

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strings"
)

const (
	typ = "JWT"
	alg = "HS256"
)

// Errors introduced by this package.
var (
	ErrMissingConfig      = errors.New("missing configuration")
	ErrMissingSecret      = errors.New("please provide a shared secret")
	ErrMissingAuthFunc    = errors.New("please provide an auth function")
	ErrMissingClaimsFunc  = errors.New("please provide a claims function")
	ErrEncoding           = errors.New("error encoding value")
	ErrDecoding           = errors.New("error decoding value")
	ErrMissingToken       = errors.New("please provide a token")
	ErrMalformedToken     = errors.New("please provide a valid token")
	ErrInvalidSignature   = errors.New("signature could not be verified")
	ErrParsingCredentials = errors.New("error parsing credentials")
	ErrInvalidMethod      = errors.New("invalid request method")
)

// AuthFunc is a type for delegating user authentication to the client-code.
type AuthFunc func(string, string) error

// ClaimsFunc is a type for delegating claims generation to the client-code.
type ClaimsFunc func(string) (map[string]interface{}, error)

// VerifyClaimsFunc is a type for processing and validating JWT claims on one
// or more routes in the client-code.
type VerifyClaimsFunc func([]byte, *http.Request) error

// Config is a container for setting up the JWT middleware.
type Config struct {
	Secret        string
	Auth          AuthFunc
	Claims        ClaimsFunc
	IdentityField string
	VerifyField   string
}

// Middleware is where we store all the specifics related to the client's
// JWT needs.
type Middleware struct {
	secret        string
	auth          AuthFunc
	claims        ClaimsFunc
	identityField string
	verifyField   string
}

// New creates a new Middleware from a user-specified configuration.
func New(c *Config) (*Middleware, error) {
	if c == nil {
		return nil, ErrMissingConfig
	}
	if c.Secret == "" {
		return nil, ErrMissingSecret
	}
	if c.Auth == nil {
		return nil, ErrMissingAuthFunc
	}
	if c.Claims == nil {
		return nil, ErrMissingClaimsFunc
	}
	if c.IdentityField == "" {
		c.IdentityField = "email"
	}
	if c.VerifyField == "" {
		c.VerifyField = "password"
	}
	m := &Middleware{
		secret:        c.Secret,
		auth:          c.Auth,
		claims:        c.Claims,
		identityField: c.IdentityField,
		verifyField:   c.VerifyField,
	}
	return m, nil
}

// Secure wraps a client-specified http.Handler with a verification function,
// as well as-built in parsing of the request's JWT. This allows each handler
// to have it's own verification/validation protocol.
func (m *Middleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
	secureHandler := func(w http.ResponseWriter, r *http.Request) *jwtError {
		var token string

		authHeader := r.Header.Get("Authorization")
		if authHeader == "" {
			queryParam := r.FormValue("token")
			if queryParam == "" {
				return &jwtError{status: http.StatusUnauthorized, err: ErrMissingToken}
			}
			var err error
			token, err = url.QueryUnescape(queryParam)
			if err != nil {
				return &jwtError{status: http.StatusUnauthorized, err: ErrMalformedToken}
			}
		} else {
			token = strings.Split(authHeader, " ")[1]
		}

		if status, err, message := m.VerifyToken(token, v, r); err != nil {
			return &jwtError{
				status:  status,
				err:     err,
				message: message,
			}
		}

		// If we make it this far, process the downstream handler
		h.ServeHTTP(w, r)
		return nil
	}
	return errorHandler(secureHandler)
}

// Authenticate returns a middleware that parsing an incoming request for a JWT,
// calls the client-supplied auth function, and if successful, returns a JWT to
// the requester.
func (m *Middleware) Authenticate() http.Handler {
	generateHandler := func(w http.ResponseWriter, r *http.Request) *jwtError {
		if r.Method != "POST" {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrInvalidMethod,
				message: "receiving request",
			}
		}
		var b map[string]string
		err := json.NewDecoder(r.Body).Decode(&b)
		if err != nil {
			return &jwtError{
				status:  http.StatusInternalServerError,
				err:     ErrParsingCredentials,
				message: "parsing authorization",
			}
		}
		// Check if required fields are in the body
		if _, ok := b[m.identityField]; !ok {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrParsingCredentials,
				message: "parsing credentials, missing identity field",
			}
		}
		if _, ok := b[m.verifyField]; !ok {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrParsingCredentials,
				message: "parsing credentials, missing verify field",
			}
		}
		err = m.auth(b[m.identityField], b[m.verifyField])
		if err != nil {
			return &jwtError{
				status:  http.StatusInternalServerError,
				err:     err,
				message: "performing authorization",
			}
		}
		response, err := m.CreateToken(b[m.identityField])
		if err != nil {
			return &jwtError{
				status:  http.StatusInternalServerError,
				err:     err,
				message: response,
			}
		}
		w.Write([]byte(response))
		return nil
	}

	return errorHandler(generateHandler)
}

// CreateToken generates a token from a user's identity
func (m *Middleware) CreateToken(identity string) (string, error) {
	// For now, the header will be static
	header, err := encode(fmt.Sprintf(`{"typ":%q,"alg":%q}`, typ, alg))
	if err != nil {
		return "encoding header", ErrEncoding
	}

	// Generate claims for user
	claims, err := m.claims(identity)
	if err != nil {
		return "generating claims", err
	}

	claimsJSON, err := json.Marshal(claims)
	if err != nil {
		return "mashalling claims", ErrEncoding
	}

	claimsSet, err := encode(claimsJSON)
	if err != nil {
		return "encoding claims", ErrEncoding
	}

	toSig := strings.Join([]string{header, claimsSet}, ".")

	h := hmac.New(sha256.New, []byte(m.secret))
	h.Write([]byte(toSig))
	sig, err := encode(h.Sum(nil))
	if err != nil {
		return "encoding signature", ErrEncoding
	}

	response := strings.Join([]string{toSig, sig}, ".")
	return response, nil
}

// VerifyToken verifies a token
func (m *Middleware) VerifyToken(token string, v VerifyClaimsFunc, r *http.Request) (int, error, string) {
	tokenParts := strings.Split(token, ".")
	if len(tokenParts) != 3 {
		return http.StatusUnauthorized, ErrMalformedToken, ""
	}

	// First, verify JOSE header
	header, err := decode(tokenParts[0])
	if err != nil {
		return http.StatusInternalServerError, err, fmt.Sprintf("decoding header (%v)", tokenParts[0])
	}
	var t struct {
		Typ string
		Alg string
	}
	err = json.Unmarshal(header, &t)
	if err != nil {
		return http.StatusInternalServerError, ErrMalformedToken, fmt.Sprintf("unmarshalling header (%s)", header)
	}

	// Then, verify signature
	mac := hmac.New(sha256.New, []byte(m.secret))
	message := []byte(strings.Join([]string{tokenParts[0], tokenParts[1]}, "."))
	mac.Write(message)
	expectedMac, err := encode(mac.Sum(nil))
	if err != nil {
		return http.StatusInternalServerError, err, ""
	}
	if !hmac.Equal([]byte(tokenParts[2]), []byte(expectedMac)) {
		return http.StatusUnauthorized, ErrInvalidSignature, fmt.Sprintf("checking signature (%v)", tokenParts[2])
	}

	// Finally, check claims
	claimSet, err := decode(tokenParts[1])
	if err != nil {
		return http.StatusInternalServerError, ErrDecoding, "decoding claims"
	}
	err = v(claimSet, r)
	if err != nil {
		return http.StatusUnauthorized, err, "handling claims callback"
	}

	return 200, nil, ""
}

type jwtError struct {
	status  int
	err     error
	message string
}

type errorHandler func(http.ResponseWriter, *http.Request) *jwtError

func (e errorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if err := e(w, r); err != nil {
		if err.message != "" {
			log.Printf("error (%v) while %s", err.err, err.message)
		}
		http.Error(w, err.err.Error(), err.status)
	}
}

func encode(s interface{}) (string, error) {
	var r []byte
	switch v := s.(type) {
	case string:
		r = []byte(v)
	case []byte:
		r = v
	default:
		return "", ErrEncoding
	}
	return base64.StdEncoding.EncodeToString(r), nil
}

func decode(s string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(s)
}
<commit_msg>Accept urlencoded form for authentication<commit_after>// Package jwt implements a simple, opinionated net/http-compatible middleware for
// integrating JSON Web Tokens (JWT).
package jwt

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strings"
)

const (
	typ = "JWT"
	alg = "HS256"
)

// Errors introduced by this package.
var (
	ErrMissingConfig      = errors.New("missing configuration")
	ErrMissingSecret      = errors.New("please provide a shared secret")
	ErrMissingAuthFunc    = errors.New("please provide an auth function")
	ErrMissingClaimsFunc  = errors.New("please provide a claims function")
	ErrEncoding           = errors.New("error encoding value")
	ErrDecoding           = errors.New("error decoding value")
	ErrMissingToken       = errors.New("please provide a token")
	ErrMalformedToken     = errors.New("please provide a valid token")
	ErrInvalidSignature   = errors.New("signature could not be verified")
	ErrParsingCredentials = errors.New("error parsing credentials")
	ErrInvalidMethod      = errors.New("invalid request method")
)

// AuthFunc is a type for delegating user authentication to the client-code.
type AuthFunc func(string, string) error

// ClaimsFunc is a type for delegating claims generation to the client-code.
type ClaimsFunc func(string) (map[string]interface{}, error)

// VerifyClaimsFunc is a type for processing and validating JWT claims on one
// or more routes in the client-code.
type VerifyClaimsFunc func([]byte, *http.Request) error

// Config is a container for setting up the JWT middleware.
type Config struct {
	Secret        string
	Auth          AuthFunc
	Claims        ClaimsFunc
	IdentityField string
	VerifyField   string
}

// Middleware is where we store all the specifics related to the client's
// JWT needs.
type Middleware struct {
	secret        string
	auth          AuthFunc
	claims        ClaimsFunc
	identityField string
	verifyField   string
}

// New creates a new Middleware from a user-specified configuration.
func New(c *Config) (*Middleware, error) {
	if c == nil {
		return nil, ErrMissingConfig
	}
	if c.Secret == "" {
		return nil, ErrMissingSecret
	}
	if c.Auth == nil {
		return nil, ErrMissingAuthFunc
	}
	if c.Claims == nil {
		return nil, ErrMissingClaimsFunc
	}
	if c.IdentityField == "" {
		c.IdentityField = "email"
	}
	if c.VerifyField == "" {
		c.VerifyField = "password"
	}
	m := &Middleware{
		secret:        c.Secret,
		auth:          c.Auth,
		claims:        c.Claims,
		identityField: c.IdentityField,
		verifyField:   c.VerifyField,
	}
	return m, nil
}

// Secure wraps a client-specified http.Handler with a verification function,
// as well as-built in parsing of the request's JWT. This allows each handler
// to have it's own verification/validation protocol.
func (m *Middleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
	secureHandler := func(w http.ResponseWriter, r *http.Request) *jwtError {
		var token string

		authHeader := r.Header.Get("Authorization")
		if authHeader == "" {
			queryParam := r.FormValue("token")
			if queryParam == "" {
				return &jwtError{status: http.StatusUnauthorized, err: ErrMissingToken}
			}
			var err error
			token, err = url.QueryUnescape(queryParam)
			if err != nil {
				return &jwtError{status: http.StatusUnauthorized, err: ErrMalformedToken}
			}
		} else {
			token = strings.Split(authHeader, " ")[1]
		}

		if status, err, message := m.VerifyToken(token, v, r); err != nil {
			return &jwtError{
				status:  status,
				err:     err,
				message: message,
			}
		}

		// If we make it this far, process the downstream handler
		h.ServeHTTP(w, r)
		return nil
	}
	return errorHandler(secureHandler)
}

// Authenticate returns a middleware that parsing an incoming request for a JWT,
// calls the client-supplied auth function, and if successful, returns a JWT to
// the requester.
func (m *Middleware) Authenticate() http.Handler {
	generateHandler := func(w http.ResponseWriter, r *http.Request) *jwtError {
		if r.Method != "POST" {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrInvalidMethod,
				message: "receiving request",
			}
		}

		b := make(map[string]string, 0)
		contentType := r.Header.Get("content-type")
		switch contentType {
		case "application/x-www-form-urlencoded":
			identity, verify := r.FormValue(m.identityField), r.FormValue(m.verifyField)
			if identity == "" || verify == "" {
				return &jwtError{
					status:  http.StatusInternalServerError,
					err:     ErrParsingCredentials,
					message: "parsing authorization",
				}
			}
			b[m.identityField], b[m.verifyField] = identity, verify
		default:
			err := json.NewDecoder(r.Body).Decode(&b)
			if err != nil {
				return &jwtError{
					status:  http.StatusInternalServerError,
					err:     ErrParsingCredentials,
					message: "parsing authorization",
				}
			}
		}

		// Check if required fields are in the body
		if _, ok := b[m.identityField]; !ok {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrParsingCredentials,
				message: "parsing credentials, missing identity field",
			}
		}
		if _, ok := b[m.verifyField]; !ok {
			return &jwtError{
				status:  http.StatusBadRequest,
				err:     ErrParsingCredentials,
				message: "parsing credentials, missing verify field",
			}
		}
		err := m.auth(b[m.identityField], b[m.verifyField])
		if err != nil {
			return &jwtError{
				status:  http.StatusInternalServerError,
				err:     err,
				message: "performing authorization",
			}
		}
		response, err := m.CreateToken(b[m.identityField])
		if err != nil {
			return &jwtError{
				status:  http.StatusInternalServerError,
				err:     err,
				message: response,
			}
		}
		w.Write([]byte(response))
		return nil
	}

	return errorHandler(generateHandler)
}

// CreateToken generates a token from a user's identity
func (m *Middleware) CreateToken(identity string) (string, error) {
	// For now, the header will be static
	header, err := encode(fmt.Sprintf(`{"typ":%q,"alg":%q}`, typ, alg))
	if err != nil {
		return "encoding header", ErrEncoding
	}

	// Generate claims for user
	claims, err := m.claims(identity)
	if err != nil {
		return "generating claims", err
	}

	claimsJSON, err := json.Marshal(claims)
	if err != nil {
		return "mashalling claims", ErrEncoding
	}

	claimsSet, err := encode(claimsJSON)
	if err != nil {
		return "encoding claims", ErrEncoding
	}

	toSig := strings.Join([]string{header, claimsSet}, ".")

	h := hmac.New(sha256.New, []byte(m.secret))
	h.Write([]byte(toSig))
	sig, err := encode(h.Sum(nil))
	if err != nil {
		return "encoding signature", ErrEncoding
	}

	response := strings.Join([]string{toSig, sig}, ".")
	return response, nil
}

// VerifyToken verifies a token
func (m *Middleware) VerifyToken(token string, v VerifyClaimsFunc, r *http.Request) (int, error, string) {
	tokenParts := strings.Split(token, ".")
	if len(tokenParts) != 3 {
		return http.StatusUnauthorized, ErrMalformedToken, ""
	}

	// First, verify JOSE header
	header, err := decode(tokenParts[0])
	if err != nil {
		return http.StatusInternalServerError, err, fmt.Sprintf("decoding header (%v)", tokenParts[0])
	}
	var t struct {
		Typ string
		Alg string
	}
	err = json.Unmarshal(header, &t)
	if err != nil {
		return http.StatusInternalServerError, ErrMalformedToken, fmt.Sprintf("unmarshalling header (%s)", header)
	}

	// Then, verify signature
	mac := hmac.New(sha256.New, []byte(m.secret))
	message := []byte(strings.Join([]string{tokenParts[0], tokenParts[1]}, "."))
	mac.Write(message)
	expectedMac, err := encode(mac.Sum(nil))
	if err != nil {
		return http.StatusInternalServerError, err, ""
	}
	if !hmac.Equal([]byte(tokenParts[2]), []byte(expectedMac)) {
		return http.StatusUnauthorized, ErrInvalidSignature, fmt.Sprintf("checking signature (%v)", tokenParts[2])
	}

	// Finally, check claims
	claimSet, err := decode(tokenParts[1])
	if err != nil {
		return http.StatusInternalServerError, ErrDecoding, "decoding claims"
	}
	err = v(claimSet, r)
	if err != nil {
		return http.StatusUnauthorized, err, "handling claims callback"
	}

	return 200, nil, ""
}

type jwtError struct {
	status  int
	err     error
	message string
}

type errorHandler func(http.ResponseWriter, *http.Request) *jwtError

func (e errorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if err := e(w, r); err != nil {
		if err.message != "" {
			log.Printf("error (%v) while %s", err.err, err.message)
		}
		http.Error(w, err.err.Error(), err.status)
	}
}

func encode(s interface{}) (string, error) {
	var r []byte
	switch v := s.(type) {
	case string:
		r = []byte(v)
	case []byte:
		r = v
	default:
		return "", ErrEncoding
	}
	return base64.StdEncoding.EncodeToString(r), nil
}

func decode(s string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(s)
}
<|endoftext|>


<commit_before>// jwx contains tools that deal with the various JWx technologies such as
// JWT, JWS, JWE, etc in Go.
//
// The primary focus of this library tool set is to implement the extremely
// flexible OAuth2 / OpenID Connect protocols. There are many other libraries
// out there that deal with all or parts of these JWx technologies:
//
//    https://github.com/square/go-jose
//	  https://github.com/coreos/oidc
//    https://golang.org/x/oauth2
//
package jwx<commit_msg>Tweak docs<commit_after>// Package jwx contains tools that deal with the various JWx technologies such as
// JWT, JWS, JWE, etc in Go.
//
//    JWA (https://tools.ietf.org/html/rfc7518)
//    JWE (https://tools.ietf.org/html/rfc7516)
//    JWK (https://tools.ietf.org/html/rfc7517)
//    JWS (https://tools.ietf.org/html/rfc7515)
//
// The primary focus of this library tool set is to implement the extremely
// flexible OAuth2 / OpenID Connect protocols. There are many other libraries
// out there that deal with all or parts of these JWx technologies:
//
//    https://github.com/square/go-jose
//    https://github.com/coreos/oidc
//    https://golang.org/x/oauth2
//
package jwx<|endoftext|>


<commit_before>// Package gpio implements a timer/counter unit.
// Tested compatibility:
//   ATmega48/88/168
// Untested compatability:
//   ATtiny4/5/9/10
package timer

import (
    "fmt"
    "github.com/kierdavis/avr/clock"
    "github.com/kierdavis/avr/emulator"
    "github.com/kierdavis/avr/hardware/gpio"
    "log"
)

// TODO: for a OSCx output, require corresponding DDR bit to be set to output

// TODO: writing to TCNT prevents a compare match on the next clock

// TODO: thread-safety!!

type Timer struct {
    digit uint
    controlA uint8
    controlB uint8
    count uint8
    compareValA uint8
    compareValB uint8
    interruptMask uint8
    interruptFlags uint8
    downwards bool // count direction
    ocPinStates [2]bool
    ocPinCallbacks [2]func(bool)
    logging bool
}

func New(digit uint) (t *Timer) {
    return &Timer{
        digit: digit,
    }
}

func (t *Timer) SetLogging(enabled bool) {
    t.logging = enabled
}

func (t *Timer) AddTo(em *emulator.Emulator) {
    em.RegisterPortByName(fmt.Sprintf("TCCR%dA", t.digit), tccra{t})
    em.RegisterPortByName(fmt.Sprintf("TCCR%dB", t.digit), tccrb{t})
    em.RegisterPortByName(fmt.Sprintf("TCNT%d", t.digit), tcnt{t})
    em.RegisterPortByName(fmt.Sprintf("OCR%dA", t.digit), ocra{t})
    em.RegisterPortByName(fmt.Sprintf("OCR%dB", t.digit), ocrb{t})
    em.RegisterPortByName(fmt.Sprintf("TIMSK%d", t.digit), timsk{t})
    em.RegisterPortByName(fmt.Sprintf("TIFR%d", t.digit), tifr{t})
}

// Connect an output-compare pin to a GPIO port by calling the GPIO's
// OverrideOutput method.
func (t *Timer) OverrideOCPin(ocPinNum uint, gpioPinNum uint, g *gpio.GPIO) {
    t.ocPinCallbacks[ocPinNum] = g.OverrideOutput(gpioPinNum)
}

// Run the timer off the specified clock.
func (t *Timer) Run(clk clock.Clock) {
    // TODO: implement clock source selector again

    for {
        now := clk.Now()
        t.Tick()
        clk.Await(now + 1)
    }
}

// Note: in PWM modes, OCRA/OCRB do not exhibit a newly written value until the count overflows

// TODO: in PC-PWM mode, an OCRx bit may transition without a compare match for two reasons (see datasheet page 98)

// Tick the timer.
func (t *Timer) Tick() {
    // Get the waveform generation mode bits
    wgmA := t.controlA & 0x03 // bits 1 and 0
    wgmB := (t.controlB & 0x08) >> 1 // bit 3 (shifted to bit 2)
    wgm := wgmB | wgmA

    // Prepare to tick counter
    switch wgm {
    case 0: // Normal
        t.tickNormalMode()
    case 1: // Phase-correct PWM (TOP = 0xFF)
        t.tickPCPWMMode(0xFF)
    case 2: // Clear timer on compare
        t.tickCTCMode()
    case 3: // Fast PWM (TOP = 0xFF)
        t.tickFastPWMMode(0xFF)
    case 5: // Phase-correct PWM (TOP = OCRA)
        t.tickPCPWMMode(t.compareValA)
    case 7: // Fast PWM (TOP = OCRA)
        t.tickPCPWMMode(t.compareValA)
    }

    // Actually tick the counter
    if t.downwards {
        t.count--
    } else {
        t.count++
    }

    /*
    if t.logging {
        log.Printf("[avr/hardware/timer:(*Timer).tick] ticked, count is now $%02X", t.count)
    }
    */
}

// Tick the timer in Normal mode.
func (t *Timer) tickNormalMode() {
    t.downwards = false
    if t.count == 0xFF { // Overflow
        t.interruptFlags |= 0x01 // set TOVx bit
    }

    t.checkOCPinNormalMode(0, t.compareValA)
    t.checkOCPinNormalMode(1, t.compareValB)
}

// Check for output-compare in normal mode.
func (t *Timer) checkOCPinNormalMode(ocPinNum uint, compareVal uint8) {
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // toggle OCy
            t.toggleOCPin(ocPinNum)
        case 2: // clear OCy
            t.clearOCPin(ocPinNum)
        case 3: // set OCy
            t.setOCPin(ocPinNum)
        }
    }
}

// Tick the timer in phase-corrected PWM mode.
func (t *Timer) tickPCPWMMode(top uint8) {
    if t.downwards {
        if t.count - 1 == 0x00 { // Reached BOTTOM
            t.downwards = false // Begin counting upwards
        }
    } else {
        if t.count + 1 == top { // Reached TOP
            t.downwards = true // Begin counting downwards
        }
    }

    t.checkOCPinPCPWMMode(0, t.compareValA)
    t.checkOCPinPCPWMMode(1, t.compareValB)
}

// TODO: there is a special case in the OC pin checking for both PWM modes when OCRy == TOP and COMxy1 is set (see datasheet page 101)

// Check for output-compare in phase-corrected PWM mode.
func (t *Timer) checkOCPinPCPWMMode(ocPinNum uint, compareVal uint8) {
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy (only on OC pin 0 with WGM2 bit set)
            if ocPinNum == 0 && (t.controlB & 0x80) != 0 {
                t.toggleOCPin(ocPinNum)
            }
        case 2: // Clear OCy if counting upwards or set OCy if counting downwards
            if t.downwards {
                t.setOCPin(ocPinNum)
            } else {
                t.clearOCPin(ocPinNum)
            }
        case 3: // Set OCy if counting upwards or clear OCy if counting downwards
            if t.downwards {
                t.clearOCPin(ocPinNum)
            } else {
                t.setOCPin(ocPinNum)
            }
        }
    }
}

// Tick the timer in clear-timer-on-compare mode.
func (t *Timer) tickCTCMode() {
    t.downwards = false
    if t.count == t.compareValA {
        // this tick should set counter to 0
        t.count = 0xFF
    }
}

// Tick the timer in fast PWM mode.
func (t *Timer) tickFastPWMMode(top uint8) {
    t.downwards = false
    if t.count == top {
        // this tick should set counter to 0
        t.count = 0xFF
    }

    t.checkOCPinFastPWMMode(0, t.compareValA)
    t.checkOCPinFastPWMMode(1, t.compareValB)
}

// Check for output-compare in fast PWM mode.
func (t *Timer) checkOCPinFastPWMMode(ocPinNum uint, compareVal uint8) {
    // BOTTOM
    if t.count == 0x00 {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy on compare match (only on OC pin 0 with WGM2 bit set)
            // do nothing
        case 2: // Clear OCy on compare match, set OCy at BOTTOM
            t.setOCPin(ocPinNum)
        case 3: // Set OCy on compare match, clear OCy at BOTTOM
            t.clearOCPin(ocPinNum)
        }
    }

    // Compare match
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy on compare match (only on OC pin 0 with WGM2 bit set)
            if ocPinNum == 0 && (t.controlB & 0x80) != 0 {
                t.toggleOCPin(ocPinNum)
            }
        case 2: // Clear OCy on compare match, set OCy at BOTTOM
            t.clearOCPin(ocPinNum)
        case 3: // Set OCy on compare match, clear OCy at BOTTOM
            t.setOCPin(ocPinNum)
        }
    }
}

// Toggle an output-compare pin.
func (t *Timer) toggleOCPin(ocPinNum uint) {
    t.ocPinStates[ocPinNum] = !t.ocPinStates[ocPinNum]
    t.updateOCPin(ocPinNum)
}

// Set an output-compare pin to low.
func (t *Timer) clearOCPin(ocPinNum uint) {
    if t.ocPinStates[ocPinNum] {
        t.ocPinStates[ocPinNum] = false
        t.updateOCPin(ocPinNum)
    }
}

// Set an output-compare pin to high.
func (t *Timer) setOCPin(ocPinNum uint) {
    if !t.ocPinStates[ocPinNum] {
        t.ocPinStates[ocPinNum] = true
        t.updateOCPin(ocPinNum)
    }
}

// Push the new status of an output-compare pin to the GPIO layer.
func (t *Timer) updateOCPin(ocPinNum uint) {
    callback := t.ocPinCallbacks[ocPinNum]
    if callback != nil {
        callback(t.ocPinStates[ocPinNum])
    }
}

// Implementation of TCCRxA port
type tccra struct {
    t *Timer
}

func (p tccra) Read() uint8 {
    return p.t.controlA
}

func (p tccra) Write(x uint8) {
    if p.t.logging {
        log.Printf("[avr/hardware/timer:tccra.Write] $%02X (%08b) written to TCCRxA", x, x)
    }
    p.t.controlA = x
}

// Implementation of TCCRxB port
type tccrb struct {
    t *Timer
}

func (p tccrb) Read() uint8 {
    return p.t.controlB
}

func (p tccrb) Write(x uint8) {
    if p.t.logging {
        log.Printf("[avr/hardware/timer:tccrb.Write] $%02X (%08b) written to TCCRxB", x, x)
    }
    p.t.controlB = x
}

// Implementation of TCNTx port
type tcnt struct {
    t *Timer
}

func (p tcnt) Read() uint8 {
    return p.t.count
}

func (p tcnt) Write(x uint8) {
    p.t.count = x
}

// Implementation of OCRxA port
type ocra struct {
    t *Timer
}

func (p ocra) Read() uint8 {
    return p.t.compareValA
}

func (p ocra) Write(x uint8) {
    p.t.compareValA = x
}

// Implementation of OCRxb port
type ocrb struct {
    t *Timer
}

func (p ocrb) Read() uint8 {
    return p.t.compareValB
}

func (p ocrb) Write(x uint8) {
    p.t.compareValB = x
}

// Implementation of TIMSKx port
type timsk struct {
    t *Timer
}

func (p timsk) Read() uint8 {
    return p.t.interruptMask
}

func (p timsk) Write(x uint8) {
    p.t.interruptMask = x
}

// Implementation of TIFRx port
type tifr struct {
    t *Timer
}

func (p tifr) Read() uint8 {
    return p.t.interruptFlags
}

func (p tifr) Write(x uint8) {
    p.t.interruptFlags = x
}
<commit_msg>Fix PC-PWM timer mode changing count direction at slightly the wrong time<commit_after>// Package gpio implements a timer/counter unit.
// Tested compatibility:
//   ATmega48/88/168
// Untested compatability:
//   ATtiny4/5/9/10
package timer

import (
    "fmt"
    "github.com/kierdavis/avr/clock"
    "github.com/kierdavis/avr/emulator"
    "github.com/kierdavis/avr/hardware/gpio"
    "log"
)

// TODO: for a OSCx output, require corresponding DDR bit to be set to output

// TODO: writing to TCNT prevents a compare match on the next clock

// TODO: thread-safety!!

type Timer struct {
    digit uint
    controlA uint8
    controlB uint8
    count uint8
    compareValA uint8
    compareValB uint8
    interruptMask uint8
    interruptFlags uint8
    downwards bool // count direction
    ocPinStates [2]bool
    ocPinCallbacks [2]func(bool)
    logging bool
}

func New(digit uint) (t *Timer) {
    return &Timer{
        digit: digit,
    }
}

func (t *Timer) SetLogging(enabled bool) {
    t.logging = enabled
}

func (t *Timer) AddTo(em *emulator.Emulator) {
    em.RegisterPortByName(fmt.Sprintf("TCCR%dA", t.digit), tccra{t})
    em.RegisterPortByName(fmt.Sprintf("TCCR%dB", t.digit), tccrb{t})
    em.RegisterPortByName(fmt.Sprintf("TCNT%d", t.digit), tcnt{t})
    em.RegisterPortByName(fmt.Sprintf("OCR%dA", t.digit), ocra{t})
    em.RegisterPortByName(fmt.Sprintf("OCR%dB", t.digit), ocrb{t})
    em.RegisterPortByName(fmt.Sprintf("TIMSK%d", t.digit), timsk{t})
    em.RegisterPortByName(fmt.Sprintf("TIFR%d", t.digit), tifr{t})
}

// Connect an output-compare pin to a GPIO port by calling the GPIO's
// OverrideOutput method.
func (t *Timer) OverrideOCPin(ocPinNum uint, gpioPinNum uint, g *gpio.GPIO) {
    t.ocPinCallbacks[ocPinNum] = g.OverrideOutput(gpioPinNum)
}

// Run the timer off the specified clock.
func (t *Timer) Run(clk clock.Clock) {
    // TODO: implement clock source selector again

    for {
        now := clk.Now()
        t.Tick()
        clk.Await(now + 1)
    }
}

// Note: in PWM modes, OCRA/OCRB do not exhibit a newly written value until the count overflows

// TODO: in PC-PWM mode, an OCRx bit may transition without a compare match for two reasons (see datasheet page 98)

// Tick the timer.
func (t *Timer) Tick() {
    // Get the waveform generation mode bits
    wgmA := t.controlA & 0x03 // bits 1 and 0
    wgmB := (t.controlB & 0x08) >> 1 // bit 3 (shifted to bit 2)
    wgm := wgmB | wgmA

    // Prepare to tick counter
    switch wgm {
    case 0: // Normal
        t.tickNormalMode()
    case 1: // Phase-correct PWM (TOP = 0xFF)
        t.tickPCPWMMode(0xFF)
    case 2: // Clear timer on compare
        t.tickCTCMode()
    case 3: // Fast PWM (TOP = 0xFF)
        t.tickFastPWMMode(0xFF)
    case 5: // Phase-correct PWM (TOP = OCRA)
        t.tickPCPWMMode(t.compareValA)
    case 7: // Fast PWM (TOP = OCRA)
        t.tickPCPWMMode(t.compareValA)
    }

    // Actually tick the counter
    if t.downwards {
        t.count--
    } else {
        t.count++
    }

    /*
    if t.logging {
        log.Printf("[avr/hardware/timer:(*Timer).tick] ticked, count is now $%02X", t.count)
    }
    */
}

// Tick the timer in Normal mode.
func (t *Timer) tickNormalMode() {
    t.downwards = false
    if t.count == 0xFF { // Overflow
        t.interruptFlags |= 0x01 // set TOVx bit
    }

    t.checkOCPinNormalMode(0, t.compareValA)
    t.checkOCPinNormalMode(1, t.compareValB)
}

// Check for output-compare in normal mode.
func (t *Timer) checkOCPinNormalMode(ocPinNum uint, compareVal uint8) {
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // toggle OCy
            t.toggleOCPin(ocPinNum)
        case 2: // clear OCy
            t.clearOCPin(ocPinNum)
        case 3: // set OCy
            t.setOCPin(ocPinNum)
        }
    }
}

// Tick the timer in phase-corrected PWM mode.
func (t *Timer) tickPCPWMMode(top uint8) {
    if t.downwards {
        if t.count == 0x00 { // Reached BOTTOM
            t.downwards = false // Begin counting upwards
        }
    } else {
        if t.count == top { // Reached TOP
            t.downwards = true // Begin counting downwards
        }
    }

    t.checkOCPinPCPWMMode(0, t.compareValA)
    t.checkOCPinPCPWMMode(1, t.compareValB)
}

// TODO: there is a special case in the OC pin checking for both PWM modes when OCRy == TOP and COMxy1 is set (see datasheet page 101)

// Check for output-compare in phase-corrected PWM mode.
func (t *Timer) checkOCPinPCPWMMode(ocPinNum uint, compareVal uint8) {
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy (only on OC pin 0 with WGM2 bit set)
            if ocPinNum == 0 && (t.controlB & 0x80) != 0 {
                t.toggleOCPin(ocPinNum)
            }
        case 2: // Clear OCy if counting upwards or set OCy if counting downwards
            if t.downwards {
                t.setOCPin(ocPinNum)
            } else {
                t.clearOCPin(ocPinNum)
            }
        case 3: // Set OCy if counting upwards or clear OCy if counting downwards
            if t.downwards {
                t.clearOCPin(ocPinNum)
            } else {
                t.setOCPin(ocPinNum)
            }
        }
    }
}

// Tick the timer in clear-timer-on-compare mode.
func (t *Timer) tickCTCMode() {
    t.downwards = false
    if t.count == t.compareValA {
        // this tick should set counter to 0
        t.count = 0xFF
    }
}

// Tick the timer in fast PWM mode.
func (t *Timer) tickFastPWMMode(top uint8) {
    t.downwards = false
    if t.count == top {
        // this tick should set counter to 0
        t.count = 0xFF
    }

    t.checkOCPinFastPWMMode(0, t.compareValA)
    t.checkOCPinFastPWMMode(1, t.compareValB)
}

// Check for output-compare in fast PWM mode.
func (t *Timer) checkOCPinFastPWMMode(ocPinNum uint, compareVal uint8) {
    // BOTTOM
    if t.count == 0x00 {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy on compare match (only on OC pin 0 with WGM2 bit set)
            // do nothing
        case 2: // Clear OCy on compare match, set OCy at BOTTOM
            t.setOCPin(ocPinNum)
        case 3: // Set OCy on compare match, clear OCy at BOTTOM
            t.clearOCPin(ocPinNum)
        }
    }

    // Compare match
    if t.count == compareVal {
        // Get COMxy bits
        shiftAmt := 6 - 2*ocPinNum // 0 => 6, 1 => 4
        com := (t.controlA >> shiftAmt) & 0x03
        switch com {
        case 0: // OCy disabled
            // do nothing
        case 1: // Toggle OCy on compare match (only on OC pin 0 with WGM2 bit set)
            if ocPinNum == 0 && (t.controlB & 0x80) != 0 {
                t.toggleOCPin(ocPinNum)
            }
        case 2: // Clear OCy on compare match, set OCy at BOTTOM
            t.clearOCPin(ocPinNum)
        case 3: // Set OCy on compare match, clear OCy at BOTTOM
            t.setOCPin(ocPinNum)
        }
    }
}

// Toggle an output-compare pin.
func (t *Timer) toggleOCPin(ocPinNum uint) {
    t.ocPinStates[ocPinNum] = !t.ocPinStates[ocPinNum]
    t.updateOCPin(ocPinNum)
}

// Set an output-compare pin to low.
func (t *Timer) clearOCPin(ocPinNum uint) {
    if t.ocPinStates[ocPinNum] {
        t.ocPinStates[ocPinNum] = false
        t.updateOCPin(ocPinNum)
    }
}

// Set an output-compare pin to high.
func (t *Timer) setOCPin(ocPinNum uint) {
    if !t.ocPinStates[ocPinNum] {
        t.ocPinStates[ocPinNum] = true
        t.updateOCPin(ocPinNum)
    }
}

// Push the new status of an output-compare pin to the GPIO layer.
func (t *Timer) updateOCPin(ocPinNum uint) {
    callback := t.ocPinCallbacks[ocPinNum]
    if callback != nil {
        callback(t.ocPinStates[ocPinNum])
    }
}

// Implementation of TCCRxA port
type tccra struct {
    t *Timer
}

func (p tccra) Read() uint8 {
    return p.t.controlA
}

func (p tccra) Write(x uint8) {
    if p.t.logging {
        log.Printf("[avr/hardware/timer:tccra.Write] $%02X (%08b) written to TCCRxA", x, x)
    }
    p.t.controlA = x
}

// Implementation of TCCRxB port
type tccrb struct {
    t *Timer
}

func (p tccrb) Read() uint8 {
    return p.t.controlB
}

func (p tccrb) Write(x uint8) {
    if p.t.logging {
        log.Printf("[avr/hardware/timer:tccrb.Write] $%02X (%08b) written to TCCRxB", x, x)
    }
    p.t.controlB = x
}

// Implementation of TCNTx port
type tcnt struct {
    t *Timer
}

func (p tcnt) Read() uint8 {
    return p.t.count
}

func (p tcnt) Write(x uint8) {
    p.t.count = x
}

// Implementation of OCRxA port
type ocra struct {
    t *Timer
}

func (p ocra) Read() uint8 {
    return p.t.compareValA
}

func (p ocra) Write(x uint8) {
    p.t.compareValA = x
}

// Implementation of OCRxb port
type ocrb struct {
    t *Timer
}

func (p ocrb) Read() uint8 {
    return p.t.compareValB
}

func (p ocrb) Write(x uint8) {
    p.t.compareValB = x
}

// Implementation of TIMSKx port
type timsk struct {
    t *Timer
}

func (p timsk) Read() uint8 {
    return p.t.interruptMask
}

func (p timsk) Write(x uint8) {
    p.t.interruptMask = x
}

// Implementation of TIFRx port
type tifr struct {
    t *Timer
}

func (p tifr) Read() uint8 {
    return p.t.interruptFlags
}

func (p tifr) Write(x uint8) {
    p.t.interruptFlags = x
}
<|endoftext|>


<commit_before>package jwthelper

import (
	"io/ioutil"

	"github.com/northbright/pathhelper"
)

// ReadKey reads the key file on disk into a buffer.
func ReadKey(keyFile string) ([]byte, error) {
	var buf []byte

	// Make Abs key file path with current executable path if KeyFilePath is relative.
	p, err := pathhelper.GetAbsPath(keyFile)
	if err != nil {
		return []byte{}, err
	}

	if buf, err = ioutil.ReadFile(p); err != nil {
		return []byte{}, err
	}

	return buf, nil
}
<commit_msg>Remove ReadKey()<commit_after><|endoftext|>


<commit_before>package cmd

import (
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/sirupsen/logrus"

	"github.com/pkg/errors"

	"github.com/gobuffalo/buffalo/generators/newapp"
	"github.com/gobuffalo/buffalo/meta"
	"github.com/gobuffalo/envy"
	"github.com/gobuffalo/makr"
	"github.com/gobuffalo/plush"
	"github.com/spf13/cobra"
)

var rootPath string

var app = newapp.Generator{
	App:        meta.New("."),
	DBType:     "postgres",
	CIProvider: "none",
	AsWeb:      true,
	Docker:     "multi",
	VCS:        "git",
	Bootstrap:  3,
}

var newCmd = &cobra.Command{
	Use:   "new [name]",
	Short: "Creates a new Buffalo application",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) <= 0 {
			return errors.New("you must enter a name for your new application")
		}

		app.Name = meta.Name(args[0])
		app.Version = Version

		if app.Name == "." {
			app.Name = meta.Name(filepath.Base(app.Root))
		} else {
			app.Root = filepath.Join(app.Root, app.Name.File())
		}
		aa := meta.New(app.Root)
		app.ActionsPkg = aa.ActionsPkg
		app.GriftsPkg = aa.GriftsPkg
		app.ModelsPkg = aa.ModelsPkg
		app.PackagePkg = aa.PackagePkg

		if err := app.Validate(); err != nil {
			if errors.Cause(err) == newapp.ErrNotInGoPath {
				return notInGoPath(app)
			}
			return errors.WithStack(err)
		}

		app.WithPop = !app.SkipPop
		app.WithWebpack = !app.SkipWebpack
		app.WithYarn = !app.SkipYarn
		app.AsWeb = !app.AsAPI

		if err := app.Run(app.Root, makr.Data{}); err != nil {
			return errors.WithStack(err)
		}

		logrus.Infof("Congratulations! Your application, %s, has been successfully built!\n\n", app.Name)
		logrus.Infof("You can find your new application at:\n%v", app.Root)
		logrus.Info("\nPlease read the README.md file in your new application for next steps on running your application.")

		return nil
	},
}

func currentUser() (string, error) {
	if _, err := exec.LookPath("git"); err == nil {
		if b, err := exec.Command("git", "config", "github.user").Output(); err != nil {
			return string(b), nil
		}
	}
	u, err := user.Current()
	if err != nil {
		return "", err
	}
	username := u.Username
	if t := strings.Split(username, `\`); len(t) > 0 {
		username = t[len(t)-1]
	}
	return username, nil
}

func notInGoPath(ag newapp.Generator) error {
	username, err := currentUser()
	if err != nil {
		return errors.WithStack(err)
	}
	pwd, _ := os.Getwd()
	t, err := plush.Render(notInGoWorkspace, plush.NewContextWith(map[string]interface{}{
		"name":     ag.Name,
		"gopath":   envy.GoPath(),
		"current":  pwd,
		"username": username,
	}))
	if err != nil {
		return err
	}
	logrus.Error(t)
	os.Exit(-1)
	return nil
}

func init() {
	pwd, _ := os.Getwd()

	app.App = meta.New(pwd)

	decorate("new", newCmd)
	RootCmd.AddCommand(newCmd)
	newCmd.Flags().BoolVar(&app.AsAPI, "api", false, "skip all front-end code and configure for an API server")
	newCmd.Flags().BoolVarP(&app.Force, "force", "f", false, "delete and remake if the app already exists")
	newCmd.Flags().BoolVarP(&app.Verbose, "verbose", "v", false, "verbosely print out the go get commands")
	newCmd.Flags().BoolVar(&app.SkipPop, "skip-pop", false, "skips adding pop/soda to your app")
	newCmd.Flags().BoolVar(&app.WithDep, "with-dep", false, "adds github.com/golang/dep to your app")
	newCmd.Flags().BoolVar(&app.SkipWebpack, "skip-webpack", false, "skips adding Webpack to your app")
	newCmd.Flags().BoolVar(&app.SkipYarn, "skip-yarn", false, "use npm instead of yarn for frontend dependencies management")
	newCmd.Flags().StringVar(&app.DBType, "db-type", "postgres", "specify the type of database you want to use [postgres, mysql, sqlite3, cockroach]")
	newCmd.Flags().StringVar(&app.Docker, "docker", "multi", "specify the type of Docker file to generate [none, multi, standard]")
	newCmd.Flags().StringVar(&app.CIProvider, "ci-provider", "none", "specify the type of ci file you would like buffalo to generate [none, travis, gitlab-ci]")
	newCmd.Flags().StringVar(&app.VCS, "vcs", "git", "specify the Version control system you would like to use [none, git, bzr]")
	newCmd.Flags().IntVar(&app.Bootstrap, "bootstrap", app.Bootstrap, "specify version for Bootstrap [3, 4]")
}

const notInGoWorkspace = `Oops! It would appear that you are not in your Go Workspace.

Your $GOPATH is set to "<%= gopath %>".

You are currently in "<%= current %>".

The standard location for putting Go projects is something along the lines of "$GOPATH/src/github.com/<%= username %>/<%= name %>" (adjust accordingly).

We recommend you go to "$GOPATH/src/github.com/<%= username %>/" and try "buffalo new <%= name %>" again.`
<commit_msg>generating a new app as API should turn off Webpack automatically<commit_after>package cmd

import (
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/sirupsen/logrus"

	"github.com/pkg/errors"

	"github.com/gobuffalo/buffalo/generators/newapp"
	"github.com/gobuffalo/buffalo/meta"
	"github.com/gobuffalo/envy"
	"github.com/gobuffalo/makr"
	"github.com/gobuffalo/plush"
	"github.com/spf13/cobra"
)

var rootPath string

var app = newapp.Generator{
	App:        meta.New("."),
	DBType:     "postgres",
	CIProvider: "none",
	AsWeb:      true,
	Docker:     "multi",
	VCS:        "git",
	Bootstrap:  3,
}

var newCmd = &cobra.Command{
	Use:   "new [name]",
	Short: "Creates a new Buffalo application",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) <= 0 {
			return errors.New("you must enter a name for your new application")
		}

		app.Name = meta.Name(args[0])
		app.Version = Version

		if app.Name == "." {
			app.Name = meta.Name(filepath.Base(app.Root))
		} else {
			app.Root = filepath.Join(app.Root, app.Name.File())
		}
		aa := meta.New(app.Root)
		app.ActionsPkg = aa.ActionsPkg
		app.GriftsPkg = aa.GriftsPkg
		app.ModelsPkg = aa.ModelsPkg
		app.PackagePkg = aa.PackagePkg

		if err := app.Validate(); err != nil {
			if errors.Cause(err) == newapp.ErrNotInGoPath {
				return notInGoPath(app)
			}
			return errors.WithStack(err)
		}

		app.WithPop = !app.SkipPop
		app.WithWebpack = !app.SkipWebpack
		app.WithYarn = !app.SkipYarn
		app.AsWeb = !app.AsAPI
		if app.AsAPI {
			app.WithWebpack = false
		}

		if err := app.Run(app.Root, makr.Data{}); err != nil {
			return errors.WithStack(err)
		}

		logrus.Infof("Congratulations! Your application, %s, has been successfully built!\n\n", app.Name)
		logrus.Infof("You can find your new application at:\n%v", app.Root)
		logrus.Info("\nPlease read the README.md file in your new application for next steps on running your application.")

		return nil
	},
}

func currentUser() (string, error) {
	if _, err := exec.LookPath("git"); err == nil {
		if b, err := exec.Command("git", "config", "github.user").Output(); err != nil {
			return string(b), nil
		}
	}
	u, err := user.Current()
	if err != nil {
		return "", err
	}
	username := u.Username
	if t := strings.Split(username, `\`); len(t) > 0 {
		username = t[len(t)-1]
	}
	return username, nil
}

func notInGoPath(ag newapp.Generator) error {
	username, err := currentUser()
	if err != nil {
		return errors.WithStack(err)
	}
	pwd, _ := os.Getwd()
	t, err := plush.Render(notInGoWorkspace, plush.NewContextWith(map[string]interface{}{
		"name":     ag.Name,
		"gopath":   envy.GoPath(),
		"current":  pwd,
		"username": username,
	}))
	if err != nil {
		return err
	}
	logrus.Error(t)
	os.Exit(-1)
	return nil
}

func init() {
	pwd, _ := os.Getwd()

	app.App = meta.New(pwd)

	decorate("new", newCmd)
	RootCmd.AddCommand(newCmd)
	newCmd.Flags().BoolVar(&app.AsAPI, "api", false, "skip all front-end code and configure for an API server")
	newCmd.Flags().BoolVarP(&app.Force, "force", "f", false, "delete and remake if the app already exists")
	newCmd.Flags().BoolVarP(&app.Verbose, "verbose", "v", false, "verbosely print out the go get commands")
	newCmd.Flags().BoolVar(&app.SkipPop, "skip-pop", false, "skips adding pop/soda to your app")
	newCmd.Flags().BoolVar(&app.WithDep, "with-dep", false, "adds github.com/golang/dep to your app")
	newCmd.Flags().BoolVar(&app.SkipWebpack, "skip-webpack", false, "skips adding Webpack to your app")
	newCmd.Flags().BoolVar(&app.SkipYarn, "skip-yarn", false, "use npm instead of yarn for frontend dependencies management")
	newCmd.Flags().StringVar(&app.DBType, "db-type", "postgres", "specify the type of database you want to use [postgres, mysql, sqlite3, cockroach]")
	newCmd.Flags().StringVar(&app.Docker, "docker", "multi", "specify the type of Docker file to generate [none, multi, standard]")
	newCmd.Flags().StringVar(&app.CIProvider, "ci-provider", "none", "specify the type of ci file you would like buffalo to generate [none, travis, gitlab-ci]")
	newCmd.Flags().StringVar(&app.VCS, "vcs", "git", "specify the Version control system you would like to use [none, git, bzr]")
	newCmd.Flags().IntVar(&app.Bootstrap, "bootstrap", app.Bootstrap, "specify version for Bootstrap [3, 4]")
}

const notInGoWorkspace = `Oops! It would appear that you are not in your Go Workspace.

Your $GOPATH is set to "<%= gopath %>".

You are currently in "<%= current %>".

The standard location for putting Go projects is something along the lines of "$GOPATH/src/github.com/<%= username %>/<%= name %>" (adjust accordingly).

We recommend you go to "$GOPATH/src/github.com/<%= username %>/" and try "buffalo new <%= name %>" again.`
<|endoftext|>