<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/codegangsta/cli"

	"github.com/cloudfoundry-incubator/candiedyaml"
	"github.com/cloudfoundry-incubator/spiff/compare"
	"github.com/cloudfoundry-incubator/spiff/flow"
	"github.com/cloudfoundry-incubator/spiff/yaml"
)

func main() {
	app := cli.NewApp()
	app.Name = "spiff"
	app.Usage = "BOSH deployment manifest toolkit"
	app.Version = "1.0.2"

	app.Commands = []cli.Command{
		{
			Name:      "merge",
			ShortName: "m",
			Usage:     "merge stub files into a manifest template",
			Action: func(c *cli.Context) {
				if len(c.Args()) < 1 {
					cli.ShowCommandHelp(c, "merge")
					os.Exit(1)
				}

				merge(c.Args()[0], c.Args()[1:])
			},
		},
		{
			Name:      "diff",
			ShortName: "d",
			Usage:     "structurally compare two YAML files",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "separator",
					Usage: "separator to print between diffs",
				},
			},
			Action: func(c *cli.Context) {
				if len(c.Args()) < 2 {
					cli.ShowCommandHelp(c, "diff")
					os.Exit(1)
				}

				diff(c.Args()[0], c.Args()[1], c.String("separator"))
			},
		},
	}

	app.Run(os.Args)
}

func merge(templateFilePath string, stubFilePaths []string) {
	templateFile, err := ioutil.ReadFile(templateFilePath)
	if err != nil {
		log.Fatalln("error reading template:", err)
	}

	templateYAML, err := yaml.Parse(templateFilePath, templateFile)
	if err != nil {
		log.Fatalln("error parsing template:", err)
	}

	stubs := []yaml.Node{}

	for _, stubFilePath := range stubFilePaths {
		stubFile, err := ioutil.ReadFile(stubFilePath)
		if err != nil {
			log.Fatalln("error reading stub:", err)
		}

		stubYAML, err := yaml.Parse(stubFilePath, stubFile)
		if err != nil {
			log.Fatalln("error parsing stub:", err)
		}

		stubs = append(stubs, stubYAML)
	}

	flowed, err := flow.Cascade(templateYAML, stubs...)
	if err != nil {
		log.Fatalln("error generating manifest:", err)
	}

	yaml, err := candiedyaml.Marshal(flowed)
	if err != nil {
		log.Fatalln("error marshalling manifest:", err)
	}

	fmt.Println(string(yaml))
}

func diff(aFilePath, bFilePath string, separator string) {
	aFile, err := ioutil.ReadFile(aFilePath)
	if err != nil {
		log.Fatalln("error reading a:", err)
	}

	aYAML, err := yaml.Parse(aFilePath, aFile)
	if err != nil {
		log.Fatalln("error parsing a:", err)
	}

	bFile, err := ioutil.ReadFile(bFilePath)
	if err != nil {
		log.Fatalln("error reading b:", err)
	}

	bYAML, err := yaml.Parse(bFilePath, bFile)
	if err != nil {
		log.Fatalln("error parsing b:", err)
	}

	diffs := compare.Compare(aYAML, bYAML)

	if len(diffs) == 0 {
		fmt.Println("no differences!")
		return
	}

	for _, diff := range diffs {
		fmt.Println("Difference in", strings.Join(diff.Path, "."))

		if diff.A != nil {
			ayaml, err := candiedyaml.Marshal(diff.A)
			if err != nil {
				panic(err)
			}

			fmt.Printf("  %s has:\n    \x1b[31m%s\x1b[0m\n", aFilePath, strings.Replace(string(ayaml), "\n", "\n    ", -1))
		}

		if diff.B != nil {
			byaml, err := candiedyaml.Marshal(diff.B)
			if err != nil {
				panic(err)
			}

			fmt.Printf("  %s has:\n    \x1b[32m%s\x1b[0m\n", bFilePath, strings.Replace(string(byaml), "\n", "\n    ", -1))
		}

		fmt.Printf(separator)
	}
}
<commit_msg>bump to 1.0.3<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/codegangsta/cli"

	"github.com/cloudfoundry-incubator/candiedyaml"
	"github.com/cloudfoundry-incubator/spiff/compare"
	"github.com/cloudfoundry-incubator/spiff/flow"
	"github.com/cloudfoundry-incubator/spiff/yaml"
)

func main() {
	app := cli.NewApp()
	app.Name = "spiff"
	app.Usage = "BOSH deployment manifest toolkit"
	app.Version = "1.0.3"

	app.Commands = []cli.Command{
		{
			Name:      "merge",
			ShortName: "m",
			Usage:     "merge stub files into a manifest template",
			Action: func(c *cli.Context) {
				if len(c.Args()) < 1 {
					cli.ShowCommandHelp(c, "merge")
					os.Exit(1)
				}

				merge(c.Args()[0], c.Args()[1:])
			},
		},
		{
			Name:      "diff",
			ShortName: "d",
			Usage:     "structurally compare two YAML files",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "separator",
					Usage: "separator to print between diffs",
				},
			},
			Action: func(c *cli.Context) {
				if len(c.Args()) < 2 {
					cli.ShowCommandHelp(c, "diff")
					os.Exit(1)
				}

				diff(c.Args()[0], c.Args()[1], c.String("separator"))
			},
		},
	}

	app.Run(os.Args)
}

func merge(templateFilePath string, stubFilePaths []string) {
	templateFile, err := ioutil.ReadFile(templateFilePath)
	if err != nil {
		log.Fatalln("error reading template:", err)
	}

	templateYAML, err := yaml.Parse(templateFilePath, templateFile)
	if err != nil {
		log.Fatalln("error parsing template:", err)
	}

	stubs := []yaml.Node{}

	for _, stubFilePath := range stubFilePaths {
		stubFile, err := ioutil.ReadFile(stubFilePath)
		if err != nil {
			log.Fatalln("error reading stub:", err)
		}

		stubYAML, err := yaml.Parse(stubFilePath, stubFile)
		if err != nil {
			log.Fatalln("error parsing stub:", err)
		}

		stubs = append(stubs, stubYAML)
	}

	flowed, err := flow.Cascade(templateYAML, stubs...)
	if err != nil {
		log.Fatalln("error generating manifest:", err)
	}

	yaml, err := candiedyaml.Marshal(flowed)
	if err != nil {
		log.Fatalln("error marshalling manifest:", err)
	}

	fmt.Println(string(yaml))
}

func diff(aFilePath, bFilePath string, separator string) {
	aFile, err := ioutil.ReadFile(aFilePath)
	if err != nil {
		log.Fatalln("error reading a:", err)
	}

	aYAML, err := yaml.Parse(aFilePath, aFile)
	if err != nil {
		log.Fatalln("error parsing a:", err)
	}

	bFile, err := ioutil.ReadFile(bFilePath)
	if err != nil {
		log.Fatalln("error reading b:", err)
	}

	bYAML, err := yaml.Parse(bFilePath, bFile)
	if err != nil {
		log.Fatalln("error parsing b:", err)
	}

	diffs := compare.Compare(aYAML, bYAML)

	if len(diffs) == 0 {
		fmt.Println("no differences!")
		return
	}

	for _, diff := range diffs {
		fmt.Println("Difference in", strings.Join(diff.Path, "."))

		if diff.A != nil {
			ayaml, err := candiedyaml.Marshal(diff.A)
			if err != nil {
				panic(err)
			}

			fmt.Printf("  %s has:\n    \x1b[31m%s\x1b[0m\n", aFilePath, strings.Replace(string(ayaml), "\n", "\n    ", -1))
		}

		if diff.B != nil {
			byaml, err := candiedyaml.Marshal(diff.B)
			if err != nil {
				panic(err)
			}

			fmt.Printf("  %s has:\n    \x1b[32m%s\x1b[0m\n", bFilePath, strings.Replace(string(byaml), "\n", "\n    ", -1))
		}

		fmt.Printf(separator)
	}
}
<|endoftext|>


<commit_before>package codegen

import (
	"bytes"
	"testing"
)

func TestHeader(t *testing.T) {
	const (
		pack  = "testpackage"
		title = "test title"
	)
	var (
		imprt   = []*ImportSpec{&ImportSpec{Path: "test"}}
		imports = append(imprt, &ImportSpec{Path: "other"})
	)
	cases := map[string]struct {
		Title    string
		Imports  []*ImportSpec
		Expected string
	}{
		"no-title":      {Expected: noTitleHeader},
		"title":         {Title: title, Expected: titleHeader},
		"single-import": {Imports: imprt, Expected: singleImportHeader},
		"many-imports":  {Imports: imports, Expected: manyImportsHeader},
	}
	for k, tc := range cases {
		buf := new(bytes.Buffer)
		s := Header(tc.Title, "testpackage", tc.Imports)
		s.Render(buf)
		actual := buf.String()
		if actual != tc.Expected {
			t.Errorf("%s: got %#v, expected %#v", k, actual, tc.Expected)
		}
	}
}

const (
	noTitleHeader = `package testpackage

`

	titleHeader = `// Code generated by goagen v2.0.0-wip, command line:
// $ codegen.test
//
// test title
//
// The content of this file is auto-generated, DO NOT MODIFY

package testpackage

`

	singleImportHeader = `package testpackage

import 	"test"

`

	manyImportsHeader = `package testpackage

import (
	"test"
	"other"
)

`
)
<commit_msg>Move constants inside test.<commit_after>package codegen

import (
	"bytes"
	"testing"
)

func TestHeader(t *testing.T) {
	const (
		pack          = "testpackage"
		title         = "test title"
		noTitleHeader = `package testpackage

`
		titleHeader = `// Code generated by goagen v2.0.0-wip, command line:
// $ codegen.test
//
// test title
//
// The content of this file is auto-generated, DO NOT MODIFY

package testpackage

`
		singleImportHeader = `package testpackage

import 	"test"

`
		manyImportsHeader = `package testpackage

import (
	"test"
	"other"
)

`
	)
	var (
		imprt   = []*ImportSpec{&ImportSpec{Path: "test"}}
		imports = append(imprt, &ImportSpec{Path: "other"})
	)
	cases := map[string]struct {
		Title    string
		Imports  []*ImportSpec
		Expected string
	}{
		"no-title":      {Expected: noTitleHeader},
		"title":         {Title: title, Expected: titleHeader},
		"single-import": {Imports: imprt, Expected: singleImportHeader},
		"many-imports":  {Imports: imports, Expected: manyImportsHeader},
	}
	for k, tc := range cases {
		buf := new(bytes.Buffer)
		s := Header(tc.Title, "testpackage", tc.Imports)
		s.Render(buf)
		actual := buf.String()
		if actual != tc.Expected {
			t.Errorf("%s: got %#v, expected %#v", k, actual, tc.Expected)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"math"
	"net"
	"os"
	"strconv"
	"sync"
	"time"

	log "github.com/sirupsen/logrus"
)

// runClient spawns threads for parallel uplink/downlink via TCP
func runClient(connectionType string, codePhrase string) {
	logger := log.WithFields(log.Fields{
		"codePhrase": codePhrase,
		"connection": connectionType,
	})
	var wg sync.WaitGroup
	wg.Add(numberConnections)
	for id := 0; id < numberConnections; id++ {
		go func(id int) {
			defer wg.Done()
			port := strconv.Itoa(27001 + id)
			connection, err := net.Dial("tcp", "localhost:"+port)
			if err != nil {
				panic(err)
			}
			defer connection.Close()

			message := receiveMessage(connection)
			logger.Infof("message: %s", message)
			sendMessage(connectionType+"."+codePhrase, connection)
			if connectionType == "s" {
				logger.Info("waiting for ok from relay")
				message = receiveMessage(connection)
				logger.Info("got ok from relay")
				// wait for pipe to be made
				time.Sleep(1 * time.Second)
				// Send file name
				logger.Info("sending filename")
				sendMessage("filename", connection)
				// Send file size
				time.Sleep(3 * time.Second)
				logger.Info("sending filesize")
				sendMessage("filesize", connection)
				// TODO: Write data from file

				// TODO: Release from connection pool
				// POST /release
			} else {
				fileName := receiveMessage(connection)
				fileSize := receiveMessage(connection)
				logger.Infof("fileName: %s", fileName)
				logger.Infof("fileSize: %s", fileSize)
				// TODO: Pull data and write to file

				// TODO: Release from connection pool
				// POST /release
			}

		}(id)
	}
	wg.Wait()
}

func sendFileToClient(id int, connection net.Conn) {
	logger := log.WithFields(log.Fields{
		"function": "sendFileToClient #" + strconv.Itoa(id),
	})
	defer connection.Close()
	//Open the file that needs to be send to the client
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()
	//Get the filename and filesize
	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return
	}

	numChunks := math.Ceil(float64(fileInfo.Size()) / float64(BUFFERSIZE))
	chunksPerWorker := int(math.Ceil(numChunks / float64(numberConnections)))

	bytesPerConnection := int64(chunksPerWorker * BUFFERSIZE)
	if id+1 == numberConnections {
		bytesPerConnection = fileInfo.Size() - (numberConnections-1)*bytesPerConnection
	}
	fileSize := fillString(strconv.FormatInt(int64(bytesPerConnection), 10), 10)

	fileName := fillString(fileInfo.Name(), 64)

	if id == 0 || id == numberConnections-1 {
		logger.Infof("numChunks: %v", numChunks)
		logger.Infof("chunksPerWorker: %v", chunksPerWorker)
		logger.Infof("bytesPerConnection: %v", bytesPerConnection)
		logger.Infof("fileName: %v", fileInfo.Name())
	}

	logger.Info("sending")
	connection.Write([]byte(fileSize))
	connection.Write([]byte(fileName))
	sendBuffer := make([]byte, BUFFERSIZE)

	chunkI := 0
	for {
		_, err = file.Read(sendBuffer)
		if err == io.EOF {
			//End of file reached, break out of for loop
			logger.Info("EOF")
			break
		}
		if (chunkI >= chunksPerWorker*id && chunkI < chunksPerWorker*id+chunksPerWorker) || (id == numberConnections-1 && chunkI >= chunksPerWorker*id) {
			connection.Write(sendBuffer)
		}
		chunkI++
	}
	fmt.Println("File has been sent, closing connection!")
	return
}
<commit_msg>Added send/receiev<commit_after>package main

import (
	"fmt"
	"io"
	"math"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"

	log "github.com/sirupsen/logrus"
)

// runClient spawns threads for parallel uplink/downlink via TCP
func runClient(connectionType string, codePhrase string) {
	logger := log.WithFields(log.Fields{
		"codePhrase": codePhrase,
		"connection": connectionType,
	})
	var wg sync.WaitGroup
	wg.Add(numberConnections)
	for id := 0; id < numberConnections; id++ {
		go func(id int) {
			defer wg.Done()
			port := strconv.Itoa(27001 + id)
			connection, err := net.Dial("tcp", "localhost:"+port)
			if err != nil {
				panic(err)
			}
			defer connection.Close()

			message := receiveMessage(connection)
			logger.Infof("message: %s", message)
			sendMessage(connectionType+"."+codePhrase, connection)
			if connectionType == "s" { // this is a sender
				logger.Info("waiting for ok from relay")
				message = receiveMessage(connection)
				logger.Info("got ok from relay")
				// wait for pipe to be made
				time.Sleep(1 * time.Second)

				// Write data from file
				sendFileToClient(id, connection)

				// TODO: Release from connection pool
				// POST /release
			} else { // this is a receiver
				// receive file
				receiveFile(id, connection)

				// TODO: Release from connection pool
				// POST /release
			}

		}(id)
	}
	wg.Wait()
}

func receiveFile(id int, connection net.Conn) {
	bufferFileName := make([]byte, 64)
	bufferFileSize := make([]byte, 10)

	connection.Read(bufferFileSize)
	fileSize, _ := strconv.ParseInt(strings.Trim(string(bufferFileSize), ":"), 10, 64)

	connection.Read(bufferFileName)
	fileName = strings.Trim(string(bufferFileName), ":")
	os.Remove(fileName + "." + strconv.Itoa(id))
	newFile, err := os.Create(fileName + "." + strconv.Itoa(id))
	if err != nil {
		panic(err)
	}
	defer newFile.Close()

	var receivedBytes int64
	for {
		if (fileSize - receivedBytes) < BUFFERSIZE {
			io.CopyN(newFile, connection, (fileSize - receivedBytes))
			// Empty the remaining bytes that we don't need from the network buffer
			connection.Read(make([]byte, (receivedBytes+BUFFERSIZE)-fileSize))
			break
		}
		io.CopyN(newFile, connection, BUFFERSIZE)
		//Increment the counter
		receivedBytes += BUFFERSIZE
	}
}

func sendFileToClient(id int, connection net.Conn) {
	logger := log.WithFields(log.Fields{
		"function": "sendFileToClient #" + strconv.Itoa(id),
	})
	defer connection.Close()
	//Open the file that needs to be send to the client
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()
	//Get the filename and filesize
	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return
	}

	numChunks := math.Ceil(float64(fileInfo.Size()) / float64(BUFFERSIZE))
	chunksPerWorker := int(math.Ceil(numChunks / float64(numberConnections)))

	bytesPerConnection := int64(chunksPerWorker * BUFFERSIZE)
	if id+1 == numberConnections {
		bytesPerConnection = fileInfo.Size() - (numberConnections-1)*bytesPerConnection
	}
	fileSize := fillString(strconv.FormatInt(int64(bytesPerConnection), 10), 10)

	fileName := fillString(fileInfo.Name(), 64)

	if id == 0 || id == numberConnections-1 {
		logger.Infof("numChunks: %v", numChunks)
		logger.Infof("chunksPerWorker: %v", chunksPerWorker)
		logger.Infof("bytesPerConnection: %v", bytesPerConnection)
		logger.Infof("fileName: %v", fileInfo.Name())
	}

	logger.Info("sending")
	connection.Write([]byte(fileSize))
	connection.Write([]byte(fileName))
	sendBuffer := make([]byte, BUFFERSIZE)

	chunkI := 0
	for {
		_, err = file.Read(sendBuffer)
		if err == io.EOF {
			//End of file reached, break out of for loop
			logger.Info("EOF")
			break
		}
		if (chunkI >= chunksPerWorker*id && chunkI < chunksPerWorker*id+chunksPerWorker) || (id == numberConnections-1 && chunkI >= chunksPerWorker*id) {
			connection.Write(sendBuffer)
		}
		chunkI++
	}
	fmt.Println("File has been sent, closing connection!")
	return
}
<|endoftext|>


<commit_before>package loader

import (
	"errors"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"github.com/fatih/images/command/flags"
	"github.com/fatih/structs"
	"github.com/koding/multiconfig"
)

var (
	DefaultConfigName = "imagesrc"
)

// Load loads the given config to the rules of images CLI
func Load(conf interface{}, args []string) error {
	// only pass the config's field names arguments
	configArgs := []string{}

	// need to be declared so we can call it recursively :)
	var addFields func(fields []*structs.Field)

	addFields = func(fields []*structs.Field) {
		for _, field := range fields {
			// don't forget nested structs
			if field.Kind() == reflect.Struct {
				addFields(field.Fields())
			}

			fieldName := field.Name()
			fName := strings.ToLower(fieldName)

			val, err := flags.ParseValue(fName, args)
			if err != nil {
				return
			}

			configArgs = append(configArgs, "--"+fName, val)
		}
	}

	addFields(structs.Fields(conf))

	loaders := []multiconfig.Loader{}

	// check for any files
	path, ext, err := discoverConfigPath(DefaultConfigName)
	if err == nil {
		// Choose what while is passed
		switch ext {
		case "json":
			// .imagesrc.json
			loaders = append(loaders, &multiconfig.JSONLoader{Path: path})
		case "toml":
			fallthrough
		default:
			// .imagesrc or .imagesrc.toml
			loaders = append(loaders, &multiconfig.TOMLLoader{Path: path})
		}
	}

	e := &multiconfig.EnvironmentLoader{
		Prefix: "IMAGES",
	}
	f := &multiconfig.FlagLoader{
		Args:      configArgs,
		Flatten:   true,
		EnvPrefix: "IMAGES",
	}
	loaders = append(loaders, e, f)

	l := multiconfig.MultiLoader(loaders...)
	return l.Load(conf)
}

func discoverConfigPath(configName string) (string, string, error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", "", err
	}

	configPath := filepath.Join(cwd, "."+configName)

	if _, err := os.Stat(configPath); err == nil {
		return configPath, "", nil
	}

	// check for .toml
	tomlPath := filepath.Join(cwd, "."+configName+".toml")
	if _, err := os.Stat(tomlPath); err == nil {
		return tomlPath, "toml", nil
	}

	// check for .json
	jsonPath := filepath.Join(cwd, "."+configName+".json")
	if _, err := os.Stat(jsonPath); err == nil {
		return jsonPath, "json", nil
	}

	return "", "", errors.New("couldn't find any .imagesrc file")
}
<commit_msg>loader: just add recent multiconfig changes<commit_after>package loader

import (
	"errors"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"github.com/fatih/images/command/flags"
	"github.com/fatih/structs"
	"github.com/koding/multiconfig"
)

var (
	DefaultConfigName = "imagesrc"
)

// Load loads the given config to the rules of images CLI
func Load(conf interface{}, args []string) error {
	// only pass the config's field names arguments
	configArgs := []string{}

	// need to be declared so we can call it recursively :)
	var addFields func(fields []*structs.Field)

	addFields = func(fields []*structs.Field) {
		for _, field := range fields {
			// don't forget nested structs
			if field.Kind() == reflect.Struct {
				addFields(field.Fields())
			}

			fieldName := field.Name()
			fName := strings.ToLower(fieldName)

			val, err := flags.ParseValue(fName, args)
			if err != nil {
				continue
			}

			configArgs = append(configArgs, "--"+fName, val)
		}
	}
	addFields(structs.Fields(conf))

	loaders := []multiconfig.Loader{}

	// check for any files
	path, ext, err := discoverConfigPath(DefaultConfigName)
	if err == nil {
		// Choose what while is passed
		switch ext {
		case "json":
			// .imagesrc.json
			loaders = append(loaders, &multiconfig.JSONLoader{Path: path})
		case "toml":
			fallthrough
		default:
			// .imagesrc or .imagesrc.toml
			loaders = append(loaders, &multiconfig.TOMLLoader{Path: path})
		}
	}

	e := &multiconfig.EnvironmentLoader{
		Prefix:    "IMAGES",
		CamelCase: true,
	}
	f := &multiconfig.FlagLoader{
		Args:      configArgs,
		Flatten:   true,
		CamelCase: true,
		EnvPrefix: "IMAGES",
	}
	loaders = append(loaders, e, f)

	l := multiconfig.MultiLoader(loaders...)
	return l.Load(conf)
}

func discoverConfigPath(configName string) (string, string, error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", "", err
	}

	configPath := filepath.Join(cwd, "."+configName)

	if _, err := os.Stat(configPath); err == nil {
		return configPath, "", nil
	}

	// check for .toml
	tomlPath := filepath.Join(cwd, "."+configName+".toml")
	if _, err := os.Stat(tomlPath); err == nil {
		return tomlPath, "toml", nil
	}

	// check for .json
	jsonPath := filepath.Join(cwd, "."+configName+".json")
	if _, err := os.Stat(jsonPath); err == nil {
		return jsonPath, "json", nil
	}

	return "", "", errors.New("couldn't find any .imagesrc file")
}
<|endoftext|>


<commit_before>package commands

import (
	"github.com/github/git-media/git"
	"github.com/github/git-media/gitmedia"
	"github.com/github/git-media/gitmediaclient"
	"github.com/github/git-media/pointer"
	"github.com/spf13/cobra"
	"io/ioutil"
	"os"
	"strings"
)

var (
	pushCmd = &cobra.Command{
		Use:   "push",
		Short: "Push files to the media endpoint",
		Run:   pushCommand,
	}
	dryRun       = false
	useStdin     = false
	deleteBranch = "(delete)"
)

// pushCommand is the command that's run via `git media push`. It has two modes
// of operation. The primary mode is run via the git pre-push hook. The pre-push
// hook passes two arguments on the command line:
//   1. Name of the remote to which the push is being done
//   2. URL to which the push is being done
//
// The hook receives commit information on stdin in the form:
//   <local ref> <local sha1> <remote ref> <remote sha1>
//
// In the typical case, pushCommand will get a list of git objects being pushed
// by using the following:
//    git rev-list --objects <local sha1> ^<remote sha1>
//
// If any of those git objects are associated with git media objects, those git
// media objects will be pushed to the git media endpoint.
//
// In the case of pushing a new branch, the list of git objects will be all of
// the git objects in this branch.
//
// In the case of deleting a branch, no attempts to push git media objects will be
// made.
//
// When pushing git media objects, the client will first perform an OPTIONS command
// which will determine not only whether or not the client is authorized, but also
// whether or not that git media endpoint already has the git media object. If it
// does, the object will not be pushed.
//
// The other mode of operation is the dry run mode. In this mode, the repo
// and refspec are passed on the command line. pushCommand will calculate the
// git objects that would be pushed in a similar manner as above and will print
// out each file name.
func pushCommand(cmd *cobra.Command, args []string) {
	var left, right string

	if useStdin {
		refsData, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			Panic(err, "Error reading refs on stdin")
		}

		if len(refsData) == 0 {
			return
		}

		left, right = decodeRefs(string(refsData))
		if left == deleteBranch {
			return
		}
	} else {
		var repo, refspec string

		if len(args) < 1 {
			Print("Usage: git media push --dry-run <repo> [refspec]")
			return
		}

		repo = args[0]
		if len(args) == 2 {
			refspec = args[1]
		}

		localRef, err := gitmedia.CurrentRef()
		if err != nil {
			Panic(err, "Error getting local ref")
		}
		left = localRef

		remoteRef, err := git.LsRemote(repo, refspec)
		if err != nil {
			Panic(err, "Error getting remote ref")
		}

		if remoteRef != "" {
			right = "^" + strings.Split(remoteRef, "\t")[0]
		}
	}

	links := linksFromRefs(left, right)

	for i, link := range links {
		if dryRun {
			Print("push %s", link.Name)
			continue
		}
		if wErr := pushAsset(link.Oid, link.Name, i+1, len(links)); wErr != nil {
			Panic(wErr.Err, wErr.Error())
		}
	}
}

// pushAsset pushes the asset with the given oid to the git media endpoint. It will
// first make an OPTIONS call. If OPTIONS returns a 200 status, it indicates that the
// git media endpoint already has a git media object for that oid. The object will
// not be pushed again.
func pushAsset(oid, filename string, index, totalFiles int) *gitmedia.WrappedError {
	path, err := gitmedia.LocalMediaPath(oid)
	if err != nil {
		return gitmedia.Errorf(err, "Error uploading file %s (%s)", filename, oid)
	}

	status, err := gitmediaclient.Options(path)
	if err != nil {
		return gitmedia.Errorf(err, "Error uploading file %s (%s)", filename, oid)
	}

	if status == 200 {
		return nil
	}

	cb, file, cbErr := gitmedia.CopyCallbackFile("push", filename, index, totalFiles)
	if cbErr != nil {
		Error(cbErr.Error())
	}

	err = gitmediaclient.Put(path, filename, cb)
	if file != nil {
		file.Close()
	}

	return nil
}

// decodeRefs pulls the sha1s out of the line read from the pre-push
// hook's stdin.
func decodeRefs(input string) (string, string) {
	refs := strings.Split(strings.TrimSpace(input), " ")
	var left, right string

	if len(refs) > 1 {
		left = refs[1]
	}

	if len(refs) > 3 {
		right = "^" + refs[3]
	}

	return left, right
}

// linksFromRefs runs git.RevListObjects for the passed refs and builds
// a slice of pointer.Link's for any object that has an associated git media file.
func linksFromRefs(left, right string) []*pointer.Link {
	revList, err := git.RevListObjects(left, right, false)
	if err != nil {
		Panic(err, "Error running git rev-list --objects %s %s", left, right)
	}

	links := make([]*pointer.Link, 0)
	for _, object := range revList {
		link, err := pointer.FindLink(object.Sha1)
		if err != nil {
			continue
		}

		links = append(links, link)
	}

	return links
}

func init() {
	pushCmd.Flags().BoolVarP(&dryRun, "dry-run", "d", false, "Do everything except actually send the updates")
	pushCmd.Flags().BoolVarP(&useStdin, "stdin", "s", false, "Take refs on stdin (for pre-push hook)")
	RootCmd.AddCommand(pushCmd)
}
<commit_msg>ララララー ラララー ララ<commit_after>package commands

import (
	"github.com/github/git-media/git"
	"github.com/github/git-media/gitmedia"
	"github.com/github/git-media/gitmediaclient"
	"github.com/github/git-media/pointer"
	"github.com/spf13/cobra"
	"io/ioutil"
	"os"
	"strings"
)

var (
	pushCmd = &cobra.Command{
		Use:   "push",
		Short: "Push files to the media endpoint",
		Run:   pushCommand,
	}
	dryRun       = false
	useStdin     = false
	deleteBranch = "(delete)"
)

// pushCommand is the command that's run via `git media push`. It has two modes
// of operation. The primary mode is run via the git pre-push hook. The pre-push
// hook passes two arguments on the command line:
//   1. Name of the remote to which the push is being done
//   2. URL to which the push is being done
//
// The hook receives commit information on stdin in the form:
//   <local ref> <local sha1> <remote ref> <remote sha1>
//
// In the typical case, pushCommand will get a list of git objects being pushed
// by using the following:
//    git rev-list --objects <local sha1> ^<remote sha1>
//
// If any of those git objects are associated with git media objects, those git
// media objects will be pushed to the git media endpoint.
//
// In the case of pushing a new branch, the list of git objects will be all of
// the git objects in this branch.
//
// In the case of deleting a branch, no attempts to push git media objects will be
// made.
//
// When pushing git media objects, the client will first perform an OPTIONS command
// which will determine not only whether or not the client is authorized, but also
// whether or not that git media endpoint already has the git media object. If it
// does, the object will not be pushed.
//
// The other mode of operation is the dry run mode. In this mode, the repo
// and refspec are passed on the command line. pushCommand will calculate the
// git objects that would be pushed in a similar manner as above and will print
// out each file name.
func pushCommand(cmd *cobra.Command, args []string) {
	var left, right string

	if len(args) == 0 {
		Print("The git media pre-push hook is out of date. Please run `git media update`")
		os.Exit(1)
	}

	if useStdin {
		refsData, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			Panic(err, "Error reading refs on stdin")
		}

		if len(refsData) == 0 {
			return
		}

		left, right = decodeRefs(string(refsData))
		if left == deleteBranch {
			return
		}
	} else {
		var repo, refspec string

		if len(args) < 1 {
			Print("Usage: git media push --dry-run <repo> [refspec]")
			return
		}

		repo = args[0]
		if len(args) == 2 {
			refspec = args[1]
		}

		localRef, err := gitmedia.CurrentRef()
		if err != nil {
			Panic(err, "Error getting local ref")
		}
		left = localRef

		remoteRef, err := git.LsRemote(repo, refspec)
		if err != nil {
			Panic(err, "Error getting remote ref")
		}

		if remoteRef != "" {
			right = "^" + strings.Split(remoteRef, "\t")[0]
		}
	}

	links := linksFromRefs(left, right)

	for i, link := range links {
		if dryRun {
			Print("push %s", link.Name)
			continue
		}
		if wErr := pushAsset(link.Oid, link.Name, i+1, len(links)); wErr != nil {
			Panic(wErr.Err, wErr.Error())
		}
	}
}

// pushAsset pushes the asset with the given oid to the git media endpoint. It will
// first make an OPTIONS call. If OPTIONS returns a 200 status, it indicates that the
// git media endpoint already has a git media object for that oid. The object will
// not be pushed again.
func pushAsset(oid, filename string, index, totalFiles int) *gitmedia.WrappedError {
	path, err := gitmedia.LocalMediaPath(oid)
	if err != nil {
		return gitmedia.Errorf(err, "Error uploading file %s (%s)", filename, oid)
	}

	status, err := gitmediaclient.Options(path)
	if err != nil {
		return gitmedia.Errorf(err, "Error uploading file %s (%s)", filename, oid)
	}

	if status == 200 {
		return nil
	}

	cb, file, cbErr := gitmedia.CopyCallbackFile("push", filename, index, totalFiles)
	if cbErr != nil {
		Error(cbErr.Error())
	}

	err = gitmediaclient.Put(path, filename, cb)
	if file != nil {
		file.Close()
	}

	return nil
}

// decodeRefs pulls the sha1s out of the line read from the pre-push
// hook's stdin.
func decodeRefs(input string) (string, string) {
	refs := strings.Split(strings.TrimSpace(input), " ")
	var left, right string

	if len(refs) > 1 {
		left = refs[1]
	}

	if len(refs) > 3 {
		right = "^" + refs[3]
	}

	return left, right
}

// linksFromRefs runs git.RevListObjects for the passed refs and builds
// a slice of pointer.Link's for any object that has an associated git media file.
func linksFromRefs(left, right string) []*pointer.Link {
	revList, err := git.RevListObjects(left, right, false)
	if err != nil {
		Panic(err, "Error running git rev-list --objects %s %s", left, right)
	}

	links := make([]*pointer.Link, 0)
	for _, object := range revList {
		link, err := pointer.FindLink(object.Sha1)
		if err != nil {
			continue
		}

		links = append(links, link)
	}

	return links
}

func init() {
	pushCmd.Flags().BoolVarP(&dryRun, "dry-run", "d", false, "Do everything except actually send the updates")
	pushCmd.Flags().BoolVarP(&useStdin, "stdin", "s", false, "Take refs on stdin (for pre-push hook)")
	RootCmd.AddCommand(pushCmd)
}
<|endoftext|>


<commit_before>// errchk $G -e $F.go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Incorrect short declarations and redeclarations.

package main

func f1() int { return 1 }
func f2() (float, int) { return 1, 2 }
func f3() (float, int, string) { return 1, 2, "3" }

func main() {
	{
		// simple redeclaration
		i := f1();
		i := f1();	// ERROR "redeclared|redefinition|no new"
	}
	{
		// change of type for f
		i, f, s := f3();	// GCCGO_ERROR "previous"
		f, g, t := f3();	// ERROR "redeclared|redefinition|cannot assign"
	}
	{
		// change of type for i
		i, f, s := f3();	// GCCGO_ERROR "previous"
		j, i, t := f3();	// ERROR "redeclared|redefinition|cannot assign"
	}
	{
		// no new variables
		i, f, s := f3();
		i, f := f2();	// ERROR "redeclared|redefinition|no new"
	}
	{
		// single redeclaration
		i, f, s := f3();	// GCCGO_ERROR "previous"
		i := f1();		// ERROR "redeclared|redefinition|no new"
	}
		// double redeclaration
	{
		i, f, s := f3();
		i, f := f2();	// ERROR "redeclared|redefinition|no new"
	}
	{
		// triple redeclaration
		i, f, s := f3();
		i, f, s := f3();	// ERROR "redeclared|redefinition|no new"
	}
}
<commit_msg>With the changes to support automatic forward declarations of type names, gccgo no longer reports redefinition errors for :=, because it no longer knows at parse time whether the type has changed.  Adjust this test to not match "redefinition", and to instead match gccgo's current output.<commit_after>// errchk $G -e $F.go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Incorrect short declarations and redeclarations.

package main

func f1() int { return 1 }
func f2() (float, int) { return 1, 2 }
func f3() (float, int, string) { return 1, 2, "3" }

func main() {
	{
		// simple redeclaration
		i := f1();
		i := f1();	// ERROR "redeclared|no new"
	}
	{
		// change of type for f
		i, f, s := f3();
		f, g, t := f3();	// ERROR "redeclared|cannot assign|incompatible"
	}
	{
		// change of type for i
		i, f, s := f3();
		j, i, t := f3();	// ERROR "redeclared|cannot assign|incompatible"
	}
	{
		// no new variables
		i, f, s := f3();
		i, f := f2();	// ERROR "redeclared|no new"
	}
	{
		// single redeclaration
		i, f, s := f3();
		i := f1();		// ERROR "redeclared|no new|incompatible"
	}
		// double redeclaration
	{
		i, f, s := f3();
		i, f := f2();	// ERROR "redeclared|no new"
	}
	{
		// triple redeclaration
		i, f, s := f3();
		i, f, s := f3();	// ERROR "redeclared|no new"
	}
}
<|endoftext|>


<commit_before>package testutil

import (
	"path/filepath"

	"veyron.io/tools/lib/envutil"
	"veyron.io/tools/lib/util"
)

// runJSTest is a harness for executing javascript tests.
func runJSTest(ctx *util.Context, testName, testDir, target string, cleanFn func() error, env map[string]string) (*TestResult, error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, []string{"web"})
	if err != nil {
		return nil, err
	}
	defer cleanup()

	// Navigate to the target directory.
	if err := ctx.Run().Chdir(testDir); err != nil {
		return nil, err
	}

	// Clean up after previous instances of the test.
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}
	if cleanFn != nil {
		if err := cleanFn(); err != nil {
			return nil, err
		}
	}

	// Run the test target.
	opts := ctx.Run().Opts()
	osEnv := envutil.NewSnapshotFromOS()
	for key, value := range env {
		osEnv.Set(key, value)
	}
	opts.Env = osEnv.Map()
	if err := ctx.Run().CommandWithOpts(opts, "make", target); err != nil {
		return &TestResult{Status: TestFailed}, nil
	}

	return &TestResult{Status: TestPassed}, nil
}

// VeyronJSBuildExtension tests the veyron javascript build extension.
func VeyronJSBuildExtension(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "extension/veyron.crx"
	return runJSTest(ctx, testName, testDir, target, nil, nil)
}

// VeyronJSDoc (re)generates the content of the veyron javascript
// documentation server.
func VeyronJSDoc(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "docs"
	webDir, jsDocDir := "/var/www/jsdoc", filepath.Join(testDir, "docs")
	cleanFn := func() error {
		if err := ctx.Run().RemoveAll(webDir); err != nil {
			return err
		}
		return nil
	}
	result, err := runJSTest(ctx, testName, testDir, target, cleanFn, nil)
	if err != nil {
		return nil, err
	}
	// Move generated js documentation to the web server directory
	// using "mv" instead of "os.Rename()" to account for the fact
	// the the source and the destination may be on different
	// partitions.
	if err := ctx.Run().Command("mv", jsDocDir, webDir); err != nil {
		return nil, err
	}
	return result, nil
}

// VeyronJSIntegrationTest runs the veyron javascript integration test.
func VeyronJSIntegrationTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-integration"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSUnitTest runs the veyron javascript unit test.
func VeyronJSUnitTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-unit"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSVdlTest runs the veyron javascript vdl test.
func VeyronJSVdlTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-vdl"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSVomTest runs the veyron javascript vom test.
func VeyronJSVomTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron", "javascript", "vom")
	target := "test"
	return runJSTest(ctx, testName, testDir, target, nil, nil)
}
<commit_msg>veyron.io/tools/testutil: JavaScript VOM tests now support xunit output as well.<commit_after>package testutil

import (
	"path/filepath"

	"veyron.io/tools/lib/envutil"
	"veyron.io/tools/lib/util"
)

// runJSTest is a harness for executing javascript tests.
func runJSTest(ctx *util.Context, testName, testDir, target string, cleanFn func() error, env map[string]string) (*TestResult, error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, []string{"web"})
	if err != nil {
		return nil, err
	}
	defer cleanup()

	// Navigate to the target directory.
	if err := ctx.Run().Chdir(testDir); err != nil {
		return nil, err
	}

	// Clean up after previous instances of the test.
	if err := ctx.Run().Command("make", "clean"); err != nil {
		return nil, err
	}
	if cleanFn != nil {
		if err := cleanFn(); err != nil {
			return nil, err
		}
	}

	// Run the test target.
	opts := ctx.Run().Opts()
	osEnv := envutil.NewSnapshotFromOS()
	for key, value := range env {
		osEnv.Set(key, value)
	}
	opts.Env = osEnv.Map()
	if err := ctx.Run().CommandWithOpts(opts, "make", target); err != nil {
		return &TestResult{Status: TestFailed}, nil
	}

	return &TestResult{Status: TestPassed}, nil
}

// VeyronJSBuildExtension tests the veyron javascript build extension.
func VeyronJSBuildExtension(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "extension/veyron.crx"
	return runJSTest(ctx, testName, testDir, target, nil, nil)
}

// VeyronJSDoc (re)generates the content of the veyron javascript
// documentation server.
func VeyronJSDoc(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "docs"
	webDir, jsDocDir := "/var/www/jsdoc", filepath.Join(testDir, "docs")
	cleanFn := func() error {
		if err := ctx.Run().RemoveAll(webDir); err != nil {
			return err
		}
		return nil
	}
	result, err := runJSTest(ctx, testName, testDir, target, cleanFn, nil)
	if err != nil {
		return nil, err
	}
	// Move generated js documentation to the web server directory
	// using "mv" instead of "os.Rename()" to account for the fact
	// the the source and the destination may be on different
	// partitions.
	if err := ctx.Run().Command("mv", jsDocDir, webDir); err != nil {
		return nil, err
	}
	return result, nil
}

// VeyronJSIntegrationTest runs the veyron javascript integration test.
func VeyronJSIntegrationTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-integration"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSUnitTest runs the veyron javascript unit test.
func VeyronJSUnitTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-unit"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSVdlTest runs the veyron javascript vdl test.
func VeyronJSVdlTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron.js")
	target := "test-vdl"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}

// VeyronJSVomTest runs the veyron javascript vom test.
func VeyronJSVomTest(ctx *util.Context, testName string) (*TestResult, error) {
	root, err := util.VeyronRoot()
	if err != nil {
		return nil, err
	}
	testDir := filepath.Join(root, "veyron", "javascript", "vom")
	target := "test"
	env := map[string]string{}
	env["XUNIT"] = "true"
	env["NODE_OUTPUT"] = XUnitReportPath(testName)
	return runJSTest(ctx, testName, testDir, target, nil, env)
}
<|endoftext|>


<commit_before>package main

<commit_msg>add error<commit_after>package main

import (
	"time"
	"fmt"
)

type MyError struct {
	when time.Time
	what string
}

func (e *MyError) Error() string{
	return fmt.Sprintf("at %v %s", e.when, e.what)
}

func run() error {
	return &MyError{
		time.Now(),
		"can't work",
	}
}

func main() {
	if err := run(); err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/jmcvetta/neoism"
	"log"
)

type PeopleDriver interface {
	Write(p person) error
	Read(uuid string) (p person, found bool, err error)
}

type PeopleCypherDriver struct {
	db *neoism.Database
}

func NewPeopleCypherDriver(db *neoism.Database) PeopleCypherDriver {
	return PeopleCypherDriver{db}
}

func (pcd PeopleCypherDriver) Read(uuid string) (person, bool, error) {
	results := []struct {
		UUID              string `json:"uuid"`
		Name              string `json: "name"`
		FactsetIdentifier string `json: "factsetIdentifier"`
	}{}

	query := &neoism.CypherQuery{
		Statement: `MATCH (n:Person {uuid:{uuid}}) return n.uuid as uuid, n.name as name, n.factsetIdentifier as factsetIdentifier`,
		Parameters: map[string]interface{}{
			"uuid": uuid,
		},
		Result: &results,
	}

	err := pcd.db.Cypher(query)

	if err != nil {
		return person{}, false, err
	}
	j, _ := json.MarshalIndent(results, "  ", "  ")
	log.Printf("Result is %v", string(j))

	if len(results) == 0 {
		return person{}, false, nil
	}

	result := results[0]

	p := person{
		UUID: result.UUID,
		Name: result.Name,
	}

	if result.FactsetIdentifier != "" {
		p.Identifiers = append(p.Identifiers, identifier{fsAuthority, result.FactsetIdentifier})
	}

	return p, true, nil

}

func (pcd PeopleCypherDriver) Write(p person) error {

	params := map[string]interface{}{
		"name": p.Name,
		"uuid": p.UUID,
	}

	for _, identifier := range p.Identifiers {
		if identifier.Authority == fsAuthority {
			params["factsetIdentifier"] = identifier.IdentifierValue
		}
	}

	query := &neoism.CypherQuery{
		Statement: `MERGE (n:Person {uuid: {uuid}})
					set n={allprops}
					return  n`,
		Parameters: map[string]interface{}{
			"uuid":     p.UUID,
			"allprops": params,
		},
	}

	return pcd.db.Cypher(query)

}

const (
	fsAuthority = "http://api.ft.com/system/FACTSET-PPL"
)
<commit_msg>Move to batched cypher query, even though we currently only run one query<commit_after>package main

import (
	"github.com/jmcvetta/neoism"
)

type CypherRunner interface {
	Cypher() error
}

type PeopleDriver interface {
	Write(p person) error
	Read(uuid string) (p person, found bool, err error)
}

type PeopleCypherDriver struct {
	db *neoism.Database
}

func NewPeopleCypherDriver(db *neoism.Database) PeopleCypherDriver {
	return PeopleCypherDriver{db}
}

func (pcd PeopleCypherDriver) Read(uuid string) (person, bool, error) {
	results := []struct {
		UUID              string `json:"uuid"`
		Name              string `json: "name"`
		FactsetIdentifier string `json: "factsetIdentifier"`
	}{}

	query := &neoism.CypherQuery{
		Statement: `MATCH (n:Person {uuid:{uuid}}) return n.uuid as uuid, n.name as name, n.factsetIdentifier as factsetIdentifier`,
		Parameters: map[string]interface{}{
			"uuid": uuid,
		},
		Result: &results,
	}

	err := pcd.db.CypherBatch([]*neoism.CypherQuery{query})

	if err != nil {
		return person{}, false, err
	}

	if len(results) == 0 {
		return person{}, false, nil
	}

	result := results[0]

	p := person{
		UUID: result.UUID,
		Name: result.Name,
	}

	if result.FactsetIdentifier != "" {
		p.Identifiers = append(p.Identifiers, identifier{fsAuthority, result.FactsetIdentifier})
	}

	return p, true, nil

}

func (pcd PeopleCypherDriver) Write(p person) error {

	params := map[string]interface{}{
		"name": p.Name,
		"uuid": p.UUID,
	}

	for _, identifier := range p.Identifiers {
		if identifier.Authority == fsAuthority {
			params["factsetIdentifier"] = identifier.IdentifierValue
		}
	}

	query := &neoism.CypherQuery{
		Statement: `MERGE (n:Person {uuid: {uuid}})
					set n={allprops}
					return  n`,
		Parameters: map[string]interface{}{
			"uuid":     p.UUID,
			"allprops": params,
		},
	}

	return pcd.db.CypherBatch([]*neoism.CypherQuery{query})

}

const (
	fsAuthority = "http://api.ft.com/system/FACTSET-PPL"
)
<|endoftext|>


<commit_before>// Package transport provides an net/http Transport in a single place.
// HTTP(S) timeout can be set with a flag.
// It is a separate package so libs and plugins use it instead of net/http.
// That way, in case HTTP(S) needs to go through a proxy or else, only this
// file needs to be edited.
// This also allows us to use our own TLS package, also extensible.
package transport

import (
	"flag"
	"net"
	"net/http"
	neturl "net/url"
	"time"

	"github.com/StalkR/goircbot/lib/tls"
)

var timeout = flag.Duration("http_timeout", 5*time.Second, "Timeout for HTTP(S) connections.")

// ByURL returns an transport given an URL for use with a client.
// It extracts the hostname from URL and give it to TLS for SNI.
func ByURL(url string) (*http.Transport, error) {
	u, err := neturl.Parse(url)
	if err != nil {
		return nil, err
	}
	return &http.Transport{
		Dial:            timeoutDialer(*timeout),
		TLSClientConfig: tls.Config(u.Host),
	}, nil
}

// Client returns an client given an URL.
func Client(url string) (*http.Client, error) {
	trans, err := ByURL(url)
	if err != nil {
		return nil, err
	}
	return &http.Client{Transport: trans}, nil
}

func timeoutDialer(d time.Duration) func(net, addr string) (net.Conn, error) {
	return func(netw, addr string) (net.Conn, error) {
		return net.DialTimeout(netw, addr, d)
	}
}
<commit_msg>lib/transport: comment typo<commit_after>// Package transport provides an net/http Transport in a single place.
// HTTP(S) timeout can be set with a flag.
// It is a separate package so libs and plugins use it instead of net/http.
// That way, in case HTTP(S) needs to go through a proxy or else, only this
// file needs to be edited.
// This also allows us to use our own TLS package, also extensible.
package transport

import (
	"flag"
	"net"
	"net/http"
	neturl "net/url"
	"time"

	"github.com/StalkR/goircbot/lib/tls"
)

var timeout = flag.Duration("http_timeout", 5*time.Second, "Timeout for HTTP(S) connections.")

// ByURL returns an transport given an URL for use with a client.
// It extracts the hostname from URL and give it to TLS for SNI.
func ByURL(url string) (*http.Transport, error) {
	u, err := neturl.Parse(url)
	if err != nil {
		return nil, err
	}
	return &http.Transport{
		Dial:            timeoutDialer(*timeout),
		TLSClientConfig: tls.Config(u.Host),
	}, nil
}

// Client returns a client given an URL.
func Client(url string) (*http.Client, error) {
	trans, err := ByURL(url)
	if err != nil {
		return nil, err
	}
	return &http.Client{Transport: trans}, nil
}

func timeoutDialer(d time.Duration) func(net, addr string) (net.Conn, error) {
	return func(netw, addr string) (net.Conn, error) {
		return net.DialTimeout(netw, addr, d)
	}
}
<|endoftext|>


<commit_before>package configcommands

type CfMgmtConfigCommand struct {
	Version                             VersionCommand                      `command:"version" description:"Print version information and exit"`
	InitConfigurationCommand            InitConfigurationCommand            `command:"init" description:"Initializes folder structure for configuration"`
	GlobalConfigurationCommand          GlobalConfigurationCommand          `command:"global" description:"Updates values in cf-mgmt.yml"`
	OrgConfigurationCommand             OrgConfigurationCommand             `command:"org" description:"Adds/updates specified org to configuration"`
	SpaceConfigurationCommand           SpaceConfigurationCommand           `command:"space" description:"adds/updates space configuration"`
	AddOrgToConfigurationCommand        AddOrgToConfigurationCommand        `command:"add-org" description:"*****DEPRECATED, use 'cf-mgmt-config org instead' - Adds specified org to configuration"`
	AddSpaceToConfigurationCommand      AddSpaceToConfigurationCommand      `command:"add-space" description:"*****DEPRECATED, use 'cf-mgmt-config space instead' - Adds specified space to configuration for org"`
	GenerateConcoursePipelineCommand    GenerateConcoursePipelineCommand    `command:"generate-concourse-pipeline" description:"generates a concourse pipline to be used to drive cf-mgmt"`
	UpdateOrgConfigurationCommand       UpdateOrgConfigurationCommand       `command:"update-org" description:"*****DEPRECATED, use 'cf-mgmt-config org instead' - updates org configuration"`
	UpdateSpaceConfigurationCommand     UpdateSpaceConfigurationCommand     `command:"update-space" description:"*****DEPRECATED, use 'cf-mgmt-config space instead' - updates space configuration"`
	DeleteOrgConfigurationCommand       DeleteOrgConfigurationCommand       `command:"delete-org" description:"deletes org configuration"`
	DeleteSpaceConfigurationCommand     DeleteSpaceConfigurationCommand     `command:"delete-space" description:"deletes space configuration"`
	AddASGToConfigurationCommand        AddASGToConfigurationCommand        `command:"add-asg" description:"*****DEPRECATED, use 'cf-mgmt-config asg instead' - add a named asg to configuration"`
	ASGToConfigurationCommand           ASGToConfigurationCommand           `command:"asg" description:"creates/updates a named asg"`
	UpdateOrgsConfigurationCommand      UpdateOrgsConfigurationCommand      `command:"update-orgs" description:"updates orgs.yml"`
	RenameOrgConfigurationCommand       RenameOrgConfigurationCommand       `command:"rename-org" description:"renames an org"`
	RenameSpaceConfigurationCommand     RenameSpaceConfigurationCommand     `command:"rename-space" description:"renames a space for a given org"`
	OrgNamedQuotaConfigurationCommand   OrgNamedQuotaConfigurationCommand   `command:"named-org-quota" description:"creates/updates named org quota"`
	SpaceNamedQuotaConfigurationCommand SpaceNamedQuotaConfigurationCommand `command:"named-space-quota" description:"creates/updates named space quota"`
}

var CfMgmtConfig CfMgmtConfigCommand
<commit_msg>Minor spelling error on pipline, change to pipeline<commit_after>package configcommands

type CfMgmtConfigCommand struct {
	Version                             VersionCommand                      `command:"version" description:"Print version information and exit"`
	InitConfigurationCommand            InitConfigurationCommand            `command:"init" description:"Initializes folder structure for configuration"`
	GlobalConfigurationCommand          GlobalConfigurationCommand          `command:"global" description:"Updates values in cf-mgmt.yml"`
	OrgConfigurationCommand             OrgConfigurationCommand             `command:"org" description:"Adds/updates specified org to configuration"`
	SpaceConfigurationCommand           SpaceConfigurationCommand           `command:"space" description:"adds/updates space configuration"`
	AddOrgToConfigurationCommand        AddOrgToConfigurationCommand        `command:"add-org" description:"*****DEPRECATED, use 'cf-mgmt-config org instead' - Adds specified org to configuration"`
	AddSpaceToConfigurationCommand      AddSpaceToConfigurationCommand      `command:"add-space" description:"*****DEPRECATED, use 'cf-mgmt-config space instead' - Adds specified space to configuration for org"`
	GenerateConcoursePipelineCommand    GenerateConcoursePipelineCommand    `command:"generate-concourse-pipeline" description:"generates a concourse pipeline to be used to drive cf-mgmt"`
	UpdateOrgConfigurationCommand       UpdateOrgConfigurationCommand       `command:"update-org" description:"*****DEPRECATED, use 'cf-mgmt-config org instead' - updates org configuration"`
	UpdateSpaceConfigurationCommand     UpdateSpaceConfigurationCommand     `command:"update-space" description:"*****DEPRECATED, use 'cf-mgmt-config space instead' - updates space configuration"`
	DeleteOrgConfigurationCommand       DeleteOrgConfigurationCommand       `command:"delete-org" description:"deletes org configuration"`
	DeleteSpaceConfigurationCommand     DeleteSpaceConfigurationCommand     `command:"delete-space" description:"deletes space configuration"`
	AddASGToConfigurationCommand        AddASGToConfigurationCommand        `command:"add-asg" description:"*****DEPRECATED, use 'cf-mgmt-config asg instead' - add a named asg to configuration"`
	ASGToConfigurationCommand           ASGToConfigurationCommand           `command:"asg" description:"creates/updates a named asg"`
	UpdateOrgsConfigurationCommand      UpdateOrgsConfigurationCommand      `command:"update-orgs" description:"updates orgs.yml"`
	RenameOrgConfigurationCommand       RenameOrgConfigurationCommand       `command:"rename-org" description:"renames an org"`
	RenameSpaceConfigurationCommand     RenameSpaceConfigurationCommand     `command:"rename-space" description:"renames a space for a given org"`
	OrgNamedQuotaConfigurationCommand   OrgNamedQuotaConfigurationCommand   `command:"named-org-quota" description:"creates/updates named org quota"`
	SpaceNamedQuotaConfigurationCommand SpaceNamedQuotaConfigurationCommand `command:"named-space-quota" description:"creates/updates named space quota"`
}

var CfMgmtConfig CfMgmtConfigCommand
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"net"
	"net/http"
)

func main() {

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", HelloWeave)
	router.HandleFunc("/myip", myIp)

	log.Fatal(http.ListenAndServe(":80", router))
}

func HelloWeave(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Welcome!")
}

func myIp(w http.ResponseWriter, r *http.Request) {
	var theIps bytes.Buffer

	addrs, _ := net.InterfaceAddrs()

	for _, a := range addrs {
		if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			theIps.WriteString(ipnet.IP.String())
			theIps.WriteString("\n")
		}
	}
	fmt.Fprintln(w, theIps.String())
}
<commit_msg>Update to just look at ethwe for the example<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"net"
	"net/http"
)

func main() {

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", HelloWeave)
	router.HandleFunc("/myip", myIp)

	log.Fatal(http.ListenAndServe(":80", router))
}

func HelloWeave(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Welcome!")
}

func myIp(w http.ResponseWriter, r *http.Request) {
	var theIps bytes.Buffer

	ief, _ := net.InterfaceByName("ethwe")
	addrs, _ := ief.Addrs()

	for _, a := range addrs {
		if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			theIps.WriteString(ipnet.IP.String())
		}
	}
	fmt.Fprintln(w, theIps.String())
}
<|endoftext|>


<commit_before>package words

import (
    "testing"

    "bufio"
    "strings"
)

func assertStringSlicesEqual(t *testing.T, expected, actual []string) {
    for i, e := range expected {
        if e != actual[i] {
            t.Log(len(actual[i]))
            t.Errorf("'%s' should equal '%s'\n", actual[i], e)
        }
    }
}

func TestSimpleWords(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    t.Log(actual)
    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestPeriod(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test."))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestDoubleQuotes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this \"is a test.\""))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestSingleQuotes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this 'is a test.'"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestPunctuation(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this 'is a test,' I said; I was thinking about bannanas! Really?"))
    expected := []string{"this", "is", "a", "test", "I", "said", "I", "was", "thinking", "about", "bannanas", "Really"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestWhitespace(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is\ta\r\ntest"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestParenthesis(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test (really it is [really])."))
    expected := []string{"this", "is", "a", "test", "really", "it", "is", "really"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestDashes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test--really. I'm gonna have an em dash—told ya! Here comes an en dash–wow."))
    expected := []string{"this", "is", "a", "test", "really", "I'm", "gonna", "have", "an", "em", "dash", "told", "ya", "Here", "comes", "an", "en", "dash", "wow"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestURLs(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("Go to http://www.google.com/ for info or bit.ly/123 but not bit .ly/123. Definitely https://www.pivotaltracker.com"))
    expected := []string{"Go", "to", "http://www.google.com/", "for", "info", "or", "bit.ly/123", "but", "not", "bit", "ly", "123", "Definitely", "https://www.pivotaltracker.com"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestLongURLs(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("github.com/mceldeen/words"))
    expected := []string{"github.com/mceldeen/words"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestSlashes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("Talk to tom/jim for info"))
    expected := []string{"Talk", "to", "tom", "jim", "for", "info"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}
<commit_msg>Revise long url test to include query strings<commit_after>package words

import (
    "testing"

    "bufio"
    "strings"
)

func assertStringSlicesEqual(t *testing.T, expected, actual []string) {
    for i, e := range expected {
        if e != actual[i] {
            t.Log(len(actual[i]))
            t.Errorf("'%s' should equal '%s'\n", actual[i], e)
        }
    }
}

func TestSimpleWords(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    t.Log(actual)
    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestPeriod(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test."))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestDoubleQuotes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this \"is a test.\""))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestSingleQuotes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this 'is a test.'"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestPunctuation(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this 'is a test,' I said; I was thinking about bannanas! Really?"))
    expected := []string{"this", "is", "a", "test", "I", "said", "I", "was", "thinking", "about", "bannanas", "Really"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestWhitespace(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is\ta\r\ntest"))
    expected := []string{"this", "is", "a", "test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestParenthesis(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test (really it is [really])."))
    expected := []string{"this", "is", "a", "test", "really", "it", "is", "really"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestDashes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("this is a test--really. I'm gonna have an em dash—told ya! Here comes an en dash–wow."))
    expected := []string{"this", "is", "a", "test", "really", "I'm", "gonna", "have", "an", "em", "dash", "told", "ya", "Here", "comes", "an", "en", "dash", "wow"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestURLs(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("Go to http://www.google.com/ for info or bit.ly/123 but not bit .ly/123. Definitely https://www.pivotaltracker.com"))
    expected := []string{"Go", "to", "http://www.google.com/", "for", "info", "or", "bit.ly/123", "but", "not", "bit", "ly", "123", "Definitely", "https://www.pivotaltracker.com"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestLongURLs(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("github.com/mceldeen/words google.com/#q=test"))
    expected := []string{"github.com/mceldeen/words", "google.com/#q=test"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}

func TestSlashes(t *testing.T) {
    input := bufio.NewReader(strings.NewReader("Talk to tom/jim for info"))
    expected := []string{"Talk", "to", "tom", "jim", "for", "info"}
    actual := Tokenize(input)

    if len(expected) != len(actual) {
        t.Error("Slices are not the same length")
    }

    assertStringSlicesEqual(t, expected, actual)
}
<|endoftext|>


<commit_before>package notificationsetting

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"

	"github.com/cihangir/nisql"
	"github.com/koding/bongo"
)

var (
	ErrTypeAssertion = errors.New("type assertion error")
)

// Create creates the notification settings with the channelId and accountId
func Create(u *url.URL, h http.Header, req *models.NotificationSetting, ctx *models.Context) (int, http.Header, interface{}, error) {
	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	channelId, err := fetchChannelIdwithParticipantCheck(u, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	req.AccountId = ctx.Client.Account.Id
	req.ChannelId = channelId

	if err := req.Create(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

// Get gets the notification settings with id
// If any notification setting is not found in DB,
// returns 'Not Found' error , and it means that we'r gonna show default settings
func Get(u *url.URL, header http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	id, err := fetchChannelIdwithParticipantCheck(u, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	n := models.NewNotificationSetting()
	err = n.One(&bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": id,
			"account_id": ctx.Client.Account.Id,
		}},
	)
	if err == bongo.RecordNotFound {
		return response.NewNotFound()
	}

	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(n)
}

// Update udpates the notification setting
func Update(u *url.URL, h http.Header, a map[string]interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	req := models.NewNotificationSetting()

	if err := req.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	if req.Id == 0 {
		return response.NewBadRequest(err)
	}

	// check if notification setting's account is the same with requester account
	if req.AccountId != ctx.Client.Account.Id {
		return response.NewInvalidRequest(models.ErrAccountNotFound)
	}

	// Here we update notification setting with incoming request datas
	// if field have null or any value, then we update the field
	// otherwise we dont change any value of notification setting struct
	req, err = parseToNotificationSetting(a, req)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if err := req.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

// Delete deletes the notification setting of the user
func Delete(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	ns := models.NewNotificationSetting()
	ns.Id = id

	if err := ns.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	if ns.AccountId != ctx.Client.Account.Id {
		return response.NewInvalidRequest(models.ErrAccountNotFound)
	}

	if err := ns.Delete(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewDeleted()
}

// parseToNotificationSetting updates the given notification settings struct
// with given map[string]interface.
// If interface value does exist , then we update notification setting even if interface value is  null

func parseToNotificationSetting(a map[string]interface{}, r *models.NotificationSetting) (*models.NotificationSetting, error) {

	if value, ok := a["desktopSetting"]; ok {
		if value == nil {
			r.DesktopSetting = nisql.NullString{}

		} else {
			data, ok := value.(string)
			if ok {
				r.DesktopSetting = nisql.String(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["mobileSetting"]; ok {
		if value == nil {
			r.MobileSetting = nisql.NullString{}

		} else {
			data, ok := value.(string)
			if ok {
				r.MobileSetting = nisql.String(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["isSuppressed"]; ok {
		if value == nil {
			r.IsSuppressed = nisql.NullBool{}

		} else {
			data, ok := value.(bool)
			if ok {
				r.IsSuppressed = nisql.Bool(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["isMuted"]; ok {
		if value == nil {
			r.IsMuted = nisql.NullBool{}

		} else {
			data, ok := value.(bool)
			if ok {
				r.IsMuted = nisql.Bool(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	return r, nil
}

func fetchChannelIdwithParticipantCheck(u *url.URL, context *models.Context) (int64, error) {
	channelId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return 0, err
	}

	c, err := models.Cache.Channel.ById(channelId)
	if err != nil {
		return 0, err
	}

	isParticipant, err := c.IsParticipant(context.Client.Account.Id)
	if err != nil {
		return 0, err
	}

	if !isParticipant {
		return 0, models.ErrAccountIsNotParticipant
	}

	return c.Id, nil
}
<commit_msg>go: shadowing variable issue is fixed<commit_after>package notificationsetting

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"

	"github.com/cihangir/nisql"
	"github.com/koding/bongo"
)

var (
	ErrTypeAssertion = errors.New("type assertion error")
)

// Create creates the notification settings with the channelId and accountId
func Create(u *url.URL, h http.Header, req *models.NotificationSetting, ctx *models.Context) (int, http.Header, interface{}, error) {
	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	channelId, err := fetchChannelIdwithParticipantCheck(u, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	req.AccountId = ctx.Client.Account.Id
	req.ChannelId = channelId

	if err := req.Create(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

// Get gets the notification settings with id
// If any notification setting is not found in DB,
// returns 'Not Found' error , and it means that we'r gonna show default settings
func Get(u *url.URL, header http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	id, err := fetchChannelIdwithParticipantCheck(u, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	n := models.NewNotificationSetting()
	err = n.One(&bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": id,
			"account_id": ctx.Client.Account.Id,
		}},
	)
	if err == bongo.RecordNotFound {
		return response.NewNotFound()
	}

	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(n)
}

// Update udpates the notification setting
func Update(u *url.URL, h http.Header, a map[string]interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !ctx.IsLoggedIn() {
		return response.NewInvalidRequest(models.ErrNotLoggedIn)
	}

	req := models.NewNotificationSetting()

	if err := req.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	if req.Id == 0 {
		return response.NewBadRequest(err)
	}

	// check if notification setting's account is the same with requester account
	if req.AccountId != ctx.Client.Account.Id {
		return response.NewInvalidRequest(models.ErrAccountNotFound)
	}

	// Here we update notification setting with incoming request datas
	// if field have null or any value, then we update the field
	// otherwise we dont change any value of notification setting struct
	req, err = parseToNotificationSetting(a, req)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if err := req.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

// Delete deletes the notification setting of the user
func Delete(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	ns := models.NewNotificationSetting()
	ns.Id = id

	if err := ns.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	if ns.AccountId != ctx.Client.Account.Id {
		return response.NewInvalidRequest(models.ErrAccountNotFound)
	}

	if err := ns.Delete(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewDeleted()
}

// parseToNotificationSetting updates the given notification settings struct
// with given map[string]interface.
// If interface value does exist , then we update notification setting even if interface value is  null
func parseToNotificationSetting(a map[string]interface{}, r *models.NotificationSetting) (*models.NotificationSetting, error) {

	if value, ok := a["desktopSetting"]; ok {
		if value == nil {
			r.DesktopSetting = nisql.NullString{}

		} else {
			data, k := value.(string)
			if ok {
				r.DesktopSetting = nisql.String(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["mobileSetting"]; ok {
		if value == nil {
			r.MobileSetting = nisql.NullString{}

		} else {
			data, k := value.(string)
			if ok {
				r.MobileSetting = nisql.String(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["isSuppressed"]; ok {
		if value == nil {
			r.IsSuppressed = nisql.NullBool{}

		} else {
			data, k := value.(bool)
			if ok {
				r.IsSuppressed = nisql.Bool(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	if value, ok := a["isMuted"]; ok {
		if value == nil {
			r.IsMuted = nisql.NullBool{}

		} else {
			data, k := value.(bool)
			if ok {
				r.IsMuted = nisql.Bool(data)
			} else {
				return nil, ErrTypeAssertion
			}
		}
	}

	return r, nil
}

func fetchChannelIdwithParticipantCheck(u *url.URL, context *models.Context) (int64, error) {
	channelId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return 0, err
	}

	c, err := models.Cache.Channel.ById(channelId)
	if err != nil {
		return 0, err
	}

	isParticipant, err := c.IsParticipant(context.Client.Account.Id)
	if err != nil {
		return 0, err
	}

	if !isParticipant {
		return 0, models.ErrAccountIsNotParticipant
	}

	return c.Id, nil
}
<|endoftext|>


<commit_before>package completion

import "bytes"
import "fmt"
import "os"
import "path"
import "strings"
import "unicode"

import "../box"
import "../conio"

func listUpFiles(str string) ([]string, error) {
	str = strings.Replace(strings.Replace(str, "\\", "/", -1), "\"", "", -1)
	var directory string
	str = strings.Replace(str, "\\", "/", -1)
	if strings.HasSuffix(str, "/") {
		directory = path.Join(str, ".")
	} else {
		directory = path.Dir(str)
	}
	cutprefix := 0
	if strings.HasPrefix(directory, "/") {
		wd, _ := os.Getwd()
		directory = wd[0:2] + directory
		cutprefix = 2
	}

	fd, err := os.Open(directory)
	if err != nil {
		return nil, err
	}
	defer fd.Close()
	files, err2 := fd.Readdir(-1)
	if err2 != nil {
		return nil, err2
	}
	commons := make([]string, 0)
	STR := strings.ToUpper(str)
	for _, node1 := range files {
		name := path.Join(directory, node1.Name())
		if node1.IsDir() {
			name += "/"
		}
		if cutprefix > 0 {
			name = name[2:]
		}
		NAME := strings.ToUpper(name)
		if strings.HasPrefix(NAME, STR) {
			commons = append(commons, name)
		}
	}
	return commons, nil
}

func KeyFuncCompletionList(this *conio.ReadLineBuffer) conio.KeyFuncResult {
	str, _ := this.CurrentWord()
	list, _ := listUpFiles(str)
	if list == nil {
		return conio.CONTINUE
	}
	fmt.Print("\n")
	box.Print(list, 80, os.Stdout)
	this.RepaintAll("$ ")
	return conio.CONTINUE
}

func getCommmon(list []string) string {
	common := list[0]
	for _, f := range list[1:] {
		cr := strings.NewReader(common)
		fr := strings.NewReader(f)
		i := 0
		var buffer bytes.Buffer
		for {
			ch, _, cerr := cr.ReadRune()
			fh, _, ferr := fr.ReadRune()
			if cerr != nil || ferr != nil || unicode.ToUpper(ch) != unicode.ToUpper(fh) {
				break
			}
			buffer.WriteRune(ch)
			i++
		}
		common = buffer.String()
	}
	return common
}

func compareWithoutQuote(this string, that string) bool {
	return strings.Replace(this, "\"", "", -1) == strings.Replace(that, "\"", "", -1)
}

func KeyFuncCompletion(this *conio.ReadLineBuffer) conio.KeyFuncResult {
	str, wordStart := this.CurrentWord()

	slashToBackSlash := true
	firstFoundSlashPos := strings.IndexRune(str, '/')
	firstFoundBackSlashPos := strings.IndexRune(str, '\\')
	if firstFoundSlashPos >= 0 && firstFoundBackSlashPos >= 0 && firstFoundSlashPos < firstFoundBackSlashPos {
		slashToBackSlash = false
	}

	list, err := listUpFiles(str)
	if err != nil || len(list) <= 0 {
		return conio.CONTINUE
	}
	commonStr := getCommmon(list)
	needQuote := strings.ContainsRune(str, '"')
	if !needQuote {
		for _, node := range list {
			if strings.ContainsRune(node, ' ') {
				needQuote = true
				break
			}
		}
	}
	if needQuote {
		var buffer bytes.Buffer
		buffer.WriteRune('"')
		buffer.WriteString(commonStr)
		if len(list) <= 1 {
			buffer.WriteRune('"')
		}
		commonStr = buffer.String()
	}
	if len(list) == 1 && !strings.HasSuffix(commonStr, "/") && !strings.HasSuffix(commonStr, "/\"") {
		commonStr += " "
	}
	if slashToBackSlash {
		commonStr = strings.Replace(commonStr, "/", "\\", -1)
	}
	if compareWithoutQuote(str, commonStr) {
		return KeyFuncCompletionList(this)
	}
	this.ReplaceAndRepaint(wordStart, commonStr)
	conio.PutRep('\a', 1)
	return conio.CONTINUE
}
<commit_msg>support command-name completion<commit_after>package completion

import "bytes"
import "fmt"
import "os"
import "path"
import "strings"
import "unicode"

import "../box"
import "../conio"

var pathHash []string

func isExecutable(path string) bool {
	path = strings.ToLower(path)
	if strings.HasSuffix(path, ".exe") {
		return true
	}
	if strings.HasSuffix(path, ".cmd") {
		return true
	}
	if strings.HasSuffix(path, ".bat") {
		return true
	}
	if strings.HasSuffix(path, ".com") {
		return true
	}
	return false
}

func listUpFiles(str string) ([]string, error) {
	str = strings.Replace(strings.Replace(str, "\\", "/", -1), "\"", "", -1)
	var directory string
	str = strings.Replace(str, "\\", "/", -1)
	if strings.HasSuffix(str, "/") {
		directory = path.Join(str, ".")
	} else {
		directory = path.Dir(str)
	}
	cutprefix := 0
	if strings.HasPrefix(directory, "/") {
		wd, _ := os.Getwd()
		directory = wd[0:2] + directory
		cutprefix = 2
	}

	fd, fdErr := os.Open(directory)
	if fdErr != nil {
		return nil, fdErr
	}
	defer fd.Close()
	files, filesErr := fd.Readdir(-1)
	if filesErr != nil {
		return nil, filesErr
	}
	commons := make([]string, 0)
	STR := strings.ToUpper(str)
	for _, node1 := range files {
		name := path.Join(directory, node1.Name())
		if node1.IsDir() {
			name += "/"
		}
		if cutprefix > 0 {
			name = name[2:]
		}
		nameUpr := strings.ToUpper(name)
		if strings.HasPrefix(nameUpr, STR) {
			commons = append(commons, name)
		}
	}
	return commons, nil
}

func listUpCommands(str string) ([]string, error) {
	listTmp, listErr := listUpFiles(str)
	if listErr != nil {
		return nil, listErr
	}
	list := make([]string, 0)
	for _, fname := range listTmp {
		if strings.HasSuffix(fname, "/") || strings.HasSuffix(fname, "\\") || isExecutable(fname) {
			list = append(list, fname)
		}
	}
	pathEnv := os.Getenv("PATH")
	dirList := strings.Split(pathEnv, ";")
	strUpr := strings.ToUpper(str)
	for _, dir1 := range dirList {
		dirHandle, dirErr := os.Open(dir1)
		if dirErr != nil {
			continue
		}
		defer dirHandle.Close()
		files, filesErr := dirHandle.Readdir(0)
		if filesErr != nil {
			continue
		}
		for _, file1 := range files {
			name1Upr := strings.ToUpper(file1.Name())
			if !strings.HasPrefix(name1Upr, strUpr) {
				continue
			}
			if file1.IsDir() {
				continue
			}
			name := file1.Name()
			if isExecutable(name) {
				list = append(list, path.Base(name))
			}
		}
	}
	return list, nil
}
func KeyFuncCompletionList(this *conio.ReadLineBuffer) conio.KeyFuncResult {
	str, pos := this.CurrentWord()
	var list []string
	if pos > 0 {
		list, _ = listUpFiles(str)
	} else {
		list, _ = listUpCommands(str)
	}
	if list == nil {
		return conio.CONTINUE
	}
	fmt.Print("\n")
	box.Print(list, 80, os.Stdout)
	this.RepaintAll("$ ")
	return conio.CONTINUE
}

func getCommmon(list []string) string {
	common := list[0]
	for _, f := range list[1:] {
		cr := strings.NewReader(common)
		fr := strings.NewReader(f)
		i := 0
		var buffer bytes.Buffer
		for {
			ch, _, cerr := cr.ReadRune()
			fh, _, ferr := fr.ReadRune()
			if cerr != nil || ferr != nil || unicode.ToUpper(ch) != unicode.ToUpper(fh) {
				break
			}
			buffer.WriteRune(ch)
			i++
		}
		common = buffer.String()
	}
	return common
}

func compareWithoutQuote(this string, that string) bool {
	return strings.Replace(this, "\"", "", -1) == strings.Replace(that, "\"", "", -1)
}

func KeyFuncCompletion(this *conio.ReadLineBuffer) conio.KeyFuncResult {
	str, wordStart := this.CurrentWord()

	slashToBackSlash := true
	firstFoundSlashPos := strings.IndexRune(str, '/')
	firstFoundBackSlashPos := strings.IndexRune(str, '\\')
	if firstFoundSlashPos >= 0 && firstFoundBackSlashPos >= 0 && firstFoundSlashPos < firstFoundBackSlashPos {
		slashToBackSlash = false
	}

	var list []string
	var err error
	if wordStart > 0 {
		list, err = listUpFiles(str)
	} else {
		list, err = listUpCommands(str)
	}
	if err != nil || len(list) <= 0 {
		return conio.CONTINUE
	}
	commonStr := getCommmon(list)
	needQuote := strings.ContainsRune(str, '"')
	if !needQuote {
		for _, node := range list {
			if strings.ContainsRune(node, ' ') {
				needQuote = true
				break
			}
		}
	}
	if needQuote {
		var buffer bytes.Buffer
		buffer.WriteRune('"')
		buffer.WriteString(commonStr)
		if len(list) <= 1 {
			buffer.WriteRune('"')
		}
		commonStr = buffer.String()
	}
	if len(list) == 1 && !strings.HasSuffix(commonStr, "/") && !strings.HasSuffix(commonStr, "/\"") {
		commonStr += " "
	}
	if slashToBackSlash {
		commonStr = strings.Replace(commonStr, "/", "\\", -1)
	}
	if compareWithoutQuote(str, commonStr) {
		return KeyFuncCompletionList(this)
	}
	this.ReplaceAndRepaint(wordStart, commonStr)
	conio.PutRep('\a', 1)
	return conio.CONTINUE
}
<|endoftext|>