<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/types"
)

var (
	buildContext = build.Default

	loaderConfig = loader.Config{
		TypeChecker: types.Config{FakeImportC: true},
		Build:       &buildContext,
		AllowErrors: true,
	}

	config *srcfileConfig

	goBinaryName string

	validVersions = []string{"", "1.3", "1.2", "1.1", "1"}

	// virtualCWD is the vfs cwd that corresponds to the non-vfs cwd, when using
	// vfs. It is used to determine whether a vfs path is effectively underneath
	// the cwd.
	virtualCWD string

	// dockerCWD is the original docker cwd before symlinking. If set (and if
	// running in Docker), it is used to determine whether a path is effectively
	// underneath the cwd.
	dockerCWD string

	// effectiveConfigGOPATHs is a list of GOPATH dirs that were
	// created as a result of the GOPATH config property. These are
	// the dirs that are appended to the actual build context GOPATH.
	effectiveConfigGOPATHs []string
)

func init() {
	if buildContext.GOPATH == "" {
		log.Fatal("GOPATH must be set.")
	}
}

// isInEffectiveConfigGOPATH is true if dir is underneath any of the
// dirs in effectiveConfigGOPATHs.
func isInEffectiveConfigGOPATH(dir string) bool {
	for _, gopath := range effectiveConfigGOPATHs {
		if pathHasPrefix(dir, gopath) {
			return true
		}
	}
	return false
}

type srcfileConfig struct {
	// GOROOT, if specified, is made absolute (prefixed with the
	// directory that the repository being built is checked out to)
	// and is set as the GOROOT environment variable.
	GOROOT string

	// GOPATH's colon-separated dirs, if specified, are made absolute
	// (prefixed with the directory that the repository being built is
	// checked out to) and the resulting value is appended to the
	// GOPATH environment variable during the build.
	GOPATH string

	// GOVERSION is the version of the go tool that srclib-go
	// should shell out to. If GOVERSION is empty, the system's
	// default go binary is used. The only valid values for
	// GOVERSION are the empty string, "1.3", "1.2", "1.1", and
	// "1", which are transformed into "go", "go1.3", ..., "go1",
	// respectively, when the binary is called.
	GOVERSION string

	PkgPatterns []string // pattern passed to `go list` (defaults to {"./..."})

	SourceImports bool
}

// unmarshalTypedConfig parses config from the Config field of the source unit.
// It stores it in the config global variable.
//
// Callers should typically call config.apply() after calling
// unmarshalTypedConfig to actually apply the config.
func unmarshalTypedConfig(cfg map[string]interface{}) error {
	data, err := json.Marshal(cfg)
	if err != nil {
		return err
	}

	if err := json.Unmarshal(data, &config); err != nil {
		return err
	}

	if config == nil {
		config = &srcfileConfig{}
	}

	return config.apply()
}

// apply applies the configuration.
func (c *srcfileConfig) apply() error {
	var versionValid bool
	for _, v := range validVersions {
		if config.GOVERSION == v {
			versionValid = true
			break
		}
	}
	if !versionValid {
		return fmt.Errorf("The version %s is not valid. Use one of the following: %v", config.GOVERSION, validVersions)
	}
	goBinaryName = fmt.Sprintf("go%s", config.GOVERSION)

	if config.GOROOT != "" {
		// clean/absolutize all paths
		config.GOROOT = filepath.Clean(config.GOROOT)
		if !filepath.IsAbs(config.GOROOT) {
			config.GOROOT = filepath.Join(cwd, config.GOROOT)
		}

		buildContext.GOROOT = c.GOROOT
		loaderConfig.Build = &buildContext
	}

	if config.GOPATH != "" {
		// clean/absolutize all paths
		dirs := uniq(strings.Split(config.GOPATH, ":"))
		for i, dir := range dirs {
			dir = filepath.Clean(dir)
			if !filepath.IsAbs(dir) {
				dir = filepath.Join(cwd, dir)
			}
			dirs[i] = dir
		}
		config.GOPATH = strings.Join(dirs, ":")

		buildContext.GOPATH += ":" + config.GOPATH
		loaderConfig.Build = &buildContext
	}

	loaderConfig.SourceImports = config.SourceImports

	return nil
}

func (c *srcfileConfig) env() []string {
	return []string{
		"PATH=" + os.Getenv("PATH"),
		"GOARCH=" + buildContext.GOARCH,
		"GOOS=" + buildContext.GOOS,
		"GOROOT=" + buildContext.GOROOT,
		"GOPATH=" + buildContext.GOPATH,
	}
}

func pathHasPrefix(path, prefix string) bool {
	return prefix == "." || path == prefix || strings.HasPrefix(path, prefix+"/")
}

// uniq maintains the order of s.
func uniq(s []string) []string {
	seen := make(map[string]struct{}, len(s))
	var uniq []string
	for _, s := range s {
		if _, seen := seen[s]; seen {
			continue
		}
		seen[s] = struct{}{}
		uniq = append(uniq, s)
	}
	return uniq
}
<commit_msg>look for GOROOT<version> if using a diff go ver<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/types"
)

var (
	buildContext = build.Default

	loaderConfig = loader.Config{
		TypeChecker: types.Config{FakeImportC: true},
		Build:       &buildContext,
		AllowErrors: true,
	}

	config *srcfileConfig

	goBinaryName string

	validVersions = []string{"", "1.3", "1.2", "1.1", "1"}

	// virtualCWD is the vfs cwd that corresponds to the non-vfs cwd, when using
	// vfs. It is used to determine whether a vfs path is effectively underneath
	// the cwd.
	virtualCWD string

	// dockerCWD is the original docker cwd before symlinking. If set (and if
	// running in Docker), it is used to determine whether a path is effectively
	// underneath the cwd.
	dockerCWD string

	// effectiveConfigGOPATHs is a list of GOPATH dirs that were
	// created as a result of the GOPATH config property. These are
	// the dirs that are appended to the actual build context GOPATH.
	effectiveConfigGOPATHs []string
)

func init() {
	if buildContext.GOPATH == "" {
		log.Fatal("GOPATH must be set.")
	}
}

// isInEffectiveConfigGOPATH is true if dir is underneath any of the
// dirs in effectiveConfigGOPATHs.
func isInEffectiveConfigGOPATH(dir string) bool {
	for _, gopath := range effectiveConfigGOPATHs {
		if pathHasPrefix(dir, gopath) {
			return true
		}
	}
	return false
}

type srcfileConfig struct {
	// GOROOT, if specified, is made absolute (prefixed with the
	// directory that the repository being built is checked out to)
	// and is set as the GOROOT environment variable.
	GOROOT string

	// GOPATH's colon-separated dirs, if specified, are made absolute
	// (prefixed with the directory that the repository being built is
	// checked out to) and the resulting value is appended to the
	// GOPATH environment variable during the build.
	GOPATH string

	// GOVERSION is the version of the go tool that srclib-go
	// should shell out to. If GOVERSION is empty, the system's
	// default go binary is used. The only valid values for
	// GOVERSION are the empty string, "1.3", "1.2", "1.1", and
	// "1", which are transformed into "go", "go1.3", ..., "go1",
	// respectively, when the binary is called.
	GOVERSION string

	PkgPatterns []string // pattern passed to `go list` (defaults to {"./..."})

	SourceImports bool
}

// unmarshalTypedConfig parses config from the Config field of the source unit.
// It stores it in the config global variable.
//
// Callers should typically call config.apply() after calling
// unmarshalTypedConfig to actually apply the config.
func unmarshalTypedConfig(cfg map[string]interface{}) error {
	data, err := json.Marshal(cfg)
	if err != nil {
		return err
	}

	if err := json.Unmarshal(data, &config); err != nil {
		return err
	}

	if config == nil {
		config = &srcfileConfig{}
	}

	return config.apply()
}

// apply applies the configuration.
func (c *srcfileConfig) apply() error {
	var versionValid bool
	for _, v := range validVersions {
		if config.GOVERSION == v {
			versionValid = true
			goBinaryName = fmt.Sprintf("go%s", config.GOVERSION)
			if config.GOVERSION != "" && config.GOROOT == "" {
				// If GOROOT is empty, assign $GOROOT<version_num> to it.
				newGOROOT := os.Getenv(fmt.Sprintf("GOROOT%s", strings.Replace(config.GOVERSION, ".", "", -1)))
				if newGOROOT != "" {
					config.GOROOT = newGOROOT
				}
			}
			break
		}
	}
	if !versionValid {
		return fmt.Errorf("The version %s is not valid. Use one of the following: %v", config.GOVERSION, validVersions)
	}

	if config.GOROOT != "" {
		// clean/absolutize all paths
		config.GOROOT = filepath.Clean(config.GOROOT)
		if !filepath.IsAbs(config.GOROOT) {
			config.GOROOT = filepath.Join(cwd, config.GOROOT)
		}

		buildContext.GOROOT = c.GOROOT
		loaderConfig.Build = &buildContext
	}

	if config.GOPATH != "" {
		// clean/absolutize all paths
		dirs := uniq(strings.Split(config.GOPATH, ":"))
		for i, dir := range dirs {
			dir = filepath.Clean(dir)
			if !filepath.IsAbs(dir) {
				dir = filepath.Join(cwd, dir)
			}
			dirs[i] = dir
		}
		config.GOPATH = strings.Join(dirs, ":")

		buildContext.GOPATH += ":" + config.GOPATH
		loaderConfig.Build = &buildContext
	}

	loaderConfig.SourceImports = config.SourceImports

	return nil
}

func (c *srcfileConfig) env() []string {
	return []string{
		"PATH=" + os.Getenv("PATH"),
		"GOARCH=" + buildContext.GOARCH,
		"GOOS=" + buildContext.GOOS,
		"GOROOT=" + buildContext.GOROOT,
		"GOPATH=" + buildContext.GOPATH,
	}
}

func pathHasPrefix(path, prefix string) bool {
	return prefix == "." || path == prefix || strings.HasPrefix(path, prefix+"/")
}

// uniq maintains the order of s.
func uniq(s []string) []string {
	seen := make(map[string]struct{}, len(s))
	var uniq []string
	for _, s := range s {
		if _, seen := seen[s]; seen {
			continue
		}
		seen[s] = struct{}{}
		uniq = append(uniq, s)
	}
	return uniq
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"runtime"

	"github.com/kormoc/ionice"
	flag "github.com/ogier/pflag"
	"gopkg.in/yaml.v2"
)

var config struct {
	BufferSize       int    `yaml:"bufferSize"`
	Checksums        string `yaml:"checksums"`
	ConsoleLevel     string `yaml:"consoleLevel"`
	IoniceClass      int    `yaml:"ioniceClass"`
	IoniceClassdata  int    `yaml:"ioniceClassdata"`
	LockfilePath     string `yaml:"lockfile"`
	LogfileLevel     string `yaml:"logfileLevel"`
	LogfilePath      string `yaml:"logfilePath"`
	MaxRunTime       int64  `yaml:"maxRunTime"`
	MtimeSettle      int64  `yaml:"mtimeSettle"`
	Nice             int    `yaml:"nice"`
	ResetXattrs      bool   `yaml:"resetXattrs"`
	SkipCreate       bool   `yaml:"skipCreate"`
	SkipValidation   bool   `yaml:"skipValidation"`
	UpdateOnNewMTime bool   `yaml:"updateOnNewMTime"`
	Version          bool   `yaml:"version"`
	WorkerCount      int    `yaml:"workerCount"`
	WorkerCountIO    int    `yaml:"workerCountIO"`
	XattrRoot        string `yaml:"xattrRoot"`
}

// Set defaults for the config struct
func init() {
	config.BufferSize = 2048
	config.Checksums = "sha512"
	config.ConsoleLevel = "warn"
	config.IoniceClass = int(ionice.IOPRIO_CLASS_IDLE)
	config.IoniceClassdata = 0
	config.LockfilePath = ""
	config.LogfileLevel = "warn"
	config.LogfilePath = ""
	config.MaxRunTime = 0
	config.MtimeSettle = 1800
	config.Nice = 20
	config.ResetXattrs = false
	config.SkipCreate = false
	config.SkipValidation = false
	config.UpdateOnNewMTime = false
	config.Version = false
	config.WorkerCount = 0
	config.WorkerCountIO = 1
	config.XattrRoot = "user.checksum."
}

func processFlags() (err error) {
	var configData []byte
	configData, err = ioutil.ReadFile("/etc/bitrot-scanner.yaml")
	if err == nil {
		err = yaml.Unmarshal(configData, &config)
		if err != nil {
			return
		}
	}

	flag.BoolVar(&config.ResetXattrs, "resetXattrs", config.ResetXattrs, "Don't checksum, just reset any potential checksums")
	flag.BoolVar(&config.SkipCreate, "skipCreate", config.SkipCreate, "Skip creating new hashes. Useful for just validating existing hashes")
	flag.BoolVar(&config.SkipValidation, "skipValidation", config.SkipValidation, "Skip validating existing hashes. Useful to just generate for new files")
	flag.BoolVar(&config.UpdateOnNewMTime, "updateOnNewMTime", config.UpdateOnNewMTime, "Update hashes if mtime is newer then last check time")
	flag.BoolVar(&config.Version, "version", config.Version, "Display the version")
	flag.Int64Var(&config.MaxRunTime, "maxRunTime", config.MaxRunTime, "Stop queueing new jobs after maxRunTime seconds. 0 to disable")
	flag.Int64Var(&config.MtimeSettle, "mtimeSettle", config.MtimeSettle, "Don't create a hash until the mtime is at least this many seconds old")
	flag.IntVar(&config.BufferSize, "bufferSize", config.BufferSize, "Read buffer size in blocks")
	flag.IntVar(&config.IoniceClass, "ioniceClass", config.IoniceClass, "ionice class. 0: none, 1: realtime, 2: best-effort, 3: idle")
	flag.IntVar(&config.IoniceClassdata, "ioniceClassdata", config.IoniceClassdata, "ionice classdata. Only useful for realtime/best-effort")
	flag.IntVar(&config.Nice, "nice", config.Nice, "Nice value to use")
	flag.IntVar(&config.WorkerCount, "workerCount", config.WorkerCount, "Maximum number of workers per stage to use for scanning for all other stages. 0 to detect and use the number of cpu cores")
	flag.IntVar(&config.WorkerCountIO, "workerCountIO", config.WorkerCountIO, "Maximum number of workers to use for reading file data. 0 to detect and use the number of cpu cores")
	flag.StringVar(&config.Checksums, "checksums", config.Checksums, "Which checksum(s) algorithm to use. Comma delimited")
	flag.StringVar(&config.ConsoleLevel, "consoleLevel", config.ConsoleLevel, "Log level for console output. error, warn, verbose, debug")
	flag.StringVar(&config.LockfilePath, "lockfile", config.LockfilePath, "Path to use for a lockfile")
	flag.StringVar(&config.LogfileLevel, "logfileLevel", config.LogfileLevel, "Log level for log file. error, warn, verbose, debug")
	flag.StringVar(&config.LogfilePath, "logfilePath", config.LogfilePath, "Path to logfile")
	flag.StringVar(&config.XattrRoot, "xattrRoot", config.XattrRoot, "base xattr path for checksums")

	flag.Parse()

	if config.WorkerCount == 0 {
		config.WorkerCount = runtime.NumCPU()
	}
	if config.WorkerCount < 1 {
		config.WorkerCount = 1
	}

	if config.WorkerCountIO == 0 {
		config.WorkerCountIO = runtime.NumCPU()
	}
	if config.WorkerCountIO < 1 {
		config.WorkerCountIO = 1
	}

	return
}
<commit_msg>Remove unused import<commit_after>package main

import (
	"io/ioutil"
	"runtime"

	"github.com/kormoc/ionice"
	flag "github.com/ogier/pflag"
	"gopkg.in/yaml.v2"
)

var config struct {
	BufferSize       int    `yaml:"bufferSize"`
	Checksums        string `yaml:"checksums"`
	ConsoleLevel     string `yaml:"consoleLevel"`
	IoniceClass      int    `yaml:"ioniceClass"`
	IoniceClassdata  int    `yaml:"ioniceClassdata"`
	LockfilePath     string `yaml:"lockfile"`
	LogfileLevel     string `yaml:"logfileLevel"`
	LogfilePath      string `yaml:"logfilePath"`
	MaxRunTime       int64  `yaml:"maxRunTime"`
	MtimeSettle      int64  `yaml:"mtimeSettle"`
	Nice             int    `yaml:"nice"`
	ResetXattrs      bool   `yaml:"resetXattrs"`
	SkipCreate       bool   `yaml:"skipCreate"`
	SkipValidation   bool   `yaml:"skipValidation"`
	UpdateOnNewMTime bool   `yaml:"updateOnNewMTime"`
	Version          bool   `yaml:"version"`
	WorkerCount      int    `yaml:"workerCount"`
	WorkerCountIO    int    `yaml:"workerCountIO"`
	XattrRoot        string `yaml:"xattrRoot"`
}

// Set defaults for the config struct
func init() {
	config.BufferSize = 2048
	config.Checksums = "sha512"
	config.ConsoleLevel = "warn"
	config.IoniceClass = int(ionice.IOPRIO_CLASS_IDLE)
	config.IoniceClassdata = 0
	config.LockfilePath = ""
	config.LogfileLevel = "warn"
	config.LogfilePath = ""
	config.MaxRunTime = 0
	config.MtimeSettle = 1800
	config.Nice = 20
	config.ResetXattrs = false
	config.SkipCreate = false
	config.SkipValidation = false
	config.UpdateOnNewMTime = false
	config.Version = false
	config.WorkerCount = 0
	config.WorkerCountIO = 1
	config.XattrRoot = "user.checksum."
}

func processFlags() (err error) {
	var configData []byte
	configData, err = ioutil.ReadFile("/etc/bitrot-scanner.yaml")
	if err == nil {
		err = yaml.Unmarshal(configData, &config)
		if err != nil {
			return
		}
	}

	flag.BoolVar(&config.ResetXattrs, "resetXattrs", config.ResetXattrs, "Don't checksum, just reset any potential checksums")
	flag.BoolVar(&config.SkipCreate, "skipCreate", config.SkipCreate, "Skip creating new hashes. Useful for just validating existing hashes")
	flag.BoolVar(&config.SkipValidation, "skipValidation", config.SkipValidation, "Skip validating existing hashes. Useful to just generate for new files")
	flag.BoolVar(&config.UpdateOnNewMTime, "updateOnNewMTime", config.UpdateOnNewMTime, "Update hashes if mtime is newer then last check time")
	flag.BoolVar(&config.Version, "version", config.Version, "Display the version")
	flag.Int64Var(&config.MaxRunTime, "maxRunTime", config.MaxRunTime, "Stop queueing new jobs after maxRunTime seconds. 0 to disable")
	flag.Int64Var(&config.MtimeSettle, "mtimeSettle", config.MtimeSettle, "Don't create a hash until the mtime is at least this many seconds old")
	flag.IntVar(&config.BufferSize, "bufferSize", config.BufferSize, "Read buffer size in blocks")
	flag.IntVar(&config.IoniceClass, "ioniceClass", config.IoniceClass, "ionice class. 0: none, 1: realtime, 2: best-effort, 3: idle")
	flag.IntVar(&config.IoniceClassdata, "ioniceClassdata", config.IoniceClassdata, "ionice classdata. Only useful for realtime/best-effort")
	flag.IntVar(&config.Nice, "nice", config.Nice, "Nice value to use")
	flag.IntVar(&config.WorkerCount, "workerCount", config.WorkerCount, "Maximum number of workers per stage to use for scanning for all other stages. 0 to detect and use the number of cpu cores")
	flag.IntVar(&config.WorkerCountIO, "workerCountIO", config.WorkerCountIO, "Maximum number of workers to use for reading file data. 0 to detect and use the number of cpu cores")
	flag.StringVar(&config.Checksums, "checksums", config.Checksums, "Which checksum(s) algorithm to use. Comma delimited")
	flag.StringVar(&config.ConsoleLevel, "consoleLevel", config.ConsoleLevel, "Log level for console output. error, warn, verbose, debug")
	flag.StringVar(&config.LockfilePath, "lockfile", config.LockfilePath, "Path to use for a lockfile")
	flag.StringVar(&config.LogfileLevel, "logfileLevel", config.LogfileLevel, "Log level for log file. error, warn, verbose, debug")
	flag.StringVar(&config.LogfilePath, "logfilePath", config.LogfilePath, "Path to logfile")
	flag.StringVar(&config.XattrRoot, "xattrRoot", config.XattrRoot, "base xattr path for checksums")

	flag.Parse()

	if config.WorkerCount == 0 {
		config.WorkerCount = runtime.NumCPU()
	}
	if config.WorkerCount < 1 {
		config.WorkerCount = 1
	}

	if config.WorkerCountIO == 0 {
		config.WorkerCountIO = runtime.NumCPU()
	}
	if config.WorkerCountIO < 1 {
		config.WorkerCountIO = 1
	}

	return
}
<|endoftext|>


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

// Package log provides the canonical logging functionality used by Go-based
// Istio components.
//
// Istio's logging subsystem is built on top of the [Zap](https://godoc.org/go.uber.org/zap) package.
// High performance scenarios should use the Error, Warn, Info, and Debug methods. Lower perf
// scenarios can use the more expensive convenience methods such as Debugf and Warnw.
//
// The package provides direct integration with the Cobra command-line processor which makes it
// easy to build programs that use a consistent interface for logging. Here's an example
// of a simple Cobra-based program using this log package:
//
//		func main() {
//			// get the default logging options
//			options := log.NewOptions()
//
//			rootCmd := &cobra.Command{
//				Run: func(cmd *cobra.Command, args []string) {
//
//					// configure the logging system
//					if err := log.Configure(options); err != nil {
//                      // print an error and quit
//                  }
//
//					// output some logs
//					log.Info("Hello")
//					log.Sync()
//				},
//			}
//
//			// add logging-specific flags to the cobra command
//			options.AttachCobraFlags(rootCmd)
//			rootCmd.SetArgs(os.Args[1:])
//			rootCmd.Execute()
//		}
//
// Once configured, this package intercepts the output of the standard golang "log" package as well as anything
// sent to the global zap logger (zap.L()).
package log

import (
	"github.com/natefinch/lumberjack"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"go.uber.org/zap/zapgrpc"
	"google.golang.org/grpc/grpclog"
)

// Configure initializes Istio's logging subsystem.
//
// You typically call this once at process startup.
// Once this call returns, the logging system is ready to accept data.
func Configure(options *Options) error {
	outputLevel, err := options.GetOutputLevel()
	if err != nil {
		// bad format specified
		return err
	}

	stackTraceLevel, err := options.GetStackTraceLevel()
	if err != nil {
		// bad format specified
		return err
	}

	if outputLevel == None || ((len(options.OutputPaths) == 0) && options.RotateOutputPath == "") {
		// stick with the Nop default
		logger = zap.NewNop()
		sugar = logger.Sugar()
		return nil
	}

	encCfg := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stack",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
		EncodeDuration: zapcore.StringDurationEncoder,
		EncodeTime:     formatDate,
	}

	var enc zapcore.Encoder
	if options.JSONEncoding {
		enc = zapcore.NewJSONEncoder(encCfg)
	} else {
		enc = zapcore.NewConsoleEncoder(encCfg)
	}

	var rotaterSink zapcore.WriteSyncer
	if options.RotateOutputPath != "" {
		rotaterSink = zapcore.AddSync(&lumberjack.Logger{
			Filename:   options.RotateOutputPath,
			MaxSize:    options.RotationMaxSize,
			MaxBackups: options.RotationMaxAge,
			MaxAge:     options.RotationMaxBackups,
		})
	}

	errSink, closeErrorSink, err := zap.Open(options.ErrorOutputPaths...)
	if err != nil {
		return err
	}

	var outputSink zapcore.WriteSyncer
	if len(options.OutputPaths) > 0 {
		outputSink, _, err = zap.Open(options.OutputPaths...)
		if err != nil {
			closeErrorSink()
			return err
		}
	}

	var sink zapcore.WriteSyncer
	if rotaterSink != nil && outputSink != nil {
		sink = zapcore.NewMultiWriteSyncer(outputSink, rotaterSink)
	} else if rotaterSink != nil {
		sink = rotaterSink
	} else {
		sink = outputSink
	}

	opts := []zap.Option{zap.ErrorOutput(errSink)}

	if options.IncludeCallerSourceLocation {
		opts = append(opts, zap.AddCaller())
	}

	if stackTraceLevel != None {
		opts = append(opts, zap.AddStacktrace(stackTraceLevel))
	}

	l := zap.New(
		zapcore.NewCore(enc, sink, zap.NewAtomicLevelAt(outputLevel)),
		opts...,
	)

	logger = l.WithOptions(zap.AddCallerSkip(1), zap.AddStacktrace(stackTraceLevel))
	sugar = logger.Sugar()

	// capture global zap logging and force it through our logger
	_ = zap.ReplaceGlobals(l)

	// capture standard golang "log" package output and force it through our logger
	_ = zap.RedirectStdLog(logger)

	// capture gRPC logging
	grpclog.SetLogger(zapgrpc.NewLogger(logger.WithOptions(zap.AddCallerSkip(2))))

	return nil
}
<commit_msg>Polish on the build (#2331)<commit_after>// Copyright 2017 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package log provides the canonical logging functionality used by Go-based
// Istio components.
//
// Istio's logging subsystem is built on top of the [Zap](https://godoc.org/go.uber.org/zap) package.
// High performance scenarios should use the Error, Warn, Info, and Debug methods. Lower perf
// scenarios can use the more expensive convenience methods such as Debugf and Warnw.
//
// The package provides direct integration with the Cobra command-line processor which makes it
// easy to build programs that use a consistent interface for logging. Here's an example
// of a simple Cobra-based program using this log package:
//
//		func main() {
//			// get the default logging options
//			options := log.NewOptions()
//
//			rootCmd := &cobra.Command{
//				Run: func(cmd *cobra.Command, args []string) {
//
//					// configure the logging system
//					if err := log.Configure(options); err != nil {
//                      // print an error and quit
//                  }
//
//					// output some logs
//					log.Info("Hello")
//					log.Sync()
//				},
//			}
//
//			// add logging-specific flags to the cobra command
//			options.AttachCobraFlags(rootCmd)
//			rootCmd.SetArgs(os.Args[1:])
//			rootCmd.Execute()
//		}
//
// Once configured, this package intercepts the output of the standard golang "log" package as well as anything
// sent to the global zap logger (zap.L()).
package log

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"go.uber.org/zap/zapgrpc"
	"google.golang.org/grpc/grpclog"
)

// Configure initializes Istio's logging subsystem.
//
// You typically call this once at process startup.
// Once this call returns, the logging system is ready to accept data.
func Configure(options *Options) error {
	outputLevel, err := options.GetOutputLevel()
	if err != nil {
		// bad format specified
		return err
	}

	stackTraceLevel, err := options.GetStackTraceLevel()
	if err != nil {
		// bad format specified
		return err
	}

	if outputLevel == None || ((len(options.OutputPaths) == 0) && options.RotateOutputPath == "") {
		// stick with the Nop default
		logger = zap.NewNop()
		sugar = logger.Sugar()
		return nil
	}

	encCfg := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stack",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
		EncodeDuration: zapcore.StringDurationEncoder,
		EncodeTime:     formatDate,
	}

	var enc zapcore.Encoder
	if options.JSONEncoding {
		enc = zapcore.NewJSONEncoder(encCfg)
	} else {
		enc = zapcore.NewConsoleEncoder(encCfg)
	}

	var rotaterSink zapcore.WriteSyncer
	if options.RotateOutputPath != "" {
		rotaterSink = zapcore.AddSync(&lumberjack.Logger{
			Filename:   options.RotateOutputPath,
			MaxSize:    options.RotationMaxSize,
			MaxBackups: options.RotationMaxAge,
			MaxAge:     options.RotationMaxBackups,
		})
	}

	errSink, closeErrorSink, err := zap.Open(options.ErrorOutputPaths...)
	if err != nil {
		return err
	}

	var outputSink zapcore.WriteSyncer
	if len(options.OutputPaths) > 0 {
		outputSink, _, err = zap.Open(options.OutputPaths...)
		if err != nil {
			closeErrorSink()
			return err
		}
	}

	var sink zapcore.WriteSyncer
	if rotaterSink != nil && outputSink != nil {
		sink = zapcore.NewMultiWriteSyncer(outputSink, rotaterSink)
	} else if rotaterSink != nil {
		sink = rotaterSink
	} else {
		sink = outputSink
	}

	opts := []zap.Option{zap.ErrorOutput(errSink)}

	if options.IncludeCallerSourceLocation {
		opts = append(opts, zap.AddCaller())
	}

	if stackTraceLevel != None {
		opts = append(opts, zap.AddStacktrace(stackTraceLevel))
	}

	l := zap.New(
		zapcore.NewCore(enc, sink, zap.NewAtomicLevelAt(outputLevel)),
		opts...,
	)

	logger = l.WithOptions(zap.AddCallerSkip(1), zap.AddStacktrace(stackTraceLevel))
	sugar = logger.Sugar()

	// capture global zap logging and force it through our logger
	_ = zap.ReplaceGlobals(l)

	// capture standard golang "log" package output and force it through our logger
	_ = zap.RedirectStdLog(logger)

	// capture gRPC logging
	grpclog.SetLogger(zapgrpc.NewLogger(logger.WithOptions(zap.AddCallerSkip(2))))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
)

var cfgfile string = "./pushovercfg.json"

type GConfig struct {
	Notifications Notifiers
	Watches   []WatchFile
}

type WatchFile struct {
	Path         string
	TriggerWords []string
}

type Notifiers struct {
	PushOver NPushOver
	PushAlot NPushAlot
}

/* Notifiers */
type NPushOver struct {
	UserToken string
	AppToken  string
}

type NPushAlot struct {
	Token string
}

func GetDefaultConfig() GConfig {
	var tfg GConfig
	tfg.Watches = make([]WatchFile, 0)
	defaultwatch := WatchFile{
		Path: "/var/log/auth.log",
		TriggerWords: []string{
			"Accepted publickey",
			"Accepted password",
		},
	}
	tfg.Watches = append(tfg.Watches, defaultwatch)

	var nfr Notifiers
	var pusho NPushOver
	var pusha NPushAlot

	pusho.UserToken = "token"
	pusho.AppToken = "token"
	nfr.PushOver = pusho

	pusha.Token = "token"
	nfr.PushAlot = pusha

	tfg.Notifications = nfr
	return tfg
}

func CheckIfResetConfig(args []string) {
	if len(args) == 2 {
		if args[1] == "reset" {
			e := os.Remove(cfgfile)
			if e != nil {
				log.Fatal("Could not remove current config file. Permissions issue?")
			}
			Default := GetDefaultConfig()
			out, e := json.Marshal(Default)
			e = ioutil.WriteFile(cfgfile, out, 600)
			if e != nil {
				log.Fatal("cannot open settings file :(")
			}
			log.Fatal("Built config file. please fill it in.")
		}
	}
}

func GetCFG() GConfig {
	b, e := ioutil.ReadFile(cfgfile)
	tfg := GetDefaultConfig()
	if e != nil {
		out, e := json.Marshal(tfg)
		e = ioutil.WriteFile(cfgfile, out, 600)
		if e != nil {
			log.Fatal("cannot open settings file :(")
		}
		log.Fatal("Built config file. please fill it in.")
	}

	e = json.Unmarshal(b, &tfg)
	if e != nil {
		log.Fatalf("Could not parse config settings. You may have to remove ./.pushovercfg.json")
	}
	//if tfg.Notifications.PushOver.UserToken == "Fillmein" || tfg.Notifications.PushOver.AppToken == "Fillmein" {
		log.Fatal("You need to fill in the config settings in %s", cfgfile)
	//}
	return tfg
}
<commit_msg>Removed debug code<commit_after>package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
)

var cfgfile string = "./pushovercfg.json"

type GConfig struct {
	Notifications Notifiers
	Watches   []WatchFile
}

type WatchFile struct {
	Path         string
	TriggerWords []string
}

type Notifiers struct {
	PushOver NPushOver
	PushAlot NPushAlot
}

/* Notifiers */
type NPushOver struct {
	UserToken string
	AppToken  string
}

type NPushAlot struct {
	Token string
}

func GetDefaultConfig() GConfig {
	var tfg GConfig
	tfg.Watches = make([]WatchFile, 0)
	defaultwatch := WatchFile{
		Path: "/var/log/auth.log",
		TriggerWords: []string{
			"Accepted publickey",
			"Accepted password",
		},
	}
	tfg.Watches = append(tfg.Watches, defaultwatch)

	var nfr Notifiers
	var pusho NPushOver
	var pusha NPushAlot

	pusho.UserToken = "token"
	pusho.AppToken = "token"
	nfr.PushOver = pusho

	pusha.Token = "token"
	nfr.PushAlot = pusha

	tfg.Notifications = nfr
	return tfg
}

func CheckIfResetConfig(args []string) {
	if len(args) == 2 {
		if args[1] == "reset" {
			e := os.Remove(cfgfile)
			if e != nil {
				log.Fatal("Could not remove current config file. Permissions issue?")
			}
			Default := GetDefaultConfig()
			out, e := json.Marshal(Default)
			e = ioutil.WriteFile(cfgfile, out, 600)
			if e != nil {
				log.Fatal("cannot open settings file :(")
			}
			log.Fatal("Built config file. please fill it in.")
		}
	}
}

func GetCFG() GConfig {
	b, e := ioutil.ReadFile(cfgfile)
	tfg := GetDefaultConfig()
	if e != nil {
		out, e := json.Marshal(tfg)
		e = ioutil.WriteFile(cfgfile, out, 600)
		if e != nil {
			log.Fatal("cannot open settings file :(")
		}
		log.Fatal("Built config file. please fill it in.")
	}

	e = json.Unmarshal(b, &tfg)
	if e != nil {
		log.Fatalf("Could not parse config settings. You may have to remove ./.pushovercfg.json")
	}
	return tfg
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"io/ioutil"
)

type Config struct {
	Directory      string   `json:"directory"`
	SupportedTypes []string `json:"supportedTypes"`
}

func MakeDefaultConfig(directory string) Config {
	ret := Config{}
	ret.Directory = directory
	ret.SupportedTypes = []string{"png", "jpg"}
	return ret
}

func ConfigFromFile(filePath string) (Config, error) {
	//TODO
	return Config{}, nil
}

func (c *Config) WriteToFile(filePath string) error {
	jsonBytes, err := json.MarshalIndent(c, "", "\t")
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filePath, jsonBytes, 0755)
	if err != nil {
		return err
	}
	return nil
}

func (c *Config) ToJson() ([]byte, error) {
	return json.MarshalIndent(c, "", "\t")
}
<commit_msg>add sizes to config, read config from file<commit_after>package main

import (
	"encoding/json"
	"io/ioutil"
)

type Config struct {
	Directory      string   `json:"directory"`
	SupportedTypes []string `json:"supportedTypes"`
	SupportedSizes []string `json:"supportedSizes"`
}

func MakeDefaultConfig(directory string) Config {
	ret := Config{}
	ret.Directory = directory
	ret.SupportedTypes = []string{"png", "jpg"}
	ret.SupportedSizes = []string{"200x200", "300x300"}
	return ret
}

func ConfigFromFile(filePath string) (Config, error) {
	jsonContent, err := ioutil.ReadFile(filePath)
	if err != nil {
		return  Config{}, err
	}
	var config Config
	err = json.Unmarshal(jsonContent, &config)
	if err != nil {
		return Config{}, err
	}
	return config, nil
}

func (c *Config) WriteToFile(filePath string) error {
	jsonBytes, err := json.MarshalIndent(c, "", "\t")
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filePath, jsonBytes, 0755)
	if err != nil {
		return err
	}
	return nil
}

func (c *Config) ToJson() ([]byte, error) {
	return json.MarshalIndent(c, "", "\t")
}
<|endoftext|>


<commit_before>package main

var config = struct {
	AWSRegion          string
	Bucket             string
	AWSAccessKeyID     string
	AWSSecretAccessKey string
	FilesToUpload      []string
}{
	"us-west-2",
	"MY-BUCKET",
	"",
	"",
	[]string{"test.txt", "test2.txt"},
}
<commit_msg>Change example filenames<commit_after>package main

var config = struct {
	AWSRegion          string
	Bucket             string
	AWSAccessKeyID     string
	AWSSecretAccessKey string
	FilesToUpload      []string
}{
	"us-west-2",
	"MY-BUCKET",
	"",
	"",
	[]string{"README.md", "test.txt"},
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/msbranco/goconfig"
	"log"
	"log/syslog"
	"os"
	"strings"
)

type TurtleConfig struct {
	syslogLog                  *syslog.Writer
	DequeueMongoHref            string
	DequeueMongoDatabaseName    string
	DequeueMongoCollectionName  string
	DequeueAmqpHref             string
}

func NewTurtleConfig(syslogLog *syslog.Writer) (*TurtleConfig, error) {

	//DEBUG
	syslogLog.Notice("    [CONFIG] BEGIN.")

	cmdPath := os.Args[0]
	cmdPathLastSlash := strings.LastIndexFunc(cmdPath, func(c rune) bool {
		return '/' == c
	})

	cmdDirPath := cmdPath[0:cmdPathLastSlash]

	//DEBUG
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command path: [%v]", cmdPath)  )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command path last slash: [%v]", cmdPathLastSlash) )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command dir path: [%v]", cmdDirPath) )

	confRelativePath := "turtledq.ini"
	confPath := cmdDirPath + "/" + confRelativePath

	//DEBUG
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] settings file relative path: [%v]", confRelativePath) )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] settings file absolute path: [%v]", confPath) )

	return NewTurtleConfigFromFile(syslogLog, confPath)
}

func NewTurtleConfigFromFile(syslogLog *syslog.Writer, configPath string) (*TurtleConfig, error) {

	me := TurtleConfig{syslogLog: syslogLog}

	//c, err := configfile.ReadConfigFile(configPath);
	c, err := goconfig.ReadConfigFile(configPath);
	if nil != err {
		errMsg := fmt.Sprintf("Error when trying to read config file: err = [%v]", err)
		me.syslogLog.Err(errMsg)
		log.Fatal(errMsg)
/////////////// RETURN
		return nil, err
	}

	//DEBUG
	me.syslogLog.Notice( fmt.Sprintf("    [CONFIG] config file: [%v]", c) )

	// Check for use_instead
		useInstead, err := c.GetString("default", "use_instead")

		if nil == err && "" != useInstead {
			//DEBUG
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] Have use_instead = [%v]", useInstead)  )

/////////////////////// RETURN
			return NewTurtleConfigFromFile(syslogLog, useInstead,)
		}

		//DEBUG
		me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] use_instead = [%v]", useInstead)  )

	// Get banal configs.
		me.DequeueMongoHref, err = c.GetString("dequeue", "mongo_href")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_href")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_href = [%v]", me.DequeueMongoHref)  )
		}

		me.DequeueMongoDatabaseName, err = c.GetString("dequeue", "mongo_database_name")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_database_name")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_database_name = [%v]", me.DequeueMongoDatabaseName)  )
		}

		me.DequeueMongoCollectionName, err = c.GetString("dequeue", "mongo_collection_name")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_collection_name")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_collection_name = [%v]", me.DequeueMongoCollectionName)  )
		}

		me.DequeueAmqpHref, err = c.GetString("dequeue", "dequeue_amqp_href")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].dequeue_amqp_href")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].dequeue_amqp_href = [%v]", me.DequeueAmqpHref)  )
		}

	//DEBUG
	me.syslogLog.Notice("    [CONFIG] END.")

	// Return.
		return &me, nil
}
<commit_msg>change to config name<commit_after>package main

import (
	"fmt"
	"github.com/msbranco/goconfig"
	"log"
	"log/syslog"
	"os"
	"strings"
)

type TurtleConfig struct {
	syslogLog                  *syslog.Writer
	DequeueMongoHref            string
	DequeueMongoDatabaseName    string
	DequeueMongoCollectionName  string
	DequeueAmqpHref             string
}

func NewTurtleConfig(syslogLog *syslog.Writer) (*TurtleConfig, error) {

	//DEBUG
	syslogLog.Notice("    [CONFIG] BEGIN.")

	cmdPath := os.Args[0]
	cmdPathLastSlash := strings.LastIndexFunc(cmdPath, func(c rune) bool {
		return '/' == c
	})

	cmdDirPath := cmdPath[0:cmdPathLastSlash]

	//DEBUG
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command path: [%v]", cmdPath)  )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command path last slash: [%v]", cmdPathLastSlash) )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] command dir path: [%v]", cmdDirPath) )

	confRelativePath := "turtledq.ini"
	confPath := cmdDirPath + "/" + confRelativePath

	//DEBUG
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] settings file relative path: [%v]", confRelativePath) )
	syslogLog.Notice( fmt.Sprintf("    [CONFIG] settings file absolute path: [%v]", confPath) )

	return NewTurtleConfigFromFile(syslogLog, confPath)
}

func NewTurtleConfigFromFile(syslogLog *syslog.Writer, configPath string) (*TurtleConfig, error) {

	me := TurtleConfig{syslogLog: syslogLog}

	//c, err := configfile.ReadConfigFile(configPath);
	c, err := goconfig.ReadConfigFile(configPath);
	if nil != err {
		errMsg := fmt.Sprintf("Error when trying to read config file: err = [%v]", err)
		me.syslogLog.Err(errMsg)
		log.Fatal(errMsg)
/////////////// RETURN
		return nil, err
	}

	//DEBUG
	me.syslogLog.Notice( fmt.Sprintf("    [CONFIG] config file: [%v]", c) )

	// Check for use_instead
		useInstead, err := c.GetString("default", "use_instead")

		if nil == err && "" != useInstead {
			//DEBUG
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] Have use_instead = [%v]", useInstead)  )

/////////////////////// RETURN
			return NewTurtleConfigFromFile(syslogLog, useInstead,)
		}

		//DEBUG
		me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] use_instead = [%v]", useInstead)  )

	// Get banal configs.
		me.DequeueMongoHref, err = c.GetString("dequeue", "mongo_href")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_href")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_href = [%v]", me.DequeueMongoHref)  )
		}

		me.DequeueMongoDatabaseName, err = c.GetString("dequeue", "mongo_database_name")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_database_name")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_database_name = [%v]", me.DequeueMongoDatabaseName)  )
		}

		me.DequeueMongoCollectionName, err = c.GetString("dequeue", "mongo_collection_name")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].mongo_collection_name")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].mongo_collection_name = [%v]", me.DequeueMongoCollectionName)  )
		}

		me.DequeueAmqpHref, err = c.GetString("dequeue", "amqp_href")
		if nil != err {
			me.syslogLog.Notice("    [CONFIG] NO [deueue].amqp_href")
		} else {
			me.syslogLog.Notice(  fmt.Sprintf("    [CONFIG] [deueue].amqp_href = [%v]", me.DequeueAmqpHref)  )
		}

	//DEBUG
	me.syslogLog.Notice("    [CONFIG] END.")

	// Return.
		return &me, nil
}
<|endoftext|>


<commit_before>package main

import (
	"regexp"
	"time"
)

const (
	VERSION                 = "0.3.3"
	DEFAULT_INTERVAL        = "10s"                                                              // Default tick interval for pollers
	DEFAULT_OUTPUTTER       = "stdoutl2metder"                                                   // Default outputter
	DEFAULT_POLLERS         = "conntrack,cpu,df,disk,listen,load,mem,nif,ntpdate,processes,self" // Default pollers
	DEFAULT_PROFILE_PORT    = "0"                                                                // Default profile port, 0 disables
	DEFAULT_DF_TYPES        = "btrfs,ext3,ext4,tmpfs,xfs"                                        // Default fs types to report df for
	DEFAULT_NIF_DEVICES     = "eth0,lo"                                                          // Default interfaces to report stats for
	DEFAULT_CPU_AGGR        = false                                                              // Default whether to only report aggregate CPU
	DEFAULT_SYSLOGNG_SOCKET = "/var/lib/syslog-ng/syslog-ng.ctl"                                 // Default location of the syslog-ng socket
	DEFAULT_SOCKSTAT_PROTOS = "TCP,UDP,TCP6,UDP6"                                                // Default protocols to report sockstats on
)

var (
	start = time.Now()
)

type Config struct {
	Interval            time.Duration
	Outputter           string
	Pollers             []string
	Source              string
	Prefix              string
	ProfilePort         string
	DfTypes             []string
	Listen              string
	NifDevices          []string
	NtpdateServers      []string
	CpuOnlyAggregate    bool
	LibratoUser         string
	LibratoToken        string
	LibratoBatchSize    int
	LibratoBatchTimeout time.Duration
	CarbonHost          string
	SockStatProtos      []string
	StatsdHost          string
	StatsdProto         string
	SyslogngSocket      string
	Start               time.Time
	DiskFilter          *regexp.Regexp
}

func GetConfig() (config Config) {
	config.Interval = GetEnvWithDefaultDuration("SHH_INTERVAL", DEFAULT_INTERVAL)                            // Polling Interval
	config.Outputter = GetEnvWithDefault("SHH_OUTPUTTER", DEFAULT_OUTPUTTER)                                 // Outputter
	config.Pollers = GetEnvWithDefaultStrings("SHH_POLLERS", DEFAULT_POLLERS)                                // Pollers to poll
	config.Source = GetEnvWithDefault("SHH_SOURCE", "")                                                      // Source to emit
	config.Prefix = GetEnvWithDefault("SHH_PREFIX", "")                                                      // Metric prefix to use
	config.ProfilePort = GetEnvWithDefault("SHH_PROFILE_PORT", DEFAULT_PROFILE_PORT)                         // Profile Port
	config.DfTypes = GetEnvWithDefaultStrings("SHH_DF_TYPES", DEFAULT_DF_TYPES)                              // Default DF types
	config.Listen = GetEnvWithDefault("SHH_LISTEN", "unix,#shh")                                             // Default network socket info for listen
	config.NifDevices = GetEnvWithDefaultStrings("SHH_NIF_DEVICES", DEFAULT_NIF_DEVICES)                     // Devices to poll
	config.NtpdateServers = GetEnvWithDefaultStrings("SHH_NTPDATE_SERVERS", "0.pool.ntp.org,1.pool.ntp.org") // NTP Servers
	config.CpuOnlyAggregate = GetEnvWithDefaultBool("SHH_CPU_AGGR", false)                                   // Whether to only report aggregate CPU usage
	config.LibratoUser = GetEnvWithDefault("SHH_LIBRATO_USER", "")                                           // The Librato API User
	config.LibratoToken = GetEnvWithDefault("SHH_LIBRATO_TOKEN", "")                                         // The Librato API TOken
	config.LibratoBatchSize = GetEnvWithDefaultInt("SHH_LIBRATO_BATCH_SIZE", 50)                             // The max number of metrics to submit in a single request
	config.LibratoBatchTimeout = GetEnvWithDefaultDuration("SHH_LIBRATO_BATCH_TIMEOUT", "500ms")             // The max time metrics will sit un-delivered
	config.CarbonHost = GetEnvWithDefault("SHH_CARBON_HOST", "")                                             // Where the Carbon Outputter sends it's data
	config.SockStatProtos = GetEnvWithDefaultStrings("SHH_SOCKSTAT_PROTOS", DEFAULT_SOCKSTAT_PROTOS)         // Protocols to report sockstats about
	config.StatsdHost = GetEnvWithDefault("SHH_STATSD_HOST", "")                                             // Where the Statsd Outputter sends it's data
	config.StatsdProto = GetEnvWithDefault("SHH_STATSD_PROTO", "udp")                                        // Whether the Stats Outputter uses TCP or UDP
	config.SyslogngSocket = GetEnvWithDefault("SHH_SYSLOGNG_SOCKET", DEFAULT_SYSLOGNG_SOCKET)                // The location of the syslog-ng socket
	tmp := GetEnvWithDefault("SHH_DISK_FILTER", ".*")
	config.DiskFilter = regexp.MustCompile(tmp)
	config.Start = start // Start time
	return
}
<commit_msg>version bump<commit_after>package main

import (
	"regexp"
	"time"
)

const (
	VERSION                 = "0.3.4"
	DEFAULT_INTERVAL        = "10s"                                                              // Default tick interval for pollers
	DEFAULT_OUTPUTTER       = "stdoutl2metder"                                                   // Default outputter
	DEFAULT_POLLERS         = "conntrack,cpu,df,disk,listen,load,mem,nif,ntpdate,processes,self" // Default pollers
	DEFAULT_PROFILE_PORT    = "0"                                                                // Default profile port, 0 disables
	DEFAULT_DF_TYPES        = "btrfs,ext3,ext4,tmpfs,xfs"                                        // Default fs types to report df for
	DEFAULT_NIF_DEVICES     = "eth0,lo"                                                          // Default interfaces to report stats for
	DEFAULT_CPU_AGGR        = false                                                              // Default whether to only report aggregate CPU
	DEFAULT_SYSLOGNG_SOCKET = "/var/lib/syslog-ng/syslog-ng.ctl"                                 // Default location of the syslog-ng socket
	DEFAULT_SOCKSTAT_PROTOS = "TCP,UDP,TCP6,UDP6"                                                // Default protocols to report sockstats on
)

var (
	start = time.Now()
)

type Config struct {
	Interval            time.Duration
	Outputter           string
	Pollers             []string
	Source              string
	Prefix              string
	ProfilePort         string
	DfTypes             []string
	Listen              string
	NifDevices          []string
	NtpdateServers      []string
	CpuOnlyAggregate    bool
	LibratoUser         string
	LibratoToken        string
	LibratoBatchSize    int
	LibratoBatchTimeout time.Duration
	CarbonHost          string
	SockStatProtos      []string
	StatsdHost          string
	StatsdProto         string
	SyslogngSocket      string
	Start               time.Time
	DiskFilter          *regexp.Regexp
}

func GetConfig() (config Config) {
	config.Interval = GetEnvWithDefaultDuration("SHH_INTERVAL", DEFAULT_INTERVAL)                            // Polling Interval
	config.Outputter = GetEnvWithDefault("SHH_OUTPUTTER", DEFAULT_OUTPUTTER)                                 // Outputter
	config.Pollers = GetEnvWithDefaultStrings("SHH_POLLERS", DEFAULT_POLLERS)                                // Pollers to poll
	config.Source = GetEnvWithDefault("SHH_SOURCE", "")                                                      // Source to emit
	config.Prefix = GetEnvWithDefault("SHH_PREFIX", "")                                                      // Metric prefix to use
	config.ProfilePort = GetEnvWithDefault("SHH_PROFILE_PORT", DEFAULT_PROFILE_PORT)                         // Profile Port
	config.DfTypes = GetEnvWithDefaultStrings("SHH_DF_TYPES", DEFAULT_DF_TYPES)                              // Default DF types
	config.Listen = GetEnvWithDefault("SHH_LISTEN", "unix,#shh")                                             // Default network socket info for listen
	config.NifDevices = GetEnvWithDefaultStrings("SHH_NIF_DEVICES", DEFAULT_NIF_DEVICES)                     // Devices to poll
	config.NtpdateServers = GetEnvWithDefaultStrings("SHH_NTPDATE_SERVERS", "0.pool.ntp.org,1.pool.ntp.org") // NTP Servers
	config.CpuOnlyAggregate = GetEnvWithDefaultBool("SHH_CPU_AGGR", false)                                   // Whether to only report aggregate CPU usage
	config.LibratoUser = GetEnvWithDefault("SHH_LIBRATO_USER", "")                                           // The Librato API User
	config.LibratoToken = GetEnvWithDefault("SHH_LIBRATO_TOKEN", "")                                         // The Librato API TOken
	config.LibratoBatchSize = GetEnvWithDefaultInt("SHH_LIBRATO_BATCH_SIZE", 50)                             // The max number of metrics to submit in a single request
	config.LibratoBatchTimeout = GetEnvWithDefaultDuration("SHH_LIBRATO_BATCH_TIMEOUT", "500ms")             // The max time metrics will sit un-delivered
	config.CarbonHost = GetEnvWithDefault("SHH_CARBON_HOST", "")                                             // Where the Carbon Outputter sends it's data
	config.SockStatProtos = GetEnvWithDefaultStrings("SHH_SOCKSTAT_PROTOS", DEFAULT_SOCKSTAT_PROTOS)         // Protocols to report sockstats about
	config.StatsdHost = GetEnvWithDefault("SHH_STATSD_HOST", "")                                             // Where the Statsd Outputter sends it's data
	config.StatsdProto = GetEnvWithDefault("SHH_STATSD_PROTO", "udp")                                        // Whether the Stats Outputter uses TCP or UDP
	config.SyslogngSocket = GetEnvWithDefault("SHH_SYSLOGNG_SOCKET", DEFAULT_SYSLOGNG_SOCKET)                // The location of the syslog-ng socket
	tmp := GetEnvWithDefault("SHH_DISK_FILTER", ".*")
	config.DiskFilter = regexp.MustCompile(tmp)
	config.Start = start // Start time
	return
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"time"

	"github.com/freeusd/solebtc/Godeps/_workspace/src/github.com/spf13/viper"
)

type configuration struct {
	HTTP struct {
		Port string
		Env  string // production, development, test
	}
	DB struct {
		DataSourceName string
		MaxOpenConns   int
		MaxIdleConns   int
	}
	AuthToken struct {
		Lifetime time.Duration
	}
	Mandrill struct {
		Key       string
		FromEmail string
		FromName  string
	}
	Cache struct {
		NumCachedIncomes int
	}
}

var config configuration

func initConfig() {
	// env config
	viper.SetEnvPrefix("solebtc") // will turn into uppercase, e.g. SOLEBTC_PORT
	viper.AutomaticEnv()

	// set default
	viper.SetDefault("env", "development")
	viper.SetDefault("port", "3000")
	viper.SetDefault("dsn", "/solebtc_dev")
	viper.SetDefault("auth_token_lifetime", "720h")
	viper.SetDefault("mandrill_key", "SANDBOX_SUCCESS")
	viper.SetDefault("mandrill_from_email", "no_reply@solebtc.com")
	viper.SetDefault("mandrill_from_name", "SoleBTC")
	viper.SetDefault("max_open_conns", 256)
	viper.SetDefault("max_idle_conns", 128)
	viper.SetDefault("num_cached_incomes", 20)

	// See Viper doc, config is get in the following order
	// override, flag, env, config file, key/value store, default

	config.HTTP.Env = viper.GetString("env")
	config.HTTP.Port = ":" + viper.GetString("port")
	config.DB.DataSourceName = viper.GetString("dsn")

	authTokenLifetime, err := time.ParseDuration(viper.GetString("auth_token_lifetime"))
	if err != nil {
		log.Fatalf("parse auth_token_lifetime error: %v", err)
	}
	config.AuthToken.Lifetime = authTokenLifetime
	config.Mandrill.Key = viper.GetString("mandrill_key")
	config.Mandrill.FromEmail = viper.GetString("mandrill_from_email")
	config.Mandrill.FromName = viper.GetString("mandrill_from_name")
	config.DB.MaxOpenConns = viper.GetInt("max_open_conns")
	config.DB.MaxIdleConns = viper.GetInt("max_idle_conns")
	config.Cache.NumCachedIncomes = viper.GetInt("num_cached_incomes")
}

func ginEnvMode() string {
	return map[string]string{
		"production":  "release",
		"development": "debug",
		"test":        "test",
	}[config.HTTP.Env]
}
<commit_msg>Default mysql connections to 2<commit_after>package main

import (
	"log"
	"time"

	"github.com/freeusd/solebtc/Godeps/_workspace/src/github.com/spf13/viper"
)

type configuration struct {
	HTTP struct {
		Port string
		Env  string // production, development, test
	}
	DB struct {
		DataSourceName string
		MaxOpenConns   int
		MaxIdleConns   int
	}
	AuthToken struct {
		Lifetime time.Duration
	}
	Mandrill struct {
		Key       string
		FromEmail string
		FromName  string
	}
	Cache struct {
		NumCachedIncomes int
	}
}

var config configuration

func initConfig() {
	// env config
	viper.SetEnvPrefix("solebtc") // will turn into uppercase, e.g. SOLEBTC_PORT
	viper.AutomaticEnv()

	// set default
	viper.SetDefault("env", "development")
	viper.SetDefault("port", "3000")
	viper.SetDefault("dsn", "/solebtc_dev")
	viper.SetDefault("auth_token_lifetime", "720h")
	viper.SetDefault("mandrill_key", "SANDBOX_SUCCESS")
	viper.SetDefault("mandrill_from_email", "no_reply@solebtc.com")
	viper.SetDefault("mandrill_from_name", "SoleBTC")
	viper.SetDefault("max_open_conns", 2)
	viper.SetDefault("max_idle_conns", 2)
	viper.SetDefault("num_cached_incomes", 20)

	// See Viper doc, config is get in the following order
	// override, flag, env, config file, key/value store, default

	config.HTTP.Env = viper.GetString("env")
	config.HTTP.Port = ":" + viper.GetString("port")
	config.DB.DataSourceName = viper.GetString("dsn")

	authTokenLifetime, err := time.ParseDuration(viper.GetString("auth_token_lifetime"))
	if err != nil {
		log.Fatalf("parse auth_token_lifetime error: %v", err)
	}
	config.AuthToken.Lifetime = authTokenLifetime
	config.Mandrill.Key = viper.GetString("mandrill_key")
	config.Mandrill.FromEmail = viper.GetString("mandrill_from_email")
	config.Mandrill.FromName = viper.GetString("mandrill_from_name")
	config.DB.MaxOpenConns = viper.GetInt("max_open_conns")
	config.DB.MaxIdleConns = viper.GetInt("max_idle_conns")
	config.Cache.NumCachedIncomes = viper.GetInt("num_cached_incomes")
}

func ginEnvMode() string {
	return map[string]string{
		"production":  "release",
		"development": "debug",
		"test":        "test",
	}[config.HTTP.Env]
}
<|endoftext|>


<commit_before>package oz

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path"
)

type Config struct {
	ProfileDir       string   `json:"profile_dir" desc:"Directory containing the sandbox profiles"`
	ShellPath        string   `json:"shell_path" desc:"Path of the shell used when entering a sandbox"`
	PrefixPath       string   `json:"prefix_path" desc:"Prefix path containing the oz executables"`
	EtcPrefix        string   `json:"etc_prefix" desc:"Prefix for configuration files"`
	SandboxPath      string   `json:"sandbox_path" desc:"Path of the sandboxes base"`
	OpenVPNRunPath   string   `json:"openvpn_run_path" desc: "Path for OpenVPN run state"`
	OpenVPNConfDir   string   `json:"openvpn_conf_dir" desc: "Path for OpenVPN conf files"`
	OpenVPNGroup     string   `json:"openvpn_group" desc: "GID for OpenVPN process"`
	RouteTableBase   int      `json:"route_table_base" desc: "Base for routing table"`
	DivertSuffix     string   `json:"divert_suffix" desc:"Suffix using for dpkg-divert of application executables, can be left empty when using a divert path"`
	DivertPath       bool     `json:"divert_path" desc:"Whether the diverted executable should be moved out of the path"`
	NMIgnoreFile     string   `json:"nm_ignore_file" desc:"Path to the NetworkManager ignore config file, disables the warning if empty"`
	UseFullDev       bool     `json:"use_full_dev" desc:"Give sandboxes full access to devices instead of a restricted set"`
	AllowRootShell   bool     `json:"allow_root_shell" desc:"Allow entering a sandbox shell as root"`
	LogXpra          bool     `json:"log_xpra" desc:"Log output of Xpra"`
	EnableEphemerals bool     `json:"enable_ephemerals" desc:"Enable prompting to launch sandbox in ephemeral mode"`
	EnvironmentVars  []string `json:"environment_vars" desc:"Default environment variables passed to sandboxes"`
	DefaultGroups    []string `json:"default_groups" desc:"List of default group names that can be used inside the sandbox"`
	EtcIncludes      []string `json:"etc_includes" desc:"Elements to include in the etc directory in the sandbox"`
}

const OzVersion = "0.0.1"

var DefaultConfigPath = "/etc/oz/oz.conf"

func CheckSettingsOverRide() {
	nConfPath := os.Getenv("OZ_CONFIG_PATH")

	if nConfPath != "" {
		DefaultConfigPath = nConfPath
	}
}

var DefaultEtcIncludes = []string{
	"/etc/alternatives/",
	"/etc/ssl/certs/",
	"/etc/console-setup/",
	"/etc/dbus-1/",
	"/etc/default/locale",
	"/etc/fonts/",
	"/etc/gnome/defaults.list",
	"/etc/group",
	//"/etc/group-",
	"/etc/gtk-2.0/",
	"/etc/gtk-3.0/",
	"/etc/host.conf",
	"/etc/inputrc",
	"/etc/locale.alias",
	"/etc/localtime",
	"/etc/magic",
	"/etc/magic.mime",
	"/etc/mailcap",
	"/etc/mailcap.order",
	"/etc/mime.types",
	"/etc/passwd",
	//"/etc/passwd-",
	"/etc/protocols",
	"/etc/pulse/",
	"/etc/resolvconf/run/resolv.conf",
	"/etc/services",
	"/etc/shells",
	"/etc/terminfo/",
	"/etc/timezone",
	"/etc/vconsole.conf",
	"/etc/xdg/-mimeapps.list",
	"/etc/xdg/user-dirs.conf",
	"/etc/xdg/user-dirs.defaults",
	"/etc/xpra/",
	"/etc/X11/",

	//"/etc/debian_version",
	//"/etc/os-release",
	//"/etc/issue",
	//"/etc/issue.net",
}

func NewDefaultConfig() *Config {
	return &Config{
		ProfileDir:       "/var/lib/oz/cells.d",
		ShellPath:        "/bin/bash",
		PrefixPath:       "/usr/local",
		EtcPrefix:        "/etc/oz",
		SandboxPath:      "/srv/oz",
		OpenVPNRunPath:   "/var/run/openvpn",
		OpenVPNConfDir:   "/var/lib/oz/openvpn",
		OpenVPNGroup:     "oz-openvpn",
		RouteTableBase:   8000,
		DivertPath:       true,
		NMIgnoreFile:     "/etc/NetworkManager/conf.d/oz.conf",
		DivertSuffix:     "",
		UseFullDev:       false,
		AllowRootShell:   false,
		LogXpra:          true,
		EnableEphemerals: false,
		EnvironmentVars: []string{
			"USER", "USERNAME", "LOGNAME",
			"LANG", "LANGUAGE", "_", "TZ=UTC",
			"XDG_SESSION_TYPE", "XDG_RUNTIME_DIR", "XDG_DATA_DIRS",
			"XDG_SEAT", "XDG_SESSION_TYPE", "XDG_SESSION_ID",
		},
		DefaultGroups: []string{
			"audio", "video",
		},
	}
}

func LoadConfig(cpath string) (*Config, error) {
	if _, err := os.Stat(cpath); os.IsNotExist(err) {
		return nil, err
	}
	if err := checkConfigPermissions(cpath); err != nil {
		return nil, err
	}

	bs, err := ioutil.ReadFile(cpath)
	if err != nil {
		return nil, err
	}
	c := NewDefaultConfig()
	if err := json.Unmarshal(bs, c); err != nil {
		return nil, err
	}

	if c.DivertSuffix == "" && c.DivertPath == false {
		c.DivertSuffix = "unsafe"
	}

	if len(c.EtcIncludes) == 0 {
		c.EtcIncludes = DefaultEtcIncludes
	} else {
		c.EtcIncludes = append(c.EtcIncludes, DefaultEtcIncludes...)
	}
	c.EtcIncludes = append(c.EtcIncludes, c.EtcPrefix)
	if c.EtcPrefix !=  path.Dir(DefaultConfigPath) {
		c.EtcIncludes = append(c.EtcIncludes, path.Dir(DefaultConfigPath))
	}
	return c, nil
}
<commit_msg>Makes electrum not look weird<commit_after>package oz

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path"
)

type Config struct {
	ProfileDir       string   `json:"profile_dir" desc:"Directory containing the sandbox profiles"`
	ShellPath        string   `json:"shell_path" desc:"Path of the shell used when entering a sandbox"`
	PrefixPath       string   `json:"prefix_path" desc:"Prefix path containing the oz executables"`
	EtcPrefix        string   `json:"etc_prefix" desc:"Prefix for configuration files"`
	SandboxPath      string   `json:"sandbox_path" desc:"Path of the sandboxes base"`
	OpenVPNRunPath   string   `json:"openvpn_run_path" desc: "Path for OpenVPN run state"`
	OpenVPNConfDir   string   `json:"openvpn_conf_dir" desc: "Path for OpenVPN conf files"`
	OpenVPNGroup     string   `json:"openvpn_group" desc: "GID for OpenVPN process"`
	RouteTableBase   int      `json:"route_table_base" desc: "Base for routing table"`
	DivertSuffix     string   `json:"divert_suffix" desc:"Suffix using for dpkg-divert of application executables, can be left empty when using a divert path"`
	DivertPath       bool     `json:"divert_path" desc:"Whether the diverted executable should be moved out of the path"`
	NMIgnoreFile     string   `json:"nm_ignore_file" desc:"Path to the NetworkManager ignore config file, disables the warning if empty"`
	UseFullDev       bool     `json:"use_full_dev" desc:"Give sandboxes full access to devices instead of a restricted set"`
	AllowRootShell   bool     `json:"allow_root_shell" desc:"Allow entering a sandbox shell as root"`
	LogXpra          bool     `json:"log_xpra" desc:"Log output of Xpra"`
	EnableEphemerals bool     `json:"enable_ephemerals" desc:"Enable prompting to launch sandbox in ephemeral mode"`
	EnvironmentVars  []string `json:"environment_vars" desc:"Default environment variables passed to sandboxes"`
	DefaultGroups    []string `json:"default_groups" desc:"List of default group names that can be used inside the sandbox"`
	EtcIncludes      []string `json:"etc_includes" desc:"Elements to include in the etc directory in the sandbox"`
}

const OzVersion = "0.0.1"

var DefaultConfigPath = "/etc/oz/oz.conf"

func CheckSettingsOverRide() {
	nConfPath := os.Getenv("OZ_CONFIG_PATH")

	if nConfPath != "" {
		DefaultConfigPath = nConfPath
	}
}

var DefaultEtcIncludes = []string{
	"/etc/alternatives/",
	"/etc/ssl/certs/",
	"/etc/console-setup/",
	"/etc/dbus-1/",
	"/etc/default/locale",
	"/etc/fonts/",
	"/etc/gnome/defaults.list",
	"/etc/group",
	//"/etc/group-",
	"/etc/gtk-2.0/",
	"/etc/gtk-3.0/",
	"/etc/host.conf",
	"/etc/inputrc",
	"/etc/locale.alias",
	"/etc/localtime",
	"/etc/magic",
	"/etc/magic.mime",
	"/etc/mailcap",
	"/etc/mailcap.order",
	"/etc/mime.types",
	"/etc/passwd",
	//"/etc/passwd-",
	"/etc/protocols",
	"/etc/pulse/",
	"/etc/resolvconf/run/resolv.conf",
	"/etc/services",
	"/etc/shells",
	"/etc/terminfo/",
	"/etc/timezone",
	"/etc/vconsole.conf",
	"/etc/xdg/-mimeapps.list",
	"/etc/xdg/user-dirs.conf",
	"/etc/xdg/user-dirs.defaults",
	"/etc/xpra/",
	"/etc/X11/",

	//"/etc/debian_version",
	//"/etc/os-release",
	//"/etc/issue",
	//"/etc/issue.net",
}

func NewDefaultConfig() *Config {
	return &Config{
		ProfileDir:       "/var/lib/oz/cells.d",
		ShellPath:        "/bin/bash",
		PrefixPath:       "/usr/local",
		EtcPrefix:        "/etc/oz",
		SandboxPath:      "/srv/oz",
		OpenVPNRunPath:   "/var/run/openvpn",
		OpenVPNConfDir:   "/var/lib/oz/openvpn",
		OpenVPNGroup:     "oz-openvpn",
		RouteTableBase:   8000,
		DivertPath:       true,
		NMIgnoreFile:     "/etc/NetworkManager/conf.d/oz.conf",
		DivertSuffix:     "",
		UseFullDev:       false,
		AllowRootShell:   false,
		LogXpra:          true,
		EnableEphemerals: false,
		EnvironmentVars: []string{
			"USER", "USERNAME", "LOGNAME",
			"LANG", "LANGUAGE", "_", "TZ=UTC",
			"XDG_SESSION_TYPE", "XDG_RUNTIME_DIR", "XDG_DATA_DIRS",
			"XDG_SEAT", "XDG_SESSION_TYPE", "XDG_SESSION_ID","GNOME_DESKTOP_SESSION_ID=this-is-deprecated",
		},
		DefaultGroups: []string{
			"audio", "video",
		},
	}
}

func LoadConfig(cpath string) (*Config, error) {
	if _, err := os.Stat(cpath); os.IsNotExist(err) {
		return nil, err
	}
	if err := checkConfigPermissions(cpath); err != nil {
		return nil, err
	}

	bs, err := ioutil.ReadFile(cpath)
	if err != nil {
		return nil, err
	}
	c := NewDefaultConfig()
	if err := json.Unmarshal(bs, c); err != nil {
		return nil, err
	}

	if c.DivertSuffix == "" && c.DivertPath == false {
		c.DivertSuffix = "unsafe"
	}

	if len(c.EtcIncludes) == 0 {
		c.EtcIncludes = DefaultEtcIncludes
	} else {
		c.EtcIncludes = append(c.EtcIncludes, DefaultEtcIncludes...)
	}
	c.EtcIncludes = append(c.EtcIncludes, c.EtcPrefix)
	if c.EtcPrefix !=  path.Dir(DefaultConfigPath) {
		c.EtcIncludes = append(c.EtcIncludes, path.Dir(DefaultConfigPath))
	}
	return c, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"runtime"
)

const (
	// Name is the user facing name for this binary. Internally we call it
	// klientctl to avoid confusion.
	Name = "kd"

	// KlientName is the user facing name for klient.
	KlientName = "KD Daemon"

	// KlientAddress is url of locally running klient to connect to send
	// user commands.
	KlientAddress = "http://127.0.0.1:56789/kite"

	// KiteHome is full path to the kite key that we will use to authenticate
	// to the given klient.
	KiteHome = "/etc/kite"

	// KlientDirectory is full path to directory that holds klient.
	KlientDirectory = "/opt/kite/klient"

	// KlientctlDirectory is full path to directory that holds klientctl.
	KlientctlDirectory = "/usr/local/bin"

	// KlientctlBinName is the bin named that will be stored in the KlientctlDirectory.
	KlientctlBinName = "kd"

	// KontrolURL is the url to connect to authenticate local klient and get
	// list of machines.
	KontrolURL = "https://koding.com/kontrol/kite"

	// Version is the current version of klientctl. This number is used
	// by CheckUpdate to determine if current version is behind or equal to latest
	// version on S3 bucket.
	Version = 21

	osName = runtime.GOOS

	// S3UpdateLocation is publically accessible url to check for new updates.
	S3UpdateLocation = "https://koding-kd.s3.amazonaws.com/latest-version.txt"

	// S3KlientPath is publically accessible url for latest version of klient.
	// Each OS has its own version of binary, identifiable by OS suffix.
	S3KlientPath = "https://koding-kd.s3.amazonaws.com/klient-" + osName

	// S3KlientctlPath is publically accessible url for latest version of
	// klientctl. Each OS has its own version of binary, identifiable by suffix.
	S3KlientctlPath = "https://koding-kd.s3.amazonaws.com/klientctl-" + osName

	// SSHDefaultKeyDir is the default directory that stores users ssh key pairs.
	SSHDefaultKeyDir = ".ssh"

	// SSHDefaultKeyName is the default name of the ssh key pair.
	SSHDefaultKeyName = "kd-ssh-key"
)

var (
	// KiteVersion is the version identifier used to connect to Kontrol.
	KiteVersion = fmt.Sprintf("0.0.%d", Version)

	// ConfigFolder is folder where config and other related info are stored.
	ConfigFolder string
)

func init() {
	var err error
	if ConfigFolder, err = createFolderAtHome(".config", "koding"); err != nil {
		panic(err)
	}
}

func createFolderAtHome(cf ...string) (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}

	args := []string{usr.HomeDir}
	args = append(args, cf...)

	folderName := filepath.Join(args...)
	if err := os.MkdirAll(folderName, 0755); err != nil {
		return "", err
	}

	return folderName, nil
}
<commit_msg>config: Incremented ver<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"runtime"
)

const (
	// Name is the user facing name for this binary. Internally we call it
	// klientctl to avoid confusion.
	Name = "kd"

	// KlientName is the user facing name for klient.
	KlientName = "KD Daemon"

	// KlientAddress is url of locally running klient to connect to send
	// user commands.
	KlientAddress = "http://127.0.0.1:56789/kite"

	// KiteHome is full path to the kite key that we will use to authenticate
	// to the given klient.
	KiteHome = "/etc/kite"

	// KlientDirectory is full path to directory that holds klient.
	KlientDirectory = "/opt/kite/klient"

	// KlientctlDirectory is full path to directory that holds klientctl.
	KlientctlDirectory = "/usr/local/bin"

	// KlientctlBinName is the bin named that will be stored in the KlientctlDirectory.
	KlientctlBinName = "kd"

	// KontrolURL is the url to connect to authenticate local klient and get
	// list of machines.
	KontrolURL = "https://koding.com/kontrol/kite"

	// Version is the current version of klientctl. This number is used
	// by CheckUpdate to determine if current version is behind or equal to latest
	// version on S3 bucket.
	Version = 22

	osName = runtime.GOOS

	// S3UpdateLocation is publically accessible url to check for new updates.
	S3UpdateLocation = "https://koding-kd.s3.amazonaws.com/latest-version.txt"

	// S3KlientPath is publically accessible url for latest version of klient.
	// Each OS has its own version of binary, identifiable by OS suffix.
	S3KlientPath = "https://koding-kd.s3.amazonaws.com/klient-" + osName

	// S3KlientctlPath is publically accessible url for latest version of
	// klientctl. Each OS has its own version of binary, identifiable by suffix.
	S3KlientctlPath = "https://koding-kd.s3.amazonaws.com/klientctl-" + osName

	// SSHDefaultKeyDir is the default directory that stores users ssh key pairs.
	SSHDefaultKeyDir = ".ssh"

	// SSHDefaultKeyName is the default name of the ssh key pair.
	SSHDefaultKeyName = "kd-ssh-key"
)

var (
	// KiteVersion is the version identifier used to connect to Kontrol.
	KiteVersion = fmt.Sprintf("0.0.%d", Version)

	// ConfigFolder is folder where config and other related info are stored.
	ConfigFolder string
)

func init() {
	var err error
	if ConfigFolder, err = createFolderAtHome(".config", "koding"); err != nil {
		panic(err)
	}
}

func createFolderAtHome(cf ...string) (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}

	args := []string{usr.HomeDir}
	args = append(args, cf...)

	folderName := filepath.Join(args...)
	if err := os.MkdirAll(folderName, 0755); err != nil {
		return "", err
	}

	return folderName, nil
}
<|endoftext|>


<commit_before>package core

import (
	"encoding/json"
	"io/ioutil"

	"github.com/jzaikovs/core/loggy"
	"github.com/jzaikovs/t"
)

type configStruct struct {
	Host          string                 `json:"host"`
	BaseURL       string                 `json:"base_url"`
	FCGI          bool                   `json:"fcgi"`
	HandleContent bool                   `json:"handle_content"`
	Port          int                    `json:"port"`
	Subdir        string                 `json:"subdir"`
	Views         map[string]string      `json:"views"`
	Data          map[string]interface{} `json:"data"`

	err_object_func func(code int, err error) interface{}
}

// constructor for t_config object
func newConfigStruct() *configStruct {
	this := new(configStruct)

	// defaul rest error handler
	this.SetRESTErrObjectFunc(func(code int, err error) interface{} {
		obj := t.Map{"code": code}
		if err != nil {
			obj["error"] = err.Error()
		}
		return obj
	})

	return this
}

// Load is function for loading configuration from json file specified by path parameter.
func (config *configStruct) Load(path string) error {
	// default configurations
	if config.Port == 0 {
		config.Port = 8080
	}

	if len(config.Host) == 0 {
		// by default we listen to all ip
		config.Host = "0.0.0.0"
	}

	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	if err = json.Unmarshal(bytes, config); err != nil {
		return err
	}
	loggy.Info.Println("Configuration loaded from file:", path)

	b, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		loggy.Info.Println(err)
	}

	loggy.Info.Println("Configs:\n", string(b))

	return nil
}

func (config *configStruct) SetRESTErrObjectFunc(fn func(code int, err error) interface{}) {
	config.err_object_func = fn
}
<commit_msg>config data defined as t.Map<commit_after>package core

import (
	"encoding/json"
	"io/ioutil"

	"github.com/jzaikovs/core/loggy"
	"github.com/jzaikovs/t"
)

type configStruct struct {
	Host          string            `json:"host"`
	BaseURL       string            `json:"base_url"`
	FCGI          bool              `json:"fcgi"`
	HandleContent bool              `json:"handle_content"`
	Port          int               `json:"port"`
	Subdir        string            `json:"subdir"`
	Views         map[string]string `json:"views"`
	Data          t.Map             `json:"data"`

	err_object_func func(code int, err error) interface{}
}

// constructor for t_config object
func newConfigStruct() *configStruct {
	this := new(configStruct)

	// defaul rest error handler
	this.SetRESTErrObjectFunc(func(code int, err error) interface{} {
		obj := t.Map{"code": code}
		if err != nil {
			obj["error"] = err.Error()
		}
		return obj
	})

	return this
}

// Load is function for loading configuration from json file specified by path parameter.
func (config *configStruct) Load(path string) error {
	// default configurations
	if config.Port == 0 {
		config.Port = 8080
	}

	if len(config.Host) == 0 {
		// by default we listen to all ip
		config.Host = "0.0.0.0"
	}

	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	if err = json.Unmarshal(bytes, config); err != nil {
		return err
	}
	loggy.Info.Println("Configuration loaded from file:", path)

	b, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		loggy.Info.Println(err)
	}

	loggy.Info.Println("Configs:\n", string(b))

	return nil
}

func (config *configStruct) SetRESTErrObjectFunc(fn func(code int, err error) interface{}) {
	config.err_object_func = fn
}
<|endoftext|>


<commit_before>package messages

// Github config
type Github struct {
	Token  string `json:"token"`
	Labels []string
}

// Config internal to be shared between services
type Config struct {
	Github *Github `json:"github, omitempty"`
}

// GetIssuesList request message to get an issue list
type GetIssuesList struct {
	Status string `json:"status"`
	Org    string `json:"org"`
	Repo   string `json:"repo,omitempty"`
	Config `json:"config"`
}

// IssuesDetails request message to get an issue
type GetIssue struct {
	Issue  *Issue `json:"issue"`
	Config `json:"config"`
}

// CreateIssue request message to create an issue
type CreateIssue struct {
	Issue  *Issue `json:issue`
	Config `json:"config"`
}

// Setup request message to setup issue tracker
type Setup struct {
	Org    string   `json:"org"`
	Repo   string   `json:"repo"`
	States []string `json:"states"`
	Config `json:"config"`
}

// UpdateIssue request message to update an issue
type UpdateIssue struct {
	Issue    *Issue `json:issue`
	Status   string `json:"state"`
	Config   `json:"config"`
	Workflow `json:"workflow"`
}

// Workflow ...
type Workflow struct {
	Transitions []Transition `json:"transitions"`
}

// Transition json representation
type Transition struct {
	From  string   `json:"from"`
	To    string   `json:"to"`
	Hooks []string `json:"hooks"`
}
<commit_msg>Hook struct<commit_after>package messages

// Github config
type Github struct {
	Token  string `json:"token"`
	Labels []string
}

// Config internal to be shared between services
type Config struct {
	Github *Github `json:"github, omitempty"`
}

// GetIssuesList request message to get an issue list
type GetIssuesList struct {
	Status string `json:"status"`
	Org    string `json:"org"`
	Repo   string `json:"repo,omitempty"`
	Config `json:"config"`
}

// IssuesDetails request message to get an issue
type GetIssue struct {
	Issue  *Issue `json:"issue"`
	Config `json:"config"`
}

// CreateIssue request message to create an issue
type CreateIssue struct {
	Issue  *Issue `json:issue`
	Config `json:"config"`
}

// Setup request message to setup issue tracker
type Setup struct {
	Org    string   `json:"org"`
	Repo   string   `json:"repo"`
	States []string `json:"states"`
	Config `json:"config"`
}

// UpdateIssue request message to update an issue
type UpdateIssue struct {
	Issue    *Issue `json:issue`
	Status   string `json:"state"`
	Config   `json:"config"`
	Workflow `json:"workflow"`
}

// Workflow ...
type Workflow struct {
	Transitions []Transition `json:"transitions"`
}

// Transition json representation
type Transition struct {
	From  string `json:"from"`
	To    string `json:"to"`
	Hooks []Hook `json:"hooks"`
}

type Hook struct {
	URL string `json:"url"`
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package mungers

import (
	"math"
	"math/rand"
	"os"
	"strings"

	"k8s.io/contrib/mungegithub/github"
	"k8s.io/kubernetes/pkg/util/yaml"

	"github.com/golang/glog"
	github_api "github.com/google/go-github/github"
	"github.com/spf13/cobra"
)

// weightMap is a map of user to a weight for that user.
type weightMap map[string]int64

// A BlunderbussConfig maps a set of file prefixes to a set of owner names (github users)
type BlunderbussConfig struct {
	PrefixMap map[string][]string `json:"prefixMap,omitempty" yaml:"prefixMap,omitempty"`
}

func (b *BlunderbussConfig) findOwners(filename string) weightMap {
	wm := weightMap{}
	for prefix, ownersList := range b.PrefixMap {
		if strings.HasPrefix(filename, prefix) {
			// Give one point for each directory-- so that more specific directories get more weight.
			weight := int64(1 + strings.Count(prefix, "/"))
			for _, owner := range ownersList {
				wm[owner] = wm[owner] + weight
			}
		}
	}
	return wm
}

// BlunderbussMunger will assign issues to users based on the config file
// provided by --blunderbuss-config.
type BlunderbussMunger struct {
	config                *BlunderbussConfig
	blunderbussConfigFile string
	blunderbussReassign   bool
}

func init() {
	blunderbuss := &BlunderbussMunger{}
	RegisterMungerOrDie(blunderbuss)
}

// Name is the name usable in --pr-mungers
func (b *BlunderbussMunger) Name() string { return "blunderbuss" }

// Initialize will initialize the munger
func (b *BlunderbussMunger) Initialize(config *github.Config) error {
	if len(b.blunderbussConfigFile) == 0 {
		glog.Fatalf("--blunderbuss-config is required with the blunderbuss munger")
	}
	file, err := os.Open(b.blunderbussConfigFile)
	if err != nil {
		glog.Fatalf("Failed to load blunderbuss config: %v", err)
	}
	defer file.Close()

	b.config = &BlunderbussConfig{}
	if err := yaml.NewYAMLToJSONDecoder(file).Decode(b.config); err != nil {
		glog.Fatalf("Failed to load blunderbuss config: %v", err)
	}
	glog.V(4).Infof("Loaded config from %s", b.blunderbussConfigFile)
	return nil
}

// EachLoop is called at the start of every munge loop
func (b *BlunderbussMunger) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (b *BlunderbussMunger) AddFlags(cmd *cobra.Command, config *github.Config) {
	cmd.Flags().StringVar(&b.blunderbussConfigFile, "blunderbuss-config", "./blunderbuss.yml", "Path to the blunderbuss config file")
	cmd.Flags().BoolVar(&b.blunderbussReassign, "blunderbuss-reassign", false, "Assign PRs even if they're already assigned; use with -dry-run to judge changes to the assignment algorithm")
	b.addBlunderbussCommand(cmd)
}

// u may be nil.
func describeUser(u *github_api.User) string {
	if u != nil && u.Login != nil {
		return *u.Login
	}
	return "<nil>"
}

// Munge is the workhorse the will actually make updates to the PR
func (b *BlunderbussMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	issue := obj.Issue
	if !b.blunderbussReassign && issue.Assignee != nil {
		glog.V(6).Infof("skipping %v: reassign: %v assignee: %v", *issue.Number, b.blunderbussReassign, describeUser(issue.Assignee))
		return
	}

	commits, err := obj.GetCommits()
	if err != nil {
		return
	}

	potentialOwners := weightMap{}
	weightSum := int64(0)
	for _, commit := range commits {
		if commit.Author == nil || commit.Author.Login == nil || commit.SHA == nil {
			glog.Warningf("Skipping invalid commit for %d: %#v", *issue.Number, commit)
			continue
		}
		for _, file := range commit.Files {
			fileWeight := int64(1)
			if file.Changes != nil && *file.Changes != 0 {
				fileWeight = int64(*file.Changes)
			}
			// Judge file size on a log scale-- effectively this
			// makes three buckets, we shouldn't have many 10k+
			// line changes.
			fileWeight = int64(math.Log10(float64(fileWeight))) + 1
			fileOwners := b.config.findOwners(*file.Filename)
			if len(fileOwners) == 0 {
				glog.Warningf("Couldn't find an owner for: %s", *file.Filename)
			}
			for owner, ownerWeight := range fileOwners {
				if owner == *issue.User.Login {
					continue
				}
				potentialOwners[owner] = potentialOwners[owner] + fileWeight*ownerWeight
				weightSum += fileWeight * ownerWeight
			}
		}
	}
	if len(potentialOwners) == 0 {
		glog.Errorf("No owners found for PR %d", *issue.Number)
		return
	}
	glog.V(4).Infof("Weights: %#v\nSum: %v", potentialOwners, weightSum)

	if issue.Assignee != nil {
		cur := *issue.Assignee.Login
		glog.Infof("Current assignee %v has a %02.2f%% chance of having been chosen", cur, 100.0*float64(potentialOwners[cur])/float64(weightSum))
	}
	selection := rand.Int63n(weightSum)
	owner := ""
	for o, w := range potentialOwners {
		owner = o
		selection -= w
		if selection <= 0 {
			break
		}
	}
	glog.Infof("Assigning %v to %v (previously assigned to %v)", *issue.Number, owner, describeUser(issue.Assignee))
	obj.AssignPR(owner)
}
<commit_msg>Remove useless complaint in blunderbuss<commit_after>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package mungers

import (
	"math"
	"math/rand"
	"os"
	"strings"

	"k8s.io/contrib/mungegithub/github"
	"k8s.io/kubernetes/pkg/util/yaml"

	"github.com/golang/glog"
	github_api "github.com/google/go-github/github"
	"github.com/spf13/cobra"
)

// weightMap is a map of user to a weight for that user.
type weightMap map[string]int64

// A BlunderbussConfig maps a set of file prefixes to a set of owner names (github users)
type BlunderbussConfig struct {
	PrefixMap map[string][]string `json:"prefixMap,omitempty" yaml:"prefixMap,omitempty"`
}

func (b *BlunderbussConfig) findOwners(filename string) weightMap {
	wm := weightMap{}
	for prefix, ownersList := range b.PrefixMap {
		if strings.HasPrefix(filename, prefix) {
			// Give one point for each directory-- so that more specific directories get more weight.
			weight := int64(1 + strings.Count(prefix, "/"))
			for _, owner := range ownersList {
				wm[owner] = wm[owner] + weight
			}
		}
	}
	return wm
}

// BlunderbussMunger will assign issues to users based on the config file
// provided by --blunderbuss-config.
type BlunderbussMunger struct {
	config                *BlunderbussConfig
	blunderbussConfigFile string
	blunderbussReassign   bool
}

func init() {
	blunderbuss := &BlunderbussMunger{}
	RegisterMungerOrDie(blunderbuss)
}

// Name is the name usable in --pr-mungers
func (b *BlunderbussMunger) Name() string { return "blunderbuss" }

// Initialize will initialize the munger
func (b *BlunderbussMunger) Initialize(config *github.Config) error {
	if len(b.blunderbussConfigFile) == 0 {
		glog.Fatalf("--blunderbuss-config is required with the blunderbuss munger")
	}
	file, err := os.Open(b.blunderbussConfigFile)
	if err != nil {
		glog.Fatalf("Failed to load blunderbuss config: %v", err)
	}
	defer file.Close()

	b.config = &BlunderbussConfig{}
	if err := yaml.NewYAMLToJSONDecoder(file).Decode(b.config); err != nil {
		glog.Fatalf("Failed to load blunderbuss config: %v", err)
	}
	glog.V(4).Infof("Loaded config from %s", b.blunderbussConfigFile)
	return nil
}

// EachLoop is called at the start of every munge loop
func (b *BlunderbussMunger) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (b *BlunderbussMunger) AddFlags(cmd *cobra.Command, config *github.Config) {
	cmd.Flags().StringVar(&b.blunderbussConfigFile, "blunderbuss-config", "./blunderbuss.yml", "Path to the blunderbuss config file")
	cmd.Flags().BoolVar(&b.blunderbussReassign, "blunderbuss-reassign", false, "Assign PRs even if they're already assigned; use with -dry-run to judge changes to the assignment algorithm")
	b.addBlunderbussCommand(cmd)
}

// u may be nil.
func describeUser(u *github_api.User) string {
	if u != nil && u.Login != nil {
		return *u.Login
	}
	return "<nil>"
}

// Munge is the workhorse the will actually make updates to the PR
func (b *BlunderbussMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	issue := obj.Issue
	if !b.blunderbussReassign && issue.Assignee != nil {
		glog.V(6).Infof("skipping %v: reassign: %v assignee: %v", *issue.Number, b.blunderbussReassign, describeUser(issue.Assignee))
		return
	}

	commits, err := obj.GetCommits()
	if err != nil {
		return
	}

	potentialOwners := weightMap{}
	weightSum := int64(0)
	for _, commit := range commits {
		for _, file := range commit.Files {
			fileWeight := int64(1)
			if file.Changes != nil && *file.Changes != 0 {
				fileWeight = int64(*file.Changes)
			}
			// Judge file size on a log scale-- effectively this
			// makes three buckets, we shouldn't have many 10k+
			// line changes.
			fileWeight = int64(math.Log10(float64(fileWeight))) + 1
			fileOwners := b.config.findOwners(*file.Filename)
			if len(fileOwners) == 0 {
				glog.Warningf("Couldn't find an owner for: %s", *file.Filename)
			}
			for owner, ownerWeight := range fileOwners {
				if owner == *issue.User.Login {
					continue
				}
				potentialOwners[owner] = potentialOwners[owner] + fileWeight*ownerWeight
				weightSum += fileWeight * ownerWeight
			}
		}
	}
	if len(potentialOwners) == 0 {
		glog.Errorf("No owners found for PR %d", *issue.Number)
		return
	}
	glog.V(4).Infof("Weights: %#v\nSum: %v", potentialOwners, weightSum)

	if issue.Assignee != nil {
		cur := *issue.Assignee.Login
		glog.Infof("Current assignee %v has a %02.2f%% chance of having been chosen", cur, 100.0*float64(potentialOwners[cur])/float64(weightSum))
	}
	selection := rand.Int63n(weightSum)
	owner := ""
	for o, w := range potentialOwners {
		owner = o
		selection -= w
		if selection <= 0 {
			break
		}
	}
	glog.Infof("Assigning %v to %v (previously assigned to %v)", *issue.Number, owner, describeUser(issue.Assignee))
	obj.AssignPR(owner)
}
<|endoftext|>


<commit_before>package engine

import (
	"fmt"
	"github.com/TakatoshiMaeda/kinu/logger"
	"gopkg.in/gographics/imagick.v2/imagick"
)

type ImageMagickEngine struct {
	ResizeEngine

	mw                *imagick.MagickWand
	opened            bool
	originalImageBlob []byte

	heightSizeHint, widthSizeHint int
}

func newImageMagickEngine(image []byte) (e *ImageMagickEngine) {
	return &ImageMagickEngine{originalImageBlob: image}
}

func (e *ImageMagickEngine) SetSizeHint(width int, height int) {
	e.heightSizeHint = height
	e.widthSizeHint = width
}

func (e *ImageMagickEngine) Open() error {
	e.mw = imagick.NewMagickWand()
	if e.heightSizeHint > 0 && e.widthSizeHint > 0 {
		e.mw.SetOption("jpeg:size", fmt.Sprintf("%dx%d", e.heightSizeHint, e.widthSizeHint))
	}
	err := e.mw.ReadImageBlob(e.originalImageBlob)
	if err != nil {
		return logger.ErrorDebug(err)
	} else {
		e.opened = true
	}
	return nil
}

func (e *ImageMagickEngine) Close() {
	if e.opened {
		e.mw.Destroy()
	}
}

func (e *ImageMagickEngine) GetImageHeight() int {
	return int(e.mw.GetImageHeight())
}

func (e *ImageMagickEngine) GetImageWidth() int {
	return int(e.mw.GetImageWidth())
}

func (e *ImageMagickEngine) Resize(width int, height int) error {
	return e.mw.ResizeImage(uint(width), uint(height), imagick.FILTER_LANCZOS, 1.0)
}

func (e *ImageMagickEngine) Crop(width int, height int, startX int, startY int) error {
	return e.mw.CropImage(uint(width), uint(height), startX, startY)
}

func (e *ImageMagickEngine) Generate() ([]byte, error) {
	orientation := e.mw.GetImageOrientation()
	if orientation != imagick.ORIENTATION_UNDEFINED && orientation != imagick.ORIENTATION_TOP_LEFT {
		ok := e.mw.AutoOrientImage()
		if ok != nil {
			return nil, ok
		}
	}
	ok := e.mw.StripImage()
	if ok != nil {
		return nil, ok
	}
	return e.mw.GetImageBlob(), nil
}
<commit_msg>Change ok to err<commit_after>package engine

import (
	"fmt"
	"github.com/TakatoshiMaeda/kinu/logger"
	"gopkg.in/gographics/imagick.v2/imagick"
)

type ImageMagickEngine struct {
	ResizeEngine

	mw                *imagick.MagickWand
	opened            bool
	originalImageBlob []byte

	heightSizeHint, widthSizeHint int
}

func newImageMagickEngine(image []byte) (e *ImageMagickEngine) {
	return &ImageMagickEngine{originalImageBlob: image}
}

func (e *ImageMagickEngine) SetSizeHint(width int, height int) {
	e.heightSizeHint = height
	e.widthSizeHint = width
}

func (e *ImageMagickEngine) Open() error {
	e.mw = imagick.NewMagickWand()
	if e.heightSizeHint > 0 && e.widthSizeHint > 0 {
		e.mw.SetOption("jpeg:size", fmt.Sprintf("%dx%d", e.heightSizeHint, e.widthSizeHint))
	}
	err := e.mw.ReadImageBlob(e.originalImageBlob)
	if err != nil {
		return logger.ErrorDebug(err)
	} else {
		e.opened = true
	}
	return nil
}

func (e *ImageMagickEngine) Close() {
	if e.opened {
		e.mw.Destroy()
	}
}

func (e *ImageMagickEngine) GetImageHeight() int {
	return int(e.mw.GetImageHeight())
}

func (e *ImageMagickEngine) GetImageWidth() int {
	return int(e.mw.GetImageWidth())
}

func (e *ImageMagickEngine) Resize(width int, height int) error {
	return e.mw.ResizeImage(uint(width), uint(height), imagick.FILTER_LANCZOS, 1.0)
}

func (e *ImageMagickEngine) Crop(width int, height int, startX int, startY int) error {
	return e.mw.CropImage(uint(width), uint(height), startX, startY)
}

func (e *ImageMagickEngine) Generate() ([]byte, error) {
	orientation := e.mw.GetImageOrientation()
	if orientation != imagick.ORIENTATION_UNDEFINED && orientation != imagick.ORIENTATION_TOP_LEFT {
		err := e.mw.AutoOrientImage()
		if err != nil {
			return nil, err
		}
	}
	err := e.mw.StripImage()
	if err != nil {
		return nil, err
	}
	return e.mw.GetImageBlob(), nil
}
<|endoftext|>


<commit_before>package dropbox

import (
	"io/ioutil"
	"os"
	"testing"

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

func TestFiles_Upload(t *testing.T) {
	c := client()

	file, err := os.Open("Readme.md")
	assert.NoError(t, err, "error opening file")
	defer file.Close()

	out, err := c.Files.Upload(&UploadInput{
		Mute:   true,
		Mode:   WriteModeOverwrite,
		Path:   "/Readme.md",
		Reader: file,
	})

	assert.NoError(t, err, "error uploading file")
	assert.Equal(t, "/readme.md", out.PathLower)
}

func TestFiles_Download(t *testing.T) {
	c := client()

	out, err := c.Files.Download(&DownloadInput{"/Readme.md"})

	assert.NoError(t, err, "error downloading")
	defer out.Body.Close()

	remote, err := ioutil.ReadAll(out.Body)
	assert.NoError(t, err, "error reading remote")

	local, err := ioutil.ReadFile("Readme.md")
	assert.NoError(t, err, "error reading local")

	assert.Equal(t, local, remote, "Readme.md mismatch")
}

func TestFiles_GetMetadata(t *testing.T) {
	c := client()

	out, err := c.Files.GetMetadata(&GetMetadataInput{
		Path: "/Readme.md",
	})

	assert.NoError(t, err)
	assert.Equal(t, "file", out.Tag)
}

func TestFiles_ListFolder(t *testing.T) {
	t.Parallel()
	c := client()

	out, err := c.Files.ListFolder(&ListFolderInput{
		Path: "/list",
	})

	assert.NoError(t, err)
	assert.Equal(t, 2000, len(out.Entries))
	assert.True(t, out.HasMore)
}

func TestFiles_ListFolder_root(t *testing.T) {
	t.Parallel()
	c := client()

	_, err := c.Files.ListFolder(&ListFolderInput{
		Path: "/",
	})

	assert.NoError(t, err)
}

func TestFiles_Search(t *testing.T) {
	c := client()

	_, err := c.Files.Search(&SearchInput{
		Path:  "/list",
		Query: "500",
	})

	assert.NoError(t, err)
	// TODO: busted? assert len
}

func TestFiles_Delete(t *testing.T) {
	c := client()

	out, err := c.Files.Delete(&DeleteInput{
		Path: "/Readme.md",
	})

	assert.NoError(t, err)
	assert.Equal(t, "/readme.md", out.PathLower)
}

func TestFiles_GetPreview(t *testing.T) {
	c := client()

	out, err := c.Files.GetPreview(&GetPreviewInput{"/sample.ppt"})
	defer out.Body.Close()

	assert.NoError(t, err)

	buf := make([]byte, 4)
	_, err = out.Body.Read(buf)
	assert.NoError(t, err)
	assert.Equal(t, []byte{0x25, 0x50, 0x44, 0x46}, buf, "should have pdf magic number")
}
<commit_msg>add results assertion for Files.Search() test<commit_after>package dropbox

import (
	"io/ioutil"
	"os"
	"testing"

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

func TestFiles_Upload(t *testing.T) {
	c := client()

	file, err := os.Open("Readme.md")
	assert.NoError(t, err, "error opening file")
	defer file.Close()

	out, err := c.Files.Upload(&UploadInput{
		Mute:   true,
		Mode:   WriteModeOverwrite,
		Path:   "/Readme.md",
		Reader: file,
	})

	assert.NoError(t, err, "error uploading file")
	assert.Equal(t, "/readme.md", out.PathLower)
}

func TestFiles_Download(t *testing.T) {
	c := client()

	out, err := c.Files.Download(&DownloadInput{"/Readme.md"})

	assert.NoError(t, err, "error downloading")
	defer out.Body.Close()

	remote, err := ioutil.ReadAll(out.Body)
	assert.NoError(t, err, "error reading remote")

	local, err := ioutil.ReadFile("Readme.md")
	assert.NoError(t, err, "error reading local")

	assert.Equal(t, local, remote, "Readme.md mismatch")
}

func TestFiles_GetMetadata(t *testing.T) {
	c := client()

	out, err := c.Files.GetMetadata(&GetMetadataInput{
		Path: "/Readme.md",
	})

	assert.NoError(t, err)
	assert.Equal(t, "file", out.Tag)
}

func TestFiles_ListFolder(t *testing.T) {
	t.Parallel()
	c := client()

	out, err := c.Files.ListFolder(&ListFolderInput{
		Path: "/list",
	})

	assert.NoError(t, err)
	assert.Equal(t, 2000, len(out.Entries))
	assert.True(t, out.HasMore)
}

func TestFiles_ListFolder_root(t *testing.T) {
	t.Parallel()
	c := client()

	_, err := c.Files.ListFolder(&ListFolderInput{
		Path: "/",
	})

	assert.NoError(t, err)
}

func TestFiles_Search(t *testing.T) {
	c := client()

	out, err := c.Files.Search(&SearchInput{
		Path:  "/",
		Query: "hello",
	})

	assert.NoError(t, err)
	assert.Equal(t, 2, len(out.Matches))
}

func TestFiles_Delete(t *testing.T) {
	c := client()

	out, err := c.Files.Delete(&DeleteInput{
		Path: "/Readme.md",
	})

	assert.NoError(t, err)
	assert.Equal(t, "/readme.md", out.PathLower)
}

func TestFiles_GetPreview(t *testing.T) {
	c := client()

	out, err := c.Files.GetPreview(&GetPreviewInput{"/sample.ppt"})
	defer out.Body.Close()

	assert.NoError(t, err)

	buf := make([]byte, 4)
	_, err = out.Body.Read(buf)
	assert.NoError(t, err)
	assert.Equal(t, []byte{0x25, 0x50, 0x44, 0x46}, buf, "should have pdf magic number")
}
<|endoftext|>