<commit_before>// Copyright 2017 Igor Dolzhikov. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package router

import "net/http"

// Control interface contains methods that control
// HTTP header, URL/post query parameters, request/response
// and HTTP output like Code(), Write(), etc.
type Control interface {
	// Request returns *http.Request
	Request() *http.Request

	// Query searches URL/Post query parameters by key.
	// If there are no values associated with the key, an empty string is returned.
	Query(key string) string

	// Param sets URL/Post key/value query parameters.
	Param(key, value string)

	// Response writer section

	// Header represents http.ResponseWriter header, the key-value pairs in an HTTP header.
	Header() http.Header

	// Code sets HTTP status code e.g. http.StatusOk
	Code(code int)

	// Write prepared header, status code and body data into http output.
	Write(data interface{})

	// TODO Add more control methods.
}

// Router interface contains base http methods e.g. GET, PUT, POST
// and defines your own handlers that is useful in some use cases
type Router interface {
	// Standard methods

	// GET registers a new request handle for HTTP GET method.
	GET(path string, f func(Control))
	// PUT registers a new request handle for HTTP PUT method.
	PUT(path string, f func(Control))
	// POST registers a new request handle for HTTP POST method.
	POST(path string, f func(Control))
	// DELETE registers a new request handle for HTTP DELETE method.
	DELETE(path string, f func(Control))
	// HEAD registers a new request handle for HTTP HEAD method.
	HEAD(path string, f func(Control))
	// OPTIONS registers a new request handle for HTTP OPTIONS method.
	OPTIONS(path string, f func(Control))
	// PATCH registers a new request handle for HTTP PATCH method.
	PATCH(path string, f func(Control))

	// User defined options and handlers

	// If enabled, the router automatically replies to OPTIONS requests.
	// Nevertheless OPTIONS handlers take priority over automatic replies.
	// By default this option is disabled
	UseOptionsReplies(bool)

	// SetupNotAllowedHandler defines own handler which is called when a request
	// cannot be routed.
	SetupNotAllowedHandler(func(Control))

	// SetupNotFoundHandler allows to define own handler for undefined URL path.
	// If it is not set, http.NotFound is used.
	SetupNotFoundHandler(func(Control))

	// SetupRecoveryHandler allows to define handler that called when panic happen.
	// The handler prevents your server from crashing and should be used to return
	// http status code http.StatusInternalServerError (500)
	SetupRecoveryHandler(func(Control))

	// SetupMiddleware defines handler that is allowed to take control
	// before it is called standard methods above e.g. GET, PUT.
	SetupMiddleware(func(func(*Control)) func(*Control))

	// Listen and serve on requested host and port e.g "0.0.0.0:8080"
	Listen(hostPort string) error
}

// New returns new router that implement Router interface.
func New() Router {
	return newRouter()
}
<commit_msg>fixed type of middleware function<commit_after>// Copyright 2017 Igor Dolzhikov. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package router

import "net/http"

// Control interface contains methods that control
// HTTP header, URL/post query parameters, request/response
// and HTTP output like Code(), Write(), etc.
type Control interface {
	// Request returns *http.Request
	Request() *http.Request

	// Query searches URL/Post query parameters by key.
	// If there are no values associated with the key, an empty string is returned.
	Query(key string) string

	// Param sets URL/Post key/value query parameters.
	Param(key, value string)

	// Response writer section

	// Header represents http.ResponseWriter header, the key-value pairs in an HTTP header.
	Header() http.Header

	// Code sets HTTP status code e.g. http.StatusOk
	Code(code int)

	// Write prepared header, status code and body data into http output.
	Write(data interface{})

	// TODO Add more control methods.
}

// Router interface contains base http methods e.g. GET, PUT, POST
// and defines your own handlers that is useful in some use cases
type Router interface {
	// Standard methods

	// GET registers a new request handle for HTTP GET method.
	GET(path string, f func(Control))
	// PUT registers a new request handle for HTTP PUT method.
	PUT(path string, f func(Control))
	// POST registers a new request handle for HTTP POST method.
	POST(path string, f func(Control))
	// DELETE registers a new request handle for HTTP DELETE method.
	DELETE(path string, f func(Control))
	// HEAD registers a new request handle for HTTP HEAD method.
	HEAD(path string, f func(Control))
	// OPTIONS registers a new request handle for HTTP OPTIONS method.
	OPTIONS(path string, f func(Control))
	// PATCH registers a new request handle for HTTP PATCH method.
	PATCH(path string, f func(Control))

	// User defined options and handlers

	// If enabled, the router automatically replies to OPTIONS requests.
	// Nevertheless OPTIONS handlers take priority over automatic replies.
	// By default this option is disabled
	UseOptionsReplies(bool)

	// SetupNotAllowedHandler defines own handler which is called when a request
	// cannot be routed.
	SetupNotAllowedHandler(func(Control))

	// SetupNotFoundHandler allows to define own handler for undefined URL path.
	// If it is not set, http.NotFound is used.
	SetupNotFoundHandler(func(Control))

	// SetupRecoveryHandler allows to define handler that called when panic happen.
	// The handler prevents your server from crashing and should be used to return
	// http status code http.StatusInternalServerError (500)
	SetupRecoveryHandler(func(Control))

	// SetupMiddleware defines handler that is allowed to take control
	// before it is called standard methods above e.g. GET, PUT.
	SetupMiddleware(func(func(Control)) func(Control))

	// Listen and serve on requested host and port e.g "0.0.0.0:8080"
	Listen(hostPort string) error
}

// New returns new router that implement Router interface.
func New() Router {
	return newRouter()
}
<|endoftext|>


<commit_before>// Copyright 2018 Google Inc.
//
// 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 state

import (
	"fmt"
	"io"
	"io/ioutil"
	"strings"

	"github.com/golang/protobuf/proto"
	pb "gvisor.googlesource.com/gvisor/pkg/state/object_go_proto"
)

// format formats a single object, for pretty-printing.
func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool) {
	switch x := object.GetValue().(type) {
	case *pb.Object_BoolValue:
		return fmt.Sprintf("%t", x.BoolValue), x.BoolValue != false
	case *pb.Object_StringValue:
		return fmt.Sprintf("\"%s\"", string(x.StringValue)), len(x.StringValue) != 0
	case *pb.Object_Int64Value:
		return fmt.Sprintf("%d", x.Int64Value), x.Int64Value != 0
	case *pb.Object_Uint64Value:
		return fmt.Sprintf("%du", x.Uint64Value), x.Uint64Value != 0
	case *pb.Object_DoubleValue:
		return fmt.Sprintf("%f", x.DoubleValue), x.DoubleValue != 0.0
	case *pb.Object_RefValue:
		if x.RefValue == 0 {
			return "nil", false
		}
		ref := fmt.Sprintf("g%dr%d", graph, x.RefValue)
		if html {
			ref = fmt.Sprintf("%s", ref, ref)
		}
		return ref, true
	case *pb.Object_SliceValue:
		if x.SliceValue.RefValue == 0 {
			return "nil", false
		}
		ref := fmt.Sprintf("g%dr%d", graph, x.SliceValue.RefValue)
		if html {
			ref = fmt.Sprintf("%s", ref, ref)
		}
		return fmt.Sprintf("%s[:%d:%d]", ref, x.SliceValue.Length, x.SliceValue.Capacity), true
	case *pb.Object_ArrayValue:
		if len(x.ArrayValue.Contents) == 0 {
			return "[]", false
		}
		items := make([]string, 0, len(x.ArrayValue.Contents)+2)
		zeros := make([]string, 0) // used to eliminate zero entries.
		items = append(items, "[")
		tabs := "\n" + strings.Repeat("\t", depth)
		for i := 0; i < len(x.ArrayValue.Contents); i++ {
			item, ok := format(graph, depth+1, x.ArrayValue.Contents[i], html)
			if ok {
				if len(zeros) > 0 {
					items = append(items, zeros...)
					zeros = nil
				}
				items = append(items, fmt.Sprintf("\t%s,", item))
			} else {
				zeros = append(zeros, fmt.Sprintf("\t%s,", item))
			}
		}
		if len(zeros) > 0 {
			items = append(items, fmt.Sprintf("\t... (%d zero),", len(zeros)))
		}
		items = append(items, "]")
		return strings.Join(items, tabs), len(zeros) < len(x.ArrayValue.Contents)
	case *pb.Object_StructValue:
		if len(x.StructValue.Fields) == 0 {
			return "struct{}", false
		}
		items := make([]string, 0, len(x.StructValue.Fields)+2)
		items = append(items, "struct{")
		tabs := "\n" + strings.Repeat("\t", depth)
		allZero := true
		for _, field := range x.StructValue.Fields {
			element, ok := format(graph, depth+1, field.Value, html)
			allZero = allZero && !ok
			items = append(items, fmt.Sprintf("\t%s: %s,", field.Name, element))
		}
		items = append(items, "}")
		return strings.Join(items, tabs), !allZero
	case *pb.Object_MapValue:
		if len(x.MapValue.Keys) == 0 {
			return "map{}", false
		}
		items := make([]string, 0, len(x.MapValue.Keys)+2)
		items = append(items, "map{")
		tabs := "\n" + strings.Repeat("\t", depth)
		for i := 0; i < len(x.MapValue.Keys); i++ {
			key, _ := format(graph, depth+1, x.MapValue.Keys[i], html)
			value, _ := format(graph, depth+1, x.MapValue.Values[i], html)
			items = append(items, fmt.Sprintf("\t%s: %s,", key, value))
		}
		items = append(items, "}")
		return strings.Join(items, tabs), true
	case *pb.Object_InterfaceValue:
		if x.InterfaceValue.Type == "" {
			return "interface(nil){}", false
		}
		element, _ := format(graph, depth+1, x.InterfaceValue.Value, html)
		return fmt.Sprintf("interface(\"%s\"){%s}", x.InterfaceValue.Type, element), true
	}

	// Should not happen, but tolerate.
	return fmt.Sprintf("(unknown proto type: %T)", object.GetValue()), true
}

// PrettyPrint reads the state stream from r, and pretty prints to w.
func PrettyPrint(w io.Writer, r io.Reader, html bool) error {
	var (
		// current graph ID.
		graph uint64

		// current object ID.
		id uint64
	)

	if html {
		fmt.Fprintf(w, "
")
		defer fmt.Fprintf(w, "
")
	}

	for {
		// Find the first object to begin generation.
		length, object, err := ReadHeader(r)
		if err == io.EOF {
			// Nothing else to do.
			break
		} else if err != nil {
			return err
		}
		if !object {
			// Increment the graph number & reset the ID.
			graph++
			id = 0
			if length > 0 {
				fmt.Fprintf(w, "(%d bytes non-object data)\n", length)
				io.Copy(ioutil.Discard, &io.LimitedReader{
					R: r,
					N: int64(length),
				})
			}
			continue
		}

		// Read & unmarshal the object.
		buf := make([]byte, length)
		for done := 0; done < len(buf); {
			n, err := r.Read(buf[done:])
			done += n
			if n == 0 && err != nil {
				return err
			}
		}
		obj := new(pb.Object)
		if err := proto.Unmarshal(buf, obj); err != nil {
			return err
		}

		id++ // First object must be one.
		str, _ := format(graph, 0, obj, html)
		tag := fmt.Sprintf("g%dr%d", graph, id)
		if html {
			tag = fmt.Sprintf("%s", tag, tag)
		}
		if _, err := fmt.Fprintf(w, "%s = %s\n", tag, str); err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>state: pretty-print primitive type arrays.<commit_after>// Copyright 2018 Google Inc.
//
// 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 state

import (
	"fmt"
	"io"
	"io/ioutil"
	"reflect"
	"strings"

	"github.com/golang/protobuf/proto"
	pb "gvisor.googlesource.com/gvisor/pkg/state/object_go_proto"
)

// format formats a single object, for pretty-printing. It also returns whether
// the value is a non-zero value.
func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool) {
	switch x := object.GetValue().(type) {
	case *pb.Object_BoolValue:
		return fmt.Sprintf("%t", x.BoolValue), x.BoolValue != false
	case *pb.Object_StringValue:
		return fmt.Sprintf("\"%s\"", string(x.StringValue)), len(x.StringValue) != 0
	case *pb.Object_Int64Value:
		return fmt.Sprintf("%d", x.Int64Value), x.Int64Value != 0
	case *pb.Object_Uint64Value:
		return fmt.Sprintf("%du", x.Uint64Value), x.Uint64Value != 0
	case *pb.Object_DoubleValue:
		return fmt.Sprintf("%f", x.DoubleValue), x.DoubleValue != 0.0
	case *pb.Object_RefValue:
		if x.RefValue == 0 {
			return "nil", false
		}
		ref := fmt.Sprintf("g%dr%d", graph, x.RefValue)
		if html {
			ref = fmt.Sprintf("%s", ref, ref)
		}
		return ref, true
	case *pb.Object_SliceValue:
		if x.SliceValue.RefValue == 0 {
			return "nil", false
		}
		ref := fmt.Sprintf("g%dr%d", graph, x.SliceValue.RefValue)
		if html {
			ref = fmt.Sprintf("%s", ref, ref)
		}
		return fmt.Sprintf("%s[:%d:%d]", ref, x.SliceValue.Length, x.SliceValue.Capacity), true
	case *pb.Object_ArrayValue:
		if len(x.ArrayValue.Contents) == 0 {
			return "[]", false
		}
		items := make([]string, 0, len(x.ArrayValue.Contents)+2)
		zeros := make([]string, 0) // used to eliminate zero entries.
		items = append(items, "[")
		tabs := "\n" + strings.Repeat("\t", depth)
		for i := 0; i < len(x.ArrayValue.Contents); i++ {
			item, ok := format(graph, depth+1, x.ArrayValue.Contents[i], html)
			if ok {
				if len(zeros) > 0 {
					items = append(items, zeros...)
					zeros = nil
				}
				items = append(items, fmt.Sprintf("\t%s,", item))
			} else {
				zeros = append(zeros, fmt.Sprintf("\t%s,", item))
			}
		}
		if len(zeros) > 0 {
			items = append(items, fmt.Sprintf("\t... (%d zeros),", len(zeros)))
		}
		items = append(items, "]")
		return strings.Join(items, tabs), len(zeros) < len(x.ArrayValue.Contents)
	case *pb.Object_StructValue:
		if len(x.StructValue.Fields) == 0 {
			return "struct{}", false
		}
		items := make([]string, 0, len(x.StructValue.Fields)+2)
		items = append(items, "struct{")
		tabs := "\n" + strings.Repeat("\t", depth)
		allZero := true
		for _, field := range x.StructValue.Fields {
			element, ok := format(graph, depth+1, field.Value, html)
			allZero = allZero && !ok
			items = append(items, fmt.Sprintf("\t%s: %s,", field.Name, element))
		}
		items = append(items, "}")
		return strings.Join(items, tabs), !allZero
	case *pb.Object_MapValue:
		if len(x.MapValue.Keys) == 0 {
			return "map{}", false
		}
		items := make([]string, 0, len(x.MapValue.Keys)+2)
		items = append(items, "map{")
		tabs := "\n" + strings.Repeat("\t", depth)
		for i := 0; i < len(x.MapValue.Keys); i++ {
			key, _ := format(graph, depth+1, x.MapValue.Keys[i], html)
			value, _ := format(graph, depth+1, x.MapValue.Values[i], html)
			items = append(items, fmt.Sprintf("\t%s: %s,", key, value))
		}
		items = append(items, "}")
		return strings.Join(items, tabs), true
	case *pb.Object_InterfaceValue:
		if x.InterfaceValue.Type == "" {
			return "interface(nil){}", false
		}
		element, _ := format(graph, depth+1, x.InterfaceValue.Value, html)
		return fmt.Sprintf("interface(\"%s\"){%s}", x.InterfaceValue.Type, element), true
	case *pb.Object_ByteArrayValue:
		return printArray(reflect.ValueOf(x.ByteArrayValue))
	case *pb.Object_Uint16ArrayValue:
		return printArray(reflect.ValueOf(x.Uint16ArrayValue.Values))
	case *pb.Object_Uint32ArrayValue:
		return printArray(reflect.ValueOf(x.Uint32ArrayValue.Values))
	case *pb.Object_Uint64ArrayValue:
		return printArray(reflect.ValueOf(x.Uint64ArrayValue.Values))
	case *pb.Object_UintptrArrayValue:
		return printArray(castSlice(reflect.ValueOf(x.UintptrArrayValue.Values), reflect.TypeOf(uintptr(0))))
	case *pb.Object_Int8ArrayValue:
		return printArray(castSlice(reflect.ValueOf(x.Int8ArrayValue.Values), reflect.TypeOf(int8(0))))
	case *pb.Object_Int16ArrayValue:
		return printArray(reflect.ValueOf(x.Int16ArrayValue.Values))
	case *pb.Object_Int32ArrayValue:
		return printArray(reflect.ValueOf(x.Int32ArrayValue.Values))
	case *pb.Object_Int64ArrayValue:
		return printArray(reflect.ValueOf(x.Int64ArrayValue.Values))
	case *pb.Object_BoolArrayValue:
		return printArray(reflect.ValueOf(x.BoolArrayValue.Values))
	case *pb.Object_Float64ArrayValue:
		return printArray(reflect.ValueOf(x.Float64ArrayValue.Values))
	case *pb.Object_Float32ArrayValue:
		return printArray(reflect.ValueOf(x.Float32ArrayValue.Values))
	}

	// Should not happen, but tolerate.
	return fmt.Sprintf("(unknown proto type: %T)", object.GetValue()), true
}

// PrettyPrint reads the state stream from r, and pretty prints to w.
func PrettyPrint(w io.Writer, r io.Reader, html bool) error {
	var (
		// current graph ID.
		graph uint64

		// current object ID.
		id uint64
	)

	if html {
		fmt.Fprintf(w, "
")
		defer fmt.Fprintf(w, "
")
	}

	for {
		// Find the first object to begin generation.
		length, object, err := ReadHeader(r)
		if err == io.EOF {
			// Nothing else to do.
			break
		} else if err != nil {
			return err
		}
		if !object {
			// Increment the graph number & reset the ID.
			graph++
			id = 0
			if length > 0 {
				fmt.Fprintf(w, "(%d bytes non-object data)\n", length)
				io.Copy(ioutil.Discard, &io.LimitedReader{
					R: r,
					N: int64(length),
				})
			}
			continue
		}

		// Read & unmarshal the object.
		buf := make([]byte, length)
		for done := 0; done < len(buf); {
			n, err := r.Read(buf[done:])
			done += n
			if n == 0 && err != nil {
				return err
			}
		}
		obj := new(pb.Object)
		if err := proto.Unmarshal(buf, obj); err != nil {
			return err
		}

		id++ // First object must be one.
		str, _ := format(graph, 0, obj, html)
		tag := fmt.Sprintf("g%dr%d", graph, id)
		if html {
			tag = fmt.Sprintf("%s", tag, tag)
		}
		if _, err := fmt.Fprintf(w, "%s = %s\n", tag, str); err != nil {
			return err
		}
	}

	return nil
}

func printArray(s reflect.Value) (string, bool) {
	zero := reflect.Zero(s.Type().Elem()).Interface()
	z := "0"
	switch s.Type().Elem().Kind() {
	case reflect.Bool:
		z = "false"
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
	case reflect.Float32, reflect.Float64:
	default:
		return fmt.Sprintf("unexpected non-primitive type array: %#v", s.Interface()), true
	}

	zeros := 0
	items := make([]string, 0, s.Len())
	for i := 0; i <= s.Len(); i++ {
		if i < s.Len() && reflect.DeepEqual(s.Index(i).Interface(), zero) {
			zeros++
			continue
		}
		if zeros > 0 {
			if zeros <= 4 {
				for ; zeros > 0; zeros-- {
					items = append(items, z)
				}
			} else {
				items = append(items, fmt.Sprintf("(%d %ss)", zeros, z))
				zeros = 0
			}
		}
		if i < s.Len() {
			items = append(items, fmt.Sprintf("%v", s.Index(i).Interface()))
		}
	}
	return "[" + strings.Join(items, ",") + "]", zeros < s.Len()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	_build "neon/build"
	_ "neon/builtin"
	_ "neon/task"
	"neon/util"
	"os"
	"path/filepath"
	"time"
)

const (
	DEFAULT_BUILD_FILE = "build.yml"
)

func ParseCommandLine() (string, bool, bool, bool, string, bool, bool, string, bool, []string) {
	file := flag.String("file", DEFAULT_BUILD_FILE, "Build file to run")
	help := flag.Bool("build", false, "Print build help")
	timeit := flag.Bool("time", false, "Print build duration")
	tasks := flag.Bool("tasks", false, "Print tasks list")
	task := flag.String("task", "", "Print help on given task")
	targs := flag.Bool("targets", false, "Print targets list")
	builtins := flag.Bool("builtins", false, "Print builtins list")
	builtin := flag.String("builtin", "", "Print help on given builtin")
	refs := flag.Bool("refs", false, "Print tasks and builtins reference")
	flag.Parse()
	targets := flag.Args()
	return *file, *help, *timeit, *tasks, *task, *targs, *builtins, *builtin, *refs, targets
}

func FindBuildFile(name string) (string, error) {
	absolute, err := filepath.Abs(name)
	if err != nil {
		return "", fmt.Errorf("getting build file path: %v", err)
	}
	file := filepath.Base(absolute)
	dir := filepath.Dir(absolute)
	for {
		path := filepath.Join(dir, file)
		if util.FileExists(path) {
			return path, nil
		} else {
			parent := filepath.Dir(dir)
			if parent == dir {
				return "", fmt.Errorf("build file not found")
			}
			dir = parent
		}
	}
}

func main() {
	start := time.Now()
	file, help, timeit, tasks, task, targs, builtins, builtin, refs, targets := ParseCommandLine()
	if tasks {
		_build.PrintTasks()
		os.Exit(0)
	} else if task != "" {
		_build.PrintHelpTask(task)
		os.Exit(0)
	} else if builtins {
		_build.PrintBuiltins()
		os.Exit(0)
	} else if builtin != "" {
		_build.PrintHelpBuiltin(builtin)
		os.Exit(0)
	} else if refs {
		_build.PrintReference()
		os.Exit(0)
	}
	path, err := FindBuildFile(file)
	if err != nil {
		util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
		os.Exit(1)
	}
	build, err := _build.NewBuild(path)
	if err != nil {
		util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
		os.Exit(2)
	}
	if targs {
		build.PrintTargets()
	} else if help {
		err = build.Init()
		if err == nil {
			err = build.Help()
		}
		if err != nil {
			util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
			os.Exit(3)
		}
	} else {
		err = build.Init()
		if err == nil {
			err = build.Run(targets)
		}
		duration := time.Now().Sub(start)
		if timeit || duration.Seconds() > 10 {
			_build.Info("Build duration: %s", duration.String())
		}
		if err == nil {
			util.PrintColor("%s", util.Green("OK"))
		} else {
			util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
			os.Exit(4)
		}
	}
}
<commit_msg>Added comment<commit_after>package main

import (
	"flag"
	"fmt"
	_build "neon/build"
	_ "neon/builtin"
	_ "neon/task"
	"neon/util"
	"os"
	"path/filepath"
	"time"
)

const (
	DEFAULT_BUILD_FILE = "build.yml"
)

func ParseCommandLine() (string, bool, bool, bool, string, bool, bool, string, bool, []string) {
	file := flag.String("file", DEFAULT_BUILD_FILE, "Build file to run")
	help := flag.Bool("build", false, "Print build help")
	timeit := flag.Bool("time", false, "Print build duration")
	tasks := flag.Bool("tasks", false, "Print tasks list")
	task := flag.String("task", "", "Print help on given task")
	targs := flag.Bool("targets", false, "Print targets list")
	builtins := flag.Bool("builtins", false, "Print builtins list")
	builtin := flag.String("builtin", "", "Print help on given builtin")
	refs := flag.Bool("refs", false, "Print tasks and builtins reference")
	flag.Parse()
	targets := flag.Args()
	return *file, *help, *timeit, *tasks, *task, *targs, *builtins, *builtin, *refs, targets
}

func FindBuildFile(name string) (string, error) {
	absolute, err := filepath.Abs(name)
	if err != nil {
		return "", fmt.Errorf("getting build file path: %v", err)
	}
	file := filepath.Base(absolute)
	dir := filepath.Dir(absolute)
	for {
		path := filepath.Join(dir, file)
		if util.FileExists(path) {
			return path, nil
		} else {
			parent := filepath.Dir(dir)
			if parent == dir {
				return "", fmt.Errorf("build file not found")
			}
			dir = parent
		}
	}
}

func main() {
	start := time.Now()
	file, help, timeit, tasks, task, targs, builtins, builtin, refs, targets := ParseCommandLine()
	// options that do not require we load build file
	if tasks {
		_build.PrintTasks()
		os.Exit(0)
	} else if task != "" {
		_build.PrintHelpTask(task)
		os.Exit(0)
	} else if builtins {
		_build.PrintBuiltins()
		os.Exit(0)
	} else if builtin != "" {
		_build.PrintHelpBuiltin(builtin)
		os.Exit(0)
	} else if refs {
		_build.PrintReference()
		os.Exit(0)
	}
	// options that do require we load build file
	path, err := FindBuildFile(file)
	if err != nil {
		util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
		os.Exit(1)
	}
	build, err := _build.NewBuild(path)
	if err != nil {
		util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
		os.Exit(2)
	}
	if targs {
		build.PrintTargets()
	} else if help {
		err = build.Init()
		if err == nil {
			err = build.Help()
		}
		if err != nil {
			util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
			os.Exit(3)
		}
	} else {
		err = build.Init()
		if err == nil {
			err = build.Run(targets)
		}
		duration := time.Now().Sub(start)
		if timeit || duration.Seconds() > 10 {
			_build.Info("Build duration: %s", duration.String())
		}
		if err == nil {
			util.PrintColor("%s", util.Green("OK"))
		} else {
			util.PrintColor("%s %s", util.Red("ERROR"), err.Error())
			os.Exit(4)
		}
	}
}
<|endoftext|>


<commit_before>package players

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

var drafted []Player = []Player{
	{ID: 1, Name: "Antonio Brown", Position: "WR"},
	{ID: 2, Name: "Tony Romo", Position: "QB"},
}

var unDrafted []Player = []Player{
	{ID: 3, Name: "Jason Witten"},
	{ID: 4, Name: "Josh Gordon"},
	{ID: 5, Name: "Joshua Smith"},
	{ID: 99, Name: "Tim Tebow", Position: "Baseball"},
}

var subject *Repo = &Repo{
	Drafted:   drafted,
	UnDrafted: unDrafted,
}

func TestRepo_Find(t *testing.T) {
	var tests = []struct {
		search string
		result int
	}{
		{"antonio", 1},
		{"a brown", 1},
		{"witten", 3},
		{"josh gordon", 4},
	}
	for _, test := range tests {
		player := subject.Find(test.search)[0]

		assert.Equal(t, player.ID, test.result)
	}

	count := len(subject.Find("josh"))

	assert.Equal(t, count, 2)
}

func TestNewRepo(t *testing.T) {
	r := NewRepo(unDrafted)

	tebow := r.Find("Tim Tebow")
	assert.Equal(t, len(tebow), 0)
}
<commit_msg>fix test<commit_after>package players

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

var drafted []Player = []Player{
	{ID: 1, Name: "Antonio Brown", Position: "WR"},
	{ID: 2, Name: "Tony Romo", Position: "QB"},
}

var unDrafted []Player = []Player{
	{ID: 3, Name: "Jason Witten", Position: "TE"},
	{ID: 4, Name: "Josh Gordon", Position: "WR"},
	{ID: 5, Name: "Joshua Smith", Position: "RB"},
	{ID: 99, Name: "Tim Tebow", Position: "Baseball"},
}

var subject *Repo = &Repo{
	Drafted:   drafted,
	UnDrafted: unDrafted,
}

func TestRepo_Find(t *testing.T) {
	var tests = []struct {
		search string
		result int
	}{
		{"antonio", 1},
		{"a brown", 1},
		{"witten", 3},
		{"josh gordon", 4},
	}
	for _, test := range tests {
		player := subject.Find(test.search)[0]

		assert.Equal(t, player.ID, test.result)
	}

	count := len(subject.Find("josh"))

	assert.Equal(t, count, 2)
}

func TestNewRepo(t *testing.T) {
	r := NewRepo(unDrafted)

	tebow := r.Find("Tim Tebow")
	assert.Equal(t, len(tebow), 0)

	witten := r.Find("Witten")
	assert.Equal(t, len(witten), 1)
}
<|endoftext|>


<commit_before>package playlist

import (
	"errors"
	"fmt"
	"gitlab.transip.us/swiltink/go-MusicBot/player"
	"math/rand"
	"sync"
	"time"
)

type MusicPlaylist struct {
	currentItem ItemInterface
	items       []ItemInterface
	status      Status

	players       []player.MusicPlayerInterface
	currentPlayer player.MusicPlayerInterface

	playTimer         *time.Timer
	endTime           time.Time
	remainingDuration time.Duration

	controlMutex sync.Mutex
}

func NewPlaylist() (playlist *MusicPlaylist) {
	playlist = &MusicPlaylist{
		status: STOPPED,
	}
	return
}

func (p *MusicPlaylist) AddMusicPlayer(player player.MusicPlayerInterface) {
	p.players = append(p.players, player)
}

func (p *MusicPlaylist) GetItems() (items []ItemInterface) {
	return p.items
}

func (p *MusicPlaylist) GetCurrentItem() (item ItemInterface) {
	return p.currentItem
}

func (p *MusicPlaylist) findPlayer(url string) (musicPlayer player.MusicPlayerInterface, err error) {
	for _, play := range p.players {
		if play.CanPlay(url) {
			musicPlayer = play
			return
		}
	}
	err = fmt.Errorf("No suitable musicplayer found to play %s", url)
	return
}

func (p *MusicPlaylist) AddItems(url string) (addedItems []ItemInterface, err error) {
	musicPlayer, err := p.findPlayer(url)
	if err != nil {
		return
	}

	plItems, err := musicPlayer.GetItems(url)
	if err != nil {
		err = fmt.Errorf("[%s] Error getting items from url: %v", musicPlayer.Name(), err)
		return
	}

	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	for _, plItem := range plItems {
		p.items = append(p.items, &plItem)
		addedItems = append(addedItems, &plItem)
	}
	return
}

func (p *MusicPlaylist) ShuffleList() {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	for i := range p.items {
		j := rand.Intn(i + 1)
		p.items[i], p.items[j] = p.items[j], p.items[i]
	}
}
func (p *MusicPlaylist) EmptyList() {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	p.items = make([]ItemInterface, 0)
}

func (p *MusicPlaylist) GetStatus() (status Status) {
	return p.status
}

func (p *MusicPlaylist) Play() (item ItemInterface, err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	switch p.status {
	case STOPPED:
		item, err = p.next()
		return
	case PAUSED:
		err = p.pause()
	}
	item = p.currentItem
	return
}

func (p *MusicPlaylist) playWait() {
	p.playTimer = time.NewTimer(p.endTime.Sub(time.Now()))

	// Wait for the timer to time out, or be canceled because of a STOP or something
	<-p.playTimer.C

	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	p.currentItem = nil
	if len(p.items) > 0 && p.status == PLAYING {
		p.next()
	}
}

func (p *MusicPlaylist) Next() (item ItemInterface, err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.next()
}

func (p *MusicPlaylist) next() (item ItemInterface, err error) {
	if len(p.items) == 0 {
		err = errors.New("Playlist is empty, no next available")
		return
	}
	if p.status == PLAYING || p.status == PAUSED {
		p.stop()
	}

	item, p.items = p.items[0], p.items[1:]
	musicPlayer, err := p.findPlayer(item.GetURL())
	if err != nil {
		return
	}
	err = musicPlayer.Play(item.GetURL())
	if err != nil {
		err = fmt.Errorf("[%s] Error playing: %v", musicPlayer.Name(), err)
		return
	}
	p.currentItem = item
	p.currentPlayer = musicPlayer
	p.status = PLAYING
	p.endTime = time.Now().Add(item.GetDuration())
	// Start waiting for the song to be done
	go p.playWait()
	return
}

func (p *MusicPlaylist) Stop() (err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.stop()
}

func (p *MusicPlaylist) stop() (err error) {
	if p.status == STOPPED || p.currentPlayer == nil {
		err = errors.New("Nothing currently playing")
		return
	}
	err = p.currentPlayer.Stop()
	if err != nil {
		err = fmt.Errorf("[%s] Error stopping: %v", p.currentPlayer.Name(), err)
		return
	}
	p.currentItem = nil
	p.currentPlayer = nil
	if p.playTimer != nil {
		// Kill the current playWait()
		p.playTimer.Stop()
	}
	return
}

func (p *MusicPlaylist) Pause() (err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.pause()
}

func (p *MusicPlaylist) pause() (err error) {
	if p.status == STOPPED || p.currentPlayer == nil {
		err = errors.New("Nothing currently playing")
		return
	}

	err = p.currentPlayer.Pause(p.status != PAUSED)
	if err != nil {
		err = fmt.Errorf("[%s] Error (un)pausing [%v]: %v", p.currentPlayer.Name(), p.status != PAUSED, err)
		return
	}
	if p.status == PAUSED {
		p.status = PLAYING
		p.endTime = time.Now().Add(p.remainingDuration)
		// Restart the play wait goroutine with the new time
		go p.playWait()
	} else {
		p.status = PAUSED
		p.remainingDuration = p.endTime.Sub(time.Now())
		if p.playTimer != nil {
			// Kill the current playWait()
			p.playTimer.Stop()
		}
	}
	return
}
<commit_msg>Attempt to fix repeated playing at end of list<commit_after>package playlist

import (
	"errors"
	"fmt"
	"gitlab.transip.us/swiltink/go-MusicBot/player"
	"math/rand"
	"sync"
	"time"
)

type MusicPlaylist struct {
	currentItem ItemInterface
	items       []ItemInterface
	status      Status

	players       []player.MusicPlayerInterface
	currentPlayer player.MusicPlayerInterface

	playTimer         *time.Timer
	endTime           time.Time
	remainingDuration time.Duration

	controlMutex sync.Mutex
}

func NewPlaylist() (playlist *MusicPlaylist) {
	playlist = &MusicPlaylist{
		status: STOPPED,
	}
	return
}

func (p *MusicPlaylist) AddMusicPlayer(player player.MusicPlayerInterface) {
	p.players = append(p.players, player)
}

func (p *MusicPlaylist) GetItems() (items []ItemInterface) {
	return p.items
}

func (p *MusicPlaylist) GetCurrentItem() (item ItemInterface) {
	return p.currentItem
}

func (p *MusicPlaylist) findPlayer(url string) (musicPlayer player.MusicPlayerInterface, err error) {
	for _, play := range p.players {
		if play.CanPlay(url) {
			musicPlayer = play
			return
		}
	}
	err = fmt.Errorf("No suitable musicplayer found to play %s", url)
	return
}

func (p *MusicPlaylist) AddItems(url string) (addedItems []ItemInterface, err error) {
	musicPlayer, err := p.findPlayer(url)
	if err != nil {
		return
	}

	plItems, err := musicPlayer.GetItems(url)
	if err != nil {
		err = fmt.Errorf("[%s] Error getting items from url: %v", musicPlayer.Name(), err)
		return
	}

	for _, plItem := range plItems {
		addedItems = append(addedItems, &plItem)
	}
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	p.items = append(p.items, addedItems...)
	return
}

func (p *MusicPlaylist) ShuffleList() {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	for i := range p.items {
		j := rand.Intn(i + 1)
		p.items[i], p.items[j] = p.items[j], p.items[i]
	}
}
func (p *MusicPlaylist) EmptyList() {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	p.items = make([]ItemInterface, 0)
}

func (p *MusicPlaylist) GetStatus() (status Status) {
	return p.status
}

func (p *MusicPlaylist) Play() (item ItemInterface, err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	switch p.status {
	case STOPPED:
		item, err = p.next()
		return
	case PAUSED:
		err = p.pause()
	}
	item = p.currentItem
	return
}

func (p *MusicPlaylist) playWait() {
	p.playTimer = time.NewTimer(p.endTime.Sub(time.Now()))

	// Wait for the timer to time out, or be canceled because of a STOP or something
	<-p.playTimer.C

	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	p.currentItem = nil

	if len(p.items) == 0 {
		p.stop()
	} else if len(p.items) > 0 && p.status == PLAYING {
		p.next()
	}
}

func (p *MusicPlaylist) Next() (item ItemInterface, err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.next()
}

func (p *MusicPlaylist) next() (item ItemInterface, err error) {
	if len(p.items) == 0 {
		err = errors.New("Playlist is empty, no next available")
		return
	}
	if p.status == PLAYING || p.status == PAUSED {
		p.stop()
	}

	item, p.items = p.items[0], p.items[1:]
	musicPlayer, err := p.findPlayer(item.GetURL())
	if err != nil {
		return
	}
	err = musicPlayer.Play(item.GetURL())
	if err != nil {
		err = fmt.Errorf("[%s] Error playing: %v", musicPlayer.Name(), err)
		return
	}
	p.currentItem = item
	p.currentPlayer = musicPlayer
	p.status = PLAYING
	p.endTime = time.Now().Add(item.GetDuration())
	// Start waiting for the song to be done
	go p.playWait()
	return
}

func (p *MusicPlaylist) Stop() (err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.stop()
}

func (p *MusicPlaylist) stop() (err error) {
	if p.status == STOPPED || p.currentPlayer == nil {
		err = errors.New("Nothing currently playing")
		return
	}
	err = p.currentPlayer.Stop()
	if err != nil {
		err = fmt.Errorf("[%s] Error stopping: %v", p.currentPlayer.Name(), err)
		return
	}
	p.currentItem = nil
	p.currentPlayer = nil
	if p.playTimer != nil {
		// Kill the current playWait()
		p.playTimer.Stop()
	}
	return
}

func (p *MusicPlaylist) Pause() (err error) {
	p.controlMutex.Lock()
	defer p.controlMutex.Unlock()

	return p.pause()
}

func (p *MusicPlaylist) pause() (err error) {
	if p.status == STOPPED || p.currentPlayer == nil {
		err = errors.New("Nothing currently playing")
		return
	}

	err = p.currentPlayer.Pause(p.status != PAUSED)
	if err != nil {
		err = fmt.Errorf("[%s] Error (un)pausing [%v]: %v", p.currentPlayer.Name(), p.status != PAUSED, err)
		return
	}
	if p.status == PAUSED {
		p.status = PLAYING
		p.endTime = time.Now().Add(p.remainingDuration)
		// Restart the play wait goroutine with the new time
		go p.playWait()
	} else {
		p.status = PAUSED
		p.remainingDuration = p.endTime.Sub(time.Now())
		if p.playTimer != nil {
			// Kill the current playWait()
			p.playTimer.Stop()
		}
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2012 The Plotinum Authors. All rights reserved.
// Use of this source code is governed by an MIT-style license
// that can be found in the LICENSE file.

// plotutil contains a small number of utilites for creating plots.
// This package is under active development so portions of
// it may change.
package plotutil

import (
	"code.google.com/p/plotinum/plot"
	"code.google.com/p/plotinum/vg"
	"image/color"
)

// DefaultColors is a set of colors used by the Color funciton.
var DefaultColors = SoftColors

// DarkColors is a set darker colors.
var DarkColors = []color.Color{
	rgb(238, 46, 47),
	rgb(0, 140, 72),
	rgb(24, 90, 169),
	rgb(244, 125, 35),
	rgb(102, 44, 145),
	rgb(162, 29, 33),
	rgb(180, 56, 148),
}

// SoftColors is a set of low-intensity colors.
var SoftColors = []color.Color{
	rgb(241, 90, 96),
	rgb(122, 195, 106),
	rgb(90, 155, 212),
	rgb(250, 167, 91),
	rgb(158, 103, 171),
	rgb(206, 112, 88),
	rgb(215, 127, 180),
}

func rgb(r, g, b uint8) color.RGBA {
	return color.RGBA{r, g, b, 255}
}

// Color returns the ith default color, wrapping
// if i is less than zero or greater than the max
// number of colors in the DefaultColors slice.
func Color(i int) color.Color {
	n := len(DefaultColors)
	if i < 0 {
		return DefaultColors[i%n+n]
	}
	return DefaultColors[i%n]
}

// DefaultGlyphShapes is a set of GlyphDrawers used by
// the Shape function.
var DefaultGlyphShapes = []plot.GlyphDrawer{
	plot.RingGlyph{},
	plot.SquareGlyph{},
	plot.TriangleGlyph{},
	plot.CrossGlyph{},
	plot.PlusGlyph{},
	plot.CircleGlyph{},
	plot.BoxGlyph{},
	plot.PyramidGlyph{},
}

// Shape returns the ith default glyph shape,
// wrapping if i is less than zero or greater
// than the max number of GlyphDrawers
// in the DefaultGlyphShapes slice.
func Shape(i int) plot.GlyphDrawer {
	n := len(DefaultGlyphShapes)
	if i < 0 {
		return DefaultGlyphShapes[i%n+n]
	}
	return DefaultGlyphShapes[i%n]
}

// DefaultDashes is a set of dash patterns used by
// the Dashes function.
var DefaultDashes = [][]vg.Length{
	{},

	{vg.Points(6), vg.Points(2)},

	{vg.Points(2), vg.Points(2)},

	{vg.Points(1), vg.Points(1)},

	{vg.Points(5), vg.Points(2), vg.Points(1), vg.Points(2)},

	{vg.Points(10), vg.Points(2), vg.Points(2), vg.Points(2),
		vg.Points(2), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(10), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(5), vg.Points(2), vg.Points(5), vg.Points(2),
		vg.Points(2), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(4), vg.Points(2), vg.Points(4), vg.Points(1),
		vg.Points(1), vg.Points(1), vg.Points(1), vg.Points(1),
		vg.Points(1), vg.Points(1)},
}

// Dashes returns the ith default dash pattern,
// wrapping if i is less than zero or greater
// than the max number of dash patters
// in the DefaultDashes slice.
func Dashes(i int) []vg.Length {
	n := len(DefaultDashes)
	if i < 0 {
		return DefaultDashes[i%n+n]
	}
	return DefaultDashes[i%n]
}
<commit_msg>Remove redundant comments.<commit_after>// Copyright 2012 The Plotinum Authors. All rights reserved.
// Use of this source code is governed by an MIT-style license
// that can be found in the LICENSE file.

// plotutil contains a small number of utilites for creating plots.
// This package is under active development so portions of
// it may change.
package plotutil

import (
	"code.google.com/p/plotinum/plot"
	"code.google.com/p/plotinum/vg"
	"image/color"
)

// DefaultColors is a set of colors used by the Color funciton.
var DefaultColors = SoftColors

var DarkColors = []color.Color{
	rgb(238, 46, 47),
	rgb(0, 140, 72),
	rgb(24, 90, 169),
	rgb(244, 125, 35),
	rgb(102, 44, 145),
	rgb(162, 29, 33),
	rgb(180, 56, 148),
}

var SoftColors = []color.Color{
	rgb(241, 90, 96),
	rgb(122, 195, 106),
	rgb(90, 155, 212),
	rgb(250, 167, 91),
	rgb(158, 103, 171),
	rgb(206, 112, 88),
	rgb(215, 127, 180),
}

func rgb(r, g, b uint8) color.RGBA {
	return color.RGBA{r, g, b, 255}
}

// Color returns the ith default color, wrapping
// if i is less than zero or greater than the max
// number of colors in the DefaultColors slice.
func Color(i int) color.Color {
	n := len(DefaultColors)
	if i < 0 {
		return DefaultColors[i%n+n]
	}
	return DefaultColors[i%n]
}

// DefaultGlyphShapes is a set of GlyphDrawers used by
// the Shape function.
var DefaultGlyphShapes = []plot.GlyphDrawer{
	plot.RingGlyph{},
	plot.SquareGlyph{},
	plot.TriangleGlyph{},
	plot.CrossGlyph{},
	plot.PlusGlyph{},
	plot.CircleGlyph{},
	plot.BoxGlyph{},
	plot.PyramidGlyph{},
}

// Shape returns the ith default glyph shape,
// wrapping if i is less than zero or greater
// than the max number of GlyphDrawers
// in the DefaultGlyphShapes slice.
func Shape(i int) plot.GlyphDrawer {
	n := len(DefaultGlyphShapes)
	if i < 0 {
		return DefaultGlyphShapes[i%n+n]
	}
	return DefaultGlyphShapes[i%n]
}

// DefaultDashes is a set of dash patterns used by
// the Dashes function.
var DefaultDashes = [][]vg.Length{
	{},

	{vg.Points(6), vg.Points(2)},

	{vg.Points(2), vg.Points(2)},

	{vg.Points(1), vg.Points(1)},

	{vg.Points(5), vg.Points(2), vg.Points(1), vg.Points(2)},

	{vg.Points(10), vg.Points(2), vg.Points(2), vg.Points(2),
		vg.Points(2), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(10), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(5), vg.Points(2), vg.Points(5), vg.Points(2),
		vg.Points(2), vg.Points(2), vg.Points(2), vg.Points(2)},

	{vg.Points(4), vg.Points(2), vg.Points(4), vg.Points(1),
		vg.Points(1), vg.Points(1), vg.Points(1), vg.Points(1),
		vg.Points(1), vg.Points(1)},
}

// Dashes returns the ith default dash pattern,
// wrapping if i is less than zero or greater
// than the max number of dash patters
// in the DefaultDashes slice.
func Dashes(i int) []vg.Length {
	n := len(DefaultDashes)
	if i < 0 {
		return DefaultDashes[i%n+n]
	}
	return DefaultDashes[i%n]
}
<|endoftext|>


<commit_before>package plugin

import (
	"fmt"
	"sync"

	"github.com/docker/libnetwork/drivers/remote/api"
	"github.com/docker/libnetwork/types"

	"github.com/vishvananda/netlink"
	weaveapi "github.com/weaveworks/weave/api"
	"github.com/weaveworks/weave/common"
	"github.com/weaveworks/weave/common/docker"
	weavenet "github.com/weaveworks/weave/net"
	"github.com/weaveworks/weave/plugin/skel"
)

const (
	WeaveBridge = "weave"
)

type driver struct {
	scope            string
	noMulticastRoute bool
	sync.RWMutex
	endpoints map[string]struct{}
}

func New(client *docker.Client, weave *weaveapi.Client, scope string, noMulticastRoute bool) (skel.Driver, error) {
	driver := &driver{
		noMulticastRoute: noMulticastRoute,
		scope:            scope,
		endpoints:        make(map[string]struct{}),
	}

	_, err := NewWatcher(client, weave, driver)
	if err != nil {
		return nil, err
	}
	return driver, nil
}

// === protocol handlers

func (driver *driver) GetCapabilities() (*api.GetCapabilityResponse, error) {
	driver.logReq("GetCapabilities", nil, "")
	var caps = &api.GetCapabilityResponse{
		Scope: driver.scope,
	}
	driver.logRes("GetCapabilities", caps)
	return caps, nil
}

func (driver *driver) CreateNetwork(create *api.CreateNetworkRequest) error {
	driver.logReq("CreateNetwork", create, create.NetworkID)
	return nil
}

func (driver *driver) DeleteNetwork(delete *api.DeleteNetworkRequest) error {
	driver.logReq("DeleteNetwork", delete, delete.NetworkID)
	return nil
}

func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.CreateEndpointResponse, error) {
	driver.logReq("CreateEndpoint", create, create.EndpointID)
	endID := create.EndpointID

	if create.Interface == nil {
		return nil, driver.error("CreateEndpoint", "Not supported: creating an interface from within CreateEndpoint")
	}
	driver.Lock()
	driver.endpoints[endID] = struct{}{}
	driver.Unlock()
	resp := &api.CreateEndpointResponse{}

	driver.logRes("CreateEndpoint", resp)
	return resp, nil
}

func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
	driver.logReq("DeleteEndpoint", deleteReq, deleteReq.EndpointID)
	driver.Lock()
	delete(driver.endpoints, deleteReq.EndpointID)
	driver.Unlock()
	return nil
}

func (driver *driver) HasEndpoint(endpointID string) bool {
	driver.Lock()
	_, found := driver.endpoints[endpointID]
	driver.Unlock()
	return found
}

func (driver *driver) EndpointInfo(req *api.EndpointInfoRequest) (*api.EndpointInfoResponse, error) {
	driver.logReq("EndpointInfo", req, req.EndpointID)
	return &api.EndpointInfoResponse{Value: map[string]interface{}{}}, nil
}

func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error) {
	driver.logReq("JoinEndpoint", j, fmt.Sprintf("%s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey))

	name, peerName := vethPair(j.EndpointID)
	local, err := weavenet.CreateAndAttachVeth(name, peerName, WeaveBridge, 0)
	if err != nil {
		return nil, driver.error("JoinEndpoint", "%s", err)
	}

	ifname := &api.InterfaceName{
		SrcName:   local.PeerName,
		DstPrefix: "ethwe",
	}

	response := &api.JoinResponse{
		InterfaceName: ifname,
	}
	if !driver.noMulticastRoute {
		multicastRoute := api.StaticRoute{
			Destination: "224.0.0.0/4",
			RouteType:   types.CONNECTED,
		}
		response.StaticRoutes = append(response.StaticRoutes, multicastRoute)
	}
	driver.logRes("JoinEndpoint", response)
	return response, nil
}

func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error {
	driver.logReq("LeaveEndpoint", leave, fmt.Sprintf("%s:%s", leave.NetworkID, leave.EndpointID))

	name, _ := vethPair(leave.EndpointID)
	local := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
	if err := netlink.LinkDel(local); err != nil {
		driver.warn("LeaveEndpoint", "unable to delete veth: %s", err)
	}
	return nil
}

func (driver *driver) DiscoverNew(disco *api.DiscoveryNotification) error {
	driver.logReq("DiscoverNew", disco, "")
	return nil
}

func (driver *driver) DiscoverDelete(disco *api.DiscoveryNotification) error {
	driver.logReq("DiscoverDelete", disco, "")
	return nil
}

func vethPair(id string) (string, string) {
	return "vethwl" + id[:5], "vethwg" + id[:5]
}

// logging

func (driver *driver) logReq(fun string, req interface{}, short string) {
	driver.log(common.Log.Debugf, " %+v", fun, req)
	common.Log.Infof("[net] %s %s", fun, short)
}

func (driver *driver) logRes(fun string, res interface{}) {
	driver.log(common.Log.Debugf, " %+v", fun, res)
}

func (driver *driver) warn(fun string, format string, a ...interface{}) {
	driver.log(common.Log.Warnf, ": "+format, fun, a...)
}

func (driver *driver) debug(fun string, format string, a ...interface{}) {
	driver.log(common.Log.Debugf, ": "+format, fun, a...)
}

func (driver *driver) error(fun string, format string, a ...interface{}) error {
	driver.log(common.Log.Errorf, ": "+format, fun, a...)
	return fmt.Errorf(format, a...)
}

func (driver *driver) log(f func(string, ...interface{}), format string, fun string, a ...interface{}) {
	f("[net] %s"+format, append([]interface{}{fun}, a...)...)
}
<commit_msg>Slight cleanup<commit_after>package plugin

import (
	"fmt"
	"sync"

	"github.com/docker/libnetwork/drivers/remote/api"
	"github.com/docker/libnetwork/types"

	"github.com/vishvananda/netlink"
	weaveapi "github.com/weaveworks/weave/api"
	"github.com/weaveworks/weave/common"
	"github.com/weaveworks/weave/common/docker"
	weavenet "github.com/weaveworks/weave/net"
	"github.com/weaveworks/weave/plugin/skel"
)

const (
	WeaveBridge = "weave"
)

type driver struct {
	scope            string
	noMulticastRoute bool
	sync.RWMutex
	endpoints map[string]struct{}
}

func New(client *docker.Client, weave *weaveapi.Client, scope string, noMulticastRoute bool) (skel.Driver, error) {
	driver := &driver{
		noMulticastRoute: noMulticastRoute,
		scope:            scope,
		endpoints:        make(map[string]struct{}),
	}

	_, err := NewWatcher(client, weave, driver)
	if err != nil {
		return nil, err
	}
	return driver, nil
}

// === protocol handlers

func (driver *driver) GetCapabilities() (*api.GetCapabilityResponse, error) {
	driver.logReq("GetCapabilities", nil, "")
	var caps = &api.GetCapabilityResponse{
		Scope: driver.scope,
	}
	driver.logRes("GetCapabilities", caps)
	return caps, nil
}

func (driver *driver) CreateNetwork(create *api.CreateNetworkRequest) error {
	driver.logReq("CreateNetwork", create, create.NetworkID)
	return nil
}

func (driver *driver) DeleteNetwork(delete *api.DeleteNetworkRequest) error {
	driver.logReq("DeleteNetwork", delete, delete.NetworkID)
	return nil
}

func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.CreateEndpointResponse, error) {
	driver.logReq("CreateEndpoint", create, create.EndpointID)
	endID := create.EndpointID

	if create.Interface == nil {
		return nil, driver.error("CreateEndpoint", "Not supported: creating an interface from within CreateEndpoint")
	}
	driver.Lock()
	driver.endpoints[endID] = struct{}{}
	driver.Unlock()
	resp := &api.CreateEndpointResponse{}

	driver.logRes("CreateEndpoint", resp)
	return resp, nil
}

func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
	driver.logReq("DeleteEndpoint", deleteReq, deleteReq.EndpointID)
	driver.Lock()
	delete(driver.endpoints, deleteReq.EndpointID)
	driver.Unlock()
	return nil
}

func (driver *driver) HasEndpoint(endpointID string) bool {
	driver.Lock()
	_, found := driver.endpoints[endpointID]
	driver.Unlock()
	return found
}

func (driver *driver) EndpointInfo(req *api.EndpointInfoRequest) (*api.EndpointInfoResponse, error) {
	driver.logReq("EndpointInfo", req, req.EndpointID)
	return &api.EndpointInfoResponse{Value: map[string]interface{}{}}, nil
}

func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error) {
	driver.logReq("JoinEndpoint", j, fmt.Sprintf("%s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey))

	name, peerName := vethPair(j.EndpointID)
	if _, err := weavenet.CreateAndAttachVeth(name, peerName, WeaveBridge, 0); err != nil {
		return nil, driver.error("JoinEndpoint", "%s", err)
	}

	response := &api.JoinResponse{
		InterfaceName: &api.InterfaceName{
			SrcName:   peerName,
			DstPrefix: "ethwe",
		},
	}
	if !driver.noMulticastRoute {
		multicastRoute := api.StaticRoute{
			Destination: "224.0.0.0/4",
			RouteType:   types.CONNECTED,
		}
		response.StaticRoutes = append(response.StaticRoutes, multicastRoute)
	}
	driver.logRes("JoinEndpoint", response)
	return response, nil
}

func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error {
	driver.logReq("LeaveEndpoint", leave, fmt.Sprintf("%s:%s", leave.NetworkID, leave.EndpointID))

	name, _ := vethPair(leave.EndpointID)
	local := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
	if err := netlink.LinkDel(local); err != nil {
		driver.warn("LeaveEndpoint", "unable to delete veth: %s", err)
	}
	return nil
}

func (driver *driver) DiscoverNew(disco *api.DiscoveryNotification) error {
	driver.logReq("DiscoverNew", disco, "")
	return nil
}

func (driver *driver) DiscoverDelete(disco *api.DiscoveryNotification) error {
	driver.logReq("DiscoverDelete", disco, "")
	return nil
}

func vethPair(id string) (string, string) {
	return "vethwl" + id[:5], "vethwg" + id[:5]
}

// logging

func (driver *driver) logReq(fun string, req interface{}, short string) {
	driver.log(common.Log.Debugf, " %+v", fun, req)
	common.Log.Infof("[net] %s %s", fun, short)
}

func (driver *driver) logRes(fun string, res interface{}) {
	driver.log(common.Log.Debugf, " %+v", fun, res)
}

func (driver *driver) warn(fun string, format string, a ...interface{}) {
	driver.log(common.Log.Warnf, ": "+format, fun, a...)
}

func (driver *driver) debug(fun string, format string, a ...interface{}) {
	driver.log(common.Log.Debugf, ": "+format, fun, a...)
}

func (driver *driver) error(fun string, format string, a ...interface{}) error {
	driver.log(common.Log.Errorf, ": "+format, fun, a...)
	return fmt.Errorf(format, a...)
}

func (driver *driver) log(f func(string, ...interface{}), format string, fun string, a ...interface{}) {
	f("[net] %s"+format, append([]interface{}{fun}, a...)...)
}
<|endoftext|>


<commit_before>package socket

import (
    "time"
    "net/http"
    "github.com/gorilla/websocket"
    "app/hub"
    "app/message"
)

var upgrader = websocket.Upgrader{}

// Handler handles websocket connections at /ws
func Handler(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
        panic(err)
	}
	defer c.Close()

    // each socket connection has a 'received' channel
    received := make(chan message.SocketMessage)

    // all messages pushed to the 'received' channel
    // are written out to the socket
    go writeSocket(c, received)

    // read incoming messages from the socket
    for {
        m := message.SocketMessage{}
        m.CreatedAt = time.Now().UTC()

		err := c.ReadJSON(&m)
		if err != nil {
			panic(err)
		}

        if m.Action == "publish" {
            hub.Published <- m
        }

        if m.Action == "subscribe" {
            hub.Subscribed[m.Event] = append(hub.Subscribed[m.Event], received)
        }
	}

}
<commit_msg>Ignore messages that aren't JSON<commit_after>package socket

import (
    "time"
    "net/http"
    "github.com/gorilla/websocket"
    "app/hub"
    "app/message"
)

var upgrader = websocket.Upgrader{}

// Handler handles websocket connections at /ws
func Handler(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
        panic(err)
	}
	defer c.Close()

    // each socket connection has a 'received' channel
    received := make(chan message.SocketMessage)

    // all messages pushed to the 'received' channel
    // are written out to the socket
    go writeSocket(c, received)

    // read incoming messages from the socket
    for {
        m := message.SocketMessage{}
        m.CreatedAt = time.Now().UTC()

		_ = c.ReadJSON(&m)

        if m.Action == "publish" {
            hub.Published <- m
        }

        if m.Action == "subscribe" {
            hub.Subscribed[m.Event] = append(hub.Subscribed[m.Event], received)
        }
	}

}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"io/ioutil"
	"qaz/bucket"
	stks "qaz/stacks"
	"qaz/utils"
	"strings"
	"text/template"

	"encoding/base64"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/kms"
)

// Common Functions - Both Deploy/Gen

var kmsEncrypt = func(kid string, text string) (string, error) {
	sess, err := manager.GetSess(run.profile)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	svc := kms.New(sess)

	params := &kms.EncryptInput{
		KeyId:     aws.String(kid),
		Plaintext: []byte(text),
	}

	resp, err := svc.Encrypt(params)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	return base64.StdEncoding.EncodeToString(resp.CiphertextBlob), nil
}

var kmsDecrypt = func(cipher string) (string, error) {
	sess, err := manager.GetSess(run.profile)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	svc := kms.New(sess)

	ciph, err := base64.StdEncoding.DecodeString(cipher)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	params := &kms.DecryptInput{
		CiphertextBlob: []byte(ciph),
	}

	resp, err := svc.Decrypt(params)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	return string(resp.Plaintext), nil
}

var httpGet = func(url string) (interface{}, error) {
	log.Debug(fmt.Sprintln("Calling Template Function [GET] with arguments:", url))
	resp, err := utils.Get(url)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	return resp, nil
}

var s3Read = func(url string, profile ...string) (string, error) {
	log.Debug(fmt.Sprintln("Calling Template Function [S3Read] with arguments:", url))

	var p = run.profile
	if len(profile) < 1 {
		log.Warn(fmt.Sprintf("No Profile specified for S3read, using: %s", p))
	} else {
		p = profile[0]
	}

	sess, err := manager.GetSess(p)
	utils.HandleError(err)

	resp, err := bucket.S3Read(url, sess)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}
	return resp, nil
}

var lambdaInvoke = func(name string, payload string) (interface{}, error) {
	f := awsLambda{name: name}
	if payload != "" {
		f.payload = []byte(payload)
	}

	sess, err := manager.GetSess(run.profile)
	if err != nil {
		log.Error(err.Error())
		return "", err
	}

	if err := f.Invoke(sess); err != nil {
		log.Error(err.Error())
		return "", err
	}

	return f.response, nil
}

var prefix = func(s string, pre string) bool {
	return strings.HasPrefix(s, pre)
}

var suffix = func(s string, suf string) bool {
	return strings.HasSuffix(s, suf)
}

var contains = func(s string, con string) bool {
	return strings.Contains(s, con)
}

// template function maps

var genTimeFunctions = template.FuncMap{
	// simple additon function useful for counters in loops
	"add": func(a int, b int) int {
		log.Debug(fmt.Sprintln("Calling Template Function [add] with arguments:", a, b))
		return a + b
	},

	// strip function for removing characters from text
	"strip": func(s string, rmv string) string {
		log.Debug(fmt.Sprintln("Calling Template Function [strip] with arguments:", s, rmv))
		return strings.Replace(s, rmv, "", -1)
	},

	// cat function for reading text from a given file under the files folder
	"cat": func(path string) (string, error) {

		log.Debug(fmt.Sprintln("Calling Template Function [cat] with arguments:", path))
		b, err := ioutil.ReadFile(path)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}
		return string(b), nil
	},

	// suffix - returns true if string starts with given suffix
	"suffix": suffix,

	// prefix - returns true if string starts with given prefix
	"prefix": prefix,

	// contains - returns true if string contains
	"contains": contains,

	// Get get does an HTTP Get request of the given url and returns the output string
	"GET": httpGet,

	// S3Read reads content of file from s3 and returns string contents
	"s3_read": s3Read,

	// invoke - invokes a lambda function
	"invoke": lambdaInvoke,

	// kms-encrypt - Encrypts PlainText using KMS key
	"kms_encrypt": kmsEncrypt,

	// kms-decrypt - Descrypts CipherText
	"kms_decrypt": kmsDecrypt,
}

var deployTimeFunctions = template.FuncMap{
	// Fetching stackoutputs
	"stack_output": func(target string) (string, error) {
		log.Debug(fmt.Sprintf("Deploy-Time function resolving: %s", target))
		req := strings.Split(target, "::")

		s := stacks[req[0]]

		if err := s.Outputs(); err != nil {
			return "", err
		}

		for _, i := range s.Output.Stacks {
			for _, o := range i.Outputs {
				if *o.OutputKey == req[1] {
					return *o.OutputValue, nil
				}
			}
		}

		return "", fmt.Errorf("Stack Output Not found - Stack:%s | Output:%s", req[0], req[1])
	},

	"stack_output_ext": func(target string) (string, error) {
		log.Debug(fmt.Sprintf("Deploy-Time function resolving: %s", target))
		req := strings.Split(target, "::")

		sess, err := manager.GetSess(run.profile)
		if err != nil {
			log.Error(err.Error())
			return "", nil
		}

		s := stks.Stack{
			Stackname: req[0],
			Session:   sess,
		}

		if err := s.Outputs(); err != nil {
			return "", err
		}

		for _, i := range s.Output.Stacks {
			for _, o := range i.Outputs {
				if *o.OutputKey == req[1] {
					return *o.OutputValue, nil
				}
			}
		}

		return "", fmt.Errorf("Stack Output Not found - Stack:%s | Output:%s", req[0], req[1])
	},

	// suffix - returns true if string starts with given suffix
	"suffix": suffix,

	// prefix - returns true if string starts with given prefix
	"prefix": prefix,

	// contains - returns true if string contains
	"contains": contains,

	// Get get does an HTTP Get request of the given url and returns the output string
	"GET": httpGet,

	// S3Read reads content of file from s3 and returns string contents
	"s3_read": s3Read,

	// invoke - invokes a lambda function
	"invoke": lambdaInvoke,

	// kms-encrypt - Encrypts PlainText using KMS key
	"kms_encrypt": kmsEncrypt,

	// kms-decrypt - Descrypts CipherText
	"kms_decrypt": kmsDecrypt,
}
<commit_msg>re-added loop function as defined by @jaffee, added invokes function for lambda resp map[string]interface, re-structured functions.go<commit_after>package commands

import (
	"fmt"
	"io/ioutil"
	"qaz/bucket"
	stks "qaz/stacks"
	"qaz/utils"
	"strings"
	"text/template"

	"encoding/base64"
	"encoding/json"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/kms"
)

// Common Functions - Both Deploy/Gen
var (
	kmsEncrypt = func(kid string, text string) (string, error) {
		sess, err := manager.GetSess(run.profile)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		svc := kms.New(sess)

		params := &kms.EncryptInput{
			KeyId:     aws.String(kid),
			Plaintext: []byte(text),
		}

		resp, err := svc.Encrypt(params)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		return base64.StdEncoding.EncodeToString(resp.CiphertextBlob), nil
	}

	kmsDecrypt = func(cipher string) (string, error) {
		sess, err := manager.GetSess(run.profile)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		svc := kms.New(sess)

		ciph, err := base64.StdEncoding.DecodeString(cipher)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		params := &kms.DecryptInput{
			CiphertextBlob: []byte(ciph),
		}

		resp, err := svc.Decrypt(params)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		return string(resp.Plaintext), nil
	}

	httpGet = func(url string) (interface{}, error) {
		log.Debug(fmt.Sprintln("Calling Template Function [GET] with arguments:", url))
		resp, err := utils.Get(url)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		return resp, nil
	}

	s3Read = func(url string, profile ...string) (string, error) {
		log.Debug(fmt.Sprintln("Calling Template Function [S3Read] with arguments:", url))

		var p = run.profile
		if len(profile) < 1 {
			log.Warn(fmt.Sprintf("No Profile specified for S3read, using: %s", p))
		} else {
			p = profile[0]
		}

		sess, err := manager.GetSess(p)
		utils.HandleError(err)

		resp, err := bucket.S3Read(url, sess)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}
		return resp, nil
	}

	lambdaInvoke = func(name string, payload string) (interface{}, error) {
		f := awsLambda{name: name}
		if payload != "" {
			f.payload = []byte(payload)
		}

		sess, err := manager.GetSess(run.profile)
		if err != nil {
			log.Error(err.Error())
			return "", err
		}

		if err := f.Invoke(sess); err != nil {
			log.Error(err.Error())
			return "", err
		}

		return f.response, nil
	}

	lambdaMap = func(name string, payload string) (map[string]interface{}, error) {
		f := awsLambda{name: name}
		m := make(map[string]interface{})

		if payload != "" {
			f.payload = []byte(payload)
		}

		sess, err := manager.GetSess(run.profile)
		if err != nil {
			log.Error(err.Error())
			return m, err
		}

		if err := f.Invoke(sess); err != nil {
			log.Error(err.Error())
			return m, err
		}

		if err := json.Unmarshal([]byte(f.response), &m); err != nil {
			log.Error(err.Error())
			return m, err
		}

		return m, nil
	}

	prefix = func(s string, pre string) bool {
		return strings.HasPrefix(s, pre)
	}

	suffix = func(s string, suf string) bool {
		return strings.HasSuffix(s, suf)
	}

	contains = func(s string, con string) bool {
		return strings.Contains(s, con)
	}

	loop = func(n int) []struct{} {
		return make([]struct{}, n)
	}

	// gentime function maps
	genTimeFunctions = template.FuncMap{
		// simple additon function useful for counters in loops
		"add": func(a int, b int) int {
			log.Debug(fmt.Sprintln("Calling Template Function [add] with arguments:", a, b))
			return a + b
		},

		// strip function for removing characters from text
		"strip": func(s string, rmv string) string {
			log.Debug(fmt.Sprintln("Calling Template Function [strip] with arguments:", s, rmv))
			return strings.Replace(s, rmv, "", -1)
		},

		// cat function for reading text from a given file under the files folder
		"cat": func(path string) (string, error) {

			log.Debug(fmt.Sprintln("Calling Template Function [cat] with arguments:", path))
			b, err := ioutil.ReadFile(path)
			if err != nil {
				log.Error(err.Error())
				return "", err
			}
			return string(b), nil
		},

		// suffix - returns true if string starts with given suffix
		"suffix": suffix,

		// prefix - returns true if string starts with given prefix
		"prefix": prefix,

		// contains - returns true if string contains
		"contains": contains,

		// loop - useful to range over an int (rather than a slice, map, or channel). see examples/loop
		"loop": loop,

		// Get get does an HTTP Get request of the given url and returns the output string
		"GET": httpGet,

		// S3Read reads content of file from s3 and returns string contents
		"s3_read": s3Read,

		// invoke - invokes a lambda function and returns a raw string/interface{}
		"invoke": lambdaInvoke,

		// invokes - invokes a lambda function and returns a map[string]object
		"invokes": lambdaMap,

		// kms-encrypt - Encrypts PlainText using KMS key
		"kms_encrypt": kmsEncrypt,

		// kms-decrypt - Descrypts CipherText
		"kms_decrypt": kmsDecrypt,
	}

	// deploytime function maps
	deployTimeFunctions = template.FuncMap{
		// Fetching stackoutputs
		"stack_output": func(target string) (string, error) {
			log.Debug(fmt.Sprintf("Deploy-Time function resolving: %s", target))
			req := strings.Split(target, "::")

			s := stacks[req[0]]

			if err := s.Outputs(); err != nil {
				return "", err
			}

			for _, i := range s.Output.Stacks {
				for _, o := range i.Outputs {
					if *o.OutputKey == req[1] {
						return *o.OutputValue, nil
					}
				}
			}

			return "", fmt.Errorf("Stack Output Not found - Stack:%s | Output:%s", req[0], req[1])
		},

		"stack_output_ext": func(target string) (string, error) {
			log.Debug(fmt.Sprintf("Deploy-Time function resolving: %s", target))
			req := strings.Split(target, "::")

			sess, err := manager.GetSess(run.profile)
			if err != nil {
				log.Error(err.Error())
				return "", nil
			}

			s := stks.Stack{
				Stackname: req[0],
				Session:   sess,
			}

			if err := s.Outputs(); err != nil {
				return "", err
			}

			for _, i := range s.Output.Stacks {
				for _, o := range i.Outputs {
					if *o.OutputKey == req[1] {
						return *o.OutputValue, nil
					}
				}
			}

			return "", fmt.Errorf("Stack Output Not found - Stack:%s | Output:%s", req[0], req[1])
		},

		// suffix - returns true if string starts with given suffix
		"suffix": suffix,

		// prefix - returns true if string starts with given prefix
		"prefix": prefix,

		// contains - returns true if string contains
		"contains": contains,

		// loop - useful to range over an int (rather than a slice, map, or channel). see examples/loop
		"loop": loop,

		// Get get does an HTTP Get request of the given url and returns the output string
		"GET": httpGet,

		// S3Read reads content of file from s3 and returns string contents
		"s3_read": s3Read,

		// invoke - invokes a lambda function and returns a raw string/interface{}
		"invoke": lambdaInvoke,

		// invokes - invokes a lambda function and returns a map[string]object
		"invokes": lambdaMap,

		// kms-encrypt - Encrypts PlainText using KMS key
		"kms_encrypt": kmsEncrypt,

		// kms-decrypt - Descrypts CipherText
		"kms_decrypt": kmsDecrypt,
	}
)
<|endoftext|>


<commit_before>package functional

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

	"github.com/coreos/fleet/functional/platform"
)

func TestKnownHostsVerification(t *testing.T) {
	cluster, err := platform.NewNspawnCluster("smoke")
	if err != nil {
		t.Fatalf(err.Error())
	}
	defer cluster.DestroyAll()

	if err := cluster.CreateMultiple(1, platform.MachineConfig{}); err != nil {
		t.Fatalf(err.Error())
	}
	machines, err := waitForNMachines(1)
	if err != nil {
		t.Fatalf(err.Error())
	}
	machine := machines[0]

	tmp, err := ioutil.TempFile(os.TempDir(), "known-hosts")
	if err != nil {
		t.Fatalf(err.Error())
	}
	tmp.Close()
	defer syscall.Unlink(tmp.Name())

	khFile := tmp.Name()

	if _, _, err := fleetctlWithInput("yes", "--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err != nil {
		t.Errorf("Unable to SSH into fleet machine: %v", err)
	}

	// Recreation of the cluster simulates a change in the server's host key
	cluster.DestroyAll()
	cluster.CreateMultiple(1, platform.MachineConfig{})
	machines, err = waitForNMachines(1)
	if err != nil {
		t.Fatalf(err.Error())
	}
	machine = machines[0]

	// SSH'ing to the cluster member should now fail with a host key mismatch
	if _, _, err := fleetctl("--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err == nil {
		t.Errorf("Expected error while SSH'ing to fleet machine")
	}

	// Overwrite the known-hosts file to simulate removing the old host key
	if err := ioutil.WriteFile(khFile, []byte{}, os.FileMode(0644)); err != nil {
		t.Fatalf("Unable to overwrite known-hosts file: %v", err)
	}

	// And SSH should work again
	if _, _, err := fleetctlWithInput("yes", "--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err != nil {
		t.Errorf("Unable to SSH into fleet machine: %v", err)
	}

}
<commit_msg>test(functional): test fleetctl ssh/journal/status<commit_after>package functional

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"syscall"
	"testing"

	"github.com/coreos/fleet/functional/platform"
)

func TestKnownHostsVerification(t *testing.T) {
	cluster, err := platform.NewNspawnCluster("smoke")
	if err != nil {
		t.Fatalf(err.Error())
	}
	defer cluster.DestroyAll()

	if err := cluster.CreateMultiple(1, platform.MachineConfig{}); err != nil {
		t.Fatalf(err.Error())
	}
	machines, err := waitForNMachines(1)
	if err != nil {
		t.Fatalf(err.Error())
	}
	machine := machines[0]

	tmp, err := ioutil.TempFile(os.TempDir(), "known-hosts")
	if err != nil {
		t.Fatalf(err.Error())
	}
	tmp.Close()
	defer syscall.Unlink(tmp.Name())

	khFile := tmp.Name()

	if _, _, err := fleetctlWithInput("yes", "--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err != nil {
		t.Errorf("Unable to SSH into fleet machine: %v", err)
	}

	// Recreation of the cluster simulates a change in the server's host key
	cluster.DestroyAll()
	cluster.CreateMultiple(1, platform.MachineConfig{})
	machines, err = waitForNMachines(1)
	if err != nil {
		t.Fatalf(err.Error())
	}
	machine = machines[0]

	// SSH'ing to the cluster member should now fail with a host key mismatch
	if _, _, err := fleetctl("--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err == nil {
		t.Errorf("Expected error while SSH'ing to fleet machine")
	}

	// Overwrite the known-hosts file to simulate removing the old host key
	if err := ioutil.WriteFile(khFile, []byte{}, os.FileMode(0644)); err != nil {
		t.Fatalf("Unable to overwrite known-hosts file: %v", err)
	}

	// And SSH should work again
	if _, _, err := fleetctlWithInput("yes", "--strict-host-key-checking=true", fmt.Sprintf("--known-hosts-file=%s", khFile), "ssh", machine, "uptime"); err != nil {
		t.Errorf("Unable to SSH into fleet machine: %v", err)
	}

}

func TestSSHActions(t *testing.T) {
	cluster, err := platform.NewNspawnCluster("smoke")
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.DestroyAll()

	if err := cluster.CreateMultiple(1, platform.MachineConfig{}); err != nil {
		t.Fatal(err)
	}
	_, err = waitForNMachines(1)
	if err != nil {
		t.Fatal(err)
	}

	if _, _, err := fleetctl("start", "--no-block", "fixtures/units/hello.service"); err != nil {
		t.Fatalf("Unable to start fleet unit: %v", err)
	}

	units, err := waitForNActiveUnits(1)
	if err != nil {
		t.Fatal(err)
	}

	if len(units) != 1 || units[0] != "hello.service" {
		t.Fatalf("Expected hello.service to be sole active unit, got %v", units)
	}

	stdout, _, err := fleetctl("--strict-host-key-checking=false", "ssh", "hello.service", "echo", "foo")
	if err != nil {
		t.Errorf("Failure occurred while calling fleetctl ssh: %v", err)
	}

	if !strings.Contains(stdout, "foo") {
		t.Errorf("Could not find expected string in command output:\n%s", stdout)
	}

	stdout, _, err = fleetctl("--strict-host-key-checking=false", "status", "hello.service")
	if err != nil {
		t.Errorf("Failure occurred while calling fleetctl status: %v", err)
	}

	if !strings.Contains(stdout, "Active: active") {
		t.Errorf("Could not find expected string in status output:\n%s", stdout)
	}

	stdout, _, err = fleetctl("--strict-host-key-checking=false", "journal", "hello.service")
	if err != nil {
		t.Errorf("Failure occurred while calling fleetctl journal: %v", err)
	}

	if !strings.Contains(stdout, "Hello, World!") {
		t.Errorf("Could not find expected string in journal output:\n%s", stdout)
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"os"
	"testing"

	"github.com/hashicorp/consul/testutil"
)

var consulTestAddr string

func TestMain(m *testing.M) {
	// create a test Consul server
	consulTestServer, err := testutil.NewTestServerConfig(func(c *testutil.TestServerConfig) {
		c.Connect = nil
	})

	if err != nil {
		panic(err)
	}

	consulTestAddr = consulTestServer.HTTPAddr

	exitCode := m.Run()
	consulTestServer.Stop()

	os.Exit(exitCode)
}
<commit_msg>Discard consul test server output by default<commit_after>package commands

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

	"github.com/hashicorp/consul/testutil"
)

var consulTestAddr string

func TestMain(m *testing.M) {
	var consulServerOutputEnabled bool
	flag.BoolVar(&consulServerOutputEnabled, "enable-consul-output", false, "Enables consul server output")

	flag.Parse()
	// create a test Consul server
	consulTestServer, err := testutil.NewTestServerConfig(func(c *testutil.TestServerConfig) {
		c.Connect = nil
		if !consulServerOutputEnabled {
			c.Stderr = ioutil.Discard
			c.Stdout = ioutil.Discard
		}
	})

	if err != nil {
		panic(err)
	}

	consulTestAddr = consulTestServer.HTTPAddr

	exitCode := m.Run()
	consulTestServer.Stop()

	os.Exit(exitCode)
}
<|endoftext|>


<commit_before>package main

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

type response struct {
	UserID    int    `json:"userId"`
	ID        int    `json:"id"`
	Title     string `json:"title"`
	Completed bool   `json:"completed"`
}

func getHTTPResponse() (*response, error) {
	resp, err := http.Get("https://jsonplaceholder.typicode.com/todos/1")

	if err != nil {
		return nil, fmt.Errorf("error in http call")
	}

	defer resp.Body.Close()
	byteResp, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, fmt.Errorf("error in reading response")
	}

	structResp := &Response{}
	err = json.Unmarshal(byteResp, structResp)

	if err != nil {
		return nil, fmt.Errorf("error in unmarshalling response")
	}

	return structResp, nil
}

func main() {

	res, err := getHTTPResponse()

	if err != nil {
		fmt.Printf("err %v", err)
	} else {
		fmt.Printf("res %v", res)
	}
}
<commit_msg>fix: response<commit_after>package main

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

type response struct {
	UserID    int    `json:"userId"`
	ID        int    `json:"id"`
	Title     string `json:"title"`
	Completed bool   `json:"completed"`
}

func getHTTPResponse() (*response, error) {
	resp, err := http.Get("https://jsonplaceholder.typicode.com/todos/1")

	if err != nil {
		return nil, fmt.Errorf("error in http call")
	}

	defer resp.Body.Close()
	byteResp, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, fmt.Errorf("error in reading response")
	}

	structResp := &response{}
	err = json.Unmarshal(byteResp, structResp)

	if err != nil {
		return nil, fmt.Errorf("error in unmarshalling response")
	}

	return structResp, nil
}

func main() {

	res, err := getHTTPResponse()

	if err != nil {
		fmt.Printf("err %v", err)
	} else {
		fmt.Printf("res %v", res)
	}
}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"log"
	"time"
)

const (
	// Default time format
	TIMEFORMAT = "2006-01-02 15:04:05 MST"

	// Default time format
	TIMEFORMAT_NO_TZ = "2006-01-02 15:04:05"

	// Time format used by the Google Drive api
	DRIVE_TIMEFORMAT = "2006-01-02T15:04:05.000Z"
	// Default timezone
	TIMEZONE = "PST"
	// Timezone for Dexcom interval time values
	INTERNAL_TIMEZONE = "GMT"
)

// Beginning of time should be unix epoch 0 but, to optimize some processing
// may iterate overtime starting at this value, we just define the notion
// of Glukit epoch time and have this value be set to something less far back
// but still before anything interesting happened in the Glukit world.
// This maps to 01 Jan 2004 00:00:00 GMT.
var GLUKIT_EPOCH_TIME = time.Unix(1072915200, 0)

// ParseGoogleDriveDate parses a Google Drive API time value
func ParseGoogleDriveDate(value string) (timeValue time.Time, err error) {
	return time.Parse(DRIVE_TIMEFORMAT, value)
}

// GetTimeInSeconds parses a datetime string and returns its unix timestamp.
func GetTimeInSeconds(timeValue string) (value int64) {
	// time values without timezone info are interpreted as UTC, which is perfect
	if timeValue, err := time.Parse(TIMEFORMAT_NO_TZ, timeValue); err == nil {
		return timeValue.Unix()
	} else {
		log.Printf("Error parsing string", err)
	}
	return 0
}

// GetEndOfDayBoundaryBefore returns the boundary of very last "end of day" before the given time.
// To give an example, if the given time is July 17th 8h00 PST, the boundary returned is going to be
// July 17th 06h00. If the time is July 17th 05h00 PST, the boundary returned is July 16th 06h00.
// Very important: The timeValue's location must be accurate!
func GetEndOfDayBoundaryBefore(timeValue time.Time) (latestEndOfDayBoundary time.Time) {
	if timeValue.Hour() < 6 {
		// Rewind by one more day
		previousDay := timeValue.Add(time.Duration(-24 * time.Hour))
		latestEndOfDayBoundary = time.Date(previousDay.Year(), previousDay.Month(), previousDay.Day(), 6, 0, 0, 0, timeValue.Location())
	} else {
		latestEndOfDayBoundary = time.Date(timeValue.Year(), timeValue.Month(), timeValue.Day(), 6, 0, 0, 0, timeValue.Location())
	}

	return latestEndOfDayBoundary
}

// GetMidnightUTCBefore returns the boundary of very last occurence of midnight before the given time.
// To give an example, if the given time is July 17th 2h00 UTC, the boundary returned is going to be
// July 17th 00h00. If the time is July 16th 23h00 PST, the boundary returned is July 16th 00h00.
func GetMidnightUTCBefore(timeValue time.Time) (latestMidnightBoundary time.Time) {
	timeInUTC := timeValue.UTC()
	latestMidnightBoundary = time.Date(timeInUTC.Year(), timeInUTC.Month(), timeInUTC.Day(), 0, 0, 0, 0, time.UTC)
	return latestMidnightBoundary
}

// Returns the timevalue with its timezone set to the default TIMEZONE_LOCATION
// func TimeWithDefaultTimezone(timevalue time.Time) (localTime string) {
// 	return timevalue.In(TIMEZONE_LOCATION).Format(TIMEFORMAT)
// }

// Returns the timevalue with its timezone set to the default TIMEZONE_LOCATION but without
// printing the timezone in the formatted string
// func TimeInDefaultTimezoneNoTz(timevalue time.Time) (localTime string) {
// 	return timevalue.In(TIMEZONE_LOCATION).Format(TIMEFORMAT_NO_TZ)
// }

// Returns the timevalue with its timezone set to UTC but without
// printing the timezone in the formatted string
func TimeInUTCNoTz(timevalue time.Time) (localTime string) {
	return timevalue.UTC().Format(TIMEFORMAT_NO_TZ)
}

// GetLocaltimeOffset returns the Fixed location extrapolated by calculating the offset
// of the localtime and the internal time in UTC
func GetLocaltimeOffset(localTime string, internalTime time.Time) (location *time.Location) {
	// Get the local time as if it was UTC (it's not)
	localTimeUTC, _ := time.Parse(TIMEFORMAT_NO_TZ, localTime)

	// Get the difference between the internal time (actual UTC) and the local time
	durationOffset := localTimeUTC.Sub(internalTime)

	locationName := fmt.Sprintf("%+03d%02d", int64(durationOffset.Hours()), (int64(durationOffset)-int64(durationOffset.Hours())*int64(time.Hour))/int64(time.Minute))
	return time.FixedZone(locationName, int(durationOffset.Seconds()))
}

// GetLocalTimeInProperLocation returns the parsed local time with the location appropriately set as extrapolated
// by calculating the difference of the internal time vs the local time
func GetLocalTimeInProperLocation(localTime string, internalTime time.Time) (localTimeWithLocation time.Time) {
	location := GetLocaltimeOffset(localTime, internalTime)
	localTimeWithLocation, _ = time.ParseInLocation(TIMEFORMAT_NO_TZ, localTime, location)
	return
}
<commit_msg>Make Days End at 18h00 rather than 06h00.<commit_after>package util

import (
	"fmt"
	"log"
	"time"
)

const (
	// Default time format
	TIMEFORMAT = "2006-01-02 15:04:05 MST"

	// Default time format
	TIMEFORMAT_NO_TZ = "2006-01-02 15:04:05"

	// Time format used by the Google Drive api
	DRIVE_TIMEFORMAT = "2006-01-02T15:04:05.000Z"
	// Default timezone
	TIMEZONE = "PST"
	// Timezone for Dexcom interval time values
	INTERNAL_TIMEZONE = "GMT"

	// Let's make days end at 18h00
	HOUR_OF_END_OF_DAY = 18
)

// Beginning of time should be unix epoch 0 but, to optimize some processing
// may iterate overtime starting at this value, we just define the notion
// of Glukit epoch time and have this value be set to something less far back
// but still before anything interesting happened in the Glukit world.
// This maps to 01 Jan 2004 00:00:00 GMT.
var GLUKIT_EPOCH_TIME = time.Unix(1072915200, 0)

// ParseGoogleDriveDate parses a Google Drive API time value
func ParseGoogleDriveDate(value string) (timeValue time.Time, err error) {
	return time.Parse(DRIVE_TIMEFORMAT, value)
}

// GetTimeInSeconds parses a datetime string and returns its unix timestamp.
func GetTimeInSeconds(timeValue string) (value int64) {
	// time values without timezone info are interpreted as UTC, which is perfect
	if timeValue, err := time.Parse(TIMEFORMAT_NO_TZ, timeValue); err == nil {
		return timeValue.Unix()
	} else {
		log.Printf("Error parsing string", err)
	}
	return 0
}

// GetEndOfDayBoundaryBefore returns the boundary of very last "end of day" before the given time.
// To give an example, if the given time is July 17th 8h00 PST, the boundary returned is going to be
// July 17th 06h00. If the time is July 17th 05h00 PST, the boundary returned is July 16th 06h00.
// Very important: The timeValue's location must be accurate!
func GetEndOfDayBoundaryBefore(timeValue time.Time) (latestEndOfDayBoundary time.Time) {
	if timeValue.Hour() < HOUR_OF_END_OF_DAY {
		// Rewind by one more day
		previousDay := timeValue.Add(time.Duration(-24 * time.Hour))
		latestEndOfDayBoundary = time.Date(previousDay.Year(), previousDay.Month(), previousDay.Day(), HOUR_OF_END_OF_DAY, 0, 0, 0, timeValue.Location())
	} else {
		latestEndOfDayBoundary = time.Date(timeValue.Year(), timeValue.Month(), timeValue.Day(), HOUR_OF_END_OF_DAY, 0, 0, 0, timeValue.Location())
	}

	return latestEndOfDayBoundary
}

// GetMidnightUTCBefore returns the boundary of very last occurence of midnight before the given time.
// To give an example, if the given time is July 17th 2h00 UTC, the boundary returned is going to be
// July 17th 00h00. If the time is July 16th 23h00 PST, the boundary returned is July 16th 00h00.
func GetMidnightUTCBefore(timeValue time.Time) (latestMidnightBoundary time.Time) {
	timeInUTC := timeValue.UTC()
	latestMidnightBoundary = time.Date(timeInUTC.Year(), timeInUTC.Month(), timeInUTC.Day(), 0, 0, 0, 0, time.UTC)
	return latestMidnightBoundary
}

// Returns the timevalue with its timezone set to the default TIMEZONE_LOCATION
// func TimeWithDefaultTimezone(timevalue time.Time) (localTime string) {
// 	return timevalue.In(TIMEZONE_LOCATION).Format(TIMEFORMAT)
// }

// Returns the timevalue with its timezone set to the default TIMEZONE_LOCATION but without
// printing the timezone in the formatted string
// func TimeInDefaultTimezoneNoTz(timevalue time.Time) (localTime string) {
// 	return timevalue.In(TIMEZONE_LOCATION).Format(TIMEFORMAT_NO_TZ)
// }

// Returns the timevalue with its timezone set to UTC but without
// printing the timezone in the formatted string
func TimeInUTCNoTz(timevalue time.Time) (localTime string) {
	return timevalue.UTC().Format(TIMEFORMAT_NO_TZ)
}

// GetLocaltimeOffset returns the Fixed location extrapolated by calculating the offset
// of the localtime and the internal time in UTC
func GetLocaltimeOffset(localTime string, internalTime time.Time) (location *time.Location) {
	// Get the local time as if it was UTC (it's not)
	localTimeUTC, _ := time.Parse(TIMEFORMAT_NO_TZ, localTime)

	// Get the difference between the internal time (actual UTC) and the local time
	durationOffset := localTimeUTC.Sub(internalTime)

	locationName := fmt.Sprintf("%+03d%02d", int64(durationOffset.Hours()), (int64(durationOffset)-int64(durationOffset.Hours())*int64(time.Hour))/int64(time.Minute))
	return time.FixedZone(locationName, int(durationOffset.Seconds()))
}

// GetLocalTimeInProperLocation returns the parsed local time with the location appropriately set as extrapolated
// by calculating the difference of the internal time vs the local time
func GetLocalTimeInProperLocation(localTime string, internalTime time.Time) (localTimeWithLocation time.Time) {
	location := GetLocaltimeOffset(localTime, internalTime)
	localTimeWithLocation, _ = time.ParseInLocation(TIMEFORMAT_NO_TZ, localTime, location)
	return
}
<|endoftext|>


<commit_before>package blobinfocache

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

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/require"

	"github.com/containers/image/v5/pkg/blobinfocache/boltdb"
	"github.com/containers/image/v5/pkg/blobinfocache/memory"
	"github.com/containers/image/v5/types"
	"github.com/stretchr/testify/assert"
)

func TestBlobInfoCacheDir(t *testing.T) {
	const nondefaultDir = "/this/is/not/the/default/cache/dir"
	const rootPrefix = "/root/prefix"
	const homeDir = "/fake/home/directory"
	const xdgDataHome = "/fake/home/directory/XDG"

	// Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
	// run in parallel unless they opt in by calling t.Parallel().  So don’t do that.
	oldXRD, hasXRD := os.LookupEnv("XDG_RUNTIME_DIR")
	defer func() {
		if hasXRD {
			os.Setenv("XDG_RUNTIME_DIR", oldXRD)
		} else {
			os.Unsetenv("XDG_RUNTIME_DIR")
		}
	}()
	// FIXME: This should be a shared helper in internal/testing
	oldHome, hasHome := os.LookupEnv("HOME")
	defer func() {
		if hasHome {
			os.Setenv("HOME", oldHome)
		} else {
			os.Unsetenv("HOME")
		}
	}()

	os.Setenv("HOME", homeDir)
	os.Setenv("XDG_DATA_HOME", xdgDataHome)

	// The default paths and explicit overrides
	for _, c := range []struct {
		sys      *types.SystemContext
		euid     int
		expected string
	}{
		// The common case
		{nil, 0, systemBlobInfoCacheDir},
		{nil, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// There is a context, but it does not override the path.
		{&types.SystemContext{}, 0, systemBlobInfoCacheDir},
		{&types.SystemContext{}, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// Path overridden
		{&types.SystemContext{BlobInfoCacheDir: nondefaultDir}, 0, nondefaultDir},
		{&types.SystemContext{BlobInfoCacheDir: nondefaultDir}, 1, nondefaultDir},
		// Root overridden
		{&types.SystemContext{RootForImplicitAbsolutePaths: rootPrefix}, 0, filepath.Join(rootPrefix, systemBlobInfoCacheDir)},
		{&types.SystemContext{RootForImplicitAbsolutePaths: rootPrefix}, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// Root and path overrides present simultaneously,
		{
			&types.SystemContext{
				RootForImplicitAbsolutePaths: rootPrefix,
				BlobInfoCacheDir:             nondefaultDir,
			},
			0, nondefaultDir,
		},
		{
			&types.SystemContext{
				RootForImplicitAbsolutePaths: rootPrefix,
				BlobInfoCacheDir:             nondefaultDir,
			},
			1, nondefaultDir,
		},
	} {
		path, err := blobInfoCacheDir(c.sys, c.euid)
		require.NoError(t, err)
		assert.Equal(t, c.expected, path)
	}

	// Paths used by unprivileged users
	for _, c := range []struct {
		xdgDH, home, expected string
	}{
		{"", homeDir, filepath.Join(homeDir, ".local", "share", "containers", "cache")}, // HOME only
		{xdgDataHome, "", filepath.Join(xdgDataHome, "containers", "cache")},            // XDG_DATA_HOME only
		{xdgDataHome, homeDir, filepath.Join(xdgDataHome, "containers", "cache")},       // both
		{"", "", ""}, // neither
	} {
		if c.xdgDH != "" {
			os.Setenv("XDG_DATA_HOME", c.xdgDH)
		} else {
			os.Unsetenv("XDG_DATA_HOME")
		}
		if c.home != "" {
			os.Setenv("HOME", c.home)
		} else {
			os.Unsetenv("HOME")
		}
		for _, sys := range []*types.SystemContext{nil, {}} {
			path, err := blobInfoCacheDir(sys, 1)
			if c.expected != "" {
				require.NoError(t, err)
				assert.Equal(t, c.expected, path)
			} else {
				assert.Error(t, err)
			}
		}
	}
}

func TestDefaultCache(t *testing.T) {
	tmpDir, err := ioutil.TempDir("", "TestDefaultCache")
	require.NoError(t, err)
	//defer os.RemoveAll(tmpDir)

	// Success
	normalDir := filepath.Join(tmpDir, "normal")
	c := DefaultCache(&types.SystemContext{BlobInfoCacheDir: normalDir})
	// This is ugly hard-coding internals of boltDBCache:
	assert.Equal(t, boltdb.New(filepath.Join(normalDir, blobInfoCacheFilename)), c)

	// Error running blobInfoCacheDir:
	// Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
	// run in parallel unless they opt in by calling t.Parallel().  So don’t do that.
	oldXRD, hasXRD := os.LookupEnv("XDG_RUNTIME_DIR")
	defer func() {
		if hasXRD {
			os.Setenv("XDG_RUNTIME_DIR", oldXRD)
		} else {
			os.Unsetenv("XDG_RUNTIME_DIR")
		}
	}()
	// FIXME: This should be a shared helper in internal/testing
	oldHome, hasHome := os.LookupEnv("HOME")
	defer func() {
		if hasHome {
			os.Setenv("HOME", oldHome)
		} else {
			os.Unsetenv("HOME")
		}
	}()
	os.Unsetenv("HOME")
	os.Unsetenv("XDG_DATA_HOME")
	c = DefaultCache(nil)
	assert.IsType(t, memory.New(), c)

	// Error creating the parent directory:
	unwritableDir := filepath.Join(tmpDir, "unwritable")
	err = os.Mkdir(unwritableDir, 0700)
	require.NoError(t, err)
	defer func() {
		err = os.Chmod(unwritableDir, 0700) // To make it possible to remove it again
		require.NoError(t, err)
	}()
	err = os.Chmod(unwritableDir, 0500)
	require.NoError(t, err)
	st, _ := os.Stat(unwritableDir)
	logrus.Errorf("%s: %#v", unwritableDir, st)
	c = DefaultCache(&types.SystemContext{BlobInfoCacheDir: filepath.Join(unwritableDir, "subdirectory")})
	assert.IsType(t, memory.New(), c)
}
<commit_msg>blobinfocache: clean up after test<commit_after>package blobinfocache

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

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/require"

	"github.com/containers/image/v5/pkg/blobinfocache/boltdb"
	"github.com/containers/image/v5/pkg/blobinfocache/memory"
	"github.com/containers/image/v5/types"
	"github.com/stretchr/testify/assert"
)

func TestBlobInfoCacheDir(t *testing.T) {
	const nondefaultDir = "/this/is/not/the/default/cache/dir"
	const rootPrefix = "/root/prefix"
	const homeDir = "/fake/home/directory"
	const xdgDataHome = "/fake/home/directory/XDG"

	// Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
	// run in parallel unless they opt in by calling t.Parallel().  So don’t do that.
	oldXRD, hasXRD := os.LookupEnv("XDG_RUNTIME_DIR")
	defer func() {
		if hasXRD {
			os.Setenv("XDG_RUNTIME_DIR", oldXRD)
		} else {
			os.Unsetenv("XDG_RUNTIME_DIR")
		}
	}()
	// FIXME: This should be a shared helper in internal/testing
	oldHome, hasHome := os.LookupEnv("HOME")
	defer func() {
		if hasHome {
			os.Setenv("HOME", oldHome)
		} else {
			os.Unsetenv("HOME")
		}
	}()

	os.Setenv("HOME", homeDir)
	os.Setenv("XDG_DATA_HOME", xdgDataHome)

	// The default paths and explicit overrides
	for _, c := range []struct {
		sys      *types.SystemContext
		euid     int
		expected string
	}{
		// The common case
		{nil, 0, systemBlobInfoCacheDir},
		{nil, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// There is a context, but it does not override the path.
		{&types.SystemContext{}, 0, systemBlobInfoCacheDir},
		{&types.SystemContext{}, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// Path overridden
		{&types.SystemContext{BlobInfoCacheDir: nondefaultDir}, 0, nondefaultDir},
		{&types.SystemContext{BlobInfoCacheDir: nondefaultDir}, 1, nondefaultDir},
		// Root overridden
		{&types.SystemContext{RootForImplicitAbsolutePaths: rootPrefix}, 0, filepath.Join(rootPrefix, systemBlobInfoCacheDir)},
		{&types.SystemContext{RootForImplicitAbsolutePaths: rootPrefix}, 1, filepath.Join(xdgDataHome, "containers", "cache")},
		// Root and path overrides present simultaneously,
		{
			&types.SystemContext{
				RootForImplicitAbsolutePaths: rootPrefix,
				BlobInfoCacheDir:             nondefaultDir,
			},
			0, nondefaultDir,
		},
		{
			&types.SystemContext{
				RootForImplicitAbsolutePaths: rootPrefix,
				BlobInfoCacheDir:             nondefaultDir,
			},
			1, nondefaultDir,
		},
	} {
		path, err := blobInfoCacheDir(c.sys, c.euid)
		require.NoError(t, err)
		assert.Equal(t, c.expected, path)
	}

	// Paths used by unprivileged users
	for _, c := range []struct {
		xdgDH, home, expected string
	}{
		{"", homeDir, filepath.Join(homeDir, ".local", "share", "containers", "cache")}, // HOME only
		{xdgDataHome, "", filepath.Join(xdgDataHome, "containers", "cache")},            // XDG_DATA_HOME only
		{xdgDataHome, homeDir, filepath.Join(xdgDataHome, "containers", "cache")},       // both
		{"", "", ""}, // neither
	} {
		if c.xdgDH != "" {
			os.Setenv("XDG_DATA_HOME", c.xdgDH)
		} else {
			os.Unsetenv("XDG_DATA_HOME")
		}
		if c.home != "" {
			os.Setenv("HOME", c.home)
		} else {
			os.Unsetenv("HOME")
		}
		for _, sys := range []*types.SystemContext{nil, {}} {
			path, err := blobInfoCacheDir(sys, 1)
			if c.expected != "" {
				require.NoError(t, err)
				assert.Equal(t, c.expected, path)
			} else {
				assert.Error(t, err)
			}
		}
	}
}

func TestDefaultCache(t *testing.T) {
	tmpDir, err := ioutil.TempDir("", "TestDefaultCache")
	require.NoError(t, err)
	defer os.RemoveAll(tmpDir)

	// Success
	normalDir := filepath.Join(tmpDir, "normal")
	c := DefaultCache(&types.SystemContext{BlobInfoCacheDir: normalDir})
	// This is ugly hard-coding internals of boltDBCache:
	assert.Equal(t, boltdb.New(filepath.Join(normalDir, blobInfoCacheFilename)), c)

	// Error running blobInfoCacheDir:
	// Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
	// run in parallel unless they opt in by calling t.Parallel().  So don’t do that.
	oldXRD, hasXRD := os.LookupEnv("XDG_RUNTIME_DIR")
	defer func() {
		if hasXRD {
			os.Setenv("XDG_RUNTIME_DIR", oldXRD)
		} else {
			os.Unsetenv("XDG_RUNTIME_DIR")
		}
	}()
	// FIXME: This should be a shared helper in internal/testing
	oldHome, hasHome := os.LookupEnv("HOME")
	defer func() {
		if hasHome {
			os.Setenv("HOME", oldHome)
		} else {
			os.Unsetenv("HOME")
		}
	}()
	os.Unsetenv("HOME")
	os.Unsetenv("XDG_DATA_HOME")
	c = DefaultCache(nil)
	assert.IsType(t, memory.New(), c)

	// Error creating the parent directory:
	unwritableDir := filepath.Join(tmpDir, "unwritable")
	err = os.Mkdir(unwritableDir, 0700)
	require.NoError(t, err)
	defer func() {
		err = os.Chmod(unwritableDir, 0700) // To make it possible to remove it again
		require.NoError(t, err)
	}()
	err = os.Chmod(unwritableDir, 0500)
	require.NoError(t, err)
	st, _ := os.Stat(unwritableDir)
	logrus.Errorf("%s: %#v", unwritableDir, st)
	c = DefaultCache(&types.SystemContext{BlobInfoCacheDir: filepath.Join(unwritableDir, "subdirectory")})
	assert.IsType(t, memory.New(), c)
}
<|endoftext|>


<commit_before>package internal

import (
	"net/http"
	"time"

	"github.com/cenkalti/backoff/v4"
	"github.com/pkg/errors"
)

// MaybeRetryRequest is an internal implementation detail of this module. It
// shouldn't be used by users of the geoipupdate Go library. You can use the
// RetryFor field of geoipupdate.Config if you'd like to retry failed requests
// when using the library directly.
func MaybeRetryRequest(c *http.Client, retryFor time.Duration, req *http.Request) (*http.Response, error) {
	if retryFor < 0 {
		return nil, errors.New("negative retry duration")
	}
	if req.Body != nil {
		return nil, errors.New("can't retry requests with bodies")
	}
	exp := backoff.NewExponentialBackOff()
	exp.MaxElapsedTime = retryFor
	var resp *http.Response
	err := backoff.Retry(
		func() error {
			var err error
			resp, err = c.Do(req) // nolint: bodyclose
			if err != nil {
				return errors.Wrap(err, "error performing http request")
			}
			return err
		},
		exp,
	)
	return resp, err
}
<commit_msg>Appease linters<commit_after>// Package internal is none of your business
package internal

import (
	"net/http"
	"time"

	"github.com/cenkalti/backoff/v4"
	"github.com/pkg/errors"
)

// MaybeRetryRequest is an internal implementation detail of this module. It
// shouldn't be used by users of the geoipupdate Go library. You can use the
// RetryFor field of geoipupdate.Config if you'd like to retry failed requests
// when using the library directly.
func MaybeRetryRequest(c *http.Client, retryFor time.Duration, req *http.Request) (*http.Response, error) {
	if retryFor < 0 {
		return nil, errors.New("negative retry duration")
	}
	if req.Body != nil {
		return nil, errors.New("can't retry requests with bodies")
	}
	exp := backoff.NewExponentialBackOff()
	exp.MaxElapsedTime = retryFor
	var resp *http.Response
	err := backoff.Retry(
		func() error {
			var err error
			resp, err = c.Do(req) // nolint: bodyclose
			if err != nil {
				return errors.Wrap(err, "error performing http request")
			}
			return err
		},
		exp,
	)
	return resp, err
}
<|endoftext|>