<commit_before>package gogitconfig

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os/exec"
	"strings"
	"syscall"
)

type ConfigValue struct {
	key string
}

func New(key string) *ConfigValue {
	return &ConfigValue{key}
}

func (val *ConfigValue) Get() (string, error) {
	return val.execCommand([]string{val.key})
}

func (val *ConfigValue) Set(configValue string) error {
	_, err := val.execCommand([]string{val.key, configValue})
	return err
}

func (val *ConfigValue) Unset() error {
	_, err := val.execCommand([]string{"--unset", val.key})
	return err
}

func (val *ConfigValue) UnsetGlobal() error {
	_, err := val.execCommand([]string{"--global", "--unset", val.key})
	return err
}

func (val *ConfigValue) SetGlobal(configValue string) error {
	_, err := val.execCommand([]string{"--global", val.key, configValue})
	return err
}

func (val *ConfigValue) execCommand(args []string) (string, error) {
	var stdout bytes.Buffer
	cmdArguments := []string{"config"}
	cmdArguments = append(cmdArguments, args...)
	cmd := exec.Command("git", cmdArguments...)
	cmd.Stdout = &stdout
	cmd.Stderr = ioutil.Discard
	err := cmd.Run()
	if exitError, ok := err.(*exec.ExitError); ok {
		if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
			errorCode := waitStatus.ExitStatus()
			switch errorCode {
			case 0:
				{
					break
				}
			case 1:
				{
					return "", errors.New("gogitconfig: the section or key is invalid")
				}
			case 2:
				{
					return "", errors.New("gogitconfig: no section or name was provided")
				}
			case 3:
				{
					return "", errors.New("gogitconfig: the config file is invalid")
				}
			case 4:
				{
					return "", errors.New("gogitconfig: can not write to the config file")
				}
			case 5:
				{
					return "", errors.New("gogitconfig: you try to unset an option which does not exist, or you try to unset/set an option for which multiple lines match. Do you want to use GlobalUnset()?")
				}
			case 6:
				{
					return "", errors.New("gogitconfig: you try to use an invalid regexp")
				}
			default:
				{
					return "", errors.New("gogitconfig: git command returned unknown exit code (" + fmt.Sprintf("%v", errorCode) + ") ")
				}
			}
			if waitStatus.ExitStatus() == 1 {
				return "", errors.New("gogitconfig: key not found")
			} else if waitStatus.ExitStatus() == 5 {

			}
		}
		return "", err
	}
	return strings.TrimRight(stdout.String(), "\n\000"), nil
}

/*

func main() {
	configValue := New("test.value")
	v, err := configValue.Get()
	if err != nil {
		log.Println("error in Get:", err.Error())
		err := configValue.Set("foobar")
		if err != nil {
			log.Println("error in Set:", err.Error())
		}
	} else {
		log.Println("value: ", v)
		err = configValue.Unset()
		if err != nil {
			log.Println("error in Unset:", err.Error())
		}
	}
}

*/
<commit_msg>resolved little issue;<commit_after>package gogitconfig

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os/exec"
	"strings"
	"syscall"
)

type ConfigValue struct {
	key string
}

func New(key string) *ConfigValue {
	return &ConfigValue{key}
}

func (val *ConfigValue) Get() (string, error) {
	return val.execCommand([]string{val.key})
}

func (val *ConfigValue) Set(configValue string) error {
	_, err := val.execCommand([]string{val.key, configValue})
	return err
}

func (val *ConfigValue) Unset() error {
	_, err := val.execCommand([]string{"--unset", val.key})
	return err
}

func (val *ConfigValue) UnsetGlobal() error {
	_, err := val.execCommand([]string{"--global", "--unset", val.key})
	return err
}

func (val *ConfigValue) SetGlobal(configValue string) error {
	_, err := val.execCommand([]string{"--global", val.key, configValue})
	return err
}

func (val *ConfigValue) execCommand(args []string) (string, error) {
	var stdout bytes.Buffer
	cmdArguments := []string{"config"}
	cmdArguments = append(cmdArguments, args...)
	cmd := exec.Command("git", cmdArguments...)
	cmd.Stdout = &stdout
	cmd.Stderr = ioutil.Discard
	err := cmd.Run()
	if exitError, ok := err.(*exec.ExitError); ok {
		if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
			errorCode := waitStatus.ExitStatus()
			switch errorCode {
			case 0:
				{
					break
				}
			case 1:
				{
					return "", errors.New("gogitconfig: the section or key is invalid")
				}
			case 2:
				{
					return "", errors.New("gogitconfig: no section or name was provided")
				}
			case 3:
				{
					return "", errors.New("gogitconfig: the config file is invalid")
				}
			case 4:
				{
					return "", errors.New("gogitconfig: can not write to the config file")
				}
			case 5:
				{
					return "", errors.New("gogitconfig: you try to unset an option which does not exist, or you try to unset/set an option for which multiple lines match. Do you want to use GlobalUnset()?")
				}
			case 6:
				{
					return "", errors.New("gogitconfig: you try to use an invalid regexp")
				}
			default:
				{
					return "", errors.New("gogitconfig: git command returned unknown exit code (" + fmt.Sprintf("%v", errorCode) + ") ")
				}
			}
			if waitStatus.ExitStatus() == 1 {
				return "", errors.New("gogitconfig: key not found")
			} else if waitStatus.ExitStatus() == 5 {

			}
		}
		return "", err
	}
	return strings.TrimRight(stdout.String(), "\n\000"), nil
}

/*

func main() {
	configValue := New("test.value")
	v, err := configValue.Get()
	if err != nil {
		log.Println("error in Get:", err.Error())
		err := configValue.Set("foobar")
		if err != nil {
			log.Println("error in Set:", err.Error())
		}
	} else {
		log.Println("value: ", v)
		err = configValue.Unset()
		if err != nil {
			log.Println("error in Unset:", err.Error())
		}
	}
}

*/
<|endoftext|>


<commit_before>package oiio

/*
#include "stdlib.h"

#include "cpp/color.h"
*/
import "C"
import (
	"errors"
	"runtime"
	"unsafe"
)

// The ColorProcessor encapsulates a baked color transformation, suitable for
// application to raw pixels, or ImageBuf(s). These are generated using
// ColorConfig.CreateColorProcessor, and referenced in ImageBufAlgo
// (amongst other places)
type ColorProcessor struct {
	ptr unsafe.Pointer
}

func newColorProcessor(i unsafe.Pointer) *ColorProcessor {
	in := &ColorProcessor{i}
	runtime.SetFinalizer(in, deleteColorProcessor)
	return in
}

func deleteColorProcessor(i *ColorProcessor) {
	if i.ptr != nil {
		C.deleteColorProcessor(i.ptr)
		i.ptr = nil
	}
}

// Represents the set of all color transformations that are allowed.
// If OpenColorIO is enabled at build time, this configuration is loaded
// at runtime, allowing the user to have complete control of all color
// transformation math. ($OCIO)  (See opencolorio.org for details).
// If OpenColorIO is not enabled at build time, a generic color configuration
// is provided for minimal color support.
//
// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight.
// Their construction / destruction should be kept to a minimum.
type ColorConfig struct {
	ptr unsafe.Pointer
}

func newColorConfig(i unsafe.Pointer) *ColorConfig {
	in := &ColorConfig{i}
	runtime.SetFinalizer(in, deleteColorConfig)
	return in
}

func deleteColorConfig(i *ColorConfig) {
	if i.ptr != nil {
		C.free(i.ptr)
		i.ptr = nil
	}
}

// Return if OpenImageIO was built with OCIO support
func SupportsOpenColorIO() bool {
	return bool(C.supportsOpenColorIO())
}

// If OpenColorIO is enabled at build time, initialize with the current
// color configuration. ($OCIO)
// If OpenColorIO is not enabled, this does nothing.
//
// Multiple calls to this are inexpensive.
func NewColorConfig() (*ColorConfig, error) {
	c := newColorConfig(C.New_ColorConfig())
	return c, c.error()
}

// If OpenColorIO is enabled at build time, initialize with the
// specified color configuration (.ocio) file
// If OpenColorIO is not enabled, this will result in an error.
//
// Multiple calls to this are potentially expensive.
func NewColorConfigPath(path string) (*ColorConfig, error) {
	c_str := C.CString(path)
	defer C.free(unsafe.Pointer(c_str))
	c := newColorConfig(C.New_ColorConfigPath(c_str))
	return c, c.error()
}

// Get the number of ColorSpace(s) defined in this configuration
func (c *ColorConfig) NumColorSpaces() int {
	return int(C.ColorConfig_getNumColorSpaces(c.ptr))
}

// Return the name of the colorspace at a given index
func (c *ColorConfig) ColorSpaceNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getColorSpaceNameByIndex(c.ptr, C.int(index)))
}

// Get the number of Looks defined in this configuration
func (c *ColorConfig) NumLooks() int {
	return int(C.ColorConfig_getNumLooks(c.ptr))
}

// Return the name of the look at a given index
func (c *ColorConfig) LookNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getLookNameByIndex(c.ptr, C.int(index)))
}

// Get the number of displays defined in this configuration
func (c *ColorConfig) NumDisplays() int {
	return int(C.ColorConfig_getNumDisplays(c.ptr))
}

// Return the name of the display at a given index
func (c *ColorConfig) DisplayNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getDisplayNameByIndex(c.ptr, C.int(index)))
}

// Get the number of displays defined in this configuration
func (c *ColorConfig) NumViews(displayName string) int {
	c_str := C.CString(displayName)
	defer C.free(unsafe.Pointer(c_str))
	return int(C.ColorConfig_getNumViews(c.ptr, c_str))
}

// Get the name of a view at a specific index of a display
func (c *ColorConfig) ViewNameByIndex(displayName string, index int) string {
	c_str := C.CString(displayName)
	defer C.free(unsafe.Pointer(c_str))
	return C.GoString(C.ColorConfig_getViewNameByIndex(c.ptr, c_str, C.int(index)))
}

// Get the name of the color space representing the named role,
// or empty string if none could be identified.
func (c *ColorConfig) ColorSpaceNameByRole(role string) string {
	c_str := C.CString(role)
	defer C.free(unsafe.Pointer(c_str))
	return C.GoString(C.ColorConfig_getColorSpaceNameByRole(c.ptr, c_str))
}

// Given the specified input and output ColorSpace, construct the
// processor.  It is possible that this will return nil and an error, if the
// inputColorSpace doesnt exist, the outputColorSpace doesn't
// exist, or if the specified transformation is illegal (for
// example, it may require the inversion of a 3D-LUT, etc).  When
// the user is finished with a ColorProcess, ColorProcess.Destroy()
// should be called.  ColorProcessor(s) remain valid even if the
// ColorConfig that created them no longer exists.
//
// Multiple calls to this are potentially expensive, so you should
// call once to create a ColorProcessor to use on an entire image
// (or multiple images), NOT for every scanline or pixel
// separately!
func (c *ColorConfig) CreateColorProcessor(inColorSpace, outColorSpace string) (*ColorProcessor, error) {
	c_in := C.CString(inColorSpace)
	defer C.free(unsafe.Pointer(c_in))

	c_out := C.CString(outColorSpace)
	defer C.free(unsafe.Pointer(c_out))

	ptr := C.ColorConfig_createColorProcessor(c.ptr, c_in, c_out)
	err := c.error()
	if err != nil {
		return nil, err
	}
	return newColorProcessor(ptr), err
}

// This routine will return the error string (and clear any error
// flags).  If no error has occurred since the last time GetError()
// was called, it will return an empty string.
func (c *ColorConfig) error() error {
	isError := C.ColorConfig_error(c.ptr)
	if C.bool(isError) {
		return errors.New(C.GoString(C.ColorConfig_geterror(c.ptr)))
	}
	return nil
}
<commit_msg>return nil explicitly  for clarity<commit_after>package oiio

/*
#include "stdlib.h"

#include "cpp/color.h"
*/
import "C"
import (
	"errors"
	"runtime"
	"unsafe"
)

// The ColorProcessor encapsulates a baked color transformation, suitable for
// application to raw pixels, or ImageBuf(s). These are generated using
// ColorConfig.CreateColorProcessor, and referenced in ImageBufAlgo
// (amongst other places)
type ColorProcessor struct {
	ptr unsafe.Pointer
}

func newColorProcessor(i unsafe.Pointer) *ColorProcessor {
	in := &ColorProcessor{i}
	runtime.SetFinalizer(in, deleteColorProcessor)
	return in
}

func deleteColorProcessor(i *ColorProcessor) {
	if i.ptr != nil {
		C.deleteColorProcessor(i.ptr)
		i.ptr = nil
	}
}

// Represents the set of all color transformations that are allowed.
// If OpenColorIO is enabled at build time, this configuration is loaded
// at runtime, allowing the user to have complete control of all color
// transformation math. ($OCIO)  (See opencolorio.org for details).
// If OpenColorIO is not enabled at build time, a generic color configuration
// is provided for minimal color support.
//
// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight.
// Their construction / destruction should be kept to a minimum.
type ColorConfig struct {
	ptr unsafe.Pointer
}

func newColorConfig(i unsafe.Pointer) *ColorConfig {
	in := &ColorConfig{i}
	runtime.SetFinalizer(in, deleteColorConfig)
	return in
}

func deleteColorConfig(i *ColorConfig) {
	if i.ptr != nil {
		C.free(i.ptr)
		i.ptr = nil
	}
}

// Return if OpenImageIO was built with OCIO support
func SupportsOpenColorIO() bool {
	return bool(C.supportsOpenColorIO())
}

// If OpenColorIO is enabled at build time, initialize with the current
// color configuration. ($OCIO)
// If OpenColorIO is not enabled, this does nothing.
//
// Multiple calls to this are inexpensive.
func NewColorConfig() (*ColorConfig, error) {
	c := newColorConfig(C.New_ColorConfig())
	return c, c.error()
}

// If OpenColorIO is enabled at build time, initialize with the
// specified color configuration (.ocio) file
// If OpenColorIO is not enabled, this will result in an error.
//
// Multiple calls to this are potentially expensive.
func NewColorConfigPath(path string) (*ColorConfig, error) {
	c_str := C.CString(path)
	defer C.free(unsafe.Pointer(c_str))
	c := newColorConfig(C.New_ColorConfigPath(c_str))
	return c, c.error()
}

// Get the number of ColorSpace(s) defined in this configuration
func (c *ColorConfig) NumColorSpaces() int {
	return int(C.ColorConfig_getNumColorSpaces(c.ptr))
}

// Return the name of the colorspace at a given index
func (c *ColorConfig) ColorSpaceNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getColorSpaceNameByIndex(c.ptr, C.int(index)))
}

// Get the number of Looks defined in this configuration
func (c *ColorConfig) NumLooks() int {
	return int(C.ColorConfig_getNumLooks(c.ptr))
}

// Return the name of the look at a given index
func (c *ColorConfig) LookNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getLookNameByIndex(c.ptr, C.int(index)))
}

// Get the number of displays defined in this configuration
func (c *ColorConfig) NumDisplays() int {
	return int(C.ColorConfig_getNumDisplays(c.ptr))
}

// Return the name of the display at a given index
func (c *ColorConfig) DisplayNameByIndex(index int) string {
	return C.GoString(C.ColorConfig_getDisplayNameByIndex(c.ptr, C.int(index)))
}

// Get the number of displays defined in this configuration
func (c *ColorConfig) NumViews(displayName string) int {
	c_str := C.CString(displayName)
	defer C.free(unsafe.Pointer(c_str))
	return int(C.ColorConfig_getNumViews(c.ptr, c_str))
}

// Get the name of a view at a specific index of a display
func (c *ColorConfig) ViewNameByIndex(displayName string, index int) string {
	c_str := C.CString(displayName)
	defer C.free(unsafe.Pointer(c_str))
	return C.GoString(C.ColorConfig_getViewNameByIndex(c.ptr, c_str, C.int(index)))
}

// Get the name of the color space representing the named role,
// or empty string if none could be identified.
func (c *ColorConfig) ColorSpaceNameByRole(role string) string {
	c_str := C.CString(role)
	defer C.free(unsafe.Pointer(c_str))
	return C.GoString(C.ColorConfig_getColorSpaceNameByRole(c.ptr, c_str))
}

// Given the specified input and output ColorSpace, construct the
// processor.  It is possible that this will return nil and an error, if the
// inputColorSpace doesnt exist, the outputColorSpace doesn't
// exist, or if the specified transformation is illegal (for
// example, it may require the inversion of a 3D-LUT, etc).  When
// the user is finished with a ColorProcess, ColorProcess.Destroy()
// should be called.  ColorProcessor(s) remain valid even if the
// ColorConfig that created them no longer exists.
//
// Multiple calls to this are potentially expensive, so you should
// call once to create a ColorProcessor to use on an entire image
// (or multiple images), NOT for every scanline or pixel
// separately!
func (c *ColorConfig) CreateColorProcessor(inColorSpace, outColorSpace string) (*ColorProcessor, error) {
	c_in := C.CString(inColorSpace)
	defer C.free(unsafe.Pointer(c_in))

	c_out := C.CString(outColorSpace)
	defer C.free(unsafe.Pointer(c_out))

	ptr := C.ColorConfig_createColorProcessor(c.ptr, c_in, c_out)
	err := c.error()
	if err != nil {
		return nil, err
	}
	return newColorProcessor(ptr), nil
}

// This routine will return the error string (and clear any error
// flags).  If no error has occurred since the last time GetError()
// was called, it will return an empty string.
func (c *ColorConfig) error() error {
	isError := C.ColorConfig_error(c.ptr)
	if C.bool(isError) {
		return errors.New(C.GoString(C.ColorConfig_geterror(c.ptr)))
	}
	return nil
}
<|endoftext|>


<commit_before>package models

// IErrorResponse interface para implementar Error
type IErrorResponse interface {
	Error() string
	ErrorCode() string
}

// IServerError interface para implementar Error
type IServerError interface {
	Error() string
	Message() string
}

// IHttpNotFound interface para implementar Error
type IHttpNotFound interface {
	Error() string
	Message() string
}

// IGatewayTimeout interface para timeout
type IGatewayTimeout interface {
	Error() string
	Message() string
}

// IFormatError interface para implementar Error
type IFormatError interface {
	Error() string
}

// FormatError objeto para erros de input no request da API
type FormatError struct {
	Err string
}

func (e FormatError) Error() string {
	return e.Err
}

// InternalServerError objeto para erros internos da aplicaÃ§Ã£o: ex banco de dados
type InternalServerError struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuÃ¡rio
func (e InternalServerError) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e InternalServerError) Error() string {
	return e.Err
}

//NewInternalServerError cria um novo objeto InternalServerError a partir de uma mensagem original e final
func NewInternalServerError(err, msg string) InternalServerError {
	return InternalServerError{Err: err, Msg: msg}
}

// HttpNotFound objeto para erros 404 da aplicaÃ§Ã£o: ex boleto nÃ£o encontrado
type HttpNotFound struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuÃ¡rio
func (e HttpNotFound) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e HttpNotFound) Error() string {
	return e.Err
}

//NewHTTPNotFound cria um novo objeto NewHttpNotFound a partir de uma mensagem original e final
func NewHTTPNotFound(err, msg string) HttpNotFound {
	return HttpNotFound{Err: err, Msg: msg}
}

// GatewayTimeout objeto para erros 404 da aplicaÃ§Ã£o: ex boleto nÃ£o encontrado
type GatewayTimeout struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuÃ¡rio
func (e GatewayTimeout) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e GatewayTimeout) Error() string {
	return e.Err
}

//NewGatewayTimeout cria um novo objeto NewGatewayTimeout a partir de uma mensagem original e final
func NewGatewayTimeout(err, msg string) GatewayTimeout {
	return GatewayTimeout{Err: err, Msg: msg}
}

//NewErrorResponse cria um novo objeto de ErrorReponse com cÃ³digo e mensagem
func NewErrorResponse(code, msg string) ErrorResponse {
	return ErrorResponse{Code: code, Message: msg}
}

//NewFormatError cria um novo objeto de FormatError com descriÃ§Ã£o do erro
func NewFormatError(e string) FormatError {
	return FormatError{Err: e}
}

// ErrorResponse objeto de erro
type ErrorResponse struct {
	Code    string `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

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

// ErrorCode retorna cÃ³digo do erro
func (e ErrorResponse) ErrorCode() string {
	return e.Code
}

// Errors coleÃ§Ã£o de erros
type Errors []ErrorResponse

// NewErrorCollection cria nova coleÃ§Ã£o de erros
func NewErrorCollection(errorResponse ErrorResponse) Errors {
	return []ErrorResponse{errorResponse}
}

// NewSingleErrorCollection cria nova coleÃ§Ã£o de erros com 1 item
func NewSingleErrorCollection(code, msg string) Errors {
	return NewErrorCollection(NewErrorResponse(code, msg))
}

// NewErrors cria nova coleÃ§Ã£o de erros vazia
func NewErrors() Errors {
	return []ErrorResponse{}
}

// Append adiciona mais um erro na coleÃ§Ã£o
func (e *Errors) Append(code, message string) {
	*e = append(*e, ErrorResponse{Code: code, Message: message})
}
<commit_msg>:art: arruma a codificacao do arquivo<commit_after>package models

// IErrorResponse interface para implementar Error
type IErrorResponse interface {
	Error() string
	ErrorCode() string
}

// IServerError interface para implementar Error
type IServerError interface {
	Error() string
	Message() string
}

// IHttpNotFound interface para implementar Error
type IHttpNotFound interface {
	Error() string
	Message() string
}

// IGatewayTimeout interface para timeout
type IGatewayTimeout interface {
	Error() string
	Message() string
}

// IFormatError interface para implementar Error
type IFormatError interface {
	Error() string
}

// FormatError objeto para erros de input no request da API
type FormatError struct {
	Err string
}

func (e FormatError) Error() string {
	return e.Err
}

// InternalServerError objeto para erros internos da aplicação: ex banco de dados
type InternalServerError struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuário
func (e InternalServerError) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e InternalServerError) Error() string {
	return e.Err
}

//NewInternalServerError cria um novo objeto InternalServerError a partir de uma mensagem original e final
func NewInternalServerError(err, msg string) InternalServerError {
	return InternalServerError{Err: err, Msg: msg}
}

// HttpNotFound objeto para erros 404 da aplicação: ex boleto nÃ£o encontrado
type HttpNotFound struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuário
func (e HttpNotFound) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e HttpNotFound) Error() string {
	return e.Err
}

//NewHTTPNotFound cria um novo objeto NewHttpNotFound a partir de uma mensagem original e final
func NewHTTPNotFound(err, msg string) HttpNotFound {
	return HttpNotFound{Err: err, Msg: msg}
}

// GatewayTimeout objeto para erros 404 da aplicação: ex boleto nÃ£o encontrado
type GatewayTimeout struct {
	Err string
	Msg string
}

// Message retorna a mensagem final para o usuário
func (e GatewayTimeout) Message() string {
	return e.Msg
}

// Error retorna o erro original
func (e GatewayTimeout) Error() string {
	return e.Err
}

//NewGatewayTimeout cria um novo objeto NewGatewayTimeout a partir de uma mensagem original e final
func NewGatewayTimeout(err, msg string) GatewayTimeout {
	return GatewayTimeout{Err: err, Msg: msg}
}

//NewErrorResponse cria um novo objeto de ErrorReponse com código e mensagem
func NewErrorResponse(code, msg string) ErrorResponse {
	return ErrorResponse{Code: code, Message: msg}
}

//NewFormatError cria um novo objeto de FormatError com descrição do erro
func NewFormatError(e string) FormatError {
	return FormatError{Err: e}
}

// ErrorResponse objeto de erro
type ErrorResponse struct {
	Code    string `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

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

// ErrorCode retorna código do erro
func (e ErrorResponse) ErrorCode() string {
	return e.Code
}

// Errors coleção de erros
type Errors []ErrorResponse

// NewErrorCollection cria nova coleção de erros
func NewErrorCollection(errorResponse ErrorResponse) Errors {
	return []ErrorResponse{errorResponse}
}

// NewSingleErrorCollection cria nova coleção de erros com 1 item
func NewSingleErrorCollection(code, msg string) Errors {
	return NewErrorCollection(NewErrorResponse(code, msg))
}

// NewErrors cria nova coleção de erros vazia
func NewErrors() Errors {
	return []ErrorResponse{}
}

// Append adiciona mais um erro na coleção
func (e *Errors) Append(code, message string) {
	*e = append(*e, ErrorResponse{Code: code, Message: message})
}
<|endoftext|>


<commit_before>//
package config

import (
	"fmt"
	"github.com/nanobox-io/nanobox/util"
	"os"
	"path/filepath"
)

// NanofileConfig represents all available/expected .nanofile configurable options
type NanofileConfig struct {
	CPUCap   int    `json:"cpu_cap"`   // max %CPU usage allowed to the guest vm
	CPUs     int    `json:"cpus"`      // number of CPUs to dedicate to the guest vm
	Domain   string `json:"domain"`    // the domain to use in conjuntion with the ip when accesing the guest vm (defaults to <Name>.dev)
	IP       string `json:"ip"`        // the ip added to the /etc/hosts file for accessing the guest vm
	MountNFS bool   `json:"mount_nfs"` // does the code directory get mounted as NFS
	Name     string `json:"name"`      // the name given to the project (defaults to cwd)
	Provider string `json:"provider"`  // guest vm provider (virtual box, vmware, etc)
	RAM      int    `json:"ram"`       // ammount of RAM to dedicate to the guest vm
}

// ParseNanofile
func ParseNanofile() *NanofileConfig {

	//
	nanofile := &NanofileConfig{
		CPUCap:   50,
		CPUs:     2,
		MountNFS: true,
		Name:     filepath.Base(CWDir),
		Provider: "virtualbox", // this may change in the future (adding additional hosts such as vmware)
		RAM:      1024,
	}

	nanofilePath := Root + "/.nanofile"

	// look for a global .nanofile first in the ~/.nanobox directory, and override
	// any default options found.
	if _, err := os.Stat(nanofilePath); err == nil {
		if err := ParseConfig(nanofilePath, nanofile); err != nil {
			fmt.Printf("Nanobox failed to parse your .nanofile. Please ensure it is valid YAML and try again.\n")
			Exit(1)
		}
	}

	nanofilePath = "./.nanofile"

	// then look for a local .nanofile and override any global, or remaining default
	// options found
	if _, err := os.Stat(nanofilePath); err == nil {
		if err := ParseConfig(nanofilePath, nanofile); err != nil {
			fmt.Printf("Nanobox failed to parse your .nanofile. Please ensure it is valid YAML and try again.\n")
			Exit(1)
		}
	}

	// set name specific options after potential .nanofiles have been parsed
	nanofile.Domain = fmt.Sprintf("%s.dev", nanofile.Name)

	// assign a default IP if none is specified
	if nanofile.IP == "" {
		nanofile.IP = util.StringToIP(nanofile.Name)
	}

	// if the OS is Windows folders CANNOT be mounted as NFS
	if config.OS == "windows" {
		nanofile.MountNFS = false
	}

	return nanofile
}
<commit_msg>don't need to use config.OS inside the config package<commit_after>//
package config

import (
	"fmt"
	"github.com/nanobox-io/nanobox/util"
	"os"
	"path/filepath"
)

// NanofileConfig represents all available/expected .nanofile configurable options
type NanofileConfig struct {
	CPUCap   int    `json:"cpu_cap"`   // max %CPU usage allowed to the guest vm
	CPUs     int    `json:"cpus"`      // number of CPUs to dedicate to the guest vm
	Domain   string `json:"domain"`    // the domain to use in conjuntion with the ip when accesing the guest vm (defaults to <Name>.dev)
	IP       string `json:"ip"`        // the ip added to the /etc/hosts file for accessing the guest vm
	MountNFS bool   `json:"mount_nfs"` // does the code directory get mounted as NFS
	Name     string `json:"name"`      // the name given to the project (defaults to cwd)
	Provider string `json:"provider"`  // guest vm provider (virtual box, vmware, etc)
	RAM      int    `json:"ram"`       // ammount of RAM to dedicate to the guest vm
}

// ParseNanofile
func ParseNanofile() *NanofileConfig {

	//
	nanofile := &NanofileConfig{
		CPUCap:   50,
		CPUs:     2,
		MountNFS: true,
		Name:     filepath.Base(CWDir),
		Provider: "virtualbox", // this may change in the future (adding additional hosts such as vmware)
		RAM:      1024,
	}

	nanofilePath := Root + "/.nanofile"

	// look for a global .nanofile first in the ~/.nanobox directory, and override
	// any default options found.
	if _, err := os.Stat(nanofilePath); err == nil {
		if err := ParseConfig(nanofilePath, nanofile); err != nil {
			fmt.Printf("Nanobox failed to parse your .nanofile. Please ensure it is valid YAML and try again.\n")
			Exit(1)
		}
	}

	nanofilePath = "./.nanofile"

	// then look for a local .nanofile and override any global, or remaining default
	// options found
	if _, err := os.Stat(nanofilePath); err == nil {
		if err := ParseConfig(nanofilePath, nanofile); err != nil {
			fmt.Printf("Nanobox failed to parse your .nanofile. Please ensure it is valid YAML and try again.\n")
			Exit(1)
		}
	}

	// set name specific options after potential .nanofiles have been parsed
	nanofile.Domain = fmt.Sprintf("%s.dev", nanofile.Name)

	// assign a default IP if none is specified
	if nanofile.IP == "" {
		nanofile.IP = util.StringToIP(nanofile.Name)
	}

	// if the OS is Windows folders CANNOT be mounted as NFS
	if OS == "windows" {
		nanofile.MountNFS = false
	}

	return nanofile
}
<|endoftext|>


<commit_before>package scipipe

const (
	// BUFSIZE is the standard buffer size used for channels connecting processes
	BUFSIZE = 16
)
<commit_msg>Add SciPipe version as a constant<commit_after>package scipipe

const (
	// BUFSIZE is the standard buffer size used for channels connecting processes
	BUFSIZE = 16
	// Version is the SciPipe version in string format
	Version = "0.7"
)
<|endoftext|>


<commit_before>package main

const NGINX_BUILD_VERSION = "0.7.1"

// nginx
const (
	NGINX_VERSION             = "1.9.12"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.38"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2f"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.9.7.3"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "https://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.2"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<commit_msg>bumped openssl version to 1.0.2g.<commit_after>package main

const NGINX_BUILD_VERSION = "0.7.1"

// nginx
const (
	NGINX_VERSION             = "1.9.12"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.38"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2g"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.9.7.3"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "https://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.2"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<|endoftext|>


<commit_before>package fit

import "reflect"

// ActivityFile represents the Activity FIT file type.
// Records sensor data and events from active sessions.
type ActivityFile struct {
	Activity    *ActivityMsg
	Sessions    []*SessionMsg
	Laps        []*LapMsg
	Lengths     []*LengthMsg
	Records     []*RecordMsg
	Events      []*EventMsg
	Hrvs        []*HrvMsg
	DeviceInfos []*DeviceInfoMsg
}

// DeviceFile represents the Device FIT file type.
// Describes a device's file structure and capabilities.
type DeviceFile struct {
	Softwares         []*SoftwareMsg
	Capabilities      []*CapabilitiesMsg
	FileCapabilities  []*FileCapabilitiesMsg
	MesgCapabilities  []*MesgCapabilitiesMsg
	FieldCapabilities []*FieldCapabilitiesMsg
}

// SettingsFile represents the Settings FIT file type.
// Describes a user’s parameters such as Age & Weight as well as device
// settings.
type SettingsFile struct {
	UserProfiles   []*UserProfileMsg
	HrmProfiles    []*HrmProfileMsg
	SdmProfiles    []*SdmProfileMsg
	BikeProfiles   []*BikeProfileMsg
	DeviceSettings []*DeviceSettingsMsg
}

// SportFile represents the Sport Settings FIT file type.
// Describes a user’s desired sport/zone settings.
type SportFile struct {
	ZonesTarget  *ZonesTargetMsg
	Sport        *SportMsg
	HrZones      []*HrZoneMsg
	PowerZones   []*PowerZoneMsg
	MetZones     []*MetZoneMsg
	SpeedZones   []*SpeedZoneMsg
	CadenceZones []*CadenceZoneMsg
}

// WorkoutFile represents the Workout FIT file type.
// Describes a structured activity that can be designed on a computer and
// transferred to a display device to guide a user through the activity.
type WorkoutFile struct {
	Workout      *WorkoutMsg
	WorkoutSteps []*WorkoutStepMsg
}

// CourseFile represents the Course FIT file type.
// Uses data from an activity to recreate a course.
type CourseFile struct {
	Course       *CourseMsg
	Laps         []*LapMsg
	CoursePoints []*CoursePointMsg
	Records      []*RecordMsg
}

// SchedulesFile represents the Schedules FIT file type.
// Provides scheduling of workouts and courses.
type SchedulesFile struct {
	Schedules []*ScheduleMsg
}

// WeightFile represents the Weight FIT file type.
// Records weight scale data.
type WeightFile struct {
	UserProfile  *UserProfileMsg
	WeightScales []*WeightScaleMsg
	DeviceInfos  []*DeviceInfoMsg
}

// TotalsFile represents the Totals FIT file type.
// Summarizes a user’s total activity, characterized by sport.
type TotalsFile struct {
	Totals []*TotalsMsg
}

// GoalsFile represents the Goals FIT file type.
// Describes a user’s exercise/health goals.
type GoalsFile struct {
	Goals []*GoalMsg
}

// BloodPressureFile represents the Bload Pressure FIT file type.
// Records blood pressure data.
type BloodPressureFile struct {
	UserProfile    *UserProfileMsg
	BloodPressures []*BloodPressureMsg
	DeviceInfos    []*DeviceInfoMsg
}

// MonitoringAFile represents the MonitoringA FIT file type.
// Records detailed monitoring data (i.e. logging interval < 24 Hr).
type MonitoringAFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
	DeviceInfos    []*DeviceInfoMsg
}

// ActivitySummaryFile represents the Activity Summary FIT file type.
// Similar to Activity file, contains summary information only.
type ActivitySummaryFile struct {
	Activity *ActivityMsg
	Sessions []*SessionMsg
	Laps     []*LapMsg
}

// MonitoringDailyFile represents the Daily Monitoring FIT file type.
// Records daily summary monitoring data (i.e. logging interval = 24 hour).
type MonitoringDailyFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
}

// MonitoringBFile represents the MonitoringB FIT file type.
// Records detailed monitoring data (i.e. logging interval < 24 Hr).
type MonitoringBFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
	DeviceInfos    []*DeviceInfoMsg
}

// SegmentFile represents the Segment FIT file type.
// Describes timing data for virtual races.
type SegmentFile struct {
	SegmentId               *SegmentIdMsg
	SegmentLeaderboardEntry *SegmentLeaderboardEntryMsg
	SegmentLap              *SegmentLapMsg
	SegmentPoints           []*SegmentPointMsg
}

// SegmentListFile represents the Segment List FIT file type.
// Describes available segments.
type SegmentListFile struct {
	SegmentFiles []*SegmentFileMsg
}

func (a *ActivityFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ActivityMsg:
		a.Activity = &tmp
	case SessionMsg:
		tmp.expandComponents()
		a.Sessions = append(a.Sessions, &tmp)
	case LapMsg:
		tmp.expandComponents()
		a.Laps = append(a.Laps, &tmp)
	case LengthMsg:
		a.Lengths = append(a.Lengths, &tmp)
	case RecordMsg:
		tmp.expandComponents()
		a.Records = append(a.Records, &tmp)
	case EventMsg:
		tmp.expandComponents()
		a.Events = append(a.Events, &tmp)
	case HrvMsg:
		a.Hrvs = append(a.Hrvs, &tmp)
	case DeviceInfoMsg:
		a.DeviceInfos = append(a.DeviceInfos, &tmp)
	default:
	}
}

func (d *DeviceFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SoftwareMsg:
		d.Softwares = append(d.Softwares, &tmp)
	case CapabilitiesMsg:
		d.Capabilities = append(d.Capabilities, &tmp)
	case FileCapabilitiesMsg:
		d.FileCapabilities = append(d.FileCapabilities, &tmp)
	case MesgCapabilitiesMsg:
		d.MesgCapabilities = append(d.MesgCapabilities, &tmp)
	case FieldCapabilitiesMsg:
		d.FieldCapabilities = append(d.FieldCapabilities, &tmp)
	default:
	}
}

func (s *SettingsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		s.UserProfiles = append(s.UserProfiles, &tmp)
	case HrmProfileMsg:
		s.HrmProfiles = append(s.HrmProfiles, &tmp)
	case SdmProfileMsg:
		s.SdmProfiles = append(s.SdmProfiles, &tmp)
	case BikeProfileMsg:
		s.BikeProfiles = append(s.BikeProfiles, &tmp)
	case DeviceSettingsMsg:
		s.DeviceSettings = append(s.DeviceSettings, &tmp)
	default:
	}
}

func (s *SportFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ZonesTargetMsg:
		s.ZonesTarget = &tmp
	case SportMsg:
		s.Sport = &tmp
	case HrZoneMsg:
		s.HrZones = append(s.HrZones, &tmp)
	case PowerZoneMsg:
		s.PowerZones = append(s.PowerZones, &tmp)
	case MetZoneMsg:
		s.MetZones = append(s.MetZones, &tmp)
	case SpeedZoneMsg:
		s.SpeedZones = append(s.SpeedZones, &tmp)
	case CadenceZoneMsg:
		s.CadenceZones = append(s.CadenceZones, &tmp)
	default:
	}
}

func (w *WorkoutFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case WorkoutMsg:
		w.Workout = &tmp
	case WorkoutStepMsg:
		w.WorkoutSteps = append(w.WorkoutSteps, &tmp)
	default:
	}
}

func (c *CourseFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case CourseMsg:
		c.Course = &tmp
	case LapMsg:
		tmp.expandComponents()
		c.Laps = append(c.Laps, &tmp)
	case CoursePointMsg:
		c.CoursePoints = append(c.CoursePoints, &tmp)
	case RecordMsg:
		tmp.expandComponents()
		c.Records = append(c.Records, &tmp)
	default:
	}
}

func (s *SchedulesFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ScheduleMsg:
		s.Schedules = append(s.Schedules, &tmp)
	default:
	}
}

func (w *WeightFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		w.UserProfile = &tmp
	case WeightScaleMsg:
		w.WeightScales = append(w.WeightScales, &tmp)
	case DeviceInfoMsg:
		w.DeviceInfos = append(w.DeviceInfos, &tmp)
	default:
	}
}

func (t *TotalsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case TotalsMsg:
		t.Totals = append(t.Totals, &tmp)
	default:
	}
}

func (g *GoalsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case GoalMsg:
		g.Goals = append(g.Goals, &tmp)
	default:
	}
}

func (b *BloodPressureFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		b.UserProfile = &tmp
	case BloodPressureMsg:
		b.BloodPressures = append(b.BloodPressures, &tmp)
	case DeviceInfoMsg:
		b.DeviceInfos = append(b.DeviceInfos, &tmp)
	default:
	}
}

func (m *MonitoringAFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	case DeviceInfoMsg:
		m.DeviceInfos = append(m.DeviceInfos, &tmp)
	default:
	}
}

func (a *ActivitySummaryFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ActivityMsg:
		a.Activity = &tmp
	case SessionMsg:
		tmp.expandComponents()
		a.Sessions = append(a.Sessions, &tmp)
	case LapMsg:
		tmp.expandComponents()
		a.Laps = append(a.Laps, &tmp)
	default:
	}
}

func (m *MonitoringDailyFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	default:
	}
}

func (m *MonitoringBFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	case DeviceInfoMsg:
		m.DeviceInfos = append(m.DeviceInfos, &tmp)
	default:
	}
}

func (s *SegmentFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SegmentIdMsg:
		s.SegmentId = &tmp
	case SegmentLeaderboardEntryMsg:
		s.SegmentLeaderboardEntry = &tmp
	case SegmentLapMsg:
		s.SegmentLap = &tmp
	case SegmentPointMsg:
		s.SegmentPoints = append(s.SegmentPoints, &tmp)
	default:
	}
}

func (s *SegmentListFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SegmentFileMsg:
		s.SegmentFiles = append(s.SegmentFiles, &tmp)
	default:
	}
}
<commit_msg>Fixes #55<commit_after>package fit

import "reflect"

// ActivityFile represents the Activity FIT file type.
// Records sensor data and events from active sessions.
type ActivityFile struct {
	Activity    *ActivityMsg
	Sessions    []*SessionMsg
	Laps        []*LapMsg
	Lengths     []*LengthMsg
	Records     []*RecordMsg
	Events      []*EventMsg
	Hrvs        []*HrvMsg
	DeviceInfos []*DeviceInfoMsg
}

// DeviceFile represents the Device FIT file type.
// Describes a device's file structure and capabilities.
type DeviceFile struct {
	Softwares         []*SoftwareMsg
	Capabilities      []*CapabilitiesMsg
	FileCapabilities  []*FileCapabilitiesMsg
	MesgCapabilities  []*MesgCapabilitiesMsg
	FieldCapabilities []*FieldCapabilitiesMsg
}

// SettingsFile represents the Settings FIT file type.
// Describes a user’s parameters such as Age & Weight as well as device
// settings.
type SettingsFile struct {
	UserProfiles   []*UserProfileMsg
	HrmProfiles    []*HrmProfileMsg
	SdmProfiles    []*SdmProfileMsg
	BikeProfiles   []*BikeProfileMsg
	DeviceSettings []*DeviceSettingsMsg
}

// SportFile represents the Sport Settings FIT file type.
// Describes a user’s desired sport/zone settings.
type SportFile struct {
	ZonesTarget  *ZonesTargetMsg
	Sport        *SportMsg
	HrZones      []*HrZoneMsg
	PowerZones   []*PowerZoneMsg
	MetZones     []*MetZoneMsg
	SpeedZones   []*SpeedZoneMsg
	CadenceZones []*CadenceZoneMsg
}

// WorkoutFile represents the Workout FIT file type.
// Describes a structured activity that can be designed on a computer and
// transferred to a display device to guide a user through the activity.
type WorkoutFile struct {
	Workout      *WorkoutMsg
	WorkoutSteps []*WorkoutStepMsg
}

// CourseFile represents the Course FIT file type.
// Uses data from an activity to recreate a course.
type CourseFile struct {
	Course       *CourseMsg
	Laps         []*LapMsg
	CoursePoints []*CoursePointMsg
	Events       []*EventMsg
	Records      []*RecordMsg
}

// SchedulesFile represents the Schedules FIT file type.
// Provides scheduling of workouts and courses.
type SchedulesFile struct {
	Schedules []*ScheduleMsg
}

// WeightFile represents the Weight FIT file type.
// Records weight scale data.
type WeightFile struct {
	UserProfile  *UserProfileMsg
	WeightScales []*WeightScaleMsg
	DeviceInfos  []*DeviceInfoMsg
}

// TotalsFile represents the Totals FIT file type.
// Summarizes a user’s total activity, characterized by sport.
type TotalsFile struct {
	Totals []*TotalsMsg
}

// GoalsFile represents the Goals FIT file type.
// Describes a user’s exercise/health goals.
type GoalsFile struct {
	Goals []*GoalMsg
}

// BloodPressureFile represents the Bload Pressure FIT file type.
// Records blood pressure data.
type BloodPressureFile struct {
	UserProfile    *UserProfileMsg
	BloodPressures []*BloodPressureMsg
	DeviceInfos    []*DeviceInfoMsg
}

// MonitoringAFile represents the MonitoringA FIT file type.
// Records detailed monitoring data (i.e. logging interval < 24 Hr).
type MonitoringAFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
	DeviceInfos    []*DeviceInfoMsg
}

// ActivitySummaryFile represents the Activity Summary FIT file type.
// Similar to Activity file, contains summary information only.
type ActivitySummaryFile struct {
	Activity *ActivityMsg
	Sessions []*SessionMsg
	Laps     []*LapMsg
}

// MonitoringDailyFile represents the Daily Monitoring FIT file type.
// Records daily summary monitoring data (i.e. logging interval = 24 hour).
type MonitoringDailyFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
}

// MonitoringBFile represents the MonitoringB FIT file type.
// Records detailed monitoring data (i.e. logging interval < 24 Hr).
type MonitoringBFile struct {
	MonitoringInfo *MonitoringInfoMsg
	Monitorings    []*MonitoringMsg
	DeviceInfos    []*DeviceInfoMsg
}

// SegmentFile represents the Segment FIT file type.
// Describes timing data for virtual races.
type SegmentFile struct {
	SegmentId               *SegmentIdMsg
	SegmentLeaderboardEntry *SegmentLeaderboardEntryMsg
	SegmentLap              *SegmentLapMsg
	SegmentPoints           []*SegmentPointMsg
}

// SegmentListFile represents the Segment List FIT file type.
// Describes available segments.
type SegmentListFile struct {
	SegmentFiles []*SegmentFileMsg
}

func (a *ActivityFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ActivityMsg:
		a.Activity = &tmp
	case SessionMsg:
		tmp.expandComponents()
		a.Sessions = append(a.Sessions, &tmp)
	case LapMsg:
		tmp.expandComponents()
		a.Laps = append(a.Laps, &tmp)
	case LengthMsg:
		a.Lengths = append(a.Lengths, &tmp)
	case RecordMsg:
		tmp.expandComponents()
		a.Records = append(a.Records, &tmp)
	case EventMsg:
		tmp.expandComponents()
		a.Events = append(a.Events, &tmp)
	case HrvMsg:
		a.Hrvs = append(a.Hrvs, &tmp)
	case DeviceInfoMsg:
		a.DeviceInfos = append(a.DeviceInfos, &tmp)
	default:
	}
}

func (d *DeviceFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SoftwareMsg:
		d.Softwares = append(d.Softwares, &tmp)
	case CapabilitiesMsg:
		d.Capabilities = append(d.Capabilities, &tmp)
	case FileCapabilitiesMsg:
		d.FileCapabilities = append(d.FileCapabilities, &tmp)
	case MesgCapabilitiesMsg:
		d.MesgCapabilities = append(d.MesgCapabilities, &tmp)
	case FieldCapabilitiesMsg:
		d.FieldCapabilities = append(d.FieldCapabilities, &tmp)
	default:
	}
}

func (s *SettingsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		s.UserProfiles = append(s.UserProfiles, &tmp)
	case HrmProfileMsg:
		s.HrmProfiles = append(s.HrmProfiles, &tmp)
	case SdmProfileMsg:
		s.SdmProfiles = append(s.SdmProfiles, &tmp)
	case BikeProfileMsg:
		s.BikeProfiles = append(s.BikeProfiles, &tmp)
	case DeviceSettingsMsg:
		s.DeviceSettings = append(s.DeviceSettings, &tmp)
	default:
	}
}

func (s *SportFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ZonesTargetMsg:
		s.ZonesTarget = &tmp
	case SportMsg:
		s.Sport = &tmp
	case HrZoneMsg:
		s.HrZones = append(s.HrZones, &tmp)
	case PowerZoneMsg:
		s.PowerZones = append(s.PowerZones, &tmp)
	case MetZoneMsg:
		s.MetZones = append(s.MetZones, &tmp)
	case SpeedZoneMsg:
		s.SpeedZones = append(s.SpeedZones, &tmp)
	case CadenceZoneMsg:
		s.CadenceZones = append(s.CadenceZones, &tmp)
	default:
	}
}

func (w *WorkoutFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case WorkoutMsg:
		w.Workout = &tmp
	case WorkoutStepMsg:
		w.WorkoutSteps = append(w.WorkoutSteps, &tmp)
	default:
	}
}

func (c *CourseFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case CourseMsg:
		c.Course = &tmp
	case LapMsg:
		tmp.expandComponents()
		c.Laps = append(c.Laps, &tmp)
	case CoursePointMsg:
		c.CoursePoints = append(c.CoursePoints, &tmp)
	case RecordMsg:
		tmp.expandComponents()
		c.Records = append(c.Records, &tmp)
	default:
	}
}

func (s *SchedulesFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ScheduleMsg:
		s.Schedules = append(s.Schedules, &tmp)
	default:
	}
}

func (w *WeightFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		w.UserProfile = &tmp
	case WeightScaleMsg:
		w.WeightScales = append(w.WeightScales, &tmp)
	case DeviceInfoMsg:
		w.DeviceInfos = append(w.DeviceInfos, &tmp)
	default:
	}
}

func (t *TotalsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case TotalsMsg:
		t.Totals = append(t.Totals, &tmp)
	default:
	}
}

func (g *GoalsFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case GoalMsg:
		g.Goals = append(g.Goals, &tmp)
	default:
	}
}

func (b *BloodPressureFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case UserProfileMsg:
		b.UserProfile = &tmp
	case BloodPressureMsg:
		b.BloodPressures = append(b.BloodPressures, &tmp)
	case DeviceInfoMsg:
		b.DeviceInfos = append(b.DeviceInfos, &tmp)
	default:
	}
}

func (m *MonitoringAFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	case DeviceInfoMsg:
		m.DeviceInfos = append(m.DeviceInfos, &tmp)
	default:
	}
}

func (a *ActivitySummaryFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case ActivityMsg:
		a.Activity = &tmp
	case SessionMsg:
		tmp.expandComponents()
		a.Sessions = append(a.Sessions, &tmp)
	case LapMsg:
		tmp.expandComponents()
		a.Laps = append(a.Laps, &tmp)
	default:
	}
}

func (m *MonitoringDailyFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	default:
	}
}

func (m *MonitoringBFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case MonitoringInfoMsg:
		m.MonitoringInfo = &tmp
	case MonitoringMsg:
		m.Monitorings = append(m.Monitorings, &tmp)
	case DeviceInfoMsg:
		m.DeviceInfos = append(m.DeviceInfos, &tmp)
	default:
	}
}

func (s *SegmentFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SegmentIdMsg:
		s.SegmentId = &tmp
	case SegmentLeaderboardEntryMsg:
		s.SegmentLeaderboardEntry = &tmp
	case SegmentLapMsg:
		s.SegmentLap = &tmp
	case SegmentPointMsg:
		s.SegmentPoints = append(s.SegmentPoints, &tmp)
	default:
	}
}

func (s *SegmentListFile) add(msg reflect.Value) {
	x := msg.Interface()
	switch tmp := x.(type) {
	case SegmentFileMsg:
		s.SegmentFiles = append(s.SegmentFiles, &tmp)
	default:
	}
}
<|endoftext|>


<commit_before>package cephfs

import (
	"fmt"
	"os"
	"syscall"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var (
	CephMountTest string = "/tmp/ceph/mds/mnt/"
)

func TestCreateMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	assert.NotNil(t, mount)
}

func TestMountRoot(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)
}

func TestSyncFs(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)
}

func TestChangeDir(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	require.NoError(t, err)

	dir1 := mount.CurrentDir()
	assert.NotNil(t, dir1)

	err = mount.MakeDir("/asdf", 0755)
	assert.NoError(t, err)

	err = mount.ChangeDir("/asdf")
	assert.NoError(t, err)

	dir2 := mount.CurrentDir()
	assert.NotNil(t, dir2)

	assert.NotEqual(t, dir1, dir2)
	assert.Equal(t, dir1, "/")
	assert.Equal(t, dir2, "/asdf")
}

func TestRemoveDir(t *testing.T) {
	dirname := "one"
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	_, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)

	err = mount.RemoveDir(dirname)
	assert.NoError(t, err)

	_, err = os.Stat(CephMountTest + dirname)
	assert.EqualError(t, err,
		fmt.Sprintf("stat %s: no such file or directory", CephMountTest+dirname))
}

func TestUnmountMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)
	fmt.Printf("%#v\n", mount.IsMounted())

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)
	assert.True(t, mount.IsMounted())

	err = mount.Unmount()
	assert.NoError(t, err)
	assert.False(t, mount.IsMounted())
}

func TestReleaseMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.Release()
	assert.NoError(t, err)
}

func TestChmodDir(t *testing.T) {
	dirname := "two"
	var stats_before uint32 = 0755
	var stats_after uint32 = 0700
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, stats_before)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Mode().Perm()), stats_before)

	err = mount.Chmod(dirname, stats_after)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.Equal(t, uint32(stats.Mode().Perm()), stats_after)
}

// Not cross-platform, go's os does not specifiy Sys return type
func TestChown(t *testing.T) {
	dirname := "three"
	// dockerfile creates bob user account
	var bob uint32 = 1010
	var root uint32 = 0

	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), root)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), root)

	err = mount.Chown(dirname, bob, bob)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), bob)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), bob)

}
<commit_msg>cephfs: test error type and error handling functions<commit_after>package cephfs

import (
	"fmt"
	"os"
	"syscall"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var (
	CephMountTest string = "/tmp/ceph/mds/mnt/"
)

func TestCreateMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	assert.NotNil(t, mount)
}

func TestMountRoot(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)
}

func TestSyncFs(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)
}

func TestChangeDir(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	require.NoError(t, err)

	dir1 := mount.CurrentDir()
	assert.NotNil(t, dir1)

	err = mount.MakeDir("/asdf", 0755)
	assert.NoError(t, err)

	err = mount.ChangeDir("/asdf")
	assert.NoError(t, err)

	dir2 := mount.CurrentDir()
	assert.NotNil(t, dir2)

	assert.NotEqual(t, dir1, dir2)
	assert.Equal(t, dir1, "/")
	assert.Equal(t, dir2, "/asdf")
}

func TestRemoveDir(t *testing.T) {
	dirname := "one"
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	_, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)

	err = mount.RemoveDir(dirname)
	assert.NoError(t, err)

	_, err = os.Stat(CephMountTest + dirname)
	assert.EqualError(t, err,
		fmt.Sprintf("stat %s: no such file or directory", CephMountTest+dirname))
}

func TestUnmountMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)
	fmt.Printf("%#v\n", mount.IsMounted())

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)
	assert.True(t, mount.IsMounted())

	err = mount.Unmount()
	assert.NoError(t, err)
	assert.False(t, mount.IsMounted())
}

func TestReleaseMount(t *testing.T) {
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.Release()
	assert.NoError(t, err)
}

func TestChmodDir(t *testing.T) {
	dirname := "two"
	var stats_before uint32 = 0755
	var stats_after uint32 = 0700
	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, stats_before)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Mode().Perm()), stats_before)

	err = mount.Chmod(dirname, stats_after)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.Equal(t, uint32(stats.Mode().Perm()), stats_after)
}

// Not cross-platform, go's os does not specifiy Sys return type
func TestChown(t *testing.T) {
	dirname := "three"
	// dockerfile creates bob user account
	var bob uint32 = 1010
	var root uint32 = 0

	mount, err := CreateMount()
	assert.NoError(t, err)
	require.NotNil(t, mount)

	err = mount.ReadDefaultConfigFile()
	assert.NoError(t, err)

	err = mount.Mount()
	assert.NoError(t, err)

	err = mount.MakeDir(dirname, 0755)
	assert.NoError(t, err)

	err = mount.SyncFs()
	assert.NoError(t, err)

	// os.Stat the actual mounted location to verify Makedir/RemoveDir
	stats, err := os.Stat(CephMountTest + dirname)
	require.NoError(t, err)

	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), root)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), root)

	err = mount.Chown(dirname, bob, bob)
	assert.NoError(t, err)

	stats, err = os.Stat(CephMountTest + dirname)
	assert.NoError(t, err)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Uid), bob)
	assert.Equal(t, uint32(stats.Sys().(*syscall.Stat_t).Gid), bob)

}

func TestCephFSError(t *testing.T) {
	err := getError(0)
	assert.NoError(t, err)

	err = getError(-5) // IO error
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=5, Input/output error")

	err = getError(345) // no such errno
	assert.Error(t, err)
	assert.Equal(t, err.Error(), "cephfs: ret=345")
}
<|endoftext|>


<commit_before>//
// # GoScriptify
//
package goscriptify

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/leeola/goscriptify/utils"
)

type ScriptOptions struct {
	Temp   string
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

type BuildError struct {
	Exit    int
	Message string
}

func (e *BuildError) Error() string {
	return fmt.Sprintf("Go build error:\n\n%s", e.Message)
}

// Build the given source to the destination
//
// Currently just using the go runtime to build, for simplicity.
func Build(dst string, srcs []string) error {
	// Becuase Go's builder can return some vague errors, lets do some
	// simple sanity checks.
	for _, s := range srcs {
		if e := filepath.Ext(s); e != ".go" {
			return errors.New("source must have go extension")
		}
	}

	args := append([]string{"build", "-o", dst}, srcs...)
	cmd := exec.Command("go", args...)

	// Go returns build error output on the stderr, so we're storing it
	// in case we need it. If needed, it will be returned inside of the
	// BuildError
	var stderr bytes.Buffer
	defer stderr.Reset()
	cmd.Stderr = &stderr

	err := cmd.Run()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				return &BuildError{
					Exit:    status.ExitStatus(),
					Message: stderr.String(),
				}
			}
		}
		// If it's not an execerr or we can't get the status, return err
		return err
	}

	return nil
}

// Find a single file from a list of multiple files, and returning
// the first found filename. This is to support multiple name types,
// or cases.
//
// Example:
//
//    FindScript([]string{"Builder", "builder"})
//
// Will search for both "Builder" and "builder", and return the first
// found file.
//
// NOTE: Due to OSX's case insensitivity, it's hard (maybe possible?)
// to know the *actual* filename of the found file. Tests, then
// have to ignore the string output of this function, as it will
// fail on OSX. I'd love to see a workaround for this issue.
func FindScript(ss [][]string) (string, error) {
	return "", errors.New("Not implemented")
}

type ScriptPath struct {
	Original  string
	Generated string
	Clean     bool
}

// When given a script path and a base destination directory,
// return the formatted temporary paths.
//
// The first (dst) path is the binary (executable) path
func GetPaths(sources []string, temp string) (string, []ScriptPath,
	error) {
	if len(sources) == 0 {
		return "", []ScriptPath{}, errors.New("A source file is required")
	}
	paths := make([]ScriptPath, len(sources))

	// To get a unique "id" of this build, we're combining the abs path
	// of this directory, and all source names, and then hashing it.
	dir, err := os.Getwd()
	if err != nil {
		return "", []ScriptPath{}, err
	}
	h := utils.HashString(strings.Join(append(sources, dir), ""))

	// Get the hashed bin path. Eg: /tmp/goscriptify/ads7s6adada8asdka
	binDst := filepath.Join(temp, h)

	// Loop through all of the source files and generate go build friendly
	// path names as needed.
	for i, source := range sources {
		paths[i] = ScriptPath{Original: source}
		// If the source already ends in .go, no need to do anything
		if filepath.Ext(source) == ".go" {
			paths[i].Generated = source
			paths[i].Clean = false
			continue
		}

		// append .go
		paths[i].Generated = fmt.Sprintf("%s.go", source)
		paths[i].Clean = true

		// If the source.go file exists, we can't replace it. So, choose
		// an alternate, long and ugly name.
		if exists, _ := utils.Exists(paths[i].Generated); exists {
			d := filepath.Dir(source)
			f := filepath.Base(source)
			// Note that we're not checking if this exists currently.
			// Living life on the edge of our seat i guess?
			paths[i].Generated = filepath.Join(d, fmt.Sprintf("%s-%s.go", h, f))
		}
	}

	return binDst, paths, nil
}

// Run the given path as an executable, with the supplied args, and
// forwarding the stdin/out/err.
//
// Return the exit status, and any errors encountered.
func RunExec(p string, args []string,
	stdin io.Reader, stdout, stderr io.Writer) (int, error) {
	if _, err := os.Stat(p); err != nil {
		return 0, err
	}

	cmd := exec.Command(p, args...)
	cmd.Stdin = stdin
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	err := cmd.Run()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				return status.ExitStatus(), nil
			} else {
				return 0, err
			}
		} else {
			return 0, err
		}
	}

	return 0, nil
}

// Copy, compile, and run the given script with global $args, and
// default options.
func RunScript(p string) {
	opts := ScriptOptions{
		"/tmp/goscriptify",
		os.Stdin, os.Stdout, os.Stderr,
	}
	exit, err := RunScriptsWithOpts([]string{p}, os.Args[1:], opts)
	if err != nil {
		if builderr, ok := err.(*BuildError); ok {
			fmt.Fprint(os.Stderr, builderr.Error())
		} else {
			fmt.Fprintf(os.Stderr, "Fatal: %s", err.Error())
		}

		if exit == 0 {
			os.Exit(1)
		}
	}
	os.Exit(exit)
}

// Go through a slice of ScriptPaths removing all ScriptPath.Generated
// from the file system if their ScriptPath.Clean is true.
func CleanScripts(ps []ScriptPath) error {
	for _, sPath := range ps {
		if sPath.Clean {
			err := os.Remove(sPath.Generated)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// Copy a slice of ScriptPaths from their ScriptPath.Original location
// to the ScriptPath.Generated location.
func CopyScripts(ps []ScriptPath) (err error) {
	for _, sPath := range ps {
		// If they're the same, no need to copy.
		if sPath.Original == sPath.Generated {
			continue
		}
		err = utils.CopyFile(sPath.Generated, sPath.Original)
		if err != nil {
			// We should automatically clean scripts up in the future,
			// i'm just not decided on where this should take place - in the
			// api.
			//CleanScripts(ps[0:i])
			break
		}
	}
	return err
}

// Copy, compile, and run the given script with the given options.
//
// Returns the exit status and any encountered errors
func RunScriptsWithOpts(scripts, args []string,
	opts ScriptOptions) (int, error) {
	binDst, scriptPaths, err := GetPaths(scripts, opts.Temp)
	if err != nil {
		return 0, err
	}

	err = os.MkdirAll(opts.Temp, 0777)
	if err != nil {
		return 0, err
	}

	err = CopyScripts(scriptPaths)
	if err != nil {
		return 0, err
	}

	// Make a slice of sources for the build command
	srcs := make([]string, len(scriptPaths))
	for i, s := range scriptPaths {
		srcs[i] = s.Generated
	}

	// In the future we will checksum the source(s), but for now we're
	// just letting go handle the repeat build caching (if at all)
	err = Build(binDst, srcs)
	if err != nil {
		return 0, err
	}

	// Now cleanup any script mess we made.
	err = CleanScripts(scriptPaths)
	if err != nil {
		return 0, err
	}

	return RunExec(binDst, args, os.Stdin, os.Stdout, os.Stderr)
}
<commit_msg>Moved func within file<commit_after>//
// # GoScriptify
//
package goscriptify

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/leeola/goscriptify/utils"
)

type ScriptOptions struct {
	Temp   string
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

type BuildError struct {
	Exit    int
	Message string
}

func (e *BuildError) Error() string {
	return fmt.Sprintf("Go build error:\n\n%s", e.Message)
}

// Build the given source to the destination
//
// Currently just using the go runtime to build, for simplicity.
func Build(dst string, srcs []string) error {
	// Becuase Go's builder can return some vague errors, lets do some
	// simple sanity checks.
	for _, s := range srcs {
		if e := filepath.Ext(s); e != ".go" {
			return errors.New("source must have go extension")
		}
	}

	args := append([]string{"build", "-o", dst}, srcs...)
	cmd := exec.Command("go", args...)

	// Go returns build error output on the stderr, so we're storing it
	// in case we need it. If needed, it will be returned inside of the
	// BuildError
	var stderr bytes.Buffer
	defer stderr.Reset()
	cmd.Stderr = &stderr

	err := cmd.Run()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				return &BuildError{
					Exit:    status.ExitStatus(),
					Message: stderr.String(),
				}
			}
		}
		// If it's not an execerr or we can't get the status, return err
		return err
	}

	return nil
}

// Go through a slice of ScriptPaths removing all ScriptPath.Generated
// from the file system if their ScriptPath.Clean is true.
func CleanScripts(ps []ScriptPath) error {
	for _, sPath := range ps {
		if sPath.Clean {
			err := os.Remove(sPath.Generated)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// Copy a slice of ScriptPaths from their ScriptPath.Original location
// to the ScriptPath.Generated location.
func CopyScripts(ps []ScriptPath) (err error) {
	for _, sPath := range ps {
		// If they're the same, no need to copy.
		if sPath.Original == sPath.Generated {
			continue
		}
		err = utils.CopyFile(sPath.Generated, sPath.Original)
		if err != nil {
			// We should automatically clean scripts up in the future,
			// i'm just not decided on where this should take place - in the
			// api.
			//CleanScripts(ps[0:i])
			break
		}
	}
	return err
}

// Find a single file from a list of multiple files, and returning
// the first found filename. This is to support multiple name types,
// or cases.
//
// Example:
//
//    FindScript([]string{"Builder", "builder"})
//
// Will search for both "Builder" and "builder", and return the first
// found file.
//
// NOTE: Due to OSX's case insensitivity, it's hard (maybe possible?)
// to know the *actual* filename of the found file. Tests, then
// have to ignore the string output of this function, as it will
// fail on OSX. I'd love to see a workaround for this issue.
func FindScript(ss [][]string) (string, error) {
	return "", errors.New("Not implemented")
}

type ScriptPath struct {
	Original  string
	Generated string
	Clean     bool
}

// When given a script path and a base destination directory,
// return the formatted temporary paths.
//
// The first (dst) path is the binary (executable) path
func GetPaths(sources []string, temp string) (string, []ScriptPath,
	error) {
	if len(sources) == 0 {
		return "", []ScriptPath{}, errors.New("A source file is required")
	}
	paths := make([]ScriptPath, len(sources))

	// To get a unique "id" of this build, we're combining the abs path
	// of this directory, and all source names, and then hashing it.
	dir, err := os.Getwd()
	if err != nil {
		return "", []ScriptPath{}, err
	}
	h := utils.HashString(strings.Join(append(sources, dir), ""))

	// Get the hashed bin path. Eg: /tmp/goscriptify/ads7s6adada8asdka
	binDst := filepath.Join(temp, h)

	// Loop through all of the source files and generate go build friendly
	// path names as needed.
	for i, source := range sources {
		paths[i] = ScriptPath{Original: source}
		// If the source already ends in .go, no need to do anything
		if filepath.Ext(source) == ".go" {
			paths[i].Generated = source
			paths[i].Clean = false
			continue
		}

		// append .go
		paths[i].Generated = fmt.Sprintf("%s.go", source)
		paths[i].Clean = true

		// If the source.go file exists, we can't replace it. So, choose
		// an alternate, long and ugly name.
		if exists, _ := utils.Exists(paths[i].Generated); exists {
			d := filepath.Dir(source)
			f := filepath.Base(source)
			// Note that we're not checking if this exists currently.
			// Living life on the edge of our seat i guess?
			paths[i].Generated = filepath.Join(d, fmt.Sprintf("%s-%s.go", h, f))
		}
	}

	return binDst, paths, nil
}

// Run the given path as an executable, with the supplied args, and
// forwarding the stdin/out/err.
//
// Return the exit status, and any errors encountered.
func RunExec(p string, args []string,
	stdin io.Reader, stdout, stderr io.Writer) (int, error) {
	if _, err := os.Stat(p); err != nil {
		return 0, err
	}

	cmd := exec.Command(p, args...)
	cmd.Stdin = stdin
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	err := cmd.Run()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				return status.ExitStatus(), nil
			} else {
				return 0, err
			}
		} else {
			return 0, err
		}
	}

	return 0, nil
}

// Copy, compile, and run the given script with global $args, and
// default options.
func RunScript(p string) {
	opts := ScriptOptions{
		"/tmp/goscriptify",
		os.Stdin, os.Stdout, os.Stderr,
	}
	exit, err := RunScriptsWithOpts([]string{p}, os.Args[1:], opts)
	if err != nil {
		if builderr, ok := err.(*BuildError); ok {
			fmt.Fprint(os.Stderr, builderr.Error())
		} else {
			fmt.Fprintf(os.Stderr, "Fatal: %s", err.Error())
		}

		if exit == 0 {
			os.Exit(1)
		}
	}
	os.Exit(exit)
}

// Copy, compile, and run the given script with the given options.
//
// Returns the exit status and any encountered errors
func RunScriptsWithOpts(scripts, args []string,
	opts ScriptOptions) (int, error) {
	binDst, scriptPaths, err := GetPaths(scripts, opts.Temp)
	if err != nil {
		return 0, err
	}

	err = os.MkdirAll(opts.Temp, 0777)
	if err != nil {
		return 0, err
	}

	err = CopyScripts(scriptPaths)
	if err != nil {
		return 0, err
	}

	// Make a slice of sources for the build command
	srcs := make([]string, len(scriptPaths))
	for i, s := range scriptPaths {
		srcs[i] = s.Generated
	}

	// In the future we will checksum the source(s), but for now we're
	// just letting go handle the repeat build caching (if at all)
	err = Build(binDst, srcs)
	if err != nil {
		return 0, err
	}

	// Now cleanup any script mess we made.
	err = CleanScripts(scriptPaths)
	if err != nil {
		return 0, err
	}

	return RunExec(binDst, args, os.Stdin, os.Stdout, os.Stderr)
}
<|endoftext|>


<commit_before>package gosync

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"

	log "github.com/cihub/seelog"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

type Sync struct {
	Auth       aws.Auth
	Source     string
	Target     string
	Concurrent int
}

func NewSync(auth aws.Auth, source string, target string) *Sync {
	return &Sync{
		Auth:       auth,
		Source:     source,
		Target:     target,
		Concurrent: 1,
	}
}

func (s *Sync) Sync() error {
	if !s.validPair() {
		return errors.New("Invalid sync pair.")
	}

	if validS3Url(s.Source) {
		return s.syncS3ToDir()
	}
	return s.syncDirToS3()
}

func lookupBucket(bucketName string, auth aws.Auth) (*s3.Bucket, error) {
	log.Infof("Looking up region for bucket '%s'.", bucketName)

	var bucket *s3.Bucket = nil

	// Looking in each region for bucket
	// To do, make this less crusty and ghetto
	for region, _ := range aws.Regions {
		log.Debugf("Looking for bucket '%s' in '%s'.", bucketName, region)
		s3 := s3.New(auth, aws.Regions[region])
		b := s3.Bucket(bucketName)

		// If list return, bucket is valid in this region.
		_, err := b.List("", "", "", 0)
		if err == nil {
			log.Infof("Found bucket '%s' in '%s'.", bucketName, region)
			bucket = b
			break
		} else if err.Error() == "Get : 301 response missing Location header" {
			log.Debugf("Bucket '%s' not found in '%s'.", bucketName, region)
			continue
		} else {
			return nil, err
		}
	}

	if bucket != nil {
		return bucket, nil
	}

	return nil, fmt.Errorf("Bucket not found.")
}

func (s *Sync) syncDirToS3() error {
	log.Infof("Syncing to S3.")

	sourceFiles, err := loadLocalFiles(s.Source)
	if err != nil {
		return err
	}

	s3url := S3Url{Url: s.Target}
	path := s3url.Path()

	bucket, err := lookupBucket(s3url.Bucket(), s.Auth)
	if err != nil {
		return err
	}

	// Load files and do not specify marker to start
	targetFiles := make(map[string]string)
	targetFiles, err = loadS3Files(bucket, path, targetFiles, "")
	if err != nil {
		return err
	}

	return s.concurrentSyncDirToS3(s3url, bucket, targetFiles, sourceFiles)
}

func (s *Sync) concurrentSyncDirToS3(s3url S3Url, bucket *s3.Bucket, targetFiles, sourceFiles map[string]string) error {
	doneChan := newDoneChan(s.Concurrent)
	pool := newPool(s.Concurrent)
	var wg sync.WaitGroup

	for file, _ := range sourceFiles {
		if targetFiles[file] != sourceFiles[file] {
			filePath := strings.Join([]string{s.Source, file}, "/")
			keyPath := strings.Join([]string{s3url.Key(), file}, "/")

			// Get transfer reservation from pool
			log.Tracef("Requesting reservation for '%s'.", keyPath)
			<-pool
			log.Tracef("Retrieved reservation for '%s'.", keyPath)

			log.Infof("Starting sync: %s -> s3://%s/%s", filePath, bucket.Name, file)
			wg.Add(1)
			go func() {
				defer wg.Done()
				putRoutine(doneChan, filePath, bucket, keyPath)
				pool <- 1
			}()
		}
	}

	// Wait for all routines to finish
	wg.Wait()
	return nil
}

func (s *Sync) syncS3ToDir() error {
	log.Infof("Syncing from S3.")

	s3url := S3Url{Url: s.Source}
	bucket, err := lookupBucket(s3url.Bucket(), s.Auth)
	if err != nil {
		return err
	}

	sourceFiles := make(map[string]string)
	sourceFiles, err = loadS3Files(bucket, s3url.Path(), sourceFiles, "")
	if err != nil {
		return err
	}

	targetFiles, err := loadLocalFiles(s.Target)
	if err != nil {
		return err
	}
	return s.concurrentSyncS3ToDir(s3url, bucket, targetFiles, sourceFiles)
}

func (s *Sync) concurrentSyncS3ToDir(s3url S3Url, bucket *s3.Bucket, targetFiles, sourceFiles map[string]string) error {
	doneChan := newDoneChan(s.Concurrent)
	pool := newPool(s.Concurrent)
	var wg sync.WaitGroup

	for file, _ := range sourceFiles {
		if targetFiles[file] != sourceFiles[file] {
			filePath := strings.Join([]string{s.Target, file}, "/")
			if filepath.Dir(filePath) != "." {
				err := os.MkdirAll(filepath.Dir(filePath), 0755)
				if err != nil {
					return err
				}
			}

			// Get transfer reservation from pool
			log.Tracef("Requesting reservation for '%s'.", filePath)
			<-pool
			log.Tracef("Retrieved reservation for '%s'.", filePath)

			log.Infof("Starting sync: s3://%s/%s -> %s.", bucket.Name, file, filePath)
			wg.Add(1)
			go func() {
				defer wg.Done()
				getRoutine(doneChan, filePath, bucket, file)
				pool <- 1
			}()
		}
	}

	wg.Wait()
	return nil
}

func loadS3Files(bucket *s3.Bucket, path string, files map[string]string, marker string) (map[string]string, error) {
	data, err := bucket.List(path, "", marker, 0)
	if err != nil {
		return files, err
	}

	for i := range data.Contents {
		md5sum := strings.Trim(data.Contents[i].ETag, "\"")
		k := relativePath(path, data.Contents[i].Key)
		files[k] = md5sum
	}

	// Continue to call loadS3files and add
	// Files to map if next marker set
	if data.IsTruncated {
		lastKey := data.Contents[(len(data.Contents) - 1)].Key
		log.Infof("Results truncated, loading additional files via previous last key '%s'.", lastKey)
		loadS3Files(bucket, path, files, lastKey)
	}

	log.Debugf("Loaded '%d' files from S3.", len(files))
	log.Infof("Loading files from S3 complete.")
	return files, nil
}

func loadLocalFiles(path string) (map[string]string, error) {
	files := map[string]string{}

	loadMd5Sums := func(filePath string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			p := relativePath(path, filePath)

			buf, err := ioutil.ReadFile(filePath)
			if err != nil {
				return err
			}

			hasher := md5.New()
			hasher.Write(buf)
			md5sum := fmt.Sprintf("%x", hasher.Sum(nil))
			files[p] = md5sum
		}
		return nil
	}

	err := filepath.Walk(path, loadMd5Sums)

	return files, err
}

func (s *Sync) validPair() bool {
	if validTarget(s.Source) && validTarget(s.Target) {
		return true
	}
	return false
}

func validTarget(target string) bool {
	// Check for local file
	if pathExists(target) {
		return true
	}

	// Check for valid s3 url
	if validS3Url(target) {
		return true
	}

	return false
}

func validS3Url(path string) bool {
	return strings.HasPrefix(path, "s3://")
}

func pathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

func putRoutine(doneChan chan error, filePath string, bucket *s3.Bucket, file string) {
	err := Put(bucket, file, filePath)
	if err != nil {
		doneChan <- err
	}
	log.Infof("Sync completed successfully: %s -> s3://%s/%s.", filePath, bucket.Name, file)
	doneChan <- nil
}

func getRoutine(doneChan chan error, filePath string, bucket *s3.Bucket, file string) {
	err := Get(filePath, bucket, file)
	if err != nil {
		doneChan <- err
	}
	log.Infof("Sync completed successfully: s3://%s/%s -> %s.", bucket.Name, file, filePath)
	doneChan <- nil
}

func waitForRoutines(routines []chan string) {
	for _, r := range routines {
		msg := <-r
		log.Infof("%s", msg)
	}
}

func relativePath(path string, filePath string) string {
	if path == "." {
		return strings.TrimPrefix(filePath, "/")
	} else {
		return strings.TrimPrefix(strings.TrimPrefix(filePath, path), "/")
	}
}

func newDoneChan(concurrent int) chan error {
	// Panic on any errors
	doneChan := make(chan error, concurrent)
	go func() {
		for {
			select {
			case err := <-doneChan:
				if err != nil {
					panic(err.Error())
				}
			}
		}
	}()
	return doneChan
}
<commit_msg>bug fixes with new code<commit_after>package gosync

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"

	log "github.com/cihub/seelog"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

type Sync struct {
	Auth       aws.Auth
	Source     string
	Target     string
	Concurrent int
}

func NewSync(auth aws.Auth, source string, target string) *Sync {
	return &Sync{
		Auth:       auth,
		Source:     source,
		Target:     target,
		Concurrent: 1,
	}
}

func (s *Sync) Sync() error {
	if !s.validPair() {
		return errors.New("Invalid sync pair.")
	}

	if validS3Url(s.Source) {
		return s.syncS3ToDir()
	}
	return s.syncDirToS3()
}

func lookupBucket(bucketName string, auth aws.Auth) (*s3.Bucket, error) {
	log.Infof("Looking up region for bucket '%s'.", bucketName)

	var bucket *s3.Bucket = nil

	// Looking in each region for bucket
	// To do, make this less crusty and ghetto
	for region, _ := range aws.Regions {
		log.Debugf("Looking for bucket '%s' in '%s'.", bucketName, region)
		s3 := s3.New(auth, aws.Regions[region])
		b := s3.Bucket(bucketName)

		// If list return, bucket is valid in this region.
		_, err := b.List("", "", "", 0)
		if err == nil {
			log.Infof("Found bucket '%s' in '%s'.", bucketName, region)
			bucket = b
			break
		} else if err.Error() == "Get : 301 response missing Location header" {
			log.Debugf("Bucket '%s' not found in '%s'.", bucketName, region)
			continue
		} else {
			return nil, err
		}
	}

	if bucket != nil {
		return bucket, nil
	}

	return nil, fmt.Errorf("Bucket not found.")
}

func (s *Sync) syncDirToS3() error {
	log.Infof("Syncing to S3.")

	sourceFiles, err := loadLocalFiles(s.Source)
	if err != nil {
		return err
	}

	s3url := S3Url{Url: s.Target}
	path := s3url.Path()

	bucket, err := lookupBucket(s3url.Bucket(), s.Auth)
	if err != nil {
		return err
	}

	// Load files and do not specify marker to start
	targetFiles := make(map[string]string)
	targetFiles, err = loadS3Files(bucket, path, targetFiles, "")
	if err != nil {
		return err
	}

	return s.concurrentSyncDirToS3(s3url, bucket, targetFiles, sourceFiles)
}

func (s *Sync) concurrentSyncDirToS3(s3url S3Url, bucket *s3.Bucket, targetFiles, sourceFiles map[string]string) error {
	doneChan := newDoneChan(s.Concurrent)
	pool := newPool(s.Concurrent)
	var wg sync.WaitGroup

	for file, _ := range sourceFiles {
		if targetFiles[file] != sourceFiles[file] {
			filePath := strings.Join([]string{s.Source, file}, "/")
			keyPath := strings.Join([]string{s3url.Key(), file}, "/")

			// Get transfer reservation from pool
			log.Tracef("Requesting reservation for '%s'.", keyPath)
			<-pool
			log.Tracef("Retrieved reservation for '%s'.", keyPath)

			log.Infof("Starting sync: %s -> s3://%s/%s", filePath, bucket.Name, file)
			wg.Add(1)
			go func(doneChan chan error, filePath string, bucket *s3.Bucket, keyPath string) {
				defer wg.Done()
				putRoutine(doneChan, filePath, bucket, keyPath)
				pool <- 1
			}(doneChan, filePath, bucket, keyPath)
		}
	}

	// Wait for all routines to finish
	wg.Wait()
	return nil
}

func (s *Sync) syncS3ToDir() error {
	log.Infof("Syncing from S3.")

	s3url := S3Url{Url: s.Source}
	bucket, err := lookupBucket(s3url.Bucket(), s.Auth)
	if err != nil {
		return err
	}

	sourceFiles := make(map[string]string)
	sourceFiles, err = loadS3Files(bucket, s3url.Path(), sourceFiles, "")
	if err != nil {
		return err
	}

	targetFiles, err := loadLocalFiles(s.Target)
	if err != nil {
		return err
	}
	return s.concurrentSyncS3ToDir(s3url, bucket, targetFiles, sourceFiles)
}

func (s *Sync) concurrentSyncS3ToDir(s3url S3Url, bucket *s3.Bucket, targetFiles, sourceFiles map[string]string) error {
	doneChan := newDoneChan(s.Concurrent)
	pool := newPool(s.Concurrent)
	var wg sync.WaitGroup

	for file, _ := range sourceFiles {
		if targetFiles[file] != sourceFiles[file] {
			filePath := strings.Join([]string{s.Target, file}, "/")
			if filepath.Dir(filePath) != "." {
				err := os.MkdirAll(filepath.Dir(filePath), 0755)
				if err != nil {
					return err
				}
			}

			// Get transfer reservation from pool
			log.Tracef("Requesting reservation for '%s'.", filePath)
			<-pool
			log.Tracef("Retrieved reservation for '%s'.", filePath)

			log.Infof("Starting sync: s3://%s/%s -> %s.", bucket.Name, file, filePath)
			wg.Add(1)
			go func(doneChan chan error, filePath string, bucket *s3.Bucket, file string) {
				defer wg.Done()
				getRoutine(doneChan, filePath, bucket, file)
				pool <- 1
			}(doneChan, filePath, bucket, file)
		}
	}

	wg.Wait()
	return nil
}

func loadS3Files(bucket *s3.Bucket, path string, files map[string]string, marker string) (map[string]string, error) {
	data, err := bucket.List(path, "", marker, 0)
	if err != nil {
		return files, err
	}

	for i := range data.Contents {
		md5sum := strings.Trim(data.Contents[i].ETag, "\"")
		k := relativePath(path, data.Contents[i].Key)
		files[k] = md5sum
	}

	// Continue to call loadS3files and add
	// Files to map if next marker set
	if data.IsTruncated {
		lastKey := data.Contents[(len(data.Contents) - 1)].Key
		log.Infof("Results truncated, loading additional files via previous last key '%s'.", lastKey)
		loadS3Files(bucket, path, files, lastKey)
	}

	log.Debugf("Loaded '%d' files from S3.", len(files))
	log.Infof("Loading files from S3 complete.")
	return files, nil
}

func loadLocalFiles(path string) (map[string]string, error) {
	files := map[string]string{}

	loadMd5Sums := func(filePath string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			p := relativePath(path, filePath)

			buf, err := ioutil.ReadFile(filePath)
			if err != nil {
				return err
			}

			hasher := md5.New()
			hasher.Write(buf)
			md5sum := fmt.Sprintf("%x", hasher.Sum(nil))
			files[p] = md5sum
		}
		return nil
	}

	err := filepath.Walk(path, loadMd5Sums)

	return files, err
}

func (s *Sync) validPair() bool {
	if validTarget(s.Source) && validTarget(s.Target) {
		return true
	}
	return false
}

func validTarget(target string) bool {
	// Check for local file
	if pathExists(target) {
		return true
	}

	// Check for valid s3 url
	if validS3Url(target) {
		return true
	}

	return false
}

func validS3Url(path string) bool {
	return strings.HasPrefix(path, "s3://")
}

func pathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

func putRoutine(doneChan chan error, filePath string, bucket *s3.Bucket, file string) {
	err := Put(bucket, file, filePath)
	if err != nil {
		doneChan <- err
	}
	log.Infof("Sync completed successfully: %s -> s3://%s/%s.", filePath, bucket.Name, file)
	doneChan <- nil
}

func getRoutine(doneChan chan error, filePath string, bucket *s3.Bucket, file string) {
	err := Get(filePath, bucket, file)
	if err != nil {
		doneChan <- err
	}
	log.Infof("Sync completed successfully: s3://%s/%s -> %s.", bucket.Name, file, filePath)
	doneChan <- nil
}

func waitForRoutines(routines []chan string) {
	for _, r := range routines {
		msg := <-r
		log.Infof("%s", msg)
	}
}

func relativePath(path string, filePath string) string {
	if path == "." {
		return strings.TrimPrefix(filePath, "/")
	} else {
		return strings.TrimPrefix(strings.TrimPrefix(filePath, path), "/")
	}
}

func newDoneChan(concurrent int) chan error {
	// Panic on any errors
	doneChan := make(chan error, concurrent)
	go func() {
		for {
			select {
			case err := <-doneChan:
				if err != nil {
					panic(err.Error())
				}
			}
		}
	}()
	return doneChan
}
<|endoftext|>


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

package main

import (
	"bytes"
	"crypto/sha1"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var (
	verbose = flag.Bool("v", false, "print commands being run")
)

var goroot = runtime.GOROOT()

var binTools = []string{"go", "godoc", "gofmt"}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage:\n  %s [flags] save [name]\n  %s [flags] run name command...\n\nFlags:\n", os.Args[0], os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(2)
	}

	switch flag.Arg(0) {
	case "save":
		if flag.NArg() > 2 {
			flag.Usage()
			os.Exit(2)
		}
		hash, diff := getHash()
		name := ""
		if flag.NArg() >= 2 {
			name = flag.Arg(1)
		}
		doSave(name, hash, diff)

	case "run":
		if flag.NArg() < 3 {
			flag.Usage()
			os.Exit(2)
		}
		doRun(flag.Arg(1), flag.Args()[2:])

	default:
		flag.Usage()
		os.Exit(2)
	}
}

func getHash() (string, []byte) {
	c := exec.Command("git", "-C", goroot, "rev-parse", "--short", "HEAD")
	out, err := c.CombinedOutput()
	if err != nil {
		log.Fatalf("git error %s: %s", err, out)
	}

	rev := strings.TrimSpace(string(out))

	c = exec.Command("git", "-C", goroot, "diff", "HEAD")
	out, err = c.CombinedOutput()
	if err != nil {
		log.Fatal("git error %s: %s", err, out)
	}

	if len(bytes.TrimSpace(out)) > 0 {
		diffHash := fmt.Sprintf("%x", sha1.Sum(out))
		return rev + "+" + diffHash[:10], out
	}
	return rev, nil
}

func doSave(name string, hash string, diff []byte) {
	// Create a minimal GOROOT at $GOROOT/gover/hash.
	savePath := filepath.Join(goroot, "gover", hash)
	goos, goarch := runtime.GOOS, runtime.GOARCH
	if x := os.Getenv("GOOS"); x != "" {
		goos = x
	}
	if x := os.Getenv("GOARCH"); x != "" {
		goarch = x
	}
	osArch := goos + "_" + goarch

	for _, binTool := range binTools {
		cp(filepath.Join(goroot, "bin", binTool), filepath.Join(savePath, "bin", binTool))
	}
	cpR(filepath.Join(goroot, "pkg", osArch), filepath.Join(savePath, "pkg", osArch))
	cpR(filepath.Join(goroot, "pkg", "tool", osArch), filepath.Join(savePath, "pkg", "tool", osArch))

	if diff != nil {
		if err := ioutil.WriteFile(filepath.Join(savePath, "diff"), diff, 0666); err != nil {
			log.Fatal(err)
		}
	}

	// If there's a name, symlink it under that name.
	if name != "" {
		err := os.Symlink(hash, filepath.Join(goroot, "gover", name))
		if err != nil {
			log.Fatal(err)
		}
	}
}

func doRun(name string, cmd []string) {
	savePath := filepath.Join(goroot, "gover", name)

	c := exec.Command(filepath.Join(savePath, "bin", cmd[0]), cmd[1:]...)
	c.Env = append([]string(nil), os.Environ()...)
	c.Env = append(c.Env, "GOROOT="+savePath)

	c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
	if err := c.Run(); err != nil {
		fmt.Printf("command failed: %s\n", err)
		os.Exit(1)
	}
}

func cp(src, dst string) {
	if *verbose {
		fmt.Printf("cp %s %s\n", src, dst)
	}
	if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
		log.Fatal(err)
	}
	data, err := ioutil.ReadFile(src)
	if err != nil {
		log.Fatal(err)
	}
	st, err := os.Stat(src)
	if err != nil {
		log.Fatal(err)
	}
	if err := ioutil.WriteFile(dst, data, st.Mode()); err != nil {
		log.Fatal(err)
	}
}

func cpR(src, dst string) {
	filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		cp(path, dst+path[len(src):])
		return nil
	})
}
<commit_msg>gover: ignore missing bin files<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"crypto/sha1"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var (
	verbose = flag.Bool("v", false, "print commands being run")
)

var goroot = runtime.GOROOT()

var binTools = []string{"go", "godoc", "gofmt"}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage:\n  %s [flags] save [name]\n  %s [flags] run name command...\n\nFlags:\n", os.Args[0], os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()
	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(2)
	}

	switch flag.Arg(0) {
	case "save":
		if flag.NArg() > 2 {
			flag.Usage()
			os.Exit(2)
		}
		hash, diff := getHash()
		name := ""
		if flag.NArg() >= 2 {
			name = flag.Arg(1)
		}
		doSave(name, hash, diff)

	case "run":
		if flag.NArg() < 3 {
			flag.Usage()
			os.Exit(2)
		}
		doRun(flag.Arg(1), flag.Args()[2:])

	default:
		flag.Usage()
		os.Exit(2)
	}
}

func getHash() (string, []byte) {
	c := exec.Command("git", "-C", goroot, "rev-parse", "--short", "HEAD")
	out, err := c.CombinedOutput()
	if err != nil {
		log.Fatalf("git error %s: %s", err, out)
	}

	rev := strings.TrimSpace(string(out))

	c = exec.Command("git", "-C", goroot, "diff", "HEAD")
	out, err = c.CombinedOutput()
	if err != nil {
		log.Fatal("git error %s: %s", err, out)
	}

	if len(bytes.TrimSpace(out)) > 0 {
		diffHash := fmt.Sprintf("%x", sha1.Sum(out))
		return rev + "+" + diffHash[:10], out
	}
	return rev, nil
}

func doSave(name string, hash string, diff []byte) {
	// Create a minimal GOROOT at $GOROOT/gover/hash.
	savePath := filepath.Join(goroot, "gover", hash)
	goos, goarch := runtime.GOOS, runtime.GOARCH
	if x := os.Getenv("GOOS"); x != "" {
		goos = x
	}
	if x := os.Getenv("GOARCH"); x != "" {
		goarch = x
	}
	osArch := goos + "_" + goarch

	for _, binTool := range binTools {
		src := filepath.Join(goroot, "bin", binTool)
		if _, err := os.Stat(src); err == nil {
			cp(src, filepath.Join(savePath, "bin", binTool))
		}
	}
	cpR(filepath.Join(goroot, "pkg", osArch), filepath.Join(savePath, "pkg", osArch))
	cpR(filepath.Join(goroot, "pkg", "tool", osArch), filepath.Join(savePath, "pkg", "tool", osArch))

	if diff != nil {
		if err := ioutil.WriteFile(filepath.Join(savePath, "diff"), diff, 0666); err != nil {
			log.Fatal(err)
		}
	}

	// If there's a name, symlink it under that name.
	if name != "" {
		err := os.Symlink(hash, filepath.Join(goroot, "gover", name))
		if err != nil {
			log.Fatal(err)
		}
	}
}

func doRun(name string, cmd []string) {
	savePath := filepath.Join(goroot, "gover", name)

	c := exec.Command(filepath.Join(savePath, "bin", cmd[0]), cmd[1:]...)
	c.Env = append([]string(nil), os.Environ()...)
	c.Env = append(c.Env, "GOROOT="+savePath)

	c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
	if err := c.Run(); err != nil {
		fmt.Printf("command failed: %s\n", err)
		os.Exit(1)
	}
}

func cp(src, dst string) {
	if *verbose {
		fmt.Printf("cp %s %s\n", src, dst)
	}
	if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
		log.Fatal(err)
	}
	data, err := ioutil.ReadFile(src)
	if err != nil {
		log.Fatal(err)
	}
	st, err := os.Stat(src)
	if err != nil {
		log.Fatal(err)
	}
	if err := ioutil.WriteFile(dst, data, st.Mode()); err != nil {
		log.Fatal(err)
	}
}

func cpR(src, dst string) {
	filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		cp(path, dst+path[len(src):])
		return nil
	})
}
<|endoftext|>