<commit_before>//go:build linux || darwin || freebsd
// +build linux darwin freebsd

package command

import (
	"context"
	"fmt"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/chrislusf/seaweedfs/weed/storage/types"

	"github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"

	"github.com/seaweedfs/fuse"
	"github.com/seaweedfs/fuse/fs"

	"github.com/chrislusf/seaweedfs/weed/filesys"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/pb"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/util"
	"github.com/chrislusf/seaweedfs/weed/util/grace"
)

func runMount(cmd *Command, args []string) bool {

	grace.SetupProfiling(*mountCpuProfile, *mountMemProfile)
	if *mountReadRetryTime < time.Second {
		*mountReadRetryTime = time.Second
	}
	util.RetryWaitTime = *mountReadRetryTime

	umask, umaskErr := strconv.ParseUint(*mountOptions.umaskString, 8, 64)
	if umaskErr != nil {
		fmt.Printf("can not parse umask %s", *mountOptions.umaskString)
		return false
	}

	if len(args) > 0 {
		return false
	}

	return RunMount(&mountOptions, os.FileMode(umask))
}

func getParentInode(mountDir string) (uint64, error) {
	parentDir := filepath.Clean(filepath.Join(mountDir, ".."))
	fi, err := os.Stat(parentDir)
	if err != nil {
		return 0, err
	}

	stat, ok := fi.Sys().(*syscall.Stat_t)
	if !ok {
		return 0, nil
	}

	return stat.Ino, nil
}

func RunMount(option *MountOptions, umask os.FileMode) bool {

	filerAddresses := pb.ServerAddresses(*option.filer).ToAddresses()

	util.LoadConfiguration("security", false)
	// try to connect to filer, filerBucketsPath may be useful later
	grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
	var cipher bool
	var err error
	for i := 0; i < 10; i++ {
		err = pb.WithOneOfGrpcFilerClients(false, filerAddresses, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
			resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
			if err != nil {
				return fmt.Errorf("get filer grpc address %v configuration: %v", filerAddresses, err)
			}
			cipher = resp.Cipher
			return nil
		})
		if err != nil {
			glog.V(0).Infof("failed to talk to filer %v: %v", filerAddresses, err)
			glog.V(0).Infof("wait for %d seconds ...", i+1)
			time.Sleep(time.Duration(i+1) * time.Second)
		}
	}
	if err != nil {
		glog.Errorf("failed to talk to filer %v: %v", filerAddresses, err)
		return true
	}

	filerMountRootPath := *option.filerMountRootPath
	dir := util.ResolvePath(*option.dir)
	parentInode, err := getParentInode(dir)
	if err != nil {
		glog.Errorf("failed to retrieve inode for parent directory of %s: %v", dir, err)
		return true
	}

	fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
	if dir == "" {
		fmt.Printf("Please specify the mount directory via \"-dir\"")
		return false
	}

	chunkSizeLimitMB := *mountOptions.chunkSizeLimitMB
	if chunkSizeLimitMB <= 0 {
		fmt.Printf("Please specify a reasonable buffer size.")
		return false
	}

	fuse.Unmount(dir)

	// detect mount folder mode
	if *option.dirAutoCreate {
		os.MkdirAll(dir, os.FileMode(0777)&^umask)
	}
	fileInfo, err := os.Stat(dir)

	uid, gid := uint32(0), uint32(0)
	mountMode := os.ModeDir | 0777
	if err == nil {
		mountMode = os.ModeDir | os.FileMode(0777)&^umask
		uid, gid = util.GetFileUidGid(fileInfo)
		fmt.Printf("mount point owner uid=%d gid=%d mode=%s\n", uid, gid, mountMode)
	} else {
		fmt.Printf("can not stat %s\n", dir)
		return false
	}

	if uid == 0 {
		if u, err := user.Current(); err == nil {
			if parsedId, pe := strconv.ParseUint(u.Uid, 10, 32); pe == nil {
				uid = uint32(parsedId)
			}
			if parsedId, pe := strconv.ParseUint(u.Gid, 10, 32); pe == nil {
				gid = uint32(parsedId)
			}
			fmt.Printf("current uid=%d gid=%d\n", uid, gid)
		}
	}

	// mapping uid, gid
	uidGidMapper, err := meta_cache.NewUidGidMapper(*option.uidMap, *option.gidMap)
	if err != nil {
		fmt.Printf("failed to parse %s %s: %v\n", *option.uidMap, *option.gidMap, err)
		return false
	}

	// Ensure target mount point availability
	if isValid := checkMountPointAvailable(dir); !isValid {
		glog.Fatalf("Expected mount to still be active, target mount point: %s, please check!", dir)
		return true
	}

	mountName := path.Base(dir)

	options := []fuse.MountOption{
		fuse.VolumeName(mountName),
		fuse.FSName(*option.filer + ":" + filerMountRootPath),
		fuse.Subtype("seaweedfs"),
		// fuse.NoAppleDouble(), // include .DS_Store, otherwise can not delete non-empty folders
		fuse.NoAppleXattr(),
		fuse.ExclCreate(),
		fuse.DaemonTimeout("3600"),
		fuse.AllowSUID(),
		fuse.DefaultPermissions(),
		fuse.MaxReadahead(1024 * 128),
		fuse.AsyncRead(),
		// fuse.WritebackCache(),
		fuse.MaxBackground(128),
		fuse.CongestionThreshold(128),
	}

	options = append(options, osSpecificMountOptions()...)
	if *option.allowOthers {
		options = append(options, fuse.AllowOther())
	}
	if *option.nonempty {
		options = append(options, fuse.AllowNonEmptyMount())
	}
	if *option.readOnly {
		options = append(options, fuse.ReadOnly())
	}

	// find mount point
	mountRoot := filerMountRootPath
	if mountRoot != "/" && strings.HasSuffix(mountRoot, "/") {
		mountRoot = mountRoot[0 : len(mountRoot)-1]
	}

	diskType := types.ToDiskType(*option.diskType)

	seaweedFileSystem := filesys.NewSeaweedFileSystem(&filesys.Option{
		MountDirectory:     dir,
		FilerAddresses:     filerAddresses,
		GrpcDialOption:     grpcDialOption,
		FilerMountRootPath: mountRoot,
		Collection:         *option.collection,
		Replication:        *option.replication,
		TtlSec:             int32(*option.ttlSec),
		DiskType:           diskType,
		ChunkSizeLimit:     int64(chunkSizeLimitMB) * 1024 * 1024,
		ConcurrentWriters:  *option.concurrentWriters,
		CacheDir:           *option.cacheDir,
		CacheSizeMB:        *option.cacheSizeMB,
		DataCenter:         *option.dataCenter,
		MountUid:           uid,
		MountGid:           gid,
		MountMode:          mountMode,
		MountCtime:         fileInfo.ModTime(),
		MountMtime:         time.Now(),
		MountParentInode:   parentInode,
		Umask:              umask,
		VolumeServerAccess: *mountOptions.volumeServerAccess,
		Cipher:             cipher,
		UidGidMapper:       uidGidMapper,
	})

	// mount
	c, err := fuse.Mount(dir, options...)
	if err != nil {
		glog.V(0).Infof("mount: %v", err)
		return true
	}
	defer fuse.Unmount(dir)

	grace.OnInterrupt(func() {
		fuse.Unmount(dir)
		c.Close()
	})

	glog.V(0).Infof("mounted %s%s to %v", *option.filer, mountRoot, dir)
	server := fs.New(c, nil)
	seaweedFileSystem.Server = server
	seaweedFileSystem.StartBackgroundTasks()
	err = server.Serve(seaweedFileSystem)

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		glog.V(0).Infof("mount process: %v", err)
		return true
	}

	return true
}
<commit_msg>mount: remove limits on number of parallel requests<commit_after>//go:build linux || darwin || freebsd
// +build linux darwin freebsd

package command

import (
	"context"
	"fmt"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/chrislusf/seaweedfs/weed/storage/types"

	"github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"

	"github.com/seaweedfs/fuse"
	"github.com/seaweedfs/fuse/fs"

	"github.com/chrislusf/seaweedfs/weed/filesys"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/pb"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/util"
	"github.com/chrislusf/seaweedfs/weed/util/grace"
)

func runMount(cmd *Command, args []string) bool {

	grace.SetupProfiling(*mountCpuProfile, *mountMemProfile)
	if *mountReadRetryTime < time.Second {
		*mountReadRetryTime = time.Second
	}
	util.RetryWaitTime = *mountReadRetryTime

	umask, umaskErr := strconv.ParseUint(*mountOptions.umaskString, 8, 64)
	if umaskErr != nil {
		fmt.Printf("can not parse umask %s", *mountOptions.umaskString)
		return false
	}

	if len(args) > 0 {
		return false
	}

	return RunMount(&mountOptions, os.FileMode(umask))
}

func getParentInode(mountDir string) (uint64, error) {
	parentDir := filepath.Clean(filepath.Join(mountDir, ".."))
	fi, err := os.Stat(parentDir)
	if err != nil {
		return 0, err
	}

	stat, ok := fi.Sys().(*syscall.Stat_t)
	if !ok {
		return 0, nil
	}

	return stat.Ino, nil
}

func RunMount(option *MountOptions, umask os.FileMode) bool {

	filerAddresses := pb.ServerAddresses(*option.filer).ToAddresses()

	util.LoadConfiguration("security", false)
	// try to connect to filer, filerBucketsPath may be useful later
	grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
	var cipher bool
	var err error
	for i := 0; i < 10; i++ {
		err = pb.WithOneOfGrpcFilerClients(false, filerAddresses, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
			resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
			if err != nil {
				return fmt.Errorf("get filer grpc address %v configuration: %v", filerAddresses, err)
			}
			cipher = resp.Cipher
			return nil
		})
		if err != nil {
			glog.V(0).Infof("failed to talk to filer %v: %v", filerAddresses, err)
			glog.V(0).Infof("wait for %d seconds ...", i+1)
			time.Sleep(time.Duration(i+1) * time.Second)
		}
	}
	if err != nil {
		glog.Errorf("failed to talk to filer %v: %v", filerAddresses, err)
		return true
	}

	filerMountRootPath := *option.filerMountRootPath
	dir := util.ResolvePath(*option.dir)
	parentInode, err := getParentInode(dir)
	if err != nil {
		glog.Errorf("failed to retrieve inode for parent directory of %s: %v", dir, err)
		return true
	}

	fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
	if dir == "" {
		fmt.Printf("Please specify the mount directory via \"-dir\"")
		return false
	}

	chunkSizeLimitMB := *mountOptions.chunkSizeLimitMB
	if chunkSizeLimitMB <= 0 {
		fmt.Printf("Please specify a reasonable buffer size.")
		return false
	}

	fuse.Unmount(dir)

	// detect mount folder mode
	if *option.dirAutoCreate {
		os.MkdirAll(dir, os.FileMode(0777)&^umask)
	}
	fileInfo, err := os.Stat(dir)

	uid, gid := uint32(0), uint32(0)
	mountMode := os.ModeDir | 0777
	if err == nil {
		mountMode = os.ModeDir | os.FileMode(0777)&^umask
		uid, gid = util.GetFileUidGid(fileInfo)
		fmt.Printf("mount point owner uid=%d gid=%d mode=%s\n", uid, gid, mountMode)
	} else {
		fmt.Printf("can not stat %s\n", dir)
		return false
	}

	if uid == 0 {
		if u, err := user.Current(); err == nil {
			if parsedId, pe := strconv.ParseUint(u.Uid, 10, 32); pe == nil {
				uid = uint32(parsedId)
			}
			if parsedId, pe := strconv.ParseUint(u.Gid, 10, 32); pe == nil {
				gid = uint32(parsedId)
			}
			fmt.Printf("current uid=%d gid=%d\n", uid, gid)
		}
	}

	// mapping uid, gid
	uidGidMapper, err := meta_cache.NewUidGidMapper(*option.uidMap, *option.gidMap)
	if err != nil {
		fmt.Printf("failed to parse %s %s: %v\n", *option.uidMap, *option.gidMap, err)
		return false
	}

	// Ensure target mount point availability
	if isValid := checkMountPointAvailable(dir); !isValid {
		glog.Fatalf("Expected mount to still be active, target mount point: %s, please check!", dir)
		return true
	}

	mountName := path.Base(dir)

	options := []fuse.MountOption{
		fuse.VolumeName(mountName),
		fuse.FSName(*option.filer + ":" + filerMountRootPath),
		fuse.Subtype("seaweedfs"),
		// fuse.NoAppleDouble(), // include .DS_Store, otherwise can not delete non-empty folders
		fuse.NoAppleXattr(),
		fuse.ExclCreate(),
		fuse.DaemonTimeout("3600"),
		fuse.AllowSUID(),
		fuse.DefaultPermissions(),
		fuse.MaxReadahead(1024 * 512),
		fuse.AsyncRead(),
		// fuse.WritebackCache(),
		// fuse.MaxBackground(1024),
		// fuse.CongestionThreshold(1024),
	}

	options = append(options, osSpecificMountOptions()...)
	if *option.allowOthers {
		options = append(options, fuse.AllowOther())
	}
	if *option.nonempty {
		options = append(options, fuse.AllowNonEmptyMount())
	}
	if *option.readOnly {
		options = append(options, fuse.ReadOnly())
	}

	// find mount point
	mountRoot := filerMountRootPath
	if mountRoot != "/" && strings.HasSuffix(mountRoot, "/") {
		mountRoot = mountRoot[0 : len(mountRoot)-1]
	}

	diskType := types.ToDiskType(*option.diskType)

	seaweedFileSystem := filesys.NewSeaweedFileSystem(&filesys.Option{
		MountDirectory:     dir,
		FilerAddresses:     filerAddresses,
		GrpcDialOption:     grpcDialOption,
		FilerMountRootPath: mountRoot,
		Collection:         *option.collection,
		Replication:        *option.replication,
		TtlSec:             int32(*option.ttlSec),
		DiskType:           diskType,
		ChunkSizeLimit:     int64(chunkSizeLimitMB) * 1024 * 1024,
		ConcurrentWriters:  *option.concurrentWriters,
		CacheDir:           *option.cacheDir,
		CacheSizeMB:        *option.cacheSizeMB,
		DataCenter:         *option.dataCenter,
		MountUid:           uid,
		MountGid:           gid,
		MountMode:          mountMode,
		MountCtime:         fileInfo.ModTime(),
		MountMtime:         time.Now(),
		MountParentInode:   parentInode,
		Umask:              umask,
		VolumeServerAccess: *mountOptions.volumeServerAccess,
		Cipher:             cipher,
		UidGidMapper:       uidGidMapper,
	})

	// mount
	c, err := fuse.Mount(dir, options...)
	if err != nil {
		glog.V(0).Infof("mount: %v", err)
		return true
	}
	defer fuse.Unmount(dir)

	grace.OnInterrupt(func() {
		fuse.Unmount(dir)
		c.Close()
	})

	glog.V(0).Infof("mounted %s%s to %v", *option.filer, mountRoot, dir)
	server := fs.New(c, nil)
	seaweedFileSystem.Server = server
	seaweedFileSystem.StartBackgroundTasks()
	err = server.Serve(seaweedFileSystem)

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		glog.V(0).Infof("mount process: %v", err)
		return true
	}

	return true
}
<|endoftext|>


<commit_before>//   Copyright (c) 2016 Ivan A Kostko (github.com/ivan-kostko)

//   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 Default

import (
	"testing"

	//. "github.com/ivan-kostko/GoLibs/CustomErrors"
	parsers "github.com/ivan-kostko/GoLibs/Parser"
)

func TestInitRegistration(t *testing.T) {

	p, err := parsers.GetParserByFormat(parsers.DefaultXML)
	if err != nil {
		t.Errorf("parser.GetParserByFormat(parser.DefaultXML) returned error %v while no error expected", err)
	}
	expectedParser := &parser
	if p != expectedParser {
		t.Errorf("parser.GetParserByFormat(parser.DefaultXML) returned parser %v while expected %v", *p, expectedParser)
	}
}
<commit_msg>Cleanup unused referencies<commit_after>//   Copyright (c) 2016 Ivan A Kostko (github.com/ivan-kostko)

//   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 Default

import (
	"testing"

	parsers "github.com/ivan-kostko/GoLibs/Parser"
)

func TestInitRegistration(t *testing.T) {

	p, err := parsers.GetParserByFormat(parsers.DefaultXML)
	if err != nil {
		t.Errorf("parser.GetParserByFormat(parser.DefaultXML) returned error %v while no error expected", err)
	}
	expectedParser := &parser
	if p != expectedParser {
		t.Errorf("parser.GetParserByFormat(parser.DefaultXML) returned parser %v while expected %v", *p, expectedParser)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
	"gopkg.in/yaml.v2"

	cli "github.com/lxc/lxd/shared/cmd"
	"github.com/lxc/lxd/shared/i18n"
)

type cmdOperation struct {
	global *cmdGlobal
}

func (c *cmdOperation) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("operation")
	cmd.Short = i18n.G("List, show and delete background operations")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List, show and delete background operations`))

	// Delete
	operationDeleteCmd := cmdOperationDelete{global: c.global, operation: c}
	cmd.AddCommand(operationDeleteCmd.Command())

	// List
	operationListCmd := cmdOperationList{global: c.global, operation: c}
	cmd.AddCommand(operationListCmd.Command())

	// Show
	operationShowCmd := cmdOperationShow{global: c.global, operation: c}
	cmd.AddCommand(operationShowCmd.Command())

	return cmd
}

// Delete
type cmdOperationDelete struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationDelete) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("delete [<remote>:]<operation>")
	cmd.Aliases = []string{"cancel", "rm"}
	cmd.Short = i18n.G("Delete a background operation (will attempt to cancel)")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Delete a background operation (will attempt to cancel)`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationDelete) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Delete the operation
	err = resource.server.DeleteOperation(resource.name)
	if err != nil {
		return err
	}

	if !c.global.flagQuiet {
		fmt.Printf(i18n.G("Operation %s deleted")+"\n", resource.name)
	}

	return nil
}

// List
type cmdOperationList struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationList) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("list [<remote>:]")
	cmd.Aliases = []string{"ls"}
	cmd.Short = i18n.G("List background operations")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List background operations`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationList) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 0, 1)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	if len(args) == 1 {
		remote = args[0]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]
	if resource.name != "" {
		return fmt.Errorf(i18n.G("Filtering isn't supported yet"))
	}

	// Get operations
	operations, err := resource.server.GetOperations()
	if err != nil {
		return err
	}

	// Render the table
	data := [][]string{}
	for _, op := range operations {
		cancelable := i18n.G("NO")
		if op.MayCancel {
			cancelable = i18n.G("YES")
		}

		data = append(data, []string{op.ID, strings.ToUpper(op.Class), op.Description, strings.ToUpper(op.Status), cancelable, op.CreatedAt.UTC().Format("2006/01/02 15:04 UTC")})
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	table.SetHeader([]string{
		i18n.G("ID"),
		i18n.G("TYPE"),
		i18n.G("DESCRIPTION"),
		i18n.G("STATUS"),
		i18n.G("CANCELABLE"),
		i18n.G("CREATED")})
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}

// Show
type cmdOperationShow struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationShow) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("show [<remote>:]<operation>")
	cmd.Short = i18n.G("Show details on a background operation")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Show details on a background operation`))
	cmd.Example = cli.FormatSection("", i18n.G(
		`lxc operation show 344a79e4-d88a-45bf-9c39-c72c26f6ab8a
    Show details on that operation UUID`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationShow) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Get the operation
	op, _, err := resource.server.GetOperation(resource.name)
	if err != nil {
		return err
	}

	// Render as YAML
	data, err := yaml.Marshal(&op)
	if err != nil {
		return err
	}

	fmt.Printf("%s", data)

	return nil
}
<commit_msg>lxc/operation: Show location column<commit_after>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
	"gopkg.in/yaml.v2"

	cli "github.com/lxc/lxd/shared/cmd"
	"github.com/lxc/lxd/shared/i18n"
)

type cmdOperation struct {
	global *cmdGlobal
}

func (c *cmdOperation) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("operation")
	cmd.Short = i18n.G("List, show and delete background operations")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List, show and delete background operations`))

	// Delete
	operationDeleteCmd := cmdOperationDelete{global: c.global, operation: c}
	cmd.AddCommand(operationDeleteCmd.Command())

	// List
	operationListCmd := cmdOperationList{global: c.global, operation: c}
	cmd.AddCommand(operationListCmd.Command())

	// Show
	operationShowCmd := cmdOperationShow{global: c.global, operation: c}
	cmd.AddCommand(operationShowCmd.Command())

	return cmd
}

// Delete
type cmdOperationDelete struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationDelete) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("delete [<remote>:]<operation>")
	cmd.Aliases = []string{"cancel", "rm"}
	cmd.Short = i18n.G("Delete a background operation (will attempt to cancel)")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Delete a background operation (will attempt to cancel)`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationDelete) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Delete the operation
	err = resource.server.DeleteOperation(resource.name)
	if err != nil {
		return err
	}

	if !c.global.flagQuiet {
		fmt.Printf(i18n.G("Operation %s deleted")+"\n", resource.name)
	}

	return nil
}

// List
type cmdOperationList struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationList) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("list [<remote>:]")
	cmd.Aliases = []string{"ls"}
	cmd.Short = i18n.G("List background operations")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List background operations`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationList) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 0, 1)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	if len(args) == 1 {
		remote = args[0]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]
	if resource.name != "" {
		return fmt.Errorf(i18n.G("Filtering isn't supported yet"))
	}

	// Get operations
	operations, err := resource.server.GetOperations()
	if err != nil {
		return err
	}

	// Render the table
	data := [][]string{}
	for _, op := range operations {
		cancelable := i18n.G("NO")
		if op.MayCancel {
			cancelable = i18n.G("YES")
		}

		entry := []string{op.ID, strings.ToUpper(op.Class), op.Description, strings.ToUpper(op.Status), cancelable, op.CreatedAt.UTC().Format("2006/01/02 15:04 UTC")}
		if resource.server.IsClustered() {
			entry = append(entry, op.Location)
		}

		data = append(data, entry)
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	header := []string{
		i18n.G("ID"),
		i18n.G("TYPE"),
		i18n.G("DESCRIPTION"),
		i18n.G("STATUS"),
		i18n.G("CANCELABLE"),
		i18n.G("CREATED")}
	if resource.server.IsClustered() {
		header = append(header, i18n.G("LOCATION"))
	}
	table.SetHeader(header)
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}

// Show
type cmdOperationShow struct {
	global    *cmdGlobal
	operation *cmdOperation
}

func (c *cmdOperationShow) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("show [<remote>:]<operation>")
	cmd.Short = i18n.G("Show details on a background operation")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Show details on a background operation`))
	cmd.Example = cli.FormatSection("", i18n.G(
		`lxc operation show 344a79e4-d88a-45bf-9c39-c72c26f6ab8a
    Show details on that operation UUID`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdOperationShow) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Get the operation
	op, _, err := resource.server.GetOperation(resource.name)
	if err != nil {
		return err
	}

	// Render as YAML
	data, err := yaml.Marshal(&op)
	if err != nil {
		return err
	}

	fmt.Printf("%s", data)

	return nil
}
<|endoftext|>


<commit_before>package mackerel

// Host XXX
type Host struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Type   string `json:"type"` // TODO ENUM
	Status string `json:"status"`
}

type HostSpec struct {
	Name          string                   `json:"name"`
	Meta          map[string]interface{}   `json:"meta"`
	Interfaces    []map[string]interface{} `json:"interfaces"`
	RoleFullnames []string                 `json:"roleFullnames"`
	Checks        []string                 `json:"checks,omitempty"`
	DisplayName   string                   `json:"displayName,omitempty"`
}
<commit_msg>add one line document for HostSpec<commit_after>package mackerel

// Host XXX
type Host struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Type   string `json:"type"` // TODO ENUM
	Status string `json:"status"`
}

// HostSpec is host specifications sent Mackerel server per hour
type HostSpec struct {
	Name          string                   `json:"name"`
	Meta          map[string]interface{}   `json:"meta"`
	Interfaces    []map[string]interface{} `json:"interfaces"`
	RoleFullnames []string                 `json:"roleFullnames"`
	Checks        []string                 `json:"checks,omitempty"`
	DisplayName   string                   `json:"displayName,omitempty"`
}
<|endoftext|>


<commit_before>package ams

import (
	"context"
	"net/url"
	"os"
)

func (c *Client) CreateAccessPolicy(name, durationInMinutes float64, permissions int) (*AccessPolicy, error) {
	return c.CreateAccessPolicyWithContext(context.Background(), name, durationInMinutes, permissions)
}
func (c *Client) DeleteAccessPolicy(accessPolicy *AccessPolicy) error {
	return c.DeleteAccessPolicyWithContext(context.Background(), accessPolicy)
}
func (c *Client) GetAsset(assetID string) (*Asset, error) {
	return c.GetAssetWithContext(context.Background(), assetID)
}
func (c *Client) GetAssets() ([]Asset, error) {
	return c.GetAssetsWithContext(context.Background())
}
func (c *Client) CreateAsset(name string) (*Asset, error) {
	return c.CreateAssetWithContext(context.Background(), name)
}
func (c *Client) CreateAssetFile(assetID, name, mimeType string) (*AssetFile, error) {
	return c.CreateAssetFileWithContext(context.Background(), assetID, name, mimeType)
}
func (c *Client) UpdateAssetFile(assetFile *AssetFile) error {
	return c.UpdateAssetFileWithContext(context.Background(), assetFile)
}
func (c *Client) PutBlob(uploadURL *url.URL, file *os.File) ([]int, error) {
	return c.PutBlobWithContext(context.Background(), uploadURL, file)
}
func (c *Client) PutBlockList(uploadURL *url.URL, blockList []int) error {
	return c.PutBlockListWithContext(context.Background(), uploadURL, blockList)
}
func (c *Client) EncodeAsset(mediaProcessorID, configuration string, asset *Asset) (*Job, error) {
	return c.EncodeAssetWithContext(context.Background(), mediaProcessorID, configuration, asset)
}
func (c *Client) GetJob(jobID string) (*Job, error) {
	return c.GetJobWithContext(context.Background(), jobID)
}
func (c *Client) WaitJob(job *Job) error {
	return c.WaitJobWithContext(context.Background(), job)
}
func (c *Client) CreateLocator(accessPolicyID, assetID, startTime string, locatorType int) (*Locator, error) {
	return c.CreateLocatorWithContext(context.Background(), accessPolicyID, assetID, startTime, locatorType)
}
func (c *Client) DeleteLocator(locator *Locator) error {
	return c.DeleteLocatorWithContext(context.Background(), locator)
}
func (c *Client) GetMediaProcessors() ([]MediaProcessor, error) {
	return c.GetMediaProcessorsWithContext(context.Background())
}
<commit_msg>feat: update generate file<commit_after>package ams

import (
	"context"
	"net/url"
	"os"
	"time"
)

func (c *Client) CreateAccessPolicy(name string, durationInMinutes float64, permissions int) (*AccessPolicy, error) {
	return c.CreateAccessPolicyWithContext(context.Background(), name, durationInMinutes, permissions)
}
func (c *Client) DeleteAccessPolicy(accessPolicy *AccessPolicy) error {
	return c.DeleteAccessPolicyWithContext(context.Background(), accessPolicy)
}
func (c *Client) GetAsset(assetID string) (*Asset, error) {
	return c.GetAssetWithContext(context.Background(), assetID)
}
func (c *Client) GetAssets() ([]Asset, error) {
	return c.GetAssetsWithContext(context.Background())
}
func (c *Client) CreateAsset(name string) (*Asset, error) {
	return c.CreateAssetWithContext(context.Background(), name)
}
func (c *Client) GetAssetFiles(asset *Asset) ([]AssetFile, error) {
	return c.GetAssetFilesWithContext(context.Background(), asset)
}
func (c *Client) CreateAssetFile(assetID, name, mimeType string) (*AssetFile, error) {
	return c.CreateAssetFileWithContext(context.Background(), assetID, name, mimeType)
}
func (c *Client) UpdateAssetFile(assetFile *AssetFile) error {
	return c.UpdateAssetFileWithContext(context.Background(), assetFile)
}
func (c *Client) PutBlob(uploadURL *url.URL, file *os.File) ([]int, error) {
	return c.PutBlobWithContext(context.Background(), uploadURL, file)
}
func (c *Client) PutBlockList(uploadURL *url.URL, blockList []int) error {
	return c.PutBlockListWithContext(context.Background(), uploadURL, blockList)
}
func (c *Client) EncodeAsset(mediaProcessorID, configuration string, asset *Asset) (*Job, error) {
	return c.EncodeAssetWithContext(context.Background(), mediaProcessorID, configuration, asset)
}
func (c *Client) GetOutputMediaAssets(job *Job) ([]Asset, error) {
	return c.GetOutputMediaAssetsWithContext(context.Background(), job)
}
func (c *Client) GetJob(jobID string) (*Job, error) {
	return c.GetJobWithContext(context.Background(), jobID)
}
func (c *Client) WaitJob(job *Job) error {
	return c.WaitJobWithContext(context.Background(), job)
}
func (c *Client) CreateLocator(accessPolicyID, assetID string, startTime time.Time, locatorType int) (*Locator, error) {
	return c.CreateLocatorWithContext(context.Background(), accessPolicyID, assetID, startTime, locatorType)
}
func (c *Client) DeleteLocator(locator *Locator) error {
	return c.DeleteLocatorWithContext(context.Background(), locator)
}
func (c *Client) GetMediaProcessors() ([]MediaProcessor, error) {
	return c.GetMediaProcessorsWithContext(context.Background())
}
<|endoftext|>


<commit_before>package reflag

import (
	"flag"
	"fmt"
	"reflect"
	"strconv"
)

type StringField struct {
	f         *Field
	MaxLength *int
}

func NewStringField(f *Field) Fielder {
	return &StringField{f: f}
}

func (b *StringField) Init() error {
	return nil
}

func (b *StringField) BindOpt(key, value string) error {
	switch key {
	case KEY_MAX:
		length, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		b.MaxLength = &length
	default:
		return ErrOptMissHandler.Format(key, b.f.Name)
	}
	return nil
}

func (b *StringField) AfterParse() error {
	s := b.f.Instance().(*string)
	if b.MaxLength != nil {
		bb := []rune(*s)
		if len(bb) > *b.MaxLength {
			*s = string(bb[:*b.MaxLength])
		}
	}
	return nil
}

func (b *StringField) BindFlag(fs *flag.FlagSet) {
	ins := b.f.Instance().(*string)
	fs.StringVar(ins, b.f.FlagName(), b.f.DefVal, b.f.Usage)
}

func (b *StringField) Default() interface{} {
	return b.f.DefVal
}

func (b *StringField) SetArg(v *reflect.Value, arg string) error {
	if !v.CanSet() {
		return fmt.Errorf("value %v is not settable", v)
	}

	if arg != "" {
		v.Set(reflect.ValueOf(arg))
	}
	return nil
}
<commit_msg>add string arg default<commit_after>package reflag

import (
	"flag"
	"fmt"
	"reflect"
	"strconv"
)

type StringField struct {
	f         *Field
	MaxLength *int
}

func NewStringField(f *Field) Fielder {
	return &StringField{f: f}
}

func (b *StringField) Init() error {
	return nil
}

func (b *StringField) BindOpt(key, value string) error {
	switch key {
	case KEY_MAX:
		length, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		b.MaxLength = &length
	default:
		return ErrOptMissHandler.Format(key, b.f.Name)
	}
	return nil
}

func (b *StringField) AfterParse() error {
	s := b.f.Instance().(*string)
	if b.MaxLength != nil {
		bb := []rune(*s)
		if len(bb) > *b.MaxLength {
			*s = string(bb[:*b.MaxLength])
		}
	}
	return nil
}

func (b *StringField) BindFlag(fs *flag.FlagSet) {
	ins := b.f.Instance().(*string)
	fs.StringVar(ins, b.f.FlagName(), b.f.DefVal, b.f.Usage)
}

func (b *StringField) Default() interface{} {
	return b.f.DefVal
}

func (b *StringField) SetArg(v *reflect.Value, arg string) error {
	if !v.CanSet() {
		return fmt.Errorf("value %v is not settable", v)
	}

	if arg == "" {
		arg = b.Default().(string)
	}
	v.Set(reflect.ValueOf(arg))
	return nil
}
<|endoftext|>


<commit_before>package database

import (
	"testing"
)

func TestAddRepositoryGetRepository(t *testing.T) {
	r1 := CreateRepository("foo", "bar", "accessKey", false, false, false)
	r2 := GetRepository("bar")
	r2.Update("baz", "bar", "accessKey", false, false, false)
	DeleteRepository("bar")
	r3 := GetRepository("bar")

	if r1.ID != r2.ID {
		t.Error("IDs do not match.")
	}

	if r2.Name == "bar" {
		t.Error("Names are the same.")
	}

	if r3.ID == r1.ID || r3.ID != 0 {
		t.Error("Repository not deleted.")
	}
}

func TestJobs(t *testing.T) {
	r1 := CreateRepository("name", "url", "accessKey", false, false, false)
	r2 := CreateRepository("name2", "url2", "accessKey", false, false, false)

	j1 := CreateJob(r1, "branch", "commit", "commitURL", "name", "email")
	j2 := CreateJob(r1, "branch2", "commit", "commitURL", "name", "email")
	CreateJob(r2, "branch3", "commit", "commitURL", "name", "email")

	j := r1.Jobs()

	if len(j) != 2 {
		t.Error("Wrong number of jobs", len(j))
	}

	for _, v := range j {
		if v.ID != j1.ID && v.ID != j2.ID {
			t.Error("Wrong job")
		}
	}
}
<commit_msg>update / delete repository based<commit_after>package database

import (
	"testing"
)

func TestAddRepositoryGetRepository(t *testing.T) {
	r1 := CreateRepository("foo", "bar", "accessKey", false, false, false)
	r2 := GetRepository("bar")
	r2.Update("baz", "bar", "accessKey", false, false, false)
	r2.Delete("bar")
	r3 := GetRepository("bar")

	if r1.ID != r2.ID {
		t.Error("IDs do not match.")
	}

	if r2.Name == "bar" {
		t.Error("Names are the same.")
	}

	if r3.ID == r1.ID || r3.ID != 0 {
		t.Error("Repository not deleted.")
	}
}

func TestJobs(t *testing.T) {
	r1 := CreateRepository("name", "url", "accessKey", false, false, false)
	r2 := CreateRepository("name2", "url2", "accessKey", false, false, false)

	j1 := CreateJob(r1, "branch", "commit", "commitURL", "name", "email")
	j2 := CreateJob(r1, "branch2", "commit", "commitURL", "name", "email")
	CreateJob(r2, "branch3", "commit", "commitURL", "name", "email")

	j := r1.Jobs()

	if len(j) != 2 {
		t.Error("Wrong number of jobs", len(j))
	}

	for _, v := range j {
		if v.ID != j1.ID && v.ID != j2.ID {
			t.Error("Wrong job")
		}
	}
}
<|endoftext|>


<commit_before>package databath

import ()

type QueryConditions struct {
	collection string
	where      []QueryCondition
	pk         *uint64
	fieldset   *string
	limit      *int64
	filter     *map[string]interface{}
	offset     *int64
	sort       []*QuerySort
	search     map[string]string
}

type QueryCondition interface {
	GetConditionString(q *Query) (string, []interface{}, bool, error)
}

type QuerySort struct {
	Direction int32  `json:"direction"`
	FieldName string `json:"fieldName"`
}

type QueryConditionString struct {
	Str        string // No JSON. This CANNOT be exposed to the user, Utility Only.
	Parameters []interface{}
}

func (qc *QueryConditionString) GetConditionString(q *Query) (string, []interface{}, bool, error) {
	return "(" + qc.Str + ")", qc.Parameters, false, nil
}

func GetMinimalQueryConditions(collectionName string, fieldset string) *QueryConditions {
	qc := QueryConditions{
		collection: collectionName,
		where:      make([]QueryCondition, 0, 0),
		fieldset:   &fieldset,
	}
	return &qc
}
<commit_msg>Add getters for query things (BM Portal)<commit_after>package databath

import ()

type QueryConditions struct {
	collection string
	where      []QueryCondition
	pk         *uint64
	fieldset   *string
	limit      *int64
	filter     *map[string]interface{}
	offset     *int64
	sort       []*QuerySort
	search     map[string]string
}

func (qc *QueryConditions) CollectionName() string {
	return qc.collection
}

func (qc *QueryConditions) AndWhere(extraCondition QueryCondition) {
	qc.where = append(qc.where, extraCondition)
}

type QueryCondition interface {
	GetConditionString(q *Query) (string, []interface{}, bool, error)
}

type QuerySort struct {
	Direction int32  `json:"direction"`
	FieldName string `json:"fieldName"`
}

type QueryConditionString struct {
	Str        string // No JSON. This CANNOT be exposed to the user, Utility Only.
	Parameters []interface{}
}

func (qc *QueryConditionString) GetConditionString(q *Query) (string, []interface{}, bool, error) {
	return "(" + qc.Str + ")", qc.Parameters, false, nil
}

func GetMinimalQueryConditions(collectionName string, fieldset string) *QueryConditions {
	qc := QueryConditions{
		collection: collectionName,
		where:      make([]QueryCondition, 0, 0),
		fieldset:   &fieldset,
	}
	return &qc
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.

// More information about Google Distance Matrix API is available on
// https://developers.google.com/maps/documentation/distancematrix/

package maps

import (
	"errors"
	"net/url"
	"strings"

	"golang.org/x/net/context"
)

var geocodingAPI = &apiConfig{
	host:            "https://maps.googleapis.com",
	path:            "/maps/api/geocode/json",
	acceptsClientID: true,
}

// Geocode makes a Geocoding API request
func (c *Client) Geocode(ctx context.Context, r *GeocodingRequest) ([]GeocodingResult, error) {
	if r.Address == "" && len(r.Components) == 0 && r.LatLng == nil {
		return nil, errors.New("maps: address, components and LatLng are all missing")
	}

	var response struct {
		Results []GeocodingResult `json:"results"`
		commonResponse
	}

	if err := c.getJSON(ctx, geocodingAPI, r, &response); err != nil {
		return nil, err
	}

	if response.Status == "ZERO_RESULTS" {
		return []GeocodingResult{}, nil
	}

	if err := response.StatusError(); err != nil {
		return nil, err
	}

	return response.Results, nil
}

// ReverseGeocode makes a Reverse Geocoding API request
func (c *Client) ReverseGeocode(ctx context.Context, r *GeocodingRequest) ([]GeocodingResult, error) {
	// Since Geocode() does not allow a nil LatLng, whereas it is allowed here
	if r.LatLng == nil && r.PlaceID == "" {
		return nil, errors.New("maps: LatLng and PlaceID are both missing")
	}

	var response struct {
		Results []GeocodingResult `json:"results"`
		commonResponse
	}

	if err := c.getJSON(ctx, geocodingAPI, r, &response); err != nil {
		return nil, err
	}

	if err := response.StatusError(); err != nil {
		return nil, err
	}

	return response.Results, nil

}

func (r *GeocodingRequest) params() url.Values {
	q := make(url.Values)

	for k, v := range r.Custom {
		q[k] = v
	}

	if r.Address != "" {
		q.Set("address", r.Address)
	}
	var cf []string
	for c, f := range r.Components {
		cf = append(cf, string(c)+":"+f)
	}
	if len(cf) > 0 {
		q.Set("components", strings.Join(cf, "|"))
	}
	if r.Bounds != nil {
		q.Set("bounds", r.Bounds.String())
	}
	if r.Region != "" {
		q.Set("region", r.Region)
	}
	if r.LatLng != nil {
		q.Set("latlng", r.LatLng.String())
	}
	if len(r.ResultType) > 0 {
		q.Set("result_type", strings.Join(r.ResultType, "|"))
	}
	if len(r.LocationType) > 0 {
		var lt []string
		for _, l := range r.LocationType {
			lt = append(lt, string(l))
		}
		q.Set("location_type", strings.Join(lt, "|"))
	}
	if r.PlaceID != "" {
		q.Set("place_id", r.PlaceID)
	}
	if r.Language != "" {
		q.Set("language", r.Language)
	}

	return q
}

// GeocodeAccuracy is the type of a location result from the Geocoding API.
type GeocodeAccuracy string

const (
	// GeocodeAccuracyRooftop restricts the results to addresses for which Google has location information accurate down to street address precision
	GeocodeAccuracyRooftop = GeocodeAccuracy("ROOFTOP")
	// GeocodeAccuracyRangeInterpolated restricts the results to those that reflect an approximation interpolated between two precise points.
	GeocodeAccuracyRangeInterpolated = GeocodeAccuracy("RANGE_INTERPOLATED")
	// GeocodeAccuracyGeometricCenter restricts the results to geometric centers of a location such as a polyline or polygon.
	GeocodeAccuracyGeometricCenter = GeocodeAccuracy("GEOMETRIC_CENTER")
	// GeocodeAccuracyApproximate restricts the results to those that are characterized as approximate.
	GeocodeAccuracyApproximate = GeocodeAccuracy("APPROXIMATE")
)

// GeocodingRequest is the request structure for Geocoding API
type GeocodingRequest struct {
	// Geocoding fields

	// Address is the street address that you want to geocode, in the format used by the national postal service of the country concerned.
	Address string
	// Components is a component filter for which you wish to obtain a geocode. Either Address or Components is required in a geocoding request.
	// For more detail on Component Filtering please see
	// https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering
	Components map[Component]string
	// Bounds is the bounding box of the viewport within which to bias geocode results more prominently. Optional.
	Bounds *LatLngBounds
	// Region is the region code, specified as a ccTLD two-character value. Optional.
	Region string

	// Reverse geocoding fields

	// LatLng is the textual latitude/longitude value for which you wish to obtain the closest, human-readable address. Either LatLng or PlaceID is required for Reverse Geocoding.
	LatLng *LatLng
	// ResultType is an array of one or more address types. Optional.
	ResultType []string
	// LocationType is an array of one or more geocoding accuracy types. Optional.
	LocationType []GeocodeAccuracy
	// PlaceID is a string which contains the place_id, which can be used for reverse geocoding requests. Either LatLng or PlaceID is required for Reverse Geocoding.
	PlaceID string

	// Language is the language in which to return results. Optional.
	Language string

	// Custom allows passing through custom parameters to the Geocoding back end. Use with caution.
	// For more detail on why this is required, please see
	// https://googlegeodevelopers.blogspot.com/2016/11/address-geocoding-in-google-maps-apis.html
	Custom url.Values
}

// GeocodingResult is a single geocoded address
type GeocodingResult struct {
	AddressComponents []AddressComponent `json:"address_components"`
	FormattedAddress  string             `json:"formatted_address"`
	Geometry          AddressGeometry    `json:"geometry"`
	Types             []string           `json:"types"`
	PlaceID           string             `json:"place_id"`
}

// AddressComponent is a part of an address
type AddressComponent struct {
	LongName  string   `json:"long_name"`
	ShortName string   `json:"short_name"`
	Types     []string `json:"types"`
}

// AddressGeometry is the location of a an address
type AddressGeometry struct {
	Location     LatLng       `json:"location"`
	LocationType string       `json:"location_type"`
	Bounds       LatLngBounds `json:"bounds"`
	Viewport     LatLngBounds `json:"viewport"`
	Types        []string     `json:"types"`
}
<commit_msg>Fix documentation link in geocoding.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.

// More information about Google Geocoding API is available on
// https://developers.google.com/maps/documentation/geocoding

package maps

import (
	"errors"
	"net/url"
	"strings"

	"golang.org/x/net/context"
)

var geocodingAPI = &apiConfig{
	host:            "https://maps.googleapis.com",
	path:            "/maps/api/geocode/json",
	acceptsClientID: true,
}

// Geocode makes a Geocoding API request
func (c *Client) Geocode(ctx context.Context, r *GeocodingRequest) ([]GeocodingResult, error) {
	if r.Address == "" && len(r.Components) == 0 && r.LatLng == nil {
		return nil, errors.New("maps: address, components and LatLng are all missing")
	}

	var response struct {
		Results []GeocodingResult `json:"results"`
		commonResponse
	}

	if err := c.getJSON(ctx, geocodingAPI, r, &response); err != nil {
		return nil, err
	}

	if response.Status == "ZERO_RESULTS" {
		return []GeocodingResult{}, nil
	}

	if err := response.StatusError(); err != nil {
		return nil, err
	}

	return response.Results, nil
}

// ReverseGeocode makes a Reverse Geocoding API request
func (c *Client) ReverseGeocode(ctx context.Context, r *GeocodingRequest) ([]GeocodingResult, error) {
	// Since Geocode() does not allow a nil LatLng, whereas it is allowed here
	if r.LatLng == nil && r.PlaceID == "" {
		return nil, errors.New("maps: LatLng and PlaceID are both missing")
	}

	var response struct {
		Results []GeocodingResult `json:"results"`
		commonResponse
	}

	if err := c.getJSON(ctx, geocodingAPI, r, &response); err != nil {
		return nil, err
	}

	if err := response.StatusError(); err != nil {
		return nil, err
	}

	return response.Results, nil

}

func (r *GeocodingRequest) params() url.Values {
	q := make(url.Values)

	for k, v := range r.Custom {
		q[k] = v
	}

	if r.Address != "" {
		q.Set("address", r.Address)
	}
	var cf []string
	for c, f := range r.Components {
		cf = append(cf, string(c)+":"+f)
	}
	if len(cf) > 0 {
		q.Set("components", strings.Join(cf, "|"))
	}
	if r.Bounds != nil {
		q.Set("bounds", r.Bounds.String())
	}
	if r.Region != "" {
		q.Set("region", r.Region)
	}
	if r.LatLng != nil {
		q.Set("latlng", r.LatLng.String())
	}
	if len(r.ResultType) > 0 {
		q.Set("result_type", strings.Join(r.ResultType, "|"))
	}
	if len(r.LocationType) > 0 {
		var lt []string
		for _, l := range r.LocationType {
			lt = append(lt, string(l))
		}
		q.Set("location_type", strings.Join(lt, "|"))
	}
	if r.PlaceID != "" {
		q.Set("place_id", r.PlaceID)
	}
	if r.Language != "" {
		q.Set("language", r.Language)
	}

	return q
}

// GeocodeAccuracy is the type of a location result from the Geocoding API.
type GeocodeAccuracy string

const (
	// GeocodeAccuracyRooftop restricts the results to addresses for which Google has location information accurate down to street address precision
	GeocodeAccuracyRooftop = GeocodeAccuracy("ROOFTOP")
	// GeocodeAccuracyRangeInterpolated restricts the results to those that reflect an approximation interpolated between two precise points.
	GeocodeAccuracyRangeInterpolated = GeocodeAccuracy("RANGE_INTERPOLATED")
	// GeocodeAccuracyGeometricCenter restricts the results to geometric centers of a location such as a polyline or polygon.
	GeocodeAccuracyGeometricCenter = GeocodeAccuracy("GEOMETRIC_CENTER")
	// GeocodeAccuracyApproximate restricts the results to those that are characterized as approximate.
	GeocodeAccuracyApproximate = GeocodeAccuracy("APPROXIMATE")
)

// GeocodingRequest is the request structure for Geocoding API
type GeocodingRequest struct {
	// Geocoding fields

	// Address is the street address that you want to geocode, in the format used by the national postal service of the country concerned.
	Address string
	// Components is a component filter for which you wish to obtain a geocode. Either Address or Components is required in a geocoding request.
	// For more detail on Component Filtering please see
	// https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering
	Components map[Component]string
	// Bounds is the bounding box of the viewport within which to bias geocode results more prominently. Optional.
	Bounds *LatLngBounds
	// Region is the region code, specified as a ccTLD two-character value. Optional.
	Region string

	// Reverse geocoding fields

	// LatLng is the textual latitude/longitude value for which you wish to obtain the closest, human-readable address. Either LatLng or PlaceID is required for Reverse Geocoding.
	LatLng *LatLng
	// ResultType is an array of one or more address types. Optional.
	ResultType []string
	// LocationType is an array of one or more geocoding accuracy types. Optional.
	LocationType []GeocodeAccuracy
	// PlaceID is a string which contains the place_id, which can be used for reverse geocoding requests. Either LatLng or PlaceID is required for Reverse Geocoding.
	PlaceID string

	// Language is the language in which to return results. Optional.
	Language string

	// Custom allows passing through custom parameters to the Geocoding back end. Use with caution.
	// For more detail on why this is required, please see
	// https://googlegeodevelopers.blogspot.com/2016/11/address-geocoding-in-google-maps-apis.html
	Custom url.Values
}

// GeocodingResult is a single geocoded address
type GeocodingResult struct {
	AddressComponents []AddressComponent `json:"address_components"`
	FormattedAddress  string             `json:"formatted_address"`
	Geometry          AddressGeometry    `json:"geometry"`
	Types             []string           `json:"types"`
	PlaceID           string             `json:"place_id"`
}

// AddressComponent is a part of an address
type AddressComponent struct {
	LongName  string   `json:"long_name"`
	ShortName string   `json:"short_name"`
	Types     []string `json:"types"`
}

// AddressGeometry is the location of a an address
type AddressGeometry struct {
	Location     LatLng       `json:"location"`
	LocationType string       `json:"location_type"`
	Bounds       LatLngBounds `json:"bounds"`
	Viewport     LatLngBounds `json:"viewport"`
	Types        []string     `json:"types"`
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os/user"

	flag "github.com/docker/docker/pkg/mflag"
)

type Config struct {
	BuildFlags string `json:"build_flags,omitempty"`
	AuthToken  string `json:"auth_token"`
}

// initialize flags
var (
	// Config needs to be initted in init()
	ConfigPath  *string
	BuildFlags  = flag.String([]string{"b", "-buildflags"}, "", "Pass build flags to gox")
	ForceCreate = flag.Bool([]string{"f", "-force"}, false, "Replace the asset if it already exists")
	AssetName   = flag.String([]string{"n", "-name"}, "", "Set the name for the release asset")
	Prerelease  = flag.Bool([]string{"p", "-prerelease"}, false, "With -create, create as a dev release")
	ReleaseName = flag.String([]string{"r", "-release"}, "", "Create the release if it does not exist and set the release name")
	Version     = flag.Bool([]string{"v", "-version"}, false, "Print the name and version")
)

func init() {
	CurrentUser, _ := user.Current()
	DefaultConfigPath := fmt.Sprintf("%s/.config/ghrelease/config.json", CurrentUser.HomeDir)
	ConfigPath = flag.String([]string{"c", "-config"}, DefaultConfigPath, "Set ghrelease config file")

	flag.Parse()
}

func LoadConfig(ConfigPath *string) {
	var ret Config
	ConfigFile, err := ioutil.ReadFile(*ConfigPath)
	err := json.Unmarshal(ConfigFile, &ret)
	if err != nil {
		log.Fatalln(err)
	}
	return ret
}

func main() {
}
<commit_msg>set return type<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os/user"

	flag "github.com/docker/docker/pkg/mflag"
)

type Config struct {
	BuildFlags string `json:"build_flags,omitempty"`
	AuthToken  string `json:"auth_token"`
}

// initialize flags
var (
	// Config needs to be initted in init()
	ConfigPath  *string
	BuildFlags  = flag.String([]string{"b", "-buildflags"}, "", "Pass build flags to gox")
	ForceCreate = flag.Bool([]string{"f", "-force"}, false, "Replace the asset if it already exists")
	AssetName   = flag.String([]string{"n", "-name"}, "", "Set the name for the release asset")
	Prerelease  = flag.Bool([]string{"p", "-prerelease"}, false, "With -create, create as a dev release")
	ReleaseName = flag.String([]string{"r", "-release"}, "", "Create the release if it does not exist and set the release name")
	Version     = flag.Bool([]string{"v", "-version"}, false, "Print the name and version")
)

func init() {
	CurrentUser, _ := user.Current()
	DefaultConfigPath := fmt.Sprintf("%s/.config/ghrelease/config.json", CurrentUser.HomeDir)
	ConfigPath = flag.String([]string{"c", "-config"}, DefaultConfigPath, "Set ghrelease config file")

	flag.Parse()
}

func LoadConfig(ConfigPath *string) Config {
	var ret Config
	ConfigFile, err := ioutil.ReadFile(*ConfigPath)
	err := json.Unmarshal(ConfigFile, &ret)
	if err != nil {
		log.Fatalln(err)
	}
	return ret
}

func main() {
}
<|endoftext|>


<commit_before>package gps

import (
	"strings"
	"fmt"
	"log"
	"strconv"
)

// func validateNMEAChecksum determines if a string is a properly formatted NMEA sentence with a valid checksum.
//
// If the input string is valid, output is the input stripped of the "$" token and checksum, along with a boolean 'true'
// If the input string is the incorrect format, the checksum is missing/invalid, or checksum calculation fails, an error string and
// boolean 'false' are returned
//
// Checksum is calculated as XOR of all bytes between "$" and "*"
func validateNMEAChecksum(s string) (string, bool) {
	//validate format. NMEA sentences start with "$" and end in "*xx" where xx is the XOR value of all bytes between
	if !(strings.HasPrefix(s, "$") && strings.Contains(s, "*")) {
		return "Invalid NMEA message", false
	}

	// strip leading "$" and split at "*"
	s_split := strings.Split(strings.TrimPrefix(s, "$"), "*")
	s_out := s_split[0]
	s_cs := s_split[1]

	if len(s_cs) < 2 {
		return "Missing checksum. Fewer than two bytes after asterisk", false
	}

	cs, err := strconv.ParseUint(s_cs[:2], 16, 8)
	if err != nil {
		return "Invalid checksum", false
	}

	cs_calc := byte(0)
	for i := range s_out {
		cs_calc = cs_calc ^ byte(s_out[i])
	}

	if cs_calc != byte(cs) {
		return fmt.Sprintf("Checksum failed. Calculated %#X; expected %#X", cs_calc, cs), false
	}

	return s_out, true
}

func createChecksummedNMEASentence(raw []byte) []byte {
	cs_calc := byte(0)
	for _,v := range raw {
		cs_calc ^= v
	}

	return []byte(fmt.Sprintf("$%s*%02X\r\n", raw, cs_calc))
}

func processNMEASentence(line string) {
	sentence, valid := validateNMEAChecksum(line)
	if !valid {
		log.Printf("GPS Error: invalid NMEA string: %s\n", sentence)
		return
	}

	//log.Printf("Begin parse of %s\n", sentence)
	message := ParseMessage(sentence)
}

type NMEA struct {
	Sentence string
	Tokens []string
}

func ParseMessage(sentence string) *NMEA {
	n := &NMEA{ sentence, strings.Split(sentence, ",") }

	log.Printf("NMEA Message type %s, data: %v\n", Tokens[0], Tokens[1:])
}

<commit_msg>fixes<commit_after>package gps

import (
	"strings"
	"fmt"
	"log"
	"strconv"
)

// func validateNMEAChecksum determines if a string is a properly formatted NMEA sentence with a valid checksum.
//
// If the input string is valid, output is the input stripped of the "$" token and checksum, along with a boolean 'true'
// If the input string is the incorrect format, the checksum is missing/invalid, or checksum calculation fails, an error string and
// boolean 'false' are returned
//
// Checksum is calculated as XOR of all bytes between "$" and "*"
func validateNMEAChecksum(s string) (string, bool) {
	//validate format. NMEA sentences start with "$" and end in "*xx" where xx is the XOR value of all bytes between
	if !(strings.HasPrefix(s, "$") && strings.Contains(s, "*")) {
		return "Invalid NMEA message", false
	}

	// strip leading "$" and split at "*"
	s_split := strings.Split(strings.TrimPrefix(s, "$"), "*")
	s_out := s_split[0]
	s_cs := s_split[1]

	if len(s_cs) < 2 {
		return "Missing checksum. Fewer than two bytes after asterisk", false
	}

	cs, err := strconv.ParseUint(s_cs[:2], 16, 8)
	if err != nil {
		return "Invalid checksum", false
	}

	cs_calc := byte(0)
	for i := range s_out {
		cs_calc = cs_calc ^ byte(s_out[i])
	}

	if cs_calc != byte(cs) {
		return fmt.Sprintf("Checksum failed. Calculated %#X; expected %#X", cs_calc, cs), false
	}

	return s_out, true
}

func createChecksummedNMEASentence(raw []byte) []byte {
	cs_calc := byte(0)
	for _,v := range raw {
		cs_calc ^= v
	}

	return []byte(fmt.Sprintf("$%s*%02X\r\n", raw, cs_calc))
}

func processNMEASentence(line string) {
	sentence, valid := validateNMEAChecksum(line)
	if !valid {
		log.Printf("GPS Error: invalid NMEA string: %s\n", sentence)
		return
	}

	//log.Printf("Begin parse of %s\n", sentence)
	ParseMessage(sentence)
}

type NMEA struct {
	Sentence string
	Tokens []string
}

func ParseMessage(sentence string) *NMEA {
	n := &NMEA{ sentence, strings.Split(sentence, ",") }

	log.Printf("NMEA Message type %s, data: %v\n", n.Tokens[0], n.Tokens[1:])

	return n
}

<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/codegangsta/cli"
	"io/ioutil"
	"os"
)

var colors []string

type InputNode struct {
	Id      string   `json:"id"`
	Parents []string `json:"parents"`
}

// Type:
// 0: |
// 1: ┘
// 2: ┐
// 3: ┌
type Point struct {
	X    int `json:"x"`
	Y    int `json:"y"`
	Type int `json:"type"`
}

type Path struct {
	Id    string  `json:"id"`
	Path  []Point `json:"path"`
	Color string  `json:"color"`
}

type OutputNode struct {
	Id                string          `json:"id"`
	Parents           []string        `json:"parents"`
	Column            int             `json:"column"`
	ParentsPaths      map[string]Path `json:"-"`
	FinalParentsPaths []Path          `json:"parents_paths"`
	Idx               int             `json:"idx"`
	Children          []string        `json:"-"`
	Color             string          `json:"color"`
}

func (node *OutputNode) Append(parentId string, point Point) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path, point)
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) Remove(parentId string, idx int) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path[:idx], tmp.Path[idx+1:]...)
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) Insert(parentId string, idx int, point Point) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path, Point{})
	copy(tmp.Path[idx+1:], tmp.Path[idx:])
	tmp.Path[idx] = point
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) SetPathColor(parentId, color string) {
	tmp := node.ParentsPaths[parentId]
	tmp.Color = color
	node.ParentsPaths[parentId] = tmp
}

func serializeOutput(out []*OutputNode) ([]byte, error) {
	for _, node := range out {
		for parentId, path := range node.ParentsPaths {
			node.FinalParentsPaths = append(node.FinalParentsPaths, Path{parentId, path.Path, path.Color})
		}
	}
	treeBytes, err := json.Marshal(&out)
	return treeBytes, err
}

func getInputNodesFromJson(inputJson string) (nodes []InputNode, err error) {
	if err = json.Unmarshal([]byte(inputJson), &nodes); err != nil {
		return
	}
	return
}

func initNodes(inputNodes []InputNode) []*OutputNode {
	out := make([]*OutputNode, 0)
	for idx, node := range inputNodes {
		newNode := OutputNode{}
		newNode.Id = node.Id
		newNode.Parents = node.Parents
		newNode.Column = -1
		newNode.ParentsPaths = make(map[string]Path)
		newNode.FinalParentsPaths = make([]Path, 0)
		newNode.Idx = idx
		newNode.Children = make([]string, 0)
		out = append(out, &newNode)
	}
	return out
}

func initIndex(nodes []*OutputNode) map[string]*OutputNode {
	index := make(map[string]*OutputNode)
	for _, node := range nodes {
		index[node.Id] = node
	}
	return index
}

func initChildren(nodes []*OutputNode, index map[string]*OutputNode) {
	for _, node := range nodes {
		for _, parentId := range node.Parents {
			index[parentId].Children = append(index[parentId].Children, node.Id)
		}
	}
}

func setColumns(nodes []*OutputNode, index map[string]*OutputNode) {
	nextColumn := 0
	for _, node := range nodes {
		if node.Column == -1 {
			node.Column = nextColumn
			node.Color, colors = colors[0], colors[1:]
			nextColumn++
		}

		for _, childId := range node.Children {
			child := index[childId]
			if node.Column < child.Column {
				nextColumn--
				child.SetPathColor(node.Id, child.Color)
				colors = append([]string{child.Color}, colors...)

				if child.Parents[0] != node.Id || len(child.Parents) <= 1 {
					// Insert before the last element
					pos := len(child.ParentsPaths[node.Id].Path) - 1
					point := Point{child.ParentsPaths[node.Id].Path[pos-1].X, node.Idx, 1}
					child.Insert(node.Id, pos, point)

					for followingNodeIdx, followingNode := range nodes {
						if followingNodeIdx > node.Idx {
							if followingNode.Column > child.Column {

								for _, followingNodeChildId := range followingNode.Children {
									followingNodeChild := index[followingNodeChildId]

									idxRemove := len(followingNodeChild.ParentsPaths[followingNode.Id].Path) - 1
									followingNodeChild.Remove(followingNode.Id, idxRemove)

									pos := len(followingNodeChild.ParentsPaths[followingNode.Id].Path) - 1
									followingNodeChild.Append(followingNode.Id, Point{followingNodeChild.ParentsPaths[followingNode.Id].Path[pos].X, node.Idx, 1})
									followingNodeChild.Append(followingNode.Id, Point{followingNode.Column - 1, node.Idx, 0})
									followingNodeChild.Append(followingNode.Id, Point{followingNode.Column - 1, followingNode.Idx, 0})
								}

								followingNode.Column--
							}
						}
					}
				}
			}
		}

		for parentIdx, parentId := range node.Parents {
			parent := index[parentId]

			node.Append(parent.Id, Point{node.Column, node.Idx, 0})

			if parent.Column == -1 {
				if parentIdx == 0 || (parentIdx == 1 && index[node.Parents[0]].Column < node.Column) {
					parent.Column = node.Column
				} else {
					parent.Column = nextColumn
					parent.Color, colors = colors[0], colors[1:]
					node.Append(parent.Id, Point{parent.Column, node.Idx, 2})
					node.SetPathColor(parent.Id, parent.Color)
					nextColumn++
				}
			} else {
				if node.Column < parent.Column && parentIdx == 0 {
					for _, childId := range parent.Children {
						child := index[childId]
						idxRemove := len(child.ParentsPaths[parent.Id].Path) - 1
						if idxRemove > 0 {
							if child.ParentsPaths[parent.Id].Path[idxRemove].Type != 2 {
								child.Remove(parent.Id, idxRemove)
							}
							child.Append(parent.Id, Point{node.Column, parent.Idx, 0})
						}
					}
					parent.Column = node.Column
				} else if node.Column > parent.Column {
					if node.Parents[0] == parent.Id && len(node.Parents) > 1 {
						node.Append(parent.Id, Point{parent.Column, node.Idx, 3})
					}
				}
			}

			node.Append(parent.Id, Point{parent.Column, parent.Idx, 0})

		}
	}
}

func buildTree(inputNodes []InputNode) ([]*OutputNode, error) {
	colors = []string{"#5aa1be", "#c065b8", "#c0ab5f", "#59bc95", "#c0615b", "#7a63be", "#73bb5e", "#6ee585", "#7088e8", "#eb77a3"}
	var nodes []*OutputNode = initNodes(inputNodes)
	var index map[string]*OutputNode = initIndex(nodes)

	initChildren(nodes, index)
	setColumns(nodes, index)

	return nodes, nil
}

func BuildTreeJson(inputJson string) (tree string, err error) {
	nodes, err := getInputNodesFromJson(inputJson)
	if err != nil {
		return
	}

	out, err := buildTree(nodes)
	if err != nil {
		return
	}

	treeBytes, err := serializeOutput(out)
	if err != nil {
		return
	}
	tree = string(treeBytes)
	return
}

func bootstrap(c *cli.Context) {
	var inputJson string
	jsonFlag := c.String("json")
	fileFlag := c.String("file")
	if jsonFlag != "" {
		inputJson = jsonFlag
	} else if fileFlag != "" {
		bytes, err := ioutil.ReadFile(fileFlag)
		if err != nil {
			fmt.Println(err)
			return
		}
		inputJson = string(bytes)
	} else {
		cli.ShowAppHelp(c)
		return
	}

	out, err := BuildTreeJson(inputJson)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(out)
}

func main() {
	var authors []cli.Author
	// Collaborators, add your name here :)
	authors = append(authors, cli.Author{"Alain Gilbert", "alain.gilbert.15@gmail.com"})

	app := cli.NewApp()
	app.Authors = authors
	app.Version = "0.0.0"
	app.Name = "git2graph"
	app.Usage = "Take a git tree, make a graph structure"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "f, file",
			Usage: "File",
		},
		cli.StringFlag{
			Name:  "j, json",
			Usage: "Json input",
		},
	}
	app.Action = bootstrap
	app.Run(os.Args)
}
<commit_msg>Fix some color bugs<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/codegangsta/cli"
	"io/ioutil"
	"os"
)

var colors []string

type InputNode struct {
	Id      string   `json:"id"`
	Parents []string `json:"parents"`
}

// Type:
// 0: |
// 1: ┘
// 2: ┐
// 3: ┌
type Point struct {
	X    int `json:"x"`
	Y    int `json:"y"`
	Type int `json:"type"`
}

type Path struct {
	Id    string  `json:"id"`
	Path  []Point `json:"path"`
	Color string  `json:"color"`
}

type OutputNode struct {
	Id                string          `json:"id"`
	Parents           []string        `json:"parents"`
	Column            int             `json:"column"`
	ParentsPaths      map[string]Path `json:"-"`
	FinalParentsPaths []Path          `json:"parents_paths"`
	Idx               int             `json:"idx"`
	Children          []string        `json:"-"`
	Color             string          `json:"color"`
}

func (node *OutputNode) Append(parentId string, point Point) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path, point)
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) Remove(parentId string, idx int) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path[:idx], tmp.Path[idx+1:]...)
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) Insert(parentId string, idx int, point Point) {
	tmp := node.ParentsPaths[parentId]
	tmp.Path = append(tmp.Path, Point{})
	copy(tmp.Path[idx+1:], tmp.Path[idx:])
	tmp.Path[idx] = point
	node.ParentsPaths[parentId] = tmp
}

func (node *OutputNode) SetPathColor(parentId, color string) {
	tmp := node.ParentsPaths[parentId]
	tmp.Color = color
	node.ParentsPaths[parentId] = tmp
}

func serializeOutput(out []*OutputNode) ([]byte, error) {
	for _, node := range out {
		for parentId, path := range node.ParentsPaths {
			node.FinalParentsPaths = append(node.FinalParentsPaths, Path{parentId, path.Path, path.Color})
		}
	}
	treeBytes, err := json.Marshal(&out)
	return treeBytes, err
}

func getInputNodesFromJson(inputJson string) (nodes []InputNode, err error) {
	if err = json.Unmarshal([]byte(inputJson), &nodes); err != nil {
		return
	}
	return
}

func initNodes(inputNodes []InputNode) []*OutputNode {
	out := make([]*OutputNode, 0)
	for idx, node := range inputNodes {
		newNode := OutputNode{}
		newNode.Id = node.Id
		newNode.Parents = node.Parents
		newNode.Column = -1
		newNode.ParentsPaths = make(map[string]Path)
		newNode.FinalParentsPaths = make([]Path, 0)
		newNode.Idx = idx
		newNode.Children = make([]string, 0)
		out = append(out, &newNode)
	}
	return out
}

func initIndex(nodes []*OutputNode) map[string]*OutputNode {
	index := make(map[string]*OutputNode)
	for _, node := range nodes {
		index[node.Id] = node
	}
	return index
}

func initChildren(nodes []*OutputNode, index map[string]*OutputNode) {
	for _, node := range nodes {
		for _, parentId := range node.Parents {
			index[parentId].Children = append(index[parentId].Children, node.Id)
		}
	}
}

func setColumns(nodes []*OutputNode, index map[string]*OutputNode) {
	nextColumn := 0
	for _, node := range nodes {
		if node.Column == -1 {
			node.Column = nextColumn
			node.Color, colors = colors[0], colors[1:]
			nextColumn++
		}

		for _, childId := range node.Children {
			child := index[childId]
			if node.Column < child.Column {
				nextColumn--
				child.SetPathColor(node.Id, child.Color)
				colors = append(colors[:1], append([]string{child.Color}, colors[1:]...)...)

				if child.Parents[0] != node.Id || len(child.Parents) <= 1 {
					// Insert before the last element
					pos := len(child.ParentsPaths[node.Id].Path) - 1
					point := Point{child.ParentsPaths[node.Id].Path[pos-1].X, node.Idx, 1}
					child.Insert(node.Id, pos, point)

					for followingNodeIdx, followingNode := range nodes {
						if followingNodeIdx > node.Idx {
							if followingNode.Column > child.Column {

								for _, followingNodeChildId := range followingNode.Children {
									followingNodeChild := index[followingNodeChildId]

									idxRemove := len(followingNodeChild.ParentsPaths[followingNode.Id].Path) - 1
									followingNodeChild.Remove(followingNode.Id, idxRemove)

									pos := len(followingNodeChild.ParentsPaths[followingNode.Id].Path) - 1
									followingNodeChild.Append(followingNode.Id, Point{followingNodeChild.ParentsPaths[followingNode.Id].Path[pos].X, node.Idx, 1})
									followingNodeChild.Append(followingNode.Id, Point{followingNode.Column - 1, node.Idx, 0})
									followingNodeChild.Append(followingNode.Id, Point{followingNode.Column - 1, followingNode.Idx, 0})
								}

								followingNode.Column--
							}
						}
					}
				}
			}
		}

		for parentIdx, parentId := range node.Parents {
			parent := index[parentId]

			node.Append(parent.Id, Point{node.Column, node.Idx, 0})

			if parent.Column == -1 {
				if parentIdx == 0 || (parentIdx == 1 && index[node.Parents[0]].Column < node.Column) {
					parent.Column = node.Column
				} else {
					parent.Column = nextColumn
					parent.Color, colors = colors[0], colors[1:]
					node.Append(parent.Id, Point{parent.Column, node.Idx, 2})
					node.SetPathColor(parent.Id, parent.Color)
					nextColumn++
				}
			} else {
				if node.Column < parent.Column && parentIdx == 0 {
					for _, childId := range parent.Children {
						child := index[childId]
						idxRemove := len(child.ParentsPaths[parent.Id].Path) - 1
						if idxRemove > 0 {
							if child.ParentsPaths[parent.Id].Path[idxRemove].Type != 2 {
								child.Remove(parent.Id, idxRemove)
							}
							child.Append(parent.Id, Point{node.Column, parent.Idx, 0})
						}
					}
					parent.Column = node.Column
					parent.Color = node.Color
				} else if node.Column > parent.Column {
					if node.Parents[0] == parent.Id && len(node.Parents) > 1 {
						node.Append(parent.Id, Point{parent.Column, node.Idx, 3})
					}
				}
			}

			node.Append(parent.Id, Point{parent.Column, parent.Idx, 0})

		}
	}
}

func buildTree(inputNodes []InputNode) ([]*OutputNode, error) {
	colors = []string{"#5aa1be", "#c065b8", "#c0ab5f", "#59bc95", "#c0615b", "#7a63be", "#73bb5e", "#6ee585", "#7088e8", "#eb77a3"}
	var nodes []*OutputNode = initNodes(inputNodes)
	var index map[string]*OutputNode = initIndex(nodes)

	initChildren(nodes, index)
	setColumns(nodes, index)

	return nodes, nil
}

func BuildTreeJson(inputJson string) (tree string, err error) {
	nodes, err := getInputNodesFromJson(inputJson)
	if err != nil {
		return
	}

	out, err := buildTree(nodes)
	if err != nil {
		return
	}

	treeBytes, err := serializeOutput(out)
	if err != nil {
		return
	}
	tree = string(treeBytes)
	return
}

func bootstrap(c *cli.Context) {
	var inputJson string
	jsonFlag := c.String("json")
	fileFlag := c.String("file")
	if jsonFlag != "" {
		inputJson = jsonFlag
	} else if fileFlag != "" {
		bytes, err := ioutil.ReadFile(fileFlag)
		if err != nil {
			fmt.Println(err)
			return
		}
		inputJson = string(bytes)
	} else {
		cli.ShowAppHelp(c)
		return
	}

	out, err := BuildTreeJson(inputJson)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(out)
}

func main() {
	var authors []cli.Author
	// Collaborators, add your name here :)
	authors = append(authors, cli.Author{"Alain Gilbert", "alain.gilbert.15@gmail.com"})

	app := cli.NewApp()
	app.Authors = authors
	app.Version = "0.0.0"
	app.Name = "git2graph"
	app.Usage = "Take a git tree, make a graph structure"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "f, file",
			Usage: "File",
		},
		cli.StringFlag{
			Name:  "j, json",
			Usage: "Json input",
		},
	}
	app.Action = bootstrap
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire_test

import (
	"bytes"
	"io"
)

// fixedWriter implements the io.Writer interface and intentially allows
// testing of error paths by forcing short writes.
type fixedWriter struct {
	b   []byte
	pos int
}

// Write ...
func (w *fixedWriter) Write(p []byte) (n int, err error) {
	lenp := len(p)
	if w.pos+lenp > cap(w.b) {
		return 0, io.ErrShortWrite
	}
	n = lenp
	w.pos += copy(w.b[w.pos:], p)
	return
}

// Bytes ...
func (w *fixedWriter) Bytes() []byte {
	return w.b
}

// newFixedWriter...
func newFixedWriter(max int) *fixedWriter {
	b := make([]byte, max, max)
	fw := fixedWriter{b, 0}
	return &fw
}

// fixedReader implements the io.Reader interface and intentially allows
// testing of error paths by forcing short reads.
type fixedReader struct {
	buf   []byte
	pos   int
	iobuf *bytes.Buffer
}

// Read ....
func (fr *fixedReader) Read(p []byte) (n int, err error) {
	n, err = fr.iobuf.Read(p)
	fr.pos += n
	return
}

// newFixedReader ...
func newFixedReader(max int, buf []byte) *fixedReader {
	b := make([]byte, max, max)
	if buf != nil {
		copy(b[:], buf)
	}

	iobuf := bytes.NewBuffer(b)
	fr := fixedReader{b, 0, iobuf}
	return &fr
}
<commit_msg>Finish uncompleted comments in fixedIO_test.go.<commit_after>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire_test

import (
	"bytes"
	"io"
)

// fixedWriter implements the io.Writer interface and intentially allows
// testing of error paths by forcing short writes.
type fixedWriter struct {
	b   []byte
	pos int
}

// Write writes the contents of p to w.  When the contents of p would cause
// the writer to exceed the maximum allowed size of the fixed writer,
// io.ErrShortWrite is returned and the writer is left unchanged.
//
// This satisfies the io.Writer interface.
func (w *fixedWriter) Write(p []byte) (n int, err error) {
	lenp := len(p)
	if w.pos+lenp > cap(w.b) {
		return 0, io.ErrShortWrite
	}
	n = lenp
	w.pos += copy(w.b[w.pos:], p)
	return
}

// Bytes returns the bytes alreayd written to the fixed writer.
func (w *fixedWriter) Bytes() []byte {
	return w.b
}

// newFixedWriter returns a new io.Writer that will error once more bytes than
// the specified max have been written.
func newFixedWriter(max int) io.Writer {
	b := make([]byte, max, max)
	fw := fixedWriter{b, 0}
	return &fw
}

// fixedReader implements the io.Reader interface and intentially allows
// testing of error paths by forcing short reads.
type fixedReader struct {
	buf   []byte
	pos   int
	iobuf *bytes.Buffer
}

// Read reads the next len(p) bytes from the fixed reader.  When the number of
// bytes read would exceed the maximum number of allowed bytes to be read from
// the fixed writer, an error is returned.
//
// This satisfies the io.Reader interface.
func (fr *fixedReader) Read(p []byte) (n int, err error) {
	n, err = fr.iobuf.Read(p)
	fr.pos += n
	return
}

// newFixedReader returns a new io.Reader that will error once more bytes than
// the specified max have been read.
func newFixedReader(max int, buf []byte) io.Reader {
	b := make([]byte, max, max)
	if buf != nil {
		copy(b[:], buf)
	}

	iobuf := bytes.NewBuffer(b)
	fr := fixedReader{b, 0, iobuf}
	return &fr
}
<|endoftext|>


<commit_before>/*
Copyright 2014 Google Inc. All rights reserved.

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 testapi provides a helper for retrieving the KUBE_API_VERSION environment variable.
package testapi

import (
	"os"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

// Version returns the API version to test against, as set by the KUBE_API_VERSION env var.
func Version() string {
	version := os.Getenv("KUBE_API_VERSION")
	if version == "" {
		version = latest.Version
	}
	return version
}

// Codec returns the codec for the API version to test against, as set by the
// KUBE_API_VERSION env var.
func Codec() runtime.Codec {
	interfaces, err := latest.InterfacesFor(Version())
	if err != nil {
		panic(err)
	}
	return interfaces.Codec
}

// ResourceVersioner returns the ResourceVersioner for the API version to test against,
// as set by the KUBE_API_VERSION env var.
func ResourceVersioner() runtime.ResourceVersioner {
	interfaces, err := latest.InterfacesFor(Version())
	if err != nil {
		panic(err)
	}
	return interfaces.ResourceVersioner
}
<commit_msg>Make scheduler emit events<commit_after>/*
Copyright 2014 Google Inc. All rights reserved.

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 testapi provides a helper for retrieving the KUBE_API_VERSION environment variable.
package testapi

import (
	"fmt"
	"os"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

// Version returns the API version to test against, as set by the KUBE_API_VERSION env var.
func Version() string {
	version := os.Getenv("KUBE_API_VERSION")
	if version == "" {
		version = latest.Version
	}
	return version
}

// Codec returns the codec for the API version to test against, as set by the
// KUBE_API_VERSION env var.
func Codec() runtime.Codec {
	interfaces, err := latest.InterfacesFor(Version())
	if err != nil {
		panic(err)
	}
	return interfaces.Codec
}

// ResourceVersioner returns the ResourceVersioner for the API version to test against,
// as set by the KUBE_API_VERSION env var.
func ResourceVersioner() runtime.ResourceVersioner {
	interfaces, err := latest.InterfacesFor(Version())
	if err != nil {
		panic(err)
	}
	return interfaces.ResourceVersioner
}

// SelfLink returns a self link that will appear to be for the version Version().
// 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be
// empty for lists.
func SelfLink(resource, name string) string {
	if name == "" {
		return fmt.Sprintf("/api/%s/%s", Version(), resource)
	}
	return fmt.Sprintf("/api/%s/%s/%s", Version(), resource, name)
}
<|endoftext|>


<commit_before>/*
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 version

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/spf13/cobra"
	"sigs.k8s.io/yaml"

	apimachineryversion "k8s.io/apimachinery/pkg/version"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/component-base/version"
	cmdutil "k8s.io/kubectl/pkg/cmd/util"
	"k8s.io/kubectl/pkg/util/i18n"
	"k8s.io/kubectl/pkg/util/templates"
)

// Version is a struct for version information
type Version struct {
	ClientVersion *apimachineryversion.Info `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"`
	ServerVersion *apimachineryversion.Info `json:"serverVersion,omitempty" yaml:"serverVersion,omitempty"`
}

var (
	versionExample = templates.Examples(i18n.T(`
		# Print the client and server versions for the current context
		kubectl version`))
)

// Options is a struct to support version command
type Options struct {
	ClientOnly bool
	Short      bool
	Output     string

	discoveryClient discovery.CachedDiscoveryInterface

	genericclioptions.IOStreams
}

// NewOptions returns initialized Options
func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
	return &Options{
		IOStreams: ioStreams,
	}

}

// NewCmdVersion returns a cobra command for fetching versions
func NewCmdVersion(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
	o := NewOptions(ioStreams)
	cmd := &cobra.Command{
		Use:     "version",
		Short:   i18n.T("Print the client and server version information"),
		Long:    i18n.T("Print the client and server version information for the current context."),
		Example: versionExample,
		Run: func(cmd *cobra.Command, args []string) {
			cmdutil.CheckErr(o.Complete(f, cmd))
			cmdutil.CheckErr(o.Validate(args))
			cmdutil.CheckErr(o.Run())
		},
	}
	cmd.Flags().BoolVar(&o.ClientOnly, "client", o.ClientOnly, "If true, shows client version only (no server required).")
	cmd.Flags().BoolVar(&o.Short, "short", o.Short, "If true, print just the version number.")
	cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "One of 'yaml' or 'json'.")
	return cmd
}

// Complete completes all the required options
func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
	var err error
	if o.ClientOnly {
		return nil
	}
	o.discoveryClient, err = f.ToDiscoveryClient()
	// if we had an empty rest.Config, continue and just print out client information.
	// if we had an error other than being unable to build a rest.Config, fail.
	if err != nil && !clientcmd.IsEmptyConfig(err) {
		return err
	}
	return nil
}

// Validate validates the provided options
func (o *Options) Validate(args []string) error {
	if len(args) != 0 {
		return errors.New(fmt.Sprintf("extra arguments: %v", args))
	}

	if o.Output != "" && o.Output != "yaml" && o.Output != "json" {
		return errors.New(`--output must be 'yaml' or 'json'`)
	}

	return nil
}

// Run executes version command
func (o *Options) Run() error {
	var (
		serverVersion *apimachineryversion.Info
		serverErr     error
		versionInfo   Version
	)

	clientVersion := version.Get()
	versionInfo.ClientVersion = &clientVersion

	if !o.ClientOnly && o.discoveryClient != nil {
		// Always request fresh data from the server
		o.discoveryClient.Invalidate()
		serverVersion, serverErr = o.discoveryClient.ServerVersion()
		versionInfo.ServerVersion = serverVersion
	}

	switch o.Output {
	case "":
		if o.Short {
			fmt.Fprintf(o.Out, "Client Version: %s\n", clientVersion.GitVersion)
			if serverVersion != nil {
				fmt.Fprintf(o.Out, "Server Version: %s\n", serverVersion.GitVersion)
			}
		} else {
			fmt.Fprintf(o.Out, "Client Version: %#v\n", clientVersion)
			if serverVersion != nil {
				fmt.Fprintf(o.Out, "Server Version: %#v\n", *serverVersion)
			}
		}
	case "yaml":
		marshalled, err := yaml.Marshal(&versionInfo)
		if err != nil {
			return err
		}
		fmt.Fprintln(o.Out, string(marshalled))
	case "json":
		marshalled, err := json.MarshalIndent(&versionInfo, "", "  ")
		if err != nil {
			return err
		}
		fmt.Fprintln(o.Out, string(marshalled))
	default:
		// There is a bug in the program if we hit this case.
		// However, we follow a policy of never panicking.
		return fmt.Errorf("VersionOptions were not validated: --output=%q should have been rejected", o.Output)
	}

	if serverVersion != nil {
		if err := printVersionSkewWarning(o.ErrOut, clientVersion, *serverVersion); err != nil {
			return err
		}
	}

	return serverErr
}
<commit_msg>kubectl version should include bundled kustomize version<commit_after>/*
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 version

import (
	"encoding/json"
	"errors"
	"fmt"
	"runtime/debug"

	"github.com/spf13/cobra"
	"sigs.k8s.io/yaml"

	apimachineryversion "k8s.io/apimachinery/pkg/version"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/component-base/version"
	cmdutil "k8s.io/kubectl/pkg/cmd/util"
	"k8s.io/kubectl/pkg/util/i18n"
	"k8s.io/kubectl/pkg/util/templates"
)

// TODO(knverey): remove this hardcoding once kubectl being built with module support makes BuildInfo available.
const kustomizeVersion = "v4.4.1"

// Version is a struct for version information
type Version struct {
	ClientVersion    *apimachineryversion.Info `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"`
	KustomizeVersion string                    `json:"kustomizeVersion,omitempty" yaml:"kustomizeVersion,omitempty"`
	ServerVersion    *apimachineryversion.Info `json:"serverVersion,omitempty" yaml:"serverVersion,omitempty"`
}

var (
	versionExample = templates.Examples(i18n.T(`
		# Print the client and server versions for the current context
		kubectl version`))
)

// Options is a struct to support version command
type Options struct {
	ClientOnly bool
	Short      bool
	Output     string

	discoveryClient discovery.CachedDiscoveryInterface

	genericclioptions.IOStreams
}

// NewOptions returns initialized Options
func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
	return &Options{
		IOStreams: ioStreams,
	}

}

// NewCmdVersion returns a cobra command for fetching versions
func NewCmdVersion(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
	o := NewOptions(ioStreams)
	cmd := &cobra.Command{
		Use:     "version",
		Short:   i18n.T("Print the client and server version information"),
		Long:    i18n.T("Print the client and server version information for the current context."),
		Example: versionExample,
		Run: func(cmd *cobra.Command, args []string) {
			cmdutil.CheckErr(o.Complete(f, cmd))
			cmdutil.CheckErr(o.Validate(args))
			cmdutil.CheckErr(o.Run())
		},
	}
	cmd.Flags().BoolVar(&o.ClientOnly, "client", o.ClientOnly, "If true, shows client version only (no server required).")
	cmd.Flags().BoolVar(&o.Short, "short", o.Short, "If true, print just the version number.")
	cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "One of 'yaml' or 'json'.")
	return cmd
}

// Complete completes all the required options
func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
	var err error
	if o.ClientOnly {
		return nil
	}
	o.discoveryClient, err = f.ToDiscoveryClient()
	// if we had an empty rest.Config, continue and just print out client information.
	// if we had an error other than being unable to build a rest.Config, fail.
	if err != nil && !clientcmd.IsEmptyConfig(err) {
		return err
	}
	return nil
}

// Validate validates the provided options
func (o *Options) Validate(args []string) error {
	if len(args) != 0 {
		return errors.New(fmt.Sprintf("extra arguments: %v", args))
	}

	if o.Output != "" && o.Output != "yaml" && o.Output != "json" {
		return errors.New(`--output must be 'yaml' or 'json'`)
	}

	return nil
}

// Run executes version command
func (o *Options) Run() error {
	var (
		serverErr   error
		versionInfo Version
	)

	versionInfo.ClientVersion = func() *apimachineryversion.Info { v := version.Get(); return &v }()
	versionInfo.KustomizeVersion = getKustomizeVersion()

	if !o.ClientOnly && o.discoveryClient != nil {
		// Always request fresh data from the server
		o.discoveryClient.Invalidate()
		versionInfo.ServerVersion, serverErr = o.discoveryClient.ServerVersion()
	}

	switch o.Output {
	case "":
		if o.Short {
			fmt.Fprintf(o.Out, "Client Version: %s\n", versionInfo.ClientVersion.GitVersion)
			fmt.Fprintf(o.Out, "Kustomize Version: %s\n", versionInfo.KustomizeVersion)
			if versionInfo.ServerVersion != nil {
				fmt.Fprintf(o.Out, "Server Version: %s\n", versionInfo.ServerVersion.GitVersion)
			}
		} else {
			fmt.Fprintf(o.Out, "Client Version: %#v\n", *versionInfo.ClientVersion)
			fmt.Fprintf(o.Out, "Kustomize Version: %s\n", versionInfo.KustomizeVersion)
			if versionInfo.ServerVersion != nil {
				fmt.Fprintf(o.Out, "Server Version: %#v\n", *versionInfo.ServerVersion)
			}
		}
	case "yaml":
		marshalled, err := yaml.Marshal(&versionInfo)
		if err != nil {
			return err
		}
		fmt.Fprintln(o.Out, string(marshalled))
	case "json":
		marshalled, err := json.MarshalIndent(&versionInfo, "", "  ")
		if err != nil {
			return err
		}
		fmt.Fprintln(o.Out, string(marshalled))
	default:
		// There is a bug in the program if we hit this case.
		// However, we follow a policy of never panicking.
		return fmt.Errorf("VersionOptions were not validated: --output=%q should have been rejected", o.Output)
	}

	if versionInfo.ServerVersion != nil {
		if err := printVersionSkewWarning(o.ErrOut, *versionInfo.ClientVersion, *versionInfo.ServerVersion); err != nil {
			return err
		}
	}

	return serverErr
}

func getKustomizeVersion() string {
	info, ok := debug.ReadBuildInfo()
	if !ok {
		return kustomizeVersion
	}
	for _, dep := range info.Deps {
		if dep.Path == "sigs.k8s.io/kustomize/kustomize/v4" {
			return dep.Version
		}
	}
	return kustomizeVersion
}
<|endoftext|>