<commit_before>// Copyright 2014 Arne Roomann-Kurrik
//
// 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 twodee

import (
	"image"
	"image/color"
)

type Grid struct {
	Width  int32
	Height int32
	points []bool
}

func NewGrid(w, h int32) *Grid {
	return &Grid{
		points: make([]bool, w*h),
		Width:  w,
		Height: h,
	}
}

func (g *Grid) Index(x, y int32) int32 {
	if x < 0 || y < 0 {
		return -1
	}
	return g.Width*(g.Height-y-1) + x
}

func (g *Grid) Get(x, y int32) bool {
	return g.GetIndex(g.Index(x, y))
}

func (g *Grid) GetIndex(index int32) bool {
	if index < 0 || index > g.Width*g.Height {
		return false
	}
	return g.points[index]
}

func (g *Grid) Set(x, y int32, val bool) {
	g.SetIndex(g.Index(x, y), val)
}

func (g *Grid) SetIndex(index int32, val bool) {
	if index < 0 || index > g.Width*g.Height {
		return
	}
	g.points[index] = val
}

func (g *Grid) GetImage(fg, bg color.Color) *image.NRGBA {
	var img = image.NewNRGBA(image.Rect(0, 0, int(g.Width), int(g.Height)))
	for x := 0; x < int(g.Width); x++ {
		for y := 0; y < int(g.Height); y++ {
			if g.Get(int32(x), int32(y)) {
				img.Set(x, y, fg)
			} else {
				img.Set(x, y, bg)
			}
		}
	}
	return img
}
<commit_msg>Added the ability to fix a move to a grid<commit_after>// Copyright 2014 Arne Roomann-Kurrik
//
// 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 twodee

import (
	"github.com/go-gl/mathgl/mgl32"
	"image"
	"image/color"
)

type Grid struct {
	Width  int32
	Height int32
	points []bool
}

func NewGrid(w, h int32) *Grid {
	return &Grid{
		points: make([]bool, w*h),
		Width:  w,
		Height: h,
	}
}

func (g *Grid) Index(x, y int32) int32 {
	if x < 0 || y < 0 {
		return -1
	}
	return g.Width*(g.Height-y-1) + x
}

func (g *Grid) Get(x, y int32) bool {
	return g.GetIndex(g.Index(x, y))
}

func (g *Grid) GetIndex(index int32) bool {
	if index < 0 || index > g.Width*g.Height {
		return false
	}
	return g.points[index]
}

func (g *Grid) Set(x, y int32, val bool) {
	g.SetIndex(g.Index(x, y), val)
}

func (g *Grid) SetIndex(index int32, val bool) {
	if index < 0 || index > g.Width*g.Height {
		return
	}
	g.points[index] = val
}

func (g *Grid) GetImage(fg, bg color.Color) *image.NRGBA {
	var img = image.NewNRGBA(image.Rect(0, 0, int(g.Width), int(g.Height)))
	for x := 0; x < int(g.Width); x++ {
		for y := 0; y < int(g.Height); y++ {
			if g.Get(int32(x), int32(y)) {
				img.Set(x, y, fg)
			} else {
				img.Set(x, y, bg)
			}
		}
	}
	return img
}

func (g *Grid) squareCollides(bounds mgl32.Vec4, x, y, sizex, sizey float32) bool {
	// Bounds are {minx, miny, maxx, maxy}
	// Sizex, sizey are the number of coordinate units a grid entry occupies.
	var (
		fudge = float32(0.001) // Prevents item from sticking to wall when we round its coordinates.
		minx  = int32((bounds[0] + x) / sizex)
		miny  = int32((bounds[1] + y) / sizey)
		maxx  = int32((bounds[2] + x - fudge) / sizex)
		maxy  = int32((bounds[3] + y - fudge) / sizey)
		i     int32
		j     int32
	)
	for i = minx; i <= maxx; i++ {
		for j = miny; j <= maxy; j++ {
			if g.Get(i, j) {
				return true
			}
		}
	}
	return false
}

func (g *Grid) FixMove(bounds mgl32.Vec4, move mgl32.Vec2, sizex, sizey float32) (out mgl32.Vec2) {
	out = move
	if g.squareCollides(bounds, out[0], 0.0, sizex, sizey) {
		out[0] = g.GridAligned(bounds[0], sizex) - bounds[0]
	}
	if g.squareCollides(bounds, out[0], out[1], sizex, sizey) {
		out[1] = g.GridAligned(bounds[1], sizey) - bounds[1]
	}
	return
}

func (g *Grid) GridAligned(x float32, sizex float32) float32 {
	return sizex * float32(int32((x/sizex)+0.5))
}
<|endoftext|>


<commit_before>package grok

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
)

// Grok Type
type Grok struct {
	compiledPattern map[string]*regexp.Regexp
	patterns        map[string]string
	serviceMu       sync.Mutex
}

// New returns a Grok struct
func New() *Grok {
	o := new(Grok)
	o.patterns = patterns
	o.compiledPattern = map[string]*regexp.Regexp{}
	return o
}

// AddPattern add a named pattern to grok
func (g *Grok) AddPattern(name string, pattern string) {
	g.patterns[name] = pattern
}

func (g *Grok) cache(pattern string, cr *regexp.Regexp) {
	g.serviceMu.Lock()
	defer g.serviceMu.Unlock()
	g.compiledPattern[pattern] = cr
}

func (g *Grok) cacheExists(pattern string) bool {
	g.serviceMu.Lock()
	defer g.serviceMu.Unlock()

	if _, ok := g.compiledPattern[pattern]; ok {
		return true
	}

	return false
}

func (g *Grok) compile(pattern string) (*regexp.Regexp, error) {
	if g.cacheExists(pattern) {
		return g.compiledPattern[pattern], nil
	}

	//search for %{...:...}
	r, _ := regexp.Compile(`%{(\w+:?\w+)}`)
	newPattern := pattern
	for _, values := range r.FindAllStringSubmatch(pattern, -1) {
		names := strings.Split(values[1], ":")

		customname := names[0]
		if len(names) != 1 {
			customname = names[1]
		}
		//search for replacements
		if ok := g.patterns[names[0]]; ok == "" {
			return nil, fmt.Errorf("ERROR no pattern found for %%{%s}", names[0])
		}
		replace := fmt.Sprintf("(?P<%s>%s)", customname, g.patterns[names[0]])
		//build the new regexp
		newPattern = strings.Replace(newPattern, values[0], replace, -1)
	}
	patternCompiled, err := regexp.Compile(newPattern)

	if err != nil {
		return nil, err
	}
	g.cache(pattern, patternCompiled)
	return patternCompiled, nil

}

// Match returns true when text match the compileed pattern
func (g *Grok) Match(pattern, text string) (bool, error) {
	cr, err := g.compile(pattern)

	if err != nil {
		return false, err
	}

	if m := cr.MatchString(text); !m {
		return false, nil
	}

	return true, nil
}

// Parse returns a string map with captured string based on provided pattern over the text
func (g *Grok) Parse(pattern string, text string) (map[string]string, error) {
	cr, err := g.compile(pattern)
	if err != nil {
		return nil, err
	}

	match := cr.FindStringSubmatch(text)
	captures := make(map[string]string)
	if len(match) > 0 {
		for i, name := range cr.SubexpNames() {
			captures[name] = match[i]
		}
	}

	return captures, nil
}

// ParseToMultiMap works just like Parse, except that it allows to map multiple values to the same capture name.
func (g *Grok) ParseToMultiMap(pattern string, text string) (map[string][]string, error) {
	multiCaptures := make(map[string][]string)
	cr, err := g.compile(pattern)
	if err != nil {
		return nil, err
	}

	match := cr.FindStringSubmatch(text)
	if len(match) > 0 {
		for i, name := range cr.SubexpNames() {
			multiCaptures[name] = append(multiCaptures[name], match[i])
		}
	}

	return multiCaptures, nil
}

// AddPatternsFromPath loads grok patterns from a file or files from a directory
func (g *Grok) AddPatternsFromPath(path string) error {

	if fi, err := os.Stat(path); err == nil {
		if fi.IsDir() {
			path = path + "/*"
		}
	}

	var patternDependancies = graph{}
	var fileContent = map[string]string{}

	//List all files if path folder
	files, _ := filepath.Glob(path)
	for _, file := range files {
		inFile, _ := os.Open(file)

		reader := bufio.NewReader(inFile)
		scanner := bufio.NewScanner(reader)

		for scanner.Scan() {
			l := scanner.Text()
			if len(l) > 0 { // line has text
				if l[0] != '#' { // line does not start with #
					names := strings.SplitN(l, " ", 2)
					// names[0] = key
					// names[1] = pattern
					fileContent[names[0]] = names[1]

					r, _ := regexp.Compile(`%{(\w+):?(\w+)?}`)
					keys := []string{}
					for _, key := range r.FindAllStringSubmatch(names[1], -1) {
						keys = append(keys, key[1])
					}
					patternDependancies[names[0]] = keys
				}
			}
		}
		inFile.Close()
	}

	order, _ := sortGraph(patternDependancies)
	order = reverseList(order)

	var denormalizedPattern = map[string]string{}
	for _, key := range order {
		denormalizedPattern[key] = denormalizePattern(fileContent[key], denormalizedPattern)
		g.AddPattern(key, denormalizedPattern[key])
	}

	return nil
}

func denormalizePattern(pattern string, finalPatterns map[string]string) string {
	r, _ := regexp.Compile(`%{((\w+):?(\w+)?)}`)
	newPattern := pattern
	for _, values := range r.FindAllStringSubmatch(pattern, -1) {
		customname := values[2]
		if values[3] != "" {
			customname = values[3]
		}
		//search for replacements
		replace := fmt.Sprintf("(?P<%s>%s)", customname, finalPatterns[values[2]])

		//build the new regex
		newPattern = strings.Replace(newPattern, values[0], replace, -1)
	}
	return newPattern
}
<commit_msg>regex compiled one time for all in AddPatternsFromPath<commit_after>package grok

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
)

// Grok Type
type Grok struct {
	compiledPattern map[string]*regexp.Regexp
	patterns        map[string]string
	serviceMu       sync.Mutex
}

// New returns a Grok struct
func New() *Grok {
	o := new(Grok)
	o.patterns = patterns
	o.compiledPattern = map[string]*regexp.Regexp{}
	return o
}

// AddPattern add a named pattern to grok
func (g *Grok) AddPattern(name string, pattern string) {
	g.patterns[name] = pattern
}

func (g *Grok) cache(pattern string, cr *regexp.Regexp) {
	g.serviceMu.Lock()
	defer g.serviceMu.Unlock()
	g.compiledPattern[pattern] = cr
}

func (g *Grok) cacheExists(pattern string) bool {
	g.serviceMu.Lock()
	defer g.serviceMu.Unlock()

	if _, ok := g.compiledPattern[pattern]; ok {
		return true
	}

	return false
}

func (g *Grok) compile(pattern string) (*regexp.Regexp, error) {
	if g.cacheExists(pattern) {
		return g.compiledPattern[pattern], nil
	}

	//search for %{...:...}
	r, _ := regexp.Compile(`%{(\w+:?\w+)}`)
	newPattern := pattern
	for _, values := range r.FindAllStringSubmatch(pattern, -1) {
		names := strings.Split(values[1], ":")

		customname := names[0]
		if len(names) != 1 {
			customname = names[1]
		}
		//search for replacements
		if ok := g.patterns[names[0]]; ok == "" {
			return nil, fmt.Errorf("ERROR no pattern found for %%{%s}", names[0])
		}
		replace := fmt.Sprintf("(?P<%s>%s)", customname, g.patterns[names[0]])
		//build the new regexp
		newPattern = strings.Replace(newPattern, values[0], replace, -1)
	}
	patternCompiled, err := regexp.Compile(newPattern)

	if err != nil {
		return nil, err
	}
	g.cache(pattern, patternCompiled)
	return patternCompiled, nil

}

// Match returns true when text match the compileed pattern
func (g *Grok) Match(pattern, text string) (bool, error) {
	cr, err := g.compile(pattern)

	if err != nil {
		return false, err
	}

	if m := cr.MatchString(text); !m {
		return false, nil
	}

	return true, nil
}

// Parse returns a string map with captured string based on provided pattern over the text
func (g *Grok) Parse(pattern string, text string) (map[string]string, error) {
	cr, err := g.compile(pattern)
	if err != nil {
		return nil, err
	}

	match := cr.FindStringSubmatch(text)
	captures := make(map[string]string)
	if len(match) > 0 {
		for i, name := range cr.SubexpNames() {
			captures[name] = match[i]
		}
	}

	return captures, nil
}

// ParseToMultiMap works just like Parse, except that it allows to map multiple values to the same capture name.
func (g *Grok) ParseToMultiMap(pattern string, text string) (map[string][]string, error) {
	multiCaptures := make(map[string][]string)
	cr, err := g.compile(pattern)
	if err != nil {
		return nil, err
	}

	match := cr.FindStringSubmatch(text)
	if len(match) > 0 {
		for i, name := range cr.SubexpNames() {
			multiCaptures[name] = append(multiCaptures[name], match[i])
		}
	}

	return multiCaptures, nil
}

// AddPatternsFromPath loads grok patterns from a file or files from a directory
func (g *Grok) AddPatternsFromPath(path string) error {

	if fi, err := os.Stat(path); err == nil {
		if fi.IsDir() {
			path = path + "/*"
		}
	}

	var patternDependancies = graph{}
	var fileContent = map[string]string{}

	//List all files if path folder
	files, _ := filepath.Glob(path)
	for _, file := range files {
		inFile, _ := os.Open(file)

		reader := bufio.NewReader(inFile)
		scanner := bufio.NewScanner(reader)
		r, _ := regexp.Compile(`%{(\w+):?(\w+)?}`)

		for scanner.Scan() {
			l := scanner.Text()
			if len(l) > 0 { // line has text
				if l[0] != '#' { // line does not start with #
					names := strings.SplitN(l, " ", 2)
					// names[0] = key
					// names[1] = pattern
					fileContent[names[0]] = names[1]

					keys := []string{}
					for _, key := range r.FindAllStringSubmatch(names[1], -1) {
						keys = append(keys, key[1])
					}
					patternDependancies[names[0]] = keys
				}
			}
		}
		inFile.Close()
	}

	order, _ := sortGraph(patternDependancies)
	order = reverseList(order)

	var denormalizedPattern = map[string]string{}
	for _, key := range order {
		denormalizedPattern[key] = denormalizePattern(fileContent[key], denormalizedPattern)
		g.AddPattern(key, denormalizedPattern[key])
	}

	return nil
}

func denormalizePattern(pattern string, finalPatterns map[string]string) string {
	r, _ := regexp.Compile(`%{((\w+):?(\w+)?)}`)
	newPattern := pattern
	for _, values := range r.FindAllStringSubmatch(pattern, -1) {
		customname := values[2]
		if values[3] != "" {
			customname = values[3]
		}
		//search for replacements
		replace := fmt.Sprintf("(?P<%s>%s)", customname, finalPatterns[values[2]])

		//build the new regex
		newPattern = strings.Replace(newPattern, values[0], replace, -1)
	}
	return newPattern
}
<|endoftext|>


<commit_before>package ole

var (
	// IID_NULL is null Interface ID, used when no other Interface ID is known.
	IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}

	// IID_IUnknown is for IUnknown interfaces.
	IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IDispatch is for IDispatch interfaces.
	IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IEnumVariant is for IEnumVariant interfaces
	IID_IEnumVariant = &GUID{0x00020404, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IConnectionPointContainer is for IConnectionPointContainer interfaces.
	IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IConnectionPoint is for IConnectionPoint interfaces.
	IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IInspectable is for IInspectable interfaces.
	IID_IInspectable = &GUID{0xaf86e2e0, 0xb12d, 0x4c6a, [8]byte{0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90}}

	// IID_IProvideClassInfo is for IProvideClassInfo interfaces.
	IID_IProvideClassInfo = &GUID{0xb196b283, 0xbab4, 0x101a, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
)

// These are for testing and not part of any library.
var (
	// IID_ICOMTestString is for ICOMTestString interfaces.
	//
	// {E0133EB4-C36F-469A-9D3D-C66B84BE19ED}
	IID_ICOMTestString = &GUID{0xe0133eb4, 0xc36f, 0x469a, [8]byte{0x9d, 0x3d, 0xc6, 0x6b, 0x84, 0xbe, 0x19, 0xed}}

	// IID_ICOMTestInt8 is for ICOMTestInt8 interfaces.
	//
	// {BEB06610-EB84-4155-AF58-E2BFF53608B4}
	IID_ICOMTestInt8 = &GUID{0xbeb06610, 0xeb84, 0x4155, [8]byte{0xaf, 0x58, 0xe2, 0xbf, 0xf5, 0x36, 0x80, 0xb4}}

	// IID_ICOMTestInt16 is for ICOMTestInt16 interfaces.
	//
	// {DAA3F9FA-761E-4976-A860-8364CE55F6FC}
	IID_ICOMTestInt16 = &GUID{0xdaa3f9fa, 0x761e, 0x4976, [8]byte{0xa8, 0x60, 0x83, 0x64, 0xce, 0x55, 0xf6, 0xfc}}

	// IID_ICOMTestInt32 is for ICOMTestInt32 interfaces.
	//
	// {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}
	IID_ICOMTestInt32 = &GUID{0xe3dedee7, 0x38a2, 0x4540, [8]byte{0x91, 0xd1, 0x2e, 0xef, 0x1d, 0x88, 0x91, 0xb0}}

	// IID_ICOMTestInt64 is for ICOMTestInt64 interfaces.
	//
	// {8D437CBC-B3ED-485C-BC32-C336432A1623}
	IID_ICOMTestInt64 = &GUID{0x8d437cbc, 0xb3ed, 0x485c, [8]byte{0xbc, 0x32, 0xc3, 0x36, 0x43, 0x2a, 0x16, 0x23}}

	// IID_ICOMTestFloat is for ICOMTestFloat interfaces.
	//
	// {BF1ED004-EA02-456A-AA55-2AC8AC6B054C}
	IID_ICOMTestFloat = &GUID{0xbf1ed004, 0xea02, 0x456a, [8]byte{0xaa, 0x55, 0x2a, 0xc8, 0xac, 0x6b, 0x5, 0x4c}}

	// IID_ICOMTestDouble is for ICOMTestDouble interfaces.
	//
	// {BF908A81-8687-4E93-999F-D86FAB284BA0}
	IID_ICOMTestDouble = &GUID{0xbf908a81, 0x8687, 0x4e93, [8]byte{0x99, 0x9f, 0xd8, 0x6f, 0xab, 0x28, 0x4b, 0xa0}}

	// IID_ICOMTestBoolean is for ICOMTestBoolean interfaces.
	//
	// {D530E7A6-4EE8-40D1-8931-3D63B8605001}
	IID_ICOMTestBoolean = &GUID{0xd530e7a6, 0x4ee8, 0x40d1, [8]byte{0x89, 0x31, 0x3d, 0x63, 0xb8, 0x60, 0x50, 0x10}}

	// IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces.
	//
	// {6485B1EF-D780-4834-A4FE-1EBB51746CA3}
	IID_ICOMEchoTestObject = &GUID{0x6485b1ef, 0xd780, 0x4834, [8]byte{0xa4, 0xfe, 0x1e, 0xbb, 0x51, 0x74, 0x6c, 0xa3}}

	// IID_ICOMTestTypes is for ICOMTestTypes interfaces.
	//
	// {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}
	IID_ICOMTestTypes = &GUID{0xcca8d7ae, 0x91c0, 0x4277, [8]byte{0xa8, 0xb3, 0xff, 0x4e, 0xdf, 0x28, 0xd3, 0xc0}}

	// CLSID_COMEchoTestObject is for COMEchoTestObject class.
	//
	// {3C24506A-AE9E-4D50-9157-EF317281F1B0}
	CLSID_COMEchoTestObject = &GUID{0x3c24506a, 0xae9e, 0x4d50, [8]byte{0x91, 0x57, 0xef, 0x31, 0x72, 0x81, 0xf1, 0xb0}}

	// CLSID_COMTestScalarClass is for COMTestScalarClass class.
	//
	// {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}
	CLSID_COMTestScalarClass = &GUID{0x865b85c5, 0x0334, 0x4ac6, [8]byte{0x9e, 0xf6, 0xaa, 0xce, 0xc8, 0xfc, 0x5e, 0x86}}
)

// GUID is Windows API specific GUID type.
//
// This exists to match Windows GUID type for direct passing for COM.
// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

// IsEqualGUID compares two GUID.
//
// Not constant time comparison.
func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool {
	return guid1.Data1 == guid2.Data1 &&
		guid1.Data2 == guid2.Data2 &&
		guid1.Data3 == guid2.Data3 &&
		guid1.Data4[0] == guid2.Data4[0] &&
		guid1.Data4[1] == guid2.Data4[1] &&
		guid1.Data4[2] == guid2.Data4[2] &&
		guid1.Data4[3] == guid2.Data4[3] &&
		guid1.Data4[4] == guid2.Data4[4] &&
		guid1.Data4[5] == guid2.Data4[5] &&
		guid1.Data4[6] == guid2.Data4[6] &&
		guid1.Data4[7] == guid2.Data4[7]
}
<commit_msg>Added native GUID string parsing<commit_after>package ole

var (
	// IID_NULL is null Interface ID, used when no other Interface ID is known.
	IID_NULL = NewGUID("{00000000-0000-0000-0000-000000000000}")

	// IID_IUnknown is for IUnknown interfaces.
	IID_IUnknown = NewGUID("{00000000-0000-0000-C000-000000000046}")

	// IID_IDispatch is for IDispatch interfaces.
	IID_IDispatch = NewGUID("{00020400-0000-0000-C000-000000000046}")

	// IID_IEnumVariant is for IEnumVariant interfaces
	IID_IEnumVariant = NewGUID("{00020404-0000-0000-C000-000000000046}")

	// IID_IConnectionPointContainer is for IConnectionPointContainer interfaces.
	IID_IConnectionPointContainer = NewGUID("{B196B284-BAB4-101A-B69C-00AA00341D07}")

	// IID_IConnectionPoint is for IConnectionPoint interfaces.
	IID_IConnectionPoint = NewGUID("{B196B286-BAB4-101A-B69C-00AA00341D07}")

	// IID_IInspectable is for IInspectable interfaces.
	IID_IInspectable = NewGUID("{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}")

	// IID_IProvideClassInfo is for IProvideClassInfo interfaces.
	IID_IProvideClassInfo = NewGUID("{B196B283-BAB4-101A-B69C-00AA00341D07}")
)

// These are for testing and not part of any library.
var (
	// IID_ICOMTestString is for ICOMTestString interfaces.
	//
	// {E0133EB4-C36F-469A-9D3D-C66B84BE19ED}
	IID_ICOMTestString = NewGUID("{E0133EB4-C36F-469A-9D3D-C66B84BE19ED}")

	// IID_ICOMTestInt8 is for ICOMTestInt8 interfaces.
	//
	// {BEB06610-EB84-4155-AF58-E2BFF53680B4}
	IID_ICOMTestInt8 = NewGUID("{BEB06610-EB84-4155-AF58-E2BFF53680B4}")

	// IID_ICOMTestInt16 is for ICOMTestInt16 interfaces.
	//
	// {DAA3F9FA-761E-4976-A860-8364CE55F6FC}
	IID_ICOMTestInt16 = NewGUID("{DAA3F9FA-761E-4976-A860-8364CE55F6FC}")

	// IID_ICOMTestInt32 is for ICOMTestInt32 interfaces.
	//
	// {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}
	IID_ICOMTestInt32 = NewGUID("{E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}")

	// IID_ICOMTestInt64 is for ICOMTestInt64 interfaces.
	//
	// {8D437CBC-B3ED-485C-BC32-C336432A1623}
	IID_ICOMTestInt64 = NewGUID("{8D437CBC-B3ED-485C-BC32-C336432A1623}")

	// IID_ICOMTestFloat is for ICOMTestFloat interfaces.
	//
	// {BF1ED004-EA02-456A-AA55-2AC8AC6B054C}
	IID_ICOMTestFloat = NewGUID("{BF1ED004-EA02-456A-AA55-2AC8AC6B054C}")

	// IID_ICOMTestDouble is for ICOMTestDouble interfaces.
	//
	// {BF908A81-8687-4E93-999F-D86FAB284BA0}
	IID_ICOMTestDouble = NewGUID("{BF908A81-8687-4E93-999F-D86FAB284BA0}")

	// IID_ICOMTestBoolean is for ICOMTestBoolean interfaces.
	//
	// {D530E7A6-4EE8-40D1-8931-3D63B8605010}
	IID_ICOMTestBoolean = NewGUID("{D530E7A6-4EE8-40D1-8931-3D63B8605010}")

	// IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces.
	//
	// {6485B1EF-D780-4834-A4FE-1EBB51746CA3}
	IID_ICOMEchoTestObject = NewGUID("{6485B1EF-D780-4834-A4FE-1EBB51746CA3}")

	// IID_ICOMTestTypes is for ICOMTestTypes interfaces.
	//
	// {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}
	IID_ICOMTestTypes = NewGUID("{CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}")

	// CLSID_COMEchoTestObject is for COMEchoTestObject class.
	//
	// {3C24506A-AE9E-4D50-9157-EF317281F1B0}
	CLSID_COMEchoTestObject = NewGUID("{3C24506A-AE9E-4D50-9157-EF317281F1B0}")

	// CLSID_COMTestScalarClass is for COMTestScalarClass class.
	//
	// {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}
	CLSID_COMTestScalarClass = NewGUID("{865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}")
)

const hextable = "0123456789ABCDEF"
const emptyGUID = "{00000000-0000-0000-0000-000000000000}"

// GUID is Windows API specific GUID type.
//
// This exists to match Windows GUID type for direct passing for COM.
// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

// NewGUID converts the given string into a globally unique identifier that is
// compliant with the Windows API.
//
// The supplied string may be in any of these formats:
//
//  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//  XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
//  {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
//
// The conversion of the supplied string is not case-sensitive.
func NewGUID(guid string) *GUID {
	d := []byte(guid)
	var d1, d2, d3, d4a, d4b []byte

	switch len(d) {
	case 38:
		if d[0] != '{' || d[37] != '}' {
			return nil
		}
		d = d[1:37]
		fallthrough
	case 36:
		if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' {
			return nil
		}
		d1 = d[0:8]
		d2 = d[9:13]
		d3 = d[14:18]
		d4a = d[19:23]
		d4b = d[24:36]
	case 32:
		d1 = d[0:8]
		d2 = d[8:12]
		d3 = d[12:16]
		d4a = d[16:20]
		d4b = d[20:32]
	default:
		return nil
	}

	var g GUID
	var ok1, ok2, ok3, ok4 bool
	g.Data1, ok1 = decodeHexUint32(d1)
	g.Data2, ok2 = decodeHexUint16(d2)
	g.Data3, ok3 = decodeHexUint16(d3)
	g.Data4, ok4 = decodeHexByte64(d4a, d4b)
	if ok1 && ok2 && ok3 && ok4 {
		return &g
	}
	return nil
}

func decodeHexUint32(src []byte) (value uint32, ok bool) {
	var b1, b2, b3, b4 byte
	var ok1, ok2, ok3, ok4 bool
	b1, ok1 = decodeHexByte(src[0], src[1])
	b2, ok2 = decodeHexByte(src[2], src[3])
	b3, ok3 = decodeHexByte(src[4], src[5])
	b4, ok4 = decodeHexByte(src[6], src[7])
	value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4)
	ok = ok1 && ok2 && ok3 && ok4
	return
}

func decodeHexUint16(src []byte) (value uint16, ok bool) {
	var b1, b2 byte
	var ok1, ok2 bool
	b1, ok1 = decodeHexByte(src[0], src[1])
	b2, ok2 = decodeHexByte(src[2], src[3])
	value = (uint16(b1) << 8) | uint16(b2)
	ok = ok1 && ok2
	return
}

func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) {
	var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool
	value[0], ok1 = decodeHexByte(s1[0], s1[1])
	value[1], ok2 = decodeHexByte(s1[2], s1[3])
	value[2], ok3 = decodeHexByte(s2[0], s2[1])
	value[3], ok4 = decodeHexByte(s2[2], s2[3])
	value[4], ok5 = decodeHexByte(s2[4], s2[5])
	value[5], ok6 = decodeHexByte(s2[6], s2[7])
	value[6], ok7 = decodeHexByte(s2[8], s2[9])
	value[7], ok8 = decodeHexByte(s2[10], s2[11])
	ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8
	return
}

func decodeHexByte(c1, c2 byte) (value byte, ok bool) {
	var n1, n2 byte
	var ok1, ok2 bool
	n1, ok1 = decodeHexChar(c1)
	n2, ok2 = decodeHexChar(c2)
	value = (n1 << 4) | n2
	ok = ok1 && ok2
	return
}

func decodeHexChar(c byte) (byte, bool) {
	switch {
	case '0' <= c && c <= '9':
		return c - '0', true
	case 'a' <= c && c <= 'f':
		return c - 'a' + 10, true
	case 'A' <= c && c <= 'F':
		return c - 'A' + 10, true
	}

	return 0, false
}

// String converts the GUID to string form. It will adhere to this pattern:
//
//  {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
//
// If the GUID is nil, the string representation of an empty GUID is returned:
//
//  {00000000-0000-0000-0000-000000000000}
func (guid *GUID) String() string {
	if guid == nil {
		return emptyGUID
	}

	var c [38]byte
	c[0] = '{'
	putUint32Hex(c[1:9], guid.Data1)
	c[9] = '-'
	putUint16Hex(c[10:14], guid.Data2)
	c[14] = '-'
	putUint16Hex(c[15:19], guid.Data3)
	c[19] = '-'
	putByteHex(c[20:24], guid.Data4[0:2])
	c[24] = '-'
	putByteHex(c[25:37], guid.Data4[2:8])
	c[37] = '}'
	return string(c[:])
}

func putUint32Hex(b []byte, v uint32) {
	b[0] = hextable[byte(v>>24)>>4]
	b[1] = hextable[byte(v>>24)&0x0f]
	b[2] = hextable[byte(v>>16)>>4]
	b[3] = hextable[byte(v>>16)&0x0f]
	b[4] = hextable[byte(v>>8)>>4]
	b[5] = hextable[byte(v>>8)&0x0f]
	b[6] = hextable[byte(v)>>4]
	b[7] = hextable[byte(v)&0x0f]
}

func putUint16Hex(b []byte, v uint16) {
	b[0] = hextable[byte(v>>8)>>4]
	b[1] = hextable[byte(v>>8)&0x0f]
	b[2] = hextable[byte(v)>>4]
	b[3] = hextable[byte(v)&0x0f]
}

func putByteHex(dst, src []byte) {
	for i := 0; i < len(src); i++ {
		dst[i*2] = hextable[src[i]>>4]
		dst[i*2+1] = hextable[src[i]&0x0f]
	}
}

// IsEqualGUID compares two GUID.
//
// Not constant time comparison.
func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool {
	return guid1.Data1 == guid2.Data1 &&
		guid1.Data2 == guid2.Data2 &&
		guid1.Data3 == guid2.Data3 &&
		guid1.Data4[0] == guid2.Data4[0] &&
		guid1.Data4[1] == guid2.Data4[1] &&
		guid1.Data4[2] == guid2.Data4[2] &&
		guid1.Data4[3] == guid2.Data4[3] &&
		guid1.Data4[4] == guid2.Data4[4] &&
		guid1.Data4[5] == guid2.Data4[5] &&
		guid1.Data4[6] == guid2.Data4[6] &&
		guid1.Data4[7] == guid2.Data4[7]
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package hack

/*
Package imports dependencies required for "dep ensure" to fetch all of the go package dependencies needed
by kubebuilder commands to work without rerunning "dep ensure".

Example: make sure the testing libraries and apimachinery libraries are fetched by "dep ensure" so that
dep ensure doesn't need to be rerun after "kubebuilder create resource".

This is necessary for subsequent commands - such as building docs, tests, etc - to work without rerunning "dep ensure"
afterward.
*/
import _ "github.com/kubernetes-sigs/kubebuilder/pkg/imports"
<commit_msg>Move the package comments above package<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

/*
Package imports dependencies required for "dep ensure" to fetch all of the go package dependencies needed
by kubebuilder commands to work without rerunning "dep ensure".

Example: make sure the testing libraries and apimachinery libraries are fetched by "dep ensure" so that
dep ensure doesn't need to be rerun after "kubebuilder create resource".

This is necessary for subsequent commands - such as building docs, tests, etc - to work without rerunning "dep ensure"
afterward.
*/
package hack

import _ "github.com/kubernetes-sigs/kubebuilder/pkg/imports"
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"

	"github.com/apex/apex/function"
	"github.com/apex/apex/project"
	"github.com/apex/log"
	"github.com/apex/log/handlers/text"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/segmentio/go-prompt"
	"github.com/tj/docopt"
)

var version = "0.1.0"

const usage = `
  Usage:
    apex deploy [options] [<name>...]
    apex delete [options] [<name>...]
    apex invoke [options] <name> [--async] [-v]
    apex rollback [options] <name> [<version>]
    apex build [options] <name>
    apex list [options]
    apex -h | --help
    apex --version

  Options:
    -a, --async         Async invocation
    -C, --chdir path    Working directory
    -y, --yes           Automatic yes to prompts
    -h, --help          Output help information
    -v, --verbose       Output verbose logs
    -V, --version       Output version

  Examples:
    Deploy a function in the current directory
    $ apex deploy

    Delete a function in the current directory
    $ apex delete

    Invoke a function in the current directory
    $ apex invoke < request.json

    Rollback a function to the previous version (another call will go back to the latest version)
    $ apex rollback

    Rollback a function to the specified version (another call will go back to the latest version)
    $ apex rollback 3

    Deploy a function in a different directory
    $ apex deploy -C functions/hello-world

    Output zip of a function in the current directory
    $ apex build > /tmp/out.zip

    Tail Kinesis logs
    $ apex logs
`

func main() {
	args, err := docopt.Parse(usage, nil, true, version, false)
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	// TODO(tj): configurable level
	log.SetLevel(log.InfoLevel)
	log.SetHandler(text.New(os.Stderr))

	project := &project.Project{
		Service: lambda.New(session.New(aws.NewConfig())),
		Log:     log.Log,
		Path:    ".",
	}

	if dir, ok := args["--chdir"].(string); ok {
		if err := os.Chdir(dir); err != nil {
			log.Fatalf("error: %s", err)
		}
	}

	if err := project.Open(); err != nil {
		log.Fatalf("error opening project: %s", err)
	}

	switch {
	case args["list"].(bool):
		list(project)
	case args["deploy"].(bool):
		deploy(project, args["<name>"].([]string))
	case args["delete"].(bool):
		delete(project, args["<name>"].([]string), args["--yes"].(bool))
	case args["invoke"].(bool):
		invoke(project, args["<name>"].([]string), args["--verbose"].(bool), args["--async"].(bool))
	case args["rollback"].(bool):
		rollback(project, args["<name>"].([]string), args["<version>"])
	case args["build"].(bool):
		build(project, args["<name>"].([]string))
	}
}

// list functions.
func list(project *project.Project) {
	// TODO(tj): more informative output
	fmt.Println()
	for _, fn := range project.Functions {
		fmt.Printf("  - %s (%s)\n", fn.Name, fn.Runtime)
	}
	fmt.Println()
}

// invoke reads request json from stdin and outputs the responses.
func invoke(project *project.Project, name []string, verbose, async bool) {
	dec := json.NewDecoder(os.Stdin)
	kind := function.RequestResponse

	if async {
		kind = function.Event
	}

	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	for {
		var v struct {
			Event   interface{}
			Context interface{}
		}

		err := dec.Decode(&v)

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Fatalf("error: %s", err)
		}

		reply, logs, err := fn.Invoke(v.Event, v.Context, kind)
		if err != nil {
			log.Fatalf("error: %s", err)
		}

		// TODO(tj) rename flag to --with-logs or --logs
		if verbose {
			io.Copy(os.Stderr, logs)
		}

		io.Copy(os.Stdout, reply)
		fmt.Fprintf(os.Stdout, "\n")
	}
}

// deploy changes.
func deploy(project *project.Project, names []string) {
	var err error

	if len(names) == 0 {
		names, err = project.FunctionNames()
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if err := project.DeployAndClean(names); err != nil {
		log.Fatalf("error: %s", err)
	}
}

// delete the resources.
func delete(project *project.Project, names []string, force bool) {
	var err error

	if len(names) == 0 {
		names, err = project.FunctionNames()
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if !force && len(names) > 1 {
		fmt.Printf("The following will be deleted:\n\n")
		for _, name := range names {
			fmt.Printf("  - %s\n", name)
		}
		fmt.Printf("\n")
	}

	if !force && !prompt.Confirm("Are you sure? (yes/no)") {
		return
	}

	if err := project.Delete(names); err != nil {
		log.Fatalf("error: %s", err)
	}
}

// rollback the function.
func rollback(project *project.Project, name []string, version interface{}) {
	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if version == nil {
		err = fn.Rollback()
	} else {
		err = fn.Rollback(version.(string))
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}
}

// build outputs the generated archive to stdout.
func build(project *project.Project, name []string) {
	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	zip, err := fn.Zip()
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	_, err = io.Copy(os.Stdout, zip)
	if err != nil {
		log.Fatalf("error: %s", err)
	}
}
<commit_msg>add --log-level. Closes #42<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"

	"github.com/apex/apex/function"
	"github.com/apex/apex/project"
	"github.com/apex/log"
	"github.com/apex/log/handlers/text"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/segmentio/go-prompt"
	"github.com/tj/docopt"
)

var version = "0.1.0"

const usage = `
  Usage:
    apex deploy [options] [<name>...]
    apex delete [options] [<name>...]
    apex invoke [options] <name> [--async] [-v]
    apex rollback [options] <name> [<version>]
    apex build [options] <name>
    apex list [options]
    apex -h | --help
    apex --version

  Options:
    -l, --log-level level   Log severity level [default: info]
    -a, --async             Async invocation
    -C, --chdir path        Working directory
    -y, --yes               Automatic yes to prompts
    -h, --help              Output help information
    -v, --verbose           Output verbose logs
    -V, --version           Output version

  Examples:
    Deploy a function in the current directory
    $ apex deploy

    Delete a function in the current directory
    $ apex delete

    Invoke a function in the current directory
    $ apex invoke < request.json

    Rollback a function to the previous version (another call will go back to the latest version)
    $ apex rollback

    Rollback a function to the specified version (another call will go back to the latest version)
    $ apex rollback 3

    Deploy a function in a different directory
    $ apex deploy -C functions/hello-world

    Output zip of a function in the current directory
    $ apex build > /tmp/out.zip

    Tail Kinesis logs
    $ apex logs
`

func main() {
	args, err := docopt.Parse(usage, nil, true, version, false)
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	log.SetHandler(text.New(os.Stderr))

	if l, err := log.ParseLevel(args["--log-level"].(string)); err == nil {
		log.SetLevel(l)
	}

	project := &project.Project{
		Service: lambda.New(session.New(aws.NewConfig())),
		Log:     log.Log,
		Path:    ".",
	}

	if dir, ok := args["--chdir"].(string); ok {
		if err := os.Chdir(dir); err != nil {
			log.Fatalf("error: %s", err)
		}
	}

	if err := project.Open(); err != nil {
		log.Fatalf("error opening project: %s", err)
	}

	switch {
	case args["list"].(bool):
		list(project)
	case args["deploy"].(bool):
		deploy(project, args["<name>"].([]string))
	case args["delete"].(bool):
		delete(project, args["<name>"].([]string), args["--yes"].(bool))
	case args["invoke"].(bool):
		invoke(project, args["<name>"].([]string), args["--verbose"].(bool), args["--async"].(bool))
	case args["rollback"].(bool):
		rollback(project, args["<name>"].([]string), args["<version>"])
	case args["build"].(bool):
		build(project, args["<name>"].([]string))
	}
}

// list functions.
func list(project *project.Project) {
	// TODO(tj): more informative output
	fmt.Println()
	for _, fn := range project.Functions {
		fmt.Printf("  - %s (%s)\n", fn.Name, fn.Runtime)
	}
	fmt.Println()
}

// invoke reads request json from stdin and outputs the responses.
func invoke(project *project.Project, name []string, verbose, async bool) {
	dec := json.NewDecoder(os.Stdin)
	kind := function.RequestResponse

	if async {
		kind = function.Event
	}

	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	for {
		var v struct {
			Event   interface{}
			Context interface{}
		}

		err := dec.Decode(&v)

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Fatalf("error: %s", err)
		}

		reply, logs, err := fn.Invoke(v.Event, v.Context, kind)
		if err != nil {
			log.Fatalf("error: %s", err)
		}

		// TODO(tj) rename flag to --with-logs or --logs
		if verbose {
			io.Copy(os.Stderr, logs)
		}

		io.Copy(os.Stdout, reply)
		fmt.Fprintf(os.Stdout, "\n")
	}
}

// deploy changes.
func deploy(project *project.Project, names []string) {
	var err error

	if len(names) == 0 {
		names, err = project.FunctionNames()
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if err := project.DeployAndClean(names); err != nil {
		log.Fatalf("error: %s", err)
	}
}

// delete the resources.
func delete(project *project.Project, names []string, force bool) {
	var err error

	if len(names) == 0 {
		names, err = project.FunctionNames()
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if !force && len(names) > 1 {
		fmt.Printf("The following will be deleted:\n\n")
		for _, name := range names {
			fmt.Printf("  - %s\n", name)
		}
		fmt.Printf("\n")
	}

	if !force && !prompt.Confirm("Are you sure? (yes/no)") {
		return
	}

	if err := project.Delete(names); err != nil {
		log.Fatalf("error: %s", err)
	}
}

// rollback the function.
func rollback(project *project.Project, name []string, version interface{}) {
	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	if version == nil {
		err = fn.Rollback()
	} else {
		err = fn.Rollback(version.(string))
	}

	if err != nil {
		log.Fatalf("error: %s", err)
	}
}

// build outputs the generated archive to stdout.
func build(project *project.Project, name []string) {
	fn, err := project.FunctionByName(name[0])
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	zip, err := fn.Zip()
	if err != nil {
		log.Fatalf("error: %s", err)
	}

	_, err = io.Copy(os.Stdout, zip)
	if err != nil {
		log.Fatalf("error: %s", err)
	}
}
<|endoftext|>


<commit_before>/*
 * Minio Cloud Storage, (C) 2016 Minio, 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 cmd

import (
	"os"
	"sync"

	"github.com/minio/minio/pkg/quick"
)

// serverConfigV6 server configuration version '5'.
type serverConfigV6 struct {
	Version string `json:"version"`

	// S3 API configuration.
	Credential credential `json:"credential"`
	Region     string     `json:"region"`

	// Additional error logging configuration.
	Logger logger `json:"logger"`

	// Notification queue configuration.
	Notify notifier `json:"notify"`

	// Read Write mutex.
	rwMutex *sync.RWMutex
}

// initConfig - initialize server config. config version (called only once).
func initConfig() error {
	if !isConfigFileExists() {
		// Initialize server config.
		srvCfg := &serverConfigV6{}
		srvCfg.Version = globalMinioConfigVersion
		srvCfg.Region = "us-east-1"
		srvCfg.Credential = mustGenAccessKeys()

		// Enable console logger by default on a fresh run.
		srvCfg.Logger.Console = consoleLogger{
			Enable: true,
			Level:  "fatal",
		}
		srvCfg.rwMutex = &sync.RWMutex{}

		// Create config path.
		err := createConfigPath()
		if err != nil {
			return err
		}

		// Save the new config globally.
		serverConfig = srvCfg

		// Save config into file.
		return serverConfig.Save()
	}
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}
	if _, err = os.Stat(configFile); err != nil {
		return err
	}
	srvCfg := &serverConfigV6{}
	srvCfg.Version = globalMinioConfigVersion
	srvCfg.rwMutex = &sync.RWMutex{}
	qc, err := quick.New(srvCfg)
	if err != nil {
		return err
	}
	if err := qc.Load(configFile); err != nil {
		return err
	}
	// Save the loaded config globally.
	serverConfig = srvCfg
	// Set the version properly after the unmarshalled json is loaded.
	serverConfig.Version = globalMinioConfigVersion

	return nil
}

// serverConfig server config.
var serverConfig *serverConfigV6

// GetVersion get current config version.
func (s serverConfigV6) GetVersion() string {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Version
}

/// Logger related.

func (s *serverConfigV6) SetAMQPNotifyByID(accountID string, amqpn amqpNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.AMQP[accountID] = amqpn
}

func (s serverConfigV6) GetAMQP() map[string]amqpNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.AMQP
}

// GetAMQPNotify get current AMQP logger.
func (s serverConfigV6) GetAMQPNotifyByID(accountID string) amqpNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.AMQP[accountID]
}

func (s *serverConfigV6) SetElasticSearchNotifyByID(accountID string, esNotify elasticSearchNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.ElasticSearch[accountID] = esNotify
}

func (s serverConfigV6) GetElasticSearch() map[string]elasticSearchNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.ElasticSearch
}

// GetElasticSearchNotify get current ElasicSearch logger.
func (s serverConfigV6) GetElasticSearchNotifyByID(accountID string) elasticSearchNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.ElasticSearch[accountID]
}

func (s *serverConfigV6) SetRedisNotifyByID(accountID string, rNotify redisNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.Redis[accountID] = rNotify
}

func (s serverConfigV6) GetRedis() map[string]redisNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.Redis
}

// GetRedisNotify get current Redis logger.
func (s serverConfigV6) GetRedisNotifyByID(accountID string) redisNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.Redis[accountID]
}

// SetFileLogger set new file logger.
func (s *serverConfigV6) SetFileLogger(flogger fileLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.File = flogger
}

// GetFileLogger get current file logger.
func (s serverConfigV6) GetFileLogger() fileLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.File
}

// SetConsoleLogger set new console logger.
func (s *serverConfigV6) SetConsoleLogger(clogger consoleLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.Console = clogger
}

// GetConsoleLogger get current console logger.
func (s serverConfigV6) GetConsoleLogger() consoleLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.Console
}

// SetSyslogLogger set new syslog logger.
func (s *serverConfigV6) SetSyslogLogger(slogger syslogLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.Syslog = slogger
}

// GetSyslogLogger get current syslog logger.
func (s *serverConfigV6) GetSyslogLogger() syslogLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.Syslog
}

// SetRegion set new region.
func (s *serverConfigV6) SetRegion(region string) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Region = region
}

// GetRegion get current region.
func (s serverConfigV6) GetRegion() string {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Region
}

// SetCredentials set new credentials.
func (s *serverConfigV6) SetCredential(creds credential) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Credential = creds
}

// GetCredentials get current credentials.
func (s serverConfigV6) GetCredential() credential {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Credential
}

// Save config.
func (s serverConfigV6) Save() error {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()

	// get config file.
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}

	// initialize quick.
	qc, err := quick.New(&s)
	if err != nil {
		return err
	}

	// Save config file.
	return qc.Save(configFile)
}
<commit_msg>config: Initialize notify for fresh configs. (#2531)<commit_after>/*
 * Minio Cloud Storage, (C) 2016 Minio, 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 cmd

import (
	"os"
	"sync"

	"github.com/minio/minio/pkg/quick"
)

// serverConfigV6 server configuration version '5'.
type serverConfigV6 struct {
	Version string `json:"version"`

	// S3 API configuration.
	Credential credential `json:"credential"`
	Region     string     `json:"region"`

	// Additional error logging configuration.
	Logger logger `json:"logger"`

	// Notification queue configuration.
	Notify notifier `json:"notify"`

	// Read Write mutex.
	rwMutex *sync.RWMutex
}

// initConfig - initialize server config. config version (called only once).
func initConfig() error {
	if !isConfigFileExists() {
		// Initialize server config.
		srvCfg := &serverConfigV6{}
		srvCfg.Version = globalMinioConfigVersion
		srvCfg.Region = "us-east-1"
		srvCfg.Credential = mustGenAccessKeys()

		// Enable console logger by default on a fresh run.
		srvCfg.Logger.Console = consoleLogger{
			Enable: true,
			Level:  "fatal",
		}

		// Make sure to initialize notification configs.
		srvCfg.Notify.AMQP = make(map[string]amqpNotify)
		srvCfg.Notify.AMQP["1"] = amqpNotify{}
		srvCfg.Notify.ElasticSearch = make(map[string]elasticSearchNotify)
		srvCfg.Notify.ElasticSearch["1"] = elasticSearchNotify{}
		srvCfg.Notify.Redis = make(map[string]redisNotify)
		srvCfg.Notify.Redis["1"] = redisNotify{}
		srvCfg.rwMutex = &sync.RWMutex{}

		// Create config path.
		err := createConfigPath()
		if err != nil {
			return err
		}

		// Save the new config globally.
		serverConfig = srvCfg

		// Save config into file.
		return serverConfig.Save()
	}
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}
	if _, err = os.Stat(configFile); err != nil {
		return err
	}
	srvCfg := &serverConfigV6{}
	srvCfg.Version = globalMinioConfigVersion
	srvCfg.rwMutex = &sync.RWMutex{}
	qc, err := quick.New(srvCfg)
	if err != nil {
		return err
	}
	if err := qc.Load(configFile); err != nil {
		return err
	}
	// Save the loaded config globally.
	serverConfig = srvCfg
	// Set the version properly after the unmarshalled json is loaded.
	serverConfig.Version = globalMinioConfigVersion

	return nil
}

// serverConfig server config.
var serverConfig *serverConfigV6

// GetVersion get current config version.
func (s serverConfigV6) GetVersion() string {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Version
}

/// Logger related.

func (s *serverConfigV6) SetAMQPNotifyByID(accountID string, amqpn amqpNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.AMQP[accountID] = amqpn
}

func (s serverConfigV6) GetAMQP() map[string]amqpNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.AMQP
}

// GetAMQPNotify get current AMQP logger.
func (s serverConfigV6) GetAMQPNotifyByID(accountID string) amqpNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.AMQP[accountID]
}

func (s *serverConfigV6) SetElasticSearchNotifyByID(accountID string, esNotify elasticSearchNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.ElasticSearch[accountID] = esNotify
}

func (s serverConfigV6) GetElasticSearch() map[string]elasticSearchNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.ElasticSearch
}

// GetElasticSearchNotify get current ElasicSearch logger.
func (s serverConfigV6) GetElasticSearchNotifyByID(accountID string) elasticSearchNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.ElasticSearch[accountID]
}

func (s *serverConfigV6) SetRedisNotifyByID(accountID string, rNotify redisNotify) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Notify.Redis[accountID] = rNotify
}

func (s serverConfigV6) GetRedis() map[string]redisNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.Redis
}

// GetRedisNotify get current Redis logger.
func (s serverConfigV6) GetRedisNotifyByID(accountID string) redisNotify {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Notify.Redis[accountID]
}

// SetFileLogger set new file logger.
func (s *serverConfigV6) SetFileLogger(flogger fileLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.File = flogger
}

// GetFileLogger get current file logger.
func (s serverConfigV6) GetFileLogger() fileLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.File
}

// SetConsoleLogger set new console logger.
func (s *serverConfigV6) SetConsoleLogger(clogger consoleLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.Console = clogger
}

// GetConsoleLogger get current console logger.
func (s serverConfigV6) GetConsoleLogger() consoleLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.Console
}

// SetSyslogLogger set new syslog logger.
func (s *serverConfigV6) SetSyslogLogger(slogger syslogLogger) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Logger.Syslog = slogger
}

// GetSyslogLogger get current syslog logger.
func (s *serverConfigV6) GetSyslogLogger() syslogLogger {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Logger.Syslog
}

// SetRegion set new region.
func (s *serverConfigV6) SetRegion(region string) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Region = region
}

// GetRegion get current region.
func (s serverConfigV6) GetRegion() string {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Region
}

// SetCredentials set new credentials.
func (s *serverConfigV6) SetCredential(creds credential) {
	s.rwMutex.Lock()
	defer s.rwMutex.Unlock()
	s.Credential = creds
}

// GetCredentials get current credentials.
func (s serverConfigV6) GetCredential() credential {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()
	return s.Credential
}

// Save config.
func (s serverConfigV6) Save() error {
	s.rwMutex.RLock()
	defer s.rwMutex.RUnlock()

	// get config file.
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}

	// initialize quick.
	qc, err := quick.New(&s)
	if err != nil {
		return err
	}

	// Save config file.
	return qc.Save(configFile)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/exoscale/egoscale"
)

type cmd struct {
	command egoscale.Command
	hidden  bool
}

var methods = map[string][]cmd{
	"network": {
		{&egoscale.CreateNetwork{}, false},
		{&egoscale.DeleteNetwork{}, false},
		{&egoscale.ListNetworkOfferings{}, false},
		{&egoscale.ListNetworks{}, false},
		{&egoscale.RestartNetwork{}, true},
		{&egoscale.UpdateNetwork{}, false},
	},
	"virtual machine": {
		{&egoscale.AddNicToVirtualMachine{}, false},
		{&egoscale.ChangeServiceForVirtualMachine{}, false},
		{&egoscale.DeployVirtualMachine{}, false},
		{&egoscale.DestroyVirtualMachine{}, false},
		{&egoscale.ExpungeVirtualMachine{}, false},
		{&egoscale.GetVMPassword{}, false},
		{&egoscale.GetVirtualMachineUserData{}, false},
		{&egoscale.ListVirtualMachines{}, false},
		{&egoscale.MigrateVirtualMachine{}, true},
		{&egoscale.RebootVirtualMachine{}, false},
		{&egoscale.RecoverVirtualMachine{}, false},
		{&egoscale.RemoveNicFromVirtualMachine{}, false},
		{&egoscale.ResetPasswordForVirtualMachine{}, false},
		{&egoscale.RestoreVirtualMachine{}, false},
		{&egoscale.ScaleVirtualMachine{}, false},
		{&egoscale.StartVirtualMachine{}, false},
		{&egoscale.StopVirtualMachine{}, false},
		{&egoscale.UpdateDefaultNicForVirtualMachine{}, true},
		{&egoscale.UpdateVirtualMachine{}, false},
		{&egoscale.UpdateVMNicIP{}, false},
	},
	"volume": {
		{&egoscale.ListVolumes{}, false},
		{&egoscale.ResizeVolume{}, false},
	},
	"template": {
		{&egoscale.CopyTemplate{}, true},
		{&egoscale.CreateTemplate{}, true},
		{&egoscale.ListTemplates{}, false},
		{&egoscale.PrepareTemplate{}, true},
		{&egoscale.RegisterTemplate{}, true},
		{&egoscale.ListOSCategories{}, true},
	},
	"account": {
		{&egoscale.EnableAccount{}, true},
		{&egoscale.DisableAccount{}, true},
		{&egoscale.ListAccounts{}, false},
	},
	"zone": {
		{&egoscale.ListZones{}, false},
	},
	"snapshot": {
		{&egoscale.CreateSnapshot{}, false},
		{&egoscale.DeleteSnapshot{}, false},
		{&egoscale.ListSnapshots{}, false},
		{&egoscale.RevertSnapshot{}, false},
	},
	"user": {
		{&egoscale.CreateUser{}, true},
		{&egoscale.DeleteUser{}, true},
		//{&egoscale.DisableUser{}, true},
		//{&egoscale.GetUser{}, true},
		{&egoscale.UpdateUser{}, true},
		{&egoscale.ListUsers{}, false},
		{&egoscale.RegisterUserKeys{}, false},
	},
	"security group": {
		{&egoscale.AuthorizeSecurityGroupEgress{}, false},
		{&egoscale.AuthorizeSecurityGroupIngress{}, false},
		{&egoscale.CreateSecurityGroup{}, false},
		{&egoscale.DeleteSecurityGroup{}, false},
		{&egoscale.ListSecurityGroups{}, false},
		{&egoscale.RevokeSecurityGroupEgress{}, false},
		{&egoscale.RevokeSecurityGroupIngress{}, false},
	},
	"ssh": {
		{&egoscale.RegisterSSHKeyPair{}, false},
		{&egoscale.ListSSHKeyPairs{}, false},
		{&egoscale.CreateSSHKeyPair{}, false},
		{&egoscale.DeleteSSHKeyPair{}, false},
		{&egoscale.ResetSSHKeyForVirtualMachine{}, false},
	},
	"affinity group": {
		{&egoscale.CreateAffinityGroup{}, false},
		{&egoscale.DeleteAffinityGroup{}, false},
		{&egoscale.ListAffinityGroups{}, false},
		{&egoscale.UpdateVMAffinityGroup{}, false},
	},
	"vm group": {
		{&egoscale.CreateInstanceGroup{}, false},
		{&egoscale.ListInstanceGroups{}, false},
	},
	"tags": {
		{&egoscale.CreateTags{}, false},
		{&egoscale.DeleteTags{}, false},
		{&egoscale.ListTags{}, false},
	},
	"nic": {
		{&egoscale.ActivateIP6{}, false},
		{&egoscale.AddIPToNic{}, false},
		{&egoscale.ListNics{}, false},
		{&egoscale.RemoveIPFromNic{}, false},
	},
	"address": {
		{&egoscale.AssociateIPAddress{}, false},
		{&egoscale.DisassociateIPAddress{}, false},
		{&egoscale.ListPublicIPAddresses{}, false},
		{&egoscale.UpdateIPAddress{}, false},
	},
	"async job": {
		{&egoscale.QueryAsyncJobResult{}, false},
		{&egoscale.ListAsyncJobs{}, false},
	},
	"apis": {
		{&egoscale.ListAPIs{}, false},
	},
	"event": {
		{&egoscale.ListEventTypes{}, false},
		{&egoscale.ListEvents{}, false},
	},
	"offerings": {
		{&egoscale.ListResourceDetails{}, false},
		{&egoscale.ListResourceLimits{}, false},
		{&egoscale.ListServiceOfferings{}, false},
	},
	"host": {
		{&egoscale.ListHosts{}, true},
		{&egoscale.UpdateHost{}, true},
	},
	"reversedns": {
		{&egoscale.DeleteReverseDNSFromPublicIPAddress{}, false},
		{&egoscale.QueryReverseDNSForPublicIPAddress{}, false},
		{&egoscale.UpdateReverseDNSForPublicIPAddress{}, false},
		{&egoscale.DeleteReverseDNSFromVirtualMachine{}, false},
		{&egoscale.QueryReverseDNSForVirtualMachine{}, false},
		{&egoscale.UpdateReverseDNSForVirtualMachine{}, false},
	},
}
<commit_msg>cs: add missing vm-group calls (#349)<commit_after>package main

import (
	"github.com/exoscale/egoscale"
)

type cmd struct {
	command egoscale.Command
	hidden  bool
}

var methods = map[string][]cmd{
	"network": {
		{&egoscale.CreateNetwork{}, false},
		{&egoscale.DeleteNetwork{}, false},
		{&egoscale.ListNetworkOfferings{}, false},
		{&egoscale.ListNetworks{}, false},
		{&egoscale.RestartNetwork{}, true},
		{&egoscale.UpdateNetwork{}, false},
	},
	"virtual machine": {
		{&egoscale.AddNicToVirtualMachine{}, false},
		{&egoscale.ChangeServiceForVirtualMachine{}, false},
		{&egoscale.DeployVirtualMachine{}, false},
		{&egoscale.DestroyVirtualMachine{}, false},
		{&egoscale.ExpungeVirtualMachine{}, false},
		{&egoscale.GetVMPassword{}, false},
		{&egoscale.GetVirtualMachineUserData{}, false},
		{&egoscale.ListVirtualMachines{}, false},
		{&egoscale.MigrateVirtualMachine{}, true},
		{&egoscale.RebootVirtualMachine{}, false},
		{&egoscale.RecoverVirtualMachine{}, false},
		{&egoscale.RemoveNicFromVirtualMachine{}, false},
		{&egoscale.ResetPasswordForVirtualMachine{}, false},
		{&egoscale.RestoreVirtualMachine{}, false},
		{&egoscale.ScaleVirtualMachine{}, false},
		{&egoscale.StartVirtualMachine{}, false},
		{&egoscale.StopVirtualMachine{}, false},
		{&egoscale.UpdateDefaultNicForVirtualMachine{}, true},
		{&egoscale.UpdateVirtualMachine{}, false},
		{&egoscale.UpdateVMNicIP{}, false},
	},
	"volume": {
		{&egoscale.ListVolumes{}, false},
		{&egoscale.ResizeVolume{}, false},
	},
	"template": {
		{&egoscale.CopyTemplate{}, true},
		{&egoscale.CreateTemplate{}, true},
		{&egoscale.ListTemplates{}, false},
		{&egoscale.PrepareTemplate{}, true},
		{&egoscale.RegisterTemplate{}, true},
		{&egoscale.ListOSCategories{}, true},
	},
	"account": {
		{&egoscale.EnableAccount{}, true},
		{&egoscale.DisableAccount{}, true},
		{&egoscale.ListAccounts{}, false},
	},
	"zone": {
		{&egoscale.ListZones{}, false},
	},
	"snapshot": {
		{&egoscale.CreateSnapshot{}, false},
		{&egoscale.DeleteSnapshot{}, false},
		{&egoscale.ListSnapshots{}, false},
		{&egoscale.RevertSnapshot{}, false},
	},
	"user": {
		{&egoscale.CreateUser{}, true},
		{&egoscale.DeleteUser{}, true},
		//{&egoscale.DisableUser{}, true},
		//{&egoscale.GetUser{}, true},
		{&egoscale.UpdateUser{}, true},
		{&egoscale.ListUsers{}, false},
		{&egoscale.RegisterUserKeys{}, false},
	},
	"security group": {
		{&egoscale.AuthorizeSecurityGroupEgress{}, false},
		{&egoscale.AuthorizeSecurityGroupIngress{}, false},
		{&egoscale.CreateSecurityGroup{}, false},
		{&egoscale.DeleteSecurityGroup{}, false},
		{&egoscale.ListSecurityGroups{}, false},
		{&egoscale.RevokeSecurityGroupEgress{}, false},
		{&egoscale.RevokeSecurityGroupIngress{}, false},
	},
	"ssh": {
		{&egoscale.RegisterSSHKeyPair{}, false},
		{&egoscale.ListSSHKeyPairs{}, false},
		{&egoscale.CreateSSHKeyPair{}, false},
		{&egoscale.DeleteSSHKeyPair{}, false},
		{&egoscale.ResetSSHKeyForVirtualMachine{}, false},
	},
	"affinity group": {
		{&egoscale.CreateAffinityGroup{}, false},
		{&egoscale.DeleteAffinityGroup{}, false},
		{&egoscale.ListAffinityGroups{}, false},
		{&egoscale.UpdateVMAffinityGroup{}, false},
	},
	"vm group": {
		{&egoscale.CreateInstanceGroup{}, false},
		{&egoscale.DeleteInstanceGroup{}, false},
		{&egoscale.ListInstanceGroups{}, false},
		{&egoscale.UpdateInstanceGroup{}, false},
	},
	"tags": {
		{&egoscale.CreateTags{}, false},
		{&egoscale.DeleteTags{}, false},
		{&egoscale.ListTags{}, false},
	},
	"nic": {
		{&egoscale.ActivateIP6{}, false},
		{&egoscale.AddIPToNic{}, false},
		{&egoscale.ListNics{}, false},
		{&egoscale.RemoveIPFromNic{}, false},
	},
	"address": {
		{&egoscale.AssociateIPAddress{}, false},
		{&egoscale.DisassociateIPAddress{}, false},
		{&egoscale.ListPublicIPAddresses{}, false},
		{&egoscale.UpdateIPAddress{}, false},
	},
	"async job": {
		{&egoscale.QueryAsyncJobResult{}, false},
		{&egoscale.ListAsyncJobs{}, false},
	},
	"apis": {
		{&egoscale.ListAPIs{}, false},
	},
	"event": {
		{&egoscale.ListEventTypes{}, false},
		{&egoscale.ListEvents{}, false},
	},
	"offerings": {
		{&egoscale.ListResourceDetails{}, false},
		{&egoscale.ListResourceLimits{}, false},
		{&egoscale.ListServiceOfferings{}, false},
	},
	"host": {
		{&egoscale.ListHosts{}, true},
		{&egoscale.UpdateHost{}, true},
	},
	"reversedns": {
		{&egoscale.DeleteReverseDNSFromPublicIPAddress{}, false},
		{&egoscale.QueryReverseDNSForPublicIPAddress{}, false},
		{&egoscale.UpdateReverseDNSForPublicIPAddress{}, false},
		{&egoscale.DeleteReverseDNSFromVirtualMachine{}, false},
		{&egoscale.QueryReverseDNSForVirtualMachine{}, false},
		{&egoscale.UpdateReverseDNSForVirtualMachine{}, false},
	},
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/aelsabbahy/goss"
	"github.com/aelsabbahy/goss/outputs"
	"github.com/urfave/cli"
	//"time"
)

var version string

func main() {
	startTime := time.Now()
	app := cli.NewApp()
	app.EnableBashCompletion = true
	app.Version = version
	app.Name = "goss"
	app.Usage = "Quick and Easy server validation"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "gossfile, g",
			Value:  "./goss.yaml",
			Usage:  "Goss file to read from / write to",
			EnvVar: "GOSS_FILE",
		},
		cli.StringFlag{
			Name:   "vars",
			Usage:  "json/yaml file containing variables for template",
			EnvVar: "GOSS_VARS",
		},
		cli.StringFlag{
			Name:  "package",
			Usage: "Package type to use [rpm, deb, apk, pacman]",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "validate",
			Aliases: []string{"v"},
			Usage:   "Validate system",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:   "format, f",
					Value:  "rspecish",
					Usage:  fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()),
					EnvVar: "GOSS_FMT",
				},
				cli.StringSliceFlag{
					Name:   "format-options, o",
					Usage:  fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()),
					EnvVar: "GOSS_FMT_OPTIONS",
				},
				cli.BoolFlag{
					Name:   "color",
					Usage:  "Force color on",
					EnvVar: "GOSS_COLOR",
				},
				cli.BoolFlag{
					Name:   "no-color",
					Usage:  "Force color off",
					EnvVar: "GOSS_NOCOLOR",
				},
				cli.DurationFlag{
					Name:   "sleep,s",
					Usage:  "Time to sleep between retries, only active when -r is set",
					Value:  1 * time.Second,
					EnvVar: "GOSS_SLEEP",
				},
				cli.DurationFlag{
					Name:   "retry-timeout,r",
					Usage:  "Retry on failure so long as elapsed + sleep time is less than this",
					Value:  0,
					EnvVar: "GOSS_RETRY_TIMEOUT",
				},
				cli.IntFlag{
					Name:   "max-concurrent",
					Usage:  "Max number of tests to run concurrently",
					Value:  50,
					EnvVar: "GOSS_MAX_CONCURRENT",
				},
			},
			Action: func(c *cli.Context) error {
				goss.Validate(c, startTime)
				return nil
			},
		},
		{
			Name:    "serve",
			Aliases: []string{"s"},
			Usage:   "Serve a health endpoint",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:   "format, f",
					Value:  "rspecish",
					Usage:  fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()),
					EnvVar: "GOSS_FMT",
				},
				cli.StringSliceFlag{
					Name:   "format-options, o",
					Usage:  fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()),
					EnvVar: "GOSS_FMT_OPTIONS",
				},
				cli.DurationFlag{
					Name:   "cache,c",
					Usage:  "Time to cache the results",
					Value:  5 * time.Second,
					EnvVar: "GOSS_CACHE",
				},
				cli.StringFlag{
					Name:   "listen-addr,l",
					Value:  ":8080",
					Usage:  "Address to listen on [ip]:port",
					EnvVar: "GOSS_LISTEN",
				},
				cli.StringFlag{
					Name:   "endpoint,e",
					Value:  "/healthz",
					Usage:  "Endpoint to expose",
					EnvVar: "GOSS_ENDPOINT",
				},
				cli.IntFlag{
					Name:   "max-concurrent",
					Usage:  "Max number of tests to run concurrently",
					Value:  50,
					EnvVar: "GOSS_MAX_CONCURRENT",
				},
			},
			Action: func(c *cli.Context) error {
				goss.Serve(c)
				return nil
			},
		},
		{
			Name:    "render",
			Aliases: []string{"r"},
			Usage:   "render gossfile after imports",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "debug, d",
					Usage: fmt.Sprintf("Print debugging info when rendering"),
				},
			},
			Action: func(c *cli.Context) error {
				fmt.Print(goss.RenderJSON(c))
				return nil
			},
		},
		{
			Name:    "autoadd",
			Aliases: []string{"aa"},
			Usage:   "automatically add all matching resource to the test suite",
			Action: func(c *cli.Context) error {
				goss.AutoAddResources(c.GlobalString("gossfile"), c.Args(), c)
				return nil
			},
		},
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "add a resource to the test suite",
			Flags: []cli.Flag{
				cli.StringSliceFlag{
					Name:  "exclude-attr",
					Usage: "Exclude the following attributes when adding a new resource",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:  "package",
					Usage: "add new package",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Package", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "file",
					Usage: "add new file",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "File", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "addr",
					Usage: "add new remote address:port - ex: google.com:80",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 500 * time.Millisecond,
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Addr", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "port",
					Usage: "add new listening [protocol]:port - ex: 80 or udp:123",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Port", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "service",
					Usage: "add new service",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Service", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "user",
					Usage: "add new user",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "User", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "group",
					Usage: "add new group",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Group", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "command",
					Usage: "add new command",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 10 * time.Second,
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Command", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "dns",
					Usage: "add new dns",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 500 * time.Millisecond,
						},
						cli.StringFlag{
							Name:  "server",
							Usage: "The IP address of a DNS server to query",
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "DNS", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "process",
					Usage: "add new process name",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Process", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "http",
					Usage: "add new http",
					Flags: []cli.Flag{
						cli.BoolFlag{
							Name: "insecure, k",
						},
						cli.BoolFlag{
							Name: "no-follow-redirects, r",
						},
						cli.DurationFlag{
							Name:  "timeout",
							Value: 5 * time.Second,
						},
						cli.StringFlag{
							Name: "username, u",
							Usage: "Username for basic auth",
						},
						cli.StringFlag{
							Name: "password, p",
							Usage: "Password for basic auth",
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "HTTP", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "goss",
					Usage: "add new goss file, it will be imported from this one",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Gossfile", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "kernel-param",
					Usage: "add new goss kernel param",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "KernelParam", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "mount",
					Usage: "add new mount",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Mount", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "interface",
					Usage: "add new interface",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Interface", c.Args(), c)
						return nil
					},
				},
			},
		},
	}

	app.Run(os.Args)

}
<commit_msg>Handle invalid CLI flags (#421)<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/aelsabbahy/goss"
	"github.com/aelsabbahy/goss/outputs"
	"github.com/urfave/cli"
	//"time"
)

var version string

func main() {
	startTime := time.Now()
	app := cli.NewApp()
	app.EnableBashCompletion = true
	app.Version = version
	app.Name = "goss"
	app.Usage = "Quick and Easy server validation"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "gossfile, g",
			Value:  "./goss.yaml",
			Usage:  "Goss file to read from / write to",
			EnvVar: "GOSS_FILE",
		},
		cli.StringFlag{
			Name:   "vars",
			Usage:  "json/yaml file containing variables for template",
			EnvVar: "GOSS_VARS",
		},
		cli.StringFlag{
			Name:  "package",
			Usage: "Package type to use [rpm, deb, apk, pacman]",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "validate",
			Aliases: []string{"v"},
			Usage:   "Validate system",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:   "format, f",
					Value:  "rspecish",
					Usage:  fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()),
					EnvVar: "GOSS_FMT",
				},
				cli.StringSliceFlag{
					Name:   "format-options, o",
					Usage:  fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()),
					EnvVar: "GOSS_FMT_OPTIONS",
				},
				cli.BoolFlag{
					Name:   "color",
					Usage:  "Force color on",
					EnvVar: "GOSS_COLOR",
				},
				cli.BoolFlag{
					Name:   "no-color",
					Usage:  "Force color off",
					EnvVar: "GOSS_NOCOLOR",
				},
				cli.DurationFlag{
					Name:   "sleep,s",
					Usage:  "Time to sleep between retries, only active when -r is set",
					Value:  1 * time.Second,
					EnvVar: "GOSS_SLEEP",
				},
				cli.DurationFlag{
					Name:   "retry-timeout,r",
					Usage:  "Retry on failure so long as elapsed + sleep time is less than this",
					Value:  0,
					EnvVar: "GOSS_RETRY_TIMEOUT",
				},
				cli.IntFlag{
					Name:   "max-concurrent",
					Usage:  "Max number of tests to run concurrently",
					Value:  50,
					EnvVar: "GOSS_MAX_CONCURRENT",
				},
			},
			Action: func(c *cli.Context) error {
				goss.Validate(c, startTime)
				return nil
			},
		},
		{
			Name:    "serve",
			Aliases: []string{"s"},
			Usage:   "Serve a health endpoint",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:   "format, f",
					Value:  "rspecish",
					Usage:  fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()),
					EnvVar: "GOSS_FMT",
				},
				cli.StringSliceFlag{
					Name:   "format-options, o",
					Usage:  fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()),
					EnvVar: "GOSS_FMT_OPTIONS",
				},
				cli.DurationFlag{
					Name:   "cache,c",
					Usage:  "Time to cache the results",
					Value:  5 * time.Second,
					EnvVar: "GOSS_CACHE",
				},
				cli.StringFlag{
					Name:   "listen-addr,l",
					Value:  ":8080",
					Usage:  "Address to listen on [ip]:port",
					EnvVar: "GOSS_LISTEN",
				},
				cli.StringFlag{
					Name:   "endpoint,e",
					Value:  "/healthz",
					Usage:  "Endpoint to expose",
					EnvVar: "GOSS_ENDPOINT",
				},
				cli.IntFlag{
					Name:   "max-concurrent",
					Usage:  "Max number of tests to run concurrently",
					Value:  50,
					EnvVar: "GOSS_MAX_CONCURRENT",
				},
			},
			Action: func(c *cli.Context) error {
				goss.Serve(c)
				return nil
			},
		},
		{
			Name:    "render",
			Aliases: []string{"r"},
			Usage:   "render gossfile after imports",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "debug, d",
					Usage: fmt.Sprintf("Print debugging info when rendering"),
				},
			},
			Action: func(c *cli.Context) error {
				fmt.Print(goss.RenderJSON(c))
				return nil
			},
		},
		{
			Name:    "autoadd",
			Aliases: []string{"aa"},
			Usage:   "automatically add all matching resource to the test suite",
			Action: func(c *cli.Context) error {
				goss.AutoAddResources(c.GlobalString("gossfile"), c.Args(), c)
				return nil
			},
		},
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "add a resource to the test suite",
			Flags: []cli.Flag{
				cli.StringSliceFlag{
					Name:  "exclude-attr",
					Usage: "Exclude the following attributes when adding a new resource",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:  "package",
					Usage: "add new package",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Package", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "file",
					Usage: "add new file",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "File", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "addr",
					Usage: "add new remote address:port - ex: google.com:80",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 500 * time.Millisecond,
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Addr", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "port",
					Usage: "add new listening [protocol]:port - ex: 80 or udp:123",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Port", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "service",
					Usage: "add new service",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Service", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "user",
					Usage: "add new user",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "User", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "group",
					Usage: "add new group",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Group", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "command",
					Usage: "add new command",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 10 * time.Second,
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Command", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "dns",
					Usage: "add new dns",
					Flags: []cli.Flag{
						cli.DurationFlag{
							Name:  "timeout",
							Value: 500 * time.Millisecond,
						},
						cli.StringFlag{
							Name:  "server",
							Usage: "The IP address of a DNS server to query",
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "DNS", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "process",
					Usage: "add new process name",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Process", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "http",
					Usage: "add new http",
					Flags: []cli.Flag{
						cli.BoolFlag{
							Name: "insecure, k",
						},
						cli.BoolFlag{
							Name: "no-follow-redirects, r",
						},
						cli.DurationFlag{
							Name:  "timeout",
							Value: 5 * time.Second,
						},
						cli.StringFlag{
							Name:  "username, u",
							Usage: "Username for basic auth",
						},
						cli.StringFlag{
							Name:  "password, p",
							Usage: "Password for basic auth",
						},
					},
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "HTTP", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "goss",
					Usage: "add new goss file, it will be imported from this one",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Gossfile", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "kernel-param",
					Usage: "add new goss kernel param",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "KernelParam", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "mount",
					Usage: "add new mount",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Mount", c.Args(), c)
						return nil
					},
				},
				{
					Name:  "interface",
					Usage: "add new interface",
					Action: func(c *cli.Context) error {
						goss.AddResources(c.GlobalString("gossfile"), "Interface", c.Args(), c)
						return nil
					},
				},
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"os"
	"strings"

	"github.com/spf13/cobra"
	"google.golang.org/grpc"

	"k8s.io/helm/pkg/helm"
)

const (
	homeEnvVar = "HELM_HOME"
	hostEnvVar = "HELM_HOST"
)

var (
	helmHome        string
	tillerHost      string
	tillerNamespace string
)

// flagDebug is a signal that the user wants additional output.
var flagDebug bool

var globalUsage = `The Kubernetes package manager

To begin working with Helm, run the 'helm init' command:

	$ helm init

This will install Tiller to your running Kubernetes cluster.
It will also set up any necessary local configuration.

Common actions from this point include:

- helm search:    search for charts
- helm fetch:     download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

Environment:
  $HELM_HOME      Set an alternative location for Helm files. By default, these are stored in ~/.helm
  $HELM_HOST      Set an alternative Tiller host. The format is host:port (default ":44134").
`

// RootCommand is the top-level command for Helm.
var RootCommand = &cobra.Command{
	Use:               "helm",
	Short:             "The Helm package manager for Kubernetes.",
	Long:              globalUsage,
	PersistentPostRun: teardown,
}

func init() {
	home := os.Getenv(homeEnvVar)
	if home == "" {
		home = "$HOME/.helm"
	}
	thost := os.Getenv(hostEnvVar)
	p := RootCommand.PersistentFlags()
	p.StringVar(&helmHome, "home", home, "location of your Helm config. Overrides $HELM_HOME.")
	p.StringVar(&tillerHost, "host", thost, "address of tiller. Overrides $HELM_HOST.")
	p.StringVarP(&tillerNamespace, "namespace", "n", "", "kubernetes namespace")
	p.BoolVarP(&flagDebug, "debug", "", false, "enable verbose output")
}

func main() {
	if err := RootCommand.Execute(); err != nil {
		os.Exit(1)
	}
}

func setupConnection(c *cobra.Command, args []string) error {
	if tillerHost == "" {
		tunnel, err := newTillerPortForwarder(tillerNamespace)
		if err != nil {
			return err
		}

		tillerHost = fmt.Sprintf(":%d", tunnel.Local)
		if flagDebug {
			fmt.Printf("Created tunnel using local port: '%d'\n", tunnel.Local)
		}
	}

	// Set up the gRPC config.
	helm.Config.ServAddr = tillerHost
	if flagDebug {
		fmt.Printf("Server: %q\n", helm.Config.ServAddr)
	}
	return nil
}

func teardown(c *cobra.Command, args []string) {
	if tunnel != nil {
		tunnel.Close()
	}
}

func checkArgsLength(expectedNum, actualNum int, requiredArgs ...string) error {
	if actualNum != expectedNum {
		arg := "arguments"
		if expectedNum == 1 {
			arg = "argument"
		}
		return fmt.Errorf("This command needs %v %s: %s", expectedNum, arg, strings.Join(requiredArgs, ", "))
	}
	return nil
}

// requireInit is a PreRunE implementation for validating that $HELM_HOME is configured.
func requireInit(cmd *cobra.Command, args []string) error {
	err := requireHome()
	if err != nil {
		return fmt.Errorf("%s (try running 'helm init')", err)
	}
	return nil
}

// prettyError unwraps or rewrites certain errors to make them more user-friendly.
func prettyError(err error) error {
	// This is ridiculous. Why is 'grpc.rpcError' not exported? The least they
	// could do is throw an interface on the lib that would let us get back
	// the desc. Instead, we have to pass ALL errors through this.
	return errors.New(grpc.ErrorDesc(err))
}
<commit_msg>fix(cli): resolve flag name conflict<commit_after>package main

import (
	"errors"
	"fmt"
	"os"
	"strings"

	"github.com/spf13/cobra"
	"google.golang.org/grpc"

	"k8s.io/helm/pkg/helm"
)

const (
	homeEnvVar = "HELM_HOME"
	hostEnvVar = "HELM_HOST"
)

var (
	helmHome        string
	tillerHost      string
	tillerNamespace string
)

// flagDebug is a signal that the user wants additional output.
var flagDebug bool

var globalUsage = `The Kubernetes package manager

To begin working with Helm, run the 'helm init' command:

	$ helm init

This will install Tiller to your running Kubernetes cluster.
It will also set up any necessary local configuration.

Common actions from this point include:

- helm search:    search for charts
- helm fetch:     download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

Environment:
  $HELM_HOME      Set an alternative location for Helm files. By default, these are stored in ~/.helm
  $HELM_HOST      Set an alternative Tiller host. The format is host:port (default ":44134").
`

// RootCommand is the top-level command for Helm.
var RootCommand = &cobra.Command{
	Use:               "helm",
	Short:             "The Helm package manager for Kubernetes.",
	Long:              globalUsage,
	PersistentPostRun: teardown,
}

func init() {
	home := os.Getenv(homeEnvVar)
	if home == "" {
		home = "$HOME/.helm"
	}
	thost := os.Getenv(hostEnvVar)
	p := RootCommand.PersistentFlags()
	p.StringVar(&helmHome, "home", home, "location of your Helm config. Overrides $HELM_HOME.")
	p.StringVar(&tillerHost, "host", thost, "address of tiller. Overrides $HELM_HOST.")
	p.StringVarP(&tillerNamespace, "namespace", "", "", "kubernetes namespace")
	p.BoolVarP(&flagDebug, "debug", "", false, "enable verbose output")
}

func main() {
	if err := RootCommand.Execute(); err != nil {
		os.Exit(1)
	}
}

func setupConnection(c *cobra.Command, args []string) error {
	if tillerHost == "" {
		tunnel, err := newTillerPortForwarder(tillerNamespace)
		if err != nil {
			return err
		}

		tillerHost = fmt.Sprintf(":%d", tunnel.Local)
		if flagDebug {
			fmt.Printf("Created tunnel using local port: '%d'\n", tunnel.Local)
		}
	}

	// Set up the gRPC config.
	helm.Config.ServAddr = tillerHost
	if flagDebug {
		fmt.Printf("Server: %q\n", helm.Config.ServAddr)
	}
	return nil
}

func teardown(c *cobra.Command, args []string) {
	if tunnel != nil {
		tunnel.Close()
	}
}

func checkArgsLength(expectedNum, actualNum int, requiredArgs ...string) error {
	if actualNum != expectedNum {
		arg := "arguments"
		if expectedNum == 1 {
			arg = "argument"
		}
		return fmt.Errorf("This command needs %v %s: %s", expectedNum, arg, strings.Join(requiredArgs, ", "))
	}
	return nil
}

// requireInit is a PreRunE implementation for validating that $HELM_HOME is configured.
func requireInit(cmd *cobra.Command, args []string) error {
	err := requireHome()
	if err != nil {
		return fmt.Errorf("%s (try running 'helm init')", err)
	}
	return nil
}

// prettyError unwraps or rewrites certain errors to make them more user-friendly.
func prettyError(err error) error {
	// This is ridiculous. Why is 'grpc.rpcError' not exported? The least they
	// could do is throw an interface on the lib that would let us get back
	// the desc. Instead, we have to pass ALL errors through this.
	return errors.New(grpc.ErrorDesc(err))
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/go-ini/ini"
	"github.com/josselinauguste/libnotype/library"
	"os/user"
	"path"
)

func main() {
	usr, err := user.Current()
	if err != nil {
		fmt.Printf("%v\n", err)
	}
	configurationFile := path.Join(usr.HomeDir, ".libnotype")
	configuration, err := ini.Load(configurationFile)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(2)
	}
	libraryPath, err := configuration.Section("").GetKey("library_path")
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(3)
	}
	library := library.New(libraryPath.String())
	command, err := parseCommand(os.Args[1:])
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
	err = command(library)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(4)
	}
}

func parseCommand(args []string) (func(*library.Library) error, error) {
	if len(args) == 0 {
		return nil, errors.New("Missing command")
	}
	if args[0] == "add" {
		if len(args) > 1 {
			return func(library *library.Library) error {
				return library.AddBook(args[1])
			}, nil
		}
		return nil, errors.New("Missing <library> argument")
	}
	return nil, errors.New("Unknown command")
}
<commit_msg>Improve command readability<commit_after>package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/go-ini/ini"
	"github.com/josselinauguste/libnotype/library"
	"os/user"
	"path"
)

func main() {
	usr, err := user.Current()
	if err != nil {
		fmt.Printf("%v\n", err)
	}
	configurationFile := path.Join(usr.HomeDir, ".libnotype")
	configuration, err := ini.Load(configurationFile)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(2)
	}
	libraryPath, err := configuration.Section("").GetKey("library_path")
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(3)
	}
	library := library.New(libraryPath.String())
	command, err := parseCommand(os.Args[1:])
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
	err = command(library)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(4)
	}
}

func parseCommand(args []string) (func(*library.Library) error, error) {
	if len(args) == 0 {
		return nil, errors.New("Missing command")
	}
	if args[0] == "add" {
		if len(args) > 1 {
			return addBook(args[1]), nil
		}
		return nil, errors.New("Missing <library> argument")
	}
	return nil, errors.New("Unknown command")
}

func addBook(filePath string) func(*library.Library) error {
	return func(library *library.Library) error {
		return library.AddBook(filePath)
	}
}<|endoftext|>


<commit_before>//
package main

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

type room struct {
}

func newChatRoom() *room {
	return &room{}
}

func (r *room) hello(resp http.ResponseWriter, req *http.Request) {
	defer closeRequestBody(req)

	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var hello Hello
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&hello)

	if err != nil || hello.UserID == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	location := Location{
		Type:        "location",
		Name:        "chat room",
		Description: "a darkly lit room, there are people here, some are walking around, some are standing in groups",
	}
	welcome := Event{
		Type:     "event",
		Bookmark: time.Now().UTC().String(),
		Content: map[string]string{
			hello.UserID: "welcome",
			"*":          fmt.Sprintf("%s(%s) just enetered the room", hello.UserID, hello.Username),
		},
	}
	array := []interface{}{location, welcome}
	b, err := json.Marshal(&array)
	raw := json.RawMessage(b)
	body, err := json.Marshal(&Response{
		Destination: "player",
		Recipient:   hello.UserID,
		Payload:     &raw,
	})
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}

func (r *room) goodbye(resp http.ResponseWriter, req *http.Request) {
	defer closeRequestBody(req)

	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var bye Goodbye
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&bye)
	if err != nil || bye.UserID == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	body, err := json.Marshal(&Response{
		Destination: "player",
		Recipient:   bye.UserID,
		// Payload is array of JSON raw messages (location, event announcing user departure and sending
		// "farewell and thanks for all the fish" to user)
	})

	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}

func (r *room) message(resp http.ResponseWriter, req *http.Request) {
	defer closeRequestBody(req)

	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var message PlayerMessage
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&message)
	if err != nil || message.UserID == "" || message.Content == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	if message.Content[0] == '/' { // room command
		r.handleCommand(message, resp)

	} else {
		r.handleChat(message, resp)
	}
}

func (r *room) handleCommand(message PlayerMessage, resp http.ResponseWriter) {
	words := strings.Fields(message.Content)
	command := strings.ToLower(words[0])

	var reply string

	switch command {
	case "/examine":
		reply = "Shouldn't you be mingling?"
	case "/go":
		reply = "Sorry to see you go..."
	case "/inventory":
		reply = "There is nothing here"
	case "/look":
		reply = "It's just a room"
	default:
		reply = fmt.Sprintf("Don't know how to %s", command[1:len(command)])
	}

	r.sendEvent(message.UserID, reply, resp)
}

func (r *room) handleChat(message PlayerMessage, resp http.ResponseWriter) {
	r.sendEvent("*", message.Content, resp)
}

func (r *room) sendEvent(recipient, message string, resp http.ResponseWriter) {
	event := Event{
		Type:     "event",
		Bookmark: time.Now().UTC().String(),
		Content: map[string]string{
			recipient: message,
		},
	}

	body, err := json.Marshal(&event)
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}
	raw := json.RawMessage(body)

	body, err = json.Marshal(&Response{
		Destination: "player",
		Recipient:   recipient,
		Payload:     &raw,
	})

	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}

func closeRequestBody(r *http.Request) {
	io.Copy(ioutil.Discard, r.Body)
	r.Body.Close()
}
<commit_msg>room service: remove redundant closeRequestBody()<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"
)

type room struct{}

func newChatRoom() *room {
	return &room{}
}

func (r *room) hello(resp http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var hello Hello
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&hello)

	if err != nil || hello.UserID == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	location := Location{
		Type:        "location",
		Name:        "chat room",
		Description: "a darkly lit room, there are people here, some are walking around, some are standing in groups",
	}
	welcome := Event{
		Type:     "event",
		Bookmark: time.Now().UTC().String(),
		Content: map[string]string{
			hello.UserID: "welcome",
			"*":          fmt.Sprintf("%s(%s) just enetered the room", hello.UserID, hello.Username),
		},
	}
	array := []interface{}{location, welcome}
	b, err := json.Marshal(&array)
	raw := json.RawMessage(b)
	body, err := json.Marshal(&Response{
		Destination: "player",
		Recipient:   hello.UserID,
		Payload:     &raw,
	})
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}

func (r *room) goodbye(resp http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var bye Goodbye
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&bye)
	if err != nil || bye.UserID == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	body, err := json.Marshal(&Response{
		Destination: "player",
		Recipient:   bye.UserID,
		// Payload is array of JSON raw messages (location, event announcing user departure and sending
		// "farewell and thanks for all the fish" to user)
	})

	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}

func (r *room) message(resp http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		resp.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var message PlayerMessage
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&message)
	if err != nil || message.UserID == "" || message.Content == "" {
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	if message.Content[0] == '/' { // room command
		r.handleCommand(message, resp)

	} else {
		r.handleChat(message, resp)
	}
}

func (r *room) handleCommand(message PlayerMessage, resp http.ResponseWriter) {
	words := strings.Fields(message.Content)
	command := strings.ToLower(words[0])

	var reply string

	switch command {
	case "/examine":
		reply = "Shouldn't you be mingling?"
	case "/go":
		reply = "Sorry to see you go..."
	case "/inventory":
		reply = "There is nothing here"
	case "/look":
		reply = "It's just a room"
	default:
		reply = fmt.Sprintf("Don't know how to %s", command[1:len(command)])
	}

	r.sendEvent(message.UserID, reply, resp)
}

func (r *room) handleChat(message PlayerMessage, resp http.ResponseWriter) {
	r.sendEvent("*", message.Content, resp)
}

func (r *room) sendEvent(recipient, message string, resp http.ResponseWriter) {
	event := Event{
		Type:     "event",
		Bookmark: time.Now().UTC().String(),
		Content: map[string]string{
			recipient: message,
		},
	}

	body, err := json.Marshal(&event)
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}
	raw := json.RawMessage(body)

	body, err = json.Marshal(&Response{
		Destination: "player",
		Recipient:   recipient,
		Payload:     &raw,
	})

	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	resp.Write(body)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/url"
	"strings"
)

func init() {
	h := NewHandler()
	h.CommandName = "status"
	h.CommandPattern = "(status)( )(.*)"
	h.CommandParser = func(cmd *Command) map[string]string {
		argParts := strings.Split(cmd.Args, " ")
		m := make(map[string]string)
		m["scheme"] = "http"
		m["host"] = server.host
		m["port"] = server.port
		m["endpoint"] = "_status"
		if argParts[0] != "/" {
			m["index"] = argParts[0]
		}
		return m
	}
	h.HandlerFunc = func(cmd *Command) string {
		m := h.CommandParser(cmd)
		u := new(url.URL)
		u.Scheme = m["scheme"]
		u.Host = m["host"] + ":" + m["port"]
		index, ok := m["index"]
		if ok {
			index += "/"
		}
		u.Path = index + m["endpoint"]
		q := u.Query()
		q.Add("pretty", "true")
		u.RawQuery = q.Encode()
		fmt.Println("Request:", u)
		res, err := getHttpResource(u.String())
		if err != nil {
			return err.Error()
		}
		return res
	}
	HandlerRegistry[h.CommandName] = h
}
<commit_msg>Added usage.<commit_after>package main

import (
	"fmt"
	"net/url"
	"strings"
)

func init() {
	h := NewHandler()
	h.CommandName = "status"
	h.CommandPattern = "(status)( )(.*)"
	h.CommandParser = func(cmd *Command) (map[string]string, bool) {
		argParts := strings.Split(cmd.Args, " ")

		if len(argParts) == 0 {
			return nil, false
		}

		m := make(map[string]string)
		m["scheme"] = "http"
		m["host"] = server.host
		m["port"] = server.port
		m["endpoint"] = "_status"
		if argParts[0] != "/" {
			m["index"] = argParts[0]
		}
		return m, true
	}
	h.HandlerFunc = func(cmd *Command) string {
		m, ok := h.CommandParser(cmd)
		if !ok {
			return "Usage:"
		}
		u := new(url.URL)
		u.Scheme = m["scheme"]
		u.Host = m["host"] + ":" + m["port"]
		index, ok := m["index"]
		if ok {
			index += "/"
		}
		u.Path = index + m["endpoint"]
		q := u.Query()
		q.Add("pretty", "true")
		u.RawQuery = q.Encode()
		fmt.Println("Request:", u)
		res, err := getHttpResource(u.String())
		if err != nil {
			return err.Error()
		}
		return res
	}
	HandlerRegistry[h.CommandName] = h
}
<|endoftext|>