<commit_before>package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
)

type Program struct {
	Name string `json:"name"`
	CommandPath string
}

func (p *Program) Execute() {
	log.Println("executing", p.CommandPath)
	cmd := exec.Command(p.CommandPath)
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		log.Println(err)
	}
	log.Println("Output:", stdout.String())
	log.Println("Err:", stderr.String())

	log.Println("finished executing", p.Name)
}

// does the given directory contain a 'main' file?
func isProgram(parentDir, dir string) bool {
	_, err := os.Stat(filepath.Join(parentDir, dir, "main"))
	return err == nil
}

func readDir(dir string) ([]*Program, error) {
	programs := []*Program{}

	log.Println("looking for programs in", dir)
	infos, err := ioutil.ReadDir(dir)
	if err != nil {
		return programs, err
	}

	for _, info := range infos {
		if err == nil && info.IsDir() && isProgram(dir, info.Name()) {
			commandPath := filepath.Join(dir, info.Name(), "main")
			log.Println("program executable:", commandPath)

			programs = append(programs, &Program{info.Name(), commandPath})
		}
	}

	return programs, nil
}
<commit_msg>have an ExecutionWriter that will log the stderr and stdout produced by executing the process<commit_after>package main

import (
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
)

type Program struct {
	Name string `json:"name"`
	CommandPath string
}

type ExecutionWriter struct {
	ProgramName string
}

func NewExecutionWriter(p *Program) *ExecutionWriter {
	return &ExecutionWriter{p.Name}
}

func (e *ExecutionWriter) Write(bs []byte) (n int, err error) {
	s := string(bs[:])
	log.Println(e.ProgramName, ":", s)
	return len(bs), nil
}

func (p *Program) Execute() {
	log.Println("executing", p.CommandPath)
	cmd := exec.Command(p.CommandPath)
	w := NewExecutionWriter(p)
	cmd.Stdout = w
	cmd.Stderr = w

	err := cmd.Run()

	if err != nil {
		log.Println(err)
	}

	log.Println("finished executing", p.Name)
}

// does the given directory contain a 'main' file?
func isProgram(parentDir, dir string) bool {
	_, err := os.Stat(filepath.Join(parentDir, dir, "main"))
	return err == nil
}

func readDir(dir string) ([]*Program, error) {
	programs := []*Program{}

	log.Println("looking for programs in", dir)
	infos, err := ioutil.ReadDir(dir)
	if err != nil {
		return programs, err
	}

	for _, info := range infos {
		if err == nil && info.IsDir() && isProgram(dir, info.Name()) {
			commandPath := filepath.Join(dir, info.Name(), "main")
			log.Println("program executable:", commandPath)

			programs = append(programs, &Program{info.Name(), commandPath})
		}
	}

	return programs, nil
}
<|endoftext|>


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

package keys

import "github.com/cockroachdb/cockroach/roachpb"

// Constants for system-reserved keys in the KV map.
var (
	// localPrefix is the prefix for keys which hold data local to a
	// RocksDB instance, such as store and range-specific metadata which
	// must not pollute the user key space, but must be collocate with
	// the store and/or ranges which they refer to. Storing this
	// information in the normal system keyspace would place the data on
	// an arbitrary set of stores, with no guarantee of collocation.
	// Local data includes store metadata, range metadata, response
	// cache values, transaction records, range-spanning binary tree
	// node pointers, and message queues.
	//
	// The local key prefix has been deliberately chosen to sort before
	// the SystemPrefix, because these local keys are not addressable
	// via the meta range addressing indexes.
	//
	// Some local data are not replicated, such as the store's 'ident'
	// record. Most local data are replicated, such as response cache
	// entries and transaction rows, but are not addressable as normal
	// MVCC values as part of transactions. Finally, some local data are
	// stored as MVCC values and are addressable as part of distributed
	// transactions, such as range metadata, range-spanning binary tree
	// node pointers, and message queues.
	localPrefix = []byte("\x00\x00\x00")

	// localSuffixLength specifies the length in bytes of all local
	// key suffixes.
	localSuffixLength = 4

	// There are three types of local key data enumerated below:
	// store-local, range-local by ID, and range-local by key.

	// localStorePrefix is the prefix identifying per-store data.
	localStorePrefix = MakeKey(localPrefix, roachpb.Key("s"))
	// localStoreIdentSuffix stores an immutable identifier for this
	// store, created when the store is first bootstrapped.
	localStoreIdentSuffix = []byte("iden")

	// LocalRangeIDPrefix is the prefix identifying per-range data
	// indexed by Range ID. The Range ID is appended to this prefix,
	// encoded using EncodeUvarint. The specific sort of per-range
	// metadata is identified by one of the suffixes listed below, along
	// with potentially additional encoded key info, such as a command
	// ID in the case of response cache entry.
	//
	// NOTE: LocalRangeIDPrefix must be kept in sync with the value
	// in storage/engine/db.cc.
	LocalRangeIDPrefix = roachpb.RKey(MakeKey(localPrefix, roachpb.Key("i")))
	// LocalResponseCacheSuffix is the suffix for keys storing
	// command responses used to guarantee idempotency (see ResponseCache).
	// NOTE: if this value changes, it must be updated in C++
	// (storage/engine/db.cc).
	LocalResponseCacheSuffix = []byte("res-")
	// localRaftLeaderLeaseSuffix is the suffix for the raft leader lease.
	localRaftLeaderLeaseSuffix = []byte("rfll")
	// localRaftTombstoneSuffix is the suffix for the raft tombstone.
	localRaftTombstoneSuffix = []byte("rftb")
	// localRaftHardStateSuffix is the Suffix for the raft HardState.
	localRaftHardStateSuffix = []byte("rfth")
	// localRaftAppliedIndexSuffix is the suffix for the raft applied index.
	localRaftAppliedIndexSuffix = []byte("rfta")
	// localRaftLogSuffix is the suffix for the raft log.
	localRaftLogSuffix = []byte("rftl")
	// localRaftTruncatedStateSuffix is the suffix for the RaftTruncatedState.
	localRaftTruncatedStateSuffix = []byte("rftt")
	// localRaftLastIndexSuffix is the suffix for raft's last index.
	localRaftLastIndexSuffix = []byte("rfti")
	// localRangeGCMetadataSuffix is the suffix for a range's GC metadata.
	localRangeGCMetadataSuffix = []byte("rgcm")
	// localRangeLastVerificationTimestampSuffix is the suffix for a range's
	// last verification timestamp (for checking integrity of on-disk data).
	localRangeLastVerificationTimestampSuffix = []byte("rlvt")
	// localRangeStatsSuffix is the suffix for range statistics.
	localRangeStatsSuffix = []byte("stat")

	// LocalRangePrefix is the prefix identifying per-range data indexed
	// by range key (either start key, or some key in the range). The
	// key is appended to this prefix, encoded using EncodeBytes. The
	// specific sort of per-range metadata is identified by one of the
	// suffixes listed below, along with potentially additional encoded
	// key info, such as the txn ID in the case of a transaction record.
	//
	// NOTE: LocalRangePrefix must be kept in sync with the value in
	// storage/engine/db.cc.
	LocalRangePrefix = roachpb.Key(MakeKey(localPrefix, roachpb.RKey("k")))
	LocalRangeMax    = LocalRangePrefix.PrefixEnd()
	// LocalRangeDescriptorSuffix is the suffix for keys storing
	// range descriptors. The value is a struct of type RangeDescriptor.
	LocalRangeDescriptorSuffix = roachpb.RKey("rdsc")
	// localRangeTreeNodeSuffix is the suffix for keys storing
	// range tree nodes.  The value is a struct of type RangeTreeNode.
	localRangeTreeNodeSuffix = roachpb.RKey("rtn-")
	// localTransactionSuffix specifies the key suffix for
	// transaction records. The additional detail is the transaction id.
	// NOTE: if this value changes, it must be updated in C++
	// (storage/engine/db.cc).
	localTransactionSuffix = roachpb.RKey("txn-")

	// LocalMax is the end of the local key range.
	LocalMax = roachpb.Key(localPrefix).PrefixEnd()

	// SystemPrefix indicates the beginning of the key range for
	// global, system data which are replicated across the cluster.
	SystemPrefix = roachpb.Key("\x00")
	SystemMax    = roachpb.Key("\x01")

	// MetaPrefix is the prefix for range metadata keys. Notice that
	// an extra null character in the prefix causes all range addressing
	// records to sort before any system tables which they might describe.
	MetaPrefix = MakeKey(SystemPrefix, roachpb.RKey("\x00meta"))
	// Meta1Prefix is the first level of key addressing. The value is a
	// RangeDescriptor struct.
	Meta1Prefix = roachpb.Key(MakeKey(MetaPrefix, roachpb.RKey("1")))
	// Meta2Prefix is the second level of key addressing. The value is a
	// RangeDescriptor struct.
	Meta2Prefix = roachpb.Key(MakeKey(MetaPrefix, roachpb.RKey("2")))
	// Meta1KeyMax is the end of the range of the first level of key addressing.
	// The value is a RangeDescriptor struct.
	Meta1KeyMax = roachpb.Key(MakeKey(Meta1Prefix, roachpb.RKeyMax))
	// Meta2KeyMax is the end of the range of the second level of key addressing.
	// The value is a RangeDescriptor struct.
	Meta2KeyMax = roachpb.Key(MakeKey(Meta2Prefix, roachpb.RKeyMax))

	// MetaMax is the end of the range of addressing keys.
	MetaMax = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("\x01")))

	// DescIDGenerator is the global descriptor ID generator sequence used for
	// table and namespace IDs.
	DescIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("desc-idgen")))
	// NodeIDGenerator is the global node ID generator sequence.
	NodeIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("node-idgen")))
	// RangeIDGenerator is the global range ID generator sequence.
	RangeIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("range-idgen")))
	// StoreIDGenerator is the global store ID generator sequence.
	StoreIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("store-idgen")))
	// RangeTreeRoot specifies the root range in the range tree.
	RangeTreeRoot = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("range-tree-root")))

	// StatusPrefix specifies the key prefix to store all status details.
	StatusPrefix = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("status-")))
	// StatusStorePrefix stores all status info for stores.
	StatusStorePrefix = roachpb.Key(MakeKey(StatusPrefix, roachpb.RKey("store-")))
	// StatusNodePrefix stores all status info for nodes.
	StatusNodePrefix = roachpb.Key(MakeKey(StatusPrefix, roachpb.RKey("node-")))

	// TableDataPrefix prefixes all table data. It is specifically chosen to
	// occur after the range of common user data prefixes so that tests which use
	// those prefixes will not see table data.
	TableDataPrefix = roachpb.Key("\xff")

	// UserTableDataMin is the start key of user structured data.
	UserTableDataMin = roachpb.Key(MakeTablePrefix(MaxReservedDescID + 1))
)

// Various IDs used by the structured data layer.
// NOTE: these must not change during the lifetime of a cluster.
const (
	// MaxReservedDescID is the maximum value of the system IDs
	// under 'TableDataPrefix'.
	// It is here only so that we may define keys/ranges using it.
	MaxReservedDescID = 999

	// RootNamespaceID is the ID of the root namespace.
	RootNamespaceID = 0

	// SystemDatabaseID and following are the database/table IDs for objects
	// in the system span.
	// NOTE: IDs should remain <= MaxReservedDescID.
	SystemDatabaseID  = 1
	NamespaceTableID  = 2
	DescriptorTableID = 3
	UsersTableID      = 4
	ZonesTableID      = 5
)
<commit_msg>Tiny comment fix to the db.cc path<commit_after>// Copyright 2015 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License. See the AUTHORS file
// for names of contributors.
//
// Author: Peter Mattis (peter@cockroachlabs.com)

package keys

import "github.com/cockroachdb/cockroach/roachpb"

// Constants for system-reserved keys in the KV map.
var (
	// localPrefix is the prefix for keys which hold data local to a
	// RocksDB instance, such as store and range-specific metadata which
	// must not pollute the user key space, but must be collocate with
	// the store and/or ranges which they refer to. Storing this
	// information in the normal system keyspace would place the data on
	// an arbitrary set of stores, with no guarantee of collocation.
	// Local data includes store metadata, range metadata, response
	// cache values, transaction records, range-spanning binary tree
	// node pointers, and message queues.
	//
	// The local key prefix has been deliberately chosen to sort before
	// the SystemPrefix, because these local keys are not addressable
	// via the meta range addressing indexes.
	//
	// Some local data are not replicated, such as the store's 'ident'
	// record. Most local data are replicated, such as response cache
	// entries and transaction rows, but are not addressable as normal
	// MVCC values as part of transactions. Finally, some local data are
	// stored as MVCC values and are addressable as part of distributed
	// transactions, such as range metadata, range-spanning binary tree
	// node pointers, and message queues.
	localPrefix = []byte("\x00\x00\x00")

	// localSuffixLength specifies the length in bytes of all local
	// key suffixes.
	localSuffixLength = 4

	// There are three types of local key data enumerated below:
	// store-local, range-local by ID, and range-local by key.

	// localStorePrefix is the prefix identifying per-store data.
	localStorePrefix = MakeKey(localPrefix, roachpb.Key("s"))
	// localStoreIdentSuffix stores an immutable identifier for this
	// store, created when the store is first bootstrapped.
	localStoreIdentSuffix = []byte("iden")

	// LocalRangeIDPrefix is the prefix identifying per-range data
	// indexed by Range ID. The Range ID is appended to this prefix,
	// encoded using EncodeUvarint. The specific sort of per-range
	// metadata is identified by one of the suffixes listed below, along
	// with potentially additional encoded key info, such as a command
	// ID in the case of response cache entry.
	//
	// NOTE: LocalRangeIDPrefix must be kept in sync with the value
	// in storage/engine/rocksdb/db.cc.
	LocalRangeIDPrefix = roachpb.RKey(MakeKey(localPrefix, roachpb.Key("i")))
	// LocalResponseCacheSuffix is the suffix for keys storing
	// command responses used to guarantee idempotency (see ResponseCache).
	// NOTE: if this value changes, it must be updated in C++
	// (storage/engine/rocksdb/db.cc).
	LocalResponseCacheSuffix = []byte("res-")
	// localRaftLeaderLeaseSuffix is the suffix for the raft leader lease.
	localRaftLeaderLeaseSuffix = []byte("rfll")
	// localRaftTombstoneSuffix is the suffix for the raft tombstone.
	localRaftTombstoneSuffix = []byte("rftb")
	// localRaftHardStateSuffix is the Suffix for the raft HardState.
	localRaftHardStateSuffix = []byte("rfth")
	// localRaftAppliedIndexSuffix is the suffix for the raft applied index.
	localRaftAppliedIndexSuffix = []byte("rfta")
	// localRaftLogSuffix is the suffix for the raft log.
	localRaftLogSuffix = []byte("rftl")
	// localRaftTruncatedStateSuffix is the suffix for the RaftTruncatedState.
	localRaftTruncatedStateSuffix = []byte("rftt")
	// localRaftLastIndexSuffix is the suffix for raft's last index.
	localRaftLastIndexSuffix = []byte("rfti")
	// localRangeGCMetadataSuffix is the suffix for a range's GC metadata.
	localRangeGCMetadataSuffix = []byte("rgcm")
	// localRangeLastVerificationTimestampSuffix is the suffix for a range's
	// last verification timestamp (for checking integrity of on-disk data).
	localRangeLastVerificationTimestampSuffix = []byte("rlvt")
	// localRangeStatsSuffix is the suffix for range statistics.
	localRangeStatsSuffix = []byte("stat")

	// LocalRangePrefix is the prefix identifying per-range data indexed
	// by range key (either start key, or some key in the range). The
	// key is appended to this prefix, encoded using EncodeBytes. The
	// specific sort of per-range metadata is identified by one of the
	// suffixes listed below, along with potentially additional encoded
	// key info, such as the txn ID in the case of a transaction record.
	//
	// NOTE: LocalRangePrefix must be kept in sync with the value in
	// storage/engine/rocksdb/db.cc.
	LocalRangePrefix = roachpb.Key(MakeKey(localPrefix, roachpb.RKey("k")))
	LocalRangeMax    = LocalRangePrefix.PrefixEnd()
	// LocalRangeDescriptorSuffix is the suffix for keys storing
	// range descriptors. The value is a struct of type RangeDescriptor.
	LocalRangeDescriptorSuffix = roachpb.RKey("rdsc")
	// localRangeTreeNodeSuffix is the suffix for keys storing
	// range tree nodes.  The value is a struct of type RangeTreeNode.
	localRangeTreeNodeSuffix = roachpb.RKey("rtn-")
	// localTransactionSuffix specifies the key suffix for
	// transaction records. The additional detail is the transaction id.
	// NOTE: if this value changes, it must be updated in C++
	// (storage/engine/rocksdb/db.cc).
	localTransactionSuffix = roachpb.RKey("txn-")

	// LocalMax is the end of the local key range.
	LocalMax = roachpb.Key(localPrefix).PrefixEnd()

	// SystemPrefix indicates the beginning of the key range for
	// global, system data which are replicated across the cluster.
	SystemPrefix = roachpb.Key("\x00")
	SystemMax    = roachpb.Key("\x01")

	// MetaPrefix is the prefix for range metadata keys. Notice that
	// an extra null character in the prefix causes all range addressing
	// records to sort before any system tables which they might describe.
	MetaPrefix = MakeKey(SystemPrefix, roachpb.RKey("\x00meta"))
	// Meta1Prefix is the first level of key addressing. The value is a
	// RangeDescriptor struct.
	Meta1Prefix = roachpb.Key(MakeKey(MetaPrefix, roachpb.RKey("1")))
	// Meta2Prefix is the second level of key addressing. The value is a
	// RangeDescriptor struct.
	Meta2Prefix = roachpb.Key(MakeKey(MetaPrefix, roachpb.RKey("2")))
	// Meta1KeyMax is the end of the range of the first level of key addressing.
	// The value is a RangeDescriptor struct.
	Meta1KeyMax = roachpb.Key(MakeKey(Meta1Prefix, roachpb.RKeyMax))
	// Meta2KeyMax is the end of the range of the second level of key addressing.
	// The value is a RangeDescriptor struct.
	Meta2KeyMax = roachpb.Key(MakeKey(Meta2Prefix, roachpb.RKeyMax))

	// MetaMax is the end of the range of addressing keys.
	MetaMax = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("\x01")))

	// DescIDGenerator is the global descriptor ID generator sequence used for
	// table and namespace IDs.
	DescIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("desc-idgen")))
	// NodeIDGenerator is the global node ID generator sequence.
	NodeIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("node-idgen")))
	// RangeIDGenerator is the global range ID generator sequence.
	RangeIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("range-idgen")))
	// StoreIDGenerator is the global store ID generator sequence.
	StoreIDGenerator = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("store-idgen")))
	// RangeTreeRoot specifies the root range in the range tree.
	RangeTreeRoot = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("range-tree-root")))

	// StatusPrefix specifies the key prefix to store all status details.
	StatusPrefix = roachpb.Key(MakeKey(SystemPrefix, roachpb.RKey("status-")))
	// StatusStorePrefix stores all status info for stores.
	StatusStorePrefix = roachpb.Key(MakeKey(StatusPrefix, roachpb.RKey("store-")))
	// StatusNodePrefix stores all status info for nodes.
	StatusNodePrefix = roachpb.Key(MakeKey(StatusPrefix, roachpb.RKey("node-")))

	// TableDataPrefix prefixes all table data. It is specifically chosen to
	// occur after the range of common user data prefixes so that tests which use
	// those prefixes will not see table data.
	TableDataPrefix = roachpb.Key("\xff")

	// UserTableDataMin is the start key of user structured data.
	UserTableDataMin = roachpb.Key(MakeTablePrefix(MaxReservedDescID + 1))
)

// Various IDs used by the structured data layer.
// NOTE: these must not change during the lifetime of a cluster.
const (
	// MaxReservedDescID is the maximum value of the system IDs
	// under 'TableDataPrefix'.
	// It is here only so that we may define keys/ranges using it.
	MaxReservedDescID = 999

	// RootNamespaceID is the ID of the root namespace.
	RootNamespaceID = 0

	// SystemDatabaseID and following are the database/table IDs for objects
	// in the system span.
	// NOTE: IDs should remain <= MaxReservedDescID.
	SystemDatabaseID  = 1
	NamespaceTableID  = 2
	DescriptorTableID = 3
	UsersTableID      = 4
	ZonesTableID      = 5
)
<|endoftext|>


<commit_before>package ps

// Process is the generic interface that is implemented on every platform
// and provides common operations for processes.
type Process interface {
	// Pid is the process ID for this process.
	Pid() int

	// PPid is the parent process ID for this process.
	PPid() int

	// Executable name running this process. This is not a path to the
	// executable.
	Executable() string
}

// Processes returns all processes.
//
// This of course will be a point-in-time snapshot of when this method was
// called. Some operating systems don't provide snapshot capability of the
// process table, in which case the process table returned might contain
// ephemeral entities that happened to be running when this was called.
func Processes() ([]Process, error) {
	return processes()
}

// FindProcess looks up a single process by pid.
//
// Process will be nil and error will be nil if a matching process is
// not found.
func FindProcess(pid int) (Process, error) {
	return findProcess(pid)
}
<commit_msg>Package docs<commit_after>// ps provides an API for finding and listing processes in a platform-agnostic
// way.
//
// NOTE: If you're reading these docs online via GoDocs or some other system,
// you might only see the Unix docs. This project makes heavy use of
// platform-specific implementations. We recommend reading the source if you
// are interested.
package ps

// Process is the generic interface that is implemented on every platform
// and provides common operations for processes.
type Process interface {
	// Pid is the process ID for this process.
	Pid() int

	// PPid is the parent process ID for this process.
	PPid() int

	// Executable name running this process. This is not a path to the
	// executable.
	Executable() string
}

// Processes returns all processes.
//
// This of course will be a point-in-time snapshot of when this method was
// called. Some operating systems don't provide snapshot capability of the
// process table, in which case the process table returned might contain
// ephemeral entities that happened to be running when this was called.
func Processes() ([]Process, error) {
	return processes()
}

// FindProcess looks up a single process by pid.
//
// Process will be nil and error will be nil if a matching process is
// not found.
func FindProcess(pid int) (Process, error) {
	return findProcess(pid)
}
<|endoftext|>


<commit_before>// +build windows

package joystick

import (
	"fmt"
	"golang.org/x/sys/windows"
	"math"
	"unsafe"
)

var PrintFunc func(x, y int, s string)

const (
	_MAXPNAMELEN            = 32
	_MAX_JOYSTICKOEMVXDNAME = 260
	_MAX_AXIS               = 6

	_JOY_RETURNX        = 1
	_JOY_RETURNY        = 2
	_JOY_RETURNZ        = 4
	_JOY_RETURNR        = 8
	_JOY_RETURNU        = 16
	_JOY_RETURNV        = 32
	_JOY_RETURNPOV      = 64
	_JOY_RETURNBUTTONS  = 128
	_JOY_RETURNRAWDATA  = 256
	_JOY_RETURNPOVCTS   = 512
	_JOY_RETURNCENTERED = 1024
	_JOY_USEDEADZONE    = 2048
	_JOY_RETURNALL      = (_JOY_RETURNX | _JOY_RETURNY | _JOY_RETURNZ | _JOY_RETURNR | _JOY_RETURNU | _JOY_RETURNV | _JOY_RETURNPOV | _JOY_RETURNBUTTONS)

	_JOYCAPS_HASZ    = 0x1
	_JOYCAPS_HASR    = 0x2
	_JOYCAPS_HASU    = 0x4
	_JOYCAPS_HASV    = 0x8
	_JOYCAPS_HASPOV  = 0x10
	_JOYCAPS_POV4DIR = 0x20
	_JOYCAPS_POVCTS  = 0x40
)

type JOYCAPS struct {
	wMid        uint16
	wPid        uint16
	szPname     [_MAXPNAMELEN]uint16
	wXmin       uint32
	wXmax       uint32
	wYmin       uint32
	wYmax       uint32
	wZmin       uint32
	wZmax       uint32
	wNumButtons uint32
	wPeriodMin  uint32
	wPeriodMax  uint32
	wRmin       uint32
	wRmax       uint32
	wUmin       uint32
	wUmax       uint32
	wVmin       uint32
	wVmax       uint32
	wCaps       uint32
	wMaxAxes    uint32
	wNumAxes    uint32
	wMaxButtons uint32
	szRegKey    [_MAXPNAMELEN]uint16
	szOEMVxD    [_MAX_JOYSTICKOEMVXDNAME]uint16
}

type JOYINFOEX struct {
	dwSize         uint32
	dwFlags        uint32
	dwAxis         [_MAX_AXIS]uint32
	dwButtons      uint32
	dwButtonNumber uint32
	dwPOV          uint32
	dwReserved1    uint32
	dwReserved2    uint32
}

var (
	winmmdll      = windows.MustLoadDLL("Winmm.dll")
	joyGetPosEx   = winmmdll.MustFindProc("joyGetPosEx")
	joyGetDevCaps = winmmdll.MustFindProc("joyGetDevCapsW")
)

type axisLimit struct {
	min, max uint32
}

type JoystickImpl struct {
	id           int
	axisCount    int
	povAxisCount int
	buttonCount  int
	name         string
	state        State
	axisLimits   []axisLimit
}

func mapValue(val, srcMin, srcMax, dstMin, dstMax int64) int64 {
	return (val-srcMin)*(dstMax-dstMin)/(srcMax-srcMin) + dstMin
}

func Open(id int) (Joystick, error) {

	js := &JoystickImpl{}
	js.id = id

	err := js.getJoyCaps()
	if err == nil {
		return js, nil
	}
	return nil, err
}

func (js *JoystickImpl) getJoyCaps() error {
	var caps JOYCAPS
	ret, _, _ := joyGetDevCaps.Call(uintptr(js.id), uintptr(unsafe.Pointer(&caps)), unsafe.Sizeof(caps))

	if ret != 0 {
		return fmt.Errorf("Failed to read Joystick %d", js.id)
	} else {
		js.axisCount = int(caps.wNumAxes)
		js.buttonCount = int(caps.wNumButtons)
		js.name = windows.UTF16ToString(caps.szPname[:])

		if caps.wCaps&_JOYCAPS_HASPOV != 0 {
			js.povAxisCount = 2
		}

		js.state.AxisData = make([]int, js.axisCount+js.povAxisCount, js.axisCount+js.povAxisCount)

		js.axisLimits = []axisLimit{
			{caps.wXmin, caps.wXmax},
			{caps.wYmin, caps.wYmax},
			{caps.wZmin, caps.wZmax},
			{caps.wRmin, caps.wRmax},
			{caps.wUmin, caps.wUmax},
			{caps.wVmin, caps.wVmax},
		}

		return nil
	}
}

func (js *JoystickImpl) getJoyPosEx() error {
	var info JOYINFOEX
	info.dwSize = uint32(unsafe.Sizeof(info))
	info.dwFlags = _JOY_RETURNALL
	ret, _, _ := joyGetPosEx.Call(uintptr(js.id), uintptr(unsafe.Pointer(&info)))

	if ret != 0 {
		return fmt.Errorf("Failed to read Joystick %d", js.id)
	} else {
		js.state.Buttons = info.dwButtons

		for i := 0; i < js.axisCount; i++ {
			js.state.AxisData[i] = int(mapValue(int64(info.dwAxis[i]),
				int64(js.axisLimits[i].min), int64(js.axisLimits[i].max), -32767, 32768))
		}

		if js.povAxisCount > 0 {
			angleDeg := float64(info.dwPOV) / 100.0
			if angleDeg > 359.0 {
				js.state.AxisData[js.axisCount] = 0
				js.state.AxisData[js.axisCount+1] = 0
				return nil
			}

			angleRad := angleDeg * math.Pi / 180.0
			sin, cos := math.Sincos(angleRad)

			//PrintFunc(20, 20, fmt.Sprintf("[%v][%v][%v]          ", angleDeg, sin, cos))

			switch {
			case sin < -0.01:
				js.state.AxisData[js.axisCount] = -32767
			case sin > 0.01:
				js.state.AxisData[js.axisCount] = 32768
			default:
				js.state.AxisData[js.axisCount] = 0
			}
			switch {
			case cos < -0.01:
				js.state.AxisData[js.axisCount+1] = 32768
			case cos > 0.01:
				js.state.AxisData[js.axisCount+1] = -32767
			default:
				js.state.AxisData[js.axisCount+1] = 0
			}
		}
		return nil
	}
}

func (js *JoystickImpl) AxisCount() int {
	return js.axisCount + js.povAxisCount
}

func (js *JoystickImpl) ButtonCount() int {
	return js.buttonCount
}

func (js *JoystickImpl) Name() string {
	return js.name
}

func (js *JoystickImpl) Read() (State, error) {
	err := js.getJoyPosEx()
	return js.state, err
}

func (js *JoystickImpl) Close() {
	// no impl under windows
}
<commit_msg>tidy up code<commit_after>// +build windows

package joystick

import (
	"fmt"
	"golang.org/x/sys/windows"
	"math"
	"unsafe"
)

var PrintFunc func(x, y int, s string)

const (
	_MAXPNAMELEN            = 32
	_MAX_JOYSTICKOEMVXDNAME = 260
	_MAX_AXIS               = 6

	_JOY_RETURNX        = 1
	_JOY_RETURNY        = 2
	_JOY_RETURNZ        = 4
	_JOY_RETURNR        = 8
	_JOY_RETURNU        = 16
	_JOY_RETURNV        = 32
	_JOY_RETURNPOV      = 64
	_JOY_RETURNBUTTONS  = 128
	_JOY_RETURNRAWDATA  = 256
	_JOY_RETURNPOVCTS   = 512
	_JOY_RETURNCENTERED = 1024
	_JOY_USEDEADZONE    = 2048
	_JOY_RETURNALL      = (_JOY_RETURNX | _JOY_RETURNY | _JOY_RETURNZ | _JOY_RETURNR | _JOY_RETURNU | _JOY_RETURNV | _JOY_RETURNPOV | _JOY_RETURNBUTTONS)

	_JOYCAPS_HASZ    = 0x1
	_JOYCAPS_HASR    = 0x2
	_JOYCAPS_HASU    = 0x4
	_JOYCAPS_HASV    = 0x8
	_JOYCAPS_HASPOV  = 0x10
	_JOYCAPS_POV4DIR = 0x20
	_JOYCAPS_POVCTS  = 0x40
)

type JOYCAPS struct {
	wMid        uint16
	wPid        uint16
	szPname     [_MAXPNAMELEN]uint16
	wXmin       uint32
	wXmax       uint32
	wYmin       uint32
	wYmax       uint32
	wZmin       uint32
	wZmax       uint32
	wNumButtons uint32
	wPeriodMin  uint32
	wPeriodMax  uint32
	wRmin       uint32
	wRmax       uint32
	wUmin       uint32
	wUmax       uint32
	wVmin       uint32
	wVmax       uint32
	wCaps       uint32
	wMaxAxes    uint32
	wNumAxes    uint32
	wMaxButtons uint32
	szRegKey    [_MAXPNAMELEN]uint16
	szOEMVxD    [_MAX_JOYSTICKOEMVXDNAME]uint16
}

type JOYINFOEX struct {
	dwSize         uint32
	dwFlags        uint32
	dwAxis         [_MAX_AXIS]uint32
	dwButtons      uint32
	dwButtonNumber uint32
	dwPOV          uint32
	dwReserved1    uint32
	dwReserved2    uint32
}

var (
	winmmdll      = windows.MustLoadDLL("Winmm.dll")
	joyGetPosEx   = winmmdll.MustFindProc("joyGetPosEx")
	joyGetDevCaps = winmmdll.MustFindProc("joyGetDevCapsW")
)

type axisLimit struct {
	min, max uint32
}

type JoystickImpl struct {
	id           int
	axisCount    int
	povAxisCount int
	buttonCount  int
	name         string
	state        State
	axisLimits   []axisLimit
}

func mapValue(val, srcMin, srcMax, dstMin, dstMax int64) int64 {
	return (val-srcMin)*(dstMax-dstMin)/(srcMax-srcMin) + dstMin
}

func Open(id int) (Joystick, error) {

	js := &JoystickImpl{}
	js.id = id

	err := js.getJoyCaps()
	if err == nil {
		return js, nil
	}
	return nil, err
}

func (js *JoystickImpl) getJoyCaps() error {
	var caps JOYCAPS
	ret, _, _ := joyGetDevCaps.Call(uintptr(js.id), uintptr(unsafe.Pointer(&caps)), unsafe.Sizeof(caps))

	if ret != 0 {
		return fmt.Errorf("Failed to read Joystick %d", js.id)
	} else {
		js.axisCount = int(caps.wNumAxes)
		js.buttonCount = int(caps.wNumButtons)
		js.name = windows.UTF16ToString(caps.szPname[:])

		if caps.wCaps&_JOYCAPS_HASPOV != 0 {
			js.povAxisCount = 2
		}

		js.state.AxisData = make([]int, js.axisCount+js.povAxisCount, js.axisCount+js.povAxisCount)

		js.axisLimits = []axisLimit{
			{caps.wXmin, caps.wXmax},
			{caps.wYmin, caps.wYmax},
			{caps.wZmin, caps.wZmax},
			{caps.wRmin, caps.wRmax},
			{caps.wUmin, caps.wUmax},
			{caps.wVmin, caps.wVmax},
		}

		return nil
	}
}

func axisFromPov(povVal float64) int {
	switch {
	case povVal < -0.5:
		return -32767
	case povVal > 0.5:
		return 32768
	default:
		return 0
	}
}

func (js *JoystickImpl) getJoyPosEx() error {
	var info JOYINFOEX
	info.dwSize = uint32(unsafe.Sizeof(info))
	info.dwFlags = _JOY_RETURNALL
	ret, _, _ := joyGetPosEx.Call(uintptr(js.id), uintptr(unsafe.Pointer(&info)))

	if ret != 0 {
		return fmt.Errorf("Failed to read Joystick %d", js.id)
	} else {
		js.state.Buttons = info.dwButtons

		for i := 0; i < js.axisCount; i++ {
			js.state.AxisData[i] = int(mapValue(int64(info.dwAxis[i]),
				int64(js.axisLimits[i].min), int64(js.axisLimits[i].max), -32767, 32768))
		}

		if js.povAxisCount > 0 {
			angleDeg := float64(info.dwPOV) / 100.0
			if angleDeg > 359.0 {
				js.state.AxisData[js.axisCount] = 0
				js.state.AxisData[js.axisCount+1] = 0
				return nil
			}

			angleRad := angleDeg * math.Pi / 180.0
			sin, cos := math.Sincos(angleRad)

			js.state.AxisData[js.axisCount] = axisFromPov(sin)
			js.state.AxisData[js.axisCount+1] = axisFromPov(-cos)
		}
		return nil
	}
}

func (js *JoystickImpl) AxisCount() int {
	return js.axisCount + js.povAxisCount
}

func (js *JoystickImpl) ButtonCount() int {
	return js.buttonCount
}

func (js *JoystickImpl) Name() string {
	return js.name
}

func (js *JoystickImpl) Read() (State, error) {
	err := js.getJoyPosEx()
	return js.state, err
}

func (js *JoystickImpl) Close() {
	// no impl under windows
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
)

var UniqueId string
var heartbeatChan chan bool

func processCommandLineArguments() (int, int, error) {
	var hostId = flag.Int("hostId", 0, "The unique id for the host.")
	var port = flag.Int("port", 0, "The per-host unique port")

	flag.Parse()

	if *hostId == 0 || *port == 0 {
		return 0, 0,
			fmt.Errorf("Cannot proceed with hostId %d and port %d\n"+
				"Usage: ./identity -hostId hostId -port port", *hostId, *port)
	}
	return *hostId, *port, nil
}

func getMyUniqueId() string {
	return UniqueId
}

func main() {
	hostId, port, err := processCommandLineArguments()
	if err != nil {
		fmt.Println("Problem parsing arguments:", err)
		return
	}
	heartbeatChan = make(chan bool)
	UniqueId = fmt.Sprintf("%d_%d", hostId, port)
	err = initLogger()
	if err != nil {
		fmt.Println("Problem opening file", err)
		return
	}
	stateMachineInit()
	nodeInit()
	parseConfig()
	err = startServer(port)
	if err != nil {
		fmt.Println("Problem starting server", err)
		return
	}
}
<commit_msg>Make sure we are part of the config.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
)

var UniqueId string
var heartbeatChan chan bool

func processCommandLineArguments() (int, int, error) {
	var hostId = flag.Int("hostId", 0, "The unique id for the host.")
	var port = flag.Int("port", 0, "The per-host unique port")

	flag.Parse()

	if *hostId == 0 || *port == 0 {
		return 0, 0,
			fmt.Errorf("Cannot proceed with hostId %d and port %d\n"+
				"Usage: ./identity -hostId hostId -port port", *hostId, *port)
	}
	return *hostId, *port, nil
}

func getMyUniqueId() string {
	return UniqueId
}

func main() {
	hostId, port, err := processCommandLineArguments()
	if err != nil {
		fmt.Println("Problem parsing arguments:", err)
		return
	}
	heartbeatChan = make(chan bool)
	UniqueId = fmt.Sprintf("%d_%d", hostId, port)
	err = initLogger()
	if err != nil {
		fmt.Println("Problem opening file", err)
		return
	}
	stateMachineInit()
	nodeInit()
	parseConfig()
	if findNode(UniqueId) != nil {
		log.Fatal("Could not find myself in the config: ", UniqueId)
	}
	err = startServer(port)
	if err != nil {
		fmt.Println("Problem starting server", err)
		return
	}
}
<|endoftext|>


<commit_before>// goforever - processes management
// Copyright (c) 2013 Garrett Woodworth (https://github.com/gwoo).

package main

import (
	"testing"
)

func TestPidfile(t *testing.T) {
	c := &Config{"", "",
		[]*Process{&Process{
			Name:    "test",
			Pidfile: "test.pid",
		}},
	}
	p := c.Get("test")
	err := p.Pidfile.write(100)
	if err != nil {
		t.Errorf("Error: %s.", err)
		return
	}
	ex := 100
	r := p.Pidfile.read()
	if ex != r {
		t.Errorf("Expected %#v. Result %#v\n", ex, r)
	}

	s := p.Pidfile.delete()
	if s != true {
		t.Error("Failed to remove pidfile.")
		return
	}
}

func TestProcessStart(t *testing.T) {
	c := &Config{
		"", "",
		[]*Process{&Process{
			Name:    "example",
			Command: "example/example",
			Pidfile: "example/example.pid",
			Logfile: "example/logs/example.debug.log",
			Errfile: "example/logs/example.errors.log",
			Respawn: 3,
		}},
	}
	p := c.Get("example")
	p.start("example")
	ex := 0
	r := p.x.Pid
	if ex >= r {
		t.Errorf("Expected %#v < %#v\n", ex, r)
	}
	p.stop()
}
<commit_msg>Fixing process_test.<commit_after>// goforever - processes management
// Copyright (c) 2013 Garrett Woodworth (https://github.com/gwoo).

package main

import (
	"testing"
)

func TestPidfile(t *testing.T) {
	c := &Config{"", "",
		[]*Process{&Process{
			Name:    "test",
			Pidfile: "test.pid",
		}},
	}
	p := c.Get("test")
	err := p.Pidfile.write(100)
	if err != nil {
		t.Errorf("Error: %s.", err)
		return
	}
	ex := 100
	r := p.Pidfile.read()
	if ex != r {
		t.Errorf("Expected %#v. Result %#v\n", ex, r)
	}

	s := p.Pidfile.delete()
	if s != true {
		t.Error("Failed to remove pidfile.")
		return
	}
}

func TestProcessStart(t *testing.T) {
	c := &Config{
		"", "",
		[]*Process{&Process{
			Name:    "bash",
			Command: "/bin/bash",
			Pidfile: "echo.pid",
			Logfile: "debug.log",
			Errfile: "error.log",
			Respawn: 3,
		}},
	}
	p := c.Get("bash")
	p.start("bash")
	ex := 0
	r := p.x.Pid
	if ex >= r {
		t.Errorf("Expected %#v < %#v\n", ex, r)
	}
	p.stop()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os/exec"
	"strings"
	"syscall"
)

type ServiceIP struct {
	VirtualIP string
}

func (service *ServiceIP) Up() {
	proc := exec.Command("/bin/sh", "-c", "ip route | grep -w src | grep -v -w linkdown | awk '{print $NF}' | tail -n1")
	output, err := proc.CombinedOutput()
	if err != nil {
		log.Fatalf("Failed to get host ip. %v\n", err)
	}
	hostIP := strings.TrimSpace(string(output))
	service.ensureDNAT("PREROUTING", hostIP)
	service.ensureDNAT("OUTPUT", hostIP)
}

func (service *ServiceIP) ensureDNAT(chain, hostIP string) {
	service.sh("iptables -t nat -A %v -d %v -j DNAT --to %v", chain, service.VirtualIP, hostIP)
}

func (service *ServiceIP) sh(cmd string, args ...interface{}) int {
	cmdline := fmt.Sprintf(cmd, args...)
	proc := exec.Command("/bin/sh", "-c", cmdline)
	output, err := proc.CombinedOutput()
	if err != nil {
		log.Printf("Error executing: %v\n", cmdline)
		log.Println(err)
		return 1
	} else {
		exitCode := proc.ProcessState.Sys().(syscall.WaitStatus)
		if exitCode != nil {
			log.Printf("Error executing (exit code %v): %v\n", exitCode, cmdline)
			log.Println(strings.TrimSpace(string(output)))
		}
		return int(exitCode)
	}
}
<commit_msg>braindead<commit_after>package main

import (
	"fmt"
	"log"
	"os/exec"
	"strings"
	"syscall"
)

type ServiceIP struct {
	VirtualIP string
}

func (service *ServiceIP) Up() {
	proc := exec.Command("/bin/sh", "-c", "ip route | grep -w src | grep -v -w linkdown | awk '{print $NF}' | tail -n1")
	output, err := proc.CombinedOutput()
	if err != nil {
		log.Fatalf("Failed to get host ip. %v\n", err)
	}
	hostIP := strings.TrimSpace(string(output))
	service.ensureDNAT("PREROUTING", hostIP)
	service.ensureDNAT("OUTPUT", hostIP)
}

func (service *ServiceIP) ensureDNAT(chain, hostIP string) {
	service.sh("iptables -t nat -A %v -d %v -j DNAT --to %v", chain, service.VirtualIP, hostIP)
}

func (service *ServiceIP) sh(cmd string, args ...interface{}) int {
	cmdline := fmt.Sprintf(cmd, args...)
	proc := exec.Command("/bin/sh", "-c", cmdline)
	output, err := proc.CombinedOutput()
	if err != nil {
		log.Printf("Error executing: %v\n", cmdline)
		log.Println(err)
		return 1
	} else {
		exitCode := proc.ProcessState.Sys().(syscall.WaitStatus)
		if exitCode != 0 {
			log.Printf("Error executing (exit code %v): %v\n", exitCode, cmdline)
			log.Println(strings.TrimSpace(string(output)))
		}
		return int(exitCode)
	}
}
<|endoftext|>


<commit_before>// Package settings regroups some API methods to facilitate the usage of the
// io.cozy settings documents.
package settings

import (
	"encoding/json"
	"net/http"

	"github.com/cozy/cozy-stack/pkg/consts"
	"github.com/cozy/cozy-stack/pkg/couchdb"
	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/cozy/cozy-stack/pkg/permissions"
	"github.com/cozy/cozy-stack/web/jsonapi"
	"github.com/cozy/cozy-stack/web/middlewares"
	webpermissions "github.com/cozy/cozy-stack/web/permissions"
	"github.com/cozy/echo"
)

type apiInstance struct {
	doc *couchdb.JSONDoc
}

func (i *apiInstance) ID() string                             { return i.doc.ID() }
func (i *apiInstance) Rev() string                            { return i.doc.Rev() }
func (i *apiInstance) DocType() string                        { return consts.Settings }
func (i *apiInstance) Clone() couchdb.Doc                     { return i }
func (i *apiInstance) SetID(id string)                        { i.doc.SetID(id) }
func (i *apiInstance) SetRev(rev string)                      { i.doc.SetRev(rev) }
func (i *apiInstance) Relationships() jsonapi.RelationshipMap { return nil }
func (i *apiInstance) Included() []jsonapi.Object             { return nil }
func (i *apiInstance) Links() *jsonapi.LinksList {
	return &jsonapi.LinksList{Self: "/settings/instance"}
}
func (i *apiInstance) MarshalJSON() ([]byte, error) {
	return json.Marshal(i.doc)
}

func getInstance(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	doc, err := inst.SettingsDocument()
	if err != nil {
		return err
	}

	doc.M["locale"] = inst.Locale
	doc.M["onboarding_finished"] = inst.OnboardingFinished
	doc.M["auto_update"] = !inst.NoAutoUpdate
	doc.M["auth_mode"] = instance.AuthModeToString(inst.AuthMode)
	doc.M["tos"] = inst.TOSSigned
	doc.M["tos_latest"] = inst.TOSLatest
	doc.M["uuid"] = inst.UUID
	doc.M["context"] = inst.ContextName

	if err = webpermissions.Allow(c, permissions.GET, doc); err != nil {
		return err
	}

	return jsonapi.Data(c, http.StatusOK, &apiInstance{doc}, nil)
}

func updateInstance(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	doc := &couchdb.JSONDoc{}
	obj, err := jsonapi.Bind(c.Request().Body, doc)
	if err != nil {
		return err
	}

	doc.Type = consts.Settings
	doc.SetID(consts.InstanceSettingsID)
	doc.SetRev(obj.Meta.Rev)

	if err = webpermissions.Allow(c, webpermissions.PUT, doc); err != nil {
		return err
	}

	pdoc, err := webpermissions.GetPermission(c)
	if err != nil || pdoc.Type != permissions.TypeCLI {
		delete(doc.M, "auth_mode")
		delete(doc.M, "tos")
		delete(doc.M, "tos_latest")
		delete(doc.M, "uuid")
		delete(doc.M, "context")
	}

	if err := instance.Patch(inst, &instance.Options{SettingsObj: doc}); err != nil {
		return err
	}

	doc.M["locale"] = inst.Locale
	doc.M["onboarding_finished"] = inst.OnboardingFinished
	doc.M["auto_update"] = !inst.NoAutoUpdate
	doc.M["auth_mode"] = instance.AuthModeToString(inst.AuthMode)
	doc.M["tos"] = inst.TOSSigned
	doc.M["tos_latest"] = inst.TOSLatest
	doc.M["uuid"] = inst.UUID
	doc.M["context"] = inst.ContextName

	return jsonapi.Data(c, http.StatusOK, &apiInstance{doc}, nil)
}

func updateInstanceTOS(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	// Allow any request from OAuth tokens to use this route
	pdoc, err := webpermissions.GetPermission(c)
	if err != nil {
		return err
	}
	if pdoc.Type != permissions.TypeOauth {
		return echo.NewHTTPError(http.StatusForbidden)
	}

	if err := inst.ManagerSignTOS(c.Request()); err != nil {
		return err
	}

	return c.NoContent(http.StatusNoContent)
}

func updateInstanceAuthMode(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	if err := webpermissions.AllowWholeType(c, permissions.PUT, consts.Settings); err != nil {
		return err
	}

	args := struct {
		AuthMode                string `json:"auth_mode"`
		TwoFactorActivationCode string `json:"two_factor_activation_code"`
	}{}
	if err := c.Bind(&args); err != nil {
		return err
	}

	authMode, err := instance.StringToAuthMode(args.AuthMode)
	if err != nil {
		return jsonapi.BadRequest(err)
	}
	if inst.HasAuthMode(authMode) {
		return c.NoContent(http.StatusNoContent)
	}

	switch authMode {
	case instance.Basic:
	case instance.TwoFactorMail:
		if args.TwoFactorActivationCode == "" {
			if err = inst.SendMailConfirmationCode(); err != nil {
				return err
			}
			return c.NoContent(http.StatusNoContent)
		}
		if ok := inst.ValidateMailConfirmationCode(args.TwoFactorActivationCode); !ok {
			return c.NoContent(http.StatusUnprocessableEntity)
		}
	}

	err = instance.Patch(inst, &instance.Options{AuthMode: args.AuthMode})
	if err != nil {
		return err
	}

	return c.NoContent(http.StatusNoContent)
}
<commit_msg>Allow CLI token for updating TOS version<commit_after>// Package settings regroups some API methods to facilitate the usage of the
// io.cozy settings documents.
package settings

import (
	"encoding/json"
	"net/http"

	"github.com/cozy/cozy-stack/pkg/consts"
	"github.com/cozy/cozy-stack/pkg/couchdb"
	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/cozy/cozy-stack/pkg/permissions"
	"github.com/cozy/cozy-stack/web/jsonapi"
	"github.com/cozy/cozy-stack/web/middlewares"
	webpermissions "github.com/cozy/cozy-stack/web/permissions"
	"github.com/cozy/echo"
)

type apiInstance struct {
	doc *couchdb.JSONDoc
}

func (i *apiInstance) ID() string                             { return i.doc.ID() }
func (i *apiInstance) Rev() string                            { return i.doc.Rev() }
func (i *apiInstance) DocType() string                        { return consts.Settings }
func (i *apiInstance) Clone() couchdb.Doc                     { return i }
func (i *apiInstance) SetID(id string)                        { i.doc.SetID(id) }
func (i *apiInstance) SetRev(rev string)                      { i.doc.SetRev(rev) }
func (i *apiInstance) Relationships() jsonapi.RelationshipMap { return nil }
func (i *apiInstance) Included() []jsonapi.Object             { return nil }
func (i *apiInstance) Links() *jsonapi.LinksList {
	return &jsonapi.LinksList{Self: "/settings/instance"}
}
func (i *apiInstance) MarshalJSON() ([]byte, error) {
	return json.Marshal(i.doc)
}

func getInstance(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	doc, err := inst.SettingsDocument()
	if err != nil {
		return err
	}

	doc.M["locale"] = inst.Locale
	doc.M["onboarding_finished"] = inst.OnboardingFinished
	doc.M["auto_update"] = !inst.NoAutoUpdate
	doc.M["auth_mode"] = instance.AuthModeToString(inst.AuthMode)
	doc.M["tos"] = inst.TOSSigned
	doc.M["tos_latest"] = inst.TOSLatest
	doc.M["uuid"] = inst.UUID
	doc.M["context"] = inst.ContextName

	if err = webpermissions.Allow(c, permissions.GET, doc); err != nil {
		return err
	}

	return jsonapi.Data(c, http.StatusOK, &apiInstance{doc}, nil)
}

func updateInstance(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	doc := &couchdb.JSONDoc{}
	obj, err := jsonapi.Bind(c.Request().Body, doc)
	if err != nil {
		return err
	}

	doc.Type = consts.Settings
	doc.SetID(consts.InstanceSettingsID)
	doc.SetRev(obj.Meta.Rev)

	if err = webpermissions.Allow(c, webpermissions.PUT, doc); err != nil {
		return err
	}

	pdoc, err := webpermissions.GetPermission(c)
	if err != nil || pdoc.Type != permissions.TypeCLI {
		delete(doc.M, "auth_mode")
		delete(doc.M, "tos")
		delete(doc.M, "tos_latest")
		delete(doc.M, "uuid")
		delete(doc.M, "context")
	}

	if err := instance.Patch(inst, &instance.Options{SettingsObj: doc}); err != nil {
		return err
	}

	doc.M["locale"] = inst.Locale
	doc.M["onboarding_finished"] = inst.OnboardingFinished
	doc.M["auto_update"] = !inst.NoAutoUpdate
	doc.M["auth_mode"] = instance.AuthModeToString(inst.AuthMode)
	doc.M["tos"] = inst.TOSSigned
	doc.M["tos_latest"] = inst.TOSLatest
	doc.M["uuid"] = inst.UUID
	doc.M["context"] = inst.ContextName

	return jsonapi.Data(c, http.StatusOK, &apiInstance{doc}, nil)
}

func updateInstanceTOS(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	// Allow any request from OAuth tokens to use this route
	pdoc, err := webpermissions.GetPermission(c)
	if err != nil {
		return err
	}
	if pdoc.Type != permissions.TypeOauth && pdoc.Type != permissions.TypeCLI {
		return echo.NewHTTPError(http.StatusForbidden)
	}

	if err := inst.ManagerSignTOS(c.Request()); err != nil {
		return err
	}

	return c.NoContent(http.StatusNoContent)
}

func updateInstanceAuthMode(c echo.Context) error {
	inst := middlewares.GetInstance(c)

	if err := webpermissions.AllowWholeType(c, permissions.PUT, consts.Settings); err != nil {
		return err
	}

	args := struct {
		AuthMode                string `json:"auth_mode"`
		TwoFactorActivationCode string `json:"two_factor_activation_code"`
	}{}
	if err := c.Bind(&args); err != nil {
		return err
	}

	authMode, err := instance.StringToAuthMode(args.AuthMode)
	if err != nil {
		return jsonapi.BadRequest(err)
	}
	if inst.HasAuthMode(authMode) {
		return c.NoContent(http.StatusNoContent)
	}

	switch authMode {
	case instance.Basic:
	case instance.TwoFactorMail:
		if args.TwoFactorActivationCode == "" {
			if err = inst.SendMailConfirmationCode(); err != nil {
				return err
			}
			return c.NoContent(http.StatusNoContent)
		}
		if ok := inst.ValidateMailConfirmationCode(args.TwoFactorActivationCode); !ok {
			return c.NoContent(http.StatusUnprocessableEntity)
		}
	}

	err = instance.Patch(inst, &instance.Options{AuthMode: args.AuthMode})
	if err != nil {
		return err
	}

	return c.NoContent(http.StatusNoContent)
}
<|endoftext|>


<commit_before>// Go Riemann client
//
// TODO(cloudhead): pbEventsToEvents should parse Attributes field
package raidman

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"reflect"
	"sync"

	pb "code.google.com/p/goprotobuf/proto"
	"github.com/swdunlop/raidman/proto"
)

type network interface {
	Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error)
}

type tcp struct{}

type udp struct{}

// Client represents a connection to a Riemann server
type Client struct {
	sync.Mutex
	net        network
	connection net.Conn
}

// An Event represents a single Riemann event
type Event struct {
	Ttl         float32
	Time        int64
	Tags        []string
	Host        string // Defaults to os.Hostname()
	State       string
	Service     string
	Metric      interface{} // Could be Int, Float32, Float64
	Attributes  map[string]interface{}
	Description string
}

// Dial establishes a connection to a Riemann server at addr, on the network
// netwrk.
//
// Known networks are "tcp", "tcp4", "tcp6", "udp", "udp4", and "udp6".
func Dial(netwrk, addr string) (c *Client, err error) {
	c = new(Client)

	var cnet network
	switch netwrk {
	case "tcp", "tcp4", "tcp6":
		cnet = new(tcp)
	case "udp", "udp4", "udp6":
		cnet = new(udp)
	default:
		return nil, fmt.Errorf("dial %q: unsupported network %q", netwrk, netwrk)
	}

	c.net = cnet
	c.connection, err = net.Dial(netwrk, addr)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (network *tcp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
	msg := &proto.Msg{}
	data, err := pb.Marshal(message)
	if err != nil {
		return msg, err
	}
	b := new(bytes.Buffer)
	if err = binary.Write(b, binary.BigEndian, uint32(len(data))); err != nil {
		return msg, err
	}
	if _, err = conn.Write(b.Bytes()); err != nil {
		return msg, err
	}
	if _, err = conn.Write(data); err != nil {
		return msg, err
	}
	var header uint32
	if err = binary.Read(conn, binary.BigEndian, &header); err != nil {
		return msg, err
	}
	response := make([]byte, header)
	if err = readFully(conn, response); err != nil {
		return msg, err
	}
	if err = pb.Unmarshal(response, msg); err != nil {
		return msg, err
	}
	if msg.GetOk() != true {
		return msg, errors.New(msg.GetError())
	}
	return msg, nil
}

func readFully(r io.Reader, p []byte) error {
	for len(p) > 0 {
		n, err := r.Read(p)
		p = p[n:]
		if err != nil {
			return err
		}
	}
	return nil
}

func (network *udp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
	data, err := pb.Marshal(message)
	if err != nil {
		return nil, err
	}
	if _, err = conn.Write(data); err != nil {
		return nil, err
	}

	return nil, nil
}

func eventToPbEvent(event *Event) (*proto.Event, error) {
	var e proto.Event

	if event.Host == "" {
		event.Host, _ = os.Hostname()
	}
	t := reflect.ValueOf(&e).Elem()
	s := reflect.ValueOf(event).Elem()
	typeOfEvent := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		value := reflect.ValueOf(f.Interface())
		if reflect.Zero(f.Type()) != value && f.Interface() != nil {
			name := typeOfEvent.Field(i).Name
			switch name {
			case "State", "Service", "Host", "Description":
				tmp := reflect.ValueOf(pb.String(value.String()))
				t.FieldByName(name).Set(tmp)
			case "Ttl":
				tmp := reflect.ValueOf(pb.Float32(float32(value.Float())))
				t.FieldByName(name).Set(tmp)
			case "Time":
				tmp := reflect.ValueOf(pb.Int64(value.Int()))
				t.FieldByName(name).Set(tmp)
			case "Tags":
				tmp := reflect.ValueOf(value.Interface().([]string))
				t.FieldByName(name).Set(tmp)
			case "Metric":
				switch reflect.TypeOf(f.Interface()).Kind() {
				case reflect.Int:
					tmp := reflect.ValueOf(pb.Int64(int64(value.Int())))
					t.FieldByName("MetricSint64").Set(tmp)
				case reflect.Int64:
					tmp := reflect.ValueOf(pb.Int64(value.Int()))
					t.FieldByName("MetricSint64").Set(tmp)
				case reflect.Float32:
					tmp := reflect.ValueOf(pb.Float32(float32(value.Float())))
					t.FieldByName("MetricF").Set(tmp)
				case reflect.Float64:
					tmp := reflect.ValueOf(pb.Float64(value.Float()))
					t.FieldByName("MetricD").Set(tmp)
				default:
					return nil, fmt.Errorf("Metric of invalid type (type %v)",
						reflect.TypeOf(f.Interface()).Kind())
				}
			case "Attributes":
				f := t.FieldByName(name)
				attrs := []*proto.Attribute{}
				for k, v := range value.Interface().(map[string]interface{}) {
					switch v.(type) {
					case string:
						attrs = append(attrs, &proto.Attribute{Key: pb.String(k), Value: pb.String(v.(string))})
					case bool:
						attrs = append(attrs, &proto.Attribute{Key: pb.String(k)})
					default:
						return nil, fmt.Errorf("Attribute value of invalid type (type %v)", reflect.TypeOf(v))
					}
				}
				f.Set(reflect.ValueOf(attrs))
			}
		}
	}

	return &e, nil
}

func pbEventsToEvents(pbEvents []*proto.Event) []Event {
	var events []Event

	for _, event := range pbEvents {
		e := Event{
			State:       event.GetState(),
			Service:     event.GetService(),
			Host:        event.GetHost(),
			Description: event.GetDescription(),
			Ttl:         event.GetTtl(),
			Time:        event.GetTime(),
			Tags:        event.GetTags(),
		}
		if event.MetricF != nil {
			e.Metric = event.GetMetricF()
		} else if event.MetricD != nil {
			e.Metric = event.GetMetricD()
		} else {
			e.Metric = event.GetMetricSint64()
		}

		events = append(events, e)
	}

	return events
}

// Send sends an event to Riemann
func (c *Client) Send(event *Event) error {
	e, err := eventToPbEvent(event)
	if err != nil {
		return err
	}
	message := &proto.Msg{}
	message.Events = append(message.Events, e)
	c.Lock()
	defer c.Unlock()
	_, err = c.net.Send(message, c.connection)
	if err != nil {
		return err
	}

	return nil
}

// Query returns a list of events matched by query
func (c *Client) Query(q string) ([]Event, error) {
	switch c.net.(type) {
	case *udp:
		return nil, errors.New("Querying over UDP is not supported")
	}
	query := &proto.Query{}
	query.String_ = pb.String(q)
	message := &proto.Msg{}
	message.Query = query
	c.Lock()
	defer c.Unlock()
	response, err := c.net.Send(message, c.connection)
	if err != nil {
		return nil, err
	}
	return pbEventsToEvents(response.GetEvents()), nil
}

// Close closes the connection to Riemann
func (c *Client) Close() {
	c.Lock()
	c.connection.Close()
	c.Unlock()
}
<commit_msg>made Metric optional, replaced reflect usage with type switches<commit_after>// Go Riemann client
//
// TODO(cloudhead): pbEventsToEvents should parse Attributes field
package raidman

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"sync"

	pb "code.google.com/p/goprotobuf/proto"
	"github.com/swdunlop/raidman/proto"
)

type network interface {
	Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error)
}

type tcp struct{}

type udp struct{}

// Client represents a connection to a Riemann server
type Client struct {
	sync.Mutex
	net        network
	connection net.Conn
}

// An Event represents a single Riemann event
type Event struct {
	Ttl         float32
	Time        int64
	Tags        []string
	Host        string // Defaults to os.Hostname()
	State       string
	Service     string
	Metric      interface{} // Could be Int, Float32, Float64
	Attributes  map[string]interface{}
	Description string
}

// Dial establishes a connection to a Riemann server at addr, on the network
// netwrk.
//
// Known networks are "tcp", "tcp4", "tcp6", "udp", "udp4", and "udp6".
func Dial(netwrk, addr string) (c *Client, err error) {
	c = new(Client)

	var cnet network
	switch netwrk {
	case "tcp", "tcp4", "tcp6":
		cnet = new(tcp)
	case "udp", "udp4", "udp6":
		cnet = new(udp)
	default:
		return nil, fmt.Errorf("dial %q: unsupported network %q", netwrk, netwrk)
	}

	c.net = cnet
	c.connection, err = net.Dial(netwrk, addr)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (network *tcp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
	msg := &proto.Msg{}
	data, err := pb.Marshal(message)
	if err != nil {
		return msg, err
	}
	b := new(bytes.Buffer)
	if err = binary.Write(b, binary.BigEndian, uint32(len(data))); err != nil {
		return msg, err
	}
	if _, err = conn.Write(b.Bytes()); err != nil {
		return msg, err
	}
	if _, err = conn.Write(data); err != nil {
		return msg, err
	}
	var header uint32
	if err = binary.Read(conn, binary.BigEndian, &header); err != nil {
		return msg, err
	}
	response := make([]byte, header)
	if err = readFully(conn, response); err != nil {
		return msg, err
	}
	if err = pb.Unmarshal(response, msg); err != nil {
		return msg, err
	}
	if msg.GetOk() != true {
		return msg, errors.New(msg.GetError())
	}
	return msg, nil
}

func readFully(r io.Reader, p []byte) error {
	for len(p) > 0 {
		n, err := r.Read(p)
		p = p[n:]
		if err != nil {
			return err
		}
	}
	return nil
}

func (network *udp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
	data, err := pb.Marshal(message)
	if err != nil {
		return nil, err
	}
	if _, err = conn.Write(data); err != nil {
		return nil, err
	}

	return nil, nil
}

func eventToPbEvent(event *Event) (*proto.Event, error) {
	var e proto.Event

	h := event.Host
	if event.Host == "" {
		h, _ = os.Hostname()
	}
	e.Host = &h

	if event.State != "" {
		e.State = &event.State
	}
	if event.Service != "" {
		e.Service = &event.Service
	}
	if event.Description != "" {
		e.Description = &event.Description
	}
	if event.Ttl != 0 {
		e.Ttl = &event.Ttl
	}
	if event.Time != 0 {
		e.Time = &event.Time
	}
	if len(event.Tags) > 0 {
		e.Tags = event.Tags
	}

	err := assignEventMetric(&e, event.Metric)
	if err != nil {
		return nil, err
	}

	attrs := make([]proto.Attribute, len(event.Attributes))
	i := 0
	for k, v := range event.Attributes {
		switch x := v.(type) {
		case string:
			attrs[i].Key = &k
			attrs[i].Value = &x
		case bool:
			if x {
				attrs[i].Key = &k
			}
		default:
			return nil, fmt.Errorf("Attribute %v has invalid type (type %T)", k, v)
		}
		i++
	}

	return &e, nil
}

func assignEventMetric(e *proto.Event, v interface{}) error {
	switch x := v.(type) {
	case nil:
		// do nothing; an event without a metric is legitimate
	case int:
		i := int64(x)
		e.MetricSint64 = &i
	case int32:
		i := int64(x)
		e.MetricSint64 = &i
	case int64:
		e.MetricSint64 = &x
	case float32:
		e.MetricF = &x
	case float64:
		e.MetricD = &x
	default:
		return fmt.Errorf("Metric of invalid type (type %T)", v)
	}
	return nil
}

func pbEventsToEvents(pbEvents []*proto.Event) []Event {
	var events []Event

	for _, event := range pbEvents {
		e := Event{
			State:       event.GetState(),
			Service:     event.GetService(),
			Host:        event.GetHost(),
			Description: event.GetDescription(),
			Ttl:         event.GetTtl(),
			Time:        event.GetTime(),
			Tags:        event.GetTags(),
		}
		if event.MetricF != nil {
			e.Metric = event.GetMetricF()
		} else if event.MetricD != nil {
			e.Metric = event.GetMetricD()
		} else {
			e.Metric = event.GetMetricSint64()
		}

		events = append(events, e)
	}

	return events
}

// Send sends an event to Riemann
func (c *Client) Send(event *Event) error {
	e, err := eventToPbEvent(event)
	if err != nil {
		return err
	}
	message := &proto.Msg{}
	message.Events = append(message.Events, e)
	c.Lock()
	defer c.Unlock()
	_, err = c.net.Send(message, c.connection)
	if err != nil {
		return err
	}

	return nil
}

// Query returns a list of events matched by query
func (c *Client) Query(q string) ([]Event, error) {
	switch c.net.(type) {
	case *udp:
		return nil, errors.New("Querying over UDP is not supported")
	}
	query := &proto.Query{}
	query.String_ = pb.String(q)
	message := &proto.Msg{}
	message.Query = query
	c.Lock()
	defer c.Unlock()
	response, err := c.net.Send(message, c.connection)
	if err != nil {
		return nil, err
	}
	return pbEventsToEvents(response.GetEvents()), nil
}

// Close closes the connection to Riemann
func (c *Client) Close() {
	c.Lock()
	c.connection.Close()
	c.Unlock()
}
<|endoftext|>


<commit_before>package ramlapi

import (
	"errors"
	"fmt"
	"regexp"
	"strings"

	"github.com/buddhamagnet/raml"
)

var vizer = regexp.MustCompile("[^A-Za-z0-9]+")

func variableize(s string) string {
	return vizer.ReplaceAllString(strings.Title(s), "")
}

// QueryParameter represents a URL query parameter.
type QueryParameter struct {
	Key      string
	Type     string
	Pattern  string
	Required bool
}

// Endpoint describes an API endpoint.
type Endpoint struct {
	Verb            string
	Handler         string
	Path            string
	QueryParameters []*QueryParameter
}

func (e *Endpoint) String() string {
	return fmt.Sprintf("verb: %s handler: %s path:%s\n", e.Verb, e.Handler, e.Path)
}

func (e *Endpoint) setQueryParameters(method *raml.Method) {
	for _, res := range method.QueryParameters {
		q := &QueryParameter{
			Key:      res.Name,
			Type:     res.Type,
			Required: res.Required,
		}
		if res.Pattern != nil {
			q.Pattern = *res.Pattern
		}
		e.QueryParameters = append(e.QueryParameters, q)
	}
}

func appendEndpoint(s []*Endpoint, verb string, method *raml.Method) ([]*Endpoint, error) {
	if method.DisplayName == "" {
		return s, errors.New(`"DisplayName" property not set in RAML method`)
	}

	if method != nil {
		ep := &Endpoint{
			Verb:    verb,
			Handler: variableize(method.DisplayName),
		}
		ep.setQueryParameters(method)

		s = append(s, ep)
	}

	return s, nil
}

// ProcessRAML processes a RAML file and returns an API definition.
func ProcessRAML(ramlFile string) (*raml.APIDefinition, error) {
	routes, err := raml.ParseFile(ramlFile)
	if err != nil {
		return nil, fmt.Errorf("Failed parsing RAML file: %s\n", err.Error())
	}
	return routes, nil
}

// processResource recursively process resources and their nested children
// and returns the path so far for the children. The function takes a routerFunc
// as an argument that is invoked with the verb, resource path and handler as
// the resources are processed, so the calling code can use pat, mux, httprouter
// or whatever router they desire and we don't need to know about it.
func processResource(parent, name string, resource *raml.Resource, routerFunc func(s *Endpoint)) error {
	var path = parent + name
	var err error

	s := make([]*Endpoint, 0, 6)
	for verb, details := range resource.Methods() {
		s, err = appendEndpoint(s, verb, details)
		if err != nil {
			return err
		}
	}

	for _, ep := range s {
		ep.Path = path
		routerFunc(ep)
	}

	// Get all children.
	for nestname, nested := range resource.Nested {
		return processResource(path, nestname, nested, routerFunc)
	}

	return nil
}

// Build takes a RAML API definition, a router and a routing map,
// and wires them all together.
func Build(api *raml.APIDefinition, routerFunc func(s *Endpoint)) error {
	for name, resource := range api.Resources {
		err := processResource("", name, &resource, routerFunc)
		if err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>reorganise<commit_after>package ramlapi

import (
	"errors"
	"fmt"
	"regexp"
	"strings"

	"github.com/buddhamagnet/raml"
)

var vizer = regexp.MustCompile("[^A-Za-z0-9]+")

// QueryParameter represents a URL query parameter.
type QueryParameter struct {
	Key      string
	Type     string
	Pattern  string
	Required bool
}

// Endpoint describes an API endpoint.
type Endpoint struct {
	Verb            string
	Handler         string
	Path            string
	QueryParameters []*QueryParameter
}

// String returns the string representation of an Endpoint.
func (e *Endpoint) String() string {
	return fmt.Sprintf("verb: %s handler: %s path:%s\n", e.Verb, e.Handler, e.Path)
}

func (e *Endpoint) setQueryParameters(method *raml.Method) {
	for _, res := range method.QueryParameters {
		q := &QueryParameter{
			Key:      res.Name,
			Type:     res.Type,
			Required: res.Required,
		}
		if res.Pattern != nil {
			q.Pattern = *res.Pattern
		}
		e.QueryParameters = append(e.QueryParameters, q)
	}
}

// ProcessRAML processes a RAML file and returns an API definition.
func ProcessRAML(ramlFile string) (*raml.APIDefinition, error) {
	routes, err := raml.ParseFile(ramlFile)
	if err != nil {
		return nil, fmt.Errorf("Failed parsing RAML file: %s\n", err.Error())
	}
	return routes, nil
}

// Build takes a RAML API definition, a router and a routing map,
// and wires them all together.
func Build(api *raml.APIDefinition, routerFunc func(s *Endpoint)) error {
	for name, resource := range api.Resources {
		err := processResource("", name, &resource, routerFunc)
		if err != nil {
			return err
		}
	}

	return nil
}

func appendEndpoint(s []*Endpoint, verb string, method *raml.Method) ([]*Endpoint, error) {
	if method.DisplayName == "" {
		return s, errors.New(`"DisplayName" property not set in RAML method`)
	}

	if method != nil {
		ep := &Endpoint{
			Verb:    verb,
			Handler: variableize(method.DisplayName),
		}
		ep.setQueryParameters(method)

		s = append(s, ep)
	}

	return s, nil
}

// processResource recursively process resources and their nested children
// and returns the path so far for the children. The function takes a routerFunc
// as an argument that is invoked with the verb, resource path and handler as
// the resources are processed, so the calling code can use pat, mux, httprouter
// or whatever router they desire and we don't need to know about it.
func processResource(parent, name string, resource *raml.Resource, routerFunc func(s *Endpoint)) error {
	var path = parent + name
	var err error

	s := make([]*Endpoint, 0, 6)
	for verb, details := range resource.Methods() {
		s, err = appendEndpoint(s, verb, details)
		if err != nil {
			return err
		}
	}

	for _, ep := range s {
		ep.Path = path
		routerFunc(ep)
	}

	// Get all children.
	for nestname, nested := range resource.Nested {
		return processResource(path, nestname, nested, routerFunc)
	}

	return nil
}

func variableize(s string) string {
	return vizer.ReplaceAllString(strings.Title(s), "")
}
<|endoftext|>


<commit_before>/*
 Copyright 2016 Padduck, LLC

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

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

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

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"fmt"

	"github.com/braintree/manners"
	"github.com/gin-gonic/gin"
	"github.com/pufferpanel/pufferd/config"
	"github.com/pufferpanel/pufferd/data"
	"github.com/pufferpanel/pufferd/data/templates"
	"github.com/pufferpanel/pufferd/logging"
	"github.com/pufferpanel/pufferd/migration"
	"github.com/pufferpanel/pufferd/programs"
	"github.com/pufferpanel/pufferd/routing"
	"github.com/pufferpanel/pufferd/routing/server"
	"github.com/pufferpanel/pufferd/sftp"
	"github.com/pufferpanel/pufferd/utils"
)

var (
	MAJORVERSION string
	BUILDDATE    string
	GITHASH      string
)

func main() {
	var loggingLevel string
	var port int
	var authRoot string
	var authToken string
	var install bool
	var version bool
	var license bool
	var migrate bool
	flag.StringVar(&loggingLevel, "logging", "INFO", "Lowest logging level to display")
	flag.IntVar(&port, "port", 5656, "Port to run service on")
	flag.StringVar(&authRoot, "auth", "", "Base URL to the authorization server")
	flag.StringVar(&authToken, "token", "", "Authorization token")
	flag.BoolVar(&install, "install", false, "If installing instead of running")
	flag.BoolVar(&version, "version", false, "Get the version")
	flag.BoolVar(&license, "license", false, "View license")
	flag.BoolVar(&migrate, "migrate", false, "Migrate Scales data to pufferd")
	flag.Parse()

	versionString := fmt.Sprintf("pufferd %s (%s %s)", MAJORVERSION, BUILDDATE, GITHASH)

	if version {
		os.Stdout.WriteString(versionString + "\r\n")
	}

	if license {
		os.Stdout.WriteString(data.LICENSE + "\r\n")
	}

	if migrate {
		migration.MigrateFromScales()
	}

	if license || version || migrate {
		return
	}

	logging.SetLevelByString(loggingLevel)
	logging.Init()
	gin.SetMode(gin.ReleaseMode)

	logging.Info(versionString)
	logging.Info("Logging set to " + loggingLevel)

	if install {

		if authRoot == "" {
			logging.Error("Authorization server root not passed")
			os.Exit(1)
		}

		if authToken == "" {
			logging.Error("Authorization token not passed")
			os.Exit(1)
		}

		config := data.CONFIG

		replacements := make(map[string]interface{})
		replacements["authurl"] = authRoot
		replacements["authtoken"] = authToken

		configData := []byte(utils.ReplaceTokens(config, replacements))

		var prettyJson bytes.Buffer
		json.Indent(&prettyJson, configData, "", "  ")
		err := ioutil.WriteFile("config.json", prettyJson.Bytes(), 0664)

		if err != nil {
			logging.Error("Error writing new config")
			os.Exit(1)
		}

		logging.Info("Config saved, install is complete")

		os.Exit(0)
	}

	config.Load()

	if _, err := os.Stat(templates.Folder); os.IsNotExist(err) {
		logging.Info("No template directory found, creating")
		err = os.MkdirAll(templates.Folder, 0755)
		if err != nil {
			logging.Error("Error creating template folder", err)
		}

	}
	if files, _ := ioutil.ReadDir(templates.Folder); len(files) == 0 {
		logging.Info("Templates being copied to " + templates.Folder)
		templates.CopyTemplates()
	}

	if _, err := os.Stat(programs.ServerFolder); os.IsNotExist(err) {
		logging.Info("No server directory found, creating")
		os.MkdirAll(programs.ServerFolder, 0755)
	}

	programs.LoadFromFolder()

	for _, element := range programs.GetAll() {
		if element.IsEnabled() {
			logging.Info("Starting server " + element.Id())
			element.Start()
			err := programs.Save(element.Id())
			if err != nil {
				logging.Error("Error saving server file", err)
			}
		}
	}

	r := gin.New()
	{
		r.Use(gin.Recovery())
		routing.RegisterRoutes(r)
		server.RegisterRoutes(r)
	}

	var useHttps bool
	useHttps = false

	if _, err := os.Stat(filepath.Join("data", "https.pem")); os.IsNotExist(err) {
		logging.Warn("No HTTPS.PEM found in data folder, will use no http")
	} else if _, err := os.Stat(filepath.Join("data", "https.key")); os.IsNotExist(err) {
		logging.Warn("No HTTPS.KEY found in data folder, will use no http")
	} else {
		useHttps = true
	}

	sftp.Run()

	logging.Info("Starting web access on 0.0.0.0:" + strconv.Itoa(port))
	if useHttps {
		manners.ListenAndServeTLS(":"+strconv.FormatInt(int64(port), 10), filepath.Join("data", "https.pem"), filepath.Join("data", "https.key"), r)
	} else {
		manners.ListenAndServe(":"+strconv.FormatInt(int64(port), 10), r)
	}
}
<commit_msg>Hardcode any manually built versions are unknown Our CI server populates these for tracking purposes<commit_after>/*
 Copyright 2016 Padduck, LLC

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

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

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

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"fmt"

	"github.com/braintree/manners"
	"github.com/gin-gonic/gin"
	"github.com/pufferpanel/pufferd/config"
	"github.com/pufferpanel/pufferd/data"
	"github.com/pufferpanel/pufferd/data/templates"
	"github.com/pufferpanel/pufferd/logging"
	"github.com/pufferpanel/pufferd/migration"
	"github.com/pufferpanel/pufferd/programs"
	"github.com/pufferpanel/pufferd/routing"
	"github.com/pufferpanel/pufferd/routing/server"
	"github.com/pufferpanel/pufferd/sftp"
	"github.com/pufferpanel/pufferd/utils"
)

var (
	MAJORVERSION = "unknown"
	BUILDDATE = "unknown"
	GITHASH = "unknown"
)

func main() {
	var loggingLevel string
	var port int
	var authRoot string
	var authToken string
	var install bool
	var version bool
	var license bool
	var migrate bool
	flag.StringVar(&loggingLevel, "logging", "INFO", "Lowest logging level to display")
	flag.IntVar(&port, "port", 5656, "Port to run service on")
	flag.StringVar(&authRoot, "auth", "", "Base URL to the authorization server")
	flag.StringVar(&authToken, "token", "", "Authorization token")
	flag.BoolVar(&install, "install", false, "If installing instead of running")
	flag.BoolVar(&version, "version", false, "Get the version")
	flag.BoolVar(&license, "license", false, "View license")
	flag.BoolVar(&migrate, "migrate", false, "Migrate Scales data to pufferd")
	flag.Parse()

	versionString := fmt.Sprintf("pufferd %s (%s %s)", MAJORVERSION, BUILDDATE, GITHASH)

	if version {
		os.Stdout.WriteString(versionString + "\r\n")
	}

	if license {
		os.Stdout.WriteString(data.LICENSE + "\r\n")
	}

	if migrate {
		migration.MigrateFromScales()
	}

	if license || version || migrate {
		return
	}

	logging.SetLevelByString(loggingLevel)
	logging.Init()
	gin.SetMode(gin.ReleaseMode)

	logging.Info(versionString)
	logging.Info("Logging set to " + loggingLevel)

	if install {

		if authRoot == "" {
			logging.Error("Authorization server root not passed")
			os.Exit(1)
		}

		if authToken == "" {
			logging.Error("Authorization token not passed")
			os.Exit(1)
		}

		config := data.CONFIG

		replacements := make(map[string]interface{})
		replacements["authurl"] = authRoot
		replacements["authtoken"] = authToken

		configData := []byte(utils.ReplaceTokens(config, replacements))

		var prettyJson bytes.Buffer
		json.Indent(&prettyJson, configData, "", "  ")
		err := ioutil.WriteFile("config.json", prettyJson.Bytes(), 0664)

		if err != nil {
			logging.Error("Error writing new config")
			os.Exit(1)
		}

		logging.Info("Config saved, install is complete")

		os.Exit(0)
	}

	config.Load()

	if _, err := os.Stat(templates.Folder); os.IsNotExist(err) {
		logging.Info("No template directory found, creating")
		err = os.MkdirAll(templates.Folder, 0755)
		if err != nil {
			logging.Error("Error creating template folder", err)
		}

	}
	if files, _ := ioutil.ReadDir(templates.Folder); len(files) == 0 {
		logging.Info("Templates being copied to " + templates.Folder)
		templates.CopyTemplates()
	}

	if _, err := os.Stat(programs.ServerFolder); os.IsNotExist(err) {
		logging.Info("No server directory found, creating")
		os.MkdirAll(programs.ServerFolder, 0755)
	}

	programs.LoadFromFolder()

	for _, element := range programs.GetAll() {
		if element.IsEnabled() {
			logging.Info("Starting server " + element.Id())
			element.Start()
			err := programs.Save(element.Id())
			if err != nil {
				logging.Error("Error saving server file", err)
			}
		}
	}

	r := gin.New()
	{
		r.Use(gin.Recovery())
		routing.RegisterRoutes(r)
		server.RegisterRoutes(r)
	}

	var useHttps bool
	useHttps = false

	if _, err := os.Stat(filepath.Join("data", "https.pem")); os.IsNotExist(err) {
		logging.Warn("No HTTPS.PEM found in data folder, will use no http")
	} else if _, err := os.Stat(filepath.Join("data", "https.key")); os.IsNotExist(err) {
		logging.Warn("No HTTPS.KEY found in data folder, will use no http")
	} else {
		useHttps = true
	}

	sftp.Run()

	logging.Info("Starting web access on 0.0.0.0:" + strconv.Itoa(port))
	if useHttps {
		manners.ListenAndServeTLS(":"+strconv.FormatInt(int64(port), 10), filepath.Join("data", "https.pem"), filepath.Join("data", "https.key"), r)
	} else {
		manners.ListenAndServe(":"+strconv.FormatInt(int64(port), 10), r)
	}
}
<|endoftext|>


<commit_before><commit_msg>resolved review comments<commit_after><|endoftext|>


<commit_before>package bitbucket

import (
	"encoding/json"
	"os"

	"github.com/k0kubun/pp"
)

type PullRequests struct {
	c *Client
}

func (p *PullRequests) Create(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := p.c.requestUrl("/repositories/%s/%s/pullrequests/", po.Owner, po.Repo_slug)
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) Update(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id
	return p.c.execute("PUT", urlStr, data)
}

func (p *PullRequests) Gets(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Get(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Activities(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/activity"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Activity(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/activity"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Commits(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/commits"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Patch(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/patch"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Diff(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/diff"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Merge(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/merge"
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) Decline(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/decline"
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) GetComments(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/comments/"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) GetComment(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/comments/" + po.Comment_id
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) buildPullRequestBody(po *PullRequestsOptions) string {

	body := map[string]interface{}{}
	body["source"] = map[string]interface{}{}
	body["destination"] = map[string]interface{}{}
	body["reviewers"] = []map[string]string{}
	body["title"] = ""
	body["description"] = ""
	body["message"] = ""
	body["close_source_branch"] = false

	if n := len(po.Reviewers); n > 0 {
		for i, user := range po.Reviewers {
			body["reviewers"].([]map[string]string)[i] = map[string]string{"username": user}
		}
	}

	if po.Source_branch != "" {
		body["source"].(map[string]interface{})["branch"] = map[string]string{"name": po.Source_branch}
	}

	if po.Source_repository != "" {
		body["source"].(map[string]interface{})["repository"] = map[string]interface{}{"full_name": po.Source_repository}
	}

	if po.Destination_branch != "" {
		body["destination"].(map[string]interface{})["branch"] = map[string]interface{}{"name": po.Destination_branch}
	}

	if po.Destination_commit != "" {
		body["destination"].(map[string]interface{})["commit"] = map[string]interface{}{"hash": po.Destination_commit}
	}

	if po.Title != "" {
		body["title"] = po.Title
	}

	if po.Description != "" {
		body["description"] = po.Description
	}

	if po.Message != "" {
		body["message"] = po.Message
	}

	if po.Close_source_branch == true || po.Close_source_branch == false {
		body["close_source_branch"] = po.Close_source_branch
	}

	data, err := json.Marshal(body)
	if err != nil {
		pp.Println(err)
		os.Exit(9)
	}

	return string(data)
}
<commit_msg>Create pull request - handle reviewer list <commit_after>package bitbucket

import (
	"encoding/json"
	"os"

	"github.com/k0kubun/pp"
)

type PullRequests struct {
	c *Client
}

func (p *PullRequests) Create(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := p.c.requestUrl("/repositories/%s/%s/pullrequests/", po.Owner, po.Repo_slug)
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) Update(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id
	return p.c.execute("PUT", urlStr, data)
}

func (p *PullRequests) Gets(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Get(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Activities(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/activity"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Activity(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/activity"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Commits(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/commits"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Patch(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/patch"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Diff(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/diff"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) Merge(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/merge"
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) Decline(po *PullRequestsOptions) (interface{}, error) {
	data := p.buildPullRequestBody(po)
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/decline"
	return p.c.execute("POST", urlStr, data)
}

func (p *PullRequests) GetComments(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/comments/"
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) GetComment(po *PullRequestsOptions) (interface{}, error) {
	urlStr := GetApiBaseURL() + "/repositories/" + po.Owner + "/" + po.Repo_slug + "/pullrequests/" + po.Id + "/comments/" + po.Comment_id
	return p.c.execute("GET", urlStr, "")
}

func (p *PullRequests) buildPullRequestBody(po *PullRequestsOptions) string {

	body := map[string]interface{}{}
	body["source"] = map[string]interface{}{}
	body["destination"] = map[string]interface{}{}
	body["title"] = ""
	body["description"] = ""
	body["message"] = ""
	body["close_source_branch"] = false

	if n := len(po.Reviewers); n > 0 {
		body["reviewers"] = make([]map[string]string, n)
		for i, user := range po.Reviewers {
			body["reviewers"].([]map[string]string)[i] = map[string]string{"username": user}
		}
	} else {
		body["reviewers"] = []map[string]string{}
	}

	if po.Source_branch != "" {
		body["source"].(map[string]interface{})["branch"] = map[string]string{"name": po.Source_branch}
	}

	if po.Source_repository != "" {
		body["source"].(map[string]interface{})["repository"] = map[string]interface{}{"full_name": po.Source_repository}
	}

	if po.Destination_branch != "" {
		body["destination"].(map[string]interface{})["branch"] = map[string]interface{}{"name": po.Destination_branch}
	}

	if po.Destination_commit != "" {
		body["destination"].(map[string]interface{})["commit"] = map[string]interface{}{"hash": po.Destination_commit}
	}

	if po.Title != "" {
		body["title"] = po.Title
	}

	if po.Description != "" {
		body["description"] = po.Description
	}

	if po.Message != "" {
		body["message"] = po.Message
	}

	if po.Close_source_branch == true || po.Close_source_branch == false {
		body["close_source_branch"] = po.Close_source_branch
	}

	data, err := json.Marshal(body)
	if err != nil {
		pp.Println(err)
		os.Exit(9)
	}

	return string(data)
}
<|endoftext|>


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

// Package memory provides an in-memory volatile config store implementation
package memory

import (
	"errors"
	"time"

	"istio.io/istio/pilot/pkg/model"
)

var (
	errNotFound      = errors.New("item not found")
	errAlreadyExists = errors.New("item already exists")
)

// Make creates an in-memory config store from a config descriptor
func Make(descriptor model.ConfigDescriptor) model.ConfigStore {
	out := store{
		descriptor: descriptor,
		data:       make(map[string]map[string]map[string]model.Config),
	}
	for _, typ := range descriptor.Types() {
		out.data[typ] = make(map[string]map[string]model.Config)
	}
	return &out
}

type store struct {
	descriptor model.ConfigDescriptor
	data       map[string]map[string]map[string]model.Config
}

func (cr *store) ConfigDescriptor() model.ConfigDescriptor {
	return cr.descriptor
}

func (cr *store) Get(typ, name, namespace string) (*model.Config, bool) {
	_, ok := cr.data[typ]
	if !ok {
		return nil, false
	}

	ns, exists := cr.data[typ][namespace]
	if !exists {
		return nil, false
	}

	out, exists := ns[name]
	if !exists {
		return nil, false
	}

	return &out, true
}

func (cr *store) List(typ, namespace string) ([]model.Config, error) {
	data, exists := cr.data[typ]
	if !exists {
		return nil, nil
	}
	out := make([]model.Config, 0, len(cr.data[typ]))
	if namespace == "" {
		for _, ns := range data {
			for _, elt := range ns {
				out = append(out, elt)
			}
		}
	} else {
		for _, elt := range data[namespace] {
			out = append(out, elt)
		}
	}
	return out, nil
}

func (cr *store) Delete(typ, name, namespace string) error {
	data, ok := cr.data[typ]
	if !ok {
		return errors.New("unknown type")
	}
	ns, exists := data[namespace]
	if !exists {
		return errNotFound
	}

	_, exists = ns[name]
	if !exists {
		return errNotFound
	}

	delete(ns, name)
	return nil
}

func (cr *store) Create(config model.Config) (string, error) {
	typ := config.Type
	schema, ok := cr.descriptor.GetByType(typ)
	if !ok {
		return "", errors.New("unknown type")
	}
	if err := schema.Validate(config.Spec); err != nil {
		return "", err
	}
	ns, exists := cr.data[typ][config.Namespace]
	if !exists {
		ns = make(map[string]model.Config)
		cr.data[typ][config.Namespace] = ns
	}

	_, exists = ns[config.Name]

	if !exists {
		config.ResourceVersion = time.Now().String()
		ns[config.Name] = config
		return config.ResourceVersion, nil
	}
	return "", errAlreadyExists
}

func (cr *store) Update(config model.Config) (string, error) {
	typ := config.Type
	schema, ok := cr.descriptor.GetByType(typ)
	if !ok {
		return "", errors.New("unknown type")
	}
	if err := schema.Validate(config.Spec); err != nil {
		return "", err
	}

	ns, exists := cr.data[typ][config.Namespace]
	if !exists {
		return "", errNotFound
	}

	oldConfig, exists := ns[config.Name]
	if !exists {
		return "", errNotFound
	}

	if config.ResourceVersion != oldConfig.ResourceVersion {
		return "", errors.New("old revision")
	}

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

// Package memory provides an in-memory volatile config store implementation
package memory

import (
	"errors"
	"sync"
	"time"

	"istio.io/istio/pilot/pkg/model"
)

var (
	errNotFound      = errors.New("item not found")
	errAlreadyExists = errors.New("item already exists")
)

// Make creates an in-memory config store from a config descriptor
func Make(descriptor model.ConfigDescriptor) model.ConfigStore {
	out := store{
		descriptor: descriptor,
		data:       make(map[string]map[string]*sync.Map),
	}
	for _, typ := range descriptor.Types() {
		out.data[typ] = make(map[string]*sync.Map)
	}
	return &out
}

type store struct {
	descriptor model.ConfigDescriptor
	data       map[string]map[string]*sync.Map
}

func (cr *store) ConfigDescriptor() model.ConfigDescriptor {
	return cr.descriptor
}

func (cr *store) Get(typ, name, namespace string) (*model.Config, bool) {
	_, ok := cr.data[typ]
	if !ok {
		return nil, false
	}

	ns, exists := cr.data[typ][namespace]
	if !exists {
		return nil, false
	}

	out, exists := ns.Load(name)
	if !exists {
		return nil, false
	}
	config := out.(model.Config)

	return &config, true
}

func (cr *store) List(typ, namespace string) ([]model.Config, error) {
	data, exists := cr.data[typ]
	if !exists {
		return nil, nil
	}
	out := make([]model.Config, 0, len(cr.data[typ]))
	if namespace == "" {
		for _, ns := range data {
			ns.Range(func(key, value interface{}) bool {
				out = append(out, value.(model.Config))
				return true
			})
		}
	} else {
		ns, exists := data[namespace]
		if !exists {
			return nil, nil
		}
		ns.Range(func(key, value interface{}) bool {
			out = append(out, value.(model.Config))
			return true
		})
	}
	return out, nil
}

func (cr *store) Delete(typ, name, namespace string) error {
	data, ok := cr.data[typ]
	if !ok {
		return errors.New("unknown type")
	}
	ns, exists := data[namespace]
	if !exists {
		return errNotFound
	}

	_, exists = ns.Load(name)
	if !exists {
		return errNotFound
	}

	ns.Delete(name)
	return nil
}

func (cr *store) Create(config model.Config) (string, error) {
	typ := config.Type
	schema, ok := cr.descriptor.GetByType(typ)
	if !ok {
		return "", errors.New("unknown type")
	}
	if err := schema.Validate(config.Spec); err != nil {
		return "", err
	}
	ns, exists := cr.data[typ][config.Namespace]
	if !exists {
		ns = new(sync.Map)
		cr.data[typ][config.Namespace] = ns
	}

	_, exists = ns.Load(config.Name)

	if !exists {
		config.ResourceVersion = time.Now().String()
		ns.Store(config.Name, config)
		return config.ResourceVersion, nil
	}
	return "", errAlreadyExists
}

func (cr *store) Update(config model.Config) (string, error) {
	typ := config.Type
	schema, ok := cr.descriptor.GetByType(typ)
	if !ok {
		return "", errors.New("unknown type")
	}
	if err := schema.Validate(config.Spec); err != nil {
		return "", err
	}

	ns, exists := cr.data[typ][config.Namespace]
	if !exists {
		return "", errNotFound
	}

	oldConfig, exists := ns.Load(config.Name)
	if !exists {
		return "", errNotFound
	}

	if config.ResourceVersion != oldConfig.(model.Config).ResourceVersion {
		return "", errors.New("old revision")
	}

	rev := time.Now().String()
	config.ResourceVersion = rev
	ns.Store(config.Name, config)
	return rev, nil
}
<|endoftext|>