<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/docopt/docopt-go"
	"github.com/jesand/crowds/amt"
	xsdt "github.com/metaleap/go-xsd/types"
	"os"
	"reflect"
	"sort"
	"strconv"
)

const (
	USAGE = `hiclusterd - Web service hosting for hicluster

Usage:
  amtadmin assns --hit=<id> [--status=<str>] [--sort=<field>] [--desc] ` +
		`[--page=<num>] [--pageSize=<num>] --amt=<path> [--sandbox]
  amtadmin balance --amt=<path> [--sandbox]
  amtadmin expire [--hit=<id>] [--all] --amt=<path> [--sandbox]
  amtadmin hits [--sort=<field>] [--desc] [--page=<num>] [--pageSize=<num>] ` +
		`--amt=<path> [--sandbox]
  amtadmin show [--hit=<id>] [--assn=<id>] --amt=<path> [--sandbox]
  amtadmin -h | --help
  amtadmin --version

Options:
  assns             Find assignments for a HIT
  balance           Get the account balance
  expire            Force-expire the specified HIT
  hits              Find matching HITs
  show              Display the status of a HIT or Assignment
  --all             Operate on all applicable objects
  --amt=<path>      The path to a file containing AMT credentials
  --sandbox         Address the AMT sandbox instead of the production site
  --hit=<id>        The ID of the HIT you want to view
  --assn=<id>       The ID of the assignment you want to view
  --sort=<field>    The field to sort by. For hits, one of: CreationTime,
                    Enumeration, Expiration, Reward, or Title. For assns, one
                    of: AcceptTime, SubmitTime, or AssignmentStatus.
  --status=<str>    The assignment status to search for. Can be:
                    Submitted, Approved, or Rejected.
  --desc            Sort results in descending order
  --page=<num>      The page number of results to display [default: 1]
  --pageSize=<num>  The number of results to display per page [default: 10]
`
)

type AmtCred struct {
	AccessKey, SecretKey string
}

func main() {

	// Parse the command line
	args, _ := docopt.Parse(USAGE, nil, true, "1.0", false)

	// Initialize the AMT client
	var (
		credPath = args["--amt"].(string)
		sandbox  = args["--sandbox"].(bool)
		amtCred  AmtCred
		client   amt.AmtClient
	)
	if f, err := os.Open(credPath); err != nil {
		fmt.Printf("Error: Could not open %s - %v", credPath, err)
		return
	} else if err = json.NewDecoder(f).Decode(&amtCred); err != nil {
		fmt.Printf("Error: Could not parse %s - %v", credPath, err)
		return
	} else {
		client = amt.NewClient(amtCred.AccessKey, amtCred.SecretKey, sandbox)
	}

	switch {
	case args["assns"].(bool):
		var (
			hitId, _              = args["--hit"].(string)
			status, _             = args["--status"].(string)
			sort, _               = args["--sort"].(string)
			desc                  = args["--desc"].(bool)
			page, pageErr         = strconv.Atoi(args["--page"].(string))
			pageSize, pageSizeErr = strconv.Atoi(args["--pageSize"].(string))
			statuses              []string
		)
		if sort == "" {
			sort = "AcceptTime"
		}
		if status != "" {
			statuses = append(statuses, status)
		}
		if pageErr != nil {
			fmt.Printf("Invalid --page argument\n")
		} else if pageSizeErr != nil {
			fmt.Printf("Invald --pageSize argument\n")
		} else {
			RunAssns(client, hitId, statuses, sort, desc, page, pageSize)
		}

	case args["balance"].(bool):
		RunBalance(client)

	case args["expire"].(bool):
		var (
			all      = args["--all"].(bool)
			hitId, _ = args["--hit"].(string)
		)
		RunExpire(client, hitId, all)

	case args["hits"].(bool):
		var (
			sort, _               = args["--sort"].(string)
			desc                  = args["--desc"].(bool)
			page, pageErr         = strconv.Atoi(args["--page"].(string))
			pageSize, pageSizeErr = strconv.Atoi(args["--pageSize"].(string))
		)
		if sort == "" {
			sort = "CreationTime"
		}
		if pageErr != nil {
			fmt.Printf("Invalid --page argument\n")
		} else if pageSizeErr != nil {
			fmt.Printf("Invald --pageSize argument\n")
		} else {
			RunHits(client, sort, desc, page, pageSize)
		}

	case args["show"].(bool):
		hitId, _ := args["--hit"].(string)
		assnId, _ := args["--assn"].(string)
		RunShow(client, hitId, assnId)
	}
}

func getObjectFields(object interface{}, vals map[string]string) {
	v := reflect.Indirect(reflect.ValueOf(object))
	if !v.IsValid() {
		return
	}
	t := v.Type()
	switch t.Kind() {
	case reflect.Slice:
		for i := 0; i < v.Len(); i++ {
			getObjectFields(v.Index(i).Interface(), vals)
		}
	case reflect.Struct:
		for i := 0; i < t.NumField(); i++ {
			field := t.Field(i)
			switch field.Type.Kind() {
			case reflect.Struct, reflect.Ptr, reflect.Slice:
				getObjectFields(v.Field(i).Interface(), vals)
			default:
				if field.Type == reflect.TypeOf(xsdt.Int(0)) {
					vals[field.Name] = fmt.Sprintf("%d", v.Field(i).Interface())
				} else if field.Type == reflect.TypeOf(xsdt.Long(0)) {
					vals[field.Name] = fmt.Sprintf("%d", v.Field(i).Interface())
				} else {
					vals[field.Name] = v.Field(i).String()
				}
			}
		}
	}
}

func printObject(object interface{}) {
	var (
		fields   []string
		vals     = make(map[string]string)
		fieldLen int
	)
	getObjectFields(object, vals)
	for name, _ := range vals {
		fields = append(fields, name)
		if len(name) > fieldLen {
			fieldLen = len(name)
		}
	}
	sort.Strings(fields)
	format := fmt.Sprintf("%%%ds: %%s\n", fieldLen)
	for _, name := range fields {
		fmt.Printf(format, name, vals[name])
	}
}

func RunAssns(client amt.AmtClient, hitId string, statuses []string, sort string, desc bool, page, pageSize int) {
	if resp, err := client.GetAssignmentsForHIT(hitId, statuses, sort, !desc,
		pageSize, page); err != nil {

		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	} else if len(resp.GetAssignmentsForHITResults) > 0 &&
		resp.GetAssignmentsForHITResults[0].Request != nil &&
		resp.GetAssignmentsForHITResults[0].Request.Errors != nil {

		printObject(resp.GetAssignmentsForHITResults[0].Request)
	} else if len(resp.GetAssignmentsForHITResults[0].Assignments) == 0 {
		fmt.Println("Found no assignments for this HIT")
	} else {
		for i, assn := range resp.GetAssignmentsForHITResults[0].Assignments {
			fmt.Printf("Assignment %d/%d:\n", i+1, len(resp.GetAssignmentsForHITResults))
			printObject(assn)
			fmt.Println()
		}
	}
}

func RunBalance(client amt.AmtClient) {
	balance, err := client.GetAccountBalance()
	if err != nil {
		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	}
	printObject(balance)
}

func RunExpire(client amt.AmtClient, hitId string, all bool) {
	if all {
		const maxHits = 100
		if resp, err := client.SearchHITs("CreationTime", false, maxHits, 1); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.SearchHITsResults) > 0 &&
			resp.SearchHITsResults[0].Request != nil &&
			resp.SearchHITsResults[0].Request.Errors != nil {

			printObject(resp.SearchHITsResults[0].Request)
		} else if len(resp.SearchHITsResults[0].Hits) == 0 {
			fmt.Println("Found no HITs for this account")
		} else {
			for _, hit := range resp.SearchHITsResults[0].Hits {
				if hit.HITStatus == "Assignable" {
					fmt.Printf("Expire HIT %q with %d available assignments\n",
						hit.HITId, hit.NumberOfAssignmentsAvailable)
					RunExpire(client, string(hit.HITId), false)
				}
			}
			if len(resp.SearchHITsResults[0].Hits) == maxHits {
				fmt.Println("Retrieved the maximum number of HITs. Repeat the command to find any remaining HITs.")
			}
		}
	} else if resp, err := client.ForceExpireHIT(hitId); err != nil {
		fmt.Printf("Error: Could not expire HIT - %v", err)
	} else {
		printObject(resp)
	}
}

func RunHits(client amt.AmtClient, sort string, desc bool, page, pageSize int) {
	if resp, err := client.SearchHITs(sort, !desc, pageSize, page); err != nil {
		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	} else if len(resp.SearchHITsResults) > 0 &&
		resp.SearchHITsResults[0].Request != nil &&
		resp.SearchHITsResults[0].Request.Errors != nil {

		printObject(resp.SearchHITsResults[0].Request)
	} else if len(resp.SearchHITsResults[0].Hits) == 0 {
		fmt.Println("Found no HITs for this account")
	} else {
		for i, hit := range resp.SearchHITsResults[0].Hits {
			fmt.Printf("HIT %d/%d:\n", i+1, len(resp.SearchHITsResults))
			printObject(hit)
			fmt.Println()
		}
	}
}

func RunShow(client amt.AmtClient, hitId, assnId string) {
	switch {
	case hitId != "":
		if resp, err := client.GetHIT(hitId); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.Hits) > 0 && resp.Hits[0].Request != nil &&
			resp.Hits[0].Request.Errors != nil {

			printObject(resp.Hits[0].Request)
		} else {
			printObject(resp)
		}

	case assnId != "":
		if resp, err := client.GetAssignment(assnId); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.GetAssignmentResults) > 0 &&
			resp.GetAssignmentResults[0].Request != nil &&
			resp.GetAssignmentResults[0].Request.Errors != nil {

			printObject(resp.GetAssignmentResults[0].Request)
		} else {
			printObject(resp)
		}

	default:
		fmt.Println("You must provide a value for either --hit or --assn")
	}
}
<commit_msg>added the bonus command<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/docopt/docopt-go"
	"github.com/jesand/crowds/amt"
	xsdt "github.com/metaleap/go-xsd/types"
	"os"
	"reflect"
	"sort"
	"strconv"
)

const (
	USAGE = `hiclusterd - Web service hosting for hicluster

Usage:
  amtadmin assns --hit=<id> [--status=<str>] [--sort=<field>] [--desc] ` +
		`[--page=<num>] [--pageSize=<num>] --amt=<path> [--sandbox]
  amtadmin balance --amt=<path> [--sandbox]
  amtadmin bonus --worker=<id> --assn=<id> --amount=<num> --reason=<str> ` +
		`--token=<str> --amt=<path> [--sandbox]
  amtadmin expire [--hit=<id>] [--all] --amt=<path> [--sandbox]
  amtadmin hits [--sort=<field>] [--desc] [--page=<num>] [--pageSize=<num>] ` +
		`--amt=<path> [--sandbox]
  amtadmin show [--hit=<id>] [--assn=<id>] --amt=<path> [--sandbox]
  amtadmin -h | --help
  amtadmin --version

Options:
  assns             Find assignments for a HIT
  balance           Get the account balance
  bonus             Grant a worker bonus
  expire            Force-expire the specified HIT
  hits              Find matching HITs
  show              Display the status of a HIT or Assignment
  --all             Operate on all applicable objects
  --amount=<num>    The amount of money
  --amt=<path>      The path to a file containing AMT credentials
  --assn=<id>       The ID of the assignment you want to view
  --desc            Sort results in descending order
  --hit=<id>        The ID of the HIT you want to view
  --page=<num>      The page number of results to display [default: 1]
  --pageSize=<num>  The number of results to display per page [default: 10]
  --reason=<str>    The reason to communicate to the worker
  --sandbox         Address the AMT sandbox instead of the production site
  --sort=<field>    The field to sort by. For hits, one of: CreationTime,
                    Enumeration, Expiration, Reward, or Title. For assns, one
                    of: AcceptTime, SubmitTime, or AssignmentStatus.
  --status=<str>    The assignment status to search for. Can be:
                    Submitted, Approved, or Rejected.
  --token=<str>     A unique token to prevent duplicate requests
  --worker=<id>     The id of the worker
`
)

type AmtCred struct {
	AccessKey, SecretKey string
}

func main() {

	// Parse the command line
	args, _ := docopt.Parse(USAGE, nil, true, "1.0", false)

	// Initialize the AMT client
	var (
		credPath = args["--amt"].(string)
		sandbox  = args["--sandbox"].(bool)
		amtCred  AmtCred
		client   amt.AmtClient
	)
	if f, err := os.Open(credPath); err != nil {
		fmt.Printf("Error: Could not open %s - %v", credPath, err)
		return
	} else if err = json.NewDecoder(f).Decode(&amtCred); err != nil {
		fmt.Printf("Error: Could not parse %s - %v", credPath, err)
		return
	} else {
		client = amt.NewClient(amtCred.AccessKey, amtCred.SecretKey, sandbox)
	}

	switch {
	case args["assns"].(bool):
		var (
			hitId, _              = args["--hit"].(string)
			status, _             = args["--status"].(string)
			sort, _               = args["--sort"].(string)
			desc                  = args["--desc"].(bool)
			page, pageErr         = strconv.Atoi(args["--page"].(string))
			pageSize, pageSizeErr = strconv.Atoi(args["--pageSize"].(string))
			statuses              []string
		)
		if sort == "" {
			sort = "AcceptTime"
		}
		if status != "" {
			statuses = append(statuses, status)
		}
		if pageErr != nil {
			fmt.Printf("Invalid --page argument\n")
		} else if pageSizeErr != nil {
			fmt.Printf("Invald --pageSize argument\n")
		} else {
			RunAssns(client, hitId, statuses, sort, desc, page, pageSize)
		}

	case args["balance"].(bool):
		RunBalance(client)

	case args["bonus"].(bool):
		var (
			workerId, _       = args["--worker"].(string)
			assnId, _         = args["--assn"].(string)
			reason, _         = args["--reason"].(string)
			token, _          = args["--token"].(string)
			amount, amountErr = strconv.ParseFloat(args["--amount"].(string), 32)
		)
		if amountErr != nil {
			fmt.Printf("Invalid --amount argument\n")
		} else {
			RunBonus(client, workerId, assnId, float32(amount), reason, token)
		}

	case args["expire"].(bool):
		var (
			all      = args["--all"].(bool)
			hitId, _ = args["--hit"].(string)
		)
		RunExpire(client, hitId, all)

	case args["hits"].(bool):
		var (
			sort, _               = args["--sort"].(string)
			desc                  = args["--desc"].(bool)
			page, pageErr         = strconv.Atoi(args["--page"].(string))
			pageSize, pageSizeErr = strconv.Atoi(args["--pageSize"].(string))
		)
		if sort == "" {
			sort = "CreationTime"
		}
		if pageErr != nil {
			fmt.Printf("Invalid --page argument\n")
		} else if pageSizeErr != nil {
			fmt.Printf("Invald --pageSize argument\n")
		} else {
			RunHits(client, sort, desc, page, pageSize)
		}

	case args["show"].(bool):
		hitId, _ := args["--hit"].(string)
		assnId, _ := args["--assn"].(string)
		RunShow(client, hitId, assnId)
	}
}

func getObjectFields(object interface{}, vals map[string]string) {
	v := reflect.Indirect(reflect.ValueOf(object))
	if !v.IsValid() {
		return
	}
	t := v.Type()
	switch t.Kind() {
	case reflect.Slice:
		for i := 0; i < v.Len(); i++ {
			getObjectFields(v.Index(i).Interface(), vals)
		}
	case reflect.Struct:
		for i := 0; i < t.NumField(); i++ {
			field := t.Field(i)
			switch field.Type.Kind() {
			case reflect.Struct, reflect.Ptr, reflect.Slice:
				getObjectFields(v.Field(i).Interface(), vals)
			default:
				if field.Type == reflect.TypeOf(xsdt.Int(0)) {
					vals[field.Name] = fmt.Sprintf("%d", v.Field(i).Interface())
				} else if field.Type == reflect.TypeOf(xsdt.Long(0)) {
					vals[field.Name] = fmt.Sprintf("%d", v.Field(i).Interface())
				} else {
					vals[field.Name] = v.Field(i).String()
				}
			}
		}
	}
}

func printObject(object interface{}) {
	var (
		fields   []string
		vals     = make(map[string]string)
		fieldLen int
	)
	getObjectFields(object, vals)
	for name, _ := range vals {
		fields = append(fields, name)
		if len(name) > fieldLen {
			fieldLen = len(name)
		}
	}
	sort.Strings(fields)
	format := fmt.Sprintf("%%%ds: %%s\n", fieldLen)
	for _, name := range fields {
		fmt.Printf(format, name, vals[name])
	}
}

func RunAssns(client amt.AmtClient, hitId string, statuses []string, sort string, desc bool, page, pageSize int) {
	if resp, err := client.GetAssignmentsForHIT(hitId, statuses, sort, !desc,
		pageSize, page); err != nil {

		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	} else if len(resp.GetAssignmentsForHITResults) > 0 &&
		resp.GetAssignmentsForHITResults[0].Request != nil &&
		resp.GetAssignmentsForHITResults[0].Request.Errors != nil {

		printObject(resp.GetAssignmentsForHITResults[0].Request)
	} else if len(resp.GetAssignmentsForHITResults[0].Assignments) == 0 {
		fmt.Println("Found no assignments for this HIT")
	} else {
		for i, assn := range resp.GetAssignmentsForHITResults[0].Assignments {
			fmt.Printf("Assignment %d/%d:\n", i+1, len(resp.GetAssignmentsForHITResults))
			printObject(assn)
			fmt.Println()
		}
	}
}

func RunBalance(client amt.AmtClient) {
	balance, err := client.GetAccountBalance()
	if err != nil {
		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	}
	printObject(balance)
}

func RunBonus(client amt.AmtClient, workerId, assnId string, amount float32,
	reason, token string) {
	resp, err := client.GrantBonus(workerId, assnId, amount, reason, token)
	if err != nil {
		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	}
	printObject(resp)
}

func RunExpire(client amt.AmtClient, hitId string, all bool) {
	if all {
		const maxHits = 100
		if resp, err := client.SearchHITs("CreationTime", false, maxHits, 1); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.SearchHITsResults) > 0 &&
			resp.SearchHITsResults[0].Request != nil &&
			resp.SearchHITsResults[0].Request.Errors != nil {

			printObject(resp.SearchHITsResults[0].Request)
		} else if len(resp.SearchHITsResults[0].Hits) == 0 {
			fmt.Println("Found no HITs for this account")
		} else {
			for _, hit := range resp.SearchHITsResults[0].Hits {
				if hit.HITStatus == "Assignable" {
					fmt.Printf("Expire HIT %q with %d available assignments\n",
						hit.HITId, hit.NumberOfAssignmentsAvailable)
					RunExpire(client, string(hit.HITId), false)
				}
			}
			if len(resp.SearchHITsResults[0].Hits) == maxHits {
				fmt.Println("Retrieved the maximum number of HITs. Repeat the command to find any remaining HITs.")
			}
		}
	} else if resp, err := client.ForceExpireHIT(hitId); err != nil {
		fmt.Printf("Error: Could not expire HIT - %v", err)
	} else {
		printObject(resp)
	}
}

func RunHits(client amt.AmtClient, sort string, desc bool, page, pageSize int) {
	if resp, err := client.SearchHITs(sort, !desc, pageSize, page); err != nil {
		fmt.Printf("Error: The AMT request failed: %v\n", err)
		return
	} else if len(resp.SearchHITsResults) > 0 &&
		resp.SearchHITsResults[0].Request != nil &&
		resp.SearchHITsResults[0].Request.Errors != nil {

		printObject(resp.SearchHITsResults[0].Request)
	} else if len(resp.SearchHITsResults[0].Hits) == 0 {
		fmt.Println("Found no HITs for this account")
	} else {
		for i, hit := range resp.SearchHITsResults[0].Hits {
			fmt.Printf("HIT %d/%d:\n", i+1, len(resp.SearchHITsResults))
			printObject(hit)
			fmt.Println()
		}
	}
}

func RunShow(client amt.AmtClient, hitId, assnId string) {
	switch {
	case hitId != "":
		if resp, err := client.GetHIT(hitId); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.Hits) > 0 && resp.Hits[0].Request != nil &&
			resp.Hits[0].Request.Errors != nil {

			printObject(resp.Hits[0].Request)
		} else {
			printObject(resp)
		}

	case assnId != "":
		if resp, err := client.GetAssignment(assnId); err != nil {
			fmt.Printf("Error: The AMT request failed: %v\n", err)
			return
		} else if len(resp.GetAssignmentResults) > 0 &&
			resp.GetAssignmentResults[0].Request != nil &&
			resp.GetAssignmentResults[0].Request.Errors != nil {

			printObject(resp.GetAssignmentResults[0].Request)
		} else {
			printObject(resp)
		}

	default:
		fmt.Println("You must provide a value for either --hit or --assn")
	}
}
<|endoftext|>


<commit_before>package iso9660

import (
	"fmt"
	"io"
)

// File represents a single file in an iso9660 filesystem
//  it is NOT used when working in a workspace, where we just use the underlying OS
type File struct {
	*directoryEntry
	isReadWrite bool
	isAppend    bool
	offset      int64
}

// Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF
// reads from the last known offset in the file from last read or write
// use Seek() to set at a particular point
func (fl *File) Read(b []byte) (int, error) {
	// we have the DirectoryEntry, so we can get the starting location and size
	// since iso9660 files are contiguous, we only need the starting location and size
	//   to get the entire file
	fs := fl.filesystem
	size := int(fl.size) - int(fl.offset)
	location := int(fl.location)
	maxRead := size
	file := fs.file

	// if there is nothing left to read, just return EOF
	if size <= 0 {
		return 0, io.EOF
	}

	// we stop when we hit the lesser of
	//   1- len(b)
	//   2- file end
	if len(b) < maxRead {
		maxRead = len(b)
	}

	// just read the requested number of bytes and change our offset
	file.ReadAt(b[0:maxRead], int64(location)*fs.blocksize+int64(fl.offset))

	fl.offset = fl.offset + int64(maxRead)
	var retErr error
	if fl.offset >= int64(fl.size) {
		retErr = io.EOF
	}
	return maxRead, retErr
}

// Write writes len(b) bytes to the File.
//  you cannot write to an iso, so this returns an error
func (fl *File) Write(p []byte) (int, error) {
	return 0, fmt.Errorf("Cannot write to a read-only iso filesystem")
}

// Seek set the offset to a particular point in the file
func (fl *File) Seek(offset int64, whence int) (int64, error) {
	newOffset := int64(0)
	switch whence {
	case io.SeekStart:
		newOffset = offset
	case io.SeekEnd:
		newOffset = int64(fl.size) + offset
	case io.SeekCurrent:
		newOffset = fl.offset + offset
	}
	if newOffset < 0 {
		return fl.offset, fmt.Errorf("Cannot set offset %d before start of file", offset)
	}
	fl.offset = newOffset
	return fl.offset, nil
}
<commit_msg>Add iso file Location() function<commit_after>package iso9660

import (
	"fmt"
	"io"
)

// File represents a single file in an iso9660 filesystem
//  it is NOT used when working in a workspace, where we just use the underlying OS
type File struct {
	*directoryEntry
	isReadWrite bool
	isAppend    bool
	offset      int64
}

// Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF
// reads from the last known offset in the file from last read or write
// use Seek() to set at a particular point
func (fl *File) Read(b []byte) (int, error) {
	// we have the DirectoryEntry, so we can get the starting location and size
	// since iso9660 files are contiguous, we only need the starting location and size
	//   to get the entire file
	fs := fl.filesystem
	size := int(fl.size) - int(fl.offset)
	location := int(fl.location)
	maxRead := size
	file := fs.file

	// if there is nothing left to read, just return EOF
	if size <= 0 {
		return 0, io.EOF
	}

	// we stop when we hit the lesser of
	//   1- len(b)
	//   2- file end
	if len(b) < maxRead {
		maxRead = len(b)
	}

	// just read the requested number of bytes and change our offset
	file.ReadAt(b[0:maxRead], int64(location)*fs.blocksize+int64(fl.offset))

	fl.offset = fl.offset + int64(maxRead)
	var retErr error
	if fl.offset >= int64(fl.size) {
		retErr = io.EOF
	}
	return maxRead, retErr
}

// Write writes len(b) bytes to the File.
//  you cannot write to an iso, so this returns an error
func (fl *File) Write(p []byte) (int, error) {
	return 0, fmt.Errorf("Cannot write to a read-only iso filesystem")
}

// Seek set the offset to a particular point in the file
func (fl *File) Seek(offset int64, whence int) (int64, error) {
	newOffset := int64(0)
	switch whence {
	case io.SeekStart:
		newOffset = offset
	case io.SeekEnd:
		newOffset = int64(fl.size) + offset
	case io.SeekCurrent:
		newOffset = fl.offset + offset
	}
	if newOffset < 0 {
		return fl.offset, fmt.Errorf("Cannot set offset %d before start of file", offset)
	}
	fl.offset = newOffset
	return fl.offset, nil
}

func (fl *File) Location() uint32 {
	return fl.location
}
<|endoftext|>


<commit_before>package queries

import (
	"flag"
	"fmt"
	"strconv"
	"sync"

	sous "github.com/opentable/sous/lib"
)

// MaxConcurrentArtifactQueries is the max number of concurrent artifact
// queries. 100 is a conservative value to ensure we don't run out of file
// descriptors locally.
// NOTE: If users complain this is too slow we could make this configurable
//       by env var, or perhaps lookup the max file descriptors via ulimit -n...
const MaxConcurrentArtifactQueries = 100

// DeploymentFilters is the argument that determines which deployments are
// returned by a query.
type DeploymentFilters struct {
	AttributeFilters DeploymentAttributeFilters
}

// DeploymentAttributeFilters filters deployments based on their attributes.
type DeploymentAttributeFilters struct {
	filters []boundDeployFilter
	flagMap map[string]*string
}

// AddFlags adds the available filters from q as flags to fs.
func (f *DeploymentAttributeFilters) AddFlags(q *Deployment, fs *flag.FlagSet) {
	f.flagMap = map[string]*string{}
	for _, n := range q.availableFilterNames() {
		f.flagMap[n] = new(string)
		help := fmt.Sprintf("filter based on %s (true|false|<empty string>)", n)
		fs.StringVar(f.flagMap[n], n, "", help)
	}
}

// UnpackFlags should be called after flag.Parse and sets the filters up
// accordingly, overwriting any currently setup filters.
func (f *DeploymentAttributeFilters) UnpackFlags(q *Deployment) error {
	named := map[string]boundDeployFilter{}
	for name, val := range f.flagMap {
		if val == nil || *val == "" {
			continue
		}
		v, err := strconv.ParseBool(*val)
		if err != nil {
			return fmt.Errorf("value %q for flag %s not valid (want true or false)",
				val, name)
		}
		f, err := q.getFilter(name)
		if err != nil {
			return err
		}
		named[name] = func(ds sous.Deployments) (sous.Deployments, error) {
			return f(ds, v)
		}
	}
	f.filters = nil
	for _, name := range filterOrder {
		if filter, ok := named[name]; ok {
			f.filters = append(f.filters, filter)
		}
	}
	return nil
}

func (f *DeploymentAttributeFilters) apply(ds sous.Deployments) (sous.Deployments, error) {
	var err error
	for _, filter := range f.filters {
		ds, err = filter(ds)
		if err != nil {
			return ds, err
		}
	}
	return ds, nil
}

type deployFilter func(sous.Deployments, bool) (sous.Deployments, error)
type boundDeployFilter func(sous.Deployments) (sous.Deployments, error)

func simpleFilter(p func(*sous.Deployment) bool) deployFilter {
	return func(ds sous.Deployments, which bool) (sous.Deployments, error) {
		return ds.Filter(func(d *sous.Deployment) bool {
			return p(d) == which
		}), nil
	}
}

func parallelFilter(maxConcurrent int, p func(*sous.Deployment) (bool, error)) deployFilter {
	return func(deployments sous.Deployments, which bool) (sous.Deployments, error) {
		if maxConcurrent < 1 {
			return deployments, fmt.Errorf("maxConcurrent < 1 not allowed")
		}
		// NOTE: We take snapshot here so that len cannot change. Deployments is
		// a concurrent map, so we have to assume len can change at any time.
		ds := deployments.Snapshot()
		// We take advantage of filtered being a concurrent map, writing to it
		// willy nilly from the goroutines we start in the loop below.
		filtered := sous.NewDeployments()

		wg := sync.WaitGroup{}
		wg.Add(len(ds))

		errs := make(chan error, len(ds))
		pool := make(chan struct{}, MaxConcurrentArtifactQueries)
		for i := 0; i < MaxConcurrentArtifactQueries; i++ {
			pool <- struct{}{}
		}

		for _, d := range ds {
			d := d
			<-pool
			go func() {
				defer wg.Done()
				defer func() { pool <- struct{}{} }()
				match, err := p(d)
				if err != nil {
					errs <- err
					return
				}
				if match != which {
					return
				}
				// This .Add call is safe because filtered is a concurrent map.
				filtered.Add(d)
			}()
		}
		done := make(chan error)
		go func() {
			select {
			case <-func() chan struct{} {
				c := make(chan struct{})
				go func() { wg.Wait(); close(c) }()
				return c
			}():
				close(done)
			case err := <-errs: // do nothing
				done <- err
			}
		}()
		return filtered, <-done
	}
}
<commit_msg>cli/queries: fix respect of maxConcurrent<commit_after>package queries

import (
	"flag"
	"fmt"
	"strconv"
	"sync"

	sous "github.com/opentable/sous/lib"
)

// MaxConcurrentArtifactQueries is the max number of concurrent artifact
// queries. 100 is a conservative value to ensure we don't run out of file
// descriptors locally.
// NOTE: If users complain this is too slow we could make this configurable
//       by env var, or perhaps lookup the max file descriptors via ulimit -n...
const MaxConcurrentArtifactQueries = 100

// DeploymentFilters is the argument that determines which deployments are
// returned by a query.
type DeploymentFilters struct {
	AttributeFilters DeploymentAttributeFilters
}

// DeploymentAttributeFilters filters deployments based on their attributes.
type DeploymentAttributeFilters struct {
	filters []boundDeployFilter
	flagMap map[string]*string
}

// AddFlags adds the available filters from q as flags to fs.
func (f *DeploymentAttributeFilters) AddFlags(q *Deployment, fs *flag.FlagSet) {
	f.flagMap = map[string]*string{}
	for _, n := range q.availableFilterNames() {
		f.flagMap[n] = new(string)
		help := fmt.Sprintf("filter based on %s (true|false|<empty string>)", n)
		fs.StringVar(f.flagMap[n], n, "", help)
	}
}

// UnpackFlags should be called after flag.Parse and sets the filters up
// accordingly, overwriting any currently setup filters.
func (f *DeploymentAttributeFilters) UnpackFlags(q *Deployment) error {
	named := map[string]boundDeployFilter{}
	for name, val := range f.flagMap {
		if val == nil || *val == "" {
			continue
		}
		v, err := strconv.ParseBool(*val)
		if err != nil {
			return fmt.Errorf("value %q for flag %s not valid (want true or false)",
				val, name)
		}
		f, err := q.getFilter(name)
		if err != nil {
			return err
		}
		named[name] = func(ds sous.Deployments) (sous.Deployments, error) {
			return f(ds, v)
		}
	}
	f.filters = nil
	for _, name := range filterOrder {
		if filter, ok := named[name]; ok {
			f.filters = append(f.filters, filter)
		}
	}
	return nil
}

func (f *DeploymentAttributeFilters) apply(ds sous.Deployments) (sous.Deployments, error) {
	var err error
	for _, filter := range f.filters {
		ds, err = filter(ds)
		if err != nil {
			return ds, err
		}
	}
	return ds, nil
}

type deployFilter func(sous.Deployments, bool) (sous.Deployments, error)
type boundDeployFilter func(sous.Deployments) (sous.Deployments, error)

func simpleFilter(p func(*sous.Deployment) bool) deployFilter {
	return func(ds sous.Deployments, which bool) (sous.Deployments, error) {
		return ds.Filter(func(d *sous.Deployment) bool {
			return p(d) == which
		}), nil
	}
}

func parallelFilter(maxConcurrent int, p func(*sous.Deployment) (bool, error)) deployFilter {
	return func(deployments sous.Deployments, which bool) (sous.Deployments, error) {
		if maxConcurrent < 1 {
			return deployments, fmt.Errorf("maxConcurrent < 1 not allowed")
		}
		// NOTE: We take snapshot here so that len cannot change. Deployments is
		// a concurrent map, so we have to assume len can change at any time.
		ds := deployments.Snapshot()
		// We take advantage of filtered being a concurrent map, writing to it
		// willy nilly from the goroutines we start in the loop below.
		filtered := sous.NewDeployments()

		wg := sync.WaitGroup{}
		wg.Add(len(ds))

		errs := make(chan error, len(ds))
		pool := make(chan struct{}, maxConcurrent)
		for i := 0; i < maxConcurrent; i++ {
			pool <- struct{}{}
		}

		for _, d := range ds {
			d := d
			<-pool
			go func() {
				defer wg.Done()
				defer func() { pool <- struct{}{} }()
				match, err := p(d)
				if err != nil {
					errs <- err
					return
				}
				if match != which {
					return
				}
				// This .Add call is safe because filtered is a concurrent map.
				filtered.Add(d)
			}()
		}
		done := make(chan error)
		go func() {
			select {
			case <-func() chan struct{} {
				c := make(chan struct{})
				go func() { wg.Wait(); close(c) }()
				return c
			}():
				close(done)
			case err := <-errs: // do nothing
				done <- err
			}
		}()
		return filtered, <-done
	}
}
<|endoftext|>


<commit_before>// chris 090415

// flag_test tests the contents of its parent package.  This is
// implemented as a separate command due to the flag library using
// global state and it being somewhat difficult to integrate it with
// package testing.
package main

import (
	"flag"
	"log"

	fixflag "chrispennello.com/go/util/fix/flag"
)

func main() {
	tests := new(fixflag.SliceStrings)
	flag.Var(tests, "test", "can specify more than once")
	flag.Parse()
	log.Print(*tests)
}
<commit_msg>fix/flag/flag_test: Improves verbiage of command documentation.<commit_after>// chris 090415

// flag_test tests the contents of its parent package.  This is
// implemented as a separate command due to the flag library using
// global state and it being somewhat difficult to integrate with
// package testing.
package main

import (
	"flag"
	"log"

	fixflag "chrispennello.com/go/util/fix/flag"
)

func main() {
	tests := new(fixflag.SliceStrings)
	flag.Var(tests, "test", "can specify more than once")
	flag.Parse()
	log.Print(*tests)
}
<|endoftext|>


<commit_before>package store

import (
	"bytes"
	"compress/zlib"
	"encoding/base64"

	"github.com/diyan/assimilator/interfaces"
	"github.com/diyan/assimilator/lib/conv"
	"github.com/diyan/assimilator/models"
	"github.com/gocraft/dbr"
	pickle "github.com/hydrogen18/stalecucumber"
	"github.com/pkg/errors"
)

type EventStore struct {
}

func NewEventStore() EventStore {
	return EventStore{}
}

func (s EventStore) GetEvent(tx *dbr.Tx, projectID, eventID int) (*models.Event, error) {
	event := models.Event{}
	_, err := tx.SelectBySql(`
            select m.*
                from sentry_message m
            where m.project_id  = ? and m.id = ?`,
		projectID, eventID).
		LoadStructs(&event)
	if err != nil {
		return nil, errors.Wrap(err, "can not get issue event")
	}
	if event.DetailsRefRaw != nil {
		nodeRefMap, err := unpickleZippedBase64String(*event.DetailsRefRaw)
		if err != nil {
			return nil, errors.Wrap(err, "can not get issue event: failed to decode reference to the event details")
		}
		event.DetailsRef = &models.NodeRef{}
		if err := models.DecodeRecord(nodeRefMap, event.DetailsRef); err != nil {
			return nil, errors.Wrap(err, "can not get issue event: failed to decode reference to the event details")
		}
		event.DetailsRefRaw = nil
	}
	return &event, nil
}

func (s EventStore) GetEventDetailsMap(tx *dbr.Tx, nodeRef models.NodeRef) (map[string]interface{}, error) {
	nodeBlob := models.NodeBlob{}
	_, err := tx.SelectBySql(`
            select n.*
                from nodestore_node n
            where n.id = ?`,
		nodeRef.NodeID).
		LoadStructs(&nodeBlob)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load event details from node store")
	}
	eventMap, err := unpickleZippedBase64String(nodeBlob.Data)
	if err != nil {
		return nil, errors.Wrap(err, "failed to decode event details blob")
	}
	// TODO it's a bad idea to import interfaces from db/store
	return interfaces.ToAliasKeys(eventMap), nil
}

func (s EventStore) SaveEvent(tx *dbr.Tx, event models.Event) error {
	if event.DetailsRef != nil {
		// TODO how to re-use `kv` tag for pickler which uses `pickle` tag name?
		detailsMap := map[string]interface{}{
			"node_id": event.DetailsRef.NodeID,
		}
		detailsRefRaw, err := toBase64ZipPickleString(detailsMap)
		if err != nil {
			errors.Wrap(err, "failed to save issue event: failed to encode reference to the event details")
		}
		event.DetailsRefRaw = &detailsRefRaw
		event.DetailsRef = nil
	}
	_, err := tx.InsertInto("sentry_message").
		Columns("id", "group_id", "message_id", "project_id", "message",
			"platform", "time_spent", "data", "datetime").
		Record(event).
		Exec()
	return errors.Wrap(err, "failed to save issue event")
}

// TODO move to the nodeStore
func (s EventStore) SaveNodeBlob(tx *dbr.Tx, nodeBlob models.NodeBlob) error {
	_, err := tx.InsertInto("nodestore_node").
		Columns("id", "data", "timestamp").
		Record(nodeBlob).
		Exec()
	return errors.Wrap(err, "failed to save node blob")
}

func toBase64ZipPickleString(value map[string]interface{}) (string, error) {
	pickleBuffer := bytes.Buffer{} // io.Writer
	_, err := pickle.NewPickler(&pickleBuffer).Pickle(value)
	if err != nil {
		return "", errors.Wrap(err, "pickle failed")
	}
	zlibBuffer := bytes.Buffer{} // io.Writer
	zlibWriter := zlib.NewWriter(&zlibBuffer)
	_, err = zlibWriter.Write(pickleBuffer.Bytes())
	if err != nil {
		return "", errors.Wrap(err, "zip stream failed")
	}
	err = zlibWriter.Close()
	if err != nil {
		return "", errors.Wrap(err, "zip stream failed")
	}
	return base64.StdEncoding.EncodeToString(zlibBuffer.Bytes()), nil
}

func unpickleZippedBase64String(blob string) (map[string]interface{}, error) {
	zippedBytes, err := base64.StdEncoding.DecodeString(blob)
	if err != nil {
		return nil, errors.Wrap(err, "base64 decode failed")
	}
	zlibReader, err := zlib.NewReader(bytes.NewReader(zippedBytes))
	defer zlibReader.Close()
	if err != nil {
		return nil, errors.Wrap(err, "unzip stream failed")
	}
	unpickledBlob, err := pickle.Unpickle(zlibReader)
	if err != nil {
		return nil, errors.Wrap(err, "unpickle failed")
	}
	unpickledMap := conv.StringMap(unpickledBlob)
	return unpickledMap, nil
}
<commit_msg>Change func name to fromBase64ZipPickleString<commit_after>package store

import (
	"bytes"
	"compress/zlib"
	"encoding/base64"

	"github.com/diyan/assimilator/interfaces"
	"github.com/diyan/assimilator/lib/conv"
	"github.com/diyan/assimilator/models"
	"github.com/gocraft/dbr"
	pickle "github.com/hydrogen18/stalecucumber"
	"github.com/pkg/errors"
)

type EventStore struct {
}

func NewEventStore() EventStore {
	return EventStore{}
}

func (s EventStore) GetEvent(tx *dbr.Tx, projectID, eventID int) (*models.Event, error) {
	event := models.Event{}
	_, err := tx.SelectBySql(`
            select m.*
                from sentry_message m
            where m.project_id  = ? and m.id = ?`,
		projectID, eventID).
		LoadStructs(&event)
	if err != nil {
		return nil, errors.Wrap(err, "can not get issue event")
	}
	if event.DetailsRefRaw != nil {
		nodeRefMap, err := fromBase64ZipPickleString(*event.DetailsRefRaw)
		if err != nil {
			return nil, errors.Wrap(err, "can not get issue event: failed to decode reference to the event details")
		}
		event.DetailsRef = &models.NodeRef{}
		if err := models.DecodeRecord(nodeRefMap, event.DetailsRef); err != nil {
			return nil, errors.Wrap(err, "can not get issue event: failed to decode reference to the event details")
		}
		event.DetailsRefRaw = nil
	}
	return &event, nil
}

func (s EventStore) GetEventDetailsMap(tx *dbr.Tx, nodeRef models.NodeRef) (map[string]interface{}, error) {
	nodeBlob := models.NodeBlob{}
	_, err := tx.SelectBySql(`
            select n.*
                from nodestore_node n
            where n.id = ?`,
		nodeRef.NodeID).
		LoadStructs(&nodeBlob)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load event details from node store")
	}
	eventMap, err := fromBase64ZipPickleString(nodeBlob.Data)
	if err != nil {
		return nil, errors.Wrap(err, "failed to decode event details blob")
	}
	// TODO it's a bad idea to import interfaces from db/store
	return interfaces.ToAliasKeys(eventMap), nil
}

func (s EventStore) SaveEvent(tx *dbr.Tx, event models.Event) error {
	if event.DetailsRef != nil {
		// TODO how to re-use `kv` tag for pickler which uses `pickle` tag name?
		detailsMap := map[string]interface{}{
			"node_id": event.DetailsRef.NodeID,
		}
		detailsRefRaw, err := toBase64ZipPickleString(detailsMap)
		if err != nil {
			errors.Wrap(err, "failed to save issue event: failed to encode reference to the event details")
		}
		event.DetailsRefRaw = &detailsRefRaw
		event.DetailsRef = nil
	}
	_, err := tx.InsertInto("sentry_message").
		Columns("id", "group_id", "message_id", "project_id", "message",
			"platform", "time_spent", "data", "datetime").
		Record(event).
		Exec()
	return errors.Wrap(err, "failed to save issue event")
}

// TODO move to the nodeStore
func (s EventStore) SaveNodeBlob(tx *dbr.Tx, nodeBlob models.NodeBlob) error {
	_, err := tx.InsertInto("nodestore_node").
		Columns("id", "data", "timestamp").
		Record(nodeBlob).
		Exec()
	return errors.Wrap(err, "failed to save node blob")
}

func toBase64ZipPickleString(value map[string]interface{}) (string, error) {
	pickleBuffer := bytes.Buffer{} // io.Writer
	_, err := pickle.NewPickler(&pickleBuffer).Pickle(value)
	if err != nil {
		return "", errors.Wrap(err, "pickle failed")
	}
	zlibBuffer := bytes.Buffer{} // io.Writer
	zlibWriter := zlib.NewWriter(&zlibBuffer)
	_, err = zlibWriter.Write(pickleBuffer.Bytes())
	if err != nil {
		return "", errors.Wrap(err, "zip stream failed")
	}
	err = zlibWriter.Close()
	if err != nil {
		return "", errors.Wrap(err, "zip stream failed")
	}
	return base64.StdEncoding.EncodeToString(zlibBuffer.Bytes()), nil
}

func fromBase64ZipPickleString(blob string) (map[string]interface{}, error) {
	zippedBytes, err := base64.StdEncoding.DecodeString(blob)
	if err != nil {
		return nil, errors.Wrap(err, "base64 decode failed")
	}
	zlibReader, err := zlib.NewReader(bytes.NewReader(zippedBytes))
	defer zlibReader.Close()
	if err != nil {
		return nil, errors.Wrap(err, "unzip stream failed")
	}
	unpickledBlob, err := pickle.Unpickle(zlibReader)
	if err != nil {
		return nil, errors.Wrap(err, "unpickle failed")
	}
	unpickledMap := conv.StringMap(unpickledBlob)
	return unpickledMap, nil
}
<|endoftext|>


<commit_before>package wireup

import (
	"net/http"
	"time"

	international_street "github.com/smartystreets/smartystreets-go-sdk/international-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-autocomplete-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-extract-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-zipcode-api"
)

// BuildUSStreetAPIClient builds a client for the US Street API using the provided options.
func BuildUSStreetAPIClient(options ...Option) *street.Client {
	return configure(options...).buildUSStreetAPIClient()
}

// BuildUSZIPCodeAPIClient builds a client for the US ZIP Code API using the provided options.
func BuildUSZIPCodeAPIClient(options ...Option) *zipcode.Client {
	return configure(options...).buildUSZIPCodeAPIClient()
}

// BuildUSAutocompleteAPIClient builds a client for the US Autocomplete API using the provided options.
func BuildUSAutocompleteAPIClient(options ...Option) *autocomplete.Client {
	return configure(options...).buildUSAutocompleteAPIClient()
}

// BuildUSExtractAPIClient builds a client for the US Extract API using the provided options.
func BuildUSExtractAPIClient(options ...Option) *extract.Client {
	return configure(options...).buildUSExtractAPIClient()
}

// BuildInternationalStreetAPIClient builds a client for the International Street API using the provided options.
func BuildInternationalStreetAPIClient(options ...Option) *international_street.Client {
	return configure(options...).buildInternationalStreetAPIClient()
}

func configure(options ...Option) *clientBuilder {
	builder := newClientBuilder()
	for _, option := range options {
		if option != nil {
			option(builder)
		}
	}
	return builder
}

type Option func(builder *clientBuilder)

// SecretKeyCredential sets the authID and authToken for use with the client.
// In all but very few cases calling this method with a valid authID and authToken is required.
func SecretKeyCredential(authID, authToken string) Option {
	return func(builder *clientBuilder) {
		builder.withSecretKeyCredential(authID, authToken)
	}
}

// WebsiteKeyCredential sets the key and hostnameOrIP for use with the client.
// This kind of authentication is generally only used for client-side applications but it
// included here for completeness.
func WebsiteKeyCredential(key, hostnameOrIP string) Option {
	return func(builder *clientBuilder) {
		builder.withWebsiteKeyCredential(key, hostnameOrIP)
	}
}

// CustomBaseURL specifies the url that the client will use.
// In all but very few use cases the default value is sufficient and this method should not be called.
// The address provided will be consulted for scheme, host, and path values. Any other URL components
// (such as a path, query string, or fragment) will be ignored.
func CustomBaseURL(address string) Option {
	return func(builder *clientBuilder) {
		builder.withCustomBaseURL(address)
	}
}

// MaxRetry specifies the number of times an API request will be resent in the
// case of network errors or unexpected results.
func MaxRetry(retries int) Option {
	return func(builder *clientBuilder) {
		builder.withMaxRetry(retries)
	}
}

// Timeout specifies the timeout for all API requests.
func Timeout(duration time.Duration) Option {
	return func(builder *clientBuilder) {
		builder.withTimeout(duration)
	}
}

// DebugHTTPOutput engages detailed HTTP request/response logging using functions from net/http/httputil.
func DebugHTTPOutput() Option {
	return func(builder *clientBuilder) {
		builder.withDebugHTTPOutput()
	}
}

// DebugHTTPTracing engages additional HTTP-level tracing for each API request.
func DebugHTTPTracing() Option {
	return func(builder *clientBuilder) {
		builder.withHTTPRequestTracing()
	}
}

// CustomHeader ensures the provided header is added to every API request made with the resulting client.
func CustomHeader(key, value string) Option {
	return func(builder *clientBuilder) {
		builder.withCustomHeader(key, value)
	}
}

// DisableKeepAlive disables keep-alive for API requests.
// This is helpful if your environment limits the number of open files.
func DisableKeepAlive() Option {
	return func(builder *clientBuilder) {
		builder.withoutKeepAlive()
	}
}

// ViaProxy saves the address of your proxy server through which to send all requests.
func ViaProxy(address string) Option {
	return func(builder *clientBuilder) {
		builder.viaProxy(address)
	}
}

// WithMaxIdleConnections sets MaxIdleConnsPerHost on the http.Transport used to send requests.
// Docs for http.Transport.MaxIdleConnsPerHost: https://golang.org/pkg/net/http/#Transport
// Also see: https://stackoverflow.com/questions/22881090/golang-about-maxidleconnsperhost-in-the-http-clients-transport
func WithMaxIdleConnections(max int) Option {
	return func(builder *clientBuilder) {
		builder.withMaxIdleConnections(max)
	}
}

// DisableHTTP2 prevents clients from making use of the http2 protocol. This is achieved by following the instructions
// from the http package documentation (see: https://golang.org/pkg/net/http):
// > "Programs that must disable HTTP/2 can do so by setting Transport.TLSNextProto to a non-nil, empty map."
func DisableHTTP2() Option {
	return func(builder *clientBuilder) {
		builder.disableHTTP2()
	}
}

// WithHTTPClient allows the caller to supply their own *http.Client. This is useful if you want full
// control over the http client and its properties, but keep in mind that it reduces the following
// options to no-ops (you would need to specify any of those details on the *http.Client you provide):
//
// - DisableHTTP2
// - WithMaxIdleConnections
// - ViaProxy
// - Timeout
//
func WithHTTPClient(client *http.Client) Option {
	return func(builder *clientBuilder) {
		builder.client = client
	}
}

// WithLicenses allows the caller to specify the subscription license (aka "track") they wish to use.
func WithLicenses(licenses ...string) Option {
	return func(builder *clientBuilder) {
		builder.licenses = append(builder.licenses, licenses...)
	}
}
<commit_msg>Typos<commit_after>package wireup

import (
	"net/http"
	"time"

	international_street "github.com/smartystreets/smartystreets-go-sdk/international-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-autocomplete-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-extract-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-zipcode-api"
)

// BuildUSStreetAPIClient builds a client for the US Street API using the provided options.
func BuildUSStreetAPIClient(options ...Option) *street.Client {
	return configure(options...).buildUSStreetAPIClient()
}

// BuildUSZIPCodeAPIClient builds a client for the US ZIP Code API using the provided options.
func BuildUSZIPCodeAPIClient(options ...Option) *zipcode.Client {
	return configure(options...).buildUSZIPCodeAPIClient()
}

// BuildUSAutocompleteAPIClient builds a client for the US Autocomplete API using the provided options.
func BuildUSAutocompleteAPIClient(options ...Option) *autocomplete.Client {
	return configure(options...).buildUSAutocompleteAPIClient()
}

// BuildUSExtractAPIClient builds a client for the US Extract API using the provided options.
func BuildUSExtractAPIClient(options ...Option) *extract.Client {
	return configure(options...).buildUSExtractAPIClient()
}

// BuildInternationalStreetAPIClient builds a client for the International Street API using the provided options.
func BuildInternationalStreetAPIClient(options ...Option) *international_street.Client {
	return configure(options...).buildInternationalStreetAPIClient()
}

func configure(options ...Option) *clientBuilder {
	builder := newClientBuilder()
	for _, option := range options {
		if option != nil {
			option(builder)
		}
	}
	return builder
}

type Option func(builder *clientBuilder)

// SecretKeyCredential sets the authID and authToken for use with the client.
// In all but very few cases calling this method with a valid authID and authToken is required.
func SecretKeyCredential(authID, authToken string) Option {
	return func(builder *clientBuilder) {
		builder.withSecretKeyCredential(authID, authToken)
	}
}

// WebsiteKeyCredential sets the key and hostnameOrIP for use with the client.
// This kind of authentication is generally only used for client-side applications but it
// included here for completeness.
func WebsiteKeyCredential(key, hostnameOrIP string) Option {
	return func(builder *clientBuilder) {
		builder.withWebsiteKeyCredential(key, hostnameOrIP)
	}
}

// CustomBaseURL specifies the url that the client will use.
// In all but very few use cases the default value is sufficient and this method should not be called.
// The address provided will be consulted for scheme, host, and path values. Any other URL components
// such as the query string or fragment will be ignored.
func CustomBaseURL(address string) Option {
	return func(builder *clientBuilder) {
		builder.withCustomBaseURL(address)
	}
}

// MaxRetry specifies the number of times an API request will be resent in the
// case of network errors or unexpected results.
func MaxRetry(retries int) Option {
	return func(builder *clientBuilder) {
		builder.withMaxRetry(retries)
	}
}

// Timeout specifies the timeout for all API requests.
func Timeout(duration time.Duration) Option {
	return func(builder *clientBuilder) {
		builder.withTimeout(duration)
	}
}

// DebugHTTPOutput engages detailed HTTP request/response logging using functions from net/http/httputil.
func DebugHTTPOutput() Option {
	return func(builder *clientBuilder) {
		builder.withDebugHTTPOutput()
	}
}

// DebugHTTPTracing engages additional HTTP-level tracing for each API request.
func DebugHTTPTracing() Option {
	return func(builder *clientBuilder) {
		builder.withHTTPRequestTracing()
	}
}

// CustomHeader ensures the provided header is added to every API request made with the resulting client.
func CustomHeader(key, value string) Option {
	return func(builder *clientBuilder) {
		builder.withCustomHeader(key, value)
	}
}

// DisableKeepAlive disables keep-alive for API requests.
// This is helpful if your environment limits the number of open files.
func DisableKeepAlive() Option {
	return func(builder *clientBuilder) {
		builder.withoutKeepAlive()
	}
}

// ViaProxy saves the address of your proxy server through which to send all requests.
func ViaProxy(address string) Option {
	return func(builder *clientBuilder) {
		builder.viaProxy(address)
	}
}

// WithMaxIdleConnections sets MaxIdleConnsPerHost on the http.Transport used to send requests.
// Docs for http.Transport.MaxIdleConnsPerHost: https://golang.org/pkg/net/http/#Transport
// Also see: https://stackoverflow.com/questions/22881090/golang-about-maxidleconnsperhost-in-the-http-clients-transport
func WithMaxIdleConnections(max int) Option {
	return func(builder *clientBuilder) {
		builder.withMaxIdleConnections(max)
	}
}

// DisableHTTP2 prevents clients from making use of the http2 protocol. This is achieved by following the instructions
// from the http package documentation (see: https://golang.org/pkg/net/http):
// > "Programs that must disable HTTP/2 can do so by setting Transport.TLSNextProto to a non-nil, empty map."
func DisableHTTP2() Option {
	return func(builder *clientBuilder) {
		builder.disableHTTP2()
	}
}

// WithHTTPClient allows the caller to supply their own *http.Client. This is useful if you want full
// control over the http client and its properties, but keep in mind that it reduces the following
// options to no-ops (you would need to specify any of those details on the *http.Client you provide):
//
// - DisableHTTP2
// - WithMaxIdleConnections
// - ViaProxy
// - Timeout
//
func WithHTTPClient(client *http.Client) Option {
	return func(builder *clientBuilder) {
		builder.client = client
	}
}

// WithLicenses allows the caller to specify the subscription license (aka "track") they wish to use.
func WithLicenses(licenses ...string) Option {
	return func(builder *clientBuilder) {
		builder.licenses = append(builder.licenses, licenses...)
	}
}
<|endoftext|>


<commit_before>package gofakeit

import (
	"fmt"
	"testing"
)

func ExampleNoun() {
	Seed(11)
	fmt.Println(Noun())
	// Output: foot
}

func ExampleFaker_Noun() {
	f := New(11)
	fmt.Println(f.Noun())
	// Output: foot
}

func BenchmarkNoun(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Noun()
	}
}

func ExampleNounCommon() {
	Seed(11)
	fmt.Println(NounCommon())
	// Output: part
}

func ExampleFaker_NounCommon() {
	f := New(11)
	fmt.Println(f.NounCommon())
	// Output: part
}

func BenchmarkNounCommon(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCommon()
	}
}

func ExampleNounConcrete() {
	Seed(11)
	fmt.Println(NounConcrete())
	// Output: part
}

func ExampleFaker_NounConcrete() {
	f := New(11)
	fmt.Println(f.NounConcrete())
	// Output: part
}

func BenchmarkNounConcrete(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounConcrete()
	}
}

func ExampleNounAbstract() {
	Seed(11)
	fmt.Println(NounAbstract())
	// Output: part
}

func ExampleFaker_NounAbstract() {
	f := New(11)
	fmt.Println(f.NounAbstract())
	// Output: part
}

func BenchmarkNounAbstract(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounAbstract()
	}
}

func ExampleNounCollectivePeople() {
	Seed(11)
	fmt.Println(NounCollectivePeople())
	// Output: part
}

func ExampleFaker_NounCollectivePeople() {
	f := New(11)
	fmt.Println(f.NounCollectivePeople())
	// Output: part
}

func BenchmarkNounCollectivePeople(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectivePeople()
	}
}

func ExampleNounCollectiveAnimal() {
	Seed(11)
	fmt.Println(NounCollectiveAnimal())
	// Output: part
}

func ExampleFaker_NounCollectiveAnimal() {
	f := New(11)
	fmt.Println(f.NounCollectiveAnimal())
	// Output: part
}

func BenchmarkNounCollectiveAnimal(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectiveAnimal()
	}
}

func ExampleNounCollectiveThing() {
	Seed(11)
	fmt.Println(NounCollectiveThing())
	// Output: part
}

func ExampleFaker_NounCollectiveThing() {
	f := New(11)
	fmt.Println(f.NounCollectiveThing())
	// Output: part
}

func BenchmarkNounCollectiveThing(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectiveThing()
	}
}

func ExampleNounCountable() {
	Seed(11)
	fmt.Println(NounCountable())
	// Output: part
}

func ExampleFaker_NounCountable() {
	f := New(11)
	fmt.Println(f.NounCountable())
	// Output: part
}

func BenchmarkNounCountable(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCountable()
	}
}

func ExampleNounUncountable() {
	Seed(11)
	fmt.Println(NounUncountable())
	// Output: part
}

func ExampleFaker_NounUncountable() {
	f := New(11)
	fmt.Println(f.NounUncountable())
	// Output: part
}

func BenchmarkNounUncountable(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounUncountable()
	}
}

func ExampleNounProper() {
	Seed(11)
	fmt.Println(NounProper())
	// Output: Arlington
}

func ExampleFaker_NounProper() {
	f := New(11)
	fmt.Println(f.NounProper())
	// Output: Arlington
}

func BenchmarkNounProper(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounProper()
	}
}
<commit_msg>word - updated noun tests<commit_after>package gofakeit

import (
	"fmt"
	"testing"
)

func ExampleNoun() {
	Seed(11)
	fmt.Println(Noun())
	// Output: foot
}

func ExampleFaker_Noun() {
	f := New(11)
	fmt.Println(f.Noun())
	// Output: foot
}

func BenchmarkNoun(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Noun()
	}
}

func ExampleNounCommon() {
	Seed(11)
	fmt.Println(NounCommon())
	// Output: part
}

func ExampleFaker_NounCommon() {
	f := New(11)
	fmt.Println(f.NounCommon())
	// Output: part
}

func BenchmarkNounCommon(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCommon()
	}
}

func ExampleNounConcrete() {
	Seed(11)
	fmt.Println(NounConcrete())
	// Output: snowman
}

func ExampleFaker_NounConcrete() {
	f := New(11)
	fmt.Println(f.NounConcrete())
	// Output: snowman
}

func BenchmarkNounConcrete(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounConcrete()
	}
}

func ExampleNounAbstract() {
	Seed(11)
	fmt.Println(NounAbstract())
	// Output: confusion
}

func ExampleFaker_NounAbstract() {
	f := New(11)
	fmt.Println(f.NounAbstract())
	// Output: confusion
}

func BenchmarkNounAbstract(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounAbstract()
	}
}

func ExampleNounCollectivePeople() {
	Seed(11)
	fmt.Println(NounCollectivePeople())
	// Output: body
}

func ExampleFaker_NounCollectivePeople() {
	f := New(11)
	fmt.Println(f.NounCollectivePeople())
	// Output: body
}

func BenchmarkNounCollectivePeople(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectivePeople()
	}
}

func ExampleNounCollectiveAnimal() {
	Seed(11)
	fmt.Println(NounCollectiveAnimal())
	// Output: party
}

func ExampleFaker_NounCollectiveAnimal() {
	f := New(11)
	fmt.Println(f.NounCollectiveAnimal())
	// Output: party
}

func BenchmarkNounCollectiveAnimal(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectiveAnimal()
	}
}

func ExampleNounCollectiveThing() {
	Seed(11)
	fmt.Println(NounCollectiveThing())
	// Output: hand
}

func ExampleFaker_NounCollectiveThing() {
	f := New(11)
	fmt.Println(f.NounCollectiveThing())
	// Output: hand
}

func BenchmarkNounCollectiveThing(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCollectiveThing()
	}
}

func ExampleNounCountable() {
	Seed(11)
	fmt.Println(NounCountable())
	// Output: neck
}

func ExampleFaker_NounCountable() {
	f := New(11)
	fmt.Println(f.NounCountable())
	// Output: neck
}

func BenchmarkNounCountable(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounCountable()
	}
}

func ExampleNounUncountable() {
	Seed(11)
	fmt.Println(NounUncountable())
	// Output: seafood
}

func ExampleFaker_NounUncountable() {
	f := New(11)
	fmt.Println(f.NounUncountable())
	// Output: seafood
}

func BenchmarkNounUncountable(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounUncountable()
	}
}

func ExampleNounProper() {
	Seed(11)
	fmt.Println(NounProper())
	// Output: Arlington
}

func ExampleFaker_NounProper() {
	f := New(11)
	fmt.Println(f.NounProper())
	// Output: Arlington
}

func BenchmarkNounProper(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NounProper()
	}
}
<|endoftext|>


<commit_before>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("get-health-check command", func() {
	Describe("help", func() {
		Context("when --help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("get-health-check", "--help")

				Eventually(session.Out).Should(Say("NAME:"))
				Eventually(session.Out).Should(Say("   get-health-check - Show the type of health check performed on an app"))
				Eventually(session.Out).Should(Say("USAGE:"))
				Eventually(session.Out).Should(Say("   cf get-health-check APP_NAME"))
				Eventually(session).Should(Exit(0))
			})
		})
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				helpers.UnsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No API endpoint set\\. Use 'cf login' or 'cf api' to target an endpoint\\."))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
			})

			It("fails with not logged in message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("Not logged in\\. Use 'cf login' to log in\\."))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when there is no org and space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
			})

			It("fails with no targeted org error message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org"))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when there is no space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
				helpers.TargetOrg(ReadOnlyOrg)
			})

			It("fails with no targeted space error message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space\\."))
				Eventually(session).Should(Exit(1))
			})
		})
	})

	Context("when the environment is set up correctly", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.PrefixedRandomName("SPACE")

			setupCF(orgName, spaceName)
		})

		Context("when the input is invalid", func() {
			Context("when there are not enough arguments", func() {
				It("outputs the usage and exits 1", func() {
					session := helpers.CF("get-health-check")

					Eventually(session.Err).Should(Say("Incorrect Usage:"))
					Eventually(session.Out).Should(Say("NAME:"))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("when there too many arguments", func() {
				It("ignores the extra arguments", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("get-health-check", appName, "extra")

					Eventually(session.Out).Should(Say("Getting health_check_type value for %s", appName))
					Eventually(session.Err).Should(Say("App %s not found", appName))
					Eventually(session.Out).Should(Say("FAILED"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		Context("when the app does not exist", func() {
			It("tells the user that the app is not found and exits 1", func() {
				appName := helpers.PrefixedRandomName("app")
				session := helpers.CF("get-health-check", appName)
				username, _ := helpers.GetCredentials()

				Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
				Eventually(session.Err).Should(Say("App %s not found", appName))
				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when the app exists", func() {
			var (
				appName  string
				username string
			)

			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				helpers.WithHelloWorldApp(func(appDir string) {
					Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
				})
				username, _ = helpers.GetCredentials()
			})

			Context("when the health check type is http", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "http")).Should(Exit(0))
				})

				It("shows an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          http"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   /"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is http with a custom endpoint", func() {
				BeforeEach(func() {
					Skip("until #137592777, #137502797 so set-health-check can set http with endpoint")
					Eventually(helpers.CF("set-health-check", appName, "http", "--endpoint", "/some-endpoint")).Should(Exit(0))
				})

				It("show the custom endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   /some-endpoint"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is none", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "none")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is port", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "port")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          port"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is process", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "process")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type changes from http to another type", func() {
				BeforeEach(func() {
					Skip("until #137592777, #137502797 so set-health-check can set http with endpoint")
					Eventually(helpers.CF("set-health-check", appName, "http", "--endpoint", "/some-endpoint")).Should(Exit(0))
					Eventually(helpers.CF("set-health-check", appName, "process")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})
		})
	})
})
<commit_msg>fix get-health-check integration test output<commit_after>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("get-health-check command", func() {
	Describe("help", func() {
		Context("when --help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("get-health-check", "--help")

				Eventually(session.Out).Should(Say("NAME:"))
				Eventually(session.Out).Should(Say("   get-health-check - Show the type of health check performed on an app"))
				Eventually(session.Out).Should(Say("USAGE:"))
				Eventually(session.Out).Should(Say("   cf get-health-check APP_NAME"))
				Eventually(session).Should(Exit(0))
			})
		})
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				helpers.UnsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No API endpoint set\\. Use 'cf login' or 'cf api' to target an endpoint\\."))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
			})

			It("fails with not logged in message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("Not logged in\\. Use 'cf login' to log in\\."))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when there is no org and space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
			})

			It("fails with no targeted org error message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org"))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when there is no space set", func() {
			BeforeEach(func() {
				helpers.LogoutCF()
				helpers.LoginCF()
				helpers.TargetOrg(ReadOnlyOrg)
			})

			It("fails with no targeted space error message", func() {
				session := helpers.CF("get-health-check", "some-app")

				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space\\."))
				Eventually(session).Should(Exit(1))
			})
		})
	})

	Context("when the environment is set up correctly", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.PrefixedRandomName("SPACE")

			setupCF(orgName, spaceName)
		})

		Context("when the input is invalid", func() {
			Context("when there are not enough arguments", func() {
				It("outputs the usage and exits 1", func() {
					session := helpers.CF("get-health-check")

					Eventually(session.Err).Should(Say("Incorrect Usage:"))
					Eventually(session.Out).Should(Say("NAME:"))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("when there too many arguments", func() {
				It("ignores the extra arguments", func() {
					appName := helpers.PrefixedRandomName("app")
					session := helpers.CF("get-health-check", appName, "extra")
					username, _ := helpers.GetCredentials()

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Err).Should(Say("App %s not found", appName))
					Eventually(session.Out).Should(Say("FAILED"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		Context("when the app does not exist", func() {
			It("tells the user that the app is not found and exits 1", func() {
				appName := helpers.PrefixedRandomName("app")
				session := helpers.CF("get-health-check", appName)
				username, _ := helpers.GetCredentials()

				Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
				Eventually(session.Err).Should(Say("App %s not found", appName))
				Eventually(session.Out).Should(Say("FAILED"))
				Eventually(session).Should(Exit(1))
			})
		})

		Context("when the app exists", func() {
			var (
				appName  string
				username string
			)

			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				helpers.WithHelloWorldApp(func(appDir string) {
					Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
				})
				username, _ = helpers.GetCredentials()
			})

			Context("when the health check type is http", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "http")).Should(Exit(0))
				})

				It("shows an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          http"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   /"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is http with a custom endpoint", func() {
				BeforeEach(func() {
					Skip("until #137592777, #137502797 so set-health-check can set http with endpoint")
					Eventually(helpers.CF("set-health-check", appName, "http", "--endpoint", "/some-endpoint")).Should(Exit(0))
				})

				It("show the custom endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   /some-endpoint"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is none", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "none")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is port", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "port")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          port"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type is process", func() {
				BeforeEach(func() {
					Eventually(helpers.CF("set-health-check", appName, "process")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})

			Context("when the health check type changes from http to another type", func() {
				BeforeEach(func() {
					Skip("until #137592777, #137502797 so set-health-check can set http with endpoint")
					Eventually(helpers.CF("set-health-check", appName, "http", "--endpoint", "/some-endpoint")).Should(Exit(0))
					Eventually(helpers.CF("set-health-check", appName, "process")).Should(Exit(0))
				})

				It("does not show an endpoint", func() {
					session := helpers.CF("get-health-check", appName)

					Eventually(session.Out).Should(Say("Getting health check type for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, username))
					Eventually(session.Out).Should(Say("\n\n"))
					Eventually(session.Out).Should(Say("Health check type:          process"))
					Eventually(session.Out).Should(Say("Endpoint \\(for http type\\):   \n"))
					Eventually(session).Should(Exit(0))
				})
			})
		})
	})
})
<|endoftext|>


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

import (
	"log"
	"path/filepath"

	"golang.org/x/mod/module"

	"github.com/goplus/gop/x/mod/modfetch"
	"github.com/goplus/gop/x/mod/modfile"
)

func LoadClassFile() {
	if modFile.Register == nil {
		return
	}

	var dir string
	var err error
	var claassMod module.Version

	for _, require := range modFile.Require {
		if require.Mod.Path == modFile.Register.ClassfileMod {
			claassMod = require.Mod
		}
	}
	for _, replace := range modFile.Replace {
		if replace.Old.Path == modFile.Register.ClassfileMod {
			claassMod = replace.New
		}
	}

	if claassMod.Version != "" {
		dir, err = modfetch.Download(claassMod)
		if err != nil {
			log.Fatalf("gop: download classsfile module error %v", err)
		}
	} else {
		dir = claassMod.Path
	}

	if dir == "" {
		log.Fatalf("gop: can't find classfile path in require statment")
	}

	gopmod := filepath.Join(dir, "gop.mod")
	data, err := modfetch.Read(gopmod)
	if err != nil {
		log.Fatalf("gop: %v", err)
	}

	var fixed bool
	f, err := modfile.Parse(gopmod, data, fixVersion(&fixed))
	if err != nil {
		// Errors returned by modfile.Parse begin with file:line.
		log.Fatalf("go: errors parsing go.mod:\n%s\n", err)
	}
	classModFile = f
}
<commit_msg>fix the problem that the path to get the class file gop.mod is wrong<commit_after>/*
 * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package modload

import (
	"log"
	"path/filepath"

	"golang.org/x/mod/module"

	"github.com/goplus/gop/x/mod/modfetch"
	"github.com/goplus/gop/x/mod/modfile"
)

func LoadClassFile() {
	if modFile.Register == nil {
		return
	}

	var dir string
	var err error
	var claassMod module.Version

	for _, require := range modFile.Require {
		if require.Mod.Path == modFile.Register.ClassfileMod {
			claassMod = require.Mod
		}
	}
	for _, replace := range modFile.Replace {
		if replace.Old.Path == modFile.Register.ClassfileMod {
			claassMod = replace.New
		}
	}

	if claassMod.Version != "" {
		dir, err = modfetch.Download(claassMod)
		if err != nil {
			log.Fatalf("gop: download classsfile module error %v", err)
		}
	} else {
		dir = claassMod.Path
	}

	if dir == "" {
		log.Fatalf("gop: can't find classfile path in require statment")
	}

	gopmod := filepath.Join(modRoot, dir, "gop.mod")
	data, err := modfetch.Read(gopmod)
	if err != nil {
		log.Fatalf("gop: %v", err)
	}

	var fixed bool
	f, err := modfile.Parse(gopmod, data, fixVersion(&fixed))
	if err != nil {
		// Errors returned by modfile.Parse begin with file:line.
		log.Fatalf("go: errors parsing go.mod:\n%s\n", err)
	}
	classModFile = f
}
<|endoftext|>


<commit_before>package disk

import (
	"testing"
	"time"

	"github.com/funkygao/assert"
)

func TestQueueBasic(t *testing.T) {
	cfg := DefaultConfig()
	cfg.Dirs = []string{"hh"}
	var b block
	q := newQueue("hh", clusterTopic{cluster: "me", topic: "foobar"}, 1<<10, time.Second, time.Hour)
	err := q.Open()
	q.Start()
	assert.Equal(t, nil, err)
	for i := 0; i < 10; i++ {
		b.key = []byte("key")
		b.value = []byte("value")
		err = q.Append(&b)
		assert.Equal(t, nil, err)
	}
	err = q.Close()
	assert.Equal(t, nil, err)
}
<commit_msg>WIP: test case for disk corrupt<commit_after>package disk

import (
	"fmt"
	"testing"
	"time"

	"github.com/funkygao/assert"
)

func TestQueueBasic(t *testing.T) {
	var b block
	q := newQueue("hh", clusterTopic{cluster: "me", topic: "foobar"}, 0, time.Second, time.Hour)
	err := q.Open()
	q.Start()
	assert.Equal(t, nil, err)
	for i := 0; i < 10; i++ {
		b.key = []byte(fmt.Sprintf("key%d", i))
		b.value = []byte(fmt.Sprintf("value%d", i))
		err = q.Append(&b)
		assert.Equal(t, nil, err)
	}
	err = q.Close()
	assert.Equal(t, nil, err)
}

func TestQueueCorrupt(t *testing.T) {
	var b block
	q := newQueue("hh", clusterTopic{cluster: "me", topic: "foobar"}, 0, time.Second, time.Hour)
	err := q.Open()
	assert.Equal(t, nil, err)
	go func() {
		for {
			err := q.Next(&b)
			switch err {
			case nil:
				t.Logf("got block: %s/%s", string(b.key), string(b.value))

			case ErrQueueNotOpen:
				t.Fatal("queu not open")

			case ErrCursorOutOfRange:
				t.Fatal("out of range")

			case ErrEOQ:
				t.Log("end of queue, sleeping...")
				time.Sleep(pollSleep)

			default:
				t.Fatal(err)
			}
		}
	}()

	for i := 0; i < 10; i++ {
		b.key = []byte(fmt.Sprintf("key%d", i))
		b.value = []byte(fmt.Sprintf("value%d", i))
		err = q.Append(&b)
		assert.Equal(t, nil, err)
	}

}
<|endoftext|>


<commit_before>package validate

import (
	"fmt"
	"log"
	"os"
	"path"

	"github.com/gobuffalo/packr"
	"github.com/xeipuuv/gojsonschema"
)

// ValidateJSON is used to check for validity
func ValidateJSON(doc string) bool {

	file := path.Join("file:///", GetPath(), "/", doc)
	box := packr.NewBox("../../../")
	s, err := box.MustString("schema.json")
	if err != nil {
		panic(err.Error())
	}
	schemaLoader := gojsonschema.NewStringLoader(s)
	documentLoader := gojsonschema.NewReferenceLoader(file)
	result, err := gojsonschema.Validate(schemaLoader, documentLoader)
	if err != nil {
		panic(err.Error())
	}

	if result.Valid() {
		fmt.Printf("The document is valid\n")
		return true
	} else {
		fmt.Printf("The document is not valid. see errors :\n")
		for _, desc := range result.Errors() {
			fmt.Printf("- %s\n", desc)
		}
		return false
	}

}

// GetPath is used to get current path
func GetPath() string {
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	return dir
}
<commit_msg>Create generic packr function to get schema<commit_after>package validate

import (
	"fmt"
	"log"
	"os"
	"path"

	"github.com/gobuffalo/packr"
	"github.com/xeipuuv/gojsonschema"
)

// ValidateJSON is used to check for validity
func ValidateJSON(doc string) bool {

	file := path.Join("file:///", GetPath(), "/", doc)
	s := GetSchema()
	schemaLoader := gojsonschema.NewStringLoader(s)
	documentLoader := gojsonschema.NewReferenceLoader(file)
	result, err := gojsonschema.Validate(schemaLoader, documentLoader)
	if err != nil {
		panic(err.Error())
	}

	if result.Valid() {
		fmt.Printf("The document is valid\n")
		return true
	} else {
		fmt.Printf("The document is not valid. see errors :\n")
		for _, desc := range result.Errors() {
			fmt.Printf("- %s\n", desc)
		}
		return false
	}

}

// GetPath is used to get current path
func GetPath() string {
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	return dir
}

//GetSchema is used to obtain the string representation of schema.json via packr
func GetSchema() string {
	box := packr.NewBox("../../../")
	s, err := box.MustString("schema.json")
	if err != nil {
		panic(err.Error())
	}
	return s
}
<|endoftext|>


<commit_before>package completion

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

func NewCmd(rootCmd *cobra.Command) *cobra.Command {
	cmd := &cobra.Command{
		Use:                   "completion",
		DisableFlagsInUseLine: true,
		Short:                 "Generate bash completion scripts",
		Example: fmt.Sprintf(`  # Load completion run
  $ source <(%[1]s completion)

  # To configure current user bash shell to load completions for each session
  $ echo ". <(%[1]s completion)" >> ~/.bashrc`, rootCmd.Name()),
		Run: func(cmd *cobra.Command, args []string) {
			rootCmd.GenBashCompletion(os.Stdout)
		},
	}

	return cmd
}
<commit_msg>[way2alpha13] Remove example about .bashrc from 'werf completion' help<commit_after>package completion

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

func NewCmd(rootCmd *cobra.Command) *cobra.Command {
	cmd := &cobra.Command{
		Use: "completion",
		DisableFlagsInUseLine: true,
		Short: "Generate bash completion scripts",
		Example: fmt.Sprintf(`  # Load completion run
  $ source <(%[1]s completion)`, rootCmd.Name()),
		Run: func(cmd *cobra.Command, args []string) {
			rootCmd.GenBashCompletion(os.Stdout)
		},
	}

	return cmd
}
<|endoftext|>


<commit_before>package writer

import (
	"github.com/tonglil/labeler/types"

	"github.com/golang/glog"
	"github.com/google/go-github/github"
)

func Rename(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if l.From != "" {
			if _, ok := remoteHas(l.Name, remote); ok {
				glog.Infof("Skipped renaming '%s' to '%s', label already exists - please update your config file '%s'", l.From, l.Name, opt.Filename)
				continue
			}

			if r, ok := remoteHas(l.From, remote); ok {
				glog.V(4).Infof("Renaming '%s' to '%s' with color '%s' to '%s'\n", *r.Name, l.Name, *r.Color, l.Color)

				if opt.DryRun {
					count++
					continue
				}

				count++
				continue
			}
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Update(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if r, ok := remoteHas(l.Name, remote); ok {
			glog.V(4).Infof("Updating '%s' with color '%s' to '%s'\n", l.Name, *r.Color, l.Color)

			if opt.DryRun {
				count++
				continue
			}

			count++
			continue
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Create(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if _, ok := remoteHas(l.Name, remote); !ok {
			glog.V(4).Infof("Creating '%s' with color '%s'\n", l.Name, l.Color)

			if opt.DryRun {
				count++
				continue
			}

			count++
			continue
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Delete(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) (int, error) {
	var count int

	for _, l := range remote {
		if _, ok := localHasOrRenamed(*l.Name, local); ok {
			continue
		}

		glog.V(4).Infof("Deleting '%s' with color '%s'\n", *l.Name, *l.Color)

		if opt.DryRun {
			count++
			continue
		}

		count++
	}

	return count, nil
}

func remoteHas(name string, labels []*github.Label) (*github.Label, bool) {
	for _, l := range labels {
		if name == *l.Name {
			return l, true
		}
	}

	return nil, false
}

func localHasOrRenamed(name string, labels []*types.Label) (*types.Label, bool) {
	for _, l := range labels {
		if name == l.Name || name == l.From {
			return l, true
		}
	}

	return nil, false
}
<commit_msg>fix update to check for color diff as well<commit_after>package writer

import (
	"github.com/tonglil/labeler/types"

	"github.com/golang/glog"
	"github.com/google/go-github/github"
)

func Rename(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if l.From != "" {
			if _, ok := remoteHas(l.Name, remote); ok {
				glog.Infof("Skipped renaming '%s' to '%s', label already exists - please update your config file '%s'", l.From, l.Name, opt.Filename)
				continue
			}

			if r, ok := remoteHas(l.From, remote); ok {
				glog.V(4).Infof("Renaming '%s' to '%s' with color '%s' to '%s'\n", *r.Name, l.Name, *r.Color, l.Color)

				if opt.DryRun {
					count++
					continue
				}

				count++
				continue
			}
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Update(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if r, ok := remoteHas(l.Name, remote); ok && l.Color != *r.Color {
			glog.V(4).Infof("Updating '%s' with color '%s' to '%s'\n", l.Name, *r.Color, l.Color)

			if opt.DryRun {
				count++
				continue
			}

			count++
			continue
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Create(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) ([]*types.Label, int, error) {
	var remain []*types.Label
	var count int

	for _, l := range local {
		if _, ok := remoteHas(l.Name, remote); !ok {
			glog.V(4).Infof("Creating '%s' with color '%s'\n", l.Name, l.Color)

			if opt.DryRun {
				count++
				continue
			}

			count++
			continue
		}

		remain = append(remain, l)
	}

	return remain, count, nil
}

func Delete(client *github.Client, opt *types.Options, local []*types.Label, remote []*github.Label) (int, error) {
	var count int

	for _, l := range remote {
		if _, ok := localHasOrRenamed(*l.Name, local); ok {
			continue
		}

		glog.V(4).Infof("Deleting '%s' with color '%s'\n", *l.Name, *l.Color)

		if opt.DryRun {
			count++
			continue
		}

		count++
	}

	return count, nil
}

func remoteHas(name string, labels []*github.Label) (*github.Label, bool) {
	for _, l := range labels {
		if name == *l.Name {
			return l, true
		}
	}

	return nil, false
}

func localHasOrRenamed(name string, labels []*types.Label) (*types.Label, bool) {
	for _, l := range labels {
		if name == l.Name || name == l.From {
			return l, true
		}
	}

	return nil, false
}
<|endoftext|>