<commit_before>// Package files is for storing files on the cozy, including binary ones like
// photos and movies. The range of possible operations with this endpoint goes
// from simple ones, like uploading a file, to more complex ones, like renaming
// a folder. It also ensure that an instance is not exceeding its quota, and
// keeps a trash to recover files recently deleted.
package files

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strings"

	"github.com/cozy/cozy-stack/web/jsonapi"
	"github.com/cozy/cozy-stack/web/middlewares"
	"github.com/gin-gonic/gin"
	"github.com/spf13/afero"
)

// DefaultContentType is used for files uploaded with no content-type
const DefaultContentType = "application/octet-stream"

// DocType is the type of document, eg. file or folder
type DocType string

const (
	// FileDocType is document type
	FileDocType DocType = "io.cozy.files"
	// FolderDocType is document type
	FolderDocType = "io.cozy.folders"
)

var (
	errDocAlreadyExists = errors.New("Directory already exists")
	errDocTypeInvalid   = errors.New("Invalid document type")
	errIllegalFilename  = errors.New("Invalid filename: empty or contains one of these illegal characters: / \\ : ? * \" |")
)

var regFileName = regexp.MustCompile("[\\/\\\\:\\?\\*\"|]+")

// DocMetadata encapsulates the few metadata linked to a document
// creation request.
type DocMetadata struct {
	Type       DocType
	Name       string
	FolderID   string
	Executable bool
	Tags       []string
}

func (metadata *DocMetadata) path() string {
	return metadata.FolderID + "/" + metadata.Name
}

// NewDocMetadata is the DocMetadata constructor. All inputs are
// validated and if wrong, an error is returned.
func NewDocMetadata(docTypeStr, name, folderID, tagsStr string, executable bool) (*DocMetadata, error) {
	docType, err := parseDocType(docTypeStr)
	if err != nil {
		return nil, err
	}

	if err = checkFileName(name); err != nil {
		return nil, err
	}

	// FolderID is not mandatory. If empty, the document is at the root
	// of the FS
	if folderID != "" {
		if err = checkFileName(folderID); err != nil {
			return nil, err
		}
	}

	tags := parseTags(tagsStr)

	return &DocMetadata{
		Type:       docType,
		Name:       name,
		FolderID:   folderID,
		Tags:       tags,
		Executable: executable,
	}, nil
}

// Upload is the method for uploading a file
//
// This will be used to upload a file
// @TODO
func Upload(metadata *DocMetadata, storage afero.Fs, body io.ReadCloser) error {
	if metadata.Type != FileDocType {
		return errDocTypeInvalid
	}

	path := metadata.path()

	defer body.Close()
	return afero.SafeWriteReader(storage, path, body)
}

// CreateDirectory is the method for creating a new directory
//
// @TODO
func CreateDirectory(metadata *DocMetadata, storage afero.Fs) error {
	if metadata.Type != FolderDocType {
		return errDocTypeInvalid
	}

	path := metadata.path()

	exists, err := afero.DirExists(storage, path)
	if err != nil {
		return err
	}
	if exists {
		return errDocAlreadyExists
	}

	return storage.Mkdir(path, 0777)
}

// CreationHandler handle all POST requests on /files/:folder-id
// aiming at creating a new document in the FS. Given the Type
// parameter of the request, it will either upload a new file or
// create a new directory.
//
// swagger:route POST /files/:folder-id files uploadFileOrCreateDir
func CreationHandler(c *gin.Context) {
	instance := middlewares.GetInstance(c)
	storage, err := instance.GetStorageProvider()
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	metadata, err := NewDocMetadata(
		c.Query("Type"),
		c.Query("Name"),
		c.Param("folder-id"),
		c.Query("Tags"),
		c.Query("Executable") == "true",
	)

	if err != nil {
		c.AbortWithError(http.StatusUnprocessableEntity, err)
		return
	}

	contentType := c.ContentType()
	if contentType == "" {
		contentType = DefaultContentType
	}

	exists, err := checkParentFolderID(storage, metadata.FolderID)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}
	if !exists {
		err = fmt.Errorf("Parent folder with given FolderID does not exist")
		c.AbortWithError(http.StatusNotFound, err)
		return
	}

	fmt.Printf("%s:\n\t- %+v\n\t- %v\n", metadata.Name, metadata, contentType)

	switch metadata.Type {
	case FileDocType:
		err = Upload(metadata, storage, c.Request.Body)
	case FolderDocType:
		err = CreateDirectory(metadata, storage)
	}

	if err != nil {
		var code int
		switch err {
		case errDocAlreadyExists:
			code = http.StatusConflict
		default:
			code = http.StatusInternalServerError
		}
		c.AbortWithError(code, err)
		return
	}

	data := []byte{'O', 'K'}
	c.Data(http.StatusCreated, jsonapi.ContentType, data)
}

// Routes sets the routing for the files service
func Routes(router *gin.RouterGroup) {
	router.POST("/", CreationHandler)
	router.POST("/:folder-id", CreationHandler)
}

func parseTags(str string) []string {
	var tags []string
	for _, tag := range strings.Split(str, ",") {
		// @TODO: more sanitization maybe ?
		tag = strings.TrimSpace(tag)
		if tag != "" {
			tags = append(tags, tag)
		}
	}
	return tags
}

func parseDocType(docType string) (DocType, error) {
	var result DocType
	var err error
	switch docType {
	case "io.cozy.files":
		result = FileDocType
	case "io.cozy.folders":
		result = FolderDocType
	default:
		err = errDocTypeInvalid
	}
	return result, err
}

func checkFileName(str string) error {
	if str == "" || regFileName.MatchString(str) {
		return errIllegalFilename
	}
	return nil
}

func checkParentFolderID(storage afero.Fs, folderID string) (bool, error) {
	if folderID == "" {
		return true, nil
	}

	exists, err := afero.DirExists(storage, folderID)
	if err != nil {
		return false, err
	}
	if !exists {
		return false, nil
	}

	return true, nil
}
<commit_msg>Extract error code selector<commit_after>// Package files is for storing files on the cozy, including binary ones like
// photos and movies. The range of possible operations with this endpoint goes
// from simple ones, like uploading a file, to more complex ones, like renaming
// a folder. It also ensure that an instance is not exceeding its quota, and
// keeps a trash to recover files recently deleted.
package files

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strings"

	"github.com/cozy/cozy-stack/web/jsonapi"
	"github.com/cozy/cozy-stack/web/middlewares"
	"github.com/gin-gonic/gin"
	"github.com/spf13/afero"
)

// DefaultContentType is used for files uploaded with no content-type
const DefaultContentType = "application/octet-stream"

// DocType is the type of document, eg. file or folder
type DocType string

const (
	// FileDocType is document type
	FileDocType DocType = "io.cozy.files"
	// FolderDocType is document type
	FolderDocType = "io.cozy.folders"
)

var (
	errDocAlreadyExists = errors.New("Directory already exists")
	errDocTypeInvalid   = errors.New("Invalid document type")
	errIllegalFilename  = errors.New("Invalid filename: empty or contains one of these illegal characters: / \\ : ? * \" |")
)

var regFileName = regexp.MustCompile("[\\/\\\\:\\?\\*\"|]+")

// DocMetadata encapsulates the few metadata linked to a document
// creation request.
type DocMetadata struct {
	Type       DocType
	Name       string
	FolderID   string
	Executable bool
	Tags       []string
}

func (metadata *DocMetadata) path() string {
	return metadata.FolderID + "/" + metadata.Name
}

// NewDocMetadata is the DocMetadata constructor. All inputs are
// validated and if wrong, an error is returned.
func NewDocMetadata(docTypeStr, name, folderID, tagsStr string, executable bool) (*DocMetadata, error) {
	docType, err := parseDocType(docTypeStr)
	if err != nil {
		return nil, err
	}

	if err = checkFileName(name); err != nil {
		return nil, err
	}

	// FolderID is not mandatory. If empty, the document is at the root
	// of the FS
	if folderID != "" {
		if err = checkFileName(folderID); err != nil {
			return nil, err
		}
	}

	tags := parseTags(tagsStr)

	return &DocMetadata{
		Type:       docType,
		Name:       name,
		FolderID:   folderID,
		Tags:       tags,
		Executable: executable,
	}, nil
}

// Upload is the method for uploading a file
//
// This will be used to upload a file
// @TODO
func Upload(metadata *DocMetadata, storage afero.Fs, body io.ReadCloser) error {
	if metadata.Type != FileDocType {
		return errDocTypeInvalid
	}

	path := metadata.path()

	defer body.Close()
	return afero.SafeWriteReader(storage, path, body)
}

// CreateDirectory is the method for creating a new directory
//
// @TODO
func CreateDirectory(metadata *DocMetadata, storage afero.Fs) error {
	if metadata.Type != FolderDocType {
		return errDocTypeInvalid
	}

	path := metadata.path()

	exists, err := afero.DirExists(storage, path)
	if err != nil {
		return err
	}
	if exists {
		return errDocAlreadyExists
	}

	return storage.Mkdir(path, 0777)
}

// CreationHandler handle all POST requests on /files/:folder-id
// aiming at creating a new document in the FS. Given the Type
// parameter of the request, it will either upload a new file or
// create a new directory.
//
// swagger:route POST /files/:folder-id files uploadFileOrCreateDir
func CreationHandler(c *gin.Context) {
	instance := middlewares.GetInstance(c)
	storage, err := instance.GetStorageProvider()
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	metadata, err := NewDocMetadata(
		c.Query("Type"),
		c.Query("Name"),
		c.Param("folder-id"),
		c.Query("Tags"),
		c.Query("Executable") == "true",
	)

	if err != nil {
		c.AbortWithError(http.StatusUnprocessableEntity, err)
		return
	}

	contentType := c.ContentType()
	if contentType == "" {
		contentType = DefaultContentType
	}

	exists, err := checkParentFolderID(storage, metadata.FolderID)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}
	if !exists {
		err = fmt.Errorf("Parent folder with given FolderID does not exist")
		c.AbortWithError(http.StatusNotFound, err)
		return
	}

	fmt.Printf("%s:\n\t- %+v\n\t- %v\n", metadata.Name, metadata, contentType)

	switch metadata.Type {
	case FileDocType:
		err = Upload(metadata, storage, c.Request.Body)
	case FolderDocType:
		err = CreateDirectory(metadata, storage)
	}

	if err != nil {
		c.AbortWithError(makeCode(err), err)
		return
	}

	data := []byte{'O', 'K'}
	c.Data(http.StatusCreated, jsonapi.ContentType, data)
}

// Routes sets the routing for the files service
func Routes(router *gin.RouterGroup) {
	router.POST("/", CreationHandler)
	router.POST("/:folder-id", CreationHandler)
}

func makeCode(err error) (code int) {
	switch err {
	case errDocAlreadyExists:
		code = http.StatusConflict
	default:
		code = http.StatusInternalServerError
	}
	return
}

func parseTags(str string) []string {
	var tags []string
	for _, tag := range strings.Split(str, ",") {
		// @TODO: more sanitization maybe ?
		tag = strings.TrimSpace(tag)
		if tag != "" {
			tags = append(tags, tag)
		}
	}
	return tags
}

func parseDocType(docType string) (DocType, error) {
	var result DocType
	var err error
	switch docType {
	case "io.cozy.files":
		result = FileDocType
	case "io.cozy.folders":
		result = FolderDocType
	default:
		err = errDocTypeInvalid
	}
	return result, err
}

func checkFileName(str string) error {
	if str == "" || regFileName.MatchString(str) {
		return errIllegalFilename
	}
	return nil
}

func checkParentFolderID(storage afero.Fs, folderID string) (bool, error) {
	if folderID == "" {
		return true, nil
	}

	exists, err := afero.DirExists(storage, folderID)
	if err != nil {
		return false, err
	}
	if !exists {
		return false, nil
	}

	return true, nil
}
<|endoftext|>


<commit_before>// Copyright (c) Ilia Kravets, 2015. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package cmd

import (
	"encoding/binary"
	"hash/crc32"
	"io"
	"log"
	"os"

	"github.com/jessevdk/go-flags"
	"my/errs"

	"my/itto/verify/anal"
	"my/itto/verify/efhsim"
	"my/itto/verify/rec"
)

type cmdEfhsim struct {
	InputFileName           string `long:"input" short:"i" required:"y" value-name:"PCAP_FILE" description:"input pcap file to read"`
	OutputFileNameSimOrders string `long:"output-sim-orders" value-name:"FILE" description:"output file for hw simulator"`
	OutputFileNameSimQuotes string `long:"output-sim-quotes" value-name:"FILE" description:"output file for hw simulator"`
	OutputFileNameEfhOrders string `long:"output-efh-orders" value-name:"FILE" description:"output file for EFH order messages"`
	OutputFileNameEfhQuotes string `long:"output-efh-quotes" value-name:"FILE" description:"output file for EFH quote messages"`
	OutputFileNameAvt       string `long:"output-avt" value-name:"FILE" description:"output file for AVT CSV"`
	InputFileNameAvtDict    string `long:"avt-dict" value-name:"DICT" description:"read dictionary for AVT CSV output"`
	OutputDirStats          string `long:"output-stats" value-name:"DIR" description:"output dir for stats"`
	PacketNumLimit          int    `long:"count" short:"c" value-name:"NUM" description:"limit number of input packets"`
	shouldExecute           bool
	outFiles                []io.Closer
}

func (c *cmdEfhsim) Execute(args []string) error {
	c.shouldExecute = true
	return nil
}

func (c *cmdEfhsim) ConfigParser(parser *flags.Parser) {
	_, err := parser.AddCommand("efhsim", "simulate efh", "", c)
	if err != nil {
		log.Fatalln(err)
	}
}

func (c *cmdEfhsim) ParsingFinished() {
	if !c.shouldExecute {
		return
	}
	defer func() {
		for _, f := range c.outFiles {
			f.Close()
		}
	}()
	efh := efhsim.NewEfhSim()
	efh.SetInput(c.InputFileName, c.PacketNumLimit)
	c.addOut(c.OutputFileNameSimOrders, func(w io.Writer) error {
		logger := rec.NewSimLogger(w)
		logger.SetOutputMode(rec.EfhLoggerOutputOrders)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameSimQuotes, func(w io.Writer) error {
		logger := rec.NewSimLogger(w)
		logger.SetOutputMode(rec.EfhLoggerOutputQuotes)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameEfhOrders, func(w io.Writer) error {
		logger := rec.NewEfhLogger(rec.NewTestefhPrinter(w))
		logger.SetOutputMode(rec.EfhLoggerOutputOrders)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameEfhQuotes, func(w io.Writer) error {
		logger := rec.NewEfhLogger(rec.NewTestefhPrinter(w))
		logger.SetOutputMode(rec.EfhLoggerOutputQuotes)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameAvt, func(w io.Writer) (err error) {
		var dict io.ReadCloser
		if c.InputFileNameAvtDict != "" {
			if dict, err = os.Open(c.InputFileNameAvtDict); err != nil {
				return
			} else {
				c.outFiles = append(c.outFiles, dict)
			}
		}
		return efh.AddLogger(rec.NewAvtLogger(w, dict))
	})

	reporter := c.addAnalyzer(efh)
	errs.CheckE(efh.AnalyzeInput())
	if reporter != nil {
		reporter.SaveAll()
	}
}

func (c *cmdEfhsim) addOut(fileName string, setOut func(io.Writer) error) {
	if fileName == "" {
		return
	}
	file, err := os.Create(fileName)
	if err != nil {
		log.Fatalln(err)
	}
	if err := setOut(file); err != nil {
		file.Close()
		log.Fatalln(err)
	}
	c.outFiles = append(c.outFiles, file)
}
func (c *cmdEfhsim) addAnalyzer(efh *efhsim.EfhSim) *anal.Reporter {
	if c.OutputDirStats == "" {
		return nil
	}
	hashFn := func(v uint64) uint64 {
		data := make([]byte, 8)
		binary.BigEndian.PutUint64(data, v)
		h := crc32.ChecksumIEEE(data)
		return uint64(h & (1<<24 - 1))
	}
	moduloFn := func(v uint64) uint64 {
		return v & (1<<24 - 1)
	}
	analyzer := anal.NewAnalyzer()
	analyzer.AddOrderHashFunction(hashFn)
	analyzer.AddOrderHashFunction(moduloFn)
	efh.AddLogger(analyzer.Observer())
	reporter := anal.NewReporter()
	reporter.SetAnalyzer(analyzer)
	reporter.SetOutputDir(c.OutputDirStats)
	return reporter
}

func init() {
	var c cmdEfhsim
	Registry.Register(&c)
}
<commit_msg>cmd:efhsim: add --subscribe option<commit_after>// Copyright (c) Ilia Kravets, 2015. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package cmd

import (
	"encoding/binary"
	"hash/crc32"
	"io"
	"log"
	"os"

	"github.com/jessevdk/go-flags"
	"my/errs"

	"my/itto/verify/anal"
	"my/itto/verify/efhsim"
	"my/itto/verify/rec"
)

type cmdEfhsim struct {
	InputFileName           string `long:"input" short:"i" required:"y" value-name:"PCAP_FILE" description:"input pcap file to read"`
	SubscriptionFileName    string `long:"subscribe" short:"s" value-name:"SUBSCRIPTION_FILE" description:"read subscriptions from file"`
	OutputFileNameSimOrders string `long:"output-sim-orders" value-name:"FILE" description:"output file for hw simulator"`
	OutputFileNameSimQuotes string `long:"output-sim-quotes" value-name:"FILE" description:"output file for hw simulator"`
	OutputFileNameEfhOrders string `long:"output-efh-orders" value-name:"FILE" description:"output file for EFH order messages"`
	OutputFileNameEfhQuotes string `long:"output-efh-quotes" value-name:"FILE" description:"output file for EFH quote messages"`
	OutputFileNameAvt       string `long:"output-avt" value-name:"FILE" description:"output file for AVT CSV"`
	InputFileNameAvtDict    string `long:"avt-dict" value-name:"DICT" description:"read dictionary for AVT CSV output"`
	OutputDirStats          string `long:"output-stats" value-name:"DIR" description:"output dir for stats"`
	PacketNumLimit          int    `long:"count" short:"c" value-name:"NUM" description:"limit number of input packets"`
	shouldExecute           bool
	outFiles                []io.Closer
}

func (c *cmdEfhsim) Execute(args []string) error {
	c.shouldExecute = true
	return nil
}

func (c *cmdEfhsim) ConfigParser(parser *flags.Parser) {
	_, err := parser.AddCommand("efhsim", "simulate efh", "", c)
	if err != nil {
		log.Fatalln(err)
	}
}

func (c *cmdEfhsim) ParsingFinished() {
	if !c.shouldExecute {
		return
	}
	defer func() {
		for _, f := range c.outFiles {
			f.Close()
		}
	}()
	efh := efhsim.NewEfhSim()
	efh.SetInput(c.InputFileName, c.PacketNumLimit)
	if c.SubscriptionFileName != "" {
		file, err := os.Open(c.SubscriptionFileName)
		errs.CheckE(err)
		errs.CheckE(efh.SubscribeFromReader(file))
		file.Close()
	}
	c.addOut(c.OutputFileNameSimOrders, func(w io.Writer) error {
		logger := rec.NewSimLogger(w)
		logger.SetOutputMode(rec.EfhLoggerOutputOrders)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameSimQuotes, func(w io.Writer) error {
		logger := rec.NewSimLogger(w)
		logger.SetOutputMode(rec.EfhLoggerOutputQuotes)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameEfhOrders, func(w io.Writer) error {
		logger := rec.NewEfhLogger(rec.NewTestefhPrinter(w))
		logger.SetOutputMode(rec.EfhLoggerOutputOrders)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameEfhQuotes, func(w io.Writer) error {
		logger := rec.NewEfhLogger(rec.NewTestefhPrinter(w))
		logger.SetOutputMode(rec.EfhLoggerOutputQuotes)
		return efh.AddLogger(logger)
	})
	c.addOut(c.OutputFileNameAvt, func(w io.Writer) (err error) {
		var dict io.ReadCloser
		if c.InputFileNameAvtDict != "" {
			if dict, err = os.Open(c.InputFileNameAvtDict); err != nil {
				return
			} else {
				c.outFiles = append(c.outFiles, dict)
			}
		}
		return efh.AddLogger(rec.NewAvtLogger(w, dict))
	})

	reporter := c.addAnalyzer(efh)
	errs.CheckE(efh.AnalyzeInput())
	if reporter != nil {
		reporter.SaveAll()
	}
}

func (c *cmdEfhsim) addOut(fileName string, setOut func(io.Writer) error) {
	if fileName == "" {
		return
	}
	file, err := os.Create(fileName)
	if err != nil {
		log.Fatalln(err)
	}
	if err := setOut(file); err != nil {
		file.Close()
		log.Fatalln(err)
	}
	c.outFiles = append(c.outFiles, file)
}
func (c *cmdEfhsim) addAnalyzer(efh *efhsim.EfhSim) *anal.Reporter {
	if c.OutputDirStats == "" {
		return nil
	}
	hashFn := func(v uint64) uint64 {
		data := make([]byte, 8)
		binary.BigEndian.PutUint64(data, v)
		h := crc32.ChecksumIEEE(data)
		return uint64(h & (1<<24 - 1))
	}
	moduloFn := func(v uint64) uint64 {
		return v & (1<<24 - 1)
	}
	analyzer := anal.NewAnalyzer()
	analyzer.AddOrderHashFunction(hashFn)
	analyzer.AddOrderHashFunction(moduloFn)
	efh.AddLogger(analyzer.Observer())
	reporter := anal.NewReporter()
	reporter.SetAnalyzer(analyzer)
	reporter.SetOutputDir(c.OutputDirStats)
	return reporter
}

func init() {
	var c cmdEfhsim
	Registry.Register(&c)
}
<|endoftext|>


<commit_before>package terp

import (
	"bytes"
	. "fmt"
	"log"
)

func White(ch uint8) bool {
	return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'
}

func WhiteOrSemi(ch uint8) bool {
	return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == ';'
}

func (fr *Frame) TEval(a T) (result T) {
	result = MkTs("")  // In case of empty eval.
	log.Printf("< TEval < (%T) ## %#v ## %q\n", a, a, a.String())

	if v, ok := a.(Tl); ok {
		return fr.TApply(v.l)
	}

	rest := a.String()
Loop:
	for {
		var words List
		words, rest = fr.ParseCmd(rest)
		if len(words) == 0 {
			break Loop
		}
		result = fr.TApply(new(words).(Tl).l)
	}
	if len(rest) > 0 {
		panic(Sprintf("TEval: Did not eval entire string: rest=<%q>", rest))
	}
	log.Printf("> TEval > (%T) ## %#v ## %q\n", result, result, result.String())
	return
}

// Parse nested curlies, returning contents and new position
func (fr *Frame) ParseCurly(s string) (result T, rest string) {
	if s[0] != '{' {
		panic("ParseCurly should begin at open curly")
	} // vim: '}'
	n := len(s)
	i := 1

	buf := bytes.NewBuffer(nil)
	c := s[i]
	b := 1 // brace depth
Loop:
	for i < n {
		c = s[i]
		switch c {
		case '{':
			b++
		case '}':
			b--
		}
		if b == 0 {
			break Loop
		}
		buf.WriteByte(c)
		i++
	}
	// vim: '{'
	if c != '}' {
		panic("ParseCurly: missing end curly:" + Repr(c))
	}
	i++

	result = MkTs(buf.String())
	rest = s[i:]
	return
}

// TODO: ParseSquare is too much like Eval.
// Parse Square Bracketed subcommand, returning result and new position
func (fr *Frame) ParseSquare(s string) (result Any, rest string) {
	//- log.Printf("< ParseSquare < %#v\n", s)
	result = "" // In case there are no commands.
	if s[0] != '[' {
		panic("ParseSquare should begin at open square")
	}
	rest = s[1:]

Loop:
	for {
		var words List // OLD LIST TYPE
		words, rest = fr.ParseCmd(rest)
		if len(words) == 0 {
			break Loop
		}
		result = old(fr.TApply(newlist(words)))
	}
	if len(rest) == 0 || rest[0] != ']' {
		panic("ParseSquare: missing end bracket")
	}
	rest = rest[1:]
	//- log.Printf("> ParseSquare > %#v > %q\n", result, rest)
	return
}

func (fr *Frame) ParseQuote(s string) (result Any, rest string) {
	//- log.Printf("< ParseQuote < %#v\n", s)
	if s[0] != '"' {
		panic("ParseQuote should begin at open Quote")
	}
	i := 1
	n := len(s)
	buf := bytes.NewBuffer(nil)
Loop:
	for i < n {
		c := s[i]
		switch c {
		case '[':
			// Mid-word, squares should return stringlike result.
			result, rest := fr.ParseSquare(s[i:])
			buf.WriteString(new(result).String())
			s = rest
			n = len(s)
			i = 0
		case ']':
			panic("ParseQuote: CloseSquareBracket inside Quote")
		case '"':
			i++
			break Loop
		default:
			buf.WriteByte(c)
			i++
		}
	}
	result = buf.String()
	rest = s[i:]
	//- log.Printf("> ParseQuote > %#v > %q\n", result, rest)
	return
}

// Parse a bareword, returning result and new position
func (fr *Frame) ParseWord(s string) (result Any, rest string) {
	//- log.Printf("< ParseWord < %#v\n", s)
	i := 0
	n := len(s)
	buf := bytes.NewBuffer(nil)
Loop:
	for i < n {
		c := s[i]
		switch c {
		case '[':
			// Mid-word, squares should return stringlike result.
			result, rest := fr.ParseSquare(s[i:])
			buf.WriteString(Str(result))
			s = rest
			n = len(s)
			i = 0
		case ']':
			break Loop
		case ' ', '\t', '\n', '\r', ';':
			break Loop
		case '"':
			panic("ParseWord: DoubleQuote inside word")
		default:
			buf.WriteByte(c)
			i++
		}
	}
	result = buf.String()
	rest = s[i:]
	//- log.Printf("> ParseWord > %#v > %q\n", result, rest)
	return
}

// Might return nonempty <rest> if it finds ']'
// Returns next command as List (may be empty) (substituting as needed) and remaining string.
func (fr *Frame) ParseCmd(str string) (z List, s string) {
	s = str
	//- log.Printf("< ParseCmd < %#v\n", s)
	z = make(List, 0, 8)
	var c uint8

	// skip space or ;
	i := 0
	n := len(s)
	for i < n {
		c = s[i]
		if !WhiteOrSemi(s[i]) {
			break
		}
		i++
	}
	s = s[i:]

Loop:
	for len(s) > 0 {
		//- log.Printf("* ParseCmd * TopLoop * z=%#v * s=%q\n", z, s)
		// found non-white
		switch s[0] {
		case ']':
			break Loop
		case '{':
			result, rest := fr.ParseCurly(s)
			z = append(z, old(result))
			s = rest
		case '[':
			result, rest := fr.ParseSquare(s)
			z = append(z, result)
			s = rest
		case '"':
			result, rest := fr.ParseQuote(s)
			z = append(z, result)
			s = rest
		default:
			result, rest := fr.ParseWord(s)
			z = append(z, result)
			s = rest
		}

		// skip white
		//- log.Printf("* ParseCmd * skip white * z=%#v * s=%q\n", z, s)
		n = len(s)
		i = 0
	Skip:
		for i < n {
			switch s[i] {
			case ' ', '\t', '\r':
				i++
				continue Skip
			case ';', '\n':
				break Skip
			default:
				break Skip
			}
		}
		s = s[i:]
		if len(s) == 0 {
			break Loop // end of string
		}
		c = s[0]
		if c == ';' || c == '\n' {
			s = s[1:]  // Omit the semicolon or newline
			break Loop // end of cmd
		}
		//- log.Printf("* ParseCmd * End Loop * z=%#v * s=%q\n", z, s)
	} // End Loop
	//- log.Printf("* ParseCmd * Break Loop * z=%#v * s=%q\n", z, s)

	//- log.Printf("> ParseCmd > %#v > %q\n", z, s)
	return
}

func ParseList(s string) []T {
	n := len(s)
	i := 0
	z := make([]T, 0, 4)

	for i < n {
		var c uint8

		// skip space
		for i < n {
			c = s[i]
			if !White(s[i]) {
				break
			}
			i++
		}
		if i == n {
			break
		}

		buf := bytes.NewBuffer(nil)

		// found non-white
		if c == '{' {
			i++
			c = s[i]
			b := 1
			for i < n {
				c = s[i]
				switch c {
				case '{':
					b++
				case '}':
					b--
				}
				if b == 0 {
					break
				}
				buf.WriteByte(c)
				i++
			}
			if c != '}' {
				panic("ParseList: missing end brace:" + Repr(c))
			}
			i++
		} else {
			for i < n {
				c = s[i]
				if White(s[i]) {
					break
				}
				buf.WriteByte(c)
				i++
			}
		}
		z = append(z, MkTs(buf.String()))
	}
	return z
}
<commit_msg>modernize ParseWord<commit_after>package terp

import (
	"bytes"
	. "fmt"
	"log"
)

func White(ch uint8) bool {
	return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'
}

func WhiteOrSemi(ch uint8) bool {
	return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == ';'
}

func (fr *Frame) TEval(a T) (result T) {
	result = MkTs("")  // In case of empty eval.
	log.Printf("< TEval < (%T) ## %#v ## %q\n", a, a, a.String())

	if v, ok := a.(Tl); ok {
		return fr.TApply(v.l)
	}

	rest := a.String()
Loop:
	for {
		var words List
		words, rest = fr.ParseCmd(rest)
		if len(words) == 0 {
			break Loop
		}
		result = fr.TApply(new(words).(Tl).l)
	}
	if len(rest) > 0 {
		panic(Sprintf("TEval: Did not eval entire string: rest=<%q>", rest))
	}
	log.Printf("> TEval > (%T) ## %#v ## %q\n", result, result, result.String())
	return
}

// Parse nested curlies, returning contents and new position
func (fr *Frame) ParseCurly(s string) (result T, rest string) {
	if s[0] != '{' {
		panic("ParseCurly should begin at open curly")
	} // vim: '}'
	n := len(s)
	i := 1

	buf := bytes.NewBuffer(nil)
	c := s[i]
	b := 1 // brace depth
Loop:
	for i < n {
		c = s[i]
		switch c {
		case '{':
			b++
		case '}':
			b--
		}
		if b == 0 {
			break Loop
		}
		buf.WriteByte(c)
		i++
	}
	// vim: '{'
	if c != '}' {
		panic("ParseCurly: missing end curly:" + Repr(c))
	}
	i++

	result = MkTs(buf.String())
	rest = s[i:]
	return
}

// TODO: ParseSquare is too much like Eval.
// Parse Square Bracketed subcommand, returning result and new position
func (fr *Frame) ParseSquare(s string) (result Any, rest string) {
	//- log.Printf("< ParseSquare < %#v\n", s)
	result = "" // In case there are no commands.
	if s[0] != '[' {
		panic("ParseSquare should begin at open square")
	}
	rest = s[1:]

Loop:
	for {
		var words List // OLD LIST TYPE
		words, rest = fr.ParseCmd(rest)
		if len(words) == 0 {
			break Loop
		}
		result = old(fr.TApply(newlist(words)))
	}
	if len(rest) == 0 || rest[0] != ']' {
		panic("ParseSquare: missing end bracket")
	}
	rest = rest[1:]
	//- log.Printf("> ParseSquare > %#v > %q\n", result, rest)
	return
}

func (fr *Frame) ParseQuote(s string) (result Any, rest string) {
	//- log.Printf("< ParseQuote < %#v\n", s)
	if s[0] != '"' {
		panic("ParseQuote should begin at open Quote")
	}
	i := 1
	n := len(s)
	buf := bytes.NewBuffer(nil)
Loop:
	for i < n {
		c := s[i]
		switch c {
		case '[':
			// Mid-word, squares should return stringlike result.
			result, rest := fr.ParseSquare(s[i:])
			buf.WriteString(new(result).String())
			s = rest
			n = len(s)
			i = 0
		case ']':
			panic("ParseQuote: CloseSquareBracket inside Quote")
		case '"':
			i++
			break Loop
		default:
			buf.WriteByte(c)
			i++
		}
	}
	result = buf.String()
	rest = s[i:]
	//- log.Printf("> ParseQuote > %#v > %q\n", result, rest)
	return
}

// Parse a bareword, returning result and new position
func (fr *Frame) ParseWord(s string) (T, string) {
	//- log.Printf("< ParseWord < %#v\n", s)
	i := 0
	n := len(s)
	buf := bytes.NewBuffer(nil)
Loop:
	for i < n {
		c := s[i]
		switch c {
		case '[':
			// Mid-word, squares should return stringlike result.
			result2, rest2 := fr.ParseSquare(s[i:])
			buf.WriteString(Str(result2))
			s = rest2
			n = len(s)
			i = 0
		case ']':
			break Loop
		case ' ', '\t', '\n', '\r', ';':
			break Loop
		case '"':
			panic("ParseWord: DoubleQuote inside word")
		default:
			buf.WriteByte(c)
			i++
		}
	}
	// result = MkTs(buf.String())
	// rest = s[i:]
	//- log.Printf("> ParseWord > %#v > %q\n", result, rest)
	return MkTs(buf.String()), s[i:]
}

// Might return nonempty <rest> if it finds ']'
// Returns next command as List (may be empty) (substituting as needed) and remaining string.
func (fr *Frame) ParseCmd(str string) (z List, s string) {
	s = str
	//- log.Printf("< ParseCmd < %#v\n", s)
	z = make(List, 0, 8)
	var c uint8

	// skip space or ;
	i := 0
	n := len(s)
	for i < n {
		c = s[i]
		if !WhiteOrSemi(s[i]) {
			break
		}
		i++
	}
	s = s[i:]

Loop:
	for len(s) > 0 {
		//- log.Printf("* ParseCmd * TopLoop * z=%#v * s=%q\n", z, s)
		// found non-white
		switch s[0] {
		case ']':
			break Loop
		case '{':
			newresult, rest := fr.ParseCurly(s)
			z = append(z, old(newresult))
			s = rest
		case '[':
			result, rest := fr.ParseSquare(s)
			z = append(z, result)
			s = rest
		case '"':
			result, rest := fr.ParseQuote(s)
			z = append(z, result)
			s = rest
		default:
			newresult, rest := fr.ParseWord(s)
			z = append(z, old(newresult))
			s = rest
		}

		// skip white
		//- log.Printf("* ParseCmd * skip white * z=%#v * s=%q\n", z, s)
		n = len(s)
		i = 0
	Skip:
		for i < n {
			switch s[i] {
			case ' ', '\t', '\r':
				i++
				continue Skip
			case ';', '\n':
				break Skip
			default:
				break Skip
			}
		}
		s = s[i:]
		if len(s) == 0 {
			break Loop // end of string
		}
		c = s[0]
		if c == ';' || c == '\n' {
			s = s[1:]  // Omit the semicolon or newline
			break Loop // end of cmd
		}
		//- log.Printf("* ParseCmd * End Loop * z=%#v * s=%q\n", z, s)
	} // End Loop
	//- log.Printf("* ParseCmd * Break Loop * z=%#v * s=%q\n", z, s)

	//- log.Printf("> ParseCmd > %#v > %q\n", z, s)
	return
}

func ParseList(s string) []T {
	n := len(s)
	i := 0
	z := make([]T, 0, 4)

	for i < n {
		var c uint8

		// skip space
		for i < n {
			c = s[i]
			if !White(s[i]) {
				break
			}
			i++
		}
		if i == n {
			break
		}

		buf := bytes.NewBuffer(nil)

		// found non-white
		if c == '{' {
			i++
			c = s[i]
			b := 1
			for i < n {
				c = s[i]
				switch c {
				case '{':
					b++
				case '}':
					b--
				}
				if b == 0 {
					break
				}
				buf.WriteByte(c)
				i++
			}
			if c != '}' {
				panic("ParseList: missing end brace:" + Repr(c))
			}
			i++
		} else {
			for i < n {
				c = s[i]
				if White(s[i]) {
					break
				}
				buf.WriteByte(c)
				i++
			}
		}
		z = append(z, MkTs(buf.String()))
	}
	return z
}
<|endoftext|>


<commit_before>package brokers

import (
	"fmt"

	"github.com/eddyzags/kafkactl/api/client"
)

func Stop(api client.APIClient, expr string) error {
	brokers, err := api.BrokerStop(expr)
	if err != nil {
		return err
	}

	if len(brokers) > 1 {
		fmt.Printf("The \"%s\" brokers were stopped successfully\n", expr)
	} else {
		fmt.Printf("The \"%s\" broker was stopped successfully\n", expr)
	}

	return nil
}
<commit_msg>brokers: Parameter added to brokerstop handling function<commit_after>package brokers

import (
	"fmt"

	"github.com/eddyzags/kafkactl/api/client"
)

func Stop(api client.APIClient, expr, timeout string, force bool) error {
	brokers, err := api.BrokerStop(expr, timeout, force)
	if err != nil {
		return err
	}

	if len(brokers) > 1 {
		fmt.Printf("The \"%s\" brokers were stopped successfully\n", expr)
	} else {
		fmt.Printf("The \"%s\" broker was stopped successfully\n", expr)
	}

	return nil
}
<|endoftext|>


<commit_before>package dnsimple

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

type Record struct {
	Id       int
	Name     string
	Content  string
	DomainId int `json:"domain_id"`
}

type recordList struct {
	Record Record
}

type Domain struct {
	Id   int
	Name string
}

type domainWrapper struct {
	Domain Domain
}

type DNSimpleClient struct {
	ApiToken    string
	Email       string
	DomainToken string
	HttpClient  *http.Client
}

func NewClient(apiToken, email string) *DNSimpleClient {
	return &DNSimpleClient{ApiToken: apiToken, Email: email, HttpClient: &http.Client{}}
}

func (client *DNSimpleClient) makeRequest(method, url string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, url, body)
	req.Header.Add("X-DNSimple-Token", fmt.Sprintf("%s:%s", client.Email, client.ApiToken))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")

	if err != nil {
		return nil, err
	}
	return req, nil
}

func (client *DNSimpleClient) sendRequest(method, url string, body io.Reader) (string, error) {
	req, err := client.makeRequest(method, url, body)
	if err != nil {
		return "", err
	}

	resp, err := client.HttpClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(responseBody), nil
}

func (client *DNSimpleClient) Record(domain, name string) (Record, error) {
	reqStr := fmt.Sprintf("https://dnsimple.com/domains/%s/records?name=%s", domain, name)

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return Record{}, err
	}

	var records []recordList

	if err = json.Unmarshal([]byte(body), &records); err != nil {
		return Record{}, err
	}

	return records[0].Record, nil
}

func (client *DNSimpleClient) Domains() ([]Domain, error) {
	reqStr := "https://dnsimple.com/domains"

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return []Domain{}, err
	}

	var domainList []domainWrapper

	if err = json.Unmarshal([]byte(body), &domainList); err != nil {
		return []Domain{}, err
	}

	domains := []Domain{}
	for _, domain := range domainList {
		domains = append(domains, domain.Domain)
	}

	return domains, nil
}

func (client *DNSimpleClient) Domain(domain string) (Domain, error) {
	reqStr := fmt.Sprintf("https://dnsimple.com/domains/%s", domain)

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return Domain{}, err
	}

	wrappedDomain := domainWrapper{}

	if err = json.Unmarshal([]byte(body), &wrappedDomain); err != nil {
		return Domain{}, err
	}
	return wrappedDomain.Domain, nil
}

func (record *Record) UpdateIP(client *DNSimpleClient, IP string) error {
	// lame, but easy enough for now
	jsonPayload := fmt.Sprintf(`{"record": {"content": "%s"}}`, IP)
	url := fmt.Sprintf("https://dnsimple.com/domains/%d/records/%d", record.DomainId, record.Id)

	_, err := client.sendRequest("PUT", url, strings.NewReader(jsonPayload))
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Domain availabililty check<commit_after>package dnsimple

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

type Record struct {
	Id       int
	Name     string
	Content  string
	DomainId int `json:"domain_id"`
}

type recordList struct {
	Record Record
}

type Domain struct {
	Id   int
	Name string
}

type domainWrapper struct {
	Domain Domain
}

type DNSimpleClient struct {
	ApiToken    string
	Email       string
	DomainToken string
	HttpClient  *http.Client
}

func NewClient(apiToken, email string) *DNSimpleClient {
	return &DNSimpleClient{ApiToken: apiToken, Email: email, HttpClient: &http.Client{}}
}

func (client *DNSimpleClient) makeRequest(method, url string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, url, body)
	req.Header.Add("X-DNSimple-Token", fmt.Sprintf("%s:%s", client.Email, client.ApiToken))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")

	if err != nil {
		return nil, err
	}
	return req, nil
}

func (client *DNSimpleClient) sendRequest(method, url string, body io.Reader) (string, error) {
	req, err := client.makeRequest(method, url, body)
	if err != nil {
		return "", err
	}

	resp, err := client.HttpClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(responseBody), nil
}

func (client *DNSimpleClient) Record(domain, name string) (Record, error) {
	reqStr := fmt.Sprintf("https://dnsimple.com/domains/%s/records?name=%s", domain, name)

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return Record{}, err
	}

	var records []recordList

	if err = json.Unmarshal([]byte(body), &records); err != nil {
		return Record{}, err
	}

	return records[0].Record, nil
}

func (client *DNSimpleClient) Domains() ([]Domain, error) {
	reqStr := "https://dnsimple.com/domains"

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return []Domain{}, err
	}

	var domainList []domainWrapper

	if err = json.Unmarshal([]byte(body), &domainList); err != nil {
		return []Domain{}, err
	}

	domains := []Domain{}
	for _, domain := range domainList {
		domains = append(domains, domain.Domain)
	}

	return domains, nil
}

func (client *DNSimpleClient) Domain(domain string) (Domain, error) {
	reqStr := fmt.Sprintf("https://dnsimple.com/domains/%s", domain)

	body, err := client.sendRequest("GET", reqStr, nil)
	if err != nil {
		return Domain{}, err
	}

	wrappedDomain := domainWrapper{}

	if err = json.Unmarshal([]byte(body), &wrappedDomain); err != nil {
		return Domain{}, err
	}
	return wrappedDomain.Domain, nil
}

func (client *DNSimpleClient) DomainAvailable(domain string) (bool, error) {
	reqStr := fmt.Sprintf("https://dnsimple.com/domains/%s/check", domain)

	req, err := client.makeRequest("GET", reqStr, nil)
	if err != nil {
		return false, err
	}

	resp, err := client.HttpClient.Do(req)
	if err != nil {
		return false, err
	}

	return resp.StatusCode == 404, nil
}

func (record *Record) UpdateIP(client *DNSimpleClient, IP string) error {
	// lame, but easy enough for now
	jsonPayload := fmt.Sprintf(`{"record": {"content": "%s"}}`, IP)
	url := fmt.Sprintf("https://dnsimple.com/domains/%d/records/%d", record.DomainId, record.Id)

	_, err := client.sendRequest("PUT", url, strings.NewReader(jsonPayload))
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

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

	"github.com/ae6rt/decap/build-container/locks"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/spf13/cobra"
)

var buildInfo string

var buildStartTime int64
var buildDuration int64
var buildResult int64

var bucketName string
var buildID string
var contentType string
var fileName string
var awsRegion string
var Log *log.Logger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)

var BCToolCmd = &cobra.Command{
	Use:   "bctool",
	Short: "bctool is a multifunction build container tool.",
	Long:  `A multifunction build container tool that unlocks builds, uploads files to S3, and puts items to DynamoDb`,
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of bctool",
	Long:  `All software has versions. This is bctool's`,
	Run: func(cmd *cobra.Command, args []string) {
		Log.Println(buildInfo)
		os.Exit(0)
	},
}

var unlockBuildCmd = &cobra.Command{
	Use:   "unlock",
	Short: "Unlock a build",
	Long:  `Unlock a build`,
	Run: func(cmd *cobra.Command, args []string) {
		locks.Unlock()
	},
}

var putS3Cmd = &cobra.Command{
	Use:   "s3put",
	Short: "put a file to an S3 bucket",
	Long:  `put a file to an S3 bucket`,
	Run: func(cmd *cobra.Command, args []string) {
		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := s3.New(config)
		data, err := ioutil.ReadFile(fileName)
		if err != nil {
			Log.Fatal(err)
		}
		params := &s3.PutObjectInput{
			Bucket:        aws.String(bucketName),
			Key:           aws.String(buildID),
			Body:          bytes.NewReader(data),
			ContentType:   aws.String(contentType),
			ContentLength: aws.Int64(int64(len(data))),
		}
		if _, err := svc.PutObject(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("S3 PUT successful")
		}
	},
}

var buildStartCmd = &cobra.Command{
	Use:   "build-start",
	Short: "mark a build as started in DynamoDb",
	Long:  "mark a build as started in DynamoDb",
	Run: func(cmd *cobra.Command, args []string) {

		projectKey := os.Getenv("PROJECT_KEY")
		buildID := os.Getenv("BUILD_ID")
		branch := os.Getenv("BRANCH_TO_BUILD")

		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := dynamodb.New(config)

		params := &dynamodb.PutItemInput{
			TableName: aws.String("decap-build-metadata"),
			Item: map[string]*dynamodb.AttributeValue{
				"buildID": {
					S: aws.String(buildID),
				},
				"projectKey": {
					S: aws.String(projectKey),
				},
				"buildTime": {
					N: aws.String(fmt.Sprintf("%d", buildStartTime)),
				},
				"branch": {
					S: aws.String(branch),
				},
				"isBuilding": {
					N: aws.String("1"),
				},
			},
		}

		if _, err := svc.PutItem(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("DynamoDb PUT successful")
		}
	},
}

var buildFinishCmd = &cobra.Command{
	Use:   "build-finish",
	Short: "mark a build as finished in DynamoDb",
	Long:  "mark a build as finished in DynamoDb",
	Run: func(cmd *cobra.Command, args []string) {

		buildID := os.Getenv("BUILD_ID")

		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := dynamodb.New(config)

		params := &dynamodb.UpdateItemInput{
			TableName: aws.String("decap-build-metadata"),
			Key: map[string]*dynamodb.AttributeValue{
				"buildID": {
					S: aws.String(buildID),
				},
			},
			UpdateExpression: aws.String("SET buildElapsedTime = :buildDuration, buildResult = :buildResult, isBuilding = :isBuilding"),
			ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
				":buildDuration": {
					N: aws.String(fmt.Sprintf("%d", buildDuration)),
				},
				":buildResult": {
					N: aws.String(fmt.Sprintf("%d", buildResult)),
				},
				":isBuilding": {
					N: aws.String("0"),
				},
			},
		}

		if _, err := svc.UpdateItem(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("DynamoDb PUT successful")
		}
	},
}

func init() {
	putS3Cmd.Flags().StringVarP(&bucketName, "bucket-name", "b", "", "S3 Bucket Name")
	putS3Cmd.Flags().StringVarP(&buildID, "build-id", "i", "", "Build ID")
	putS3Cmd.Flags().StringVarP(&contentType, "content-type", "t", "", "Content Type")
	putS3Cmd.Flags().StringVarP(&fileName, "filename", "f", "", "File Name")
	putS3Cmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")

	buildStartCmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")
	buildStartCmd.Flags().Int64VarP(&buildStartTime, "start-time", "s", 0, "Unix time in seconds since the epoch when the build started")

	buildFinishCmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")
	buildFinishCmd.Flags().Int64VarP(&buildResult, "build-result", "s", 0, "Unix exit code of the executed build")
	buildFinishCmd.Flags().Int64VarP(&buildDuration, "build-duration", "d", 0, "Duration of the build in seconds")

	BCToolCmd.AddCommand(versionCmd)
	BCToolCmd.AddCommand(unlockBuildCmd)
	BCToolCmd.AddCommand(putS3Cmd)
	BCToolCmd.AddCommand(buildStartCmd)
	BCToolCmd.AddCommand(buildFinishCmd)
}

func main() {
	BCToolCmd.Execute()
}
<commit_msg>cleanup<commit_after>package main

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

	"github.com/ae6rt/decap/build-container/locks"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/spf13/cobra"
)

var buildInfo string

var buildStartTime int64
var buildDuration int64
var buildResult int64

var bucketName string
var buildID string
var contentType string
var fileName string
var awsRegion string
var Log *log.Logger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)

var BCToolCmd = &cobra.Command{
	Use:   "bctool",
	Short: "bctool is a multifunction build container tool.",
	Long:  `A multifunction build container tool that unlocks builds, uploads files to S3, and puts items to DynamoDb`,
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of bctool",
	Long:  `All software has versions. This is bctool's`,
	Run: func(cmd *cobra.Command, args []string) {
		Log.Println(buildInfo)
		os.Exit(0)
	},
}

var unlockBuildCmd = &cobra.Command{
	Use:   "unlock",
	Short: "Unlock a build",
	Long:  `Unlock a build`,
	Run: func(cmd *cobra.Command, args []string) {
		locks.Unlock()
	},
}

var putS3Cmd = &cobra.Command{
	Use:   "s3put",
	Short: "put a file to an S3 bucket",
	Long:  `put a file to an S3 bucket`,
	Run: func(cmd *cobra.Command, args []string) {
		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := s3.New(config)
		data, err := ioutil.ReadFile(fileName)
		if err != nil {
			Log.Fatal(err)
		}
		params := &s3.PutObjectInput{
			Bucket:        aws.String(bucketName),
			Key:           aws.String(buildID),
			Body:          bytes.NewReader(data),
			ContentType:   aws.String(contentType),
			ContentLength: aws.Int64(int64(len(data))),
		}
		if _, err := svc.PutObject(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("S3 Put successful")
		}
	},
}

var buildStartCmd = &cobra.Command{
	Use:   "build-start",
	Short: "Mark a build as started in DynamoDb",
	Long:  "Mark a build as started in DynamoDb.  This sets the isBuilding flag and sets the build start time.",
	Run: func(cmd *cobra.Command, args []string) {
		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := dynamodb.New(config)
		params := &dynamodb.PutItemInput{
			TableName: aws.String("decap-build-metadata"),
			Item: map[string]*dynamodb.AttributeValue{
				"buildID": {
					S: aws.String(os.Getenv("BUILD_ID")),
				},
				"projectKey": {
					S: aws.String(os.Getenv("PROJECT_KEY")),
				},
				"buildTime": {
					N: aws.String(fmt.Sprintf("%d", buildStartTime)),
				},
				"branch": {
					S: aws.String(os.Getenv("BRANCH_TO_BUILD")),
				},
				"isBuilding": {
					N: aws.String("1"),
				},
			},
		}
		if _, err := svc.PutItem(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("DynamoDb Put successful")
		}
	},
}

var buildFinishCmd = &cobra.Command{
	Use:   "build-finish",
	Short: "Mark a build as finished in DynamoDb",
	Long:  "Mark a build as finished in DynamoDb.  This clears the isBuilding flag and sets the build result and duration.",
	Run: func(cmd *cobra.Command, args []string) {
		config := aws.NewConfig().WithCredentials(credentials.NewEnvCredentials()).WithRegion(awsRegion).WithMaxRetries(3)
		svc := dynamodb.New(config)
		params := &dynamodb.UpdateItemInput{
			TableName: aws.String("decap-build-metadata"),
			Key: map[string]*dynamodb.AttributeValue{
				"buildID": {
					S: aws.String(os.Getenv("BUILD_ID")),
				},
			},
			UpdateExpression: aws.String("SET buildElapsedTime = :buildDuration, buildResult = :buildResult, isBuilding = :isBuilding"),
			ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
				":buildDuration": {
					N: aws.String(fmt.Sprintf("%d", buildDuration)),
				},
				":buildResult": {
					N: aws.String(fmt.Sprintf("%d", buildResult)),
				},
				":isBuilding": {
					N: aws.String("0"),
				},
			},
		}
		if _, err := svc.UpdateItem(params); err != nil {
			Log.Fatal(err.Error())
		} else {
			Log.Println("DynamoDb Update successful")
		}
	},
}

func init() {
	putS3Cmd.Flags().StringVarP(&bucketName, "bucket-name", "b", "", "S3 Bucket Name")
	putS3Cmd.Flags().StringVarP(&buildID, "build-id", "i", "", "Build ID")
	putS3Cmd.Flags().StringVarP(&contentType, "content-type", "t", "", "Content Type")
	putS3Cmd.Flags().StringVarP(&fileName, "filename", "f", "", "File Name")
	putS3Cmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")

	buildStartCmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")
	buildStartCmd.Flags().Int64VarP(&buildStartTime, "start-time", "s", 0, "Unix time in seconds since the epoch when the build started")

	buildFinishCmd.Flags().StringVarP(&awsRegion, "aws-region", "r", "us-west-1", "AWS Region")
	buildFinishCmd.Flags().Int64VarP(&buildResult, "build-result", "s", 0, "Unix exit code of the executed build")
	buildFinishCmd.Flags().Int64VarP(&buildDuration, "build-duration", "d", 0, "Duration of the build in seconds")

	BCToolCmd.AddCommand(versionCmd)
	BCToolCmd.AddCommand(unlockBuildCmd)
	BCToolCmd.AddCommand(putS3Cmd)
	BCToolCmd.AddCommand(buildStartCmd)
	BCToolCmd.AddCommand(buildFinishCmd)
}

func main() {
	BCToolCmd.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"

	"github.com/codegangsta/cli"
	"github.com/kyokomi/go-gitlab-client/gogitlab"
)

const (
	ProjectIssueUrl = "projects/%d/issues/"
)

var gitlabAppConfig *GitlabCliAppConfig

// Gitlabクライアントを作成する.
func CreateGitlab() (*gogitlab.Gitlab, error) {
	config, err := gitlabAppConfig.ReadGitlabAccessTokenJson()
	if err != nil {
		return nil, err
	}
	flag.Parse()
	return gogitlab.NewGitlab(config.Host, config.ApiPath, config.Token), nil
}

// 対象Projectのissueを作成する.
func PostIssue(gitlab *gogitlab.Gitlab, projectId int, data url.Values) error {
	issue := fmt.Sprintf(ProjectIssueUrl, projectId)
	url := gitlab.ResourceUrl(issue, nil)

	res, err := gitlab.Client.PostForm(url, data)
	if err != nil {
		fmt.Println(url)
		return err
	}
	fmt.Println(res)

	return nil
}

func ShowIssue(gitlab *gogitlab.Gitlab, projectId int, showDetail bool) {
	page := 1
	for {
		issues, err := gitlab.ProjectIssues(projectId, page)
		if err != nil {
			fmt.Println(err)
			break
		}
		if len(issues) == 0 {
			break
		}

		for _, issue := range issues {

			if issue.State != "closed" {
				if showDetail {
					fmt.Printf("[%4d(%d)] %s : [%s] (%s)\n%s\n", issue.Id, issue.LocalId, issue.State, issue.Title, issue.Assignee.Name, issue.Description)
				} else {
					fmt.Printf("[%4d(%d)] %s : [%s] (%s)\n", issue.Id, issue.LocalId, issue.State, issue.Title, issue.Assignee.Name)
				}
			}
		}
		page++
	}
}

// issue create task.
func doCreateIssue(c *cli.Context) {

	gitlab, err := CreateGitlab()
	if err != nil {
		log.Fatal("error create gitlab ")
	}

	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}

	projectId, err := GetProjectId(gitlab, projectName)
	if err != nil {
		log.Fatal("not gitlab projectId ", err)
	}

	PostIssue(gitlab, projectId, url.Values{
		//		"id":           {"1"},
		"title":       {c.String("t")},
		"description": {c.String("d")},
		//		"assignee_id":  {"1"},
		//		"milestone_id": {"1"},
		"labels": {c.String("l")},
	})
}

// project check task.
func doCheckProject(_ *cli.Context) {
	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}
	fmt.Println("projectName = ", projectName)
}

func doShowIssue(c *cli.Context) {
	gitlab, err := CreateGitlab()
	if err != nil {
		log.Fatal("error create gitlab ")
	}

	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}

	projectId, err := GetProjectId(gitlab, projectName)
	if err != nil {
		log.Fatal("not gitlab projectId ", err)
	}

	ShowIssue(gitlab, projectId, c.Bool("detail"))
}

func doInitConfig(c *cli.Context) {

	hostName := c.String("host")
	apiPath := c.String("api-path")
	token := c.String("token")

	config := GitlabAccessConfig{
		Host:    hostName,
		ApiPath: apiPath,
		Token:   token,
	}
	if err := gitlabAppConfig.WriteGitlabAccessConfig(&config); err != nil {
		log.Fatal("appConfig write error ", err)
	}
}

// main.
func main() {

	app := cli.NewApp()
	app.Version = Version
	app.Name = AppName
	app.Usage = "todo:"

	app.Flags = []cli.Flag{
		cli.BoolFlag{"gitlab.skip-cert-check",
			"If set to true, gitlab client will skip certificate checking for https, possibly exposing your system to MITM attack.",
			"GITLAB.SKIP_CERT_CHECK"},
	}

	gitlabAppConfig = NewGitlabCliAppConfig(AppName)

	app.Commands = []cli.Command{
		{
			Name:      "create_issue",
			ShortName: "i",
			Usage:     "project create issue",
			Flags: []cli.Flag{
				cli.StringFlag{"title, t", "", "issue title.", ""},
				cli.StringFlag{"description, d", "", "issue description.", ""},
				cli.StringFlag{"label, l", "", "label example hoge,fuga,piyo.", ""},
			},
			Action: doCreateIssue,
		},
		{
			Name:      "check-project",
			ShortName: "c",
			Usage:     "check project name",
			Action:    doCheckProject,
		},
		{
			Name:      "list-issue",
			ShortName: "l",
			Usage:     "list project issue",
			Action:    doShowIssue,
			Flags: []cli.Flag{
				cli.BoolFlag{"detail, d", "show/hide issue detail.", ""},
			},
		},
		{
			Name:      "init-config",
			ShortName: "init",
			Usage:     "initialize to config",
			Action:    doInitConfig,
			Flags: []cli.Flag{
				cli.StringFlag{"host", "https://gitlab.com/", "host name example [https://gitlab.com/]", ""},
				cli.StringFlag{"api-path", "api/v3/", "api path example [api/v3/]", ""},
				cli.StringFlag{"token", "", "your access token", ""},
			},
		},
	}
	app.Run(os.Args)
}
<commit_msg>refactor: commands<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"

	"github.com/codegangsta/cli"
	"github.com/kyokomi/go-gitlab-client/gogitlab"
)

const (
	ProjectIssueUrl = "projects/%d/issues/"
)

var gitlabAppConfig *GitlabCliAppConfig

// Gitlabクライアントを作成する.
func CreateGitlab() (*gogitlab.Gitlab, error) {
	config, err := gitlabAppConfig.ReadGitlabAccessTokenJson()
	if err != nil {
		return nil, err
	}
	flag.Parse()
	return gogitlab.NewGitlab(config.Host, config.ApiPath, config.Token), nil
}

// 対象Projectのissueを作成する.
func PostIssue(gitlab *gogitlab.Gitlab, projectId int, data url.Values) error {
	issue := fmt.Sprintf(ProjectIssueUrl, projectId)
	url := gitlab.ResourceUrl(issue, nil)

	res, err := gitlab.Client.PostForm(url, data)
	if err != nil {
		fmt.Println(url)
		return err
	}
	fmt.Println(res)

	return nil
}

func ShowIssue(gitlab *gogitlab.Gitlab, projectId int, showDetail bool) {
	page := 1
	for {
		issues, err := gitlab.ProjectIssues(projectId, page)
		if err != nil {
			fmt.Println(err)
			break
		}
		if len(issues) == 0 {
			break
		}

		for _, issue := range issues {

			if issue.State != "closed" {
				if showDetail {
					fmt.Printf("[%4d(%d)] %s : [%s] (%s)\n%s\n", issue.Id, issue.LocalId, issue.State, issue.Title, issue.Assignee.Name, issue.Description)
				} else {
					fmt.Printf("[%4d(%d)] %s : [%s] (%s)\n", issue.Id, issue.LocalId, issue.State, issue.Title, issue.Assignee.Name)
				}
			}
		}
		page++
	}
}

// issue create task.
func doCreateIssue(c *cli.Context) {

	gitlab, err := CreateGitlab()
	if err != nil {
		log.Fatal("error create gitlab ")
	}

	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}

	projectId, err := GetProjectId(gitlab, projectName)
	if err != nil {
		log.Fatal("not gitlab projectId ", err)
	}

	PostIssue(gitlab, projectId, url.Values{
		//		"id":           {"1"},
		"title":       {c.String("t")},
		"description": {c.String("d")},
		//		"assignee_id":  {"1"},
		//		"milestone_id": {"1"},
		"labels": {c.String("l")},
	})
}

// project check task.
func doCheckProject(_ *cli.Context) {
	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}
	fmt.Println("projectName = ", projectName)
}

func doListIssue(_ *cli.Context) {
	gitlab, err := CreateGitlab()
	if err != nil {
		log.Fatal("error create gitlab ")
	}

	projectName, err := GetCurrentDirProjectName()
	if err != nil {
		log.Fatal("not gitlab projectName ", err)
	}

	projectId, err := GetProjectId(gitlab, projectName)
	if err != nil {
		log.Fatal("not gitlab projectId ", err)
	}

	ShowIssue(gitlab, projectId)
}

func doShowIssue(_ *cli.Context) {
	// TODO:
}

func doInitConfig(c *cli.Context) {

	hostName := c.String("host")
	apiPath := c.String("api-path")
	token := c.String("token")

	config := GitlabAccessConfig{
		Host:    hostName,
		ApiPath: apiPath,
		Token:   token,
	}
	if err := gitlabAppConfig.WriteGitlabAccessConfig(&config); err != nil {
		log.Fatal("appConfig write error ", err)
	}
}

// main.
func main() {

	app := cli.NewApp()
	app.Version = Version
	app.Name = AppName
	app.Usage = "todo:"

	app.Flags = []cli.Flag{
		cli.BoolFlag{"gitlab.skip-cert-check",
			"If set to true, gitlab client will skip certificate checking for https, possibly exposing your system to MITM attack.",
			"GITLAB.SKIP_CERT_CHECK"},
	}

	gitlabAppConfig = NewGitlabCliAppConfig(AppName)

	app.Commands = []cli.Command{
		{
			Name:      "add_issue",
			ShortName: "add",
			Usage:     "project create issue",
			Flags: []cli.Flag{
				cli.StringFlag{"title, t", "", "issue title.", ""},
				cli.StringFlag{"description, d", "", "issue description.", ""},
				cli.StringFlag{"label, l", "", "label example hoge,fuga,piyo.", ""},
			},
			Action: doCreateIssue,
		},
		{
			Name:      "check-project",
			ShortName: "check",
			Usage:     "check project name",
			Action:    doCheckProject,
		},
		{
			Name:      "list-issue",
			ShortName: "list",
			Usage:     "list project issue",
			Action:    doListIssue,
		},
		{
			Name:      "issue",
			ShortName: "",
			Usage:     "show project issue",
			Action:    doShowIssue,
		},
		{
			Name:      "init-config",
			ShortName: "init",
			Usage:     "initialize to config",
			Action:    doInitConfig,
			Flags: []cli.Flag{
				cli.StringFlag{"host", "https://gitlab.com/", "host name example [https://gitlab.com/]", ""},
				cli.StringFlag{"api-path", "api/v3/", "api path example [api/v3/]", ""},
				cli.StringFlag{"token", "", "your access token", ""},
			},
		},
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"regexp"
	"testing"
	"time"
)

// These tests can probably be DRY'd up a bunch

func makeRouter() *router {
	return &router{
		routes:   make([]route, 0),
		notFound: parseHandler(http.NotFound),
	}
}

func chHandler(ch chan string, s string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- s
	})
}

var methods = []string{"CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH",
	"POST", "PUT", "TRACE", "OTHER"}

func TestMethods(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Connect("/", chHandler(ch, "CONNECT"))
	rt.Delete("/", chHandler(ch, "DELETE"))
	rt.Head("/", chHandler(ch, "HEAD"))
	rt.Get("/", chHandler(ch, "GET"))
	rt.Options("/", chHandler(ch, "OPTIONS"))
	rt.Patch("/", chHandler(ch, "PATCH"))
	rt.Post("/", chHandler(ch, "POST"))
	rt.Put("/", chHandler(ch, "PUT"))
	rt.Trace("/", chHandler(ch, "TRACE"))
	rt.Handle("/", chHandler(ch, "OTHER"))

	for _, method := range methods {
		r, _ := http.NewRequest(method, "/", nil)
		w := httptest.NewRecorder()
		rt.route(C{}, w, r)
		select {
		case val := <-ch:
			if val != method {
				t.Errorf("Got %q, expected %q", val, method)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for method %q", method)
		}
	}
}

type testPattern struct{}

func (t testPattern) Prefix() string {
	return ""
}

func (t testPattern) Match(r *http.Request, c *C, dryrun bool) bool {
	return true
}

var _ Pattern = testPattern{}

func TestPatternTypes(t *testing.T) {
	t.Parallel()
	rt := makeRouter()

	rt.Get("/hello/carl", http.NotFound)
	rt.Get("/hello/:name", http.NotFound)
	rt.Get(regexp.MustCompile(`^/hello/(?P<name>.+)$`), http.NotFound)
	rt.Get(testPattern{}, http.NotFound)
}

type testHandler chan string

func (t testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	t <- "http"
}
func (t testHandler) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	t <- "httpc"
}

var testHandlerTable = map[string]string{
	"/a": "http fn",
	"/b": "http handler",
	"/c": "web fn",
	"/d": "web handler",
	"/e": "httpc",
}

func TestHandlerTypes(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Get("/a", func(w http.ResponseWriter, r *http.Request) {
		ch <- "http fn"
	})
	rt.Get("/b", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- "http handler"
	}))
	rt.Get("/c", func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web fn"
	})
	rt.Get("/d", HandlerFunc(func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web handler"
	}))
	rt.Get("/e", testHandler(ch))

	for route, response := range testHandlerTable {
		r, _ := http.NewRequest("GET", route, nil)
		w := httptest.NewRecorder()
		rt.route(C{}, w, r)
		select {
		case resp := <-ch:
			if resp != response {
				t.Errorf("Got %q, expected %q", resp, response)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for path %q", route)
		}

	}
}

func TestNotFound(t *testing.T) {
	t.Parallel()
	rt := makeRouter()

	r, _ := http.NewRequest("post", "/", nil)
	w := httptest.NewRecorder()
	rt.route(C{}, w, r)
	if w.Code != 404 {
		t.Errorf("Expected 404, got %d", w.Code)
	}

	rt.NotFound(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "I'm a teapot!", http.StatusTeapot)
	})

	r, _ = http.NewRequest("POST", "/", nil)
	w = httptest.NewRecorder()
	rt.route(C{}, w, r)
	if w.Code != http.StatusTeapot {
		t.Errorf("Expected a teapot, got %d", w.Code)
	}
}

func TestPrefix(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Handle("/hello*", func(w http.ResponseWriter, r *http.Request) {
		ch <- r.URL.Path
	})

	r, _ := http.NewRequest("GET", "/hello/world", nil)
	w := httptest.NewRecorder()
	rt.route(C{}, w, r)
	select {
	case val := <-ch:
		if val != "/hello/world" {
			t.Error("Got %q, expected /hello/world", val)
		}
	case <-time.After(5 * time.Millisecond):
		t.Errorf("Timeout waiting for hello")
	}
}

var validMethodsTable = map[string][]string{
	"/hello/carl":       {"DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"},
	"/hello/bob":        {"DELETE", "GET", "HEAD", "PATCH", "PUT"},
	"/hola/carl":        {"DELETE", "GET", "HEAD", "PUT"},
	"/hola/bob":         {"DELETE"},
	"/does/not/compute": {},
}

func TestValidMethods(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan []string, 1)

	rt.NotFound(func(c C, w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			ch <- []string{}
			return
		}
		methods, ok := c.Env[ValidMethodsKey]
		if !ok {
			ch <- []string{}
			return
		}
		ch <- methods.([]string)
	})

	rt.Get("/hello/carl", http.NotFound)
	rt.Post("/hello/carl", http.NotFound)
	rt.Head("/hello/bob", http.NotFound)
	rt.Get("/hello/:name", http.NotFound)
	rt.Put("/hello/:name", http.NotFound)
	rt.Patch("/hello/:name", http.NotFound)
	rt.Get("/:greet/carl", http.NotFound)
	rt.Put("/:greet/carl", http.NotFound)
	rt.Delete("/:greet/:anyone", http.NotFound)

	for path, eMethods := range validMethodsTable {
		r, _ := http.NewRequest("BOGUS", path, nil)
		rt.route(C{}, httptest.NewRecorder(), r)
		aMethods := <-ch
		if !reflect.DeepEqual(eMethods, aMethods) {
			t.Errorf("For %q, expected %v, got %v", path, eMethods,
				aMethods)
		}
	}
}
<commit_msg>Fix Error => Errorf<commit_after>package web

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"regexp"
	"testing"
	"time"
)

// These tests can probably be DRY'd up a bunch

func makeRouter() *router {
	return &router{
		routes:   make([]route, 0),
		notFound: parseHandler(http.NotFound),
	}
}

func chHandler(ch chan string, s string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- s
	})
}

var methods = []string{"CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH",
	"POST", "PUT", "TRACE", "OTHER"}

func TestMethods(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Connect("/", chHandler(ch, "CONNECT"))
	rt.Delete("/", chHandler(ch, "DELETE"))
	rt.Head("/", chHandler(ch, "HEAD"))
	rt.Get("/", chHandler(ch, "GET"))
	rt.Options("/", chHandler(ch, "OPTIONS"))
	rt.Patch("/", chHandler(ch, "PATCH"))
	rt.Post("/", chHandler(ch, "POST"))
	rt.Put("/", chHandler(ch, "PUT"))
	rt.Trace("/", chHandler(ch, "TRACE"))
	rt.Handle("/", chHandler(ch, "OTHER"))

	for _, method := range methods {
		r, _ := http.NewRequest(method, "/", nil)
		w := httptest.NewRecorder()
		rt.route(C{}, w, r)
		select {
		case val := <-ch:
			if val != method {
				t.Errorf("Got %q, expected %q", val, method)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for method %q", method)
		}
	}
}

type testPattern struct{}

func (t testPattern) Prefix() string {
	return ""
}

func (t testPattern) Match(r *http.Request, c *C, dryrun bool) bool {
	return true
}

var _ Pattern = testPattern{}

func TestPatternTypes(t *testing.T) {
	t.Parallel()
	rt := makeRouter()

	rt.Get("/hello/carl", http.NotFound)
	rt.Get("/hello/:name", http.NotFound)
	rt.Get(regexp.MustCompile(`^/hello/(?P<name>.+)$`), http.NotFound)
	rt.Get(testPattern{}, http.NotFound)
}

type testHandler chan string

func (t testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	t <- "http"
}
func (t testHandler) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	t <- "httpc"
}

var testHandlerTable = map[string]string{
	"/a": "http fn",
	"/b": "http handler",
	"/c": "web fn",
	"/d": "web handler",
	"/e": "httpc",
}

func TestHandlerTypes(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Get("/a", func(w http.ResponseWriter, r *http.Request) {
		ch <- "http fn"
	})
	rt.Get("/b", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- "http handler"
	}))
	rt.Get("/c", func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web fn"
	})
	rt.Get("/d", HandlerFunc(func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web handler"
	}))
	rt.Get("/e", testHandler(ch))

	for route, response := range testHandlerTable {
		r, _ := http.NewRequest("GET", route, nil)
		w := httptest.NewRecorder()
		rt.route(C{}, w, r)
		select {
		case resp := <-ch:
			if resp != response {
				t.Errorf("Got %q, expected %q", resp, response)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for path %q", route)
		}

	}
}

func TestNotFound(t *testing.T) {
	t.Parallel()
	rt := makeRouter()

	r, _ := http.NewRequest("post", "/", nil)
	w := httptest.NewRecorder()
	rt.route(C{}, w, r)
	if w.Code != 404 {
		t.Errorf("Expected 404, got %d", w.Code)
	}

	rt.NotFound(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "I'm a teapot!", http.StatusTeapot)
	})

	r, _ = http.NewRequest("POST", "/", nil)
	w = httptest.NewRecorder()
	rt.route(C{}, w, r)
	if w.Code != http.StatusTeapot {
		t.Errorf("Expected a teapot, got %d", w.Code)
	}
}

func TestPrefix(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan string, 1)

	rt.Handle("/hello*", func(w http.ResponseWriter, r *http.Request) {
		ch <- r.URL.Path
	})

	r, _ := http.NewRequest("GET", "/hello/world", nil)
	w := httptest.NewRecorder()
	rt.route(C{}, w, r)
	select {
	case val := <-ch:
		if val != "/hello/world" {
			t.Errorf("Got %q, expected /hello/world", val)
		}
	case <-time.After(5 * time.Millisecond):
		t.Errorf("Timeout waiting for hello")
	}
}

var validMethodsTable = map[string][]string{
	"/hello/carl":       {"DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"},
	"/hello/bob":        {"DELETE", "GET", "HEAD", "PATCH", "PUT"},
	"/hola/carl":        {"DELETE", "GET", "HEAD", "PUT"},
	"/hola/bob":         {"DELETE"},
	"/does/not/compute": {},
}

func TestValidMethods(t *testing.T) {
	t.Parallel()
	rt := makeRouter()
	ch := make(chan []string, 1)

	rt.NotFound(func(c C, w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			ch <- []string{}
			return
		}
		methods, ok := c.Env[ValidMethodsKey]
		if !ok {
			ch <- []string{}
			return
		}
		ch <- methods.([]string)
	})

	rt.Get("/hello/carl", http.NotFound)
	rt.Post("/hello/carl", http.NotFound)
	rt.Head("/hello/bob", http.NotFound)
	rt.Get("/hello/:name", http.NotFound)
	rt.Put("/hello/:name", http.NotFound)
	rt.Patch("/hello/:name", http.NotFound)
	rt.Get("/:greet/carl", http.NotFound)
	rt.Put("/:greet/carl", http.NotFound)
	rt.Delete("/:greet/:anyone", http.NotFound)

	for path, eMethods := range validMethodsTable {
		r, _ := http.NewRequest("BOGUS", path, nil)
		rt.route(C{}, httptest.NewRecorder(), r)
		aMethods := <-ch
		if !reflect.DeepEqual(eMethods, aMethods) {
			t.Errorf("For %q, expected %v, got %v", path, eMethods,
				aMethods)
		}
	}
}
<|endoftext|>


<commit_before>package smpp34

import (
	"errors"
)

var (
	reqUnbindRespFields = []string{}
)

type UnbindResp struct {
	*Header
	mandatoryFields map[string]Field
	tlvFields       map[uint16]*TLVField
}

func NewUnbindResp(hdr *Header) (*UnbindResp, error) {
	s := &UnbindResp{Header: hdr}

	return s, nil
}

func (s *UnbindResp) GetField(f string) Field {
	return nil
}

func (s *UnbindResp) SetField(f string, v interface{}) error {
	return errors.New("Invalid field value")
}

func (s *UnbindResp) SetSeqNum(i uint32) {
	s.Header.Sequence = i
}

func (s *UnbindResp) SetTLVField(t, l int, v []byte) error {
	return errors.New("Invalid TLV value lenght")
}

func (s *UnbindResp) Fields() map[string]Field {
	return s.mandatoryFields
}

func (s *UnbindResp) MandatoryFieldsList() []string {
	return reqUnbindRespFields
}

func (s *UnbindResp) Ok() bool {
	if s.Header.Status == ESME_ROK {
		return true
	}

	return false
}

func (s *UnbindResp) GetHeader() *Header {
	return s.Header
}

func (s *UnbindResp) TLVFields() map[uint16]*TLVField {
	return s.tlvFields
}

func (s *UnbindResp) writeFields() []byte {
	return []byte{}
}

func (s *UnbindResp) Writer() []byte {
	b := s.writeFields()
	h := packUi32(uint32(len(b) + 16))
	h = append(h, packUi32(ENQUIRE_LINK_RESP)...)
	h = append(h, packUi32(s.Header.Status)...)
	h = append(h, packUi32(s.Header.Sequence)...)
	return append(h, b...)
}
<commit_msg>fixed bug in unbind_resp<commit_after>package smpp34

import (
	"errors"
)

var (
	reqUnbindRespFields = []string{}
)

type UnbindResp struct {
	*Header
	mandatoryFields map[string]Field
	tlvFields       map[uint16]*TLVField
}

func NewUnbindResp(hdr *Header) (*UnbindResp, error) {
	s := &UnbindResp{Header: hdr}

	return s, nil
}

func (s *UnbindResp) GetField(f string) Field {
	return nil
}

func (s *UnbindResp) SetField(f string, v interface{}) error {
	return errors.New("Invalid field value")
}

func (s *UnbindResp) SetSeqNum(i uint32) {
	s.Header.Sequence = i
}

func (s *UnbindResp) SetTLVField(t, l int, v []byte) error {
	return errors.New("Invalid TLV value lenght")
}

func (s *UnbindResp) Fields() map[string]Field {
	return s.mandatoryFields
}

func (s *UnbindResp) MandatoryFieldsList() []string {
	return reqUnbindRespFields
}

func (s *UnbindResp) Ok() bool {
	if s.Header.Status == ESME_ROK {
		return true
	}

	return false
}

func (s *UnbindResp) GetHeader() *Header {
	return s.Header
}

func (s *UnbindResp) TLVFields() map[uint16]*TLVField {
	return s.tlvFields
}

func (s *UnbindResp) writeFields() []byte {
	return []byte{}
}

func (s *UnbindResp) Writer() []byte {
	b := s.writeFields()
	h := packUi32(uint32(len(b) + 16))
	h = append(h, packUi32(s.Header.Id)...)
	h = append(h, packUi32(s.Header.Status)...)
	h = append(h, packUi32(s.Header.Sequence)...)
	return append(h, b...)
}
<|endoftext|>


<commit_before>package permset

import (
	"context"
	"fmt"
)

// Perm is a permission to do some action.
type Perm int

// Permset represents a set of permissions.
type Permset struct {
	permset map[Perm]bool
}

// New receives permissions to contain and returns a permset from it.
func New(perms ...Perm) Permset {
	permset := Permset{permset: make(map[Perm]bool)}
	permset.Add(perms...)
	return permset
}

// Add adds the received perms to the permset.
func (ps *Permset) Add(perms ...Perm) {
	for _, perm := range perms {
		ps.permset[perm] = true
	}
}

// Remove removes the received perms from the permset.
func (ps *Permset) Remove(perms ...Perm) {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			delete(ps.permset, perm)
		}
	}
}

// Perms returns the permissions contained within the permset.
func (ps *Permset) Perms() []Perm {
	var perms []Perm
	for k := range ps.permset {
		perms = append(perms, k)
	}
	return perms
}

// Contains receives single Perm and returns true if the permset contains it.
func (ps *Permset) Contains(perm Perm) bool {
	if _, ok := ps.permset[perm]; !ok {
		return false
	}
	return true
}

// ContainsAll returns true if the permset contains all received Perms.
func (ps *Permset) ContainsAll(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; !ok {
			return false
		}
	}
	return true
}

// ContainsSome returns true if the permset contains any one or more of the received Perms.
func (ps *Permset) ContainsSome(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			return true
		}
	}
	return false
}

// ContainsNone returns true if the permset contains none one of the received Perms.
func (ps *Permset) ContainsNone(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			return false
		}
	}
	return true
}

type permsetKeyType int

const permsetKey permsetKeyType = iota

// NewContext receives perms and returns a context with the received perms are the value of the context.
func NewContext(ctx context.Context, permset Permset) context.Context {
	return context.WithValue(ctx, permsetKey, permset)
}

// FromContext receives a context and returns the permset in it.
func FromContext(ctx context.Context) (Permset, error) {
	permset, ok := ctx.Value(permsetKey).(Permset)
	if !ok {
		return Permset{}, fmt.Errorf("cannot get context value")
	}
	return permset, nil
}
<commit_msg>doc(permset): add package docstring<commit_after>// Package permset provides primitives for permission management.
package permset

import (
	"context"
	"fmt"
)

// Perm is a permission to do some action.
type Perm int

// Permset represents a set of permissions.
type Permset struct {
	permset map[Perm]bool
}

// New receives permissions to contain and returns a permset from it.
func New(perms ...Perm) Permset {
	permset := Permset{permset: make(map[Perm]bool)}
	permset.Add(perms...)
	return permset
}

// Add adds the received perms to the permset.
func (ps *Permset) Add(perms ...Perm) {
	for _, perm := range perms {
		ps.permset[perm] = true
	}
}

// Remove removes the received perms from the permset.
func (ps *Permset) Remove(perms ...Perm) {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			delete(ps.permset, perm)
		}
	}
}

// Perms returns the permissions contained within the permset.
func (ps *Permset) Perms() []Perm {
	var perms []Perm
	for k := range ps.permset {
		perms = append(perms, k)
	}
	return perms
}

// Contains receives single Perm and returns true if the permset contains it.
func (ps *Permset) Contains(perm Perm) bool {
	if _, ok := ps.permset[perm]; !ok {
		return false
	}
	return true
}

// ContainsAll returns true if the permset contains all received Perms.
func (ps *Permset) ContainsAll(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; !ok {
			return false
		}
	}
	return true
}

// ContainsSome returns true if the permset contains any one or more of the received Perms.
func (ps *Permset) ContainsSome(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			return true
		}
	}
	return false
}

// ContainsNone returns true if the permset contains none one of the received Perms.
func (ps *Permset) ContainsNone(perms ...Perm) bool {
	for _, perm := range perms {
		if _, ok := ps.permset[perm]; ok {
			return false
		}
	}
	return true
}

type permsetKeyType int

const permsetKey permsetKeyType = iota

// NewContext receives perms and returns a context with the received perms are the value of the context.
func NewContext(ctx context.Context, permset Permset) context.Context {
	return context.WithValue(ctx, permsetKey, permset)
}

// FromContext receives a context and returns the permset in it.
func FromContext(ctx context.Context) (Permset, error) {
	permset, ok := ctx.Value(permsetKey).(Permset)
	if !ok {
		return Permset{}, fmt.Errorf("cannot get context value")
	}
	return permset, nil
}
<|endoftext|>


<commit_before>// package uroot contains various functions that might be needed more than
// one place.
package uroot

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"syscall"
)

const PATH = "/bin:/buildbin:/usr/local/bin"

type dir struct {
	name string
	mode os.FileMode
}

type dev struct {
	name  string
	mode  os.FileMode
	magic int
	howmany int
}

type mount struct {
	source string
	target string
	fstype string
	flags  uintptr
	opts   string
}

var (
	Envs []string
	env = map[string]string{
		"LD_LIBRARY_PATH": "/usr/local/lib",
		"GOROOT":          "/go",
		"GOPATH":          "/",
		"CGO_ENABLED":     "0",
	}

	dirs = []dir{
		{name: "/proc", mode: os.FileMode(0555)},
		{name: "/buildbin", mode: os.FileMode(0777)},
		{name: "/bin", mode: os.FileMode(0777)},
		{name: "/tmp", mode: os.FileMode(0777)},
		{name: "/env", mode: os.FileMode(0777)},
		{name: "/etc", mode: os.FileMode(0777)},
		{name: "/tcz", mode: os.FileMode(0777)},
		{name: "/dev", mode: os.FileMode(0777)},
		{name: "/lib", mode: os.FileMode(0777)},
		{name: "/usr/lib", mode: os.FileMode(0777)},
		{name: "/go/pkg/linux_amd64", mode: os.FileMode(0777)},
	}
	devs = []dev{
		// chicken and egg: these need to be there before you start. So, sadly,
		// we will always need dev.cpio.
		//{name: "/dev/null", mode: os.FileMode(0660) | 020000, magic: 0x0103},
		//{name: "/dev/console", mode: os.FileMode(0660) | 020000, magic: 0x0501},
	}
	namespace = []mount{
		{source: "proc", target: "/proc", fstype: "proc", flags: syscall.MS_MGC_VAL | syscall.MS_RDONLY, opts: ""},
	}
)

// build the root file system.
func Rootfs() {
	// Pick some reasonable values in the (unlikely!) even that Uname fails.
	uname := "linux"
	mach := "x86_64"
	// There are three possible places for go:
	// The first is in /go/bin/$OS_$ARCH
	// The second is in /go/bin [why they still use this path is anyone's guess]
	// The third is in /go/pkg/tool/$OS_$ARCH
	if u, err := Uname(); err != nil {
		log.Printf("uroot.Utsname fails: %v, so assume %v_%v\n", uname, mach)
	} else {
		// Sadly, go and the OS disagree on case.
		uname = strings.ToLower(u.Sysname)
		mach = strings.ToLower(u.Machine)
		// Yes, we really have to do this stupid thing.
		if mach[0:3] == "arm" {
			mach = "arm"
		}
	}
	env["PATH"] = fmt.Sprintf("/go/bin/%s_%s:/go/bin:/go/pkg/tool/%s_%s:%v", uname, mach, uname, mach, PATH)

	for k, v := range env {
		os.Setenv(k, v)
		Envs = append(Envs, k+"="+v)
	}

	for _, m := range dirs {
		if err := os.MkdirAll(m.name, m.mode); err != nil {
			log.Printf("mkdir :%s: mode %o: %v\n", m.name, m.mode, err)
			continue
		}
	}

	for _, d := range devs {
		syscall.Unlink(d.name)
		if err := syscall.Mknod(d.name, uint32(d.mode), d.magic); err != nil {
			log.Printf("mknod :%s: mode %o: magic: %v: %v\n", d.name, d.mode, d.magic, err)
			continue
		}
	}

	for _, m := range namespace {
		if err := syscall.Mount(m.source, m.target, m.fstype, m.flags, m.opts); err != nil {
			log.Printf("Mount :%s: on :%s: type :%s: flags %x: %v\n", m.source, m.target, m.fstype, m.flags, m.opts, err)
		}

	}

	// only in case of emergency.
	if false {
		if err := filepath.Walk("/", func(name string, fi os.FileInfo, err error) error {
			if err != nil {
				fmt.Printf(" WALK FAIL%v: %v\n", name, err)
				// That's ok, sometimes things are not there.
				return nil
			}
			fmt.Printf("%v\n", name)
			return nil
		}); err != nil {
			log.Printf("WALK fails %v\n", err)
		}
	}
}
<commit_msg>Have the root file system setup write a reasonable resolv.conf<commit_after>// package uroot contains various functions that might be needed more than
// one place.
package uroot

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"syscall"
)

const PATH = "/bin:/buildbin:/usr/local/bin"

// TODO: make this a map so it's easier to find dups.
type dir struct {
	name string
	mode os.FileMode
}

type file struct {
	contents string
	mode os.FileMode
}

// TODO: make this a map so it's easier to find dups.
type dev struct {
	name  string
	mode  os.FileMode
	magic int
	howmany int
}
type mount struct {
	source string
	target string
	fstype string
	flags  uintptr
	opts   string
}

var (
	Envs []string
	env = map[string]string{
		"LD_LIBRARY_PATH": "/usr/local/lib",
		"GOROOT":          "/go",
		"GOPATH":          "/",
		"CGO_ENABLED":     "0",
	}

	dirs = []dir{
		{name: "/proc", mode: os.FileMode(0555)},
		{name: "/buildbin", mode: os.FileMode(0777)},
		{name: "/bin", mode: os.FileMode(0777)},
		{name: "/tmp", mode: os.FileMode(0777)},
		{name: "/env", mode: os.FileMode(0777)},
		{name: "/etc", mode: os.FileMode(0777)},
		{name: "/tcz", mode: os.FileMode(0777)},
		{name: "/dev", mode: os.FileMode(0777)},
		{name: "/lib", mode: os.FileMode(0777)},
		{name: "/usr/lib", mode: os.FileMode(0777)},
		{name: "/go/pkg/linux_amd64", mode: os.FileMode(0777)},
	}
	devs = []dev{
		// chicken and egg: these need to be there before you start. So, sadly,
		// we will always need dev.cpio.
		//{name: "/dev/null", mode: os.FileMode(0660) | 020000, magic: 0x0103},
		//{name: "/dev/console", mode: os.FileMode(0660) | 020000, magic: 0x0501},
	}
	namespace = []mount{
		{source: "proc", target: "/proc", fstype: "proc", flags: syscall.MS_MGC_VAL | syscall.MS_RDONLY, opts: ""},
	}

	files = map[string] file {
		"/etc/resolv.conf": {contents: `nameserver 8.8.8.8`, mode: os.FileMode(0644)},
	}
)

// build the root file system.
func Rootfs() {
	// Pick some reasonable values in the (unlikely!) even that Uname fails.
	uname := "linux"
	mach := "x86_64"
	// There are three possible places for go:
	// The first is in /go/bin/$OS_$ARCH
	// The second is in /go/bin [why they still use this path is anyone's guess]
	// The third is in /go/pkg/tool/$OS_$ARCH
	if u, err := Uname(); err != nil {
		log.Printf("uroot.Utsname fails: %v, so assume %v_%v\n", uname, mach)
	} else {
		// Sadly, go and the OS disagree on case.
		uname = strings.ToLower(u.Sysname)
		mach = strings.ToLower(u.Machine)
		// Yes, we really have to do this stupid thing.
		if mach[0:3] == "arm" {
			mach = "arm"
		}
	}
	env["PATH"] = fmt.Sprintf("/go/bin/%s_%s:/go/bin:/go/pkg/tool/%s_%s:%v", uname, mach, uname, mach, PATH)

	for k, v := range env {
		os.Setenv(k, v)
		Envs = append(Envs, k+"="+v)
	}

	for _, m := range dirs {
		if err := os.MkdirAll(m.name, m.mode); err != nil {
			log.Printf("mkdir :%s: mode %o: %v\n", m.name, m.mode, err)
			continue
		}
	}

	for _, d := range devs {
		syscall.Unlink(d.name)
		if err := syscall.Mknod(d.name, uint32(d.mode), d.magic); err != nil {
			log.Printf("mknod :%s: mode %o: magic: %v: %v\n", d.name, d.mode, d.magic, err)
			continue
		}
	}

	for _, m := range namespace {
		if err := syscall.Mount(m.source, m.target, m.fstype, m.flags, m.opts); err != nil {
			log.Printf("Mount :%s: on :%s: type :%s: flags %x: %v\n", m.source, m.target, m.fstype, m.flags, m.opts, err)
		}

	}

	for name, m := range files {
		if err := ioutil.WriteFile(name, []byte(m.contents), m.mode); err != nil {
			log.Printf("Error writeing %v: %v", name, err)
		}
	}

	// only in case of emergency.
	if false {
		if err := filepath.Walk("/", func(name string, fi os.FileInfo, err error) error {
			if err != nil {
				fmt.Printf(" WALK FAIL%v: %v\n", name, err)
				// That's ok, sometimes things are not there.
				return nil
			}
			fmt.Printf("%v\n", name)
			return nil
		}); err != nil {
			log.Printf("WALK fails %v\n", err)
		}
	}
}
<|endoftext|>


<commit_before>package gmock_test

import (
	. "github.com/cfmobile/gmock"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	kOriginalValue = "original value"
	kMockValue = "mock value"
)

var _ = Describe("GMock", func() {
	var subject *GMock // Test subject

	var constructSubject func()
	var panicked bool

	var someVar string // Target variable to mock in our tests
	var mockValue string // Variable containing the mock value to be set to the target

	BeforeEach(func() { // Reset all base values for each test
		subject = nil
		constructSubject = nil
		panicked = false
		someVar = kOriginalValue
		mockValue = kMockValue
	})

	var panicRecover = func() {
		panicked = recover() != nil
	}

	JustBeforeEach(func() {
		defer panicRecover()
		constructSubject()
	})

	Describe("MockTarget", func() {

		Context("when creating a new GMock with a target", func() {

			Context("and the target is not passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(someVar)
					}
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})

				It("should not have constructed the mock", func() {
				    Expect(subject).To(BeNil())
				})
			})

			Context("and the target is passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(&someVar)
					}
				})

				It("should not panic", func() {
					Expect(panicked).To(BeFalse())
				})

				It("should return a valid GMock object", func() {
					Expect(subject).NotTo(BeNil())
				})

				It("should not have altered the value of the target", func() {
					Expect(someVar).To(Equal(kOriginalValue))
				})

				It("should have backed up the pointer to the original target", func() {
					var originalPtr = subject.GetOriginal().Addr().Interface()
					Expect(originalPtr).To(Equal(&someVar))
				})

				It("should not have a mock value defined by default", func() {
					var mockTargetPtr = subject.GetTarget().Addr().Interface()
					Expect(mockTargetPtr).To(Equal(&someVar))
				})
			})
	    })
	})

	Describe("GMock", func() {

		BeforeEach(func() {
		    constructSubject = func() { // Construct a valid GMock for this set of tests
				subject = CreateMockWithTarget(&someVar)
			}
		})

	    Context("when calling Replace on a GMock object with a valid mock value", func() {

	        JustBeforeEach(func() { // It has to be a JustBeforeEach so that it happens after subject is constructed
	            subject.Replace(mockValue)
	        })

			It("should replace the value in the original var with the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			It("should have retained the original value for restoring later", func() {
				Expect(subject.GetOriginal().Interface()).To(Equal(kOriginalValue))
			})

			It("should have a Target that points to the mock value", func() {
			    Expect(subject.GetTarget().Interface()).To(Equal(mockValue))
			})
	    })

		Context("when calling Replace on a GMock object with an invalid mock value", func() {

			Context("- mock value with a different type", func() {
				invalidMockValue := 21

				JustBeforeEach(func() {
					defer panicRecover()
					subject.Replace(invalidMockValue)
				})

				It("should have panicked", func() {
					Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is nil", func() {
			    JustBeforeEach(func() {
					defer panicRecover()
			        subject.Replace(nil)
			    })

				It("should not have panicked", func() {
				    Expect(panicked).To(BeFalse())
				})

				It("should have assigned a default value of that type to the mock", func() {
				    Expect(someVar).To(Equal(""))
				})
			})
		})
	})

})
<commit_msg>RS - Improved GMock.Replace() tests<commit_after>package gmock_test

import (
	. "github.com/cfmobile/gmock"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	kOriginalValue = "original value"
	kMockValue = "mock value"
)

var _ = Describe("GMock", func() {
	var subject *GMock // Test subject

	var constructSubject func()
	var panicked bool

	var someVar string // Target variable to mock in our tests
	var mockValue string // Variable containing the mock value to be set to the target

	BeforeEach(func() { // Reset all base values for each test
		subject = nil
		constructSubject = nil
		panicked = false
		someVar = kOriginalValue
		mockValue = kMockValue
	})

	var panicRecover = func() {
		panicked = recover() != nil
	}

	JustBeforeEach(func() {
		defer panicRecover()
		constructSubject()
	})

	Describe("MockTarget", func() {

		Context("when creating a new GMock with a target", func() {

			Context("and the target is not passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(someVar)
					}
				})

				It("should panic", func() {
					Expect(panicked).To(BeTrue())
				})

				It("should not have constructed the mock", func() {
				    Expect(subject).To(BeNil())
				})
			})

			Context("and the target is passed as a pointer", func() {
				BeforeEach(func() {
					constructSubject = func() {
						subject = CreateMockWithTarget(&someVar)
					}
				})

				It("should not panic", func() {
					Expect(panicked).To(BeFalse())
				})

				It("should return a valid GMock object", func() {
					Expect(subject).NotTo(BeNil())
				})

				It("should not have altered the value of the target", func() {
					Expect(someVar).To(Equal(kOriginalValue))
				})

				It("should have backed up the pointer to the original target", func() {
					var originalPtr = subject.GetOriginal().Addr().Interface()
					Expect(originalPtr).To(Equal(&someVar))
				})

				It("should not have a mock value defined by default", func() {
					var mockTargetPtr = subject.GetTarget().Addr().Interface()
					Expect(mockTargetPtr).To(Equal(&someVar))
				})
			})
	    })
	})

	Describe("GMock", func() {

		BeforeEach(func() {
		    constructSubject = func() { // Construct a valid GMock for this set of tests
				subject = CreateMockWithTarget(&someVar)
			}
		})

	    Context("when calling Replace on a GMock object with a valid mock value", func() {

	        JustBeforeEach(func() { // It has to be a JustBeforeEach so that it happens after subject is constructed
	            subject.Replace(mockValue)
	        })

			It("should replace the value in the original var with the mock value", func() {
			    Expect(someVar).To(Equal(kMockValue))
			})

			It("should have retained the original value for restoring later", func() {
				Expect(subject.GetOriginal().Interface()).To(Equal(kOriginalValue))
			})

			It("should have a Target that points to the mock value", func() {
			    Expect(subject.GetTarget().Interface()).To(Equal(mockValue))
			})
	    })

		Context("when calling Replace on a GMock object with an invalid mock value", func() {

			It("should not have panicked when creating the mock", func() {
			    Expect(panicked).To(BeFalse())
			})

			Context("- mock value with a different type", func() {
				invalidMockValue := 21

				JustBeforeEach(func() {
					defer panicRecover()
					subject.Replace(invalidMockValue)
				})

				It("should have panicked", func() {
					Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is a pointer to the same type as the target", func() {

				JustBeforeEach(func() {
				    defer panicRecover()
					subject.Replace(&mockValue)
				})

				It("should have panicked", func() {
				    Expect(panicked).To(BeTrue())
				})
			})

			Context("- mock value is nil", func() {
			    JustBeforeEach(func() {
					defer panicRecover()
			        subject.Replace(nil)
			    })

				It("should not have panicked", func() {
				    Expect(panicked).To(BeFalse())
				})

				It("should have assigned a default value of that type to the mock", func() {
				    Expect(someVar).To(Equal(""))
				})
			})
		})
	})

})
<|endoftext|>