<commit_before>package io

import (
	"fmt"

	"code.google.com/p/gcfg"
)

type BallConfig struct {
	// Required
	X, Y, Z, Radius float64

	// Optional
	RadiusMultiplier float64
	Name string
}

func (ball *BallConfig) CheckInit(name string, totalWidth float64) error {
	if ball.Radius == 0 {
		return fmt.Errorf(
			"Need to specify a positive radius for Ball '%s'.", name,
		)
	}

	if ball.X >= totalWidth || ball.X < 0 {
		return fmt.Errorf(
			"X center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.X,
		)
	} else if ball.Y >= totalWidth || ball.Y < 0 {
		return fmt.Errorf(
			"Y center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.Y,
		)
	} else if ball.Z >= totalWidth || ball.Z < 0 {
		return fmt.Errorf(
			"Z center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.Z,
		)
	}

	ball.Name = name
	if ball.RadiusMultiplier == 0 {
		ball.RadiusMultiplier = 1
	} else if ball.RadiusMultiplier < 0 {
		return fmt.Errorf(
			"Ball '%s' given a negative radius multiplier, %g.",
			name, ball.RadiusMultiplier,
		)
	}

	return nil
}

func (ball *BallConfig) Box(totalWidth float64) *BoxConfig {
	box := &BoxConfig{}
	box.XWidth = ball.Radius * 2
	box.YWidth = ball.Radius * 2
	box.ZWidth = ball.Radius * 2

	if ball.X > ball.Radius {
		box.X = ball.X - ball.Radius
	} else {
		box.X = ball.X - ball.Radius + totalWidth
	}

	if ball.Y > ball.Radius {
		box.Y = ball.Y - ball.Radius
	} else {
		box.Y = ball.Y - ball.Radius + totalWidth
	}

	if ball.Z > ball.Radius {
		box.Z = ball.Z - ball.Radius
	} else {
		box.Z = ball.Z - ball.Radius + totalWidth
	}

	return box
}

type BoxConfig struct {
	// Required
	X, Y, Z float64
	XWidth, YWidth, ZWidth float64

	// Optional
	Name string
}

func (box *BoxConfig) CheckInit(name string, totalWidth float64) error {
	if box.XWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive XWidth for Box '%s'", name,
		)
	} else if box.YWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive YWidth for Box '%s'", name,
		)
	} else if box.ZWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive ZWidth for Box '%s'", name,
		)
	}

	if box.X >= totalWidth || box.X < 0 {
		return fmt.Errorf(
			"X origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.X,
		)
	} else if box.Y >= totalWidth || box.Y < 0 {
		return fmt.Errorf(
			"Y origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.Y,
		)
	} else if box.Z >= totalWidth || box.Z < 0 {
		return fmt.Errorf(
			"Z origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.Z,
		)
	}

	box.Name = name

	return nil
}

type BoundsConfig struct {
	Ball map[string]*BallConfig
	Box  map[string]*BoxConfig
}

func ReadBoundsConfig(fname string, totalWidth float64) ([]BoxConfig, error) {
	bc := BoundsConfig{}

	if err := gcfg.ReadFileInto(&bc, fname); err != nil {
		return nil, err
	}

	boxes := []BoxConfig{}
	for name, ball := range bc.Ball {
		if err := ball.CheckInit(name, totalWidth); err != nil {
			return nil, err
		}
		boxes = append(boxes, *ball.Box(totalWidth))
	}
	for name, box := range bc.Box {
		if err := box.CheckInit(name, totalWidth); err != nil {
			return nil, err
		}
		boxes = append(boxes, *box)
	}

	return boxes, nil
}
<commit_msg>Copied over names when Ball.Box() is called.<commit_after>package io

import (
	"fmt"

	"code.google.com/p/gcfg"
)

type BallConfig struct {
	// Required
	X, Y, Z, Radius float64

	// Optional
	RadiusMultiplier float64
	Name string
}

func (ball *BallConfig) CheckInit(name string, totalWidth float64) error {
	if ball.Radius == 0 {
		return fmt.Errorf(
			"Need to specify a positive radius for Ball '%s'.", name,
		)
	}

	if ball.X >= totalWidth || ball.X < 0 {
		return fmt.Errorf(
			"X center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.X,
		)
	} else if ball.Y >= totalWidth || ball.Y < 0 {
		return fmt.Errorf(
			"Y center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.Y,
		)
	} else if ball.Z >= totalWidth || ball.Z < 0 {
		return fmt.Errorf(
			"Z center of Ball '%s' must be in range [0, %g), but is %g",
			name, totalWidth, ball.Z,
		)
	}

	ball.Name = name
	if ball.RadiusMultiplier == 0 {
		ball.RadiusMultiplier = 1
	} else if ball.RadiusMultiplier < 0 {
		return fmt.Errorf(
			"Ball '%s' given a negative radius multiplier, %g.",
			name, ball.RadiusMultiplier,
		)
	}

	return nil
}

func (ball *BallConfig) Box(totalWidth float64) *BoxConfig {
	box := &BoxConfig{}
	box.XWidth = ball.Radius * 2
	box.YWidth = ball.Radius * 2
	box.ZWidth = ball.Radius * 2

	if ball.X > ball.Radius {
		box.X = ball.X - ball.Radius
	} else {
		box.X = ball.X - ball.Radius + totalWidth
	}

	if ball.Y > ball.Radius {
		box.Y = ball.Y - ball.Radius
	} else {
		box.Y = ball.Y - ball.Radius + totalWidth
	}

	if ball.Z > ball.Radius {
		box.Z = ball.Z - ball.Radius
	} else {
		box.Z = ball.Z - ball.Radius + totalWidth
	}

	box.Name = ball.Name

	return box
}

type BoxConfig struct {
	// Required
	X, Y, Z float64
	XWidth, YWidth, ZWidth float64

	// Optional
	Name string
}

func (box *BoxConfig) CheckInit(name string, totalWidth float64) error {
	if box.XWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive XWidth for Box '%s'", name,
		)
	} else if box.YWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive YWidth for Box '%s'", name,
		)
	} else if box.ZWidth <= 0 {
		return fmt.Errorf(
			"Need to specify a positive ZWidth for Box '%s'", name,
		)
	}

	if box.X >= totalWidth || box.X < 0 {
		return fmt.Errorf(
			"X origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.X,
		)
	} else if box.Y >= totalWidth || box.Y < 0 {
		return fmt.Errorf(
			"Y origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.Y,
		)
	} else if box.Z >= totalWidth || box.Z < 0 {
		return fmt.Errorf(
			"Z origin of Box '%s' must be in range [0, %g), but is %g",
			name, totalWidth, box.Z,
		)
	}

	box.Name = name

	return nil
}

type BoundsConfig struct {
	Ball map[string]*BallConfig
	Box  map[string]*BoxConfig
}

func ReadBoundsConfig(fname string, totalWidth float64) ([]BoxConfig, error) {
	bc := BoundsConfig{}

	if err := gcfg.ReadFileInto(&bc, fname); err != nil {
		return nil, err
	}

	boxes := []BoxConfig{}
	for name, ball := range bc.Ball {
		if err := ball.CheckInit(name, totalWidth); err != nil {
			return nil, err
		}
		boxes = append(boxes, *ball.Box(totalWidth))
	}
	for name, box := range bc.Box {
		if err := box.CheckInit(name, totalWidth); err != nil {
			return nil, err
		}
		boxes = append(boxes, *box)
	}

	return boxes, nil
}
<|endoftext|>


<commit_before>//   Copyright 2020 MSolution.IO
//
//   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 tagging

import (
	"context"
	"time"

	"github.com/trackit/jsonlog"
	"github.com/trackit/trackit/es"
)

const typeTaggingReport = "tagging-reports"
const indexPrefixTaggingReport = "tagging-reports"
const templateNameTaggingReport = "tagging-reports"

// put the ElasticSearch index for *-tagging-reports indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingReport).BodyString(templateTaggingReport).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES indext tagging-reports.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-reports.", res)
		ctxCancel()
	}
}

const templateTaggingReport = `
{
    "template":"*-tagging-reports",
    "version":1,
    "mappings":{
        "tagging-reports":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "region":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "resourceId":{
                    "type":"keyword"
                },
                "resourceType":{
                    "type":"keyword"
                },
                "tags":{
                    "type":"nested",
                    "properties":{
                        "key":{
                            "type":"keyword"
                        },
                        "value":{
                            "type":"keyword"
                        }
                    }
                },
                "url":{
                    "type":"keyword"
                }
			},
			"_all": {
				"enabled": false
			},
			"date_detection": false,
			"numeric_detection": false
        }
    }
}
`
<commit_msg>Added missing new line between imports<commit_after>//   Copyright 2020 MSolution.IO
//
//   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 tagging

import (
	"context"
	"time"

	"github.com/trackit/jsonlog"

	"github.com/trackit/trackit/es"
)

const typeTaggingReport = "tagging-reports"
const indexPrefixTaggingReport = "tagging-reports"
const templateNameTaggingReport = "tagging-reports"

// put the ElasticSearch index for *-tagging-reports indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingReport).BodyString(templateTaggingReport).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES indext tagging-reports.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-reports.", res)
		ctxCancel()
	}
}

const templateTaggingReport = `
{
    "template":"*-tagging-reports",
    "version":1,
    "mappings":{
        "tagging-reports":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "region":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "resourceId":{
                    "type":"keyword"
                },
                "resourceType":{
                    "type":"keyword"
                },
                "tags":{
                    "type":"nested",
                    "properties":{
                        "key":{
                            "type":"keyword"
                        },
                        "value":{
                            "type":"keyword"
                        }
                    }
                },
                "url":{
                    "type":"keyword"
                }
			},
			"_all": {
				"enabled": false
			},
			"date_detection": false,
			"numeric_detection": false
        }
    }
}
`
<|endoftext|>


<commit_before>package client_test

import (
	"context"
	"math"
	"testing"
	"time"

	"github.com/libp2p/go-libp2p"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
	pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util"

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

func TestReservationFailures(t *testing.T) {
	type testcase struct {
		name          string
		streamHandler network.StreamHandler
		err           string
	}
	testcases := []testcase{
		{
			name:          "unsupported protocol",
			streamHandler: nil,
			err:           "protocol not supported",
		},
		{
			name: "wrong message type",
			streamHandler: func(s network.Stream) {
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type: pbv2.HopMessage_RESERVE.Enum(),
				})
			},
			err: "unexpected relay response: not a status message",
		},
		{
			name: "unknown status",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status(1337)
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:   pbv2.HopMessage_STATUS.Enum(),
					Status: &status,
				})
			},
			err: "reservation failed",
		},
		{
			name: "invalid time",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status_OK
				expire := uint64(math.MaxUint64)
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:        pbv2.HopMessage_STATUS.Enum(),
					Status:      &status,
					Reservation: &pbv2.Reservation{Expire: &expire},
				})
			},
			err: "received reservation with expiration date in the past",
		},
		{
			name: "invalid voucher",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status_OK
				expire := uint64(time.Now().Add(time.Hour).UnixNano())
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:   pbv2.HopMessage_STATUS.Enum(),
					Status: &status,
					Reservation: &pbv2.Reservation{
						Expire:  &expire,
						Voucher: []byte("foobar"),
					},
				})
			},
			err: "error consuming voucher envelope: failed when unmarshalling the envelope",
		},
	}

	for _, tc := range testcases {
		t.Run(tc.name, func(t *testing.T) {
			host, err := libp2p.New()
			require.NoError(t, err)
			defer host.Close()
			if tc.streamHandler != nil {
				host.SetStreamHandler(proto.ProtoIDv2Hop, tc.streamHandler)
			}

			cl, err := libp2p.New()
			require.NoError(t, err)
			defer cl.Close()
			_, err = client.Reserve(context.Background(), cl, peer.AddrInfo{ID: host.ID(), Addrs: host.Addrs()})
			if tc.err == "" {
				require.NoError(t, err)
			} else {
				require.Error(t, err)
				require.Contains(t, err.Error(), tc.err)
			}
		})
	}
}
<commit_msg>Don't use rcmgr in this test (#1799)<commit_after>package client_test

import (
	"context"
	"math"
	"testing"
	"time"

	"github.com/libp2p/go-libp2p"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/peer"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
	pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util"

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

func TestReservationFailures(t *testing.T) {
	type testcase struct {
		name          string
		streamHandler network.StreamHandler
		err           string
	}
	testcases := []testcase{
		{
			name:          "unsupported protocol",
			streamHandler: nil,
			err:           "protocol not supported",
		},
		{
			name: "wrong message type",
			streamHandler: func(s network.Stream) {
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type: pbv2.HopMessage_RESERVE.Enum(),
				})
			},
			err: "unexpected relay response: not a status message",
		},
		{
			name: "unknown status",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status(1337)
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:   pbv2.HopMessage_STATUS.Enum(),
					Status: &status,
				})
			},
			err: "reservation failed",
		},
		{
			name: "invalid time",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status_OK
				expire := uint64(math.MaxUint64)
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:        pbv2.HopMessage_STATUS.Enum(),
					Status:      &status,
					Reservation: &pbv2.Reservation{Expire: &expire},
				})
			},
			err: "received reservation with expiration date in the past",
		},
		{
			name: "invalid voucher",
			streamHandler: func(s network.Stream) {
				status := pbv2.Status_OK
				expire := uint64(time.Now().Add(time.Hour).UnixNano())
				util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
					Type:   pbv2.HopMessage_STATUS.Enum(),
					Status: &status,
					Reservation: &pbv2.Reservation{
						Expire:  &expire,
						Voucher: []byte("foobar"),
					},
				})
			},
			err: "error consuming voucher envelope: failed when unmarshalling the envelope",
		},
	}

	for _, tc := range testcases {
		t.Run(tc.name, func(t *testing.T) {
			host, err := libp2p.New()
			require.NoError(t, err)
			defer host.Close()
			if tc.streamHandler != nil {
				host.SetStreamHandler(proto.ProtoIDv2Hop, tc.streamHandler)
			}

			cl, err := libp2p.New(libp2p.ResourceManager(network.NullResourceManager))
			require.NoError(t, err)
			defer cl.Close()
			_, err = client.Reserve(context.Background(), cl, peer.AddrInfo{ID: host.ID(), Addrs: host.Addrs()})
			if tc.err == "" {
				require.NoError(t, err)
			} else {
				require.Error(t, err)
				require.Contains(t, err.Error(), tc.err)
			}
		})
	}
}
<|endoftext|>


<commit_before>// +build windows

/*
Copyright 2014 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 app does all of the work necessary to configure and run a
// Kubernetes app process.
package app

import (
	"errors"
	"fmt"
	"net"

	// Enable pprof HTTP handlers.
	_ "net/http/pprof"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/types"
	utilnet "k8s.io/apimachinery/pkg/util/net"
	utilfeature "k8s.io/apiserver/pkg/util/feature"
	"k8s.io/client-go/tools/record"
	"k8s.io/component-base/configz"
	"k8s.io/component-base/metrics"
	"k8s.io/klog/v2"
	"k8s.io/kubernetes/pkg/features"
	"k8s.io/kubernetes/pkg/proxy"
	proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
	proxyconfigscheme "k8s.io/kubernetes/pkg/proxy/apis/config/scheme"
	"k8s.io/kubernetes/pkg/proxy/healthcheck"
	"k8s.io/kubernetes/pkg/proxy/winkernel"
	"k8s.io/kubernetes/pkg/proxy/winuserspace"
	utilnetsh "k8s.io/kubernetes/pkg/util/netsh"
	utilnode "k8s.io/kubernetes/pkg/util/node"
	"k8s.io/utils/exec"
	utilsnet "k8s.io/utils/net"
)

// NewProxyServer returns a new ProxyServer.
func NewProxyServer(o *Options) (*ProxyServer, error) {
	return newProxyServer(o.config, o.CleanupAndExit, o.master)
}

func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, master string) (*ProxyServer, error) {
	if config == nil {
		return nil, errors.New("config is required")
	}

	if c, err := configz.New(proxyconfigapi.GroupName); err == nil {
		c.Set(config)
	} else {
		return nil, fmt.Errorf("unable to register configz: %s", err)
	}

	// We omit creation of pretty much everything if we run in cleanup mode
	if cleanupAndExit {
		return &ProxyServer{}, nil
	}

	if len(config.ShowHiddenMetricsForVersion) > 0 {
		metrics.SetShowHidden()
	}

	client, eventClient, err := createClients(config.ClientConnection, master)
	if err != nil {
		return nil, err
	}

	// Create event recorder
	hostname, err := utilnode.GetHostname(config.HostnameOverride)
	if err != nil {
		return nil, err
	}
	eventBroadcaster := record.NewBroadcaster()
	recorder := eventBroadcaster.NewRecorder(proxyconfigscheme.Scheme, v1.EventSource{Component: "kube-proxy", Host: hostname})

	nodeRef := &v1.ObjectReference{
		Kind:      "Node",
		Name:      hostname,
		UID:       types.UID(hostname),
		Namespace: "",
	}

	var healthzServer healthcheck.ProxierHealthUpdater
	if len(config.HealthzBindAddress) > 0 {
		healthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration, recorder, nodeRef)
	}

	var proxier proxy.Provider

	proxyMode := getProxyMode(string(config.Mode), winkernel.WindowsKernelCompatTester{})
	if proxyMode == proxyModeKernelspace {
		klog.V(0).Info("Using Kernelspace Proxier.")
		isIPv6DualStackEnabled := utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack)
		if isIPv6DualStackEnabled {
			klog.V(0).Info("creating dualStackProxier for Windows kernel.")

			proxier, err = winkernel.NewDualStackProxier(
				config.IPTables.SyncPeriod.Duration,
				config.IPTables.MinSyncPeriod.Duration,
				config.IPTables.MasqueradeAll,
				int(*config.IPTables.MasqueradeBit),
				config.ClusterCIDR,
				hostname,
				nodeIPTuple(config.BindAddress),
				recorder,
				healthzServer,
				config.Winkernel,
			)
		} else {

			proxier, err = winkernel.NewProxier(
				config.IPTables.SyncPeriod.Duration,
				config.IPTables.MinSyncPeriod.Duration,
				config.IPTables.MasqueradeAll,
				int(*config.IPTables.MasqueradeBit),
				config.ClusterCIDR,
				hostname,
				utilnode.GetNodeIP(client, hostname),
				recorder,
				healthzServer,
				config.Winkernel,
			)

		}

		if err != nil {
			return nil, fmt.Errorf("unable to create proxier: %v", err)
		}
	} else {
		klog.V(0).Info("Using userspace Proxier.")
		execer := exec.New()
		var netshInterface utilnetsh.Interface
		netshInterface = utilnetsh.New(execer)

		proxier, err = winuserspace.NewProxier(
			winuserspace.NewLoadBalancerRR(),
			net.ParseIP(config.BindAddress),
			netshInterface,
			*utilnet.ParsePortRangeOrDie(config.PortRange),
			// TODO @pires replace below with default values, if applicable
			config.IPTables.SyncPeriod.Duration,
			config.UDPIdleTimeout.Duration,
		)
		if err != nil {
			return nil, fmt.Errorf("unable to create proxier: %v", err)
		}
	}

	return &ProxyServer{
		Client:              client,
		EventClient:         eventClient,
		Proxier:             proxier,
		Broadcaster:         eventBroadcaster,
		Recorder:            recorder,
		ProxyMode:           proxyMode,
		NodeRef:             nodeRef,
		MetricsBindAddress:  config.MetricsBindAddress,
		BindAddressHardFail: config.BindAddressHardFail,
		EnableProfiling:     config.EnableProfiling,
		OOMScoreAdj:         config.OOMScoreAdj,
		ConfigSyncPeriod:    config.ConfigSyncPeriod.Duration,
		HealthzServer:       healthzServer,
		UseEndpointSlices:   utilfeature.DefaultFeatureGate.Enabled(features.WindowsEndpointSliceProxying),
	}, nil
}

func getProxyMode(proxyMode string, kcompat winkernel.KernelCompatTester) string {
	if proxyMode == proxyModeUserspace {
		return proxyModeUserspace
	} else if proxyMode == proxyModeKernelspace {
		return tryWinKernelSpaceProxy(kcompat)
	}
	return proxyModeUserspace
}

func tryWinKernelSpaceProxy(kcompat winkernel.KernelCompatTester) string {
	// Check for Windows Kernel Version if we can support Kernel Space proxy
	// Check for Windows Version

	// guaranteed false on error, error only necessary for debugging
	useWinKernelProxy, err := winkernel.CanUseWinKernelProxier(kcompat)
	if err != nil {
		klog.Errorf("Can't determine whether to use windows kernel proxy, using userspace proxier: %v", err)
		return proxyModeUserspace
	}
	if useWinKernelProxy {
		return proxyModeKernelspace
	}
	// Fallback.
	klog.V(1).Infof("Can't use winkernel proxy, using userspace proxier")
	return proxyModeUserspace
}

// nodeIPTuple takes an addresses and return a tuple (ipv4,ipv6)
// The returned tuple is guaranteed to have the order (ipv4,ipv6). The address NOT of the passed address
// will have "any" address (0.0.0.0 or ::) inserted.
func nodeIPTuple(bindAddress string) [2]net.IP {
	nodes := [2]net.IP{net.IPv4zero, net.IPv6zero}

	adr := net.ParseIP(bindAddress)
	if utilsnet.IsIPv6(adr) {
		nodes[1] = adr
	} else {
		nodes[0] = adr
	}

	return nodes
}
<commit_msg>Optimized function getProxyMode<commit_after>// +build windows

/*
Copyright 2014 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 app does all of the work necessary to configure and run a
// Kubernetes app process.
package app

import (
	"errors"
	"fmt"
	"net"

	// Enable pprof HTTP handlers.
	_ "net/http/pprof"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/types"
	utilnet "k8s.io/apimachinery/pkg/util/net"
	utilfeature "k8s.io/apiserver/pkg/util/feature"
	"k8s.io/client-go/tools/record"
	"k8s.io/component-base/configz"
	"k8s.io/component-base/metrics"
	"k8s.io/klog/v2"
	"k8s.io/kubernetes/pkg/features"
	"k8s.io/kubernetes/pkg/proxy"
	proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
	proxyconfigscheme "k8s.io/kubernetes/pkg/proxy/apis/config/scheme"
	"k8s.io/kubernetes/pkg/proxy/healthcheck"
	"k8s.io/kubernetes/pkg/proxy/winkernel"
	"k8s.io/kubernetes/pkg/proxy/winuserspace"
	utilnetsh "k8s.io/kubernetes/pkg/util/netsh"
	utilnode "k8s.io/kubernetes/pkg/util/node"
	"k8s.io/utils/exec"
	utilsnet "k8s.io/utils/net"
)

// NewProxyServer returns a new ProxyServer.
func NewProxyServer(o *Options) (*ProxyServer, error) {
	return newProxyServer(o.config, o.CleanupAndExit, o.master)
}

func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, master string) (*ProxyServer, error) {
	if config == nil {
		return nil, errors.New("config is required")
	}

	if c, err := configz.New(proxyconfigapi.GroupName); err == nil {
		c.Set(config)
	} else {
		return nil, fmt.Errorf("unable to register configz: %s", err)
	}

	// We omit creation of pretty much everything if we run in cleanup mode
	if cleanupAndExit {
		return &ProxyServer{}, nil
	}

	if len(config.ShowHiddenMetricsForVersion) > 0 {
		metrics.SetShowHidden()
	}

	client, eventClient, err := createClients(config.ClientConnection, master)
	if err != nil {
		return nil, err
	}

	// Create event recorder
	hostname, err := utilnode.GetHostname(config.HostnameOverride)
	if err != nil {
		return nil, err
	}
	eventBroadcaster := record.NewBroadcaster()
	recorder := eventBroadcaster.NewRecorder(proxyconfigscheme.Scheme, v1.EventSource{Component: "kube-proxy", Host: hostname})

	nodeRef := &v1.ObjectReference{
		Kind:      "Node",
		Name:      hostname,
		UID:       types.UID(hostname),
		Namespace: "",
	}

	var healthzServer healthcheck.ProxierHealthUpdater
	if len(config.HealthzBindAddress) > 0 {
		healthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration, recorder, nodeRef)
	}

	var proxier proxy.Provider

	proxyMode := getProxyMode(string(config.Mode), winkernel.WindowsKernelCompatTester{})
	if proxyMode == proxyModeKernelspace {
		klog.V(0).Info("Using Kernelspace Proxier.")
		isIPv6DualStackEnabled := utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack)
		if isIPv6DualStackEnabled {
			klog.V(0).Info("creating dualStackProxier for Windows kernel.")

			proxier, err = winkernel.NewDualStackProxier(
				config.IPTables.SyncPeriod.Duration,
				config.IPTables.MinSyncPeriod.Duration,
				config.IPTables.MasqueradeAll,
				int(*config.IPTables.MasqueradeBit),
				config.ClusterCIDR,
				hostname,
				nodeIPTuple(config.BindAddress),
				recorder,
				healthzServer,
				config.Winkernel,
			)
		} else {

			proxier, err = winkernel.NewProxier(
				config.IPTables.SyncPeriod.Duration,
				config.IPTables.MinSyncPeriod.Duration,
				config.IPTables.MasqueradeAll,
				int(*config.IPTables.MasqueradeBit),
				config.ClusterCIDR,
				hostname,
				utilnode.GetNodeIP(client, hostname),
				recorder,
				healthzServer,
				config.Winkernel,
			)

		}

		if err != nil {
			return nil, fmt.Errorf("unable to create proxier: %v", err)
		}
	} else {
		klog.V(0).Info("Using userspace Proxier.")
		execer := exec.New()
		var netshInterface utilnetsh.Interface
		netshInterface = utilnetsh.New(execer)

		proxier, err = winuserspace.NewProxier(
			winuserspace.NewLoadBalancerRR(),
			net.ParseIP(config.BindAddress),
			netshInterface,
			*utilnet.ParsePortRangeOrDie(config.PortRange),
			// TODO @pires replace below with default values, if applicable
			config.IPTables.SyncPeriod.Duration,
			config.UDPIdleTimeout.Duration,
		)
		if err != nil {
			return nil, fmt.Errorf("unable to create proxier: %v", err)
		}
	}

	return &ProxyServer{
		Client:              client,
		EventClient:         eventClient,
		Proxier:             proxier,
		Broadcaster:         eventBroadcaster,
		Recorder:            recorder,
		ProxyMode:           proxyMode,
		NodeRef:             nodeRef,
		MetricsBindAddress:  config.MetricsBindAddress,
		BindAddressHardFail: config.BindAddressHardFail,
		EnableProfiling:     config.EnableProfiling,
		OOMScoreAdj:         config.OOMScoreAdj,
		ConfigSyncPeriod:    config.ConfigSyncPeriod.Duration,
		HealthzServer:       healthzServer,
		UseEndpointSlices:   utilfeature.DefaultFeatureGate.Enabled(features.WindowsEndpointSliceProxying),
	}, nil
}

func getProxyMode(proxyMode string, kcompat winkernel.KernelCompatTester) string {
	if proxyMode == proxyModeKernelspace {
		return tryWinKernelSpaceProxy(kcompat)
	}
	return proxyModeUserspace
}

func tryWinKernelSpaceProxy(kcompat winkernel.KernelCompatTester) string {
	// Check for Windows Kernel Version if we can support Kernel Space proxy
	// Check for Windows Version

	// guaranteed false on error, error only necessary for debugging
	useWinKernelProxy, err := winkernel.CanUseWinKernelProxier(kcompat)
	if err != nil {
		klog.Errorf("Can't determine whether to use windows kernel proxy, using userspace proxier: %v", err)
		return proxyModeUserspace
	}
	if useWinKernelProxy {
		return proxyModeKernelspace
	}
	// Fallback.
	klog.V(1).Infof("Can't use winkernel proxy, using userspace proxier")
	return proxyModeUserspace
}

// nodeIPTuple takes an addresses and return a tuple (ipv4,ipv6)
// The returned tuple is guaranteed to have the order (ipv4,ipv6). The address NOT of the passed address
// will have "any" address (0.0.0.0 or ::) inserted.
func nodeIPTuple(bindAddress string) [2]net.IP {
	nodes := [2]net.IP{net.IPv4zero, net.IPv6zero}

	adr := net.ParseIP(bindAddress)
	if utilsnet.IsIPv6(adr) {
		nodes[1] = adr
	} else {
		nodes[0] = adr
	}

	return nodes
}
<|endoftext|>


<commit_before>package tokens

import (
	"os"

	"github.com/starkandwayne/goutils/ansi"
	"github.com/starkandwayne/shield/api"
	"github.com/starkandwayne/shield/cmd/shield/commands"
	"github.com/starkandwayne/shield/cmd/shield/commands/internal"
	"github.com/starkandwayne/shield/cmd/shield/log"
	"github.com/starkandwayne/shield/tui"
)

//Create - Create token for the currently authenticated user
var Create = &commands.Command{
	Summary: "Create token for the currently authenticated user",
	Help: &commands.HelpInfo{
		Flags: []commands.FlagInfo{
			commands.FlagInfo{
				Name: "tokenname", Desc: "The name of the token to create",
				Positional: true, Mandatory: true,
			},
		},
		//TODO: Update this
		JSONOutput: `[{
			"uuid":"6e83bfb7-7ae1-4f0f-88a8-84f0fe4bae20",
			"name":"test store",
			"summary":"a test store named \"test store\"",
			"plugin":"s3",
			"endpoint":"{ \"endpoint\": \"doesntmatter\" }"
		}]`,
	},
	RunFn: cliCreateToken,
	Group: commands.TokensGroup,
}

func cliCreateToken(opts *commands.Options, args ...string) error {
	log.DEBUG("running `create-auth-token' command")

	internal.Require(len(args) == 1, "shield create-auth-token NAME")
	token, err := api.CreateToken(args[0])
	if err != nil {
		return err
	}

	if *opts.Raw {
		internal.RawJSON(token)
		return nil
	}

	ansi.Fprintf(os.Stderr, "@Y{This is the only time you can see the value of this token, so store it somewhere safe}\n")

	Show(token)

	return nil
}

func Show(token *api.Token) {
	t := tui.NewReport()
	if token.Session != "" {
		t.Add("Token", token.Session)
	}
	t.Add("Name", token.Name)
	t.Add("Created At", token.CreatedAt)
	if token.Session == "" {
		if token.LastSeen == "" {
			token.LastSeen = "never"
		}
		t.Add("Last Seen", token.LastSeen)
	}
	t.Output(os.Stdout)
}
<commit_msg>Show displays a token<commit_after>package tokens

import (
	"os"

	"github.com/starkandwayne/goutils/ansi"
	"github.com/starkandwayne/shield/api"
	"github.com/starkandwayne/shield/cmd/shield/commands"
	"github.com/starkandwayne/shield/cmd/shield/commands/internal"
	"github.com/starkandwayne/shield/cmd/shield/log"
	"github.com/starkandwayne/shield/tui"
)

//Create - Create token for the currently authenticated user
var Create = &commands.Command{
	Summary: "Create token for the currently authenticated user",
	Help: &commands.HelpInfo{
		Flags: []commands.FlagInfo{
			commands.FlagInfo{
				Name: "tokenname", Desc: "The name of the token to create",
				Positional: true, Mandatory: true,
			},
		},
		//TODO: Update this
		JSONOutput: `[{
			"uuid":"6e83bfb7-7ae1-4f0f-88a8-84f0fe4bae20",
			"name":"test store",
			"summary":"a test store named \"test store\"",
			"plugin":"s3",
			"endpoint":"{ \"endpoint\": \"doesntmatter\" }"
		}]`,
	},
	RunFn: cliCreateToken,
	Group: commands.TokensGroup,
}

func cliCreateToken(opts *commands.Options, args ...string) error {
	log.DEBUG("running `create-auth-token' command")

	internal.Require(len(args) == 1, "shield create-auth-token NAME")
	token, err := api.CreateToken(args[0])
	if err != nil {
		return err
	}

	if *opts.Raw {
		internal.RawJSON(token)
		return nil
	}

	ansi.Fprintf(os.Stderr, "@Y{This is the only time you can see the value of this token, so store it somewhere safe}\n")

	Show(token)

	return nil
}

//Show displays a token
func Show(token *api.Token) {
	t := tui.NewReport()
	if token.Session != "" {
		t.Add("Token", token.Session)
	}
	t.Add("Name", token.Name)
	t.Add("Created At", token.CreatedAt)
	if token.Session == "" {
		if token.LastSeen == "" {
			token.LastSeen = "never"
		}
		t.Add("Last Seen", token.LastSeen)
	}
	t.Output(os.Stdout)
}
<|endoftext|>


<commit_before>package integration

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"testing"

	"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
	"github.com/moby/buildkit/util/contentutil"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

type Sandbox interface {
	Address() string
	PrintLogs(*testing.T)
	Cmd(...string) *exec.Cmd
	NewRegistry() (string, error)
	Rootless() bool
}

type Worker interface {
	New(...SandboxOpt) (Sandbox, func() error, error)
	Name() string
}

type SandboxConf struct {
	mirror string
}

type SandboxOpt func(*SandboxConf)

func WithMirror(h string) SandboxOpt {
	return func(c *SandboxConf) {
		c.mirror = h
	}
}

type Test func(*testing.T, Sandbox)

var defaultWorkers []Worker

func register(w Worker) {
	defaultWorkers = append(defaultWorkers, w)
}

func List() []Worker {
	return defaultWorkers
}

func Run(t *testing.T, testCases []Test) {
	if testing.Short() {
		t.Skip("skipping in short mode")
	}

	mirror, cleanup, err := runMirror(t)
	require.NoError(t, err)

	var mu sync.Mutex
	var count int
	cleanOnComplete := func() func() {
		count++
		return func() {
			mu.Lock()
			count--
			if count == 0 {
				cleanup()
			}
			mu.Unlock()
		}
	}
	defer cleanOnComplete()()

	for _, br := range List() {
		for _, tc := range testCases {
			ok := t.Run(getFunctionName(tc)+"/worker="+br.Name(), func(t *testing.T) {
				defer cleanOnComplete()()
				sb, close, err := br.New(WithMirror(mirror))
				if err != nil {
					if errors.Cause(err) == ErrorRequirements {
						t.Skip(err.Error())
					}
					require.NoError(t, err)
				}
				defer func() {
					assert.NoError(t, close())
					if t.Failed() {
						sb.PrintLogs(t)
					}
				}()
				tc(t, sb)
			})
			require.True(t, ok)
		}
	}
}

func getFunctionName(i interface{}) string {
	fullname := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
	dot := strings.LastIndex(fullname, ".") + 1
	return strings.Title(fullname[dot:])
}

func copyImagesLocal(t *testing.T, host string) error {
	for to, from := range offlineImages() {
		desc, provider, err := contentutil.ProviderFromRef(from)
		if err != nil {
			return err
		}
		ingester, err := contentutil.IngesterFromRef(host + "/" + to)
		if err != nil {
			return err
		}
		if err := contentutil.CopyChain(context.TODO(), ingester, provider, desc); err != nil {
			return err
		}
		t.Logf("copied %s to local mirror %s", from, host+"/"+to)
	}
	return nil
}

func offlineImages() map[string]string {
	arch := runtime.GOARCH
	if arch == "arm64" {
		arch = "arm64v8"
	}
	return map[string]string{
		"library/busybox:latest": "docker.io/" + arch + "/busybox:latest",
		"library/alpine:latest":  "docker.io/" + arch + "/alpine:latest",
		"tonistiigi/copy:v0.1.4": "docker.io/" + dockerfile2llb.DefaultCopyImage,
	}
}

func configWithMirror(mirror string) (string, error) {
	tmpdir, err := ioutil.TempDir("", "bktest_config")
	if err != nil {
		return "", err
	}
	if err := ioutil.WriteFile(filepath.Join(tmpdir, "buildkitd.toml"), []byte(fmt.Sprintf(`
[registry."docker.io"]
mirrors=["%s"]
`, mirror)), 0600); err != nil {
		return "", err
	}
	return tmpdir, nil
}

func runMirror(t *testing.T) (host string, cleanup func() error, err error) {
	mirrorDir := os.Getenv("BUILDKIT_REGISTRY_MIRROR_DIR")

	var f *os.File
	if mirrorDir != "" {
		f, err = os.Create(filepath.Join(mirrorDir, "lock"))
		if err != nil {
			return "", nil, err
		}
		defer func() {
			if err != nil {
				f.Close()
			}
		}()
		if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
			return "", nil, err
		}
	}

	mirror, cleanup, err := newRegistry(mirrorDir)
	if err != nil {
		return "", nil, err
	}
	defer func() {
		if err != nil {
			cleanup()
		}
	}()

	if err := copyImagesLocal(t, mirror); err != nil {
		return "", nil, err
	}

	if mirrorDir != "" {
		if err := syscall.Flock(int(f.Fd()), syscall.LOCK_UN); err != nil {
			return "", nil, err
		}
	}

	return mirror, cleanup, err
}
<commit_msg>integration: fix config permissions for rootless<commit_after>package integration

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"testing"

	"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
	"github.com/moby/buildkit/util/contentutil"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

type Sandbox interface {
	Address() string
	PrintLogs(*testing.T)
	Cmd(...string) *exec.Cmd
	NewRegistry() (string, error)
	Rootless() bool
}

type Worker interface {
	New(...SandboxOpt) (Sandbox, func() error, error)
	Name() string
}

type SandboxConf struct {
	mirror string
}

type SandboxOpt func(*SandboxConf)

func WithMirror(h string) SandboxOpt {
	return func(c *SandboxConf) {
		c.mirror = h
	}
}

type Test func(*testing.T, Sandbox)

var defaultWorkers []Worker

func register(w Worker) {
	defaultWorkers = append(defaultWorkers, w)
}

func List() []Worker {
	return defaultWorkers
}

func Run(t *testing.T, testCases []Test) {
	if testing.Short() {
		t.Skip("skipping in short mode")
	}

	mirror, cleanup, err := runMirror(t)
	require.NoError(t, err)

	var mu sync.Mutex
	var count int
	cleanOnComplete := func() func() {
		count++
		return func() {
			mu.Lock()
			count--
			if count == 0 {
				cleanup()
			}
			mu.Unlock()
		}
	}
	defer cleanOnComplete()()

	for _, br := range List() {
		for _, tc := range testCases {
			ok := t.Run(getFunctionName(tc)+"/worker="+br.Name(), func(t *testing.T) {
				defer cleanOnComplete()()
				sb, close, err := br.New(WithMirror(mirror))
				if err != nil {
					if errors.Cause(err) == ErrorRequirements {
						t.Skip(err.Error())
					}
					require.NoError(t, err)
				}
				defer func() {
					assert.NoError(t, close())
					if t.Failed() {
						sb.PrintLogs(t)
					}
				}()
				tc(t, sb)
			})
			require.True(t, ok)
		}
	}
}

func getFunctionName(i interface{}) string {
	fullname := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
	dot := strings.LastIndex(fullname, ".") + 1
	return strings.Title(fullname[dot:])
}

func copyImagesLocal(t *testing.T, host string) error {
	for to, from := range offlineImages() {
		desc, provider, err := contentutil.ProviderFromRef(from)
		if err != nil {
			return err
		}
		ingester, err := contentutil.IngesterFromRef(host + "/" + to)
		if err != nil {
			return err
		}
		if err := contentutil.CopyChain(context.TODO(), ingester, provider, desc); err != nil {
			return err
		}
		t.Logf("copied %s to local mirror %s", from, host+"/"+to)
	}
	return nil
}

func offlineImages() map[string]string {
	arch := runtime.GOARCH
	if arch == "arm64" {
		arch = "arm64v8"
	}
	return map[string]string{
		"library/busybox:latest": "docker.io/" + arch + "/busybox:latest",
		"library/alpine:latest":  "docker.io/" + arch + "/alpine:latest",
		"tonistiigi/copy:v0.1.4": "docker.io/" + dockerfile2llb.DefaultCopyImage,
	}
}

func configWithMirror(mirror string) (string, error) {
	tmpdir, err := ioutil.TempDir("", "bktest_config")
	if err != nil {
		return "", err
	}
	if err := os.Chmod(tmpdir, 0711); err != nil {
		return "", err
	}
	if err := ioutil.WriteFile(filepath.Join(tmpdir, "buildkitd.toml"), []byte(fmt.Sprintf(`
[registry."docker.io"]
mirrors=["%s"]
`, mirror)), 0644); err != nil {
		return "", err
	}
	return tmpdir, nil
}

func runMirror(t *testing.T) (host string, cleanup func() error, err error) {
	mirrorDir := os.Getenv("BUILDKIT_REGISTRY_MIRROR_DIR")

	var f *os.File
	if mirrorDir != "" {
		f, err = os.Create(filepath.Join(mirrorDir, "lock"))
		if err != nil {
			return "", nil, err
		}
		defer func() {
			if err != nil {
				f.Close()
			}
		}()
		if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
			return "", nil, err
		}
	}

	mirror, cleanup, err := newRegistry(mirrorDir)
	if err != nil {
		return "", nil, err
	}
	defer func() {
		if err != nil {
			cleanup()
		}
	}()

	if err := copyImagesLocal(t, mirror); err != nil {
		return "", nil, err
	}

	if mirrorDir != "" {
		if err := syscall.Flock(int(f.Fd()), syscall.LOCK_UN); err != nil {
			return "", nil, err
		}
	}

	return mirror, cleanup, err
}
<|endoftext|>


<commit_before>package kana

import (
	"strings"
	"unicode"
	"unicode/utf8"
)

var consonants []string = []string{"b", "d", "f", "g", "h", "j", "k", "l", "m", "p", "r", "s", "t", "w", "z"}

var kanaToRomajiTrie *Trie
var romajiToHiraganaTrie *Trie
var romajiToKatakanaTrie *Trie

func Initialize() {
	/*
		Build the Hiragana + Katakana trie.

		Because there is no overlap between the hiragana and katakana sets,
		they both use the same trie without conflict. Nice bonus!
	*/
	kanaToRomajiTrie = newTrie()
	romajiToHiraganaTrie = newTrie()
	romajiToKatakanaTrie = newTrie()

	tables := []string{HiraganaTable, KatakanaTable}
	for t, table := range tables {
		rows := strings.Split(table, "\n")
		colNames := strings.Split(string(rows[0]), "\t")[1:]
		for _, row := range rows[1:] {
			cols := strings.Split(string(row), "\t")
			rowName := cols[0]
			for i, kana := range cols[1:] {
				value := rowName + colNames[i]
				kanas := strings.Split(kana, "/")
				for _, singleKana := range kanas {
					if singleKana != "" {
						// add to tries
						kanaToRomajiTrie.insert(singleKana, value)
						if t == 0 {
							romajiToHiraganaTrie.insert(value, singleKana)
						} else if t == 1 {
							romajiToKatakanaTrie.insert(value, singleKana)
						}
					}
				}
			}
		}
	}
}

func KanaToRomaji(kana string) (romaji string) {
	romaji = kanaToRomajiTrie.convert(kana)

	// do some post-processing for the tsu and stripe characters
	// maybe a bit of a hacky solution - how can we improve?
	// (they act more like punctuation)
	tsus := []string{"っ", "ッ"}
	for _, tsu := range tsus {
		if strings.Index(romaji, tsu) > -1 {
			for _, c := range romaji {
				ch := string(c)
				if ch == tsu {
					i := strings.Index(romaji, ch)
					runeSize := len(ch)
					followingLetter, _ := utf8.DecodeRuneInString(romaji[i+runeSize:])
					followingLetterStr := string(followingLetter)
					if followingLetterStr != tsu {
						romaji = strings.Replace(romaji, tsu, followingLetterStr, 1)
					} else {
						romaji = strings.Replace(romaji, tsu, "", 1)
					}
				}
			}
		}
	}

	line := "ー"
	for i := strings.Index(romaji, line); i > -1; i = strings.Index(romaji, line) {
		if i > 0 {
			romaji = strings.Replace(romaji, line, "-", 1)
		} else {
			romaji = strings.Replace(romaji, line, "", 1)
		}
	}
	return romaji
}

func replace_tsus(romaji string, tsu string) (result string) {
	result = romaji
	for _, consonant := range consonants {
		result = strings.Replace(result, consonant+consonant, tsu+consonant, -1)
	}
	return result
}

func RomajiToHiragana(romaji string) (hiragana string) {
	romaji = strings.Replace(romaji, "-", "ー", -1)
	romaji = replace_tsus(romaji, "っ")
	hiragana = romajiToHiraganaTrie.convert(romaji)
	return hiragana
}

func RomajiToKatakana(romaji string) (katakana string) {
	romaji = strings.Replace(romaji, "-", "ー", -1)
	// convert double consonants to little tsus first
	romaji = replace_tsus(romaji, "ッ")
	katakana = romajiToKatakanaTrie.convert(romaji)
	return katakana
}

func IsLatin(s string) bool {
	isLatin := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isLatin = isLatin && unicode.IsOneOf([]*unicode.RangeTable{unicode.Latin, unicode.ASCII_Hex_Digit, unicode.White_Space, unicode.Hyphen}, r)
		if !isLatin {
			return isLatin
		}
	}
	return isLatin
}

func IsKana(s string) bool {
	isKana := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isKana = isKana && unicode.IsOneOf([]*unicode.RangeTable{unicode.Hiragana, unicode.Katakana, unicode.Hyphen, unicode.Diacritic}, r)
		if !isKana {
			return isKana
		}
	}
	return isKana
}

func IsKanji(s string) bool {
	isKanji := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isKanji = isKanji && unicode.IsOneOf([]*unicode.RangeTable{unicode.Ideographic}, r)
		if !isKanji {
			return isKanji
		}
	}
	return isKanji
}

func replaceAll(haystack string, needles []string, replacements []string) (replaced string) {
	replaced = haystack
	for i := range needles {
		replaced = strings.Replace(replaced, needles[i], replacements[i], -1)
	}
	return replaced
}

func NormalizeRomaji(s string) (romaji string) {
	// transform romaji input to one specific standard form,
	// which should be as close as possible to hiragana so that
	// this library gives correct output when transforming to
	// hiragana / katakana

	romaji = s
	romaji = strings.ToLower(romaji)
	romaji = replaceAll(
		romaji,
		[]string{"ā", "ē", "ī", "ō", "ū", "ee", "uu"},
		[]string{"a-", "ei", "ii", "oo", "u-", "ei", "u-"},
	)

	return romaji
}
<commit_msg>Fix double and triple n case<commit_after>package kana

import (
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"
)

var consonants []string = []string{"b", "d", "f", "g", "h", "j", "k", "l", "m", "p", "r", "s", "t", "w", "z"}

var hiragana_re = regexp.MustCompile(`ん([あいうえおなにぬねの])`)
var katakana_re = regexp.MustCompile(`ン([アイウエオナニヌネノ])`)

var kanaToRomajiTrie *Trie
var romajiToHiraganaTrie *Trie
var romajiToKatakanaTrie *Trie

func Initialize() {
	/*
		Build the Hiragana + Katakana trie.

		Because there is no overlap between the hiragana and katakana sets,
		they both use the same trie without conflict. Nice bonus!
	*/
	kanaToRomajiTrie = newTrie()
	romajiToHiraganaTrie = newTrie()
	romajiToKatakanaTrie = newTrie()

	tables := []string{HiraganaTable, KatakanaTable}
	for t, table := range tables {
		rows := strings.Split(table, "\n")
		colNames := strings.Split(string(rows[0]), "\t")[1:]
		for _, row := range rows[1:] {
			cols := strings.Split(string(row), "\t")
			rowName := cols[0]
			for i, kana := range cols[1:] {
				value := rowName + colNames[i]
				kanas := strings.Split(kana, "/")
				for _, singleKana := range kanas {
					if singleKana != "" {
						// add to tries
						kanaToRomajiTrie.insert(singleKana, value)
						if t == 0 {
							romajiToHiraganaTrie.insert(value, singleKana)
						} else if t == 1 {
							romajiToKatakanaTrie.insert(value, singleKana)
						}
					}
				}
			}
		}
	}
}

func KanaToRomaji(kana string) (romaji string) {

	// unfortunate hack to deal with double n's
	romaji = hiragana_re.ReplaceAllString(kana, "nn$1")
	romaji = katakana_re.ReplaceAllString(romaji, "nn$1")

	romaji = kanaToRomajiTrie.convert(romaji)

	// do some post-processing for the tsu and stripe characters
	// maybe a bit of a hacky solution - how can we improve?
	// (they act more like punctuation)
	tsus := []string{"っ", "ッ"}
	for _, tsu := range tsus {
		if strings.Index(romaji, tsu) > -1 {
			for _, c := range romaji {
				ch := string(c)
				if ch == tsu {
					i := strings.Index(romaji, ch)
					runeSize := len(ch)
					followingLetter, _ := utf8.DecodeRuneInString(romaji[i+runeSize:])
					followingLetterStr := string(followingLetter)
					if followingLetterStr != tsu {
						romaji = strings.Replace(romaji, tsu, followingLetterStr, 1)
					} else {
						romaji = strings.Replace(romaji, tsu, "", 1)
					}
				}
			}
		}
	}

	line := "ー"
	for i := strings.Index(romaji, line); i > -1; i = strings.Index(romaji, line) {
		if i > 0 {
			romaji = strings.Replace(romaji, line, "-", 1)
		} else {
			romaji = strings.Replace(romaji, line, "", 1)
		}
	}
	return romaji
}

func replace_tsus(romaji string, tsu string) (result string) {
	result = romaji
	for _, consonant := range consonants {
		result = strings.Replace(result, consonant+consonant, tsu+consonant, -1)
	}
	return result
}

func replace_ns(romaji string, n string) (result string) {
	result = romaji
	result = strings.Replace(result, "nn", n, -1)
	return result
}

func RomajiToHiragana(romaji string) (hiragana string) {
	romaji = strings.Replace(romaji, "-", "ー", -1)
	romaji = replace_tsus(romaji, "っ")
	romaji = replace_ns(romaji, "ん")
	hiragana = romajiToHiraganaTrie.convert(romaji)
	return hiragana
}

func RomajiToKatakana(romaji string) (katakana string) {
	romaji = strings.Replace(romaji, "-", "ー", -1)
	// convert double consonants to little tsus first
	romaji = replace_tsus(romaji, "ッ")
	romaji = replace_ns(romaji, "ン")
	katakana = romajiToKatakanaTrie.convert(romaji)
	return katakana
}

func IsLatin(s string) bool {
	isLatin := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isLatin = isLatin && unicode.IsOneOf([]*unicode.RangeTable{unicode.Latin, unicode.ASCII_Hex_Digit, unicode.White_Space, unicode.Hyphen}, r)
		if !isLatin {
			return isLatin
		}
	}
	return isLatin
}

func IsKana(s string) bool {
	isKana := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isKana = isKana && unicode.IsOneOf([]*unicode.RangeTable{unicode.Hiragana, unicode.Katakana, unicode.Hyphen, unicode.Diacritic}, r)
		if !isKana {
			return isKana
		}
	}
	return isKana
}

func IsKanji(s string) bool {
	isKanji := true
	runeForm := []rune(s)
	for _, r := range runeForm {
		isKanji = isKanji && unicode.IsOneOf([]*unicode.RangeTable{unicode.Ideographic}, r)
		if !isKanji {
			return isKanji
		}
	}
	return isKanji
}

func replaceAll(haystack string, needles []string, replacements []string) (replaced string) {
	replaced = haystack
	for i := range needles {
		replaced = strings.Replace(replaced, needles[i], replacements[i], -1)
	}
	return replaced
}

func NormalizeRomaji(s string) (romaji string) {
	// transform romaji input to one specific standard form,
	// which should be as close as possible to hiragana so that
	// this library gives correct output when transforming to
	// hiragana / katakana

	romaji = s
	romaji = strings.ToLower(romaji)
	romaji = replaceAll(
		romaji,
		[]string{"ā", "ē", "ī", "ō", "ū", "ee", "uu"},
		[]string{"a-", "ei", "ii", "oo", "u-", "ei", "u-"},
	)

	return romaji
}
<|endoftext|>


<commit_before>// Package kite is a library for creating micro-services.  Two main types
// implemented by this package are Kite for creating a micro-service server
// called "Kite" and Client for communicating with another kites.
package kite

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"
	"github.com/koding/kite/config"
	"github.com/koding/kite/protocol"
	"github.com/nu7hatch/gouuid"
	"gopkg.in/igm/sockjs-go.v2/sockjs"
)

var hostname string

func init() {
	var err error
	hostname, err = os.Hostname()
	if err != nil {
		panic(fmt.Sprintf("kite: cannot get hostname: %s", err.Error()))
	}
}

// Kite defines a single process that enables distributed service messaging
// amongst the peers it is connected. A Kite process acts as a Client and as a
// Server. That means it can receive request, process them, but it also can
// make request to other kites.
//
// Do not use this struct directly. Use kite.New function, add your handlers
// with HandleFunc mehtod, then call Run method to start the inbuilt server (or
// pass it to any http.Handler compatible server)
type Kite struct {
	Config *config.Config

	// Log logs with the given Logger interface
	Log Logger

	// SetLogLevel changes the level of the logger. Default is INFO.
	SetLogLevel func(Level)

	// Contains different functions for authenticating user from request.
	// Keys are the authentication types (options.auth.type).
	Authenticators map[string]func(*Request) error

	// Kontrol keys to trust. Kontrol will issue access tokens for kites
	// that are signed with the private counterpart of these keys.
	// Key data must be PEM encoded.
	trustedKontrolKeys map[string]string

	// Handlers added with Kite.HandleFunc().
	handlers     map[string]*Method // method map for exported methods
	preHandlers  []Handler          // a list of handlers that are executed before any handler
	postHandlers []Handler          // a list of handlers that are executed after any handler

	// MethodHandling defines how the kite is returning the response for
	// multiple handlers
	MethodHandling MethodHandling

	// HTTP muxer
	muxer *mux.Router

	// kontrolclient is used to register to kontrol and query third party kites
	// from kontrol
	kontrol *kontrolClient

	// Handlers to call when a new connection is received.
	onConnectHandlers []func(*Client)

	// Handlers to call before the first request of connected kite.
	onFirstRequestHandlers []func(*Client)

	// Handlers to call when a client has disconnected.
	onDisconnectHandlers []func(*Client)

	// server fields, are initialized and used when
	// TODO: move them to their own struct, just like KontrolClient
	listener  net.Listener
	TLSConfig *tls.Config
	readyC    chan bool // To signal when kite is ready to accept connections
	closeC    chan bool // To signal when kite is closed with Close()

	name    string
	version string
	Id      string // Unique kite instance id
}

// New creates, initialize and then returns a new Kite instance. Version must
// be in 3-digit semantic form. Name is important that it's also used to be
// searched by others.
func New(name, version string) *Kite {
	if name == "" {
		panic("kite: name cannot be empty")
	}

	if digits := strings.Split(version, "."); len(digits) != 3 {
		panic("kite: version must be 3-digits semantic version")
	}

	kiteID, err := uuid.NewV4()
	if err != nil {
		panic(fmt.Sprintf("kite: cannot generate unique ID: %s", err.Error()))
	}

	l, setlevel := newLogger(name)

	kClient := &kontrolClient{
		readyConnected:  make(chan struct{}),
		readyRegistered: make(chan struct{}),
		registerChan:    make(chan *url.URL, 1),
	}

	k := &Kite{
		Config:             config.New(),
		Log:                l,
		SetLogLevel:        setlevel,
		Authenticators:     make(map[string]func(*Request) error),
		trustedKontrolKeys: make(map[string]string),
		handlers:           make(map[string]*Method),
		preHandlers:        make([]Handler, 0),
		postHandlers:       make([]Handler, 0),
		kontrol:            kClient,
		name:               name,
		version:            version,
		Id:                 kiteID.String(),
		readyC:             make(chan bool),
		closeC:             make(chan bool),
		muxer:              mux.NewRouter(),
	}

	// All sockjs communication is done through this endpoint..
	k.muxer.PathPrefix("/kite").Handler(sockjs.NewHandler("/kite", sockjsOpts, k.sockjsHandler))

	// Add useful debug logs
	k.OnConnect(func(c *Client) { k.Log.Debug("New session: %s", c.session.ID()) })
	k.OnFirstRequest(func(c *Client) { k.Log.Debug("Session %q is identified as %q", c.session.ID(), c.Kite) })
	k.OnDisconnect(func(c *Client) { k.Log.Debug("Kite has disconnected: %q", c.Kite) })

	// Every kite should be able to authenticate the user from token.
	// Tokens are granted by Kontrol Kite.
	k.Authenticators["token"] = k.AuthenticateFromToken

	// A kite accepts requests with the same username.
	k.Authenticators["kiteKey"] = k.AuthenticateFromKiteKey

	// Register default methods and handlers.
	k.addDefaultHandlers()

	return k
}

// Kite returns the definition of the kite.
func (k *Kite) Kite() *protocol.Kite {
	return &protocol.Kite{
		Username:    k.Config.Username,
		Environment: k.Config.Environment,
		Name:        k.name,
		Version:     k.version,
		Region:      k.Config.Region,
		Hostname:    hostname,
		ID:          k.Id,
	}
}

// Trust a Kontrol key for validating tokens.
func (k *Kite) TrustKontrolKey(issuer, key string) {
	k.trustedKontrolKeys[issuer] = key
}

// HandleHTTP registers the HTTP handler for the given pattern into the
// underlying HTTP muxer.
func (k *Kite) HandleHTTP(pattern string, handler http.Handler) {
	k.muxer.Handle(pattern, handler)
}

// HandleHTTPFunc registers the HTTP handler for the given pattern into the
// underlying HTTP muxer.
func (k *Kite) HandleHTTPFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
	k.muxer.HandleFunc(pattern, handler)
}

// ServeHTTP helps Kite to satisfy the http.Handler interface. So kite can be
// used as a standard http server.
func (k *Kite) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	k.muxer.ServeHTTP(w, req)
}

func (k *Kite) sockjsHandler(session sockjs.Session) {
	defer session.Close(0, "")

	// This Client also handles the connected client.
	// Since both sides can send/receive messages the client code is reused here.
	c := k.NewClient("")
	c.session = session

	go c.sendHub()
	c.wg.Add(1) // with sendHub we added a new listener

	k.callOnConnectHandlers(c)

	// Run after methods are registered and delegate is set
	c.readLoop()

	c.callOnDisconnectHandlers()
	k.callOnDisconnectHandlers(c)
}

func (k *Kite) OnConnect(handler func(*Client)) {
	k.onConnectHandlers = append(k.onConnectHandlers, handler)
}

// OnFirstRequest registers a function to run when a Kite connects to this Kite.
func (k *Kite) OnFirstRequest(handler func(*Client)) {
	k.onFirstRequestHandlers = append(k.onFirstRequestHandlers, handler)
}

// OnDisconnect registers a function to run when a connected Kite is disconnected.
func (k *Kite) OnDisconnect(handler func(*Client)) {
	k.onDisconnectHandlers = append(k.onDisconnectHandlers, handler)
}

func (k *Kite) callOnConnectHandlers(c *Client) {
	for _, handler := range k.onConnectHandlers {
		handler(c)
	}
}

func (k *Kite) callOnFirstRequestHandlers(c *Client) {
	for _, handler := range k.onFirstRequestHandlers {
		handler(c)
	}
}

func (k *Kite) callOnDisconnectHandlers(c *Client) {
	for _, handler := range k.onDisconnectHandlers {
		handler(c)
	}
}

// RSAKey returns the corresponding public key for the issuer of the token.
// It is called by jwt-go package when validating the signature in the token.
func (k *Kite) RSAKey(token *jwt.Token) (interface{}, error) {
	if k.Config.KontrolKey == "" {
		panic("kontrol key is not set in config")
	}

	issuer, ok := token.Claims["iss"].(string)
	if !ok {
		return nil, errors.New("token does not contain a valid issuer claim")
	}

	if issuer != k.Config.KontrolUser {
		return nil, fmt.Errorf("issuer is not trusted: %s", issuer)
	}

	return []byte(k.Config.KontrolKey), nil
}
<commit_msg>kite: add sockjsopts<commit_after>// Package kite is a library for creating micro-services.  Two main types
// implemented by this package are Kite for creating a micro-service server
// called "Kite" and Client for communicating with another kites.
package kite

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"
	"github.com/koding/kite/config"
	"github.com/koding/kite/protocol"
	"github.com/nu7hatch/gouuid"
	"gopkg.in/igm/sockjs-go.v2/sockjs"
)

var hostname string

func init() {
	var err error
	hostname, err = os.Hostname()
	if err != nil {
		panic(fmt.Sprintf("kite: cannot get hostname: %s", err.Error()))
	}
}

// Kite defines a single process that enables distributed service messaging
// amongst the peers it is connected. A Kite process acts as a Client and as a
// Server. That means it can receive request, process them, but it also can
// make request to other kites.
//
// Do not use this struct directly. Use kite.New function, add your handlers
// with HandleFunc mehtod, then call Run method to start the inbuilt server (or
// pass it to any http.Handler compatible server)
type Kite struct {
	Config *config.Config

	// Log logs with the given Logger interface
	Log Logger

	// SetLogLevel changes the level of the logger. Default is INFO.
	SetLogLevel func(Level)

	// Contains different functions for authenticating user from request.
	// Keys are the authentication types (options.auth.type).
	Authenticators map[string]func(*Request) error

	// Kontrol keys to trust. Kontrol will issue access tokens for kites
	// that are signed with the private counterpart of these keys.
	// Key data must be PEM encoded.
	trustedKontrolKeys map[string]string

	// Handlers added with Kite.HandleFunc().
	handlers     map[string]*Method // method map for exported methods
	preHandlers  []Handler          // a list of handlers that are executed before any handler
	postHandlers []Handler          // a list of handlers that are executed after any handler

	// MethodHandling defines how the kite is returning the response for
	// multiple handlers
	MethodHandling MethodHandling

	// HTTP muxer
	muxer *mux.Router

	// kontrolclient is used to register to kontrol and query third party kites
	// from kontrol
	kontrol *kontrolClient

	// Handlers to call when a new connection is received.
	onConnectHandlers []func(*Client)

	// Handlers to call before the first request of connected kite.
	onFirstRequestHandlers []func(*Client)

	// Handlers to call when a client has disconnected.
	onDisconnectHandlers []func(*Client)

	// server fields, are initialized and used when
	// TODO: move them to their own struct, just like KontrolClient
	listener  net.Listener
	TLSConfig *tls.Config
	readyC    chan bool // To signal when kite is ready to accept connections
	closeC    chan bool // To signal when kite is closed with Close()

	name    string
	version string
	Id      string // Unique kite instance id
}

// New creates, initialize and then returns a new Kite instance. Version must
// be in 3-digit semantic form. Name is important that it's also used to be
// searched by others.
func New(name, version string) *Kite {
	if name == "" {
		panic("kite: name cannot be empty")
	}

	if digits := strings.Split(version, "."); len(digits) != 3 {
		panic("kite: version must be 3-digits semantic version")
	}

	kiteID, err := uuid.NewV4()
	if err != nil {
		panic(fmt.Sprintf("kite: cannot generate unique ID: %s", err.Error()))
	}

	l, setlevel := newLogger(name)

	kClient := &kontrolClient{
		readyConnected:  make(chan struct{}),
		readyRegistered: make(chan struct{}),
		registerChan:    make(chan *url.URL, 1),
	}

	k := &Kite{
		Config:             config.New(),
		Log:                l,
		SetLogLevel:        setlevel,
		Authenticators:     make(map[string]func(*Request) error),
		trustedKontrolKeys: make(map[string]string),
		handlers:           make(map[string]*Method),
		preHandlers:        make([]Handler, 0),
		postHandlers:       make([]Handler, 0),
		kontrol:            kClient,
		name:               name,
		version:            version,
		Id:                 kiteID.String(),
		readyC:             make(chan bool),
		closeC:             make(chan bool),
		muxer:              mux.NewRouter(),
	}

	// We change the heartbeat interval from 25 seconds to 10 seconds. This is
	// better for environments such as AWS ELB.
	sockjsOpts := sockjs.DefaultOptions
	sockjsOpts.HeartbeatDelay = 10 * time.Second

	// All sockjs communication is done through this endpoint..
	k.muxer.PathPrefix("/kite").Handler(sockjs.NewHandler("/kite", sockjsOpts, k.sockjsHandler))

	// Add useful debug logs
	k.OnConnect(func(c *Client) { k.Log.Debug("New session: %s", c.session.ID()) })
	k.OnFirstRequest(func(c *Client) { k.Log.Debug("Session %q is identified as %q", c.session.ID(), c.Kite) })
	k.OnDisconnect(func(c *Client) { k.Log.Debug("Kite has disconnected: %q", c.Kite) })

	// Every kite should be able to authenticate the user from token.
	// Tokens are granted by Kontrol Kite.
	k.Authenticators["token"] = k.AuthenticateFromToken

	// A kite accepts requests with the same username.
	k.Authenticators["kiteKey"] = k.AuthenticateFromKiteKey

	// Register default methods and handlers.
	k.addDefaultHandlers()

	return k
}

// Kite returns the definition of the kite.
func (k *Kite) Kite() *protocol.Kite {
	return &protocol.Kite{
		Username:    k.Config.Username,
		Environment: k.Config.Environment,
		Name:        k.name,
		Version:     k.version,
		Region:      k.Config.Region,
		Hostname:    hostname,
		ID:          k.Id,
	}
}

// Trust a Kontrol key for validating tokens.
func (k *Kite) TrustKontrolKey(issuer, key string) {
	k.trustedKontrolKeys[issuer] = key
}

// HandleHTTP registers the HTTP handler for the given pattern into the
// underlying HTTP muxer.
func (k *Kite) HandleHTTP(pattern string, handler http.Handler) {
	k.muxer.Handle(pattern, handler)
}

// HandleHTTPFunc registers the HTTP handler for the given pattern into the
// underlying HTTP muxer.
func (k *Kite) HandleHTTPFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
	k.muxer.HandleFunc(pattern, handler)
}

// ServeHTTP helps Kite to satisfy the http.Handler interface. So kite can be
// used as a standard http server.
func (k *Kite) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	k.muxer.ServeHTTP(w, req)
}

func (k *Kite) sockjsHandler(session sockjs.Session) {
	defer session.Close(0, "")

	// This Client also handles the connected client.
	// Since both sides can send/receive messages the client code is reused here.
	c := k.NewClient("")
	c.session = session

	go c.sendHub()
	c.wg.Add(1) // with sendHub we added a new listener

	k.callOnConnectHandlers(c)

	// Run after methods are registered and delegate is set
	c.readLoop()

	c.callOnDisconnectHandlers()
	k.callOnDisconnectHandlers(c)
}

func (k *Kite) OnConnect(handler func(*Client)) {
	k.onConnectHandlers = append(k.onConnectHandlers, handler)
}

// OnFirstRequest registers a function to run when a Kite connects to this Kite.
func (k *Kite) OnFirstRequest(handler func(*Client)) {
	k.onFirstRequestHandlers = append(k.onFirstRequestHandlers, handler)
}

// OnDisconnect registers a function to run when a connected Kite is disconnected.
func (k *Kite) OnDisconnect(handler func(*Client)) {
	k.onDisconnectHandlers = append(k.onDisconnectHandlers, handler)
}

func (k *Kite) callOnConnectHandlers(c *Client) {
	for _, handler := range k.onConnectHandlers {
		handler(c)
	}
}

func (k *Kite) callOnFirstRequestHandlers(c *Client) {
	for _, handler := range k.onFirstRequestHandlers {
		handler(c)
	}
}

func (k *Kite) callOnDisconnectHandlers(c *Client) {
	for _, handler := range k.onDisconnectHandlers {
		handler(c)
	}
}

// RSAKey returns the corresponding public key for the issuer of the token.
// It is called by jwt-go package when validating the signature in the token.
func (k *Kite) RSAKey(token *jwt.Token) (interface{}, error) {
	if k.Config.KontrolKey == "" {
		panic("kontrol key is not set in config")
	}

	issuer, ok := token.Claims["iss"].(string)
	if !ok {
		return nil, errors.New("token does not contain a valid issuer claim")
	}

	if issuer != k.Config.KontrolUser {
		return nil, fmt.Errorf("issuer is not trusted: %s", issuer)
	}

	return []byte(k.Config.KontrolKey), nil
}
<|endoftext|>


<commit_before>package goketo

import (
	"encoding/json"
	"net/url"
	"strconv"
	"strings"

	"github.com/Sirupsen/logrus"
)

// Leads response from list request
type Leads struct {
	client    *Client
	RequestID string          `json:"requestId"`
	Result    json.RawMessage `json:"result"`
	Success   bool            `json:"success"`
	Next      string          `json:"nextPageToken,omitempty"`
}

// LeadResult default result struct as part of the lead - can be customized to allow greater fields
type LeadResult struct {
	ID        int    `json:"id"`
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Email     string `json:"email"`
	Created   string `json:"createdAt"`
	Updated   string `json:"updatedAt"`
}

// LeadRequest builds a request for data retrieval
type LeadRequest struct {
	ID     int    // List ID
	Next   string // Next page Token
	Fields string
}

// LeadUpdate builds the data for an update
type LeadUpdate struct {
	Action string          `json:"action"` // createOnly - updateOnly - createOrUpdate(default request) - createDuplicate
	Lookup string          `json:"lookupField"`
	Input  json.RawMessage `json:"input"`
}

// LeadUpdateResponse data format for update response
type LeadUpdateResponse struct {
	ID      string             `json:"requestId"`
	Success bool               `json:"success"`
	Result  []LeadUpdateResult `json:"result,omitempty"`
	Error   []LeadError        `json:"errors,omitempty"`
}

// LeadUpdateResult holds result for all updates
type LeadUpdateResult struct {
	ID     int    `json:"id"`
	Status string `json:"status"`
}

// LeadError shows the error code and message for response
type LeadError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

// Leads Get leads by list Id
func (c *Client) Leads(list *LeadRequest) (leads *Leads, err error) {
	var nextPage string
	if list.Next != "" {
		nextPage = "?nextPageToken=" + list.Next
	} else {
		nextPage = ""
	}
	body, err := c.Get("/list/" + strconv.Itoa(list.ID) + "/leads.json" + nextPage)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(body, &leads)
	leads.client = c
	return leads, err
}

// Lead Get lead by Id - aka member by ID
func (c *Client) Lead(leadReq *LeadRequest) (lead *Leads, err error) {
	fields := url.Values{}
	if len(leadReq.Fields) > 0 {
		fields.Set("fields", strings.Join(strings.Fields(leadReq.Fields), ""))
	}
	logrus.Info("Fields: ", fields.Encode())
	body, err := c.Get("/lead/" + strconv.Itoa(leadReq.ID) + ".json" + "?" + fields.Encode())
	if err != nil {
		return
	}
	err = json.Unmarshal(body, &lead)
	lead.client = c
	return
}

// UpdateLeads post update of data for a lead
func (c *Client) UpdateLeads(update *LeadUpdate) ([]byte, error) {
	data, err := json.Marshal(update)
	if err != nil {
		return nil, err
	}
	body, err := c.Post("/leads.json", data)
	return body, err
}
<commit_msg>Created response struct<commit_after>package goketo

import (
	"encoding/json"
	"net/url"
	"strconv"
	"strings"

	"github.com/Sirupsen/logrus"
)

// LeadResponse response from list request
type LeadResponse struct {
	client    *Client
	RequestID string          `json:"requestId"`
	Result    json.RawMessage `json:"result"`
	Success   bool            `json:"success"`
	Next      string          `json:"nextPageToken,omitempty"`
}

// LeadResult default result struct as part of the lead - can be customized to allow greater fields
type LeadResult struct {
	ID        int    `json:"id"`
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Email     string `json:"email"`
	Created   string `json:"createdAt"`
	Updated   string `json:"updatedAt"`
}

// LeadRequest builds a request for data retrieval
type LeadRequest struct {
	ID     int    // List ID
	Next   string // Next page Token
	Fields string
}

// LeadUpdate builds the data for an update
type LeadUpdate struct {
	Action string          `json:"action"` // createOnly - updateOnly - createOrUpdate(default request) - createDuplicate
	Lookup string          `json:"lookupField"`
	Input  json.RawMessage `json:"input"`
}

// LeadUpdateResponse data format for update response
type LeadUpdateResponse struct {
	ID      string             `json:"requestId"`
	Success bool               `json:"success"`
	Result  []LeadUpdateResult `json:"result,omitempty"`
	Error   []LeadError        `json:"errors,omitempty"`
}

// LeadUpdateResult holds result for all updates
type LeadUpdateResult struct {
	ID     int    `json:"id"`
	Status string `json:"status"`
}

// LeadError shows the error code and message for response
type LeadError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

// Leads Get leads by list Id
func (c *Client) Leads(list *LeadRequest) (leads *LeadResponse, err error) {
	var nextPage string
	if list.Next != "" {
		nextPage = "?nextPageToken=" + list.Next
	} else {
		nextPage = ""
	}
	body, err := c.Get("/list/" + strconv.Itoa(list.ID) + "/leads.json" + nextPage)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(body, &leads)
	leads.client = c
	return leads, err
}

// Lead Get lead by Id - aka member by ID
func (c *Client) Lead(leadReq *LeadRequest) (lead *LeadResponse, err error) {
	fields := url.Values{}
	if len(leadReq.Fields) > 0 {
		fields.Set("fields", strings.Join(strings.Fields(leadReq.Fields), ""))
	}
	logrus.Info("Fields: ", fields.Encode())
	body, err := c.Get("/lead/" + strconv.Itoa(leadReq.ID) + ".json" + "?" + fields.Encode())
	if err != nil {
		return
	}
	err = json.Unmarshal(body, &lead)
	lead.client = c
	return
}

// UpdateLeads post update of data for a lead
func (c *Client) UpdateLeads(update *LeadUpdate) ([]byte, error) {
	data, err := json.Marshal(update)
	if err != nil {
		return nil, err
	}
	body, err := c.Post("/leads.json", data)
	return body, err
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "time"
)

const (
  rows          = 32
  cols          = 32
  cellsPerValue = 16 // a uint64 contains 16 nibbles
  deadCell      = `⋅ `
  liveCell      = `○ `
  vt100         = `[`
  vtUp          = `A`
  interframe    = 200 * time.Millisecond
)

func main() {
  fmt.Printf(fmt.Sprintf("%% %ds\n", (cols+2)), "Life")
  colz := cols / cellsPerValue
  board := make([][]uint64, rows)
  boardone := make([]uint64, rows*colz)
  for i := range board {
    board[i], boardone = boardone[:colz], boardone[colz:]
  }
  start_test := []string{
    "                               x",
    "  x            x                ",
    "  x           x                 ",
    "  x                             ",
    "                x               ",
    "",
    "",
    "  x",
    "  x",
    "  x",
    "",
    "",
    "  x   xx",
    "  x   xx",
    "  x",
    "",
    "",
    "               xx",
    "               xx",
    "                 xx",
    "                 xx",
    "",
    "",
    "",
    "      xxx",
    "      x x",
    "      xxx",
    "",
    "",
    "",
    "                               x",
    "                               x",
  }

  start := start_test

  for i := range start {
    fmt.Println()
    for j, k := range start[i] {
      if k != ' ' {
        set(board, j, i)
      }
    }
  }

  for f:=0;;f++ {
    out(board, f)
    count(board)
    rules(board)
  }
}

func set(board [][]uint64, x, y int) {
  if x < cols && y < rows {
    j := uint(x / cellsPerValue)
    offset := x % cellsPerValue
    mask := uint64(1) << uint((15-offset)*4)
    board[y][j] |= mask
  }
}

func out(board [][]uint64, f int) {
  fmt.Print(vt100, rows+1, vtUp, "frame:", f, "\n")
  for i := range board {
    for j := range board[i] {
      o := uint64(1) << uint(60)
      for o > 0 {
        if (board[i][j] & o) == o {
          fmt.Print(liveCell)
        } else {
          fmt.Print(deadCell)
        }
        o >>= 4
      }
    }
    fmt.Println()
  }
}

func count(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      // leftmost bit of uint64 adds to its 3 left and up and down
      m := uint64(1) << 60
      v := board[i][j] & m
      var y int
      if v > 0 {
        if j == 0 {
          y = len(board[i]) - 1
        } else {
          y = j - 1
        }
        if i == 0 {
          board[len(board)-1][y] += 2
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][y] += 2
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][y] += 2
        if i == len(board)-1 {
          board[0][y] += 2
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][y] += 2
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // 2nd-leftmost bit of uint64 adds to its left
      m = uint64(1) << 56
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][j] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // middle bits of uint64
      for k := 52; k >= 0; k -= 4 {
        m := uint64(0x111) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          var u, w uint64
          switch v >> uint(k) {
          case 0x010:
            u = 1
            w = 0
          case 0x001, 0x100:
            u = 1
            w = 1
          case 0x011, 0x110:
            u = 2
            w = 1
          case 0x101:
            u = 2
            w = 2
          case 0x111:
            u = 3
            w = 2
          }
          u <<= uint(k + 5)
          if i == 0 {
            board[len(board)-1][j] += u
          } else {
            board[i-1][j] += u
          }
          board[i][j] += (w << uint(k+5))
          if i == len(board)-1 {
            board[0][j] += u
          } else {
            board[i+1][j] += u
          }
        }
      }
      // rightmost bit of uint64 adds to its 3 right and up and down
      m = uint64(1)
      v = board[i][j] & m
      if v > 0 {
        if j == len(board[i])-1 {
          y = 0
        } else {
          y = j + 1
        }
        if i == 0 {
          board[len(board)-1][y] += (uint64(2) << 60)
          board[len(board)-1][j] += 2
        } else {
          board[i-1][y] += (uint64(2) << 60)
          board[i-1][j] += 2
        }
        board[i][y] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][y] += (uint64(2) << 60)
          board[0][j] += 2
        } else {
          board[i+1][y] += (uint64(2) << 60)
          board[i+1][j] += 2
        }
      }
      // 2nd-rightmost bit of uint64 adds to its right
      m = uint64(0x10)
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += 2
        } else {
          board[i-1][j] += 2
        }
        board[i][j] += 2
        if i == len(board)-1 {
          board[0][j] += 2
        } else {
          board[i+1][j] += 2
        }
      }
    }
  }
  time.Sleep(interframe)
}

func rules(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      for k := 60; k >= 0; k -= 4 {
        m := uint64(0xF) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          board[i][j] &= ^m
          switch v >> uint(k) {
          case 5, 6, 7:
            board[i][j] |= (uint64(1) << uint(k))
          }
        }
      }
    }
  }
}
<commit_msg>Adding the gosper gun.<commit_after>package main

import (
  "fmt"
  "time"
)

const (
  rows          = 32
  cols          = 48
  cellsPerValue = 16 // a uint64 contains 16 nibbles
  deadCell      = `⋅ `
  liveCell      = `○ `
  vt100         = `[`
  vtUp          = `A`
  interframe    = 200 * time.Millisecond
)

func main() {
  fmt.Printf(fmt.Sprintf("%% %ds\n", (cols+2)), "Life")
  colz := cols / cellsPerValue
  board := make([][]uint64, rows)
  boardone := make([]uint64, rows*colz)
  for i := range board {
    board[i], boardone = boardone[:colz], boardone[colz:]
  }
  start_test := []string{
    "                               x",
    "  x            x                ",
    "  x           x                 ",
    "  x                             ",
    "                x               ",
    "",
    "",
    "  x",
    "  x",
    "  x",
    "",
    "",
    "  x   xx",
    "  x   xx",
    "  x",
    "",
    "",
    "               xx",
    "               xx",
    "                 xx",
    "                 xx",
    "",
    "",
    "",
    "      xxx",
    "      x x",
    "      xxx",
    "",
    "",
    "",
    "                               x",
    "                               x",
  }
  start_gosper := []string{
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                         1            ",
    "                       1 1            ",
    "             11      11            11 ",
    "            1   1    11            11 ",
    " 11        1     1   11               ",
    " 11        1   1 11    1 1            ",
    "           1     1       1            ",
    "            1   1                     ",
    "             11                       ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
  }

  _ = start_test
  start := start_gosper

  for i := range start {
    fmt.Println()
    for j, k := range start[i] {
      if k != ' ' {
        set(board, j, i)
      }
    }
  }

  for f:=0;;f++ {
    out(board, f)
    count(board)
    rules(board)
  }
}

func set(board [][]uint64, x, y int) {
  if x < cols && y < rows {
    j := uint(x / cellsPerValue)
    offset := x % cellsPerValue
    mask := uint64(1) << uint((15-offset)*4)
    board[y][j] |= mask
  }
}

func out(board [][]uint64, f int) {
  fmt.Print(vt100, rows+1, vtUp, "frame:", f, "\n")
  for i := range board {
    for j := range board[i] {
      o := uint64(1) << uint(60)
      for o > 0 {
        if (board[i][j] & o) == o {
          fmt.Print(liveCell)
        } else {
          fmt.Print(deadCell)
        }
        o >>= 4
      }
    }
    fmt.Println()
  }
}

func count(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      // leftmost bit of uint64 adds to its 3 left and up and down
      m := uint64(1) << 60
      v := board[i][j] & m
      var y int
      if v > 0 {
        if j == 0 {
          y = len(board[i]) - 1
        } else {
          y = j - 1
        }
        if i == 0 {
          board[len(board)-1][y] += 2
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][y] += 2
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][y] += 2
        if i == len(board)-1 {
          board[0][y] += 2
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][y] += 2
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // 2nd-leftmost bit of uint64 adds to its left
      m = uint64(1) << 56
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][j] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // middle bits of uint64
      for k := 52; k >= 0; k -= 4 {
        m := uint64(0x111) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          var u, w uint64
          switch v >> uint(k) {
          case 0x010:
            u = 1
            w = 0
          case 0x001, 0x100:
            u = 1
            w = 1
          case 0x011, 0x110:
            u = 2
            w = 1
          case 0x101:
            u = 2
            w = 2
          case 0x111:
            u = 3
            w = 2
          }
          u <<= uint(k + 5)
          if i == 0 {
            board[len(board)-1][j] += u
          } else {
            board[i-1][j] += u
          }
          board[i][j] += (w << uint(k+5))
          if i == len(board)-1 {
            board[0][j] += u
          } else {
            board[i+1][j] += u
          }
        }
      }
      // rightmost bit of uint64 adds to its 3 right and up and down
      m = uint64(1)
      v = board[i][j] & m
      if v > 0 {
        if j == len(board[i])-1 {
          y = 0
        } else {
          y = j + 1
        }
        if i == 0 {
          board[len(board)-1][y] += (uint64(2) << 60)
          board[len(board)-1][j] += 2
        } else {
          board[i-1][y] += (uint64(2) << 60)
          board[i-1][j] += 2
        }
        board[i][y] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][y] += (uint64(2) << 60)
          board[0][j] += 2
        } else {
          board[i+1][y] += (uint64(2) << 60)
          board[i+1][j] += 2
        }
      }
      // 2nd-rightmost bit of uint64 adds to its right
      m = uint64(0x10)
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += 2
        } else {
          board[i-1][j] += 2
        }
        board[i][j] += 2
        if i == len(board)-1 {
          board[0][j] += 2
        } else {
          board[i+1][j] += 2
        }
      }
    }
  }
  time.Sleep(interframe)
}

func rules(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      for k := 60; k >= 0; k -= 4 {
        m := uint64(0xF) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          board[i][j] &= ^m
          switch v >> uint(k) {
          case 5, 6, 7:
            board[i][j] |= (uint64(1) << uint(k))
          }
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"fmt"
	"sort"
	"strings"

	"golang.org/x/tools/go/packages"
)

func (m *matcher) load(wd string, args ...string) ([]*packages.Package, error) {
	mode := packages.NeedName | packages.NeedImports | packages.NeedSyntax |
		packages.NeedTypes | packages.NeedTypesInfo
	if m.recursive { // need the syntax trees for the dependencies too
		mode |= packages.NeedDeps
	}
	cfg := &packages.Config{
		Mode:  mode,
		Dir:   wd,
		Fset:  m.fset,
		Tests: m.tests,
	}
	pkgs, err := packages.Load(cfg, args...)
	if err != nil {
		return nil, err
	}
	jointErr := ""
	packages.Visit(pkgs, nil, func(pkg *packages.Package) {
		for _, err := range pkg.Errors {
			jointErr += err.Error() + "\n"
		}
	})
	if jointErr != "" {
		return nil, fmt.Errorf("%s", jointErr)
	}

	// Make a sorted list of the packages, including transitive dependencies
	// if recurse is true.
	byPath := make(map[string]*packages.Package)
	var addDeps func(*packages.Package)
	addDeps = func(pkg *packages.Package) {
		if strings.HasSuffix(pkg.PkgPath, ".test") {
			// don't add recursive test deps
			return
		}
		for _, imp := range pkg.Imports {
			if _, ok := byPath[imp.PkgPath]; ok {
				continue // seen; avoid recursive call
			}
			byPath[imp.PkgPath] = imp
			addDeps(imp)
		}
	}
	for _, pkg := range pkgs {
		byPath[pkg.PkgPath] = pkg
		if m.recursive {
			// add all dependencies once
			addDeps(pkg)
		}
	}
	pkgs = pkgs[:0]
	for _, pkg := range byPath {
		pkgs = append(pkgs, pkg)
	}
	sort.Slice(pkgs, func(i, j int) bool {
		return pkgs[i].PkgPath < pkgs[j].PkgPath
	})
	return pkgs, nil
}
<commit_msg>avoid NeedImports when not needed<commit_after>// Copyright (c) 2017, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"fmt"
	"sort"
	"strings"

	"golang.org/x/tools/go/packages"
)

func (m *matcher) load(wd string, args ...string) ([]*packages.Package, error) {
	mode := packages.NeedName | packages.NeedSyntax |
		packages.NeedTypes | packages.NeedTypesInfo
	if m.recursive { // need the syntax trees for the dependencies too
		mode |= packages.NeedDeps | packages.NeedImports
	}
	cfg := &packages.Config{
		Mode:  mode,
		Dir:   wd,
		Fset:  m.fset,
		Tests: m.tests,
	}
	pkgs, err := packages.Load(cfg, args...)
	if err != nil {
		return nil, err
	}
	jointErr := ""
	packages.Visit(pkgs, nil, func(pkg *packages.Package) {
		for _, err := range pkg.Errors {
			jointErr += err.Error() + "\n"
		}
	})
	if jointErr != "" {
		return nil, fmt.Errorf("%s", jointErr)
	}

	// Make a sorted list of the packages, including transitive dependencies
	// if recurse is true.
	byPath := make(map[string]*packages.Package)
	var addDeps func(*packages.Package)
	addDeps = func(pkg *packages.Package) {
		if strings.HasSuffix(pkg.PkgPath, ".test") {
			// don't add recursive test deps
			return
		}
		for _, imp := range pkg.Imports {
			if _, ok := byPath[imp.PkgPath]; ok {
				continue // seen; avoid recursive call
			}
			byPath[imp.PkgPath] = imp
			addDeps(imp)
		}
	}
	for _, pkg := range pkgs {
		byPath[pkg.PkgPath] = pkg
		if m.recursive {
			// add all dependencies once
			addDeps(pkg)
		}
	}
	pkgs = pkgs[:0]
	for _, pkg := range byPath {
		pkgs = append(pkgs, pkg)
	}
	sort.Slice(pkgs, func(i, j int) bool {
		return pkgs[i].PkgPath < pkgs[j].PkgPath
	})
	return pkgs, nil
}
<|endoftext|>