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

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file implements the symbol table.

package golisp

import (
	"container/list"
	"errors"
	"fmt"
	"sync"
	"sync/atomic"
)

const (
	READ_LOCK = iota
	WRITE_LOCK
)

type SymbolTableFrame struct {
	Name         string
	Parent       *SymbolTableFrame
	Previous     *SymbolTableFrame
	Frame        *FrameMap
	Bindings     map[string]*Binding
	Mutex        sync.RWMutex
	CurrentCode  *list.List
	IsRestricted bool
}

type symbolsTable struct {
	Symbols map[string]*Data
	Mutex   sync.RWMutex
}

type environmentsTable struct {
	Environments map[string]*SymbolTableFrame
	Mutex        sync.RWMutex
}

var Global *SymbolTableFrame
var TopLevelEnvironments environmentsTable = environmentsTable{make(map[string]*SymbolTableFrame, 5), sync.RWMutex{}}

var internedSymbols symbolsTable = symbolsTable{make(map[string]*Data, 256), sync.RWMutex{}}

func Intern(name string) (sym *Data) {
	internedSymbols.Mutex.RLock()
	sym = internedSymbols.Symbols[name]
	internedSymbols.Mutex.RUnlock()
	if sym == nil {
		internedSymbols.Mutex.Lock()
		sym = SymbolWithName(name)
		internedSymbols.Symbols[name] = sym
		internedSymbols.Mutex.Unlock()
	}
	return
}

func (self *SymbolTableFrame) Depth() int {
	if self.Previous == nil {
		return 1
	} else {
		return 1 + self.Previous.Depth()
	}
}

func (self *SymbolTableFrame) CurrentCodeString() string {
	if self.CurrentCode.Len() > 0 {
		return self.CurrentCode.Front().Value.(string)
	} else {
		return "Unknown code"
	}
}

func (self *SymbolTableFrame) InternalDump(frameNumber int) {
	fmt.Printf("Frame %d: %s\n", frameNumber, self.CurrentCodeString())
	self.Mutex.RLock()
	defer self.Mutex.RUnlock()
	for _, b := range self.Bindings {
		if b.Val == nil || TypeOf(b.Val) != PrimitiveType {
			b.Dump()
		}
	}
	fmt.Printf("\n")
	if self.Previous != nil {
		self.Previous.InternalDump(frameNumber + 1)
	}
}

func (self *SymbolTableFrame) Dump() {
	println()
	self.InternalDump(0)
}

func (self *SymbolTableFrame) DumpSingleFrame(frameNumber int) {
	if frameNumber == 0 {
		fmt.Printf("%s\n", self.CurrentCodeString())
		self.Mutex.RLock()
		defer self.Mutex.RUnlock()
		for _, b := range self.Bindings {
			if b.Val == nil || TypeOf(b.Val) != PrimitiveType {
				b.Dump()
			}
		}
		fmt.Printf("\n")
	} else if self.Previous != nil {
		self.Previous.DumpSingleFrame(frameNumber - 1)
	} else {
		fmt.Printf("Invalid frame selected.\n")
	}
}

func (self *SymbolTableFrame) InternalDumpHeaders(frameNumber int) {
	fmt.Printf("Frame %d: %s\n", frameNumber, self.CurrentCodeString())
	if self.Previous != nil {
		self.Previous.InternalDumpHeaders(frameNumber + 1)
	}
}

func (self *SymbolTableFrame) DumpHeaders() {
	println()
	self.InternalDumpHeaders(0)
}

func (self *SymbolTableFrame) DumpHeader() {
	fmt.Printf("%s\n", self.CurrentCodeString())
}

func NewSymbolTableFrameBelow(p *SymbolTableFrame, name string) *SymbolTableFrame {
	var f *FrameMap = nil
	if p != nil {
		f = p.Frame
	}
	restricted := p != nil && p.IsRestricted
	env := &SymbolTableFrame{Name: name, Parent: p, Bindings: make(map[string]*Binding), Frame: f, CurrentCode: list.New(), IsRestricted: restricted}
	if p == nil || p == Global {
		TopLevelEnvironments.Mutex.Lock()
		TopLevelEnvironments.Environments[name] = env
		TopLevelEnvironments.Mutex.Unlock()
	}
	return env
}

func NewSymbolTableFrameBelowWithFrame(p *SymbolTableFrame, f *FrameMap, name string) *SymbolTableFrame {
	if f == nil {
		f = p.Frame
	}
	restricted := p != nil && p.IsRestricted
	env := &SymbolTableFrame{Name: name, Parent: p, Bindings: make(map[string]*Binding, 10), Frame: f, CurrentCode: list.New(), IsRestricted: restricted}
	if p == nil || p == Global {
		TopLevelEnvironments.Mutex.Lock()
		TopLevelEnvironments.Environments[name] = env
		TopLevelEnvironments.Mutex.Unlock()
	}
	return env
}

func (self *SymbolTableFrame) HasFrame() bool {
	return self.Frame != nil
}

func (self *SymbolTableFrame) BindingNamed(name string) (b *Binding, present bool) {
	self.Mutex.RLock()
	b, present = self.Bindings[name]
	self.Mutex.RUnlock()
	return
}

func (self *SymbolTableFrame) SetBindingAt(name string, b *Binding) {
	self.Mutex.Lock()
	self.Bindings[name] = b
	self.Mutex.Unlock()
}

func (self *SymbolTableFrame) DeleteBinding(name string) {
	self.Mutex.Lock()
	delete(self.Bindings, name)
	self.Mutex.Unlock()
}

func (self *SymbolTableFrame) findSymbol(name string) (symbol *Data, found bool) {
	binding, found := self.BindingNamed(name)
	if found {
		return binding.Sym, true
	} else if self.Parent != nil {
		return self.Parent.findSymbol(name)
	} else {
		return nil, false
	}
}

func (self *SymbolTableFrame) FindBindingFor(symbol *Data) (binding *Binding, found bool) {
	name := StringValue(symbol)
	binding, found = self.BindingNamed(name)
	if found {
		return
	} else if self.Parent != nil {
		return self.Parent.FindBindingFor(symbol)
	} else {
		return nil, false
	}
}

func (self *SymbolTableFrame) BindTo(symbol *Data, value *Data) (*Data, error) {
	binding, found := self.FindBindingFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		}
		binding.Val = value
	} else {
		binding = BindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val, nil
}

func (self *SymbolTableFrame) BindToProtected(symbol *Data, value *Data) *Data {
	binding, found := self.FindBindingFor(symbol)
	if found {
		binding.Val = value
		binding.Protected = true
	} else {
		binding = ProtectedBindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val
}

func (self *SymbolTableFrame) SetTo(symbol *Data, value *Data) (result *Data, err error) {
	localBinding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if localBinding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		} else {
			localBinding.Val = value
			return value, nil
		}
	}

	naked := StringValue(NakedSymbolFrom(symbol))
	if self.HasFrame() && self.Frame.HasSlot(naked) {
		self.Frame.Set(naked, value)
		return value, nil
	}

	binding, found := self.FindBindingFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		} else {
			binding.Val = value
			return value, nil
		}
	}

	return nil, errors.New(fmt.Sprintf("%s is undefined", StringValue(symbol)))
}

func (self *SymbolTableFrame) findBindingInLocalFrameFor(symbol *Data) (b *Binding, found bool) {
	return self.BindingNamed(StringValue(symbol))
}

func (self *SymbolTableFrame) BindLocallyTo(symbol *Data, value *Data) (*Data, error) {
	binding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		}
		binding.Val = value
	} else {
		binding = BindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val, nil
}

func (self *SymbolTableFrame) ValueOfWithFunctionSlotCheck(symbol *Data, needFunction bool) *Data {
	localBinding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if FunctionP(localBinding.Val) {
			atomic.StoreInt32(&FunctionValue(localBinding.Val).SlotFunction, 1)
		}
		return localBinding.Val
	}

	if self.HasFrame() {
		f := self.Frame
		naked := StringValue(NakedSymbolFrom(symbol))
		if f.HasSlot(naked) {
			slotValue := f.Get(naked)
			if !needFunction {
				return slotValue
			}
			if FunctionP(slotValue) {
				atomic.StoreInt32(&FunctionValue(slotValue).SlotFunction, 1)
				return slotValue
			}
		}
	}

	binding, found := self.FindBindingFor(symbol)
	if found {
		if FunctionP(binding.Val) {
			atomic.StoreInt32(&FunctionValue(binding.Val).SlotFunction, 0)
		}
		return binding.Val
	} else {
		return EmptyCons()
	}
}

func (self *SymbolTableFrame) ValueOf(symbol *Data) *Data {
	return self.ValueOfWithFunctionSlotCheck(symbol, false)
}
<commit_msg>fixed case where function slots in frames weren't always marked as such<commit_after>// Copyright 2014 SteelSeries ApS.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file implements the symbol table.

package golisp

import (
	"container/list"
	"errors"
	"fmt"
	"sync"
	"sync/atomic"
)

const (
	READ_LOCK = iota
	WRITE_LOCK
)

type SymbolTableFrame struct {
	Name         string
	Parent       *SymbolTableFrame
	Previous     *SymbolTableFrame
	Frame        *FrameMap
	Bindings     map[string]*Binding
	Mutex        sync.RWMutex
	CurrentCode  *list.List
	IsRestricted bool
}

type symbolsTable struct {
	Symbols map[string]*Data
	Mutex   sync.RWMutex
}

type environmentsTable struct {
	Environments map[string]*SymbolTableFrame
	Mutex        sync.RWMutex
}

var Global *SymbolTableFrame
var TopLevelEnvironments environmentsTable = environmentsTable{make(map[string]*SymbolTableFrame, 5), sync.RWMutex{}}

var internedSymbols symbolsTable = symbolsTable{make(map[string]*Data, 256), sync.RWMutex{}}

func Intern(name string) (sym *Data) {
	internedSymbols.Mutex.RLock()
	sym = internedSymbols.Symbols[name]
	internedSymbols.Mutex.RUnlock()
	if sym == nil {
		internedSymbols.Mutex.Lock()
		sym = SymbolWithName(name)
		internedSymbols.Symbols[name] = sym
		internedSymbols.Mutex.Unlock()
	}
	return
}

func (self *SymbolTableFrame) Depth() int {
	if self.Previous == nil {
		return 1
	} else {
		return 1 + self.Previous.Depth()
	}
}

func (self *SymbolTableFrame) CurrentCodeString() string {
	if self.CurrentCode.Len() > 0 {
		return self.CurrentCode.Front().Value.(string)
	} else {
		return "Unknown code"
	}
}

func (self *SymbolTableFrame) InternalDump(frameNumber int) {
	fmt.Printf("Frame %d: %s\n", frameNumber, self.CurrentCodeString())
	self.Mutex.RLock()
	defer self.Mutex.RUnlock()
	for _, b := range self.Bindings {
		if b.Val == nil || TypeOf(b.Val) != PrimitiveType {
			b.Dump()
		}
	}
	fmt.Printf("\n")
	if self.Previous != nil {
		self.Previous.InternalDump(frameNumber + 1)
	}
}

func (self *SymbolTableFrame) Dump() {
	println()
	self.InternalDump(0)
}

func (self *SymbolTableFrame) DumpSingleFrame(frameNumber int) {
	if frameNumber == 0 {
		fmt.Printf("%s\n", self.CurrentCodeString())
		self.Mutex.RLock()
		defer self.Mutex.RUnlock()
		for _, b := range self.Bindings {
			if b.Val == nil || TypeOf(b.Val) != PrimitiveType {
				b.Dump()
			}
		}
		fmt.Printf("\n")
	} else if self.Previous != nil {
		self.Previous.DumpSingleFrame(frameNumber - 1)
	} else {
		fmt.Printf("Invalid frame selected.\n")
	}
}

func (self *SymbolTableFrame) InternalDumpHeaders(frameNumber int) {
	fmt.Printf("Frame %d: %s\n", frameNumber, self.CurrentCodeString())
	if self.Previous != nil {
		self.Previous.InternalDumpHeaders(frameNumber + 1)
	}
}

func (self *SymbolTableFrame) DumpHeaders() {
	println()
	self.InternalDumpHeaders(0)
}

func (self *SymbolTableFrame) DumpHeader() {
	fmt.Printf("%s\n", self.CurrentCodeString())
}

func NewSymbolTableFrameBelow(p *SymbolTableFrame, name string) *SymbolTableFrame {
	var f *FrameMap = nil
	if p != nil {
		f = p.Frame
	}
	restricted := p != nil && p.IsRestricted
	env := &SymbolTableFrame{Name: name, Parent: p, Bindings: make(map[string]*Binding), Frame: f, CurrentCode: list.New(), IsRestricted: restricted}
	if p == nil || p == Global {
		TopLevelEnvironments.Mutex.Lock()
		TopLevelEnvironments.Environments[name] = env
		TopLevelEnvironments.Mutex.Unlock()
	}
	return env
}

func NewSymbolTableFrameBelowWithFrame(p *SymbolTableFrame, f *FrameMap, name string) *SymbolTableFrame {
	if f == nil {
		f = p.Frame
	}
	restricted := p != nil && p.IsRestricted
	env := &SymbolTableFrame{Name: name, Parent: p, Bindings: make(map[string]*Binding, 10), Frame: f, CurrentCode: list.New(), IsRestricted: restricted}
	if p == nil || p == Global {
		TopLevelEnvironments.Mutex.Lock()
		TopLevelEnvironments.Environments[name] = env
		TopLevelEnvironments.Mutex.Unlock()
	}
	return env
}

func (self *SymbolTableFrame) HasFrame() bool {
	return self.Frame != nil
}

func (self *SymbolTableFrame) BindingNamed(name string) (b *Binding, present bool) {
	self.Mutex.RLock()
	b, present = self.Bindings[name]
	self.Mutex.RUnlock()
	return
}

func (self *SymbolTableFrame) SetBindingAt(name string, b *Binding) {
	self.Mutex.Lock()
	self.Bindings[name] = b
	self.Mutex.Unlock()
}

func (self *SymbolTableFrame) DeleteBinding(name string) {
	self.Mutex.Lock()
	delete(self.Bindings, name)
	self.Mutex.Unlock()
}

func (self *SymbolTableFrame) findSymbol(name string) (symbol *Data, found bool) {
	binding, found := self.BindingNamed(name)
	if found {
		return binding.Sym, true
	} else if self.Parent != nil {
		return self.Parent.findSymbol(name)
	} else {
		return nil, false
	}
}

func (self *SymbolTableFrame) FindBindingFor(symbol *Data) (binding *Binding, found bool) {
	name := StringValue(symbol)
	binding, found = self.BindingNamed(name)
	if found {
		return
	} else if self.Parent != nil {
		return self.Parent.FindBindingFor(symbol)
	} else {
		return nil, false
	}
}

func (self *SymbolTableFrame) BindTo(symbol *Data, value *Data) (*Data, error) {
	binding, found := self.FindBindingFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		}
		binding.Val = value
	} else {
		binding = BindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val, nil
}

func (self *SymbolTableFrame) BindToProtected(symbol *Data, value *Data) *Data {
	binding, found := self.FindBindingFor(symbol)
	if found {
		binding.Val = value
		binding.Protected = true
	} else {
		binding = ProtectedBindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val
}

func (self *SymbolTableFrame) SetTo(symbol *Data, value *Data) (result *Data, err error) {
	localBinding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if localBinding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		} else {
			localBinding.Val = value
			return value, nil
		}
	}

	naked := StringValue(NakedSymbolFrom(symbol))
	if self.HasFrame() && self.Frame.HasSlot(naked) {
		self.Frame.Set(naked, value)
		return value, nil
	}

	binding, found := self.FindBindingFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		} else {
			binding.Val = value
			return value, nil
		}
	}

	return nil, errors.New(fmt.Sprintf("%s is undefined", StringValue(symbol)))
}

func (self *SymbolTableFrame) findBindingInLocalFrameFor(symbol *Data) (b *Binding, found bool) {
	return self.BindingNamed(StringValue(symbol))
}

func (self *SymbolTableFrame) BindLocallyTo(symbol *Data, value *Data) (*Data, error) {
	binding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if binding.Protected {
			return nil, fmt.Errorf("%s is a protected binding", StringValue(symbol))
		}
		binding.Val = value
	} else {
		binding = BindingWithSymbolAndValue(symbol, value)
		self.SetBindingAt(StringValue(symbol), binding)
	}
	return binding.Val, nil
}

func (self *SymbolTableFrame) ValueOfWithFunctionSlotCheck(symbol *Data, needFunction bool) *Data {
	localBinding, found := self.findBindingInLocalFrameFor(symbol)
	if found {
		if FunctionP(localBinding.Val) {
			atomic.StoreInt32(&FunctionValue(localBinding.Val).SlotFunction, 1)
		}
		return localBinding.Val
	}

	if self.HasFrame() {
		f := self.Frame
		naked := StringValue(NakedSymbolFrom(symbol))
		if f.HasSlot(naked) {
			slotValue := f.Get(naked)
			if FunctionP(slotValue) {
				atomic.StoreInt32(&FunctionValue(slotValue).SlotFunction, 1)
				return slotValue
			}
			if !needFunction {
				return slotValue
			}
		}
	}

	binding, found := self.FindBindingFor(symbol)
	if found {
		if FunctionP(binding.Val) {
			atomic.StoreInt32(&FunctionValue(binding.Val).SlotFunction, 0)
		}
		return binding.Val
	} else {
		return EmptyCons()
	}
}

func (self *SymbolTableFrame) ValueOf(symbol *Data) *Data {
	return self.ValueOfWithFunctionSlotCheck(symbol, false)
}
<|endoftext|>


<commit_before>package e2e

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path"
	"testing"
	"time"

	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/reporters"
	. "github.com/onsi/gomega"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"

	operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
	"github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
)

var (
	kubeConfigPath = flag.String(
		"kubeconfig", "", "path to the kubeconfig file")

	namespace = flag.String(
		"namespace", "", "namespace where tests will run")

	olmNamespace = flag.String(
		"olmNamespace", "", "namespace where olm is running")

	communityOperators = flag.String(
		"communityOperators",
		"quay.io/operator-framework/upstream-community-operators@sha256:098457dc5e0b6ca9599bd0e7a67809f8eca397907ca4d93597380511db478fec",
		"reference to upstream-community-operators image")

	dummyImage = flag.String(
		"dummyImage",
		"bitnami/nginx:latest",
		"dummy image to treat as an operator in tests")

	testNamespace           = ""
	operatorNamespace       = ""
	communityOperatorsImage = ""
	junitDir                = "junit"
)

func TestEndToEnd(t *testing.T) {
	RegisterFailHandler(Fail)
	SetDefaultEventuallyTimeout(1 * time.Minute)
	SetDefaultEventuallyPollingInterval(1 * time.Second)
	SetDefaultConsistentlyDuration(30 * time.Second)
	SetDefaultConsistentlyPollingInterval(1 * time.Second)

	// always configure a junit report when ARTIFACTS_DIR has been set
	if artifactsDir := os.Getenv("ARTIFACTS_DIR"); artifactsDir != "" {
		junitReporter := reporters.NewJUnitReporter(path.Join(artifactsDir, junitDir, fmt.Sprintf("junit_e2e_%02d.xml", config.GinkgoConfig.ParallelNode)))
		RunSpecsWithDefaultAndCustomReporters(t, "End-to-end", []Reporter{junitReporter})
	} else {
		RunSpecs(t, "End-to-end")
	}
}

var deprovision func() = func() {}

// This function initializes a client which is used to create an operator group for a given namespace
var _ = BeforeSuite(func() {
	if kubeConfigPath != nil && *kubeConfigPath != "" {
		// This flag can be deprecated in favor of the kubeconfig provisioner:
		os.Setenv("KUBECONFIG", *kubeConfigPath)
	}

	testNamespace = *namespace
	operatorNamespace = *olmNamespace
	communityOperatorsImage = *communityOperators
	deprovision = ctx.MustProvision(ctx.Ctx())
	ctx.MustInstall(ctx.Ctx())

	var groups operatorsv1.OperatorGroupList
	Expect(ctx.Ctx().Client().List(context.Background(), &groups, client.InNamespace(testNamespace))).To(Succeed())
	if len(groups.Items) == 0 {
		og := operatorsv1.OperatorGroup{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "opgroup",
				Namespace: testNamespace,
			},
		}
		Expect(ctx.Ctx().Client().Create(context.TODO(), &og)).To(Succeed())
	}

	// Tests can assume the group in the test namespace has been reconciled at least once.
	Eventually(func() ([]operatorsv1.OperatorGroupStatus, error) {
		var groups operatorsv1.OperatorGroupList
		if err := ctx.Ctx().Client().List(context.Background(), &groups, client.InNamespace(testNamespace)); err != nil {
			return nil, err
		}
		var statuses []operatorsv1.OperatorGroupStatus
		for _, group := range groups.Items {
			statuses = append(statuses, group.Status)
		}
		return statuses, nil
	}).Should(And(
		HaveLen(1),
		ContainElement(Not(BeZero())),
	))
})

var _ = AfterSuite(func() {
	deprovision()
})
<commit_msg>wait for operatorhubio-catalog ready before test starts (#2605)<commit_after>package e2e

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path"
	"testing"
	"time"

	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/reporters"
	. "github.com/onsi/gomega"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"

	operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
	"github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
)

var (
	kubeConfigPath = flag.String(
		"kubeconfig", "", "path to the kubeconfig file")

	namespace = flag.String(
		"namespace", "", "namespace where tests will run")

	olmNamespace = flag.String(
		"olmNamespace", "", "namespace where olm is running")

	communityOperators = flag.String(
		"communityOperators",
		"quay.io/operator-framework/upstream-community-operators@sha256:098457dc5e0b6ca9599bd0e7a67809f8eca397907ca4d93597380511db478fec",
		"reference to upstream-community-operators image")

	dummyImage = flag.String(
		"dummyImage",
		"bitnami/nginx:latest",
		"dummy image to treat as an operator in tests")

	testNamespace           = ""
	operatorNamespace       = ""
	communityOperatorsImage = ""
	junitDir                = "junit"
)

func TestEndToEnd(t *testing.T) {
	RegisterFailHandler(Fail)
	SetDefaultEventuallyTimeout(1 * time.Minute)
	SetDefaultEventuallyPollingInterval(1 * time.Second)
	SetDefaultConsistentlyDuration(30 * time.Second)
	SetDefaultConsistentlyPollingInterval(1 * time.Second)

	// always configure a junit report when ARTIFACTS_DIR has been set
	if artifactsDir := os.Getenv("ARTIFACTS_DIR"); artifactsDir != "" {
		junitReporter := reporters.NewJUnitReporter(path.Join(artifactsDir, junitDir, fmt.Sprintf("junit_e2e_%02d.xml", config.GinkgoConfig.ParallelNode)))
		RunSpecsWithDefaultAndCustomReporters(t, "End-to-end", []Reporter{junitReporter})
	} else {
		RunSpecs(t, "End-to-end")
	}
}

var deprovision func() = func() {}

// This function initializes a client which is used to create an operator group for a given namespace
var _ = BeforeSuite(func() {
	if kubeConfigPath != nil && *kubeConfigPath != "" {
		// This flag can be deprecated in favor of the kubeconfig provisioner:
		os.Setenv("KUBECONFIG", *kubeConfigPath)
	}

	testNamespace = *namespace
	operatorNamespace = *olmNamespace
	communityOperatorsImage = *communityOperators
	deprovision = ctx.MustProvision(ctx.Ctx())
	ctx.MustInstall(ctx.Ctx())

	var groups operatorsv1.OperatorGroupList
	Expect(ctx.Ctx().Client().List(context.Background(), &groups, client.InNamespace(testNamespace))).To(Succeed())
	if len(groups.Items) == 0 {
		og := operatorsv1.OperatorGroup{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "opgroup",
				Namespace: testNamespace,
			},
		}
		Expect(ctx.Ctx().Client().Create(context.TODO(), &og)).To(Succeed())
	}

	// Tests can assume the group in the test namespace has been reconciled at least once.
	Eventually(func() ([]operatorsv1.OperatorGroupStatus, error) {
		var groups operatorsv1.OperatorGroupList
		if err := ctx.Ctx().Client().List(context.Background(), &groups, client.InNamespace(testNamespace)); err != nil {
			return nil, err
		}
		var statuses []operatorsv1.OperatorGroupStatus
		for _, group := range groups.Items {
			statuses = append(statuses, group.Status)
		}
		return statuses, nil
	}).Should(And(
		HaveLen(1),
		ContainElement(Not(BeZero())),
	))
	_, err := fetchCatalogSourceOnStatus(ctx.Ctx().OperatorClient(), "operatorhubio-catalog", operatorNamespace, catalogSourceRegistryPodSynced)
	Expect(err).NotTo(HaveOccurred())

})

var _ = AfterSuite(func() {
	deprovision()
})
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"fmt"
	"os"
	"strconv"

	"github.com/fogleman/ln/ln"
)

func cube(x, y, z float64) ln.Shape {
	a := ln.Vector{x - 0.5, y - 0.5, z - 0.5}
	b := ln.Vector{x + 0.5, y + 0.5, z + 0.5}
	return ln.NewCube(a, b)
}

func load(path string) []ln.Vector {
	var result []ln.Vector
	file, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	for _, record := range records {
		x, _ := strconv.ParseFloat(record[0], 64)
		y, _ := strconv.ParseFloat(record[1], 64)
		z, _ := strconv.ParseFloat(record[2], 64)
		result = append(result, ln.Vector{x, z, y})
	}
	return result
}

func main() {
	blocks := load("examples/mountain.csv")
	fmt.Println(len(blocks))
	scene := ln.Scene{}
	size := ln.Vector{0.5, 0.5, 0.5}
	for _, v := range blocks {
		scene.Add(ln.NewCube(v.Sub(size), v.Add(size)))
	}
	eye := ln.Vector{90, -90, 70}
	center := ln.Vector{0, 0, -15}
	up := ln.Vector{0, 0, 1}
	paths := scene.Render(eye, center, up, 50, 1, 0.1, 1000, 0.1)
	paths.Render("out.png", 1024)
	// paths.Print()
}
<commit_msg>remove unused code<commit_after>package main

import (
	"encoding/csv"
	"fmt"
	"os"
	"strconv"

	"github.com/fogleman/ln/ln"
)

func load(path string) []ln.Vector {
	var result []ln.Vector
	file, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	for _, record := range records {
		x, _ := strconv.ParseFloat(record[0], 64)
		y, _ := strconv.ParseFloat(record[1], 64)
		z, _ := strconv.ParseFloat(record[2], 64)
		result = append(result, ln.Vector{x, z, y})
	}
	return result
}

func main() {
	blocks := load("examples/mountain.csv")
	fmt.Println(len(blocks))
	scene := ln.Scene{}
	size := ln.Vector{0.5, 0.5, 0.5}
	for _, v := range blocks {
		scene.Add(ln.NewCube(v.Sub(size), v.Add(size)))
	}
	eye := ln.Vector{90, -90, 70}
	center := ln.Vector{0, 0, -15}
	up := ln.Vector{0, 0, 1}
	paths := scene.Render(eye, center, up, 50, 1, 0.1, 1000, 0.1)
	paths.Render("out.png", 1024)
	// paths.Print()
}
<|endoftext|>


<commit_before>package history

import (
	"bufio"
	"bytes"
	"context"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	"github.com/mattn/go-isatty"
	"github.com/zetamatta/nyagos/shell"
	"github.com/zetamatta/nyagos/texts"
)

var Mark = "!"

var DisableMarks = "\"'"

func (hisObj *Container) Replace(line string) (string, bool) {
	var mark rune
	for _, c := range Mark {
		mark = c
		break
	}

	var buffer bytes.Buffer
	isReplaced := false
	reader := strings.NewReader(line)
	history_count := hisObj.Len()

	quotedChar := '\000'

	for reader.Len() > 0 {
		ch, _, _ := reader.ReadRune()
		if quotedChar == '\000' && strings.IndexRune(DisableMarks, ch) >= 0 {
			quotedChar = ch
			buffer.WriteRune(ch)
			continue
		} else if ch == quotedChar {
			quotedChar = '\000'
			buffer.WriteRune(ch)
			continue
		}
		if ch != mark || reader.Len() <= 0 || quotedChar != '\000' {
			buffer.WriteRune(ch)
			continue
		}
		ch, _, _ = reader.ReadRune()
		if n := strings.IndexRune("^$:*", ch); n >= 0 {
			reader.UnreadRune()
			if history_count >= 1 {
				line := hisObj.At(history_count - 1)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
			}
			continue
		}
		if ch == mark { // !!
			if history_count >= 1 {
				line := hisObj.At(history_count - 1)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
				continue
			} else {
				buffer.WriteRune(mark)
				continue
			}
		}
		if strings.IndexRune("0123456789", ch) >= 0 { // !n
			reader.UnreadRune()
			var backno int
			fmt.Fscan(reader, &backno)
			backno = backno % history_count
			if 0 <= backno && backno < history_count {
				line := hisObj.At(backno)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
			}
			continue
		}
		if ch == '-' && reader.Len() > 0 { // !-n
			var number int
			if _, err := fmt.Fscan(reader, &number); err == nil {
				backno := history_count - number
				for backno < 0 {
					backno += history_count
				}
				if 0 <= backno && backno < history_count {
					line := hisObj.At(backno)
					ExpandMacro(&buffer, reader, line)
					isReplaced = true
				} else {
					buffer.WriteRune(mark)
					buffer.WriteString("-0")
				}
				continue
			} else {
				reader.UnreadRune() // next char of '-'
			}
		}
		if ch == '?' { // !?str?
			var seekStrBuf bytes.Buffer
			lastCharIsQuestionMark := false
			for reader.Len() > 0 {
				ch, _, _ := reader.ReadRune()
				if ch == '?' {
					lastCharIsQuestionMark = true
					break
				}
				seekStrBuf.WriteRune(ch)
			}
			seekStr := seekStrBuf.String()
			found := false
			for i := history_count - 1; i >= 0; i-- {
				his1 := hisObj.At(i)
				if strings.Contains(his1, seekStr) {
					buffer.WriteString(his1)
					isReplaced = true
					found = true
					break
				}
			}
			if !found {
				buffer.WriteRune('?')
				buffer.WriteString(seekStr)
				if lastCharIsQuestionMark {
					buffer.WriteRune('?')
				}
			}
			continue
		}
		// !str
		var seekStrBuf bytes.Buffer
		seekStrBuf.WriteRune(ch)
		for reader.Len() > 0 {
			ch, _, _ := reader.ReadRune()
			if unicode.IsSpace(ch) {
				reader.UnreadRune()
				break
			}
			seekStrBuf.WriteRune(ch)
		}
		seekStr := seekStrBuf.String()
		found := false
		for i := history_count - 1; i >= 0; i-- {
			his1 := hisObj.At(i)
			if strings.HasPrefix(his1, seekStr) {
				buffer.WriteString(his1)
				isReplaced = true
				found = true
				break
			}
		}
		if !found {
			buffer.WriteRune(mark)
			buffer.WriteRune(ch)
		}
	}
	return buffer.String(), isReplaced
}

func ExpandMacro(buffer *bytes.Buffer, reader *strings.Reader, line string) {
	ch, siz, _ := reader.ReadRune()
	if siz > 0 && ch == '^' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(words[1])
		}
	} else if siz > 0 && ch == '$' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(words[len(words)-1])
		}
	} else if siz > 0 && ch == '*' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(strings.Join(words[1:], " "))
		}
	} else if siz > 0 && ch == ':' {
		var n int
		if _, err := fmt.Fscan(reader, &n); err != nil {
			buffer.WriteRune(':')
		} else if words := texts.SplitLikeShellString(line); n < len(words) {
			buffer.WriteString(words[n])
		}
	} else {
		if siz > 0 {
			reader.UnreadRune()
		}
		buffer.WriteString(line)
	}
}

func CmdHistory(ctx context.Context, cmd *shell.Cmd) (int, error) {
	if ctx == nil {
		fmt.Fprintln(cmd.Stderr, "history not found (case1)")
		return 1, nil
	}
	var num int
	if len(cmd.Args) >= 2 {
		num64, err := strconv.ParseInt(cmd.Args[1], 0, 32)
		if err != nil {
			switch err.(type) {
			case *strconv.NumError:
				return 0, fmt.Errorf(
					"history: %s not a number", cmd.Args[1])
			default:
				return 0, err
			}
		}
		num = int(num64)
		if num < 0 {
			num = -num
		}
	} else {
		num = 10
	}
	start := 0

	historyObj_ := ctx.Value(NoInstance)
	if historyObj, ok := historyObj_.(*Container); ok {
		if isatty.IsTerminal(cmd.Stdout.Fd()) && historyObj.Len() > num {

			start = historyObj.Len() - num
		}
		home := os.Getenv("USERPROFILE")
		for i := start; i < historyObj.Len(); i++ {
			row := historyObj.rows[i]
			dir := row.Dir
			if strings.HasPrefix(strings.ToUpper(dir), strings.ToUpper(home)) {
				dir = "~" + dir[len(home):]
			}
			dir = filepath.ToSlash(dir)
			fmt.Fprintf(cmd.Stdout, "%4d  %s [%d] %-s (%s)\n",
				i,
				row.Stamp.Format("Jan _2 15:04:05"),
				row.Pid,
				row.Text,
				dir)
		}
	} else {
		fmt.Fprintln(cmd.Stderr, "history not found (case 2)")
	}
	return 0, nil
}

const max_histories = 1000

func (hisObj *Container) SaveViaWriter(w io.Writer) {
	i := 0
	if len(hisObj.rows) > max_histories {
		i = len(hisObj.rows) - max_histories
	}
	bw := bufio.NewWriter(w)
	for ; i < len(hisObj.rows); i++ {
		fmt.Fprintln(bw, hisObj.rows[i].String())
	}
	bw.Flush()
}

func (hisObj *Container) Save(path string) error {
	fd, err := os.Create(path)
	if err != nil {
		return err
	}
	hisObj.SaveViaWriter(fd)
	return fd.Close()
}

func (hisObj *Container) LoadViaReader(reader io.Reader) {
	sc := bufio.NewScanner(reader)
	list := make([][]string, 0, 2000)
	hash := make(map[string]int)
	for sc.Scan() {
		line := sc.Text()
		if lnum, ok := hash[line]; ok {
			// delete duplicated record (marking)
			list[lnum] = nil
		}
		hash[line] = len(list)

		p := strings.Split(line, "\t")
		list = append(list, p)
	}
	for _, p := range list {
		// push only not duplicated record.
		if p != nil {
			var stamp time.Time
			var dir string
			pid := 0
			if len(p) >= 3 {
				dir = p[1]
				stamp, _ = time.Parse("2006-01-02 15:04:05", p[2])
				if len(p) >= 4 {
					pid, _ = strconv.Atoi(p[3])
				}
			}
			hisObj.PushLine(Line{
				Text:  p[0],
				Dir:   dir,
				Stamp: stamp,
				Pid:   pid})
		}
	}
	sort.Slice(hisObj.rows, func(i, j int) bool {
		p := hisObj.rows[i]
		q := hisObj.rows[j]
		if p.Stamp != q.Stamp {
			return p.Stamp.Before(q.Stamp)
		}
		return p.Text < q.Text
	})
}

func (hisObj *Container) Load(path string) error {
	fd, err := os.Open(path)
	if err != nil {
		return err
	}
	hisObj.LoadViaReader(fd)
	return fd.Close()
}
<commit_msg>Fix the bug that `!notfoundstr` is replaced to `!n` only.<commit_after>package history

import (
	"bufio"
	"bytes"
	"context"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	"github.com/mattn/go-isatty"
	"github.com/zetamatta/nyagos/shell"
	"github.com/zetamatta/nyagos/texts"
)

var Mark = "!"

var DisableMarks = "\"'"

func (hisObj *Container) Replace(line string) (string, bool) {
	var mark rune
	for _, c := range Mark {
		mark = c
		break
	}

	var buffer bytes.Buffer
	isReplaced := false
	reader := strings.NewReader(line)
	history_count := hisObj.Len()

	quotedChar := '\000'

	for reader.Len() > 0 {
		ch, _, _ := reader.ReadRune()
		if quotedChar == '\000' && strings.IndexRune(DisableMarks, ch) >= 0 {
			quotedChar = ch
			buffer.WriteRune(ch)
			continue
		} else if ch == quotedChar {
			quotedChar = '\000'
			buffer.WriteRune(ch)
			continue
		}
		if ch != mark || reader.Len() <= 0 || quotedChar != '\000' {
			buffer.WriteRune(ch)
			continue
		}
		ch, _, _ = reader.ReadRune()
		if n := strings.IndexRune("^$:*", ch); n >= 0 {
			reader.UnreadRune()
			if history_count >= 1 {
				line := hisObj.At(history_count - 1)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
			}
			continue
		}
		if ch == mark { // !!
			if history_count >= 1 {
				line := hisObj.At(history_count - 1)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
				continue
			} else {
				buffer.WriteRune(mark)
				continue
			}
		}
		if strings.IndexRune("0123456789", ch) >= 0 { // !n
			reader.UnreadRune()
			var backno int
			fmt.Fscan(reader, &backno)
			backno = backno % history_count
			if 0 <= backno && backno < history_count {
				line := hisObj.At(backno)
				ExpandMacro(&buffer, reader, line)
				isReplaced = true
			}
			continue
		}
		if ch == '-' && reader.Len() > 0 { // !-n
			var number int
			if _, err := fmt.Fscan(reader, &number); err == nil {
				backno := history_count - number
				for backno < 0 {
					backno += history_count
				}
				if 0 <= backno && backno < history_count {
					line := hisObj.At(backno)
					ExpandMacro(&buffer, reader, line)
					isReplaced = true
				} else {
					buffer.WriteRune(mark)
					buffer.WriteString("-0")
				}
				continue
			} else {
				reader.UnreadRune() // next char of '-'
			}
		}
		if ch == '?' { // !?str?
			var seekStrBuf bytes.Buffer
			lastCharIsQuestionMark := false
			for reader.Len() > 0 {
				ch, _, _ := reader.ReadRune()
				if ch == '?' {
					lastCharIsQuestionMark = true
					break
				}
				seekStrBuf.WriteRune(ch)
			}
			seekStr := seekStrBuf.String()
			found := false
			for i := history_count - 1; i >= 0; i-- {
				his1 := hisObj.At(i)
				if strings.Contains(his1, seekStr) {
					buffer.WriteString(his1)
					isReplaced = true
					found = true
					break
				}
			}
			if !found {
				buffer.WriteRune('?')
				buffer.WriteString(seekStr)
				if lastCharIsQuestionMark {
					buffer.WriteRune('?')
				}
			}
			continue
		}
		// !str
		var seekStrBuf bytes.Buffer
		seekStrBuf.WriteRune(ch)
		for reader.Len() > 0 {
			ch, _, _ := reader.ReadRune()
			if unicode.IsSpace(ch) {
				reader.UnreadRune()
				break
			}
			seekStrBuf.WriteRune(ch)
		}
		seekStr := seekStrBuf.String()
		found := false
		for i := history_count - 1; i >= 0; i-- {
			his1 := hisObj.At(i)
			if strings.HasPrefix(his1, seekStr) {
				buffer.WriteString(his1)
				isReplaced = true
				found = true
				break
			}
		}
		if !found {
			buffer.WriteRune(mark)
			buffer.WriteString(seekStr)
		}
	}
	return buffer.String(), isReplaced
}

func ExpandMacro(buffer *bytes.Buffer, reader *strings.Reader, line string) {
	ch, siz, _ := reader.ReadRune()
	if siz > 0 && ch == '^' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(words[1])
		}
	} else if siz > 0 && ch == '$' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(words[len(words)-1])
		}
	} else if siz > 0 && ch == '*' {
		if words := texts.SplitLikeShellString(line); len(words) >= 2 {
			buffer.WriteString(strings.Join(words[1:], " "))
		}
	} else if siz > 0 && ch == ':' {
		var n int
		if _, err := fmt.Fscan(reader, &n); err != nil {
			buffer.WriteRune(':')
		} else if words := texts.SplitLikeShellString(line); n < len(words) {
			buffer.WriteString(words[n])
		}
	} else {
		if siz > 0 {
			reader.UnreadRune()
		}
		buffer.WriteString(line)
	}
}

func CmdHistory(ctx context.Context, cmd *shell.Cmd) (int, error) {
	if ctx == nil {
		fmt.Fprintln(cmd.Stderr, "history not found (case1)")
		return 1, nil
	}
	var num int
	if len(cmd.Args) >= 2 {
		num64, err := strconv.ParseInt(cmd.Args[1], 0, 32)
		if err != nil {
			switch err.(type) {
			case *strconv.NumError:
				return 0, fmt.Errorf(
					"history: %s not a number", cmd.Args[1])
			default:
				return 0, err
			}
		}
		num = int(num64)
		if num < 0 {
			num = -num
		}
	} else {
		num = 10
	}
	start := 0

	historyObj_ := ctx.Value(NoInstance)
	if historyObj, ok := historyObj_.(*Container); ok {
		if isatty.IsTerminal(cmd.Stdout.Fd()) && historyObj.Len() > num {

			start = historyObj.Len() - num
		}
		home := os.Getenv("USERPROFILE")
		for i := start; i < historyObj.Len(); i++ {
			row := historyObj.rows[i]
			dir := row.Dir
			if strings.HasPrefix(strings.ToUpper(dir), strings.ToUpper(home)) {
				dir = "~" + dir[len(home):]
			}
			dir = filepath.ToSlash(dir)
			fmt.Fprintf(cmd.Stdout, "%4d  %s [%d] %-s (%s)\n",
				i,
				row.Stamp.Format("Jan _2 15:04:05"),
				row.Pid,
				row.Text,
				dir)
		}
	} else {
		fmt.Fprintln(cmd.Stderr, "history not found (case 2)")
	}
	return 0, nil
}

const max_histories = 1000

func (hisObj *Container) SaveViaWriter(w io.Writer) {
	i := 0
	if len(hisObj.rows) > max_histories {
		i = len(hisObj.rows) - max_histories
	}
	bw := bufio.NewWriter(w)
	for ; i < len(hisObj.rows); i++ {
		fmt.Fprintln(bw, hisObj.rows[i].String())
	}
	bw.Flush()
}

func (hisObj *Container) Save(path string) error {
	fd, err := os.Create(path)
	if err != nil {
		return err
	}
	hisObj.SaveViaWriter(fd)
	return fd.Close()
}

func (hisObj *Container) LoadViaReader(reader io.Reader) {
	sc := bufio.NewScanner(reader)
	list := make([][]string, 0, 2000)
	hash := make(map[string]int)
	for sc.Scan() {
		line := sc.Text()
		if lnum, ok := hash[line]; ok {
			// delete duplicated record (marking)
			list[lnum] = nil
		}
		hash[line] = len(list)

		p := strings.Split(line, "\t")
		list = append(list, p)
	}
	for _, p := range list {
		// push only not duplicated record.
		if p != nil {
			var stamp time.Time
			var dir string
			pid := 0
			if len(p) >= 3 {
				dir = p[1]
				stamp, _ = time.Parse("2006-01-02 15:04:05", p[2])
				if len(p) >= 4 {
					pid, _ = strconv.Atoi(p[3])
				}
			}
			hisObj.PushLine(Line{
				Text:  p[0],
				Dir:   dir,
				Stamp: stamp,
				Pid:   pid})
		}
	}
	sort.Slice(hisObj.rows, func(i, j int) bool {
		p := hisObj.rows[i]
		q := hisObj.rows[j]
		if p.Stamp != q.Stamp {
			return p.Stamp.Before(q.Stamp)
		}
		return p.Text < q.Text
	})
}

func (hisObj *Container) Load(path string) error {
	fd, err := os.Open(path)
	if err != nil {
		return err
	}
	hisObj.LoadViaReader(fd)
	return fd.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"

	"golang.org/x/net/context"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/watch"
)

type watchFunc func() (watch.Interface, error)

type event struct {
	watch.Event
}

func (e event) String() string {
	m, er := getMeta(e.Object)
	if er != nil {
		return fmt.Sprintf("Event: type=%v object=Unknown", e.Type)
	}
	return fmt.Sprintf(
		"Event: [%v] object={Kind: %q, Name: %q, Namespace: %q} registerable=%v",
		e.Type, m.kind, m.name, m.ns, registerable(e.Object),
	)
}

func acquireWatch(fn watchFunc, out chan<- watch.Interface, c context.Context) {
	retry := 2 * time.Second
	t := time.NewTicker(retry)
	defer t.Stop()

	w, e := fn()
	if e == nil {
		out <- w
		return
	}

	for {
		debugf("Setting watch failed, retry in (%v): %v", retry, e)
		select {
		case <-c.Done():
			return
		case <-t.C:
			w, e := fn()
			if e == nil {
				out <- w
				return
			}
		}
	}
}

func startWatches(c context.Context) (chan event, error) {
	resourceVersion = "0"
	out := make(chan event, 100)
	kc, er := kubeClient()
	if er != nil {
		return out, er
	}
	sv := func() (watch.Interface, error) {
		debugf("Attempting to set watch on Services")
		return kc.Services(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion)
	}
	en := func() (watch.Interface, error) {
		debugf("Attempting to set watch on Endpoints")
		return kc.Endpoints(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion)
	}

	go watcher("Services", sv, out, c)
	go watcher("Endpoints", en, out, c)
	return out, nil
}

func watcher(name string, fn watchFunc, out chan<- event, c context.Context) {
	var w watch.Interface
	var wc = make(chan watch.Interface, 1)
	defer close(wc)

Acquire:
	go acquireWatch(fn, wc, c)
	select {
	case <-c.Done():
		infof("Closing %s watch channel", name)
		return
	case w = <-wc:
		debugf("%s watch set", name)
	}

	for {
		select {
		case <-c.Done():
			infof("Closing %s watch channel", name)
			return
		case e := <-w.ResultChan():
			if isClosed(e) {
				warnf("%s watch closed: %+v", name, e)
				goto Acquire
			}
			out <- event{e}
		}
	}
}

func isClosed(e watch.Event) bool {
	return e.Type == watch.Error || e == watch.Event{}
}
<commit_msg>Try and protect against sending on closed channel. Don't reacquire watch on error<commit_after>package main

import (
	"fmt"
	"time"

	"golang.org/x/net/context"
	"k8s.io/kubernetes/pkg/api"
	uapi "k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/watch"
)

type watchFunc func() (watch.Interface, error)

type event struct {
	watch.Event
}

func (e event) String() string {
	m, er := getMeta(e.Object)
	if er != nil {
		return fmt.Sprintf("Event: type=%v object=Unknown", e.Type)
	}
	if s, ok := e.Object.(*uapi.Status); ok {
		return fmt.Sprintf("Status: [%s] code=%d %q", s.Status, s.Code, s.Message)
	}
	return fmt.Sprintf(
		"Event: [%v] object={Kind: %q, Name: %q, Namespace: %q} registerable=%v",
		e.Type, m.kind, m.name, m.ns, registerable(e.Object),
	)
}

func startWatches(c context.Context) (chan event, error) {
	resourceVersion = "0"
	out := make(chan event, 100)
	kc, er := kubeClient()
	if er != nil {
		return out, er
	}
	sv := func() (watch.Interface, error) {
		debugf("Attempting to set watch on Services")
		return kc.Services(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion)
	}
	en := func() (watch.Interface, error) {
		debugf("Attempting to set watch on Endpoints")
		return kc.Endpoints(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion)
	}

	go watcher("Services", sv, out, c)
	go watcher("Endpoints", en, out, c)
	return out, nil
}

func acquireWatch(fn watchFunc, out chan<- watch.Interface, c context.Context) {
	retry := 2 * time.Second
	t := time.NewTicker(retry)
	defer t.Stop()

	w, e := fn()
	if e == nil && c.Err() == nil {
		out <- w
		return
	}

	for {
		debugf("Setting watch failed, retry in (%v): %v", retry, e)
		select {
		case <-c.Done():
			return
		case <-t.C:
			w, e := fn()
			if e == nil && c.Err() == nil {
				out <- w
				return
			}
		}
	}
}

func watcher(name string, fn watchFunc, out chan<- event, c context.Context) {
	var w watch.Interface
	var wc = make(chan watch.Interface, 1)
	defer close(wc)

Acquire:
	go acquireWatch(fn, wc, c)
	select {
	case <-c.Done():
		infof("Closing %s watch channel", name)
		return
	case w = <-wc:
		debugf("%s watch set", name)
	}

EventLoop:
	for {
		select {
		case <-c.Done():
			infof("Closing %s watch channel", name)
			return
		case e := event{<-w.ResultChan()}:
			switch {
			case isClosed(e):
				warnf("%s watch closed: %v", name, e)
				goto Acquire
			case isError(e):
				errorf("%s watch error: %v", name, e)
				goto EventLoop
			case c.Err() == nil:
				out <- e
			}
		}
	}
}

func isClosed(e event) bool {
	return e.Event == watch.Event{}
}

func isError(e event) bool {
	return e.Type == watch.Error
}
<|endoftext|>


<commit_before>//  ---------------------------------------------------------------------------
//
//  main.go
//
//  Copyright (c) 2014, Jared Chavez.
//  All rights reserved.
//
//  Use of this source code is governed by a BSD-style
//  license that can be found in the LICENSE file.
//
//  -----------

// gobuild recursively searches a path for go packages with a 'BUILD'
// file in their directory and builds the package or application. Builds
// are performed for each platform, and with the options specified in
// the xml of that package's BUILD file.
//  Usage: gobuild <search root directory>
package main

// External imports
import (
    "github.com/xaevman/goat/lib/fs"
)

// Stdlib imports
import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
    "os/exec"
    "path"
    "path/filepath"
    "runtime"
    "strings"
    "time"
)

// File name to search for in the target path.
const buildFileName = "BUILD"

// Flag which specifies whether or not to install the build result for the
// executing platform and architecture.
var install = false

// build represents a build node in the BUILD xml file.
type build struct {
    Dir       string
    Install   bool       `xml:"install,attr"`
    Name      string
    Path      string
    Platforms []platform `xml:"Platform"`
}

// platform represents a platform node in the BUILD xml file.
type platform struct {
    OS   string `xml:"os,attr"`
    Arch string `xml:"arch,attr"`
}

// main is the entry point for the application. The first argument passed
// on the command line is used as the base path to start the recursive
// search.
func main() {
    // startup
    fmt.Println("Start run...")
    start := time.Now()

    // kick it off
    startDir := "./"
    if len(os.Args) > 1 {
        startDir = os.Args[1]
    }

    rootDir := fs.NewSearchDir()

    go rootDir.SearchFiles(startDir, buildFileName)

    buildList := make([]string, 0)

    // wait for search results
    func() {
        for {
            select {
            case a := <-rootDir.FileChan:
                fmt.Printf("BUILD detected (%v)\n", a)
                buildList = append(buildList, a)
            case a := <-rootDir.ErrChan:
                fmt.Println(a)
            case <-rootDir.DoneChan:
                return
            }
        }
    }()

    // perform all the builds
    buildChan := make(chan bool)
    for _, item := range buildList {
        buildData, err := ioutil.ReadFile(item)
        if err != nil {
            fmt.Printf("Error opening BUILD file %v (%v)\n", item, err)
            continue
        }

        b := &build {
            Dir:     path.Dir(item),
            Install: false,
            Path:    item,
        }

        resolveName(b)

        xml.Unmarshal(buildData, b)
        goBuild(b, buildChan)
    }

    // print results
    fmt.Println("Run complete")
    fmt.Printf(
        "%v builds in %v\n",
        len(buildList),
        time.Since(start),
    )
}

// resolveName attempts to resolve the name of project directory. This name
// is later used as the file name of the resulting binary.
func resolveName(b *build) {
    absPath, err := filepath.Abs(b.Dir)
    if err != nil {
        fmt.Printf("Can't resolve name for directory %s\n", b.Dir)
        return
    }

    fileName := filepath.Base(absPath)
    fmt.Printf("Resolved fileName = %s\n", fileName)
    b.Name = fileName
}

// goBuild takes a given build and stars a separate go routine to build
// each of the targetted platforms.
func goBuild(b *build, c chan bool) {
    pChan := make(chan bool)
    for _, platform := range b.Platforms {
        go goBuildPlatform(b, platform, pChan)
    }

    for i := 0; i < len(b.Platforms); i++ {
        <-pChan
    }
}

// goBuildPlatform takes a given set of build settings and target platform
// and executes to the build with those settings.
func goBuildPlatform(b *build, p platform, c chan bool) {
    fmt.Printf(
        "Starting build %v (%v-%v)\n",
        b.Dir,
        p.OS,
        p.Arch,
    )

    // build paths
    extension := ""
    if p.OS == "windows" {
        extension = ".exe"
    }

    gopath   := fmt.Sprintf("GOPATH=%s", os.Getenv("GOPATH"))
    goos     := fmt.Sprintf("GOOS=%s", p.OS)
    goarch   := fmt.Sprintf("GOARCH=%s", p.Arch)
    destPath := fmt.Sprintf("bin/%s/%s", p.OS, p.Arch)
    destFile := fmt.Sprintf("%s/%s%s", destPath, b.Name, extension)

    // build
    cmd         := exec.Command("go", "build", "-o", destFile)
    cmd.Dir      = b.Dir
    cmd.Env      = []string { gopath, goos, goarch }
    start       := time.Now()
    output, err := cmd.CombinedOutput()

    if err != nil {
        fmt.Printf("Error running %v (%v)\n", cmd.Path, err)
        fmt.Printf("\t%v\n", string(output))
    }

    // install if requested
    if b.Install               == true &&
       strings.ToLower(p.OS)   == runtime.GOOS &&
       strings.ToLower(p.Arch) == runtime.GOARCH {
        fmt.Printf("Installing %s-%s...\n", p.OS, p.Arch)
        cmd         = exec.Command("go", "install")
        cmd.Dir     = b.Dir
        start       = time.Now()
        output, err = cmd.CombinedOutput()

        if err != nil {
            fmt.Printf("Error installing %v (%v)\n", cmd.Path, err)
            fmt.Printf("\t%v\n", string(output))
        }
    }

    // report completion
    fmt.Printf(
        "%v (%v-%v) complete\t%v\n",
        b.Dir,
        p.OS,
        p.Arch,
        time.Since(start),
    )

    c <- true
}
<commit_msg>gobuild: remove unused variable<commit_after>//  ---------------------------------------------------------------------------
//
//  main.go
//
//  Copyright (c) 2014, Jared Chavez.
//  All rights reserved.
//
//  Use of this source code is governed by a BSD-style
//  license that can be found in the LICENSE file.
//
//  -----------

// gobuild recursively searches a path for go packages with a 'BUILD'
// file in their directory and builds the package or application. Builds
// are performed for each platform, and with the options specified in
// the xml of that package's BUILD file.
//  Usage: gobuild <search root directory>
package main

// External imports
import (
    "github.com/xaevman/goat/lib/fs"
)

// Stdlib imports
import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
    "os/exec"
    "path"
    "path/filepath"
    "runtime"
    "strings"
    "time"
)

// File name to search for in the target path.
const buildFileName = "BUILD"

// build represents a build node in the BUILD xml file.
type build struct {
    Dir       string
    Install   bool       `xml:"install,attr"`
    Name      string
    Path      string
    Platforms []platform `xml:"Platform"`
}

// platform represents a platform node in the BUILD xml file.
type platform struct {
    OS   string `xml:"os,attr"`
    Arch string `xml:"arch,attr"`
}

// main is the entry point for the application. The first argument passed
// on the command line is used as the base path to start the recursive
// search.
func main() {
    // startup
    fmt.Println("Start run...")
    start := time.Now()

    // kick it off
    startDir := "./"
    if len(os.Args) > 1 {
        startDir = os.Args[1]
    }

    rootDir := fs.NewSearchDir()

    go rootDir.SearchFiles(startDir, buildFileName)

    buildList := make([]string, 0)

    // wait for search results
    func() {
        for {
            select {
            case a := <-rootDir.FileChan:
                fmt.Printf("BUILD detected (%v)\n", a)
                buildList = append(buildList, a)
            case a := <-rootDir.ErrChan:
                fmt.Println(a)
            case <-rootDir.DoneChan:
                return
            }
        }
    }()

    // perform all the builds
    buildChan := make(chan bool)
    for _, item := range buildList {
        buildData, err := ioutil.ReadFile(item)
        if err != nil {
            fmt.Printf("Error opening BUILD file %v (%v)\n", item, err)
            continue
        }

        b := &build {
            Dir:     path.Dir(item),
            Install: false,
            Path:    item,
        }

        resolveName(b)

        xml.Unmarshal(buildData, b)
        goBuild(b, buildChan)
    }

    // print results
    fmt.Println("Run complete")
    fmt.Printf(
        "%v builds in %v\n",
        len(buildList),
        time.Since(start),
    )
}

// resolveName attempts to resolve the name of project directory. This name
// is later used as the file name of the resulting binary.
func resolveName(b *build) {
    absPath, err := filepath.Abs(b.Dir)
    if err != nil {
        fmt.Printf("Can't resolve name for directory %s\n", b.Dir)
        return
    }

    fileName := filepath.Base(absPath)
    fmt.Printf("Resolved fileName = %s\n", fileName)
    b.Name = fileName
}

// goBuild takes a given build and stars a separate go routine to build
// each of the targetted platforms.
func goBuild(b *build, c chan bool) {
    pChan := make(chan bool)
    for _, platform := range b.Platforms {
        go goBuildPlatform(b, platform, pChan)
    }

    for i := 0; i < len(b.Platforms); i++ {
        <-pChan
    }
}

// goBuildPlatform takes a given set of build settings and target platform
// and executes to the build with those settings.
func goBuildPlatform(b *build, p platform, c chan bool) {
    fmt.Printf(
        "Starting build %v (%v-%v)\n",
        b.Dir,
        p.OS,
        p.Arch,
    )

    // build paths
    extension := ""
    if p.OS == "windows" {
        extension = ".exe"
    }

    gopath   := fmt.Sprintf("GOPATH=%s", os.Getenv("GOPATH"))
    goos     := fmt.Sprintf("GOOS=%s", p.OS)
    goarch   := fmt.Sprintf("GOARCH=%s", p.Arch)
    destPath := fmt.Sprintf("bin/%s/%s", p.OS, p.Arch)
    destFile := fmt.Sprintf("%s/%s%s", destPath, b.Name, extension)

    // build
    cmd         := exec.Command("go", "build", "-o", destFile)
    cmd.Dir      = b.Dir
    cmd.Env      = []string { gopath, goos, goarch }
    start       := time.Now()
    output, err := cmd.CombinedOutput()

    if err != nil {
        fmt.Printf("Error running %v (%v)\n", cmd.Path, err)
        fmt.Printf("\t%v\n", string(output))
    }

    // install if requested
    if b.Install               == true &&
       strings.ToLower(p.OS)   == runtime.GOOS &&
       strings.ToLower(p.Arch) == runtime.GOARCH {
        fmt.Printf("Installing %s-%s...\n", p.OS, p.Arch)
        cmd         = exec.Command("go", "install")
        cmd.Dir     = b.Dir
        start       = time.Now()
        output, err = cmd.CombinedOutput()

        if err != nil {
            fmt.Printf("Error installing %v (%v)\n", cmd.Path, err)
            fmt.Printf("\t%v\n", string(output))
        }
    }

    // report completion
    fmt.Printf(
        "%v (%v-%v) complete\t%v\n",
        b.Dir,
        p.OS,
        p.Arch,
        time.Since(start),
    )

    c <- true
}
<|endoftext|>


<commit_before>package dfpp

import (
	"bufio"
	"fmt"
	"github.com/op/go-logging"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"runtime"
	"strings"
)

var log = logging.MustGetLogger("dfpp")

type Dfpp struct {
	Processors map[string]func(string, []string)
	Output     io.Writer
}

func NewDfpp() *Dfpp {
	pp := &Dfpp{
		Output: os.Stdout,
	}
	pp.Processors = map[string]func(string, []string){
		"INCLUDE": pp.ProcessInclude,
	}
	return pp
}

func (pp *Dfpp) ProcessDockerfile(input io.Reader) {
	for line := range InstructionScanner(input) {
		parts := strings.Fields(line)
		if len(parts) > 0 {
			instruction := parts[0]
			if fn, ok := pp.Processors[instruction]; ok {
				fn(line, parts)
				continue
			}
		}
		fmt.Fprintf(pp.Output, "%s\n", line)
	}
}

func InstructionScanner(input io.Reader) chan string {
	ch := make(chan string)
	go func() {
		scanner := bufio.NewScanner(input)
		for scanner.Scan() {
			line := scanner.Text()
			for len(line) > 0 && line[len(line)-1] == '\\' {
				scanner.Scan()
				line += "\n" + scanner.Text()
			}
			ch <- line
		}
		close(ch)
	}()
	return ch
}

func (pp *Dfpp) ProcessInclude(line string, fields []string) {
	merge := false
	exclude := make(map[string]bool)
	include := make(map[string]bool)

	uris := make([]string, 0, len(fields)-1)
	for _, field := range fields {
		if _, err := os.Stat(field); err == nil {
			uris = append(uris, field)
			continue
		}
		clude := include
		if field[0] == '-' {
			clude = exclude
			field = field[1:]
		}

		switch field {
		case "\\":
			continue
		case "INCLUDE":
			continue
		case "MERGE":
			merge = true
		case "ADD":
			fallthrough
		case "CMD":
			fallthrough
		case "COPY":
			fallthrough
		case "ENTRYPOINT":
			fallthrough
		case "ENV":
			fallthrough
		case "EXPOSE":
			fallthrough
		case "FROM":
			fallthrough
		case "LABEL":
			fallthrough
		case "MAINTAINER":
			fallthrough
		case "ONBUILD":
			fallthrough
		case "RUN":
			fallthrough
		case "USER":
			fallthrough
		case "VOLUME":
			fallthrough
		case "WORKDIR":
			clude[field] = true
		default:
			uris = append(uris, field)
		}
	}

	docs := make([]string, 0, len(uris))
	for _, uri := range uris {
		if _, err := os.Stat(uri); err == nil {
			content, err := ioutil.ReadFile(uri)
			if err != nil {
				log.Error("Failed to read %s: %s", uri, err)
				os.Exit(1)
			}
			docs = append(docs, string(content))
		} else {
			req, _ := http.NewRequest("GET", uri, nil)
			ua := &http.Client{}
			if resp, err := ua.Do(req); err != nil {
				log.Error("Failed to %s %s: %s", req.Method, req.URL.String(), err)
				os.Exit(1)
			} else {
				if resp.StatusCode < 200 || resp.StatusCode >= 300 && resp.StatusCode != 401 {
					log.Error("response status: %s", resp.Status)
				}
				runtime.SetFinalizer(resp, func(r *http.Response) {
					r.Body.Close()
				})
				if buf, err := ioutil.ReadAll(resp.Body); err == nil {
					docs = append(docs, string(buf))
				}
			}
		}
	}
	pp.Merge(merge, docs, include, exclude)
}

func (pp *Dfpp) Merge(merge bool, docs []string, include, exclude map[string]bool) {
	result := make([]*string, 0)
	ops := make(map[string]*string)
	for _, doc := range docs {
		for line := range InstructionScanner(strings.NewReader(doc)) {
			fields := strings.Fields(line)
			if len(fields) > 0 {
				op := fields[0]
				if _, ok := exclude[op]; ok {
					continue
				}
				if _, ok := include[op]; len(include) > 0 && !ok {
					continue
				}
				details := strings.TrimPrefix(line, fields[0]+" ")

				if sref, ok := ops[op]; merge && ok {
					if op == "ENV" || op == "LABEL" {
						*sref += " \\\n" + strings.Repeat(" ", len(op)+1) + details
					} else if op == "RUN" {
						*sref += " && \\\n    " + details

						// squash redundent apt-get updates
						squash := "apt-get update"
						if ix := strings.Index(*sref, squash); ix >= 0 {
							rest := strings.Replace((*sref)[ix+len(squash):], squash, "echo skipping redundent apt-get-update", -1)
							*sref = (*sref)[0:ix+len(squash)] + rest
						}

					} else {
						dup := string(line)
						result = append(result, &dup)
					}
				} else {
					dup := string(line)
					result = append(result, &dup)
					ops[op] = result[len(result)-1]
				}
			}
		}
	}
	for _, line := range result {
		fmt.Fprintf(pp.Output, "%s\n", *line)
	}
}
<commit_msg>processors should return a bool to indicate if output has been handled or not   - false means the line should be printed<commit_after>package dfpp

import (
	"bufio"
	"fmt"
	"github.com/op/go-logging"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"runtime"
	"strings"
)

var log = logging.MustGetLogger("dfpp")

type Dfpp struct {
	Processors map[string]func(string, []string)bool
	Output     io.Writer
}

func NewDfpp() *Dfpp {
	pp := &Dfpp{
		Output: os.Stdout,
	}
	pp.Processors = map[string]func(string, []string) bool {
		"INCLUDE": pp.ProcessInclude,
	}
	return pp
}

func (pp *Dfpp) ProcessDockerfile(input io.Reader) {
	for line := range InstructionScanner(input) {
		parts := strings.Fields(line)
		if len(parts) > 0 {
			instruction := parts[0]
			if fn, ok := pp.Processors[instruction]; ok {
				if fn(line, parts) {
					continue
				}
			}
		}
		fmt.Fprintf(pp.Output, "%s\n", line)
	}
}

func InstructionScanner(input io.Reader) chan string {
	ch := make(chan string)
	go func() {
		scanner := bufio.NewScanner(input)
		for scanner.Scan() {
			line := scanner.Text()
			for len(line) > 0 && line[len(line)-1] == '\\' {
				scanner.Scan()
				line += "\n" + scanner.Text()
			}
			ch <- line
		}
		close(ch)
	}()
	return ch
}

func (pp *Dfpp) ProcessInclude(line string, fields []string) bool {
	merge := false
	exclude := make(map[string]bool)
	include := make(map[string]bool)

	uris := make([]string, 0, len(fields)-1)
	for _, field := range fields {
		if _, err := os.Stat(field); err == nil {
			uris = append(uris, field)
			continue
		}
		clude := include
		if field[0] == '-' {
			clude = exclude
			field = field[1:]
		}

		switch field {
		case "\\":
			continue
		case "INCLUDE":
			continue
		case "MERGE":
			merge = true
		case "ADD":
			fallthrough
		case "CMD":
			fallthrough
		case "COPY":
			fallthrough
		case "ENTRYPOINT":
			fallthrough
		case "ENV":
			fallthrough
		case "EXPOSE":
			fallthrough
		case "FROM":
			fallthrough
		case "LABEL":
			fallthrough
		case "MAINTAINER":
			fallthrough
		case "ONBUILD":
			fallthrough
		case "RUN":
			fallthrough
		case "USER":
			fallthrough
		case "VOLUME":
			fallthrough
		case "WORKDIR":
			clude[field] = true
		default:
			uris = append(uris, field)
		}
	}

	docs := make([]string, 0, len(uris))
	for _, uri := range uris {
		if _, err := os.Stat(uri); err == nil {
			content, err := ioutil.ReadFile(uri)
			if err != nil {
				log.Error("Failed to read %s: %s", uri, err)
				os.Exit(1)
			}
			docs = append(docs, string(content))
		} else {
			req, _ := http.NewRequest("GET", uri, nil)
			ua := &http.Client{}
			if resp, err := ua.Do(req); err != nil {
				log.Error("Failed to %s %s: %s", req.Method, req.URL.String(), err)
				os.Exit(1)
			} else {
				if resp.StatusCode < 200 || resp.StatusCode >= 300 && resp.StatusCode != 401 {
					log.Error("response status: %s", resp.Status)
				}
				runtime.SetFinalizer(resp, func(r *http.Response) {
					r.Body.Close()
				})
				if buf, err := ioutil.ReadAll(resp.Body); err == nil {
					docs = append(docs, string(buf))
				}
			}
		}
	}
	pp.Merge(merge, docs, include, exclude)
	return true
}

func (pp *Dfpp) Merge(merge bool, docs []string, include, exclude map[string]bool) {
	result := make([]*string, 0)
	ops := make(map[string]*string)
	for _, doc := range docs {
		for line := range InstructionScanner(strings.NewReader(doc)) {
			fields := strings.Fields(line)
			if len(fields) > 0 {
				op := fields[0]
				if _, ok := exclude[op]; ok {
					continue
				}
				if _, ok := include[op]; len(include) > 0 && !ok {
					continue
				}
				details := strings.TrimPrefix(line, fields[0]+" ")

				if sref, ok := ops[op]; merge && ok {
					if op == "ENV" || op == "LABEL" {
						*sref += " \\\n" + strings.Repeat(" ", len(op)+1) + details
					} else if op == "RUN" {
						*sref += " && \\\n    " + details

						// squash redundent apt-get updates
						squash := "apt-get update"
						if ix := strings.Index(*sref, squash); ix >= 0 {
							rest := strings.Replace((*sref)[ix+len(squash):], squash, "echo skipping redundent apt-get-update", -1)
							*sref = (*sref)[0:ix+len(squash)] + rest
						}

					} else {
						dup := string(line)
						result = append(result, &dup)
					}
				} else {
					dup := string(line)
					result = append(result, &dup)
					ops[op] = result[len(result)-1]
				}
			}
		}
	}
	for _, line := range result {
		fmt.Fprintf(pp.Output, "%s\n", *line)
	}
}
<|endoftext|>


<commit_before>package swarm

import (
	"github.com/docker/docker/api/server/router"
	"github.com/docker/docker/daemon"
)

// buildRouter is a router to talk with the build controller
type swarmRouter struct {
	backend Backend
	routes  []router.Route
}

// NewRouter initializes a new build router
func NewRouter(d *daemon.Daemon, b Backend) router.Router {
	r := &swarmRouter{
		backend: b,
	}
	r.initRoutes()
	if d.HasExperimental() {
		r.addExperimentalRoutes()
	}
	return r
}

// Routes returns the available routers to the swarm controller
func (sr *swarmRouter) Routes() []router.Route {
	return sr.routes
}

func (sr *swarmRouter) addExperimentalRoutes() {
	sr.routes = append(sr.routes,
		router.Cancellable(router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs)),
	)
}

func (sr *swarmRouter) initRoutes() {
	sr.routes = []router.Route{
		router.NewPostRoute("/swarm/init", sr.initCluster),
		router.NewPostRoute("/swarm/join", sr.joinCluster),
		router.NewPostRoute("/swarm/leave", sr.leaveCluster),
		router.NewGetRoute("/swarm", sr.inspectCluster),
		router.NewGetRoute("/swarm/unlockkey", sr.getUnlockKey),
		router.NewPostRoute("/swarm/update", sr.updateCluster),
		router.NewPostRoute("/swarm/unlock", sr.unlockCluster),
		router.NewGetRoute("/services", sr.getServices),
		router.NewGetRoute("/services/{id}", sr.getService),
		router.NewPostRoute("/services/create", sr.createService),
		router.NewPostRoute("/services/{id}/update", sr.updateService),
		router.NewDeleteRoute("/services/{id}", sr.removeService),
		router.NewGetRoute("/nodes", sr.getNodes),
		router.NewGetRoute("/nodes/{id}", sr.getNode),
		router.NewDeleteRoute("/nodes/{id}", sr.removeNode),
		router.NewPostRoute("/nodes/{id}/update", sr.updateNode),
		router.NewGetRoute("/tasks", sr.getTasks),
		router.NewGetRoute("/tasks/{id}", sr.getTask),
		router.NewGetRoute("/secrets", sr.getSecrets),
		router.NewPostRoute("/secrets", sr.createSecret),
		router.NewDeleteRoute("/secrets/{id}", sr.removeSecret),
		router.NewGetRoute("/secrets/{id}", sr.getSecret),
		router.NewPostRoute("/secrets/{id}/update", sr.updateSecret),
	}
}
<commit_msg>rectify type defination for swarmRouter<commit_after>package swarm

import (
	"github.com/docker/docker/api/server/router"
	"github.com/docker/docker/daemon"
)

// swarmRouter is a router to talk with the build controller
type swarmRouter struct {
	backend Backend
	routes  []router.Route
}

// NewRouter initializes a new build router
func NewRouter(d *daemon.Daemon, b Backend) router.Router {
	r := &swarmRouter{
		backend: b,
	}
	r.initRoutes()
	if d.HasExperimental() {
		r.addExperimentalRoutes()
	}
	return r
}

// Routes returns the available routers to the swarm controller
func (sr *swarmRouter) Routes() []router.Route {
	return sr.routes
}

func (sr *swarmRouter) addExperimentalRoutes() {
	sr.routes = append(sr.routes,
		router.Cancellable(router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs)),
	)
}

func (sr *swarmRouter) initRoutes() {
	sr.routes = []router.Route{
		router.NewPostRoute("/swarm/init", sr.initCluster),
		router.NewPostRoute("/swarm/join", sr.joinCluster),
		router.NewPostRoute("/swarm/leave", sr.leaveCluster),
		router.NewGetRoute("/swarm", sr.inspectCluster),
		router.NewGetRoute("/swarm/unlockkey", sr.getUnlockKey),
		router.NewPostRoute("/swarm/update", sr.updateCluster),
		router.NewPostRoute("/swarm/unlock", sr.unlockCluster),
		router.NewGetRoute("/services", sr.getServices),
		router.NewGetRoute("/services/{id}", sr.getService),
		router.NewPostRoute("/services/create", sr.createService),
		router.NewPostRoute("/services/{id}/update", sr.updateService),
		router.NewDeleteRoute("/services/{id}", sr.removeService),
		router.NewGetRoute("/nodes", sr.getNodes),
		router.NewGetRoute("/nodes/{id}", sr.getNode),
		router.NewDeleteRoute("/nodes/{id}", sr.removeNode),
		router.NewPostRoute("/nodes/{id}/update", sr.updateNode),
		router.NewGetRoute("/tasks", sr.getTasks),
		router.NewGetRoute("/tasks/{id}", sr.getTask),
		router.NewGetRoute("/secrets", sr.getSecrets),
		router.NewPostRoute("/secrets", sr.createSecret),
		router.NewDeleteRoute("/secrets/{id}", sr.removeSecret),
		router.NewGetRoute("/secrets/{id}", sr.getSecret),
		router.NewPostRoute("/secrets/{id}/update", sr.updateSecret),
	}
}
<|endoftext|>


<commit_before>package system

import (
	"github.com/docker/docker/api/server/router"
	"github.com/docker/docker/api/server/router/local"
)

// systemRouter is a Router that provides information about
// the Docker system overall. It gathers information about
// host, daemon and container events.
type systemRouter struct {
	backend Backend
	routes  []router.Route
}

// NewRouter initializes a new systemRouter
func NewRouter(b Backend) router.Router {
	r := &systemRouter{
		backend: b,
	}

	r.routes = []router.Route{
		local.NewOptionsRoute("/", optionsHandler),
		local.NewGetRoute("/_ping", pingHandler),
		local.NewGetRoute("/events", r.getEvents),
		local.NewGetRoute("/info", r.getInfo),
		local.NewGetRoute("/version", r.getVersion),
		local.NewPostRoute("/auth", r.postAuth),
	}

	return r
}

// Routes return all the API routes dedicated to the docker system.
func (s *systemRouter) Routes() []router.Route {
	return s.routes
}
<commit_msg>Permit OPTIONS request against any url, fixes #19398<commit_after>package system

import (
	"github.com/docker/docker/api/server/router"
	"github.com/docker/docker/api/server/router/local"
)

// systemRouter is a Router that provides information about
// the Docker system overall. It gathers information about
// host, daemon and container events.
type systemRouter struct {
	backend Backend
	routes  []router.Route
}

// NewRouter initializes a new systemRouter
func NewRouter(b Backend) router.Router {
	r := &systemRouter{
		backend: b,
	}

	r.routes = []router.Route{
		local.NewOptionsRoute("/{anyroute:.*}", optionsHandler),
		local.NewGetRoute("/_ping", pingHandler),
		local.NewGetRoute("/events", r.getEvents),
		local.NewGetRoute("/info", r.getInfo),
		local.NewGetRoute("/version", r.getVersion),
		local.NewPostRoute("/auth", r.postAuth),
	}

	return r
}

// Routes return all the API routes dedicated to the docker system.
func (s *systemRouter) Routes() []router.Route {
	return s.routes
}
<|endoftext|>


<commit_before>// +build windows

package main

import (
	"fmt"
)

func (c CPU) Cpu_times() ([]CPU_Times, error) {
	ret := make([]CPU_Times, 0)

	fmt.Println("Windows")
	return ret, nil
}
<commit_msg>implements CPU info total on Windows. but it may be not correct.<commit_after>// +build windows

package main

import (
	"syscall"
	"unsafe"
)

var (
	modkernel32        = syscall.NewLazyDLL("kernel32.dll")
	procGetSystemTimes = modkernel32.NewProc("GetSystemTimes")
)

type FILETIME struct {
	DwLowDateTime  uint32
	DwHighDateTime uint32
}

func (c CPU) Cpu_times() ([]CPU_Times, error) {
	ret := make([]CPU_Times, 0)

	var lpIdleTime FILETIME
	var lpKernelTime FILETIME
	var lpUserTime FILETIME
	r, _, _ := procGetSystemTimes.Call(
		uintptr(unsafe.Pointer(&lpIdleTime)),
		uintptr(unsafe.Pointer(&lpKernelTime)),
		uintptr(unsafe.Pointer(&lpUserTime)))
	if r == 0 {
		return ret, syscall.GetLastError()
	}

	LO_T := float64(0.0000001)
	HI_T := (LO_T * 4294967296.0)
	idle := ((HI_T * float64(lpIdleTime.DwHighDateTime)) + (LO_T * float64(lpIdleTime.DwLowDateTime)))
	user := ((HI_T * float64(lpUserTime.DwHighDateTime)) + (LO_T * float64(lpUserTime.DwLowDateTime)))
	kernel := ((HI_T * float64(lpKernelTime.DwHighDateTime)) + (LO_T * float64(lpKernelTime.DwLowDateTime)))
	system := (kernel - idle)

	ret = append(ret, CPU_Times{
		Idle:   uint64(idle),
		User:   uint64(user),
		System: uint64(system),
	})
	return ret, nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"log"
	"regexp"
	// "net/http"
	// "io/ioutil"
	"github.com/PuerkitoBio/goquery"
)

const PTT_URL = "https://www.ptt.cc"

func harvest_board_indices(board_url string, board_name string)  {
	log.Printf("url: %s", board_url)
	log.Printf("name: %s", board_name)

	doc, err := goquery.NewDocument(board_url)
	if err != nil { log.Fatal(err) }

	re := regexp.MustCompile("/bbs/"+board_name+"/index([0-9]+)\\.html")
	doc.Find("a[href^='/bbs/" + board_name + "/index']").Each(func (_ int, s *goquery.Selection) {
		href, exists := s.Attr("href")
		if !exists { return }
		matched := re.FindStringSubmatch(href)
		if len(matched) == 0 { return }
		log.Printf("url: %s => %s", href, matched[1])
	})

	return;
}

func main() {
	board_name := os.Args[1]
	output_dir := os.Args[2]

	board_url := PTT_URL + "/bbs/" + board_name + "/index.html";
	output_board_dir := output_dir + "/" + board_name;

	os.MkdirAll(output_board_dir, os.ModeDir | os.ModePerm);

	harvest_board_indices( board_url, board_name );

}
<commit_msg>finish harvest_board_indices function.<commit_after>package main

import (
	"os"
	"log"
	"regexp"
	"strconv"
	// "net/http"
	// "io/ioutil"
	"github.com/PuerkitoBio/goquery"
)

const PTT_URL = "https://www.ptt.cc"

type BoardIndexPage struct {
	page_number int
	url string
}

func harvest_board_indices(board_url string, board_name string)  []BoardIndexPage {
	var ret []BoardIndexPage

	doc, err := goquery.NewDocument(board_url)
	if err != nil { log.Fatal(err) }

	re := regexp.MustCompile("/bbs/"+board_name+"/index([0-9]+)\\.html")
	doc.Find("a[href^='/bbs/" + board_name + "/index']").Each(func (_ int, s *goquery.Selection) {
		href, exists := s.Attr("href")
		if !exists { return }
		matched := re.FindStringSubmatch(href)
		if len(matched) == 0 { return }
		pn, err := strconv.Atoi(matched[1])
		if err != nil { log.Fatal(err) }
		ret = append( ret, BoardIndexPage{ pn, href } )
	})

	if (ret[0].page_number > ret[1].page_number) {
		ret[0],ret[1] = ret[1],ret[0]
	}

	for i := ret[0].page_number + 1; i < ret[1].page_number; i++ {
		ret = append(ret, BoardIndexPage{i, "/bbs/" + board_name + "/index" + strconv.Itoa(i) + ".html" } )
	}

	return ret;
}

func main() {
	board_name := os.Args[1]
	output_dir := os.Args[2]

	board_url := PTT_URL + "/bbs/" + board_name + "/index.html";
	output_board_dir := output_dir + "/" + board_name;

	os.MkdirAll(output_board_dir, os.ModeDir | os.ModePerm);

	board_indices := harvest_board_indices( board_url, board_name );
	log.Print(board_indices);
}
<|endoftext|>


<commit_before>// Copyright 2015 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package seeall

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"sync"
	"time"

	"appengine/datastore"
	"github.com/gorilla/mux"
	"github.com/maruel/go-lepton/appengine/seeall/api"
	"github.com/mjibson/goon"
)

func apiRoute(r *mux.Router) {
	r.HandleFunc("/api/seeall/v1/push", jsonAPI(pushHdlr))
}

func returnJSON(w http.ResponseWriter, ret interface{}) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(ret); err != nil {
		panic(err)
	}
}

func errorJSON(w http.ResponseWriter, err error, status int) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	log.Printf("Error:%s", err)
	ret := &struct{ Error error }{err}
	if err := json.NewEncoder(w).Encode(ret); err != nil {
		panic(err)
	}
}

func jsonAPI(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			errorJSON(w, errors.New("Only POST is supported"), http.StatusMethodNotAllowed)
			return
		}
		ct, ok := r.Header["Content-Type"]
		if !ok || len(ct) != 1 || ct[0] != "application/json" {
			errorJSON(w, errors.New("Requires Content-Type: application/json"), http.StatusBadRequest)
			return
		}
		f(w, r)
	}
}

func pushHdlr(w http.ResponseWriter, r *http.Request) {
	req := &api.PushRequest{}
	if err := json.NewDecoder(r.Body).Decode(req); err != nil {
		errorJSON(w, err, http.StatusBadRequest)
		return
	}
	n := goon.NewGoon(r)
	src := &Source{ID: req.ID}
	log.Printf("ID:%d Secret:%s; %d imgs", req.ID, base64.EncodeToString(req.Secret), len(req.Items))
	if err := n.Get(src); err != nil {
		errorJSON(w, err, http.StatusNotFound)
		return
	}

	// TODO(maruel): r.RemoteAddr against src.WhitelistIP.

	// TODO(maruel): Use an HMAC instead of dumb pass around.
	if src.Secret != req.Secret {
		errorJSON(w, errors.New("incorrect Secret"), http.StatusBadRequest)
		return
	}

	if len(req.Items) == 0 {
		errorJSON(w, errors.New("no item"), http.StatusBadRequest)
		return
	}

	is := &ImageStream{ID: 1, Parent: n.Key(src)}
	imgs := make([]Image, len(req.Items))
	now := time.Now().UTC()
	for i, item := range req.Items {
		imgs[i].Created = now
		imgs[i].RemoteAddr = r.RemoteAddr
		imgs[i].Timestamp = item.Timestamp
		imgs[i].PNG = item.PNG
	}
	opts := &datastore.TransactionOptions{}
	if err := n.RunInTransaction(func(tg *goon.Goon) error {
		if err := tg.Get(is); err != nil && err != datastore.ErrNoSuchEntity {
			return err
		}
		key := tg.Key(is)
		for i := range imgs {
			imgs[i].ID = is.NextID
			imgs[i].Parent = key
			is.NextID++
		}
		is.NextID++
		is.Modified = now
		// Sadly goon supports only one entity type per call, so do two concurrent
		// calls.
		var wg sync.WaitGroup
		var err1 error
		wg.Add(1)
		go func() {
			defer wg.Done()
			_, err1 = n.Put(is)
		}()
		var err2 error
		wg.Add(1)
		go func() {
			_, err2 = n.PutMulti(imgs)
		}()
		wg.Wait()
		if err1 != nil {
			return err1
		}
		return err2
	}, opts); err != nil {
		errorJSON(w, err, http.StatusInternalServerError)
		return
	}
	returnJSON(w, &struct{ OK bool }{true})
}
<commit_msg>Fix previous commit for server<commit_after>// Copyright 2015 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package seeall

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"sync"
	"time"

	"appengine/datastore"
	"github.com/gorilla/mux"
	"github.com/maruel/go-lepton/appengine/seeall/api"
	"github.com/mjibson/goon"
)

func apiRoute(r *mux.Router) {
	r.HandleFunc("/api/seeall/v1/push", jsonAPI(pushHdlr))
}

func returnJSON(w http.ResponseWriter, ret interface{}) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(ret); err != nil {
		panic(err)
	}
}

func errorJSON(w http.ResponseWriter, err error, status int) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	log.Printf("Error:%s", err)
	ret := &struct{ Error error }{err}
	if err := json.NewEncoder(w).Encode(ret); err != nil {
		panic(err)
	}
}

func jsonAPI(f http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			errorJSON(w, errors.New("Only POST is supported"), http.StatusMethodNotAllowed)
			return
		}
		ct, ok := r.Header["Content-Type"]
		if !ok || len(ct) != 1 || ct[0] != "application/json" {
			errorJSON(w, errors.New("Requires Content-Type: application/json"), http.StatusBadRequest)
			return
		}
		f(w, r)
	}
}

func pushHdlr(w http.ResponseWriter, r *http.Request) {
	req := &api.PushRequest{}
	if err := json.NewDecoder(r.Body).Decode(req); err != nil {
		errorJSON(w, err, http.StatusBadRequest)
		return
	}
	n := goon.NewGoon(r)
	src := &Source{ID: req.ID}
	log.Printf("ID:%d Secret:%s; %d imgs", req.ID, base64.URLEncoding.EncodeToString(req.Secret), len(req.Items))
	if err := n.Get(src); err != nil {
		errorJSON(w, err, http.StatusNotFound)
		return
	}

	// TODO(maruel): r.RemoteAddr against src.WhitelistIP.

	// TODO(maruel): Use an HMAC instead of dumb pass around.
	if !bytes.Equal(src.Secret, req.Secret) {
		errorJSON(w, errors.New("incorrect Secret"), http.StatusBadRequest)
		return
	}

	if len(req.Items) == 0 {
		errorJSON(w, errors.New("no item"), http.StatusBadRequest)
		return
	}

	is := &ImageStream{ID: 1, Parent: n.Key(src)}
	imgs := make([]Image, len(req.Items))
	now := time.Now().UTC()
	for i, item := range req.Items {
		imgs[i].Created = now
		imgs[i].RemoteAddr = r.RemoteAddr
		imgs[i].Timestamp = item.Timestamp
		imgs[i].PNG = item.PNG
	}
	opts := &datastore.TransactionOptions{}
	if err := n.RunInTransaction(func(tg *goon.Goon) error {
		if err := tg.Get(is); err != nil && err != datastore.ErrNoSuchEntity {
			return err
		}
		key := tg.Key(is)
		for i := range imgs {
			imgs[i].ID = is.NextID
			imgs[i].Parent = key
			is.NextID++
		}
		is.NextID++
		is.Modified = now
		// Sadly goon supports only one entity type per call, so do two concurrent
		// calls.
		var wg sync.WaitGroup
		var err1 error
		wg.Add(1)
		go func() {
			defer wg.Done()
			_, err1 = n.Put(is)
		}()
		var err2 error
		wg.Add(1)
		go func() {
			_, err2 = n.PutMulti(imgs)
		}()
		wg.Wait()
		if err1 != nil {
			return err1
		}
		return err2
	}, opts); err != nil {
		errorJSON(w, err, http.StatusInternalServerError)
		return
	}
	returnJSON(w, &struct{ OK bool }{true})
}
<|endoftext|>


<commit_before>package store

import "io"

// Searcher is an interface for the different searcher params
type Searcher interface {
	// expr returns a sqlite snippet used in the WHERE clause.
	Expr() string
	// params returns the required parameters for the sqlite snippet.
	Params() []interface{}
	// column returns the column name in the table
	Column() string
}

// between is a searcher which searches for values between (inclusive) the
// given values.
type between struct {
	col      string
	from, to int
}

// Between returns a Searcher that looks for an integer between two values
func Between(column string, from, to int) Searcher {
	return between{column, from, to}
}

func (b between) Expr() string {
	return "[" + b.col + "] BETWEEN ? AND ?"
}

func (b between) Params() []interface{} {
	return []interface{}{b.from, b.to}
}

func (b between) Column() string {
	return b.col
}

// like implements a search which uses the LIKE syntax in a WHERE clause.
type like struct {
	col, likeStr string
}

// Like returns a Searcher that looks for similar strings
func Like(column, likeStr string) Searcher {
	return like{column, likeStr}
}

func (l like) Expr() string {
	return "[" + l.col + "] LIKE ?"
}

func (l like) Params() []interface{} {
	return []interface{}{l.likeStr}
}

func (l like) Column() string {
	return l.col
}

type notLike struct {
	col, notLikeStr string
}

// NotLike returns a Searcher that excludes results with similar strings
func NotLike(column, notLikeStr string) Searcher {
	return notLike{column, notLikeStr}
}

func (n notLike) Expr() string {
	return "[" + n.col + "] NOT LIKE ?"
}

func (n notLike) Params() []interface{} {
	return []interface{}{n.notLikeStr}
}

func (n notLike) Column() string {
	return n.col
}

type matchString struct {
	col, match string
}

// MatchString searches for an exact (case-insensitive) string match on the given column
func MatchString(column, match string) Searcher {
	return matchString{column, match}
}

func (m matchString) Expr() string {
	return "[" + m.col + "] = ?"
}

func (m matchString) Params() []interface{} {
	return []interface{}{m.match}
}

func (m matchString) Column() string {
	return m.col
}

type matchInt struct {
	col   string
	match int
}

// MatchInt searches for an exact integer match on the given column
func MatchInt(column string, match int) Searcher {
	return matchInt{column, match}
}

func (m matchInt) Expr() string {
	return "[" + m.col + "] = ?"
}

func (m matchInt) Params() []interface{} {
	return []interface{}{m.match}
}

func (m matchInt) Column() string {
	return m.col
}

//

// Search is used for a custom (non primary key) search on a table.
//
// Returns the number of items found and an error if any occurred.
func (s *Store) Search(data []Interface, offset int, params ...Searcher) (int, error) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if len(data) == 0 {
		return 0, nil
	}
	table := tableName(data[0])
	cols := data[0].Get()
	vars := make([]string, 0, len(cols))
	first := true
	columns := ""
	for col := range cols {
		if first {
			first = false
		} else {
			columns += ", "
		}
		columns += "[" + col + "]"
		vars = append(vars, col)
	}
	var clause string
	paramVars := make([]interface{}, 0, len(params)+2)
	if len(params) > 0 {
		clause = "WHERE "
		first = true
		for _, param := range params {
			col := param.Column()
			if _, ok := cols[col]; !ok {
				return 0, UnknownColumn(col)
			}
			if first {
				first = false
			} else {
				clause += " AND "
			}
			clause += param.Expr()
			paramVars = append(paramVars, param.Params()...)
		}
	}
	var sortBy, dir string
	if s, ok := data[0].(sort); ok {
		sortBy = s.sortBy
		if s.asc {
			dir = "ASC"
		} else {
			dir = "DESC"
		}
	} else {
		sortBy = data[0].Key()
		dir = "ASC"
	}
	sql := "SELECT " + columns + " FROM [" + table + "] " + clause + " ORDER BY [" + sortBy + "] " + dir + " LIMIT ? OFFSET ?;"
	stmt, err := s.db.Query(sql, append(paramVars, len(data), offset)...)
	stmtVars := statement{Stmt: stmt, vars: vars}
	pos := 0
	for ; err == nil; err = stmt.Next() {
		if typeName := tableName(data[pos]); typeName != table {
			err = UnmatchedType{table, typeName}
		} else {
			err = stmtVars.Scan(stmtVars.Vars(data[pos].Get())...)
			pos++
		}
	}
	if err != nil && err != io.EOF {
		return pos, err
	}

	return pos, nil
}

// SearchCount performs the search and returns the number of results
func (s *Store) SearchCount(data Interface, params ...Searcher) (int, error) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	table := tableName(data)
	cols := data.Get()
	first := true
	var clause string
	paramVars := make([]interface{}, 0, len(params))
	if len(params) > 0 {
		clause = "WHERE "
		for _, param := range params {
			col := param.Column()
			if _, ok := cols[col]; !ok {
				return 0, UnknownColumn(col)
			}
			if first {
				first = false
			} else {
				clause += " AND "
			}
			clause += param.Expr()
			paramVars = append(paramVars, param.Params()...)
		}
	}
	sql := "SELECT count(1) FROM [" + table + "] " + clause + ";"
	stmt, err := s.db.Query(sql, paramVars...)
	if err != nil {
		return 0, err
	}
	count := 0
	err = stmt.Scan(&count)
	if err != nil && err != io.EOF {
		return 0, err
	}
	return count, nil
}

//Errors

// UnknownColumn is an error that occurrs when a search parameter requires a
// column which does not exist for the given type.
type UnknownColumn string

func (u UnknownColumn) Error() string {
	return "unknown column: " + string(u)
}
<commit_msg>Added Or searcher<commit_after>package store

import "io"

// Searcher is an interface for the different searcher params
type Searcher interface {
	// expr returns a sqlite snippet used in the WHERE clause.
	Expr() string
	// params returns the required parameters for the sqlite snippet.
	Params() []interface{}
	// column returns the column name in the table
	Column() string
}

// between is a searcher which searches for values between (inclusive) the
// given values.
type between struct {
	col      string
	from, to int
}

// Between returns a Searcher that looks for an integer between two values
func Between(column string, from, to int) Searcher {
	return between{column, from, to}
}

func (b between) Expr() string {
	return "[" + b.col + "] BETWEEN ? AND ?"
}

func (b between) Params() []interface{} {
	return []interface{}{b.from, b.to}
}

func (b between) Column() string {
	return b.col
}

// like implements a search which uses the LIKE syntax in a WHERE clause.
type like struct {
	col, likeStr string
}

// Like returns a Searcher that looks for similar strings
func Like(column, likeStr string) Searcher {
	return like{column, likeStr}
}

func (l like) Expr() string {
	return "[" + l.col + "] LIKE ?"
}

func (l like) Params() []interface{} {
	return []interface{}{l.likeStr}
}

func (l like) Column() string {
	return l.col
}

type notLike struct {
	col, notLikeStr string
}

// NotLike returns a Searcher that excludes results with similar strings
func NotLike(column, notLikeStr string) Searcher {
	return notLike{column, notLikeStr}
}

func (n notLike) Expr() string {
	return "[" + n.col + "] NOT LIKE ?"
}

func (n notLike) Params() []interface{} {
	return []interface{}{n.notLikeStr}
}

func (n notLike) Column() string {
	return n.col
}

type matchString struct {
	col, match string
}

// MatchString searches for an exact (case-insensitive) string match on the given column
func MatchString(column, match string) Searcher {
	return matchString{column, match}
}

func (m matchString) Expr() string {
	return "[" + m.col + "] = ?"
}

func (m matchString) Params() []interface{} {
	return []interface{}{m.match}
}

func (m matchString) Column() string {
	return m.col
}

type matchInt struct {
	col   string
	match int
}

// MatchInt searches for an exact integer match on the given column
func MatchInt(column string, match int) Searcher {
	return matchInt{column, match}
}

func (m matchInt) Expr() string {
	return "[" + m.col + "] = ?"
}

func (m matchInt) Params() []interface{} {
	return []interface{}{m.match}
}

func (m matchInt) Column() string {
	return m.col
}

type or []Searcher

func Or(searchers ...Searcher) Searcher {
	return or(searchers)
}

func (o or) Expr() string {
	expr := ""
	for n, searcher := range o {
		if n > 0 {
			expr += " OR "
		}
		expr += searcher.Expr()
	}
	return expr
}

func (o or) Params() []interface{} {
	p := make([]interface{}, 0, len(o))
	for _, searcher := range o {
		p = append(p, searcher.Params())
	}
	return p
}

func (o or) Column() string {
	return o[0].Column()
}

//

// Search is used for a custom (non primary key) search on a table.
//
// Returns the number of items found and an error if any occurred.
func (s *Store) Search(data []Interface, offset int, params ...Searcher) (int, error) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if len(data) == 0 {
		return 0, nil
	}
	table := tableName(data[0])
	cols := data[0].Get()
	vars := make([]string, 0, len(cols))
	first := true
	columns := ""
	for col := range cols {
		if first {
			first = false
		} else {
			columns += ", "
		}
		columns += "[" + col + "]"
		vars = append(vars, col)
	}
	var clause string
	paramVars := make([]interface{}, 0, len(params)+2)
	if len(params) > 0 {
		clause = "WHERE "
		first = true
		for _, param := range params {
			col := param.Column()
			if _, ok := cols[col]; !ok {
				return 0, UnknownColumn(col)
			}
			if first {
				first = false
			} else {
				clause += " AND "
			}
			clause += param.Expr()
			paramVars = append(paramVars, param.Params()...)
		}
	}
	var sortBy, dir string
	if s, ok := data[0].(sort); ok {
		sortBy = s.sortBy
		if s.asc {
			dir = "ASC"
		} else {
			dir = "DESC"
		}
	} else {
		sortBy = data[0].Key()
		dir = "ASC"
	}
	sql := "SELECT " + columns + " FROM [" + table + "] " + clause + " ORDER BY [" + sortBy + "] " + dir + " LIMIT ? OFFSET ?;"
	stmt, err := s.db.Query(sql, append(paramVars, len(data), offset)...)
	stmtVars := statement{Stmt: stmt, vars: vars}
	pos := 0
	for ; err == nil; err = stmt.Next() {
		if typeName := tableName(data[pos]); typeName != table {
			err = UnmatchedType{table, typeName}
		} else {
			err = stmtVars.Scan(stmtVars.Vars(data[pos].Get())...)
			pos++
		}
	}
	if err != nil && err != io.EOF {
		return pos, err
	}

	return pos, nil
}

// SearchCount performs the search and returns the number of results
func (s *Store) SearchCount(data Interface, params ...Searcher) (int, error) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	table := tableName(data)
	cols := data.Get()
	first := true
	var clause string
	paramVars := make([]interface{}, 0, len(params))
	if len(params) > 0 {
		clause = "WHERE "
		for _, param := range params {
			col := param.Column()
			if _, ok := cols[col]; !ok {
				return 0, UnknownColumn(col)
			}
			if first {
				first = false
			} else {
				clause += " AND "
			}
			clause += param.Expr()
			paramVars = append(paramVars, param.Params()...)
		}
	}
	sql := "SELECT count(1) FROM [" + table + "] " + clause + ";"
	stmt, err := s.db.Query(sql, paramVars...)
	if err != nil {
		return 0, err
	}
	count := 0
	err = stmt.Scan(&count)
	if err != nil && err != io.EOF {
		return 0, err
	}
	return count, nil
}

//Errors

// UnknownColumn is an error that occurrs when a search parameter requires a
// column which does not exist for the given type.
type UnknownColumn string

func (u UnknownColumn) Error() string {
	return "unknown column: " + string(u)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := net.Listen("unix", socket)
	syscall.Chmod(socket, 0770)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	// Make sure the socket closes
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			log.Printf("Captured: %v", sig)
			ln.Close()
		}
	}()

	backend := backend.New("status.txt", "open.txt", "closed.txt")
	s := server.New([]byte(os.Args[1]), 10, backend)
	s.Serve(ln)
}
<commit_msg>Proper signal capturing<commit_after>package main

import (
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := net.Listen("unix", socket)
	syscall.Chmod(socket, 0770)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	// Make sure the socket closes
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for sig := range c {
			log.Printf("Captured: %v", sig)
			ln.Close()
		}
	}()

	backend := backend.New("status.txt", "open.txt", "closed.txt")
	s := server.New([]byte(os.Args[1]), 10, backend)
	s.Serve(ln)
}
<|endoftext|>