<commit_before>package pocketsphinx

/*
#cgo pkg-config: pocketsphinx sphinxbase
#include <pocketsphinx.h>
*/
import "C"

import (
	"io"
	"io/ioutil"
	"strconv"
	"unsafe"

	"gopkg.in/guregu/null.v3"
	yaml "gopkg.in/yaml.v2"
)

type NullInt null.Int
type NullFloat null.Float

func IntParam(i int64) NullInt {
	return NullInt(null.IntFrom(i))
}

func FloatParam(f float64) NullFloat {
	return NullFloat(null.FloatFrom(f))
}

func (f *NullFloat) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		f.Valid = false
		return nil
	}
	var err error
	f.Float64, err = strconv.ParseFloat(str, 64)
	f.Valid = err == nil
	return err
}

func (f *NullInt) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		f.Valid = false
		return nil
	}
	var err error
	f.Int64, err = strconv.ParseInt(str, 10, 64)
	f.Valid = err == nil
	return err
}

func Load(r io.Reader) (Config, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return Config{}, err
	}

	var cfg Config
	err = yaml.Unmarshal(data, &cfg)
	if err != nil {
		return Config{}, err
	}
	return cfg, nil
}

type Config struct {
	Hmm           string
	Dict          string
	Lm            string
	Jsgf          string
	Bestpath      string
	Beam          NullFloat
	Wbeam         NullFloat
	Keyphrase     string
	Kws           string
	Kws_threshold NullFloat
	Kws_plp       NullFloat
	Debug         NullInt
	SamplingRate  NullInt
	DisableInfo   bool
	Language      string
}

func (c Config) SetParams(psConfig *C.cmd_ln_t) {
	if c.Hmm != "" {
		setStringParam(psConfig, "-hmm", c.Hmm)
	}
	if c.Dict != "" {
		setStringParam(psConfig, "-dict", c.Dict)
	}
	if c.Lm != "" {
		setStringParam(psConfig, "-lm", c.Lm)
	}
	if c.Jsgf != "" {
		setStringParam(psConfig, "-jsgf", c.Jsgf)
	}
	if c.Bestpath == "no" {
		setIntParam(psConfig, "-bestpath", 0)
	}
	if c.Keyphrase != "" {
		setStringParam(psConfig, "-keyphrase", c.Keyphrase)
	}
	if c.Kws != "" {
		setStringParam(psConfig, "-kws", c.Kws)
	}
	if c.Kws_threshold.Valid {
		setFloatParam(psConfig, "-kws_threshold", c.Kws_threshold.Float64)
	}
	if c.Kws_plp.Valid {
		setFloatParam(psConfig, "-kws_plp", c.Kws_plp.Float64)
	}
	if c.Beam.Valid {
		setFloatParam(psConfig, "-beam", c.Beam.Float64)
	}
	if c.Wbeam.Valid {
		setFloatParam(psConfig, "-wbeam", c.Wbeam.Float64)
	}

	if c.Debug.Valid {
		setIntParam(psConfig, "-debug", c.Debug.Int64)
	}
}

func setStringParam(psConfig *C.cmd_ln_t, key, val string) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	valPtr := C.CString(val)
	defer C.free(unsafe.Pointer(valPtr))
	C.cmd_ln_set_str_r(psConfig, keyPtr, valPtr)
}

func setFloatParam(psConfig *C.cmd_ln_t, key string, val float64) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	C.cmd_ln_set_float_r(psConfig, keyPtr, C.double(val))
}

func setIntParam(psConfig *C.cmd_ln_t, key string, val int64) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	C.cmd_ln_set_int_r(psConfig, keyPtr, C.long(val))
}

func (c Config) Mode() string {
	if c.Lm != "" {
		return "dictation"
	} else if c.Jsgf != "" {
		return "grammer"
	} else if c.Kws != "" || c.Keyphrase != "" {
		return "spotting"
	} else {
		return ""
	}
}
<commit_msg>Fixed samprate parameter<commit_after>package pocketsphinx

/*
#cgo pkg-config: pocketsphinx sphinxbase
#include <pocketsphinx.h>
*/
import "C"

import (
	"io"
	"io/ioutil"
	"strconv"
	"unsafe"

	"gopkg.in/guregu/null.v3"
	yaml "gopkg.in/yaml.v2"
)

type NullInt null.Int
type NullFloat null.Float

func IntParam(i int64) NullInt {
	return NullInt(null.IntFrom(i))
}

func FloatParam(f float64) NullFloat {
	return NullFloat(null.FloatFrom(f))
}

func (f *NullFloat) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		f.Valid = false
		return nil
	}
	var err error
	f.Float64, err = strconv.ParseFloat(str, 64)
	f.Valid = err == nil
	return err
}

func (f *NullInt) UnmarshalText(text []byte) error {
	str := string(text)
	if str == "" || str == "null" {
		f.Valid = false
		return nil
	}
	var err error
	f.Int64, err = strconv.ParseInt(str, 10, 64)
	f.Valid = err == nil
	return err
}

func Load(r io.Reader) (Config, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return Config{}, err
	}

	var cfg Config
	err = yaml.Unmarshal(data, &cfg)
	if err != nil {
		return Config{}, err
	}
	return cfg, nil
}

type Config struct {
	Hmm           string
	Dict          string
	Lm            string
	Jsgf          string
	Bestpath      string
	Beam          NullFloat
	Wbeam         NullFloat
	Keyphrase     string
	Kws           string
	Kws_threshold NullFloat
	Kws_plp       NullFloat
	Debug         NullInt
	SamplingRate  NullFloat
	DisableInfo   bool
	Language      string
}

func (c Config) SetParams(psConfig *C.cmd_ln_t) {
	if c.Hmm != "" {
		setStringParam(psConfig, "-hmm", c.Hmm)
	}
	if c.Dict != "" {
		setStringParam(psConfig, "-dict", c.Dict)
	}
	if c.Lm != "" {
		setStringParam(psConfig, "-lm", c.Lm)
	}
	if c.Jsgf != "" {
		setStringParam(psConfig, "-jsgf", c.Jsgf)
	}
	if c.Bestpath == "no" {
		setIntParam(psConfig, "-bestpath", 0)
	}
	if c.Keyphrase != "" {
		setStringParam(psConfig, "-keyphrase", c.Keyphrase)
	}
	if c.Kws != "" {
		setStringParam(psConfig, "-kws", c.Kws)
	}
	if c.Kws_threshold.Valid {
		setFloatParam(psConfig, "-kws_threshold", c.Kws_threshold.Float64)
	}
	if c.Kws_plp.Valid {
		setFloatParam(psConfig, "-kws_plp", c.Kws_plp.Float64)
	}
	if c.Beam.Valid {
		setFloatParam(psConfig, "-beam", c.Beam.Float64)
	}
	if c.Wbeam.Valid {
		setFloatParam(psConfig, "-wbeam", c.Wbeam.Float64)
	}
	if c.SamplingRate.Valid {
		setFloatParam(psConfig, "-samprate", c.SamplingRate.Float64)
	}

	if c.Debug.Valid {
		setIntParam(psConfig, "-debug", c.Debug.Int64)
	}
}

func setStringParam(psConfig *C.cmd_ln_t, key, val string) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	valPtr := C.CString(val)
	defer C.free(unsafe.Pointer(valPtr))
	C.cmd_ln_set_str_r(psConfig, keyPtr, valPtr)
}

func setFloatParam(psConfig *C.cmd_ln_t, key string, val float64) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	C.cmd_ln_set_float_r(psConfig, keyPtr, C.double(val))
}

func setIntParam(psConfig *C.cmd_ln_t, key string, val int64) {
	keyPtr := C.CString(key)
	defer C.free(unsafe.Pointer(keyPtr))
	C.cmd_ln_set_int_r(psConfig, keyPtr, C.long(val))
}

func (c Config) Mode() string {
	if c.Lm != "" {
		return "dictation"
	} else if c.Jsgf != "" {
		return "grammer"
	} else if c.Kws != "" || c.Keyphrase != "" {
		return "spotting"
	} else {
		return ""
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"launchpad.net/goyaml"
)

type Config map[string]interface{}

func LoadConfig(file string) (Config, error) {
	yml, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	var c Config
	err = goyaml.Unmarshal(yml, &c)
	if err != nil {
		return nil, err
	}

	err = c.Validate()
	if err != nil {
		return nil, err
	}

	return c, err
}

func (c Config) Validate() error {
	if _, ok := c["mysql"]; !ok {
		fmt.Errorf("mysql section of config not present")
	}

	if _, ok := c["destination"]; !ok {
		fmt.Errorf("destination section of config not present")
	}

	return nil
}
<commit_msg>config: switch to static structs<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"launchpad.net/goyaml"
)

/* type Config map[string]interface{} */

type ConnConfig struct {
	Hostname string `yaml:"hostname,omitempty"`
	Port     int    `yaml:"port,omitempty"`
	Username string `yaml:"username,omitempty"`
	Password string `yaml:"password,omitempty"`
	Database string `yaml:"database,omitempty"`
	Compress bool   `yaml:"compress,omitempty"`
}

type DestinationConfig struct {
	File     string      `yaml:"file,omitempty"`
	Postgres *ConnConfig `yaml:"postgres,omitempty"`
}

type Config struct {
	Mysql        *ConnConfig                  `yaml:"mysql,omitempty"`
	Destination  *DestinationConfig           `yaml:"destination,omitempty"`
	Views        map[string]string            `yaml:"views,omitempty"`
	Tables       map[string]map[string]string `yaml:"tables,omitempty"`
	SuppressData bool                         `yaml:"supress_data"`
	SuppressDdl  bool                         `yaml:"supress_ddl"`
	Truncate     bool                         `yaml:"force_truncate"`
	Timezone     bool                         `yaml:"timezone"`
}

func LoadConfig(file string) (*Config, error) {
	yml, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	var c Config
	err = goyaml.Unmarshal(yml, &c)
	if err != nil {
		return nil, err
	}

	err = c.Validate()
	if err != nil {
		return nil, err
	}

	return &c, err
}

func (c *Config) Validate() error {
	if c.Mysql == nil {
		return fmt.Errorf("config: mysql section of config not present")
	}

	if c.Destination == nil {
		return fmt.Errorf("config: destination section of config not present or complete, %v", c)
	}

	if c.Destination.File == "" && c.Destination.Postgres == nil {
		return fmt.Errorf("config: either file or postgres has to be specified in the destination field", c)
	}

	return nil
}
<|endoftext|>


<commit_before>package goutil

import (
	"crypto/hmac"
	"crypto/sha256"
	"hash"
	"io"
	"os"
)

func Zero(in []byte) {
	if in == nil {
		return
	}
	for i := 0; i < len(in); i++ {
		in[i] ^= in[i]
	}
}

func fileDigest(filename string, h hash.Hash) error {
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer func() { _ = f.Close() }()

	_, err = io.Copy(h, f)
	return err
}

func FileSHA256(filename string) (*[sha256.Size]byte, error) {
	h := sha256.New()
	err := fileDigest(filename, h)
	if err != nil {
		return nil, err
	}

	var d [sha256.Size]byte
	copy(d[:], h.Sum(nil)[:])
	return &d, nil
}

func FileHMACSHA256(filename string, key []byte) (*[sha256.Size]byte, error) {
	h := hmac.New(sha256.New, key)
	err := fileDigest(filename, h)
	if err != nil {
		return nil, err
	}

	var d [sha256.Size]byte
	copy(d[:], h.Sum(nil)[:])
	return &d, nil
}
<commit_msg>add HMACSHA256<commit_after>package goutil

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"hash"
	"io"
	"os"
)

func Zero(in []byte) {
	if in == nil {
		return
	}
	for i := 0; i < len(in); i++ {
		in[i] ^= in[i]
	}
}

func fileDigest(filename string, h hash.Hash) error {
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer func() { _ = f.Close() }()

	_, err = io.Copy(h, f)
	return err
}

func FileSHA256(filename string) (*[sha256.Size]byte, error) {
	h := sha256.New()
	err := fileDigest(filename, h)
	if err != nil {
		return nil, err
	}

	var d [sha256.Size]byte
	copy(d[:], h.Sum(nil)[:])
	return &d, nil
}

func HMACSHA256(blob []byte, key []byte) (*[sha256.Size]byte, error) {
	h := hmac.New(sha256.New, key)

	r := bytes.NewReader(blob)
	_, err := io.Copy(h, r)
	if err != nil {
		return nil, err
	}

	var d [sha256.Size]byte
	copy(d[:], h.Sum(nil)[:])
	return &d, nil
}
func FileHMACSHA256(filename string, key []byte) (*[sha256.Size]byte, error) {
	h := hmac.New(sha256.New, key)
	err := fileDigest(filename, h)
	if err != nil {
		return nil, err
	}

	var d [sha256.Size]byte
	copy(d[:], h.Sum(nil)[:])
	return &d, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2021 The Kubernetes Authors.

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

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

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

package model

import (
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
)

// EtcHostsBuilder seeds some hostnames into /etc/hosts, avoiding some circular dependencies.
type EtcHostsBuilder struct {
	*NodeupModelContext
}

var _ fi.ModelBuilder = &EtcHostsBuilder{}

// Build is responsible for configuring the gossip DNS tasks.
func (b *EtcHostsBuilder) Build(c *fi.ModelBuilderContext) error {

	task := &nodetasks.UpdateEtcHostsTask{
		Name: "control-plane-address",
	}

	if b.IsMaster && b.Cluster.IsGossip() {
		task.Records = append(task.Records, nodetasks.HostRecord{
			Hostname:  b.Cluster.Spec.MasterInternalName,
			Addresses: []string{"127.0.0.1"},
		})
		if b.Cluster.Spec.MasterPublicName != "" {
			task.Records = append(task.Records, nodetasks.HostRecord{
				Hostname:  b.Cluster.Spec.MasterPublicName,
				Addresses: []string{"127.0.0.1"},
			})
		}
	} else if b.Cluster.UsesNoneDNS() {
		task.Records = append(task.Records, nodetasks.HostRecord{
			Hostname:  b.Cluster.Spec.MasterInternalName,
			Addresses: []string{b.BootConfig.APIServer},
		})
		if b.UseKopsControllerForNodeBootstrap() {
			task.Records = append(task.Records, nodetasks.HostRecord{
				Hostname:  "kops-controller.internal." + b.Cluster.Name,
				Addresses: []string{b.BootConfig.APIServer},
			})
		}
	}

	if len(task.Records) != 0 {
		c.AddTask(task)
	}

	return nil
}
<commit_msg>Use local API server on control plane nodes for clusters without DNS<commit_after>/*
Copyright 2021 The Kubernetes Authors.

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

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

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

package model

import (
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
)

// EtcHostsBuilder seeds some hostnames into /etc/hosts, avoiding some circular dependencies.
type EtcHostsBuilder struct {
	*NodeupModelContext
}

var _ fi.ModelBuilder = &EtcHostsBuilder{}

// Build is responsible for configuring the gossip DNS tasks.
func (b *EtcHostsBuilder) Build(c *fi.ModelBuilderContext) error {

	task := &nodetasks.UpdateEtcHostsTask{
		Name: "control-plane-address",
	}

	if b.IsMaster && (b.Cluster.IsGossip() || b.Cluster.UsesNoneDNS()) {
		task.Records = append(task.Records, nodetasks.HostRecord{
			Hostname:  b.Cluster.Spec.MasterInternalName,
			Addresses: []string{"127.0.0.1"},
		})
		if b.Cluster.Spec.MasterPublicName != "" {
			task.Records = append(task.Records, nodetasks.HostRecord{
				Hostname:  b.Cluster.Spec.MasterPublicName,
				Addresses: []string{"127.0.0.1"},
			})
		}
	} else if b.Cluster.UsesNoneDNS() {
		task.Records = append(task.Records, nodetasks.HostRecord{
			Hostname:  b.Cluster.Spec.MasterInternalName,
			Addresses: []string{b.BootConfig.APIServer},
		})
		if b.UseKopsControllerForNodeBootstrap() {
			task.Records = append(task.Records, nodetasks.HostRecord{
				Hostname:  "kops-controller.internal." + b.Cluster.Name,
				Addresses: []string{b.BootConfig.APIServer},
			})
		}
	}

	if len(task.Records) != 0 {
		c.AddTask(task)
	}

	return nil
}
<|endoftext|>


<commit_before>package mdb

/*
#include <lmdb.h>
*/
import "C"

import (
	"errors"
)

// MDB_cursor_op
const (
	FIRST = iota
	FIRST_DUP
	GET_BOTH
	GET_RANGE
	GET_CURRENT
	GET_MULTIPLE
	LAST
	LAST_DUP
	NEXT
	NEXT_DUP
	NEXT_MULTIPLE
	NEXT_NODUP
	PREV
	PREV_DUP
	PREV_NODUP
	SET
	SET_KEY
	SET_RANGE
)

func (cursor *Cursor) Close() error {
	if cursor.cursor == nil {
		return errors.New("Cursor already closed")
	}
	C.mdb_cursor_close(cursor.cursor)
	cursor.cursor = nil
	return nil
}

func (cursor *Cursor) Txn() *Txn {
	var txn *C.MDB_txn
	txn = C.mdb_cursor_txn(cursor.cursor)
	if txn != nil {
		return &Txn{txn}
	}
	return nil
}

func (cursor *Cursor) DBI() DBI {
	var dbi C.MDB_dbi
	dbi = C.mdb_cursor_dbi(cursor.cursor)
	return DBI(dbi)
}

// Retrieves the low-level MDB cursor.
func (cursor *Cursor) MdbCursor() *C.MDB_cursor {
	return cursor.cursor
}

func (cursor *Cursor) Get(set_key, sval []byte, op uint) (key, val []byte, err error) {
	k, v, err := cursor.GetVal(set_key, sval, op)
	if err != nil {
		return nil, nil, err
	}
	return k.Bytes(), v.Bytes(), nil
}

func (cursor *Cursor) GetVal(key, val []byte, op uint) (Val, Val, error) {
	ckey := Wrap(key)
	cval := Wrap(val)
	ret := C.mdb_cursor_get(cursor.cursor, (*C.MDB_val)(&ckey), (*C.MDB_val)(&cval), C.MDB_cursor_op(op))
	return ckey, cval, errno(ret)
}

func (cursor *Cursor) Put(key, val []byte, flags uint) error {
	ckey := Wrap(key)
	cval := Wrap(val)
	ret := C.mdb_cursor_put(cursor.cursor, (*C.MDB_val)(&ckey), (*C.MDB_val)(&cval), C.uint(flags))
	return errno(ret)
}

func (cursor *Cursor) Del(flags uint) error {
	ret := C.mdb_cursor_del(cursor.cursor, C.uint(flags))
	return errno(ret)
}

func (cursor *Cursor) Count() (uint64, error) {
	var size C.size_t
	ret := C.mdb_cursor_count(cursor.cursor, &size)
	if ret != SUCCESS {
		return 0, errno(ret)
	}
	return uint64(size), nil
}
<commit_msg>Use MDB-defined constants, not iota.<commit_after>package mdb

/*
#include <lmdb.h>
*/
import "C"

import (
	"errors"
)

// MDB_cursor_op
const (
	FIRST          = C.MDB_FIRST
	FIRST_DUP      = C.MDB_FIRST_DUP
	GET_BOTH       = C.MDB_GET_BOTH
	GET_BOTH_RANGE = C.MDB_GET_BOTH_RANGE
	GET_CURRENT    = C.MDB_GET_CURRENT
	GET_MULTIPLE   = C.MDB_GET_MULTIPLE
	LAST           = C.MDB_LAST
	LAST_DUP       = C.MDB_LAST_DUP
	NEXT           = C.MDB_NEXT
	NEXT_DUP       = C.MDB_NEXT_DUP
	NEXT_MULTIPLE  = C.MDB_NEXT_MULTIPLE
	NEXT_NODUP     = C.MDB_NEXT_NODUP
	PREV           = C.MDB_PREV
	PREV_DUP       = C.MDB_PREV_DUP
	PREV_NODUP     = C.MDB_PREV_NODUP
	SET            = C.MDB_SET
	SET_KEY        = C.MDB_SET_KEY
	SET_RANGE      = C.MDB_SET_RANGE
)

func (cursor *Cursor) Close() error {
	if cursor.cursor == nil {
		return errors.New("Cursor already closed")
	}
	C.mdb_cursor_close(cursor.cursor)
	cursor.cursor = nil
	return nil
}

func (cursor *Cursor) Txn() *Txn {
	var txn *C.MDB_txn
	txn = C.mdb_cursor_txn(cursor.cursor)
	if txn != nil {
		return &Txn{txn}
	}
	return nil
}

func (cursor *Cursor) DBI() DBI {
	var dbi C.MDB_dbi
	dbi = C.mdb_cursor_dbi(cursor.cursor)
	return DBI(dbi)
}

// Retrieves the low-level MDB cursor.
func (cursor *Cursor) MdbCursor() *C.MDB_cursor {
	return cursor.cursor
}

func (cursor *Cursor) Get(set_key, sval []byte, op uint) (key, val []byte, err error) {
	k, v, err := cursor.GetVal(set_key, sval, op)
	if err != nil {
		return nil, nil, err
	}
	return k.Bytes(), v.Bytes(), nil
}

func (cursor *Cursor) GetVal(key, val []byte, op uint) (Val, Val, error) {
	ckey := Wrap(key)
	cval := Wrap(val)
	ret := C.mdb_cursor_get(cursor.cursor, (*C.MDB_val)(&ckey), (*C.MDB_val)(&cval), C.MDB_cursor_op(op))
	return ckey, cval, errno(ret)
}

func (cursor *Cursor) Put(key, val []byte, flags uint) error {
	ckey := Wrap(key)
	cval := Wrap(val)
	ret := C.mdb_cursor_put(cursor.cursor, (*C.MDB_val)(&ckey), (*C.MDB_val)(&cval), C.uint(flags))
	return errno(ret)
}

func (cursor *Cursor) Del(flags uint) error {
	ret := C.mdb_cursor_del(cursor.cursor, C.uint(flags))
	return errno(ret)
}

func (cursor *Cursor) Count() (uint64, error) {
	var size C.size_t
	ret := C.mdb_cursor_count(cursor.cursor, &size)
	if ret != SUCCESS {
		return 0, errno(ret)
	}
	return uint64(size), nil
}
<|endoftext|>


<commit_before>package sisyphus

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strconv"
)

// See
// https://www.socketloop.com/tutorials/golang-daemonizing-a-simple-web-server-process-example
// for the process we are using to daemonize

// Pidfile holds the Process ID file of sisyphus
type Pidfile string

// savePID stores a pidfile
func (p Pidfile) savePID(process int) error {
	file, err := os.Create(string(p))
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.WriteString(strconv.Itoa(process))
	if err != nil {
		return err
	}

	err = file.Sync()

	return err
}

// DaemonStart starts sisyphus as a backgound process
func (p Pidfile) DaemonStart() error {
	// check if daemon already running.
	if _, err := os.Stat(string(p)); err == nil {
		return errors.New("sisyphus running or " + string(p) + " file exists.")
	}

	cmd := exec.Command(os.Args[0], "run")
	err := cmd.Start()
	if err != nil {
		return err
	}
	log.Printf("starting sisyphus process ID [%v]\n", cmd.Process.Pid)
	log.Println("sisyphus started")
	err = (p).savePID(cmd.Process.Pid)

	return err
}

// DaemonStop stops a running sisyphus background process
func (p Pidfile) DaemonStop() error {

	_, err := os.Stat(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	processIDRaw, err := ioutil.ReadFile(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	processID, err := strconv.Atoi(string(processIDRaw))
	if err != nil {
		return errors.New("unable to read and parse process id found in " + string(p))
	}

	process, err := os.FindProcess(processID)

	if err != nil {
		e := fmt.Sprintf("Unable to find process ID [%v] with error %v \n", processID, err)
		return errors.New(e)
	}

	// remove PID file
	err = os.Remove(string(p))
	if err != nil {
		return err
	}

	log.Printf("stopping sisyphus process ID [%v]\n", processID)
	// kill process and exit immediately
	err = process.Kill()

	if err != nil {
		e := fmt.Sprintf("Unable to kill process ID [%v] with error %v \n", processID, err)
		return errors.New(e)
	}

	log.Println("sisyphus stopped")
	os.Exit(0)

	return nil
}

// DaemonRestart restarts a running sisyphus background process
func (p Pidfile) DaemonRestart() error {
	_, err := os.Stat(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	pid, err := ioutil.ReadFile(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	cmd := exec.Command(os.Args[0], "stop")
	err = cmd.Start()
	if err != nil {
		return err
	}
	log.Printf("stopping sisyphus process ID [%v]\n", string(pid))

	cmd = exec.Command(os.Args[0], "start")
	err = cmd.Start()
	if err != nil {
		return err
	}

	log.Println("sisyphus restarted")

	return nil
}
<commit_msg>cosmetics<commit_after>package sisyphus

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strconv"
)

// See
// https://www.socketloop.com/tutorials/golang-daemonizing-a-simple-web-server-process-example
// for the process we are using to daemonize

// Pidfile holds the Process ID file of sisyphus
type Pidfile string

// savePID stores a pidfile
func (p Pidfile) savePID(process int) error {
	file, err := os.Create(string(p))
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.WriteString(strconv.Itoa(process))
	if err != nil {
		return err
	}

	err = file.Sync()

	return err
}

// DaemonStart starts sisyphus as a backgound process
func (p Pidfile) DaemonStart() error {
	// check if daemon already running.
	if _, err := os.Stat(string(p)); err == nil {
		return errors.New("sisyphus running or " + string(p) + " file exists.")
	}

	cmd := exec.Command(os.Args[0], "run")
	err := cmd.Start()
	if err != nil {
		return err
	}
	log.Printf("starting sisyphus process ID [%v]\n", cmd.Process.Pid)
	log.Println("sisyphus started")
	err = (p).savePID(cmd.Process.Pid)

	return err
}

// DaemonStop stops a running sisyphus background process
func (p Pidfile) DaemonStop() error {

	_, err := os.Stat(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	processIDRaw, err := ioutil.ReadFile(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	processID, err := strconv.Atoi(string(processIDRaw))
	if err != nil {
		return errors.New("unable to read and parse process id found in " + string(p))
	}

	process, err := os.FindProcess(processID)
	if err != nil {
		e := fmt.Sprintf("Unable to find process ID [%v] with error %v \n", processID, err)
		return errors.New(e)
	}

	// remove PID file
	err = os.Remove(string(p))
	if err != nil {
		return err
	}

	log.Printf("stopping sisyphus process ID [%v]\n", processID)
	// kill process and exit immediately
	err = process.Kill()
	if err != nil {
		e := fmt.Sprintf("Unable to kill process ID [%v] with error %v \n", processID, err)
		return errors.New(e)
	}

	log.Println("sisyphus stopped")
	os.Exit(0)

	return nil
}

// DaemonRestart restarts a running sisyphus background process
func (p Pidfile) DaemonRestart() error {
	_, err := os.Stat(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	pid, err := ioutil.ReadFile(string(p))
	if err != nil {
		return errors.New("sisyphus is not running")
	}

	cmd := exec.Command(os.Args[0], "stop")
	err = cmd.Start()
	if err != nil {
		return err
	}
	log.Printf("stopping sisyphus process ID [%v]\n", string(pid))

	cmd = exec.Command(os.Args[0], "start")
	err = cmd.Start()
	if err != nil {
		return err
	}

	log.Println("sisyphus restarted")

	return nil
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/pkg/errors"
	"net/http"
	"time"
)

// ErrMissingDomain is for when domain is required but missing.
var ErrMissingDomain = errors.New("required missing domain")

// PagesDomain represents a pages domain.
type PagesDomain struct {
	ID               string           `json:"id"`
	Name             string           `json:"name"`
	Status           string           `json:"status"`
	VerificationData VerificationData `json:"verification_data"`
	ValidationData   ValidationData   `json:"validation_data"`
	ZoneTag          string           `json:"zone_tag"`
	CreatedOn        *time.Time       `json:"created_on"`
}

// VerificationData represents verification data for a domain.
type VerificationData struct {
	Status string `json:"status"`
}

// ValidationData represents validation data for a domain.
type ValidationData struct {
	Status string `json:"status"`
	Method string `json:"method"`
}

// PagesDomainsParameters represents parameters for a pages domains request.
type PagesDomainsParameters struct {
	AccountID   string
	ProjectName string
}

// PagesDomainsResponse represents an API response for a pages domains request.
type PagesDomainsResponse struct {
	Response
	Result []PagesDomain `json:"result,omitempty"`
}

// PagesDomainParameters represents parameters for a pages domain request.
type PagesDomainParameters struct {
	AccountID   string
	ProjectName string
	DomainName  string `json:"name,omitempty"`
}

// PagesDomainResponse represents an API response for a pages domain request.
type PagesDomainResponse struct {
	Response
	Result PagesDomain `json:"result,omitempty"`
}

// GetPagesDomains gets all domains for a pages project.
//
// API Reference: https://api.cloudflare.com/#pages-domains-get-domains
func (api *API) GetPagesDomains(ctx context.Context, params PagesDomainsParameters) ([]PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return []PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return []PagesDomain{}, ErrMissingProjectName
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains", params.AccountID, params.ProjectName)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return []PagesDomain{}, err
	}

	var pageDomainResponse PagesDomainsResponse
	if err := json.Unmarshal(res, &pageDomainResponse); err != nil {
		return []PagesDomain{}, err
	}
	return pageDomainResponse.Result, nil
}

// GetPagesDomain gets a single domain.
//
// API Reference: https://api.cloudflare.com/#pages-domains-get-domains
func (api *API) GetPagesDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains/%s", params.AccountID, params.ProjectName, params.DomainName)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}

// PagesPatchDomain retries the validation status of a single domain.
//
// API Reference: https://api.cloudflare.com/#pages-domains-patch-domain
func (api *API) PagesPatchDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains/%s", params.AccountID, params.ProjectName, params.DomainName)
	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, nil)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}

// PagesAddDomain adds a domain to a pages project.
//
// API Reference: https://community.cloudflare.com/t/add-pages-domain-via-api/303510/3
// Blame Washly for not making it official
func (api *API) PagesAddDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domain", params.AccountID, params.ProjectName)
	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}
<commit_msg>Fix lint<commit_after>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/pkg/errors"
	"net/http"
	"time"
)

// ErrMissingDomain is for when domain is required but missing.
var ErrMissingDomain = errors.New("required missing domain")

// PagesDomain represents a pages domain.
type PagesDomain struct {
	ID               string           `json:"id"`
	Name             string           `json:"name"`
	Status           string           `json:"status"`
	VerificationData VerificationData `json:"verification_data"`
	ValidationData   ValidationData   `json:"validation_data"`
	ZoneTag          string           `json:"zone_tag"`
	CreatedOn        *time.Time       `json:"created_on"`
}

// VerificationData represents verification data for a domain.
type VerificationData struct {
	Status string `json:"status"`
}

// ValidationData represents validation data for a domain.
type ValidationData struct {
	Status string `json:"status"`
	Method string `json:"method"`
}

// PagesDomainsParameters represents parameters for a pages domains request.
type PagesDomainsParameters struct {
	AccountID   string
	ProjectName string
}

// PagesDomainsResponse represents an API response for a pages domains request.
type PagesDomainsResponse struct {
	Response
	Result []PagesDomain `json:"result,omitempty"`
}

// PagesDomainParameters represents parameters for a pages domain request.
type PagesDomainParameters struct {
	AccountID   string
	ProjectName string
	DomainName  string `json:"name,omitempty"`
}

// PagesDomainResponse represents an API response for a pages domain request.
type PagesDomainResponse struct {
	Response
	Result PagesDomain `json:"result,omitempty"`
}

// GetPagesDomains gets all domains for a pages project.
//
// API Reference: https://api.cloudflare.com/#pages-domains-get-domains
func (api *API) GetPagesDomains(ctx context.Context, params PagesDomainsParameters) ([]PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return []PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return []PagesDomain{}, ErrMissingProjectName
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains", params.AccountID, params.ProjectName)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return []PagesDomain{}, err
	}

	var pageDomainResponse PagesDomainsResponse
	if err := json.Unmarshal(res, &pageDomainResponse); err != nil {
		return []PagesDomain{}, err
	}
	return pageDomainResponse.Result, nil
}

// GetPagesDomain gets a single domain.
//
// API Reference: https://api.cloudflare.com/#pages-domains-get-domains
func (api *API) GetPagesDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains/%s", params.AccountID, params.ProjectName, params.DomainName)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}

// PagesPatchDomain retries the validation status of a single domain.
//
// API Reference: https://api.cloudflare.com/#pages-domains-patch-domain
func (api *API) PagesPatchDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domains/%s", params.AccountID, params.ProjectName, params.DomainName)
	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, nil)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}

// PagesAddDomain adds a domain to a pages project.
//
// API Reference: https://community.cloudflare.com/t/add-pages-domain-via-api/303510/3
// Blame Washly for not making it official.
func (api *API) PagesAddDomain(ctx context.Context, params PagesDomainParameters) (PagesDomain, error) {
	// Make sure account id is set
	if params.AccountID == "" {
		return PagesDomain{}, ErrMissingAccountID
	}

	// Make sure project name is set
	if params.ProjectName == "" {
		return PagesDomain{}, ErrMissingProjectName
	}
	// Make sure domain name is set
	if params.DomainName == "" {
		return PagesDomain{}, ErrMissingDomain
	}

	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/domain", params.AccountID, params.ProjectName)
	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return PagesDomain{}, err
	}

	var pagesDomainResponse PagesDomainResponse
	if err := json.Unmarshal(res, &pagesDomainResponse); err != nil {
		return PagesDomain{}, err
	}
	return pagesDomainResponse.Result, nil
}
<|endoftext|>


<commit_before>package parser

import (
	"bytes"
	"fmt"
	"github.com/rhysd/gocaml/ast"
	"github.com/rhysd/gocaml/token"
)

type pseudoLexer struct {
	tokens       chan token.Token
	errorCount   int
	errorMessage bytes.Buffer
	result       ast.Expr
}

func newLexerWrapper(tokens chan token.Token) *pseudoLexer {
	return &pseudoLexer{
		tokens:     tokens,
		errorCount: 0,
	}
}

func (w *pseudoLexer) Lex(lval *yySymType) int {
	select {
	case t := <-w.tokens:
		lval.token = &t

		if t.Kind == token.EOF {
			// Zero means input ends
			// (see golang.org/x/tools/cmd/goyacc/testdata/expr/expr.y)
			return 0
		}

		// XXX:
		// Converting token value into yacc's token.
		// This conversion requires that token order must the same as
		// yacc's token order. EOF is a first token. So we can use it
		// to make an offset between token value and yacc's token value.
		return int(t.Kind) + ILLEGAL
	}
	panic("Unreachable")
}

func (w *pseudoLexer) Error(msg string) {
	w.errorCount += 1
	w.errorMessage.WriteString(fmt.Sprintf("  * %s\n", msg))
}

func (w *pseudoLexer) getErrorMessage() error {
	return fmt.Errorf("%d errors while parsing\n%s", w.errorCount, w.errorMessage.String())
}

func Parse(tokens chan token.Token) (ast.Expr, error) {
	yyErrorVerbose = true

	wrapper := &pseudoLexer{tokens: tokens}
	ret := yyParse(wrapper)

	if ret != 0 {
		return nil, wrapper.getErrorMessage()
	}

	root := wrapper.result
	if root == nil {
		panic("FATAL: Parsing was successfully done but result was not set")
	}

	return root, nil
}
<commit_msg>skip comment on parsing<commit_after>package parser

import (
	"bytes"
	"fmt"
	"github.com/rhysd/gocaml/ast"
	"github.com/rhysd/gocaml/token"
)

type pseudoLexer struct {
	tokens       chan token.Token
	errorCount   int
	errorMessage bytes.Buffer
	result       ast.Expr
}

func (w *pseudoLexer) Lex(lval *yySymType) int {
	for {
		select {
		case t := <-w.tokens:
			lval.token = &t

			switch t.Kind {
			case token.EOF:
				// Zero means input ends
				// (see golang.org/x/tools/cmd/goyacc/testdata/expr/expr.y)
				return 0
			case token.COMMENT:
				continue
			}

			// XXX:
			// Converting token value into yacc's token.
			// This conversion requires that token order must the same as
			// yacc's token order. EOF is a first token. So we can use it
			// to make an offset between token value and yacc's token value.
			return int(t.Kind) + ILLEGAL
		}
	}
	panic("Unreachable")
}

func (w *pseudoLexer) Error(msg string) {
	w.errorCount += 1
	w.errorMessage.WriteString(fmt.Sprintf("  * %s\n", msg))
}

func (w *pseudoLexer) getErrorMessage() error {
	return fmt.Errorf("%d errors while parsing\n%s", w.errorCount, w.errorMessage.String())
}

func Parse(tokens chan token.Token) (ast.Expr, error) {
	yyErrorVerbose = true

	l := &pseudoLexer{tokens: tokens}
	ret := yyParse(l)

	if ret != 0 {
		return nil, l.getErrorMessage()
	}

	root := l.result
	if root == nil {
		panic("FATAL: Parsing was successfully done but result was not set")
	}

	return root, nil
}
<|endoftext|>


<commit_before>/**
 * Parses command prompt definition strings.
 * See http://www.cyberciti.biz/tips/howto-linux-unix-bash-shell-setup-prompt.html
 */
package parser

import (
	"os/user"
	"strings"
	"bytes"
	"os"
	"path"
	"time"
)

// Used when the real host name cannot be determined.
const DefaultHostname = "etcd"

// Formatter returns a string associated with an escape sequence.
type Formatter func() string

// FormatterMap maps runes to Formatter functions.
type FormatterMap map[rune]Formatter

// Prompt is used to parse a prompt definition string.
type Prompt struct {
	formatters FormatterMap
}

// Creates and returns a new prompt parser instance.
func NewPrompt() *Prompt {
	p := new(Prompt)
	p.formatters = make(FormatterMap)
	p.formatters['\\'] = formatSlash
	p.formatters['a'] = formatBell
	p.formatters['d'] = formatTime
	p.formatters['e'] = formatEscape
	p.formatters['h'] = formatHostnameShort
	p.formatters['H'] = formatHostnameLong
	p.formatters['j'] = formatNumJobs
	p.formatters['n'] = formatNewline
	p.formatters['r'] = formatCarriageReturn
	p.formatters['s'] = formatShell
	p.formatters['t'] = formatTime24
	p.formatters['T'] = formatTime12
	p.formatters['@'] = formatTimeAmPm
	p.formatters['A'] = formatTime24Long
	p.formatters['u'] = formatUser
	p.formatters['$'] = formatUid

	return p
}

// AddFormatter adds a custom formatter to the prompt parser.
func (p *Prompt) AddFormatter(key rune, f Formatter) {
	p.formatters[key] = f
}

// Parse parses the given prompt definition.
func (p *Prompt) Parse(s string) (string, error) {
	buffer := bytes.Buffer{}
	escaped := false

	for _, ch := range s {
		if ch == '\\' && !escaped {
			escaped = true
		} else if escaped {
			escaped = false
			found, ok := p.formatters[ch]
			if ok {
				buffer.WriteString(found())
			} else {
				buffer.WriteRune(ch)
			}
		} else {
			buffer.WriteRune(ch)
		}
	}

	return buffer.String(), nil
}

// formatEscape handles the \e escape sequence.
// Returns an ASCII escape character.
func formatEscape() string {
	return "\x1B"
}

// formatNewline handles the \n escape sequence.
// Returns a newline.
func formatNewline() string {
	return "\n"
}

// formatCarriageReturn handles the \r escape sequence.
// Returns a carriage return.
func formatCarriageReturn() string {
	return "\r"
}

// formatSlash handles the \\ escape sequence.
// Returns a backslash.
func formatSlash() string {
	return "\\"
}

// formatBell handles the \a escape sequence.
// Returns an ASCII bell character (07).
func formatBell() string {
	return "\x07"
}

// formatShell handles the \s escape sequence.
// Returns the name of the shell, the basename of $0 (the portion following the final slash).
func formatShell() string {
	return path.Base(os.Args[0])
}

// formatHostnameShort handles the \h escape sequence.
// Returns the hostname up to the first '.'.
func formatHostnameShort() string {
	host := formatHostnameLong()
	parts := strings.Split(host, ".")
	return parts[0]
}

// formatHostnameLong handles the \H escape sequence.
// Returns the hostname.
func formatHostnameLong() string {
	host, err := os.Hostname()
	if err == nil {
		return host
	} else {
		return DefaultHostname
	}
}

// formatNumJobs handles the \j escape sequence.
// Returns the number of jobs currently managed by the shell.
func formatNumJobs() string {
	return "0"
}

// formatUser handles the \u escape sequence.
// Returns the username of the current user.
func formatUser() string {
	usr, err := user.Current()
	if err == nil {
		return strings.ToLower(usr.Name)
	} else {
		return DefaultHostname
	}
}

// formatUid handles the \$ escape sequence.
// Returns if the effective UID is 0, a #, otherwise a $.
func formatUid() string {
	usr, err := user.Current()
	if err == nil {
		if usr.Uid == "0" {
			return "#"
		} else {
			return "$"
		}
	} else {
		return "$"
	}
}

// formatTime handles the \d escape sequence.
// Returns the date in "Weekday Month Date" format (e.g., "Tue May 26").
func formatTime() string {
	return time.Now().Format("Mon Jan 2")
}

// formatTime24 handles the \t escape sequence.
// Returns the current time in 24-hour HH:MM:SS format.
func formatTime24() string {
	return time.Now().Format("15:04:05")
}

// formatTime12 handles the \T escape sequence.
// Returns the current time in 12-hour HH:MM:SS format.
func formatTime12() string {
	return time.Now().Format("03:04:05")
}

// formatTimeAmPm handles the \@ escape sequence.
// Returns the current time in 12-hour am/pm format.
func formatTimeAmPm() string {
	return time.Now().Format("03:04:05pm")
}

// formatTime24Long handles the \A escape sequence.
// Returns the current time in 24-hour HH:MM format.
func formatTime24Long() string {
	return time.Now().Format("15:04")
}

<commit_msg>Removed \j from prompt parser<commit_after>/**
 * Parses command prompt definition strings.
 * See http://www.cyberciti.biz/tips/howto-linux-unix-bash-shell-setup-prompt.html
 */
package parser

import (
	"os/user"
	"strings"
	"bytes"
	"os"
	"path"
	"time"
)

// Used when the real host name cannot be determined.
const DefaultHostname = "etcd"

// Formatter returns a string associated with an escape sequence.
type Formatter func() string

// FormatterMap maps runes to Formatter functions.
type FormatterMap map[rune]Formatter

// Prompt is used to parse a prompt definition string.
type Prompt struct {
	formatters FormatterMap
}

// Creates and returns a new prompt parser instance.
func NewPrompt() *Prompt {
	p := new(Prompt)
	p.formatters = make(FormatterMap)
	p.formatters['\\'] = formatSlash
	p.formatters['a'] = formatBell
	p.formatters['d'] = formatTime
	p.formatters['e'] = formatEscape
	p.formatters['h'] = formatHostnameShort
	p.formatters['H'] = formatHostnameLong
	p.formatters['n'] = formatNewline
	p.formatters['r'] = formatCarriageReturn
	p.formatters['s'] = formatShell
	p.formatters['t'] = formatTime24
	p.formatters['T'] = formatTime12
	p.formatters['@'] = formatTimeAmPm
	p.formatters['A'] = formatTime24Long
	p.formatters['u'] = formatUser
	p.formatters['$'] = formatUid

	return p
}

// AddFormatter adds a custom formatter to the prompt parser.
func (p *Prompt) AddFormatter(key rune, f Formatter) {
	p.formatters[key] = f
}

// Parse parses the given prompt definition.
func (p *Prompt) Parse(s string) (string, error) {
	buffer := bytes.Buffer{}
	escaped := false

	for _, ch := range s {
		if ch == '\\' && !escaped {
			escaped = true
		} else if escaped {
			escaped = false
			found, ok := p.formatters[ch]
			if ok {
				buffer.WriteString(found())
			} else {
				buffer.WriteRune(ch)
			}
		} else {
			buffer.WriteRune(ch)
		}
	}

	return buffer.String(), nil
}

// formatEscape handles the \e escape sequence.
// Returns an ASCII escape character.
func formatEscape() string {
	return "\x1B"
}

// formatNewline handles the \n escape sequence.
// Returns a newline.
func formatNewline() string {
	return "\n"
}

// formatCarriageReturn handles the \r escape sequence.
// Returns a carriage return.
func formatCarriageReturn() string {
	return "\r"
}

// formatSlash handles the \\ escape sequence.
// Returns a backslash.
func formatSlash() string {
	return "\\"
}

// formatBell handles the \a escape sequence.
// Returns an ASCII bell character (07).
func formatBell() string {
	return "\x07"
}

// formatShell handles the \s escape sequence.
// Returns the name of the shell, the basename of $0 (the portion following the final slash).
func formatShell() string {
	return path.Base(os.Args[0])
}

// formatHostnameShort handles the \h escape sequence.
// Returns the hostname up to the first '.'.
func formatHostnameShort() string {
	host := formatHostnameLong()
	parts := strings.Split(host, ".")
	return parts[0]
}

// formatHostnameLong handles the \H escape sequence.
// Returns the hostname.
func formatHostnameLong() string {
	host, err := os.Hostname()
	if err == nil {
		return host
	} else {
		return DefaultHostname
	}
}

// formatUser handles the \u escape sequence.
// Returns the username of the current user.
func formatUser() string {
	usr, err := user.Current()
	if err == nil {
		return strings.ToLower(usr.Name)
	} else {
		return DefaultHostname
	}
}

// formatUid handles the \$ escape sequence.
// Returns if the effective UID is 0, a #, otherwise a $.
func formatUid() string {
	usr, err := user.Current()
	if err == nil {
		if usr.Uid == "0" {
			return "#"
		} else {
			return "$"
		}
	} else {
		return "$"
	}
}

// formatTime handles the \d escape sequence.
// Returns the date in "Weekday Month Date" format (e.g., "Tue May 26").
func formatTime() string {
	return time.Now().Format("Mon Jan 2")
}

// formatTime24 handles the \t escape sequence.
// Returns the current time in 24-hour HH:MM:SS format.
func formatTime24() string {
	return time.Now().Format("15:04:05")
}

// formatTime12 handles the \T escape sequence.
// Returns the current time in 12-hour HH:MM:SS format.
func formatTime12() string {
	return time.Now().Format("03:04:05")
}

// formatTimeAmPm handles the \@ escape sequence.
// Returns the current time in 12-hour am/pm format.
func formatTimeAmPm() string {
	return time.Now().Format("03:04:05pm")
}

// formatTime24Long handles the \A escape sequence.
// Returns the current time in 24-hour HH:MM format.
func formatTime24Long() string {
	return time.Now().Format("15:04")
}

<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/dynport/dgtk/github"
	"github.com/dynport/gocli"
	"github.com/pkg/errors"
)

type Status struct {
	WithURLs bool   `cli:"opt --with-urls"`
	Open     bool   `cli:"opt --open"`
	Branch   string `cli:"opt --branch"`
	Wait     bool   `cli:"opt --wait"`
}

func (r *Status) Run() error {
	var branches []string
	if r.Branch != "" {
		branches = []string{r.Branch}
	} else {
		branches = []string{"master"}
		if cb, err := currentBranch(); err == nil && cb != "master" {
			branches = append([]string{cb}, "master")
		}
	}
	repo, err := githubRepo()
	if err != nil {
		return err
	}
	cl, err := client()
	if err != nil {
		return err
	}

	l := log.New(os.Stderr, "", 0)

	if r.Wait {
		branch := r.Branch
		if branch == "" {
			branch, err = currentBranch()
			if err != nil {
				return err
			}
		}
		var printedURL bool
		for {
			s, err := loadStatus(cl, repo, branch)
			if err != nil {
				l.Printf("error fetching status: %s", err)
			} else {
				if s.State != statePending {
					fmt.Println(s.State)
					if s.State == stateSuccess {
						return nil
					}
					return fmt.Errorf("not successful (%s)", s.State)
				}
				if !printedURL && len(s.Statuses) > 0 {
					l.Printf("url=%s", s.Statuses[0].TargetURL)
					printedURL = true
				}
			}
			time.Sleep(10 * time.Second)
		}
		return nil
	}

	type status struct {
		Time   time.Time
		Branch string
		URL    string
		URLs   []string
		Status string
		SHA    string
	}

	t := gocli.NewTable()
	all := []*status{}
	failures := 0
	agoFunc := func(t time.Time) string { return strings.Split(time.Since(t).String(), ".")[0] }
	for _, b := range branches {
		st := &status{Branch: b}
		all = append(all, st)
		if s, err := loadStatus(cl, repo, b); err != nil {
			if isNotFound(err) {
				st.Status = "not_found"
			} else {
				return err
			}
		} else {
			st.Status = s.State
			st.SHA = s.SHA
			sm := map[string]int{}
			for _, s := range s.Statuses {
				sm[s.State]++
			}
			if sm["failure"] > 0 {
				st.Status = "failure"
				failures++
			} else if sm["pending"] > 0 {
				st.Status = "pending"
			} else {
				st.Status = "success"
			}
			t.Add(string(b), colorizeStatus(st.Status))
			if len(s.Statuses) > 0 {
				for _, ss := range s.Statuses {
					if ss.TargetURL != "" {
						st.URLs = append(st.URLs, ss.TargetURL)
					}
					args := []interface{}{"", colorizeStatus(ss.State), truncate(s.SHA, 8, false), ss.Context, agoFunc(ss.CreatedAt)}
					if r.WithURLs {
						args = append(args, ss.TargetURL)
					}
					t.Add(args...)
				}
			}
		}
	}

	if r.Open {
		if len(all) == 0 {
			return fmt.Errorf("no status found")
		}
		s := all[0]
		for _, s := range all {
			l.Printf("url: %s", s.URL)
		}
		url := ""
		if s.URL != "" {
			url = s.URL
		} else if len(s.URLs) == 1 {
			url = s.URLs[0]
		} else {
			return fmt.Errorf("status has no url (yet?). url=%q urls=%#v", s.URL, s.URLs)
		}
		return openUrl(url)
	}
	fmt.Println(t)
	if failures > 0 {
		return errors.Errorf("%d failures", failures)
	}
	return nil
}

func isNotFound(err error) bool {
	return err != nil && strings.Contains(err.Error(), "404 Not Found")
}

const (
	stateSuccess  = "success"
	statePending  = "pending"
	stateNotFound = "not_found"
)

func colorizeStatus(in string) string {
	color := gocli.Green
	switch in {
	case stateSuccess:
		color = gocli.Green
	case statePending, stateNotFound:
		color = gocli.Yellow
	default:
		color = gocli.Red
	}
	return color(in)
}

func loadStatus(cl *github.Client, repo, ref string) (res *statusResponse, err error) {
	u := "https://api.github.com/repos/" + repo + "/commits/" + ref + "/status"
	rsp, err := cl.Get(u)
	if err != nil {
		return nil, err
	}
	defer rsp.Body.Close()
	if rsp.Status[0] != '2' {
		b, _ := ioutil.ReadAll(rsp.Body)
		return nil, fmt.Errorf("got status %s but expected 2x. body=%s", rsp.Status, string(b))
	}
	err = json.NewDecoder(rsp.Body).Decode(&res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

func currentBranch() (string, error) {
	b, err := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD").CombinedOutput()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(b)), nil
}

type statusResponse struct {
	State    string `json:"state"`
	Statuses []*struct {
		State     string    `json:"state,omitempty"`
		URL       string    `json:"url,omitempty"`
		Context   string    `json:"context"`
		TargetURL string    `json:"target_url,omitempty"`
		CreatedAt time.Time `json:"created_at,omitempty"`
		UpdatedAt time.Time `json:"updated_at,omitempty"`
	} `json:"statuses"`
	SHA string `json:"sha"`
}

// to be used to colorize
func dataOn(f *os.File) bool {
	stat, err := f.Stat()
	if err != nil {
		return false
	}
	return (stat.Mode() & os.ModeCharDevice) == 0
}
<commit_msg>use constants for all statuses<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/dynport/dgtk/github"
	"github.com/dynport/gocli"
	"github.com/pkg/errors"
)

type Status struct {
	WithURLs bool   `cli:"opt --with-urls"`
	Open     bool   `cli:"opt --open"`
	Branch   string `cli:"opt --branch"`
	Wait     bool   `cli:"opt --wait"`
}

func (r *Status) Run() error {
	var branches []string
	if r.Branch != "" {
		branches = []string{r.Branch}
	} else {
		branches = []string{"master"}
		if cb, err := currentBranch(); err == nil && cb != "master" {
			branches = append([]string{cb}, "master")
		}
	}
	repo, err := githubRepo()
	if err != nil {
		return err
	}
	cl, err := client()
	if err != nil {
		return err
	}

	l := log.New(os.Stderr, "", 0)

	if r.Wait {
		branch := r.Branch
		if branch == "" {
			branch, err = currentBranch()
			if err != nil {
				return err
			}
		}
		var printedURL bool
		for {
			s, err := loadStatus(cl, repo, branch)
			if err != nil {
				l.Printf("error fetching status: %s", err)
			} else {
				if s.State != statusPending {
					fmt.Println(s.State)
					if s.State == statusSuccess {
						return nil
					}
					return fmt.Errorf("not successful (%s)", s.State)
				}
				if !printedURL && len(s.Statuses) > 0 {
					l.Printf("url=%s", s.Statuses[0].TargetURL)
					printedURL = true
				}
			}
			time.Sleep(10 * time.Second)
		}
		return nil
	}

	type status struct {
		Time   time.Time
		Branch string
		URL    string
		URLs   []string
		Status string
		SHA    string
	}

	t := gocli.NewTable()
	all := []*status{}
	failures := 0
	agoFunc := func(t time.Time) string { return strings.Split(time.Since(t).String(), ".")[0] }
	for _, b := range branches {
		st := &status{Branch: b}
		all = append(all, st)
		if s, err := loadStatus(cl, repo, b); err != nil {
			if isNotFound(err) {
				st.Status = "not_found"
			} else {
				return err
			}
		} else {
			st.Status = s.State
			st.SHA = s.SHA
			sm := map[string]int{}
			for _, s := range s.Statuses {
				sm[s.State]++
			}
			if sm[statusFailure] > 0 {
				st.Status = statusFailure
				failures++
			} else if sm[statusPending] > 0 {
				st.Status = statusPending
			} else {
				st.Status = statusSuccess
			}
			t.Add(string(b), colorizeStatus(st.Status))
			if len(s.Statuses) > 0 {
				for _, ss := range s.Statuses {
					if ss.TargetURL != "" {
						st.URLs = append(st.URLs, ss.TargetURL)
					}
					args := []interface{}{"", colorizeStatus(ss.State), truncate(s.SHA, 8, false), ss.Context, agoFunc(ss.CreatedAt)}
					if r.WithURLs {
						args = append(args, ss.TargetURL)
					}
					t.Add(args...)
				}
			}
		}
	}

	if r.Open {
		if len(all) == 0 {
			return fmt.Errorf("no status found")
		}
		s := all[0]
		for _, s := range all {
			l.Printf("url: %s", s.URL)
		}
		url := ""
		if s.URL != "" {
			url = s.URL
		} else if len(s.URLs) == 1 {
			url = s.URLs[0]
		} else {
			return fmt.Errorf("status has no url (yet?). url=%q urls=%#v", s.URL, s.URLs)
		}
		return openUrl(url)
	}
	fmt.Println(t)
	if failures > 0 {
		return errors.Errorf("%d failures", failures)
	}
	return nil
}

func isNotFound(err error) bool {
	return err != nil && strings.Contains(err.Error(), "404 Not Found")
}

const (
	statusSuccess  = "success"
	statusPending  = "pending"
	statusNotFound = "not_found"
	statusFailure  = "failure"
)

func colorizeStatus(in string) string {
	color := gocli.Green
	switch in {
	case statusSuccess:
		color = gocli.Green
	case statusPending, statusNotFound:
		color = gocli.Yellow
	default:
		color = gocli.Red
	}
	return color(in)
}

func loadStatus(cl *github.Client, repo, ref string) (res *statusResponse, err error) {
	u := "https://api.github.com/repos/" + repo + "/commits/" + ref + "/status"
	rsp, err := cl.Get(u)
	if err != nil {
		return nil, err
	}
	defer rsp.Body.Close()
	if rsp.Status[0] != '2' {
		b, _ := ioutil.ReadAll(rsp.Body)
		return nil, fmt.Errorf("got status %s but expected 2x. body=%s", rsp.Status, string(b))
	}
	err = json.NewDecoder(rsp.Body).Decode(&res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

func currentBranch() (string, error) {
	b, err := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD").CombinedOutput()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(b)), nil
}

type statusResponse struct {
	State    string `json:"state"`
	Statuses []*struct {
		State     string    `json:"state,omitempty"`
		URL       string    `json:"url,omitempty"`
		Context   string    `json:"context"`
		TargetURL string    `json:"target_url,omitempty"`
		CreatedAt time.Time `json:"created_at,omitempty"`
		UpdatedAt time.Time `json:"updated_at,omitempty"`
	} `json:"statuses"`
	SHA string `json:"sha"`
}

// to be used to colorize
func dataOn(f *os.File) bool {
	stat, err := f.Stat()
	if err != nil {
		return false
	}
	return (stat.Mode() & os.ModeCharDevice) == 0
}
<|endoftext|>


<commit_before>/**
 * Copyright 2015 @ z3q.net.
 * name : value_rep
 * author : jarryliu
 * date : 2016-05-27 15:32
 * description :
 * history :
 */
package repository

//todo: 因配置缓存与本地存储问题,子系统不能分布式部署。

import (
	"database/sql"
	"errors"
	"fmt"
	"github.com/jsix/gof/db"
	"github.com/jsix/gof/log"
	"github.com/jsix/gof/storage"
	"github.com/jsix/gof/util"
	"go2o/core/domain/interface/valueobject"
	"go2o/core/infrastructure/tool/sms"
	"strconv"
	"strings"
	"sync"
)

var _ valueobject.IValueRep = new(valueRep)
var (
	valueRepCacheKey = "go2o:rep:value-rep:cache"
)

type valueRep struct {
	db.Connector
	storage          storage.Interface
	_wxConf          *valueobject.WxApiConfig
	_wxGob           *util.GobFile
	_rpConf          *valueobject.RegisterPerm
	_rpGob           *util.GobFile
	_numConf         *valueobject.GlobNumberConf
	_numGob          *util.GobFile
	_globMchConf     *valueobject.PlatformConf
	_mchGob          *util.GobFile
	_globRegistry    *valueobject.Registry
	_rstGob          *util.GobFile
	_globMchSaleConf *valueobject.GlobMchSaleConf
	_mscGob          *util.GobFile
	_smsConf         valueobject.SmsApiSet
	_smsGob          *util.GobFile
	_areaCache       map[int][]*valueobject.Area
	_areaMux         sync.Mutex
}

func NewValueRep(conn db.Connector, storage storage.Interface) valueobject.IValueRep {
	return &valueRep{
		Connector: conn,
		storage:   storage,
		_rstGob:   util.NewGobFile("conf/core/registry"),
		_wxGob:    util.NewGobFile("conf/core/wx_api"),
		_rpGob:    util.NewGobFile("conf/core/register_perm"),
		_numGob:   util.NewGobFile("conf/core/number_conf"),
		_mchGob:   util.NewGobFile("conf/core/pm_conf"),
		_mscGob:   util.NewGobFile("conf/core/mch_sale_conf"),
		_smsGob:   util.NewGobFile("conf/core/sms_conf"),
	}
}

func (vp *valueRep) checkReload() error {
	i, err := vp.storage.GetInt(valueRepCacheKey)
	if i == 0 || err != nil {
		vp._wxConf = nil
		vp._numConf = nil
		vp._rpConf = nil
		vp._smsConf = nil
		vp._globMchConf = nil
		vp._globMchSaleConf = nil
		vp._globRegistry = nil
	}
	return vp.storage.Set(valueRepCacheKey, 1)
}

func (vp *valueRep) signReload() {
	vp.storage.Set(valueRepCacheKey, 0)
}

// 获取微信接口配置
func (vp *valueRep) GetWxApiConfig() valueobject.WxApiConfig {
	vp.checkReload()
	if vp._wxConf == nil {
		vp._wxConf = &valueobject.WxApiConfig{}
		vp._wxGob.Unmarshal(vp._wxConf)
	}
	return *vp._wxConf
}

// 保存微信接口配置
func (vp *valueRep) SaveWxApiConfig(v *valueobject.WxApiConfig) error {
	if v != nil {
		defer vp.signReload()
		//todo: 检查证书文件是否存在
		vp._wxConf = v
		return vp._wxGob.Save(vp._wxConf)
	}
	return errors.New("nil value")
}

// 获取注册权限
func (vp *valueRep) GetRegisterPerm() valueobject.RegisterPerm {
	vp.checkReload()
	if vp._rpConf == nil {
		v := defaultRegisterPerm
		vp._rpConf = &v
		vp._rpGob.Unmarshal(vp._rpConf)
	}
	return *vp._rpConf
}

// 保存注册权限
func (vp *valueRep) SaveRegisterPerm(v *valueobject.RegisterPerm) error {
	if v != nil {
		defer vp.signReload()
		vp._rpConf = v
		log.Println("--- save ", vp._rpConf.RegisterMode)
		return vp._rpGob.Save(vp._rpConf)
	}
	return nil
}

// 获取全局系统销售设置
func (vp *valueRep) GetGlobNumberConf() valueobject.GlobNumberConf {
	vp.checkReload()
	if vp._numConf == nil {
		v := DefaultGlobNumberConf
		vp._numConf = &v
		vp._numGob.Unmarshal(vp._numConf)
	}
	return *vp._numConf
}

// 保存全局系统销售设置
func (vp *valueRep) SaveGlobNumberConf(v *valueobject.GlobNumberConf) error {
	if v != nil {
		defer vp.signReload()
		vp._numConf = v
		return vp._numGob.Save(vp._numConf)
	}
	return nil
}

// 获取平台设置
func (vp *valueRep) GetPlatformConf() valueobject.PlatformConf {
	vp.checkReload()
	if vp._globMchConf == nil {
		v := defaultPlatformConf
		vp._globMchConf = &v
		vp._mchGob.Unmarshal(vp._globMchConf)
	}
	return *vp._globMchConf
}

// 保存平台设置
func (vp *valueRep) SavePlatformConf(v *valueobject.PlatformConf) error {
	if v != nil {
		defer vp.signReload()
		vp._globMchConf = v
		return vp._mchGob.Save(vp._globMchConf)
	}
	return nil
}

// 获取数据存储
func (v *valueRep) GetRegistry() valueobject.Registry {
	v.checkReload()
	if v._globRegistry == nil {
		v2 := DefaultRegistry
		v._globRegistry = &v2
		v._rstGob.Unmarshal(v._globRegistry)
	}
	return *v._globRegistry
}

// 保存数据存储
func (v *valueRep) SaveRegistry(r *valueobject.Registry) error {
	if r != nil {
		defer v.signReload()
		v._globRegistry = r
		return v._rstGob.Save(v._globRegistry)
	}
	return nil
}

// 获取全局商户销售设置
func (vp *valueRep) GetGlobMchSaleConf() valueobject.GlobMchSaleConf {
	vp.checkReload()
	if vp._globMchSaleConf == nil {
		v := DefaultGlobMchSaleConf
		vp._globMchSaleConf = &v
		vp._mscGob.Unmarshal(vp._globMchSaleConf)
	}
	return *vp._globMchSaleConf
}

// 保存全局商户销售设置
func (vp *valueRep) SaveGlobMchSaleConf(v *valueobject.GlobMchSaleConf) error {
	if v != nil {
		defer vp.signReload()
		vp._globMchSaleConf = v
		return vp._mscGob.Save(vp._globMchSaleConf)
	}
	return nil
}

// 获取短信设置
func (vp *valueRep) GetSmsApiSet() valueobject.SmsApiSet {
	vp.checkReload()
	if vp._smsConf == nil {
		vp._smsConf = defaultSmsConf
		vp._smsGob.Unmarshal(&vp._smsConf)
	}
	return vp._smsConf
}

// 保存短信API
func (vp *valueRep) SaveSmsApiPerm(provider int, s *valueobject.SmsApiPerm) error {
	if _, ok := vp.GetSmsApiSet()[provider]; !ok {
		return errors.New("系统不支持的短信接口")
	}
	err := sms.CheckSmsApiPerm(provider, s)
	if err == nil {
		if s.Default {
			// 取消其他接口的默认选项
			for p, v := range vp._smsConf {
				if p == provider {
					v.Default = true
				} else {
					v.Default = false
				}
			}
		} else {
			//检验是否取消了正在使用的短信接口
			if i, _ := vp.GetDefaultSmsApiPerm(); i == provider {
				return errors.New("系统应启用一个短信接口")
			}
		}
		defer vp.signReload()
		vp._smsConf[provider] = s
		err = vp._smsGob.Save(vp._smsConf)
	}
	return err
}

// 获取默认的短信API
func (vp *valueRep) GetDefaultSmsApiPerm() (int, *valueobject.SmsApiPerm) {
	for i, v := range vp.GetSmsApiSet() {
		if v.Default {
			return i, v
		}
	}
	panic(errors.New("至少为系统设置一个短信接口"))
}

// 获取下级区域
func (vp *valueRep) GetChildAreas(id int) []*valueobject.Area {
	vp._areaMux.Lock()
	defer vp._areaMux.Unlock()
	if vp._areaCache == nil {
		vp._areaCache = make(map[int][]*valueobject.Area)
	}
	if v, ok := vp._areaCache[id]; ok {
		return v
	}
	v := []*valueobject.Area{}
	err := vp.Connector.GetOrm().Select(&v, "code <> 0 AND parent=?", id)
	if err == nil {
		vp._areaCache[id] = v
	}
	return v
}

// 获取地区名称
func (vp *valueRep) GetAreaNames(id []int) []string {
	strArr := make([]string, len(id))
	for i, v := range id {
		strArr[i] = strconv.Itoa(v)
	}
	i := 0
	vp.Connector.Query(fmt.Sprintf(
		"SELECT name FROM china_area WHERE code IN (%s)",
		strings.Join(strArr, ",")),
		func(rows *sql.Rows) {
			for rows.Next() {
				rows.Scan(&strArr[i])
				strArr[i] = strings.TrimSpace(strArr[i]) //去除空格
				i++
			}
		})
	return strArr
}

// 获取省市区字符串
func (vp *valueRep) GetAreaString(province, city, district int) string {
	names := vp.GetAreaNames([]int{province, city, district})
	if names[1] == "市辖区" || names[1] == "市辖县" || names[1] == "县" {
		return strings.Join([]string{names[0], names[2]}, " ")
	}
	return strings.Join(names, " ")
}
<commit_msg>value_rep<commit_after>/**
 * Copyright 2015 @ z3q.net.
 * name : value_rep
 * author : jarryliu
 * date : 2016-05-27 15:32
 * description :
 * history :
 */
package repository

//todo: 因配置缓存与本地存储问题,子系统不能分布式部署。

import (
	"database/sql"
	"errors"
	"fmt"
	"github.com/jsix/gof/db"
	"github.com/jsix/gof/storage"
	"github.com/jsix/gof/util"
	"go2o/core/domain/interface/valueobject"
	"go2o/core/infrastructure/tool/sms"
	"strconv"
	"strings"
	"sync"
)

var _ valueobject.IValueRep = new(valueRep)
var (
	valueRepCacheKey = "go2o:rep:value-rep:cache"
)

type valueRep struct {
	db.Connector
	storage          storage.Interface
	_wxConf          *valueobject.WxApiConfig
	_wxGob           *util.GobFile
	_rpConf          *valueobject.RegisterPerm
	_rpGob           *util.GobFile
	_numConf         *valueobject.GlobNumberConf
	_numGob          *util.GobFile
	_globMchConf     *valueobject.PlatformConf
	_mchGob          *util.GobFile
	_globRegistry    *valueobject.Registry
	_rstGob          *util.GobFile
	_globMchSaleConf *valueobject.GlobMchSaleConf
	_mscGob          *util.GobFile
	_smsConf         valueobject.SmsApiSet
	_smsGob          *util.GobFile
	_areaCache       map[int][]*valueobject.Area
	_areaMux         sync.Mutex
}

func NewValueRep(conn db.Connector, storage storage.Interface) valueobject.IValueRep {
	return &valueRep{
		Connector: conn,
		storage:   storage,
		_rstGob:   util.NewGobFile("conf/core/registry"),
		_wxGob:    util.NewGobFile("conf/core/wx_api"),
		_rpGob:    util.NewGobFile("conf/core/register_perm"),
		_numGob:   util.NewGobFile("conf/core/number_conf"),
		_mchGob:   util.NewGobFile("conf/core/pm_conf"),
		_mscGob:   util.NewGobFile("conf/core/mch_sale_conf"),
		_smsGob:   util.NewGobFile("conf/core/sms_conf"),
	}
}

func (vp *valueRep) checkReload() error {
	i, err := vp.storage.GetInt(valueRepCacheKey)
	if i == 0 || err != nil {
		vp._wxConf = nil
		vp._numConf = nil
		vp._rpConf = nil
		vp._smsConf = nil
		vp._globMchConf = nil
		vp._globMchSaleConf = nil
		vp._globRegistry = nil
	}
	return vp.storage.Set(valueRepCacheKey, 1)
}

func (vp *valueRep) signReload() {
	vp.storage.Set(valueRepCacheKey, 0)
}

// 获取微信接口配置
func (vp *valueRep) GetWxApiConfig() valueobject.WxApiConfig {
	vp.checkReload()
	if vp._wxConf == nil {
		vp._wxConf = &valueobject.WxApiConfig{}
		vp._wxGob.Unmarshal(vp._wxConf)
	}
	return *vp._wxConf
}

// 保存微信接口配置
func (vp *valueRep) SaveWxApiConfig(v *valueobject.WxApiConfig) error {
	if v != nil {
		defer vp.signReload()
		//todo: 检查证书文件是否存在
		vp._wxConf = v
		return vp._wxGob.Save(vp._wxConf)
	}
	return errors.New("nil value")
}

// 获取注册权限
func (vp *valueRep) GetRegisterPerm() valueobject.RegisterPerm {
	vp.checkReload()
	if vp._rpConf == nil {
		v := defaultRegisterPerm
		vp._rpConf = &v
		vp._rpGob.Unmarshal(vp._rpConf)
	}
	return *vp._rpConf
}

// 保存注册权限
func (vp *valueRep) SaveRegisterPerm(v *valueobject.RegisterPerm) error {
	if v != nil {
		defer vp.signReload()
		vp._rpConf = v
		return vp._rpGob.Save(vp._rpConf)
	}
	return nil
}

// 获取全局系统销售设置
func (vp *valueRep) GetGlobNumberConf() valueobject.GlobNumberConf {
	vp.checkReload()
	if vp._numConf == nil {
		v := DefaultGlobNumberConf
		vp._numConf = &v
		vp._numGob.Unmarshal(vp._numConf)
	}
	return *vp._numConf
}

// 保存全局系统销售设置
func (vp *valueRep) SaveGlobNumberConf(v *valueobject.GlobNumberConf) error {
	if v != nil {
		defer vp.signReload()
		vp._numConf = v
		return vp._numGob.Save(vp._numConf)
	}
	return nil
}

// 获取平台设置
func (vp *valueRep) GetPlatformConf() valueobject.PlatformConf {
	vp.checkReload()
	if vp._globMchConf == nil {
		v := defaultPlatformConf
		vp._globMchConf = &v
		vp._mchGob.Unmarshal(vp._globMchConf)
	}
	return *vp._globMchConf
}

// 保存平台设置
func (vp *valueRep) SavePlatformConf(v *valueobject.PlatformConf) error {
	if v != nil {
		defer vp.signReload()
		vp._globMchConf = v
		return vp._mchGob.Save(vp._globMchConf)
	}
	return nil
}

// 获取数据存储
func (v *valueRep) GetRegistry() valueobject.Registry {
	v.checkReload()
	if v._globRegistry == nil {
		v2 := DefaultRegistry
		v._globRegistry = &v2
		v._rstGob.Unmarshal(v._globRegistry)
	}
	return *v._globRegistry
}

// 保存数据存储
func (v *valueRep) SaveRegistry(r *valueobject.Registry) error {
	if r != nil {
		defer v.signReload()
		v._globRegistry = r
		return v._rstGob.Save(v._globRegistry)
	}
	return nil
}

// 获取全局商户销售设置
func (vp *valueRep) GetGlobMchSaleConf() valueobject.GlobMchSaleConf {
	vp.checkReload()
	if vp._globMchSaleConf == nil {
		v := DefaultGlobMchSaleConf
		vp._globMchSaleConf = &v
		vp._mscGob.Unmarshal(vp._globMchSaleConf)
	}
	return *vp._globMchSaleConf
}

// 保存全局商户销售设置
func (vp *valueRep) SaveGlobMchSaleConf(v *valueobject.GlobMchSaleConf) error {
	if v != nil {
		defer vp.signReload()
		vp._globMchSaleConf = v
		return vp._mscGob.Save(vp._globMchSaleConf)
	}
	return nil
}

// 获取短信设置
func (vp *valueRep) GetSmsApiSet() valueobject.SmsApiSet {
	vp.checkReload()
	if vp._smsConf == nil {
		vp._smsConf = defaultSmsConf
		vp._smsGob.Unmarshal(&vp._smsConf)
	}
	return vp._smsConf
}

// 保存短信API
func (vp *valueRep) SaveSmsApiPerm(provider int, s *valueobject.SmsApiPerm) error {
	if _, ok := vp.GetSmsApiSet()[provider]; !ok {
		return errors.New("系统不支持的短信接口")
	}
	err := sms.CheckSmsApiPerm(provider, s)
	if err == nil {
		if s.Default {
			// 取消其他接口的默认选项
			for p, v := range vp._smsConf {
				if p == provider {
					v.Default = true
				} else {
					v.Default = false
				}
			}
		} else {
			//检验是否取消了正在使用的短信接口
			if i, _ := vp.GetDefaultSmsApiPerm(); i == provider {
				return errors.New("系统应启用一个短信接口")
			}
		}
		defer vp.signReload()
		vp._smsConf[provider] = s
		err = vp._smsGob.Save(vp._smsConf)
	}
	return err
}

// 获取默认的短信API
func (vp *valueRep) GetDefaultSmsApiPerm() (int, *valueobject.SmsApiPerm) {
	for i, v := range vp.GetSmsApiSet() {
		if v.Default {
			return i, v
		}
	}
	panic(errors.New("至少为系统设置一个短信接口"))
}

// 获取下级区域
func (vp *valueRep) GetChildAreas(id int) []*valueobject.Area {
	vp._areaMux.Lock()
	defer vp._areaMux.Unlock()
	if vp._areaCache == nil {
		vp._areaCache = make(map[int][]*valueobject.Area)
	}
	if v, ok := vp._areaCache[id]; ok {
		return v
	}
	v := []*valueobject.Area{}
	err := vp.Connector.GetOrm().Select(&v, "code <> 0 AND parent=?", id)
	if err == nil {
		vp._areaCache[id] = v
	}
	return v
}

// 获取地区名称
func (vp *valueRep) GetAreaNames(id []int) []string {
	strArr := make([]string, len(id))
	for i, v := range id {
		strArr[i] = strconv.Itoa(v)
	}
	i := 0
	vp.Connector.Query(fmt.Sprintf(
		"SELECT name FROM china_area WHERE code IN (%s)",
		strings.Join(strArr, ",")),
		func(rows *sql.Rows) {
			for rows.Next() {
				rows.Scan(&strArr[i])
				strArr[i] = strings.TrimSpace(strArr[i]) //去除空格
				i++
			}
		})
	return strArr
}

// 获取省市区字符串
func (vp *valueRep) GetAreaString(province, city, district int) string {
	names := vp.GetAreaNames([]int{province, city, district})
	if names[1] == "市辖区" || names[1] == "市辖县" || names[1] == "县" {
		return strings.Join([]string{names[0], names[2]}, " ")
	}
	return strings.Join(names, " ")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"path"
	"strings"
	"syscall"

	"github.com/burke/zeus/go/config"
	"github.com/burke/zeus/go/restarter"
	slog "github.com/burke/zeus/go/shinylog"
	"github.com/burke/zeus/go/zeusclient"
	"github.com/burke/zeus/go/zeusmaster"
	"github.com/burke/zeus/go/zeusversion"
	"time"
)

var color bool = true
var Args = os.Args[1:]

func main() {
	for Args = os.Args[1:]; Args != nil && len(Args) > 0 && Args[0][0] == '-'; Args = Args[1:] {
		switch Args[0] {
		case "--no-color":
			color = false
			slog.DisableColor()
		case "--log":
			tracefile, err := os.OpenFile(Args[1], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
			if err == nil {
				slog.TraceLogger = slog.NewTraceLogger(tracefile)
				Args = Args[1:]
			} else {
				fmt.Printf("Could not open trace file %s", Args[1])
				return
			}
		case "--file-change-delay":
			if len(Args) > 1 {
				delay, err := time.ParseDuration(Args[1])
				if err != nil {
					execManPage("zeus")
				}
				Args = Args[1:]
				restarter.FileChangeWindow = delay
			} else {
				execManPage("zeus")
			}
		}
	}
	if len(Args) == 0 {
		execManPage("zeus")
	}

	if generalHelpRequested(Args) {
		execManPage("zeus")
	} else if Args[0] == "help" {
		commandSpecificHelp(Args)
	} else if Args[0] == "version" || Args[0] == "--version" {
		println("Zeus version " + zeusversion.VERSION)
	} else if Args[0] == "start" {
		zeusmaster.Run()
	} else if Args[0] == "init" {
		zeusInit()
	} else if Args[0] == "commands" {
		zeusCommands()
	} else {
		tree := config.BuildProcessTree()
		for _, name := range tree.AllCommandsAndAliases() {
			if Args[0] == name {
				zeusclient.Run()
				return
			}
		}

		commandNotFound(Args[0])
	}
}

func execManPage(page string) {
	binaryPath := os.Args[0]
	gemDir := path.Dir(path.Dir(binaryPath))
	manDir := path.Join(gemDir, "man/build")
	zeus := path.Join(manDir, page)
	syscall.Exec("/usr/bin/env", []string{"/usr/bin/env", "man", zeus}, os.Environ())
}

func red() string {
	if color {
		return "\x1b[31m"
	}
	return ""
}

func reset() string {
	if color {
		return "\x1b[0m"
	}
	return ""
}

func copyFile(from, to string) (err error) {
	var src, dst *os.File
	wd, _ := os.Getwd()
	target := path.Join(wd, to)

	if src, err = os.Open(from); err != nil {
		slog.Colorized("      {red}fail{reset}  " + to)
		return err
	}
	defer src.Close()

	if dst, err = os.OpenFile(target, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666); err != nil {
		slog.Colorized("    {red}exists{reset}  " + to)
		return err
	}
	defer dst.Close()

	if _, err = io.Copy(dst, src); err != nil {
		slog.Colorized("      {red}fail{reset}  " + to)
		return err
	}

	slog.Colorized("    {brightgreen}create{reset}  " + to)
	return nil
}

func zeusInit() {
	binaryPath := os.Args[0]
	gemDir := path.Dir(path.Dir(binaryPath))
	jsonPath := path.Join(gemDir, "examples/custom_plan/zeus.json")
	planPath := path.Join(gemDir, "examples/custom_plan/custom_plan.rb")
	copyFile(jsonPath, "zeus.json")
	copyFile(planPath, "custom_plan.rb")
}

func zeusCommands() {
	tree := config.BuildProcessTree()
	for _, command := range tree.Commands {
		alia := strings.Join(command.Aliases, ", ")
		var aliasPart string
		if len(alia) > 0 {
			aliasPart = " (alias: " + alia + ")"
		}
		println("zeus " + command.Name + aliasPart)
	}
}

func commandNotFound(command string) {
	println(red() + "Could not find command \"" + command + "\"." + reset())
}

func commandSpecificHelp(args []string) {
	if args[1] == "start" {
		execManPage("zeus-start")
	} else if args[1] == "init" {
		execManPage("zeus-init")
	} else {
		println(red() + "Command-level help is not yet fully implemented." + reset())
	}
}

func generalHelpRequested(args []string) bool {
	helps := []string{"help", "--help", "-h", "--help", "-?", "?"}
	if len(args) == 1 {
		for _, str := range helps {
			if args[0] == str {
				return true
			}
		}
	}
	return false
}
<commit_msg>Fix version option.<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"path"
	"strings"
	"syscall"

	"github.com/burke/zeus/go/config"
	"github.com/burke/zeus/go/restarter"
	slog "github.com/burke/zeus/go/shinylog"
	"github.com/burke/zeus/go/zeusclient"
	"github.com/burke/zeus/go/zeusmaster"
	"github.com/burke/zeus/go/zeusversion"
	"time"
)

var color bool = true
var Args = os.Args[1:]

func main() {
	for Args = os.Args[1:]; Args != nil && len(Args) > 0 && Args[0][0] == '-'; Args = Args[1:] {
		switch Args[0] {
		case "--no-color":
			color = false
			slog.DisableColor()
		case "--log":
			tracefile, err := os.OpenFile(Args[1], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
			if err == nil {
				slog.TraceLogger = slog.NewTraceLogger(tracefile)
				Args = Args[1:]
			} else {
				fmt.Printf("Could not open trace file %s", Args[1])
				return
			}
		case "--file-change-delay":
			if len(Args) > 1 {
				delay, err := time.ParseDuration(Args[1])
				if err != nil {
					execManPage("zeus")
				}
				Args = Args[1:]
				restarter.FileChangeWindow = delay
			} else {
				execManPage("zeus")
			}
		case "--version":
			printVersion()
			return
		}
	}
	if len(Args) == 0 {
		execManPage("zeus")
	}

	if generalHelpRequested(Args) {
		execManPage("zeus")
	} else if Args[0] == "help" {
		commandSpecificHelp(Args)
	} else if Args[0] == "version" {
		printVersion()
	} else if Args[0] == "start" {
		zeusmaster.Run()
	} else if Args[0] == "init" {
		zeusInit()
	} else if Args[0] == "commands" {
		zeusCommands()
	} else {
		tree := config.BuildProcessTree()
		for _, name := range tree.AllCommandsAndAliases() {
			if Args[0] == name {
				zeusclient.Run()
				return
			}
		}

		commandNotFound(Args[0])
	}
}

func execManPage(page string) {
	binaryPath := os.Args[0]
	gemDir := path.Dir(path.Dir(binaryPath))
	manDir := path.Join(gemDir, "man/build")
	zeus := path.Join(manDir, page)
	syscall.Exec("/usr/bin/env", []string{"/usr/bin/env", "man", zeus}, os.Environ())
}

func red() string {
	if color {
		return "\x1b[31m"
	}
	return ""
}

func reset() string {
	if color {
		return "\x1b[0m"
	}
	return ""
}

func copyFile(from, to string) (err error) {
	var src, dst *os.File
	wd, _ := os.Getwd()
	target := path.Join(wd, to)

	if src, err = os.Open(from); err != nil {
		slog.Colorized("      {red}fail{reset}  " + to)
		return err
	}
	defer src.Close()

	if dst, err = os.OpenFile(target, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666); err != nil {
		slog.Colorized("    {red}exists{reset}  " + to)
		return err
	}
	defer dst.Close()

	if _, err = io.Copy(dst, src); err != nil {
		slog.Colorized("      {red}fail{reset}  " + to)
		return err
	}

	slog.Colorized("    {brightgreen}create{reset}  " + to)
	return nil
}

func zeusInit() {
	binaryPath := os.Args[0]
	gemDir := path.Dir(path.Dir(binaryPath))
	jsonPath := path.Join(gemDir, "examples/custom_plan/zeus.json")
	planPath := path.Join(gemDir, "examples/custom_plan/custom_plan.rb")
	copyFile(jsonPath, "zeus.json")
	copyFile(planPath, "custom_plan.rb")
}

func zeusCommands() {
	tree := config.BuildProcessTree()
	for _, command := range tree.Commands {
		alia := strings.Join(command.Aliases, ", ")
		var aliasPart string
		if len(alia) > 0 {
			aliasPart = " (alias: " + alia + ")"
		}
		println("zeus " + command.Name + aliasPart)
	}
}

func commandNotFound(command string) {
	println(red() + "Could not find command \"" + command + "\"." + reset())
}

func commandSpecificHelp(args []string) {
	if args[1] == "start" {
		execManPage("zeus-start")
	} else if args[1] == "init" {
		execManPage("zeus-init")
	} else {
		println(red() + "Command-level help is not yet fully implemented." + reset())
	}
}

func generalHelpRequested(args []string) bool {
	helps := []string{"help", "--help", "-h", "--help", "-?", "?"}
	if len(args) == 1 {
		for _, str := range helps {
			if args[0] == str {
				return true
			}
		}
	}
	return false
}

func printVersion() {
	println("Zeus version " + zeusversion.VERSION)
}
<|endoftext|>


<commit_before>package parsing

import (
	"encoding/json"
	"fmt"
	"log"
	"reflect"
	"strconv"
)

func marshError(input interface{}, stage string, err error) {
	if err != nil {
		fmt.Println(input)
		fmt.Println(stage)
		log.Fatal("Remashalling error! ", err)
	}
}

// Remarshal: Converts an interface back into a Keyvalue type through re-marshalling
func Remarshal(input interface{}) Keyvalue {
	var back Keyvalue
	out, e := json.Marshal(input)
	marshError(input, "Marshal", e)
	e = json.Unmarshal([]byte(out), &back)
	marshError(input, "Unmarshal", e)
	return back
}

// Slicer: Creates an array of key names given a Keyvalue map
func Slicer(input Keyvalue) []string {
	var r []string
	for key := range input {
		r = append(r, key)
	}
	return r
}

// PathFormatter: Given an array, construct it into a jmespath expression (string with . separator)
func PathFormatter(input []string) string {
	var r string
	for i := range input {
		if i == (len(input) - 1) {
			r = r + input[i]
		} else {
			r = r + input[i] + "."
		}
	}
	return r
}

// IndexOf: Finds index of an object in a given array
func IndexOf(inputList []string, inputKey string) int {
	for i, v := range inputList {
		if v == inputKey {
			return i
		}
	}
	return -1
}

// UnorderedKeyMatch: Returns a bool dependant on all 'keys' in a map matching.
func UnorderedKeyMatch(o Keyvalue, m Keyvalue) bool {
	istanbool := true
	oSlice := Slicer(o)
	mSlice := Slicer(m)
	for k := range oSlice {
		val := IndexOf(mSlice, oSlice[k])
		if val == -1 {
			istanbool = false
		}
	}

	for k := range mSlice {
		val := IndexOf(oSlice, mSlice[k])
		if val == -1 {
			istanbool = false
		}
	}
	return istanbool
}

// SliceIndex: Adds an 'index' value to the last string in the slice, used for the 'path' to handle arrays.
func SliceIndex(i int, path []string) []string {

	nPath := make([]string, len(path))
	copy(nPath, path)
	iter := len(nPath) - 1
	nPath[iter] = nPath[iter] + "[" + strconv.Itoa(i) + "]"
	return nPath
}

func MatchAny(compare interface{}, compareSlice []interface{}) bool {
	for i := range compareSlice {
		if reflect.DeepEqual(compare, compareSlice[i]) {
			return true
		}
	}
	return false
}

// DoMapArrayKeysMatch: Uses 'UnorderedKeyMatch' to return a bool for two interfaces if they're both maps
func DoMapArrayKeysMatch(o interface{}, m interface{}) bool {
	if reflect.TypeOf(o).Kind() == reflect.Map && reflect.TypeOf(m).Kind() == reflect.Map {
		return UnorderedKeyMatch(Remarshal(o), Remarshal(m))
	}
	return false
}
<commit_msg>updating path functions for escaped .<commit_after>package parsing

import (
	"encoding/json"
	"fmt"
	"log"
	"reflect"
	"regexp"
	"strconv"
	"strings"
)

func marshError(input interface{}, stage string, err error) {
	if err != nil {
		fmt.Println(input)
		fmt.Println(stage)
		log.Fatal("Remashalling error! ", err)
	}
}

// Remarshal: Converts an interface back into a Keyvalue type through re-marshalling
func Remarshal(input interface{}) Keyvalue {
	var back Keyvalue
	out, e := json.Marshal(input)
	marshError(input, "Marshal", e)
	e = json.Unmarshal([]byte(out), &back)
	marshError(input, "Unmarshal", e)
	return back
}

// Slicer: Creates an array of key names given a Keyvalue map
func Slicer(input Keyvalue) []string {
	var r []string
	for key := range input {
		r = append(r, key)
	}
	return r
}

// PathFormatter: Given an array, construct it into a jmespath expression (string with . separator)
func PathFormatter(input []string) string {
	var r string
	for i := range input {
		str := input[i]
		// Escape a . in string name for parsing later
		str = strings.Replace(str, ".", "\\.", -1)
		if i == (len(input) - 1) {
			r = r + str
		} else {
			r = r + str + "."
		}
	}
	return r
}

// IndexOf: Finds index of an object in a given array
func IndexOf(inputList []string, inputKey string) int {
	for i, v := range inputList {
		if v == inputKey {
			return i
		}
	}
	return -1
}

// UnorderedKeyMatch: Returns a bool dependant on all 'keys' in a map matching.
func UnorderedKeyMatch(o Keyvalue, m Keyvalue) bool {
	istanbool := true
	oSlice := Slicer(o)
	mSlice := Slicer(m)
	for k := range oSlice {
		val := IndexOf(mSlice, oSlice[k])
		if val == -1 {
			istanbool = false
		}
	}

	for k := range mSlice {
		val := IndexOf(oSlice, mSlice[k])
		if val == -1 {
			istanbool = false
		}
	}
	return istanbool
}

// SliceIndex: Adds an 'index' value to the last string in the slice, used for the 'path' to handle arrays.
func SliceIndex(i int, path []string) []string {

	nPath := make([]string, len(path))
	copy(nPath, path)
	iter := len(nPath) - 1
	nPath[iter] = nPath[iter] + "[" + strconv.Itoa(i) + "]"
	return nPath
}

func MatchAny(compare interface{}, compareSlice []interface{}) bool {
	for i := range compareSlice {
		if reflect.DeepEqual(compare, compareSlice[i]) {
			return true
		}
	}
	return false
}

// DoMapArrayKeysMatch: Uses 'UnorderedKeyMatch' to return a bool for two interfaces if they're both maps
func DoMapArrayKeysMatch(o interface{}, m interface{}) bool {
	if reflect.TypeOf(o).Kind() == reflect.Map && reflect.TypeOf(m).Kind() == reflect.Map {
		return UnorderedKeyMatch(Remarshal(o), Remarshal(m))
	}
	return false
}

// PathSplit: Splits up jmespath format path into a slice, will ignore escaped '.' ; opposite of PathFormatter?
func PathSplit(input string) []string {
	r := regexp.MustCompile(`[^\\]\.`)
	str := r.Split(input, -1)
	for i := range str {
		str[i] = strings.Replace(str[i], "\\.", ".", -1)
	}
	return str
}
<|endoftext|>


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

package piazza

import (
	"net/http"
	"testing"

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

//--------------------------

func TestNT(t *testing.T) {
	assert := assert.New(t)
	server := &http.Server{Addr: ":19999", Handler: http.DefaultServeMux}
	server.ListenAndServe()

	GetValueFromHeader(http.Header{}, "Content-Type")
	_, _, _, err := HTTP(GET, "localhost:19999", NewHeaderBuilder().AddJsonContentType().AddBasicAuth("foo", "bar").GetHeader(), nil)
	assert.NoError(err)
	_, _, _, err = HTTP(GET, "localhost:19999/exit", NewHeaderBuilder().GetHeader(), nil)
	assert.NoError(err)
}

func ExitFunc(response http.ResponseWriter, request *http.Request) {
	//log.Fatal("/exit handler called")
}
<commit_msg>Loose end<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package piazza

import (
	"net/http"
	"testing"

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

//--------------------------

func TestNT(t *testing.T) {
	assert := assert.New(t)
	server := &http.Server{Addr: ":19999", Handler: http.DefaultServeMux}
	err := server.ListenAndServe()
	assert.NoError(err)

	GetValueFromHeader(http.Header{}, "Content-Type")
	_, _, _, err := HTTP(GET, "localhost:19999", NewHeaderBuilder().AddJsonContentType().AddBasicAuth("foo", "bar").GetHeader(), nil)
	assert.NoError(err)
	_, _, _, err = HTTP(GET, "localhost:19999/exit", NewHeaderBuilder().GetHeader(), nil)
	assert.NoError(err)
}

func ExitFunc(response http.ResponseWriter, request *http.Request) {
	//log.Fatal("/exit handler called")
}
<|endoftext|>