<commit_before>package model

import (
	"crypto/sha256"
	"fmt"
	hawk "github.com/tent/hawk-go"
	"io/ioutil"
	"log"
	"net/http"
)

type Auth struct {
	// Client ID required by Hawk
	ClientId string
	// Access Token required by Hawk
	AccessToken string
}

type ScopesResponse struct {
	ClientId    string
	AccessToken string
	Scopes      []string
	Expires     string
}

type GetCredentialsResponse struct {
	ClientId    string
	AccessToken string
	Scopes      []string
	Expires     string
	Name        string
	Description string
}

func (auth Auth) Scopes(clientId string) ScopesResponse {
	credentials := &hawk.Credentials{
		ID:   auth.ClientId,
		Key:  auth.AccessToken,
		Hash: sha256.New,
	}
	httpRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://auth.taskcluster.net/v1/client/%v/scopes", auth.ClientId), nil)
	reqAuth := hawk.NewRequestAuth(httpRequest, credentials, 0).RequestHeader()
	httpRequest.Header.Set("Authorization", reqAuth)
	httpClient := &http.Client{}
	response, err := httpClient.Do(httpRequest)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s\n", string(contents))
	}
	return ScopesResponse{}
}

func (auth Auth) GetCredentials(clientId string) GetCredentialsResponse {
	return GetCredentialsResponse{}
}
<commit_msg>stuff<commit_after>package model

import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	hawk "github.com/tent/hawk-go"
	"log"
	"net/http"
)

type Auth struct {
	// Client ID required by Hawk
	ClientId string
	// Access Token required by Hawk
	AccessToken string
}

type ScopesResult struct {
	ClientId string
	Scopes   []string
	Expires  string
}

func (result ScopesResult) String() string {
	return fmt.Sprintf(
		"Client ID:    %v\n"+
			"Scopes:       %v\n"+
			"Expires:      %v\n",
		result.ClientId, result.AccessToken, result.Scopes, result.Expires)
}

type GetCredentialsResult struct {
	ClientId    string
	AccessToken string
	Scopes      []string
	Expires     string
}

func (auth Auth) Scopes(clientId string) ScopesResult {
	credentials := &hawk.Credentials{
		ID:   auth.ClientId,
		Key:  auth.AccessToken,
		Hash: sha256.New,
	}
	httpRequest, err := http.NewRequest("GET", fmt.Sprintf("https://auth.taskcluster.net/v1/client/%v/scopes", auth.ClientId), nil)
	if err != nil {
		log.Fatal(err)
	}
	reqAuth := hawk.NewRequestAuth(httpRequest, credentials, 0).RequestHeader()
	httpRequest.Header.Set("Authorization", reqAuth)
	httpClient := &http.Client{}
	response, err := httpClient.Do(httpRequest)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	var scopes ScopesResult
	json := json.NewDecoder(response.Body)
	err = json.Decode(&scopes)
	if err != nil {
		log.Fatal(err)
	}
	return scopes
}

func (auth Auth) GetCredentials(clientId string) GetCredentialsResult {
	return GetCredentialsResult{}
}
<|endoftext|>


<commit_before>//http://stackoverflow.com/questions/8757389/reading-file-line-by-line-in-go
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"github.com/atotto/clipboard"
	"os"
	"strconv"
)

func longestFile(line []rune) int {
	max := 0
	for i, _ := range line {
		slice := line[0:i]
		file := string(slice)
		if file != "/" && file != "." && file != "./" && file != ".." && file != "../" {
			if _, err := os.Stat(file); err == nil {
				max = i
			}
		}
	}
	return max
}

func main() {
	var clip bytes.Buffer
	argsWithoutProg := os.Args[1:]

	reader := bufio.NewReader(os.Stdin)

	i := 0

	for {
		line, err := reader.ReadString('\n')

		if err != nil {
			// check here if err == io.EOF
			break
		}

		longest := 0
		start := 0
		for i, _ := range line {
			search := []rune(line[i:len(line)])
			found := longestFile(search)
			pos := found + i + 1
			if found > 0 && pos > longest {
				longest = pos
				start = i
			}
		}

		i = i + 1

		if longest > 0 {
			file := line[start : longest-1]
			fmt.Println(strconv.Itoa(i), file)
			for _, v := range argsWithoutProg {
				n, _ := strconv.Atoi(v)
				if n == i {
					clip.WriteString(file)
					clip.WriteString(" ")
				}
			}
		} else {
			i = i - 1
			fmt.Print(line)
		}
	}

	clipboardOutput := clip.String()
	if clipboardOutput != "" {
		clipboard.WriteAll(clipboardOutput)
	}
}
<commit_msg>less obscure naming<commit_after>//http://stackoverflow.com/questions/8757389/reading-file-line-by-line-in-go
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"github.com/atotto/clipboard"
	"os"
	"strconv"
)

func longestFile(line []rune) int {
	max := 0
	for i, _ := range line {
		slice := line[0:i]
		file := string(slice)
		if file != "/" && file != "." && file != "./" && file != ".." && file != "../" {
			if _, err := os.Stat(file); err == nil {
				max = i
			}
		}
	}
	return max
}

func main() {
	var clip bytes.Buffer
	argsWithoutProg := os.Args[1:]

	reader := bufio.NewReader(os.Stdin)

	lineNumber := 0

	for {
		line, err := reader.ReadString('\n')

		if err != nil {
			// check here if err == io.EOF
			break
		}

		longest := 0
		start := 0
		for i, _ := range line {
			search := []rune(line[i:len(line)])
			found := longestFile(search)
			pos := found + i + 1
			if found > 0 && pos > longest {
				longest = pos
				start = i
			}
		}

		lineNumber = lineNumber + 1

		if longest > 0 {
			file := line[start : longest-1]
			fmt.Println(strconv.Itoa(lineNumber), file)
			for _, v := range argsWithoutProg {
				n, _ := strconv.Atoi(v)
				if n == lineNumber {
					clip.WriteString(file)
					clip.WriteString(" ")
				}
			}
		} else {
			lineNumber = lineNumber - 1
			fmt.Print(line)
		}
	}

	clipboardOutput := clip.String()
	if clipboardOutput != "" {
		clipboard.WriteAll(clipboardOutput)
	}
}
<|endoftext|>


<commit_before>package run

import (
	"bufio"
	"bytes"
	"errors"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"
)

const (
	rootUID = 0
	rootGID = 0
)

var (
	//ErrBufferCreateFailed creating the buffer failed
	ErrBufferCreateFailed = errors.New("Unable to create the buffer object")

	//ErrScannerCreateFailed creating the scanner failed
	ErrScannerCreateFailed = errors.New("Unable to create the scanner object")

	//ErrReaderCreateFailed creating the reader failed
	ErrReaderCreateFailed = errors.New("Unable to create the reader object")

	//ErrCommandCreateFailed creating the command failed
	ErrCommandCreateFailed = errors.New("Unable to create the command object")

	//ErrExecuteFailed installation package failed
	ErrExecuteFailed = errors.New("The command line failed to execute correctly")
)

//Run is a static class that enables running and capturing command output
type Run struct{}

//NewRun generates a Run object
func NewRun() *Run {
	myRun := &Run{}
	return myRun
}

//ExecExistsInPath returns ture if exec exists in the given path
func ExecExistsInPath(exe string) bool {
	_, err := exec.LookPath(exe)
	return err == nil
}

//Command executes a command that monitors output for success or failure
func (Run) Command(cmdLine string, successRegex string, failureRegex string) error {
	log.Debugln("RunCommand ENTER")
	log.Debugln("Cmdline:", cmdLine)
	log.Debugln("SuccessRegex:", successRegex)
	log.Debugln("FailureRegex:", failureRegex)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommand LEAVE")
		return ErrCommandCreateFailed
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Errorln("Error starting Cmd:", err)
		log.Debugln("RunCommand LEAVE")
		return err
	}

	readbuffer := bytes.NewBuffer(out)
	if readbuffer == nil {
		log.Errorln("Error creating buffer")
		log.Debugln("RunCommand LEAVE")
		return ErrBufferCreateFailed
	}

	reader := bufio.NewScanner(readbuffer)
	if reader == nil {
		log.Errorln("Error creating reader")
		log.Debugln("RunCommand LEAVE")
		return ErrReaderCreateFailed
	}

	failure := false
	succeeded := false
	for reader.Scan() {
		line := reader.Text()
		log.Debugln("Line:", line)
		if failure {
			continue
		}
		if len(failureRegex) > 0 {
			myfail, _ := regexp.MatchString(failureRegex, line)
			if myfail {
				log.Debugln("Line Matched - FAILURE!")
				failure = true
			}
		}
		if succeeded {
			continue
		}
		if len(successRegex) > 0 {
			mysucceed, _ := regexp.MatchString(successRegex, line)
			if mysucceed {
				log.Debugln("Line Matched - SUCCEEDED!")
				succeeded = true
			}
		}
	}

	if failure {
		log.Debugln("Cmdline explicitly failed to execute correctly")
		log.Debugln("RunCommand LEAVE")
		return ErrExecuteFailed
	}
	if succeeded {
		log.Debugln("Cmdline executed successful")
		log.Debugln("RunCommand LEAVE")
		return nil
	}

	log.Debugln("Cmdline implicitly failed to execute correctly")
	log.Debugln("RunCommand LEAVE")
	return ErrExecuteFailed
}

//CommandEx executes a command that monitors output for success or failure with a timeout
func (Run) CommandEx(cmdLine string, successRegex string, failureRegex string, waitInSec int) error {
	log.Debugln("RunCommandEx ENTER")
	log.Debugln("Cmdline:", cmdLine)
	log.Debugln("SuccessRegex:", successRegex)
	log.Debugln("FailureRegex:", failureRegex)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommandEx LEAVE")
		return ErrCommandCreateFailed
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Errorln("Error getting StdoutPipe:", err)
		log.Debugln("RunCommandEx LEAVE")
		return err
	}

	err = cmd.Start()
	if err != nil {
		log.Errorln("Error on cmd start:", err)
		log.Debugln("RunCommandEx LEAVE")
		return err
	}

	stdoutScanner := bufio.NewScanner(stdout)
	if cmd == nil {
		log.Errorln("Error creating scanner")
		log.Debugln("RunCommandEx LEAVE")
		return ErrScannerCreateFailed
	}

	output := ""
	go func() {
		for stdoutScanner.Scan() {
			line := stdoutScanner.Text()
			log.Infoln(line)
			output += line
		}
	}()

	err = cmd.Wait()
	if err != nil {
		log.Warnln("Error on cmd wait:", err)
	}

	cmd.Process.Wait() //this should wait until all child processes are gone

	time.Sleep(time.Duration(waitInSec) * time.Second)

	outputBuffer := bytes.NewBuffer([]byte(output))
	if outputBuffer == nil {
		log.Errorln("Error creating buffer")
		log.Debugln("RunCommandEx LEAVE")
		return ErrBufferCreateFailed
	}

	outputScanner := bufio.NewScanner(outputBuffer)
	if outputScanner == nil {
		log.Errorln("Error creating reader")
		log.Debugln("RunCommandEx LEAVE")
		return ErrScannerCreateFailed
	}

	failure := false
	succeeded := false
	for outputScanner.Scan() {
		line := outputScanner.Text()
		log.Debugln("Line:", line)
		if failure {
			continue
		}
		if len(failureRegex) > 0 {
			myfail, _ := regexp.MatchString(failureRegex, line)
			if myfail {
				log.Debugln("Line Matched - FAILURE!")
				failure = true
			}
		}
		if succeeded {
			continue
		}
		if len(successRegex) > 0 {
			mysucceed, _ := regexp.MatchString(successRegex, line)
			if mysucceed {
				log.Debugln("Line Matched - SUCCEEDED!")
				succeeded = true
			}
		}
	}

	if failure {
		log.Debugln("Cmdline explicitly failed to execute correctly")
		log.Debugln("RunCommandEx LEAVE")
		return ErrExecuteFailed
	}
	if succeeded {
		log.Debugln("Cmdline executed successful")
		log.Debugln("RunCommandEx LEAVE")
		return nil
	}

	log.Debugln("Cmdline implicitly failed to execute correctly")
	log.Debugln("RunCommandEx LEAVE")
	return ErrExecuteFailed
}

//CommandOutput executes a command that returns the output
func (Run) CommandOutput(cmdLine string) (string, error) {
	log.Debugln("RunCommandOutput ENTER")
	log.Debugln("Cmdline:", cmdLine)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommandOutput LEAVE")
		return "", ErrCommandCreateFailed
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Errorln("Error getting output:", err)
		log.Debugln("RunCommandOutput LEAVE")
		return "", err
	}

	output := strings.TrimSpace(string(out))

	log.Debugln("RunCommandOutput Succeeded")
	log.Debugln(output)
	log.Debugln("RunCommandOutput LEAVE")
	return output, nil
}

//CreateProcess starts a new detached process
func (Run) CreateProcess(cmdLine string) error {
	log.Debugln("CreateProcess ENTER")
	log.Debugln("cmdLine:", cmdLine)

	// The Credential fields are used to set UID, GID and attitional GIDS of the process
	// You need to run the program as root to do this
	cred := &syscall.Credential{
		Uid:    rootUID,
		Gid:    rootGID,
		Groups: []uint32{},
	}

	// the Noctty flag is used to detach the process from parent tty
	sysproc := &syscall.SysProcAttr{
		Credential: cred,
		//Noctty: true,
	}

	attr := os.ProcAttr{
		Dir: ".",
		Env: os.Environ(),
		Files: []*os.File{
			os.Stdin,
			os.Stdout,
			os.Stderr,
		},
		Sys: sysproc,
	}

	args := strings.Split(cmdLine, " ")
	for i := 0; i < len(args); i++ {
		log.Debugln("Arg #", i, ":", args[i])
	}

	log.Debugln("CreateProcess Before")
	process, err := os.StartProcess(args[0], args, &attr)
	log.Debugln("CreateProcess After")

	if err == nil {
		// It is not clear from docs, but Realease actually detaches the process
		err = process.Release()
		if err == nil {
			log.Debugln("CreateProcess succeeded!")
		} else {
			log.Errorln("Process Release failed:", err)
		}
	} else {
		log.Errorln("StartProcess failed:", err)
	}

	log.Debugln("CreateProcess LEAVE")
	return err
}
<commit_msg>Use pointers for Run func<commit_after>package run

import (
	"bufio"
	"bytes"
	"errors"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"
)

const (
	rootUID = 0
	rootGID = 0
)

var (
	//ErrBufferCreateFailed creating the buffer failed
	ErrBufferCreateFailed = errors.New("Unable to create the buffer object")

	//ErrScannerCreateFailed creating the scanner failed
	ErrScannerCreateFailed = errors.New("Unable to create the scanner object")

	//ErrReaderCreateFailed creating the reader failed
	ErrReaderCreateFailed = errors.New("Unable to create the reader object")

	//ErrCommandCreateFailed creating the command failed
	ErrCommandCreateFailed = errors.New("Unable to create the command object")

	//ErrExecuteFailed installation package failed
	ErrExecuteFailed = errors.New("The command line failed to execute correctly")
)

//Run is a static class that enables running and capturing command output
type Run struct{}

//NewRun generates a Run object
func NewRun() *Run {
	myRun := &Run{}
	return myRun
}

//ExecExistsInPath returns ture if exec exists in the given path
func (run *Run) ExecExistsInPath(exe string) bool {
	_, err := exec.LookPath(exe)
	return err == nil
}

//Command executes a command that monitors output for success or failure
func (run *Run) Command(cmdLine string, successRegex string, failureRegex string) error {
	log.Debugln("RunCommand ENTER")
	log.Debugln("Cmdline:", cmdLine)
	log.Debugln("SuccessRegex:", successRegex)
	log.Debugln("FailureRegex:", failureRegex)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommand LEAVE")
		return ErrCommandCreateFailed
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Errorln("Error starting Cmd:", err)
		log.Debugln("RunCommand LEAVE")
		return err
	}

	readbuffer := bytes.NewBuffer(out)
	if readbuffer == nil {
		log.Errorln("Error creating buffer")
		log.Debugln("RunCommand LEAVE")
		return ErrBufferCreateFailed
	}

	reader := bufio.NewScanner(readbuffer)
	if reader == nil {
		log.Errorln("Error creating reader")
		log.Debugln("RunCommand LEAVE")
		return ErrReaderCreateFailed
	}

	failure := false
	succeeded := false
	for reader.Scan() {
		line := reader.Text()
		log.Debugln("Line:", line)
		if failure {
			continue
		}
		if len(failureRegex) > 0 {
			myfail, _ := regexp.MatchString(failureRegex, line)
			if myfail {
				log.Debugln("Line Matched - FAILURE!")
				failure = true
			}
		}
		if succeeded {
			continue
		}
		if len(successRegex) > 0 {
			mysucceed, _ := regexp.MatchString(successRegex, line)
			if mysucceed {
				log.Debugln("Line Matched - SUCCEEDED!")
				succeeded = true
			}
		}
	}

	if failure {
		log.Debugln("Cmdline explicitly failed to execute correctly")
		log.Debugln("RunCommand LEAVE")
		return ErrExecuteFailed
	}
	if succeeded {
		log.Debugln("Cmdline executed successful")
		log.Debugln("RunCommand LEAVE")
		return nil
	}

	log.Debugln("Cmdline implicitly failed to execute correctly")
	log.Debugln("RunCommand LEAVE")
	return ErrExecuteFailed
}

//CommandEx executes a command that monitors output for success or failure with a timeout
func (run *Run) CommandEx(cmdLine string, successRegex string, failureRegex string, waitInSec int) error {
	log.Debugln("RunCommandEx ENTER")
	log.Debugln("Cmdline:", cmdLine)
	log.Debugln("SuccessRegex:", successRegex)
	log.Debugln("FailureRegex:", failureRegex)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommandEx LEAVE")
		return ErrCommandCreateFailed
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Errorln("Error getting StdoutPipe:", err)
		log.Debugln("RunCommandEx LEAVE")
		return err
	}

	err = cmd.Start()
	if err != nil {
		log.Errorln("Error on cmd start:", err)
		log.Debugln("RunCommandEx LEAVE")
		return err
	}

	stdoutScanner := bufio.NewScanner(stdout)
	if cmd == nil {
		log.Errorln("Error creating scanner")
		log.Debugln("RunCommandEx LEAVE")
		return ErrScannerCreateFailed
	}

	output := ""
	go func() {
		for stdoutScanner.Scan() {
			line := stdoutScanner.Text()
			log.Infoln(line)
			output += line
		}
	}()

	err = cmd.Wait()
	if err != nil {
		log.Warnln("Error on cmd wait:", err)
	}

	cmd.Process.Wait() //this should wait until all child processes are gone

	time.Sleep(time.Duration(waitInSec) * time.Second)

	outputBuffer := bytes.NewBuffer([]byte(output))
	if outputBuffer == nil {
		log.Errorln("Error creating buffer")
		log.Debugln("RunCommandEx LEAVE")
		return ErrBufferCreateFailed
	}

	outputScanner := bufio.NewScanner(outputBuffer)
	if outputScanner == nil {
		log.Errorln("Error creating reader")
		log.Debugln("RunCommandEx LEAVE")
		return ErrScannerCreateFailed
	}

	failure := false
	succeeded := false
	for outputScanner.Scan() {
		line := outputScanner.Text()
		log.Debugln("Line:", line)
		if failure {
			continue
		}
		if len(failureRegex) > 0 {
			myfail, _ := regexp.MatchString(failureRegex, line)
			if myfail {
				log.Debugln("Line Matched - FAILURE!")
				failure = true
			}
		}
		if succeeded {
			continue
		}
		if len(successRegex) > 0 {
			mysucceed, _ := regexp.MatchString(successRegex, line)
			if mysucceed {
				log.Debugln("Line Matched - SUCCEEDED!")
				succeeded = true
			}
		}
	}

	if failure {
		log.Debugln("Cmdline explicitly failed to execute correctly")
		log.Debugln("RunCommandEx LEAVE")
		return ErrExecuteFailed
	}
	if succeeded {
		log.Debugln("Cmdline executed successful")
		log.Debugln("RunCommandEx LEAVE")
		return nil
	}

	log.Debugln("Cmdline implicitly failed to execute correctly")
	log.Debugln("RunCommandEx LEAVE")
	return ErrExecuteFailed
}

//CommandOutput executes a command that returns the output
func (run *Run) CommandOutput(cmdLine string) (string, error) {
	log.Debugln("RunCommandOutput ENTER")
	log.Debugln("Cmdline:", cmdLine)

	cmd := exec.Command("bash", "-c", cmdLine)
	if cmd == nil {
		log.Errorln("Error creating cmd")
		log.Debugln("RunCommandOutput LEAVE")
		return "", ErrCommandCreateFailed
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Errorln("Error getting output:", err)
		log.Debugln("RunCommandOutput LEAVE")
		return "", err
	}

	output := strings.TrimSpace(string(out))

	log.Debugln("RunCommandOutput Succeeded")
	log.Debugln(output)
	log.Debugln("RunCommandOutput LEAVE")
	return output, nil
}

//CreateProcess starts a new detached process
func (run *Run) CreateProcess(cmdLine string) error {
	log.Debugln("CreateProcess ENTER")
	log.Debugln("cmdLine:", cmdLine)

	// The Credential fields are used to set UID, GID and attitional GIDS of the process
	// You need to run the program as root to do this
	cred := &syscall.Credential{
		Uid:    rootUID,
		Gid:    rootGID,
		Groups: []uint32{},
	}

	// the Noctty flag is used to detach the process from parent tty
	sysproc := &syscall.SysProcAttr{
		Credential: cred,
		//Noctty: true,
	}

	attr := os.ProcAttr{
		Dir: ".",
		Env: os.Environ(),
		Files: []*os.File{
			os.Stdin,
			os.Stdout,
			os.Stderr,
		},
		Sys: sysproc,
	}

	args := strings.Split(cmdLine, " ")
	for i := 0; i < len(args); i++ {
		log.Debugln("Arg #", i, ":", args[i])
	}

	log.Debugln("CreateProcess Before")
	process, err := os.StartProcess(args[0], args, &attr)
	log.Debugln("CreateProcess After")

	if err == nil {
		// It is not clear from docs, but Realease actually detaches the process
		err = process.Release()
		if err == nil {
			log.Debugln("CreateProcess succeeded!")
		} else {
			log.Errorln("Process Release failed:", err)
		}
	} else {
		log.Errorln("StartProcess failed:", err)
	}

	log.Debugln("CreateProcess LEAVE")
	return err
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSPolicyAttachment_basic(t *testing.T) {
	var out iam.ListEntitiesForPolicyOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attach", 3, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user"}, []string{"test-role"}, []string{"test-group"}, &out),
				),
			},
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfigUpdate,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attach", 6, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user3", "test-user3"}, []string{"test-role2", "test-role3"}, []string{"test-group2", "test-group3"}, &out),
				),
			},
		},
	})
}

func TestAccAWSPolicyAttachment_paginatedEntities(t *testing.T) {
	var out iam.ListEntitiesForPolicyOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyPaginatedAttachConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-paginated-attach", 101, &out),
				),
			},
		},
	})
}

func testAccCheckAWSPolicyAttachmentDestroy(s *terraform.State) error {
	return nil
}

func testAccCheckAWSPolicyAttachmentExists(n string, c int64, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No policy name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).iamconn
		arn := rs.Primary.Attributes["policy_arn"]

		resp, err := conn.GetPolicy(&iam.GetPolicyInput{
			PolicyArn: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Policy (%s) not found", n)
		}
		if c != *resp.Policy.AttachmentCount {
			return fmt.Errorf("Error: Policy (%s) has wrong number of entities attached on initial creation", n)
		}
		resp2, err := conn.ListEntitiesForPolicy(&iam.ListEntitiesForPolicyInput{
			PolicyArn: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Failed to get entities for Policy (%s)", arn)
		}

		*out = *resp2
		return nil
	}
}

func testAccCheckAWSPolicyAttachmentAttributes(users []string, roles []string, groups []string, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		uc := len(users)
		rc := len(roles)
		gc := len(groups)

		for _, u := range users {
			for _, pu := range out.PolicyUsers {
				if u == *pu.UserName {
					uc--
				}
			}
		}
		for _, r := range roles {
			for _, pr := range out.PolicyRoles {
				if r == *pr.RoleName {
					rc--
				}
			}
		}
		for _, g := range groups {
			for _, pg := range out.PolicyGroups {
				if g == *pg.GroupName {
					gc--
				}
			}
		}
		if uc != 0 || rc != 0 || gc != 0 {
			return fmt.Errorf("Error: Number of attached users, roles, or groups was incorrect:\n expected %d users and found %d\nexpected %d roles and found %d\nexpected %d groups and found %d", len(users), len(users)-uc, len(roles), len(roles)-rc, len(groups), len(groups)-gc)
		}
		return nil
	}
}

const testAccAWSPolicyAttachConfig = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_role" "role" {
    name = "test-role"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}
resource "aws_iam_group" "group" {
    name = "test-group"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.name}"]
    roles = ["${aws_iam_role.role.name}"]
    groups = ["${aws_iam_group.group.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`

const testAccAWSPolicyAttachConfigUpdate = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_user" "user2" {
    name = "test-user2"
}
resource "aws_iam_user" "user3" {
    name = "test-user3"
}
resource "aws_iam_role" "role" {
    name = "test-role"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role" "role2" {
    name = "test-role2"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

}
resource "aws_iam_role" "role3" {
    name = "test-role3"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

}
resource "aws_iam_group" "group" {
    name = "test-group"
}
resource "aws_iam_group" "group2" {
    name = "test-group2"
}
resource "aws_iam_group" "group3" {
    name = "test-group3"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = [
        "${aws_iam_user.user2.name}",
        "${aws_iam_user.user3.name}"
    ]
    roles = [
        "${aws_iam_role.role2.name}",
        "${aws_iam_role.role3.name}"
    ]
    groups = [
        "${aws_iam_group.group2.name}",
        "${aws_iam_group.group3.name}"
    ]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`

const testAccAWSPolicyPaginatedAttachConfig = `
resource "aws_iam_user" "user" {
    count = 101
    name = "${format("paged-test-user-%d", count.index + 1)}"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-paginated-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.*.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`
<commit_msg>provider/aws: Randomize some IAM user names to avoid conflicts in tests<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSPolicyAttachment_basic(t *testing.T) {
	var out iam.ListEntitiesForPolicyOutput

	user1 := fmt.Sprintf("test-user-%d", acctest.RandInt())
	user2 := fmt.Sprintf("test-user-%d", acctest.RandInt())
	user3 := fmt.Sprintf("test-user-%d", acctest.RandInt())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfig(user1),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attach", 3, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{user1}, []string{"test-role"}, []string{"test-group"}, &out),
				),
			},
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfigUpdate(user1, user2, user3),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attach", 6, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{user3, user3}, []string{"test-role2", "test-role3"}, []string{"test-group2", "test-group3"}, &out),
				),
			},
		},
	})
}

func TestAccAWSPolicyAttachment_paginatedEntities(t *testing.T) {
	var out iam.ListEntitiesForPolicyOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyPaginatedAttachConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-paginated-attach", 101, &out),
				),
			},
		},
	})
}

func testAccCheckAWSPolicyAttachmentDestroy(s *terraform.State) error {
	return nil
}

func testAccCheckAWSPolicyAttachmentExists(n string, c int64, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No policy name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).iamconn
		arn := rs.Primary.Attributes["policy_arn"]

		resp, err := conn.GetPolicy(&iam.GetPolicyInput{
			PolicyArn: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Policy (%s) not found", n)
		}
		if c != *resp.Policy.AttachmentCount {
			return fmt.Errorf("Error: Policy (%s) has wrong number of entities attached on initial creation", n)
		}
		resp2, err := conn.ListEntitiesForPolicy(&iam.ListEntitiesForPolicyInput{
			PolicyArn: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Failed to get entities for Policy (%s)", arn)
		}

		*out = *resp2
		return nil
	}
}

func testAccCheckAWSPolicyAttachmentAttributes(users []string, roles []string, groups []string, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		uc := len(users)
		rc := len(roles)
		gc := len(groups)

		for _, u := range users {
			for _, pu := range out.PolicyUsers {
				if u == *pu.UserName {
					uc--
				}
			}
		}
		for _, r := range roles {
			for _, pr := range out.PolicyRoles {
				if r == *pr.RoleName {
					rc--
				}
			}
		}
		for _, g := range groups {
			for _, pg := range out.PolicyGroups {
				if g == *pg.GroupName {
					gc--
				}
			}
		}
		if uc != 0 || rc != 0 || gc != 0 {
			return fmt.Errorf("Error: Number of attached users, roles, or groups was incorrect:\n expected %d users and found %d\nexpected %d roles and found %d\nexpected %d groups and found %d", len(users), len(users)-uc, len(roles), len(roles)-rc, len(groups), len(groups)-gc)
		}
		return nil
	}
}

func testAccAWSPolicyAttachConfig(u1 string) string {
	return fmt.Sprintf(`
resource "aws_iam_user" "user" {
    name = "%s"
}
resource "aws_iam_role" "role" {
    name = "test-role"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}
resource "aws_iam_group" "group" {
    name = "test-group"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.name}"]
    roles = ["${aws_iam_role.role.name}"]
    groups = ["${aws_iam_group.group.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}`, u1)
}

func testAccAWSPolicyAttachConfigUpdate(u1, u2, u3 string) string {
	return fmt.Sprintf(`
resource "aws_iam_user" "user" {
    name = "%s"
}
resource "aws_iam_user" "user2" {
    name = "%s"
}
resource "aws_iam_user" "user3" {
    name = "%s"
}
resource "aws_iam_role" "role" {
    name = "test-role"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role" "role2" {
    name = "test-role2"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

}
resource "aws_iam_role" "role3" {
    name = "test-role3"
	  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

}
resource "aws_iam_group" "group" {
    name = "test-group"
}
resource "aws_iam_group" "group2" {
    name = "test-group2"
}
resource "aws_iam_group" "group3" {
    name = "test-group3"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = [
        "${aws_iam_user.user2.name}",
        "${aws_iam_user.user3.name}"
    ]
    roles = [
        "${aws_iam_role.role2.name}",
        "${aws_iam_role.role3.name}"
    ]
    groups = [
        "${aws_iam_group.group2.name}",
        "${aws_iam_group.group3.name}"
    ]
    policy_arn = "${aws_iam_policy.policy.arn}"
}`, u1, u2, u3)
}

const testAccAWSPolicyPaginatedAttachConfig = `
resource "aws_iam_user" "user" {
    count = 101
    name = "${format("paged-test-user-%d", count.index + 1)}"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-paginated-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.*.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/docopt/docopt.go"
    "time"
)

func main() {
	usage := "Usage: oc add <time> <time>"
	args, _ := docopt.Parse(usage, nil, true, "", false)

    times := args["<time>"].([]string)

    time1, _ := time.Parse("15:04", times[0])
    time2, _ := time.Parse("15:04", times[1])

    fmt.Println(time2.Sub(time1))
}
<commit_msg>reformated code<commit_after>package main

import (
	"fmt"
	"github.com/docopt/docopt.go"
	"time"
)

func main() {
	usage := "Usage: oc add <time> <time>"
	args, _ := docopt.Parse(usage, nil, true, "", false)

	times := args["<time>"].([]string)

	time1, _ := time.Parse("15:04", times[0])
	time2, _ := time.Parse("15:04", times[1])

	fmt.Println(time2.Sub(time1))
}
<|endoftext|>


<commit_before>package cluster

import (
	"errors"
	"os"
	"sync"
	"time"

	"github.com/influxdb/influxdb/meta"
	"github.com/influxdb/influxdb/tsdb"
)

const DefaultWriteTimeout = 5 * time.Second

// ConsistencyLevel represent a required replication criteria before a write can
// be returned as successful
type ConsistencyLevel int

const (
	// ConsistencyLevelAny allows for hinted hand off, potentially no write happened yet
	ConsistencyLevelAny ConsistencyLevel = iota

	// ConsistencyLevelOne requires at least one data node acknowledged a write
	ConsistencyLevelOne

	// ConsistencyLevelOne requires a quorum of data nodes to acknowledge a write
	ConsistencyLevelQuorum

	// ConsistencyLevelAll requires all data nodes to acknowledge a write
	ConsistencyLevelAll
)

var (
	// ErrTimeout is returned when a write times out.
	ErrTimeout = errors.New("timeout")

	// ErrPartialWrite is returned when a write partially succeeds but does
	// not meet the requested consistency level.
	ErrPartialWrite = errors.New("partial write")

	// ErrWriteFailed is returned when no writes succeeded.
	ErrWriteFailed = errors.New("write failed")
)

// PointsWriter handles writes across multiple local and remote data nodes.
type PointsWriter struct {
	mu      sync.RWMutex
	closing chan struct{}

	MetaStore interface {
		NodeID() uint64
		RetentionPolicy(database, policy string) (*meta.RetentionPolicyInfo, error)
		CreateShardGroupIfNotExists(database, policy string, timestamp time.Time) (*meta.ShardGroupInfo, error)
	}

	Store interface {
		CreateShard(database, retentionPolicy string, shardID uint64) error
		WriteToShard(shardID uint64, points []tsdb.Point) error
	}

	ShardWriter interface {
		WriteShard(shardID, ownerID uint64, points []tsdb.Point) error
	}
}

// NewPointsWriter returns a new instance of PointsWriter for a node.
func NewPointsWriter() *PointsWriter {
	return &PointsWriter{
		closing: make(chan struct{}),
	}
}

// ShardMapping contains a mapping of a shards to a points.
type ShardMapping struct {
	Points map[uint64][]tsdb.Point    // The points associated with a shard ID
	Shards map[uint64]*meta.ShardInfo // The shards that have been mapped, keyed by shard ID
}

// NewShardMapping creates an empty ShardMapping
func NewShardMapping() *ShardMapping {
	return &ShardMapping{
		Points: map[uint64][]tsdb.Point{},
		Shards: map[uint64]*meta.ShardInfo{},
	}
}

// MapPoint maps a point to shard
func (s *ShardMapping) MapPoint(shardInfo *meta.ShardInfo, p tsdb.Point) {
	points, ok := s.Points[shardInfo.ID]
	if !ok {
		s.Points[shardInfo.ID] = []tsdb.Point{p}
	} else {
		s.Points[shardInfo.ID] = append(points, p)
	}
	s.Shards[shardInfo.ID] = shardInfo
}

func (w *PointsWriter) Open() error {
	w.mu.Lock()
	defer w.mu.Unlock()
	if w.closing == nil {
		w.closing = make(chan struct{})
	}
	return nil
}

func (w *PointsWriter) Close() error {
	w.mu.Lock()
	defer w.mu.Unlock()
	if w.closing != nil {
		close(w.closing)
		w.closing = nil
	}
	return nil
}

// MapShards maps the points contained in wp to a ShardMapping.  If a point
// maps to a shard group or shard that does not currently exist, it will be
// created before returning the mapping.
func (w *PointsWriter) MapShards(wp *WritePointsRequest) (*ShardMapping, error) {

	// Stub out the MapShards call to return a single node/shard setup
	if os.Getenv("INFLUXDB_ALPHA1") != "" {
		sm := NewShardMapping()
		sh := &meta.ShardInfo{
			ID:       uint64(1),
			OwnerIDs: []uint64{uint64(1)},
		}
		for _, p := range wp.Points {
			sm.MapPoint(sh, p)
		}
		return sm, nil
	}

	// holds the start time ranges for required shard groups
	timeRanges := map[time.Time]*meta.ShardGroupInfo{}

	rp, err := w.MetaStore.RetentionPolicy(wp.Database, wp.RetentionPolicy)
	if err != nil {
		return nil, err
	}

	for _, p := range wp.Points {
		timeRanges[p.Time().Truncate(rp.ShardGroupDuration)] = nil
	}

	// holds all the shard groups and shards that are required for writes
	for t := range timeRanges {
		sg, err := w.MetaStore.CreateShardGroupIfNotExists(wp.Database, wp.RetentionPolicy, t)
		if err != nil {
			return nil, err
		}
		timeRanges[t] = sg
	}

	mapping := NewShardMapping()
	for _, p := range wp.Points {
		sg := timeRanges[p.Time().Truncate(rp.ShardGroupDuration)]
		sh := sg.ShardFor(p.HashID())
		mapping.MapPoint(&sh, p)
	}
	return mapping, nil
}

// WritePoints writes across multiple local and remote data nodes according the consistency level.
func (w *PointsWriter) WritePoints(p *WritePointsRequest) error {
	shardMappings, err := w.MapShards(p)
	if err != nil {
		return err
	}

	// Write each shard in it's own goroutine and return as soon
	// as one fails.
	ch := make(chan error, len(shardMappings.Points))
	for shardID, points := range shardMappings.Points {
		go func(shard *meta.ShardInfo, database, retentionPolicy string, points []tsdb.Point) {
			ch <- w.writeToShard(shard, p.Database, p.RetentionPolicy, p.ConsistencyLevel, points)
		}(shardMappings.Shards[shardID], p.Database, p.RetentionPolicy, points)
	}

	for range shardMappings.Points {
		select {
		case <-w.closing:
			return ErrWriteFailed
		case err := <-ch:
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// writeToShards writes points to a shard and ensures a write consistency level has been met.  If the write
// partially succceds, ErrPartialWrite is returned.
func (w *PointsWriter) writeToShard(shard *meta.ShardInfo, database, retentionPolicy string,
	consistency ConsistencyLevel, points []tsdb.Point) error {
	// The required number of writes to achieve the requested consistency level
	required := len(shard.OwnerIDs)
	switch consistency {
	case ConsistencyLevelAny, ConsistencyLevelOne:
		required = 1
	case ConsistencyLevelQuorum:
		required = required/2 + 1
	}

	// response channel for each shard writer go routine
	ch := make(chan error, len(shard.OwnerIDs))

	for _, nodeID := range shard.OwnerIDs {
		go func(shardID, nodeID uint64, points []tsdb.Point) {
			if w.MetaStore.NodeID() == nodeID {
				err := w.Store.WriteToShard(shardID, points)
				// If we've written to shard that should exist on the current node, but the store has
				// not actually created this shard, tell it to create it and retry the write
				if err == tsdb.ErrShardNotFound {
					err = w.Store.CreateShard(database, retentionPolicy, shardID)
					if err != nil {
						ch <- err
						return
					}
					err = w.Store.WriteToShard(shardID, points)
				}
				ch <- err
				return
			}

			ch <- w.ShardWriter.WriteShard(shardID, nodeID, points)
		}(shard.ID, nodeID, points)
	}

	var wrote int
	timeout := time.After(DefaultWriteTimeout)
	for range shard.OwnerIDs {
		select {
		case <-w.closing:
			return ErrWriteFailed
		case <-timeout:
			// return timeout error to caller
			return ErrTimeout
		case err := <-ch:
			// If the write returned an error, continue to the next response
			if err != nil {
				// FIXME
				println(err.Error())
				continue
			}

			wrote += 1
		}
	}

	// We wrote the required consistency level
	if wrote >= required {
		return nil
	}

	if wrote > 0 {
		return ErrPartialWrite
	}

	return ErrWriteFailed
}
<commit_msg>Remove temporary INFLUXDB_ALPHA write path enable flag<commit_after>package cluster

import (
	"errors"
	"sync"
	"time"

	"github.com/influxdb/influxdb/meta"
	"github.com/influxdb/influxdb/tsdb"
)

const DefaultWriteTimeout = 5 * time.Second

// ConsistencyLevel represent a required replication criteria before a write can
// be returned as successful
type ConsistencyLevel int

const (
	// ConsistencyLevelAny allows for hinted hand off, potentially no write happened yet
	ConsistencyLevelAny ConsistencyLevel = iota

	// ConsistencyLevelOne requires at least one data node acknowledged a write
	ConsistencyLevelOne

	// ConsistencyLevelOne requires a quorum of data nodes to acknowledge a write
	ConsistencyLevelQuorum

	// ConsistencyLevelAll requires all data nodes to acknowledge a write
	ConsistencyLevelAll
)

var (
	// ErrTimeout is returned when a write times out.
	ErrTimeout = errors.New("timeout")

	// ErrPartialWrite is returned when a write partially succeeds but does
	// not meet the requested consistency level.
	ErrPartialWrite = errors.New("partial write")

	// ErrWriteFailed is returned when no writes succeeded.
	ErrWriteFailed = errors.New("write failed")
)

// PointsWriter handles writes across multiple local and remote data nodes.
type PointsWriter struct {
	mu      sync.RWMutex
	closing chan struct{}

	MetaStore interface {
		NodeID() uint64
		RetentionPolicy(database, policy string) (*meta.RetentionPolicyInfo, error)
		CreateShardGroupIfNotExists(database, policy string, timestamp time.Time) (*meta.ShardGroupInfo, error)
	}

	Store interface {
		CreateShard(database, retentionPolicy string, shardID uint64) error
		WriteToShard(shardID uint64, points []tsdb.Point) error
	}

	ShardWriter interface {
		WriteShard(shardID, ownerID uint64, points []tsdb.Point) error
	}
}

// NewPointsWriter returns a new instance of PointsWriter for a node.
func NewPointsWriter() *PointsWriter {
	return &PointsWriter{
		closing: make(chan struct{}),
	}
}

// ShardMapping contains a mapping of a shards to a points.
type ShardMapping struct {
	Points map[uint64][]tsdb.Point    // The points associated with a shard ID
	Shards map[uint64]*meta.ShardInfo // The shards that have been mapped, keyed by shard ID
}

// NewShardMapping creates an empty ShardMapping
func NewShardMapping() *ShardMapping {
	return &ShardMapping{
		Points: map[uint64][]tsdb.Point{},
		Shards: map[uint64]*meta.ShardInfo{},
	}
}

// MapPoint maps a point to shard
func (s *ShardMapping) MapPoint(shardInfo *meta.ShardInfo, p tsdb.Point) {
	points, ok := s.Points[shardInfo.ID]
	if !ok {
		s.Points[shardInfo.ID] = []tsdb.Point{p}
	} else {
		s.Points[shardInfo.ID] = append(points, p)
	}
	s.Shards[shardInfo.ID] = shardInfo
}

func (w *PointsWriter) Open() error {
	w.mu.Lock()
	defer w.mu.Unlock()
	if w.closing == nil {
		w.closing = make(chan struct{})
	}
	return nil
}

func (w *PointsWriter) Close() error {
	w.mu.Lock()
	defer w.mu.Unlock()
	if w.closing != nil {
		close(w.closing)
		w.closing = nil
	}
	return nil
}

// MapShards maps the points contained in wp to a ShardMapping.  If a point
// maps to a shard group or shard that does not currently exist, it will be
// created before returning the mapping.
func (w *PointsWriter) MapShards(wp *WritePointsRequest) (*ShardMapping, error) {

	// holds the start time ranges for required shard groups
	timeRanges := map[time.Time]*meta.ShardGroupInfo{}

	rp, err := w.MetaStore.RetentionPolicy(wp.Database, wp.RetentionPolicy)
	if err != nil {
		return nil, err
	}

	for _, p := range wp.Points {
		timeRanges[p.Time().Truncate(rp.ShardGroupDuration)] = nil
	}

	// holds all the shard groups and shards that are required for writes
	for t := range timeRanges {
		sg, err := w.MetaStore.CreateShardGroupIfNotExists(wp.Database, wp.RetentionPolicy, t)
		if err != nil {
			return nil, err
		}
		timeRanges[t] = sg
	}

	mapping := NewShardMapping()
	for _, p := range wp.Points {
		sg := timeRanges[p.Time().Truncate(rp.ShardGroupDuration)]
		sh := sg.ShardFor(p.HashID())
		mapping.MapPoint(&sh, p)
	}
	return mapping, nil
}

// WritePoints writes across multiple local and remote data nodes according the consistency level.
func (w *PointsWriter) WritePoints(p *WritePointsRequest) error {
	shardMappings, err := w.MapShards(p)
	if err != nil {
		return err
	}

	// Write each shard in it's own goroutine and return as soon
	// as one fails.
	ch := make(chan error, len(shardMappings.Points))
	for shardID, points := range shardMappings.Points {
		go func(shard *meta.ShardInfo, database, retentionPolicy string, points []tsdb.Point) {
			ch <- w.writeToShard(shard, p.Database, p.RetentionPolicy, p.ConsistencyLevel, points)
		}(shardMappings.Shards[shardID], p.Database, p.RetentionPolicy, points)
	}

	for range shardMappings.Points {
		select {
		case <-w.closing:
			return ErrWriteFailed
		case err := <-ch:
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// writeToShards writes points to a shard and ensures a write consistency level has been met.  If the write
// partially succceds, ErrPartialWrite is returned.
func (w *PointsWriter) writeToShard(shard *meta.ShardInfo, database, retentionPolicy string,
	consistency ConsistencyLevel, points []tsdb.Point) error {
	// The required number of writes to achieve the requested consistency level
	required := len(shard.OwnerIDs)
	switch consistency {
	case ConsistencyLevelAny, ConsistencyLevelOne:
		required = 1
	case ConsistencyLevelQuorum:
		required = required/2 + 1
	}

	// response channel for each shard writer go routine
	ch := make(chan error, len(shard.OwnerIDs))

	for _, nodeID := range shard.OwnerIDs {
		go func(shardID, nodeID uint64, points []tsdb.Point) {
			if w.MetaStore.NodeID() == nodeID {
				err := w.Store.WriteToShard(shardID, points)
				// If we've written to shard that should exist on the current node, but the store has
				// not actually created this shard, tell it to create it and retry the write
				if err == tsdb.ErrShardNotFound {
					err = w.Store.CreateShard(database, retentionPolicy, shardID)
					if err != nil {
						ch <- err
						return
					}
					err = w.Store.WriteToShard(shardID, points)
				}
				ch <- err
				return
			}

			ch <- w.ShardWriter.WriteShard(shardID, nodeID, points)
		}(shard.ID, nodeID, points)
	}

	var wrote int
	timeout := time.After(DefaultWriteTimeout)
	for range shard.OwnerIDs {
		select {
		case <-w.closing:
			return ErrWriteFailed
		case <-timeout:
			// return timeout error to caller
			return ErrTimeout
		case err := <-ch:
			// If the write returned an error, continue to the next response
			if err != nil {
				// FIXME
				println(err.Error())
				continue
			}

			wrote += 1
		}
	}

	// We wrote the required consistency level
	if wrote >= required {
		return nil
	}

	if wrote > 0 {
		return ErrPartialWrite
	}

	return ErrWriteFailed
}
<|endoftext|>


<commit_before>package models

import (
  dmp "github.com/sergi/go-diff/diffmatchpatch"
  "html/template"
  "testing"
)

func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
  if s1 != string(s2) {
    t.Errorf("%s should be equal %s", s2, s1)
  }
}

func assertLineEqual(t *testing.T, d1 *DiffLine, d2 *DiffLine) {
  if d1 != d2 {
    t.Errorf("%v should be equal %v", d1, d2)
  }
}

func TestDiffToHTML(t *testing.T) {
  assertEqual(t, "foo bar biz", diffToHTML([]dmp.Diff{
    dmp.Diff{dmp.DiffEqual, "foo "},
    dmp.Diff{dmp.DiffInsert, "bar"},
    dmp.Diff{dmp.DiffDelete, " baz"},
    dmp.Diff{dmp.DiffEqual, " biz"},
  }, DIFF_LINE_ADD))

  assertEqual(t, "foo bar biz", diffToHTML([]dmp.Diff{
    dmp.Diff{dmp.DiffEqual, "foo "},
    dmp.Diff{dmp.DiffDelete, "bar"},
    dmp.Diff{dmp.DiffInsert, " baz"},
    dmp.Diff{dmp.DiffEqual, " biz"},
  }, DIFF_LINE_DEL))
}

// test if GetLine is return the correct lines
func TestGetLine(t *testing.T) {
  ds := DiffSection{Lines: []*DiffLine{
    &DiffLine{LeftIdx: 28,  RightIdx:   28, Type: DIFF_LINE_PLAIN},
    &DiffLine{LeftIdx: 29,  RightIdx:   29, Type: DIFF_LINE_PLAIN},
    &DiffLine{LeftIdx: 30,  RightIdx:   30, Type: DIFF_LINE_PLAIN},
    &DiffLine{LeftIdx: 31,  RightIdx:    0, Type: DIFF_LINE_DEL},
    &DiffLine{LeftIdx:  0,  RightIdx:   31, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx:  0,  RightIdx:   32, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx: 32,  RightIdx:   33, Type: DIFF_LINE_PLAIN},
    &DiffLine{LeftIdx: 33,  RightIdx:    0, Type: DIFF_LINE_DEL},
    &DiffLine{LeftIdx: 34,  RightIdx:    0, Type: DIFF_LINE_DEL},
    &DiffLine{LeftIdx: 35,  RightIdx:    0, Type: DIFF_LINE_DEL},
    &DiffLine{LeftIdx: 36,  RightIdx:    0, Type: DIFF_LINE_DEL},
    &DiffLine{LeftIdx:  0,  RightIdx:   34, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx:  0,  RightIdx:   35, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx:  0,  RightIdx:   36, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx:  0,  RightIdx:   37, Type: DIFF_LINE_ADD},
    &DiffLine{LeftIdx: 37,  RightIdx:   38, Type: DIFF_LINE_PLAIN},
    &DiffLine{LeftIdx: 38,  RightIdx:   39, Type: DIFF_LINE_PLAIN},
  }}

  assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 31), ds.Lines[4])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 31), ds.Lines[3])

  assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 33), ds.Lines[11])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 34), ds.Lines[12])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 35), ds.Lines[13])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 36), ds.Lines[14])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 34), ds.Lines[7])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 35), ds.Lines[8])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 36), ds.Lines[9])
  assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 37), ds.Lines[10])
}
<commit_msg>go fmt models/git_diff_test.go<commit_after>package models

import (
	dmp "github.com/sergi/go-diff/diffmatchpatch"
	"html/template"
	"testing"
)

func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
	if s1 != string(s2) {
		t.Errorf("%s should be equal %s", s2, s1)
	}
}

func assertLineEqual(t *testing.T, d1 *DiffLine, d2 *DiffLine) {
	if d1 != d2 {
		t.Errorf("%v should be equal %v", d1, d2)
	}
}

func TestDiffToHTML(t *testing.T) {
	assertEqual(t, "foo bar biz", diffToHTML([]dmp.Diff{
		dmp.Diff{dmp.DiffEqual, "foo "},
		dmp.Diff{dmp.DiffInsert, "bar"},
		dmp.Diff{dmp.DiffDelete, " baz"},
		dmp.Diff{dmp.DiffEqual, " biz"},
	}, DIFF_LINE_ADD))

	assertEqual(t, "foo bar biz", diffToHTML([]dmp.Diff{
		dmp.Diff{dmp.DiffEqual, "foo "},
		dmp.Diff{dmp.DiffDelete, "bar"},
		dmp.Diff{dmp.DiffInsert, " baz"},
		dmp.Diff{dmp.DiffEqual, " biz"},
	}, DIFF_LINE_DEL))
}

// test if GetLine is return the correct lines
func TestGetLine(t *testing.T) {
	ds := DiffSection{Lines: []*DiffLine{
		&DiffLine{LeftIdx: 28, RightIdx: 28, Type: DIFF_LINE_PLAIN},
		&DiffLine{LeftIdx: 29, RightIdx: 29, Type: DIFF_LINE_PLAIN},
		&DiffLine{LeftIdx: 30, RightIdx: 30, Type: DIFF_LINE_PLAIN},
		&DiffLine{LeftIdx: 31, RightIdx: 0, Type: DIFF_LINE_DEL},
		&DiffLine{LeftIdx: 0, RightIdx: 31, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 0, RightIdx: 32, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 32, RightIdx: 33, Type: DIFF_LINE_PLAIN},
		&DiffLine{LeftIdx: 33, RightIdx: 0, Type: DIFF_LINE_DEL},
		&DiffLine{LeftIdx: 34, RightIdx: 0, Type: DIFF_LINE_DEL},
		&DiffLine{LeftIdx: 35, RightIdx: 0, Type: DIFF_LINE_DEL},
		&DiffLine{LeftIdx: 36, RightIdx: 0, Type: DIFF_LINE_DEL},
		&DiffLine{LeftIdx: 0, RightIdx: 34, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 0, RightIdx: 35, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 0, RightIdx: 36, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 0, RightIdx: 37, Type: DIFF_LINE_ADD},
		&DiffLine{LeftIdx: 37, RightIdx: 38, Type: DIFF_LINE_PLAIN},
		&DiffLine{LeftIdx: 38, RightIdx: 39, Type: DIFF_LINE_PLAIN},
	}}

	assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 31), ds.Lines[4])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 31), ds.Lines[3])

	assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 33), ds.Lines[11])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 34), ds.Lines[12])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 35), ds.Lines[13])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_ADD, 36), ds.Lines[14])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 34), ds.Lines[7])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 35), ds.Lines[8])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 36), ds.Lines[9])
	assertLineEqual(t, ds.GetLine(DIFF_LINE_DEL, 37), ds.Lines[10])
}
<|endoftext|>


<commit_before>// Copyright 2016 Florian Pigorsch. All rights reserved.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package findfont

import (
	"fmt"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"strings"
)

// Find tries to locate the specified font file in the current directory as
// well as in platform specific user and system font directories; if there is
// no exact match, Find tries substring matching.
func Find(fileName string) (filePath string, err error) {
	// check if fileName already points to a readable file
	if _, err := os.Stat(fileName); err == nil {
		return fileName, nil
	}

	// search in user and system directories
	return find(path.Base(fileName))
}

// List returns a list of all font files found on the system.
func List() (filePaths []string) {
	pathList := []string{}

	walkF := func(path string, info os.FileInfo, err error) error {
		if err == nil {
			if info.IsDir() == false && strings.HasSuffix(strings.ToLower(path), ".ttf") {
				pathList = append(pathList, path)
			}
		}
		return nil
	}
	for _, dir := range getFontDirectories() {
		filepath.Walk(dir, walkF)
	}

	return pathList
}

func stripExtension(fileName string) string {
	return strings.TrimSuffix(fileName, filepath.Ext(fileName))
}

func expandUser(path string) (expandedPath string) {
	if strings.HasPrefix(path, "~") {
		if u, err := user.Current(); err == nil {
			return strings.Replace(path, "~", u.HomeDir, -1)
		}
	}
	return path
}

func find(needle string) (filePath string, err error) {
	lowerNeedle := strings.ToLower(needle)
	lowerNeedleBase := stripExtension(lowerNeedle)

	match := ""
	partial := ""
	partialScore := -1

	walkF := func(path string, info os.FileInfo, err error) error {
		// we have already found a match -> nothing to do
		if match != "" {
			return nil
		}
		if err != nil {
			return nil
		}

		lowerPath := strings.ToLower(info.Name())

		if info.IsDir() == false && strings.HasSuffix(lowerPath, ".ttf") {
			lowerBase := stripExtension(lowerPath)
			if lowerPath == lowerNeedle {
				// exact match
				match = path
			} else if strings.Contains(lowerBase, lowerNeedleBase) {
				// partial match
				score := len(lowerBase) - len(lowerNeedle)
				if partialScore < 0 || score < partialScore {
					partialScore = score
					partial = path
				}
			}
		}
		return nil
	}

	for _, dir := range getFontDirectories() {
		filepath.Walk(dir, walkF)
		if match != "" {
			return match, nil
		}
	}

	if partial != "" {
		return partial, nil
	}

	return "", fmt.Errorf("cannot find font '%s' in user or system directories", needle)
}
<commit_msg>Replacing path with filepath<commit_after>// Copyright 2016 Florian Pigorsch. All rights reserved.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package findfont

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"
)

// Find tries to locate the specified font file in the current directory as
// well as in platform specific user and system font directories; if there is
// no exact match, Find tries substring matching.
func Find(fileName string) (filePath string, err error) {
	// check if fileName already points to a readable file
	if _, err := os.Stat(fileName); err == nil {
		return fileName, nil
	}

	// search in user and system directories
	return find(filepath.Base(fileName))
}

// List returns a list of all font files found on the system.
func List() (filePaths []string) {
	pathList := []string{}

	walkF := func(path string, info os.FileInfo, err error) error {
		if err == nil {
			if info.IsDir() == false && strings.HasSuffix(strings.ToLower(path), ".ttf") {
				pathList = append(pathList, path)
			}
		}
		return nil
	}
	for _, dir := range getFontDirectories() {
		filepath.Walk(dir, walkF)
	}

	return pathList
}

func stripExtension(fileName string) string {
	return strings.TrimSuffix(fileName, filepath.Ext(fileName))
}

func expandUser(path string) (expandedPath string) {
	if strings.HasPrefix(path, "~") {
		if u, err := user.Current(); err == nil {
			return strings.Replace(path, "~", u.HomeDir, -1)
		}
	}
	return path
}

func find(needle string) (filePath string, err error) {
	lowerNeedle := strings.ToLower(needle)
	lowerNeedleBase := stripExtension(lowerNeedle)

	match := ""
	partial := ""
	partialScore := -1

	walkF := func(path string, info os.FileInfo, err error) error {
		// we have already found a match -> nothing to do
		if match != "" {
			return nil
		}
		if err != nil {
			return nil
		}

		lowerPath := strings.ToLower(info.Name())

		if info.IsDir() == false && strings.HasSuffix(lowerPath, ".ttf") {
			lowerBase := stripExtension(lowerPath)
			if lowerPath == lowerNeedle {
				// exact match
				match = path
			} else if strings.Contains(lowerBase, lowerNeedleBase) {
				// partial match
				score := len(lowerBase) - len(lowerNeedle)
				if partialScore < 0 || score < partialScore {
					partialScore = score
					partial = path
				}
			}
		}
		return nil
	}

	for _, dir := range getFontDirectories() {
		filepath.Walk(dir, walkF)
		if match != "" {
			return match, nil
		}
	}

	if partial != "" {
		return partial, nil
	}

	return "", fmt.Errorf("cannot find font '%s' in user or system directories", needle)
}
<|endoftext|>


<commit_before>// snippet-comment:[These are tags for the AWS doc team's sample catalog. Do not remove.]
// snippet-sourceauthor:[Doug-AWS]
// snippet-sourcedescription:[DynamoDBListTables.go lists your Amazon DynamoDB tables.]
// snippet-keyword:[Amazon DynamoDB]
// snippet-keyword:[ListTables function]
// snippet-keyword:[Go]
// snippet-service:[dynamodb]
// snippet-keyword:[Code Sample]
// snippet-sourcetype:[full-example]
// snippet-sourcedate:[2019-03-18]
/*
   Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.

   This file is licensed under the Apache License, Version 2.0 (the "License").
   You may not use this file except in compliance with the License. A copy of
   the License is located at

    http://aws.amazon.com/apache2.0/

   This file 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.
*/
// snippet-start:[dynamodb.go.list_tables]
package main

// snippet-start:[dynamodb.go.list_tables.imports]
import (
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/dynamodb"

	"fmt"
)

// snippet-end:[dynamodb.go.list_tables.imports]

func main() {
	// snippet-start:[dynamodb.go.list_tables.session]
	// Initialize a session that the SDK will use to load
	// credentials from the shared credentials file ~/.aws/credentials
	// and region from the shared configuration file ~/.aws/config.
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	}))

	// Create DynamoDB client
	svc := dynamodb.New(sess)
	// snippet-end:[dynamodb.go.list_tables.session]

	// snippet-start:[dynamodb.go.list_tables.call]
	// create the input configuration instance
	input := &dynamodb.ListTablesInput{}

	fmt.Printf("Tables:\n")

	for {
		// Get the list of tables
		result, err := svc.ListTables(input)
		if err != nil {
			if aerr, ok := err.(awserr.Error); ok {
				switch aerr.Code() {
				case dynamodb.ErrCodeInternalServerError:
					fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
				default:
					fmt.Println(aerr.Error())
				}
			} else {
				// Print the error, cast err to awserr.Error to get the Code and
				// Message from an error.
				fmt.Println(err.Error())
			}
			return
		}

		for _, n := range result.TableNames {
			fmt.Println(*n)
		}

		// assign the last read tablename as the start for our next call to the ListTables function
		// the maximum number of table names returned in a call is 100 (default), which requires us to make
		// multiple calls to the ListTables function to retrieve all table names
		input.ExclusiveStartTableName = result.LastEvaluatedTableName

		if result.LastEvaluatedTableName == nil {
			break
		}
	}
	// snippet-end:[dynamodb.go.list_tables.call]
}

// snippet-end:[dynamodb.go.list_tables]
<commit_msg>Update DynamoDBListTables.go<commit_after>// snippet-comment:[These are tags for the AWS doc team's sample catalog. Do not remove.]
// snippet-sourceauthor:[Doug-AWS]
// snippet-sourcedescription:[DynamoDBListTables.go lists your Amazon DynamoDB tables.]
// snippet-keyword:[Amazon DynamoDB]
// snippet-keyword:[ListTables function]
// snippet-keyword:[Go]
// snippet-service:[dynamodb]
// snippet-keyword:[Code Sample]
// snippet-sourcetype:[full-example]
// snippet-sourcedate:[2019-04-24]
/*
   Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.

   This file is licensed under the Apache License, Version 2.0 (the "License").
   You may not use this file except in compliance with the License. A copy of
   the License is located at

    http://aws.amazon.com/apache2.0/

   This file 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.
*/
// snippet-start:[dynamodb.go.list_tables]
package main

// snippet-start:[dynamodb.go.list_tables.imports]
import (
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/dynamodb"

	"fmt"
)

// snippet-end:[dynamodb.go.list_tables.imports]

func main() {
	// snippet-start:[dynamodb.go.list_tables.session]
	// Initialize a session that the SDK will use to load
	// credentials from the shared credentials file ~/.aws/credentials
	// and region from the shared configuration file ~/.aws/config.
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	}))

	// Create DynamoDB client
	svc := dynamodb.New(sess)
	// snippet-end:[dynamodb.go.list_tables.session]

	// snippet-start:[dynamodb.go.list_tables.call]
	// create the input configuration instance
	input := &dynamodb.ListTablesInput{}

	fmt.Printf("Tables:\n")

	for {
		// Get the list of tables
		result, err := svc.ListTables(input)
		if err != nil {
			if aerr, ok := err.(awserr.Error); ok {
				switch aerr.Code() {
				case dynamodb.ErrCodeInternalServerError:
					fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
				default:
					fmt.Println(aerr.Error())
				}
			} else {
				// Print the error, cast err to awserr.Error to get the Code and
				// Message from an error.
				fmt.Println(err.Error())
			}
			return
		}

		for _, n := range result.TableNames {
			fmt.Println(*n)
		}

		// assign the last read tablename as the start for our next call to the ListTables function
		// the maximum number of table names returned in a call is 100 (default), which requires us to make
		// multiple calls to the ListTables function to retrieve all table names
		input.ExclusiveStartTableName = result.LastEvaluatedTableName

		if result.LastEvaluatedTableName == nil {
			break
		}
	}
	// snippet-end:[dynamodb.go.list_tables.call]
}

// snippet-end:[dynamodb.go.list_tables]
<|endoftext|>


<commit_before><commit_msg>cmd/compilebench: use -a instead of -i to ensure dependencies are built<commit_after><|endoftext|>


<commit_before>// Copyright 2019 The Ebiten 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 main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"

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

const (
	ebitenmobileCommand = "ebitenmobile"
)

func init() {
	flag.Usage = func() {
		// This message is copied from `gomobile bind -h`
		fmt.Fprintf(os.Stderr, "%s bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]", ebitenmobileCommand)
		os.Exit(2)
	}
	flag.Parse()
}

func goEnv(name string) string {
	if val := os.Getenv(name); val != "" {
		return val
	}
	val, err := exec.Command("go", "env", name).Output()
	if err != nil {
		panic(err)
	}
	return strings.TrimSpace(string(val))
}

const (
	// Copied from gomobile.
	minAndroidAPI = 15
)

var (
	buildA          bool   // -a
	buildI          bool   // -i
	buildN          bool   // -n
	buildV          bool   // -v
	buildX          bool   // -x
	buildO          string // -o
	buildGcflags    string // -gcflags
	buildLdflags    string // -ldflags
	buildTarget     string // -target
	buildWork       bool   // -work
	buildBundleID   string // -bundleid
	buildIOSVersion string // -iosversion
	buildAndroidAPI int    // -androidapi
	buildTags       string // -tags

	bindPrefix        string // -prefix
	bindJavaPkg       string // -javapkg
	bindClasspath     string // -classpath
	bindBootClasspath string // -bootclasspath
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		flag.Usage()
	}

	var flagset flag.FlagSet
	flagset.StringVar(&buildO, "o", "", "")
	flagset.StringVar(&buildGcflags, "gcflags", "", "")
	flagset.StringVar(&buildLdflags, "ldflags", "", "")
	flagset.StringVar(&buildTarget, "target", "android", "")
	flagset.StringVar(&buildBundleID, "bundleid", "", "")
	flagset.StringVar(&buildIOSVersion, "iosversion", "7.0", "")
	flagset.StringVar(&buildTags, "tags", "", "")
	flagset.IntVar(&buildAndroidAPI, "androidapi", minAndroidAPI, "")
	flagset.BoolVar(&buildA, "a", false, "")
	flagset.BoolVar(&buildI, "i", false, "")
	flagset.BoolVar(&buildN, "n", false, "")
	flagset.BoolVar(&buildV, "v", false, "")
	flagset.BoolVar(&buildX, "x", false, "")
	flagset.BoolVar(&buildWork, "work", false, "")
	flagset.StringVar(&bindJavaPkg, "javapkg", "", "")
	flagset.StringVar(&bindPrefix, "prefix", "", "")
	flagset.StringVar(&bindClasspath, "classpath", "", "")
	flagset.StringVar(&bindBootClasspath, "bootclasspath", "", "")

	flagset.Parse(args[1:])

	// Add ldflags to suppress linker errors (#932).
	// See https://github.com/golang/go/issues/17807
	if buildLdflags == "" {
		buildLdflags += " "
	}
	buildLdflags += "-extldflags=-Wl,-soname,libgojni.so"

	if err := prepareGomobileCommands(); err != nil {
		log.Fatal(err)
	}

	switch args[0] {
	case "bind":
		if err := doBind(args, &flagset); err != nil {
			log.Fatal(err)
		}
	default:
		flag.Usage()
	}
}

func doBind(args []string, flagset *flag.FlagSet) error {
	tags := buildTags
	cfg := &packages.Config{}
	switch buildTarget {
	case "android":
		cfg.Env = append(os.Environ(), "GOOS=android")
	case "ios":
		cfg.Env = append(os.Environ(), "GOOS=darwin")
		if tags != "" {
			tags += " "
		}
		tags += "ios"
	}
	cfg.BuildFlags = []string{"-tags", tags}

	pkgs, err := packages.Load(cfg, flagset.Args()[0])
	if err != nil {
		return err
	}
	prefixLower := bindPrefix + pkgs[0].Name
	prefixUpper := strings.Title(bindPrefix) + strings.Title(pkgs[0].Name)

	args = append(args, "github.com/hajimehoshi/ebiten/mobile/ebitenmobileview")

	if buildO == "" {
		fmt.Fprintln(os.Stderr, "-o must be specified.")
		os.Exit(2)
		return nil
	}

	if buildN {
		fmt.Print("gomobile")
		for _, arg := range args {
			fmt.Print(" ", arg)
		}
		fmt.Println()
		return nil
	}

	cmd := exec.Command("gomobile", args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		os.Exit(err.(*exec.ExitError).ExitCode())
		return nil
	}

	replacePrefixes := func(content string) string {
		content = strings.ReplaceAll(content, "{{.PrefixUpper}}", prefixUpper)
		content = strings.ReplaceAll(content, "{{.PrefixLower}}", prefixLower)
		return content
	}

	switch buildTarget {
	case "android":
		// Do nothing.
	case "ios":
		dir := filepath.Join(buildO, "Versions", "A")

		if err := ioutil.WriteFile(filepath.Join(dir, "Headers", prefixUpper+"EbitenViewController.h"), []byte(replacePrefixes(objcH)), 0644); err != nil {
			return err
		}
		// TODO: Remove 'Ebitenmobileview.objc.h' here. Now it is hard since there is a header file importing
		// that header file.

		fs, err := ioutil.ReadDir(filepath.Join(dir, "Headers"))
		if err != nil {
			return err
		}
		var headerFiles []string
		for _, f := range fs {
			if strings.HasSuffix(f.Name(), ".h") {
				headerFiles = append(headerFiles, f.Name())
			}
		}

		w, err := os.OpenFile(filepath.Join(dir, "Modules", "module.modulemap"), os.O_WRONLY, 0644)
		if err != nil {
			return err
		}
		defer w.Close()
		var mmVals = struct {
			Module  string
			Headers []string
		}{
			Module:  prefixUpper,
			Headers: headerFiles,
		}
		if err := iosModuleMapTmpl.Execute(w, mmVals); err != nil {
			return err
		}

		// TODO: Remove Ebitenmobileview.objc.h?
	}

	return nil
}

const objcH = `// Code generated by ebitenmobile. DO NOT EDIT.

#import <UIKit/UIKit.h>

@interface {{.PrefixUpper}}EbitenViewController : UIViewController

// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
// You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
- (void)onErrorOnGameUpdate:(NSError*)err;

// suspendGame suspends the game.
// It is recommended to call this when the application is being suspended e.g.,
// UIApplicationDelegate's applicationWillResignActive is called.
- (void)suspendGame;

// resumeGame resumes the game.
// It is recommended to call this when the application is being resumed e.g.,
// UIApplicationDelegate's applicationDidBecomeActive is called.
- (void)resumeGame;

@end
`

var iosModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework module "{{.Module}}" {
{{range .Headers}}    header "{{.}}"
{{end}}
    export *
}`))
<commit_msg>cmd/ebitenmobile: Add -trimpath<commit_after>// Copyright 2019 The Ebiten 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 main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"

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

const (
	ebitenmobileCommand = "ebitenmobile"
)

func init() {
	flag.Usage = func() {
		// This message is copied from `gomobile bind -h`
		fmt.Fprintf(os.Stderr, "%s bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]", ebitenmobileCommand)
		os.Exit(2)
	}
	flag.Parse()
}

func goEnv(name string) string {
	if val := os.Getenv(name); val != "" {
		return val
	}
	val, err := exec.Command("go", "env", name).Output()
	if err != nil {
		panic(err)
	}
	return strings.TrimSpace(string(val))
}

const (
	// Copied from gomobile.
	minAndroidAPI = 15
)

var (
	buildA          bool   // -a
	buildI          bool   // -i
	buildN          bool   // -n
	buildV          bool   // -v
	buildX          bool   // -x
	buildO          string // -o
	buildGcflags    string // -gcflags
	buildLdflags    string // -ldflags
	buildTarget     string // -target
	buildTrimpath   bool   // -trimpath
	buildWork       bool   // -work
	buildBundleID   string // -bundleid
	buildIOSVersion string // -iosversion
	buildAndroidAPI int    // -androidapi
	buildTags       string // -tags

	bindPrefix        string // -prefix
	bindJavaPkg       string // -javapkg
	bindClasspath     string // -classpath
	bindBootClasspath string // -bootclasspath
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		flag.Usage()
	}

	var flagset flag.FlagSet
	flagset.StringVar(&buildO, "o", "", "")
	flagset.StringVar(&buildGcflags, "gcflags", "", "")
	flagset.StringVar(&buildLdflags, "ldflags", "", "")
	flagset.StringVar(&buildTarget, "target", "android", "")
	flagset.StringVar(&buildBundleID, "bundleid", "", "")
	flagset.StringVar(&buildIOSVersion, "iosversion", "7.0", "")
	flagset.StringVar(&buildTags, "tags", "", "")
	flagset.IntVar(&buildAndroidAPI, "androidapi", minAndroidAPI, "")
	flagset.BoolVar(&buildA, "a", false, "")
	flagset.BoolVar(&buildI, "i", false, "")
	flagset.BoolVar(&buildN, "n", false, "")
	flagset.BoolVar(&buildV, "v", false, "")
	flagset.BoolVar(&buildX, "x", false, "")
	flagset.BoolVar(&buildTrimpath, "trimpath", false, "")
	flagset.BoolVar(&buildWork, "work", false, "")
	flagset.StringVar(&bindJavaPkg, "javapkg", "", "")
	flagset.StringVar(&bindPrefix, "prefix", "", "")
	flagset.StringVar(&bindClasspath, "classpath", "", "")
	flagset.StringVar(&bindBootClasspath, "bootclasspath", "", "")

	flagset.Parse(args[1:])

	// Add ldflags to suppress linker errors (#932).
	// See https://github.com/golang/go/issues/17807
	if buildLdflags == "" {
		buildLdflags += " "
	}
	buildLdflags += "-extldflags=-Wl,-soname,libgojni.so"

	if err := prepareGomobileCommands(); err != nil {
		log.Fatal(err)
	}

	switch args[0] {
	case "bind":
		if err := doBind(args, &flagset); err != nil {
			log.Fatal(err)
		}
	default:
		flag.Usage()
	}
}

func doBind(args []string, flagset *flag.FlagSet) error {
	tags := buildTags
	cfg := &packages.Config{}
	switch buildTarget {
	case "android":
		cfg.Env = append(os.Environ(), "GOOS=android")
	case "ios":
		cfg.Env = append(os.Environ(), "GOOS=darwin")
		if tags != "" {
			tags += " "
		}
		tags += "ios"
	}
	cfg.BuildFlags = []string{"-tags", tags}

	pkgs, err := packages.Load(cfg, flagset.Args()[0])
	if err != nil {
		return err
	}
	prefixLower := bindPrefix + pkgs[0].Name
	prefixUpper := strings.Title(bindPrefix) + strings.Title(pkgs[0].Name)

	args = append(args, "github.com/hajimehoshi/ebiten/mobile/ebitenmobileview")

	if buildO == "" {
		fmt.Fprintln(os.Stderr, "-o must be specified.")
		os.Exit(2)
		return nil
	}

	if buildN {
		fmt.Print("gomobile")
		for _, arg := range args {
			fmt.Print(" ", arg)
		}
		fmt.Println()
		return nil
	}

	cmd := exec.Command("gomobile", args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		os.Exit(err.(*exec.ExitError).ExitCode())
		return nil
	}

	replacePrefixes := func(content string) string {
		content = strings.ReplaceAll(content, "{{.PrefixUpper}}", prefixUpper)
		content = strings.ReplaceAll(content, "{{.PrefixLower}}", prefixLower)
		return content
	}

	switch buildTarget {
	case "android":
		// Do nothing.
	case "ios":
		dir := filepath.Join(buildO, "Versions", "A")

		if err := ioutil.WriteFile(filepath.Join(dir, "Headers", prefixUpper+"EbitenViewController.h"), []byte(replacePrefixes(objcH)), 0644); err != nil {
			return err
		}
		// TODO: Remove 'Ebitenmobileview.objc.h' here. Now it is hard since there is a header file importing
		// that header file.

		fs, err := ioutil.ReadDir(filepath.Join(dir, "Headers"))
		if err != nil {
			return err
		}
		var headerFiles []string
		for _, f := range fs {
			if strings.HasSuffix(f.Name(), ".h") {
				headerFiles = append(headerFiles, f.Name())
			}
		}

		w, err := os.OpenFile(filepath.Join(dir, "Modules", "module.modulemap"), os.O_WRONLY, 0644)
		if err != nil {
			return err
		}
		defer w.Close()
		var mmVals = struct {
			Module  string
			Headers []string
		}{
			Module:  prefixUpper,
			Headers: headerFiles,
		}
		if err := iosModuleMapTmpl.Execute(w, mmVals); err != nil {
			return err
		}

		// TODO: Remove Ebitenmobileview.objc.h?
	}

	return nil
}

const objcH = `// Code generated by ebitenmobile. DO NOT EDIT.

#import <UIKit/UIKit.h>

@interface {{.PrefixUpper}}EbitenViewController : UIViewController

// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
// You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
- (void)onErrorOnGameUpdate:(NSError*)err;

// suspendGame suspends the game.
// It is recommended to call this when the application is being suspended e.g.,
// UIApplicationDelegate's applicationWillResignActive is called.
- (void)suspendGame;

// resumeGame resumes the game.
// It is recommended to call this when the application is being resumed e.g.,
// UIApplicationDelegate's applicationDidBecomeActive is called.
- (void)resumeGame;

@end
`

var iosModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework module "{{.Module}}" {
{{range .Headers}}    header "{{.}}"
{{end}}
    export *
}`))
<|endoftext|>


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

package cmd

import (
	"fmt"
	"strings"

	"github.com/minio/minio-go/pkg/set"
	"github.com/minio/minio/pkg/ellipses"
)

// This file implements and supports ellipses pattern for
// `minio server` command line arguments.

// Maximum number of unique args supported on the command line.
const (
	serverCommandLineArgsMax = 32
)

// Endpoint set represents parsed ellipses values, also provides
// methods to get the sets of endpoints.
type endpointSet struct {
	argPatterns []ellipses.ArgPattern
	endpoints   []string   // Endpoints saved from previous GetEndpoints().
	setIndexes  [][]uint64 // All the sets.
}

// Supported set sizes this is used to find the optimal
// single set size.
var setSizes = []uint64{4, 6, 8, 10, 12, 14, 16}

// getDivisibleSize - returns a greatest common divisor of
// all the ellipses sizes.
func getDivisibleSize(totalSizes []uint64) (result uint64) {
	gcd := func(x, y uint64) uint64 {
		for y != 0 {
			x, y = y, x%y
		}
		return x
	}
	result = totalSizes[0]
	for i := 1; i < len(totalSizes); i++ {
		result = gcd(result, totalSizes[i])
	}
	return result
}

// getSetIndexes returns list of indexes which provides the set size
// on each index, this function also determines the final set size
// The final set size has the affinity towards choosing smaller
// indexes (total sets)
func getSetIndexes(args []string, totalSizes []uint64) (setIndexes [][]uint64, err error) {
	if len(totalSizes) == 0 || len(args) == 0 {
		return nil, errInvalidArgument
	}

	setIndexes = make([][]uint64, len(totalSizes))
	for i, totalSize := range totalSizes {
		// Check if totalSize has minimum range upto setSize
		if totalSize < setSizes[0] {
			return nil, fmt.Errorf("Invalid inputs (%s). Ellipses range or number of args %d should be atleast divisible by least possible set size %d",
				args[i], totalSize, setSizes[0])
		}
	}

	var setSize uint64

	commonSize := getDivisibleSize(totalSizes)
	if commonSize > setSizes[len(setSizes)-1] {
		prevD := commonSize / setSizes[0]
		for _, i := range setSizes {
			if commonSize%i == 0 {
				d := commonSize / i
				if d <= prevD {
					prevD = d
					setSize = i
				}
			}
		}
	} else {
		setSize = commonSize
	}

	// isValidSetSize - checks whether given count is a valid set size for erasure coding.
	isValidSetSize := func(count uint64) bool {
		return (count >= setSizes[0] && count <= setSizes[len(setSizes)-1] && count%2 == 0)
	}

	// Check whether setSize is with the supported range.
	if !isValidSetSize(setSize) {
		return nil, fmt.Errorf("Invalid inputs (%s). Ellipses range or number of args %d should be atleast divisible by least possible set size %d",
			args, setSize, setSizes[0])
	}

	for i := range totalSizes {
		for j := uint64(0); j < totalSizes[i]/setSize; j++ {
			setIndexes[i] = append(setIndexes[i], setSize)
		}
	}

	return setIndexes, nil
}

// Returns all the expanded endpoints, each argument is expanded separately.
func (s endpointSet) getEndpoints() (endpoints []string) {
	if len(s.endpoints) != 0 {
		return s.endpoints
	}
	for _, argPattern := range s.argPatterns {
		for _, lbls := range argPattern.Expand() {
			endpoints = append(endpoints, strings.Join(lbls, ""))
		}
	}
	s.endpoints = endpoints
	return endpoints
}

// Get returns the sets representation of the endpoints
// this function also intelligently decides on what will
// be the right set size etc.
func (s endpointSet) Get() (sets [][]string) {
	var k = uint64(0)
	endpoints := s.getEndpoints()
	for i := range s.setIndexes {
		for j := range s.setIndexes[i] {
			sets = append(sets, endpoints[k:s.setIndexes[i][j]+k])
			k = s.setIndexes[i][j] + k
		}
	}

	return sets
}

// Return the total size for each argument patterns.
func getTotalSizes(argPatterns []ellipses.ArgPattern) []uint64 {
	var totalSizes []uint64
	for _, argPattern := range argPatterns {
		var totalSize uint64 = 1
		for _, p := range argPattern {
			totalSize = totalSize * uint64(len(p.Seq))
		}
		totalSizes = append(totalSizes, totalSize)
	}
	return totalSizes
}

// Parses all arguments and returns an endpointSet which is a collection
// of endpoints following the ellipses pattern, this is what is used
// by the object layer for initializing itself.
func parseEndpointSet(args ...string) (ep endpointSet, err error) {
	var argPatterns = make([]ellipses.ArgPattern, len(args))
	for i, arg := range args {
		patterns, err := ellipses.FindEllipsesPatterns(arg)
		if err != nil {
			return endpointSet{}, err
		}
		argPatterns[i] = patterns
	}

	ep.setIndexes, err = getSetIndexes(args, getTotalSizes(argPatterns))
	if err != nil {
		return endpointSet{}, err
	}

	ep.argPatterns = argPatterns

	return ep, nil
}

// Parses all ellipses input arguments, expands them into corresponding
// list of endpoints chunked evenly in accordance with a specific
// set size.
// For example: {1...64} is divided into 4 sets each of size 16.
// This applies to even distributed setup syntax as well.
func getAllSets(args ...string) ([][]string, error) {
	if len(args) == 0 {
		return nil, errInvalidArgument
	}

	var setArgs [][]string
	if !ellipses.HasEllipses(args...) {
		var setIndexes [][]uint64
		// Check if we have more one args.
		if len(args) > 1 {
			var err error
			setIndexes, err = getSetIndexes(args, []uint64{uint64(len(args))})
			if err != nil {
				return nil, err
			}
		} else {
			// We are in FS setup, proceed forward.
			setIndexes = [][]uint64{{uint64(len(args))}}
		}
		s := endpointSet{
			endpoints:  args,
			setIndexes: setIndexes,
		}
		setArgs = s.Get()
	} else {
		s, err := parseEndpointSet(args...)
		if err != nil {
			return nil, err
		}
		setArgs = s.Get()
	}

	uniqueArgs := set.NewStringSet()
	for _, sargs := range setArgs {
		for _, arg := range sargs {
			if uniqueArgs.Contains(arg) {
				return nil, fmt.Errorf("Input args (%s) has duplicate ellipses", args)
			}
			uniqueArgs.Add(arg)
		}
	}

	return setArgs, nil
}

// CreateServerEndpoints - validates and creates new endpoints from input args, supports
// both ellipses and without ellipses transparently.
func createServerEndpoints(serverAddr string, args ...string) (string, EndpointList, SetupType, int, int, error) {
	setArgs, err := getAllSets(args...)
	if err != nil {
		return serverAddr, nil, -1, 0, 0, err
	}

	var endpoints EndpointList
	var setupType SetupType
	serverAddr, endpoints, setupType, err = CreateEndpoints(serverAddr, setArgs...)
	if err != nil {
		return serverAddr, nil, -1, 0, 0, err
	}

	return serverAddr, endpoints, setupType, len(setArgs), len(setArgs[0]), nil
}
<commit_msg>Fix shadowing issue reported by go vet (#5590)<commit_after>/*
 * Minio Cloud Storage, (C) 2018 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"fmt"
	"strings"

	"github.com/minio/minio-go/pkg/set"
	"github.com/minio/minio/pkg/ellipses"
)

// This file implements and supports ellipses pattern for
// `minio server` command line arguments.

// Maximum number of unique args supported on the command line.
const (
	serverCommandLineArgsMax = 32
)

// Endpoint set represents parsed ellipses values, also provides
// methods to get the sets of endpoints.
type endpointSet struct {
	argPatterns []ellipses.ArgPattern
	endpoints   []string   // Endpoints saved from previous GetEndpoints().
	setIndexes  [][]uint64 // All the sets.
}

// Supported set sizes this is used to find the optimal
// single set size.
var setSizes = []uint64{4, 6, 8, 10, 12, 14, 16}

// getDivisibleSize - returns a greatest common divisor of
// all the ellipses sizes.
func getDivisibleSize(totalSizes []uint64) (result uint64) {
	gcd := func(x, y uint64) uint64 {
		for y != 0 {
			x, y = y, x%y
		}
		return x
	}
	result = totalSizes[0]
	for i := 1; i < len(totalSizes); i++ {
		result = gcd(result, totalSizes[i])
	}
	return result
}

// getSetIndexes returns list of indexes which provides the set size
// on each index, this function also determines the final set size
// The final set size has the affinity towards choosing smaller
// indexes (total sets)
func getSetIndexes(args []string, totalSizes []uint64) (setIndexes [][]uint64, err error) {
	if len(totalSizes) == 0 || len(args) == 0 {
		return nil, errInvalidArgument
	}

	setIndexes = make([][]uint64, len(totalSizes))
	for i, totalSize := range totalSizes {
		// Check if totalSize has minimum range upto setSize
		if totalSize < setSizes[0] {
			return nil, fmt.Errorf("Invalid inputs (%s). Ellipses range or number of args %d should be atleast divisible by least possible set size %d",
				args[i], totalSize, setSizes[0])
		}
	}

	var setSize uint64

	commonSize := getDivisibleSize(totalSizes)
	if commonSize > setSizes[len(setSizes)-1] {
		prevD := commonSize / setSizes[0]
		for _, i := range setSizes {
			if commonSize%i == 0 {
				d := commonSize / i
				if d <= prevD {
					prevD = d
					setSize = i
				}
			}
		}
	} else {
		setSize = commonSize
	}

	// isValidSetSize - checks whether given count is a valid set size for erasure coding.
	isValidSetSize := func(count uint64) bool {
		return (count >= setSizes[0] && count <= setSizes[len(setSizes)-1] && count%2 == 0)
	}

	// Check whether setSize is with the supported range.
	if !isValidSetSize(setSize) {
		return nil, fmt.Errorf("Invalid inputs (%s). Ellipses range or number of args %d should be atleast divisible by least possible set size %d",
			args, setSize, setSizes[0])
	}

	for i := range totalSizes {
		for j := uint64(0); j < totalSizes[i]/setSize; j++ {
			setIndexes[i] = append(setIndexes[i], setSize)
		}
	}

	return setIndexes, nil
}

// Returns all the expanded endpoints, each argument is expanded separately.
func (s endpointSet) getEndpoints() (endpoints []string) {
	if len(s.endpoints) != 0 {
		return s.endpoints
	}
	for _, argPattern := range s.argPatterns {
		for _, lbls := range argPattern.Expand() {
			endpoints = append(endpoints, strings.Join(lbls, ""))
		}
	}
	s.endpoints = endpoints
	return endpoints
}

// Get returns the sets representation of the endpoints
// this function also intelligently decides on what will
// be the right set size etc.
func (s endpointSet) Get() (sets [][]string) {
	var k = uint64(0)
	endpoints := s.getEndpoints()
	for i := range s.setIndexes {
		for j := range s.setIndexes[i] {
			sets = append(sets, endpoints[k:s.setIndexes[i][j]+k])
			k = s.setIndexes[i][j] + k
		}
	}

	return sets
}

// Return the total size for each argument patterns.
func getTotalSizes(argPatterns []ellipses.ArgPattern) []uint64 {
	var totalSizes []uint64
	for _, argPattern := range argPatterns {
		var totalSize uint64 = 1
		for _, p := range argPattern {
			totalSize = totalSize * uint64(len(p.Seq))
		}
		totalSizes = append(totalSizes, totalSize)
	}
	return totalSizes
}

// Parses all arguments and returns an endpointSet which is a collection
// of endpoints following the ellipses pattern, this is what is used
// by the object layer for initializing itself.
func parseEndpointSet(args ...string) (ep endpointSet, err error) {
	var argPatterns = make([]ellipses.ArgPattern, len(args))
	for i, arg := range args {
		patterns, perr := ellipses.FindEllipsesPatterns(arg)
		if perr != nil {
			return endpointSet{}, perr
		}
		argPatterns[i] = patterns
	}

	ep.setIndexes, err = getSetIndexes(args, getTotalSizes(argPatterns))
	if err != nil {
		return endpointSet{}, err
	}

	ep.argPatterns = argPatterns

	return ep, nil
}

// Parses all ellipses input arguments, expands them into corresponding
// list of endpoints chunked evenly in accordance with a specific
// set size.
// For example: {1...64} is divided into 4 sets each of size 16.
// This applies to even distributed setup syntax as well.
func getAllSets(args ...string) ([][]string, error) {
	if len(args) == 0 {
		return nil, errInvalidArgument
	}

	var setArgs [][]string
	if !ellipses.HasEllipses(args...) {
		var setIndexes [][]uint64
		// Check if we have more one args.
		if len(args) > 1 {
			var err error
			setIndexes, err = getSetIndexes(args, []uint64{uint64(len(args))})
			if err != nil {
				return nil, err
			}
		} else {
			// We are in FS setup, proceed forward.
			setIndexes = [][]uint64{{uint64(len(args))}}
		}
		s := endpointSet{
			endpoints:  args,
			setIndexes: setIndexes,
		}
		setArgs = s.Get()
	} else {
		s, err := parseEndpointSet(args...)
		if err != nil {
			return nil, err
		}
		setArgs = s.Get()
	}

	uniqueArgs := set.NewStringSet()
	for _, sargs := range setArgs {
		for _, arg := range sargs {
			if uniqueArgs.Contains(arg) {
				return nil, fmt.Errorf("Input args (%s) has duplicate ellipses", args)
			}
			uniqueArgs.Add(arg)
		}
	}

	return setArgs, nil
}

// CreateServerEndpoints - validates and creates new endpoints from input args, supports
// both ellipses and without ellipses transparently.
func createServerEndpoints(serverAddr string, args ...string) (string, EndpointList, SetupType, int, int, error) {
	setArgs, err := getAllSets(args...)
	if err != nil {
		return serverAddr, nil, -1, 0, 0, err
	}

	var endpoints EndpointList
	var setupType SetupType
	serverAddr, endpoints, setupType, err = CreateEndpoints(serverAddr, setArgs...)
	if err != nil {
		return serverAddr, nil, -1, 0, 0, err
	}

	return serverAddr, endpoints, setupType, len(setArgs), len(setArgs[0]), nil
}
<|endoftext|>