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

package xurls

import "regexp"

//go:generate go run tools/tldsgen/main.go
//go:generate go run tools/regexgen/main.go

const (
	letters   = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"
	iriChar   = letters + `0-9`
	pathChar  = iriChar + `.,:;/\-+_()?@&=$~!*%'"`
	endChar   = iriChar + `/\-+_@&=$~*%`
	ipv4Addr  = `(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])`
	ipv6Addr  = `([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:[0-9a-fA-F]{0,4}|:[0-9a-fA-F]{1,4})?|(:[0-9a-fA-F]{1,4}){0,2})|(:[0-9a-fA-F]{1,4}){0,3})|(:[0-9a-fA-F]{1,4}){0,4})|:(:[0-9a-fA-F]{1,4}){0,5})((:[0-9a-fA-F]{1,4}){2}|:(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])(\.(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])){3})|(([0-9a-fA-F]{1,4}:){1,6}|:):[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){7}:`
	ipAddr    = `(` + ipv4Addr + `|` + ipv6Addr + `)`
	iri       = `[` + iriChar + `]([` + iriChar + `\-]{0,61}[` + iriChar + `])?`
	hostName  = `((` + iri + `\.)+` + gtld + `|` + ipAddr + `)`
	wellParen = `([` + pathChar + `]*(\([` + pathChar + `]*\))+)+`
	path      = `(/(` + wellParen + `|[` + pathChar + `]*[` + endChar + `])?)?`
	webURL    = hostName + `(:[0-9]{1,5})?` + path
	email     = `[a-zA-Z0-9._%\-+]{1,256}@` + hostName

	defURL    = `(` + wellParen + `|[` + pathChar + `]*[` + endChar + `])`
	scheme    = `[a-zA-Z.\-+]+://`
	allStrict = scheme + defURL
	all       = allStrict + `|` + webURL + `|` + email
)

var (
	// All matches all the urls it can find
	All       = regexp.MustCompile(all)
	// AllStrict matches only urls with a scheme to avoid false positives
	AllStrict = regexp.MustCompile(allStrict)
)

func init() {
	All.Longest()
	AllStrict.Longest()
}
<commit_msg>Slightly simplify regex vars<commit_after>/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */

package xurls

import "regexp"

//go:generate go run tools/tldsgen/main.go
//go:generate go run tools/regexgen/main.go

const (
	letters   = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"
	iriChar   = letters + `0-9`
	pathChar  = iriChar + `.,:;/\-+_()?@&=$~!*%'"`
	endChar   = iriChar + `/\-+_@&=$~*%`
	ipv4Addr  = `(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])`
	ipv6Addr  = `([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:([0-9a-fA-F]{1,4}:[0-9a-fA-F]{0,4}|:[0-9a-fA-F]{1,4})?|(:[0-9a-fA-F]{1,4}){0,2})|(:[0-9a-fA-F]{1,4}){0,3})|(:[0-9a-fA-F]{1,4}){0,4})|:(:[0-9a-fA-F]{1,4}){0,5})((:[0-9a-fA-F]{1,4}){2}|:(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])(\.(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])){3})|(([0-9a-fA-F]{1,4}:){1,6}|:):[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){7}:`
	ipAddr    = `(` + ipv4Addr + `|` + ipv6Addr + `)`
	iri       = `[` + iriChar + `]([` + iriChar + `\-]{0,61}[` + iriChar + `])?`
	hostName  = `((` + iri + `\.)+` + gtld + `|` + ipAddr + `)`
	wellParen = `([` + pathChar + `]*(\([` + pathChar + `]*\))+)+`
	pathCont  = `(` + wellParen + `|[` + pathChar + `]*[` + endChar + `])`
	path      = `(/` + pathCont + `?)?`
	webURL    = hostName + `(:[0-9]{1,5})?` + path
	email     = `[a-zA-Z0-9._%\-+]{1,256}@` + hostName

	scheme    = `[a-zA-Z.\-+]+://`
	allStrict = scheme + pathCont
	all       = allStrict + `|` + webURL + `|` + email
)

var (
	// All matches all the urls it can find
	All = regexp.MustCompile(all)
	// AllStrict matches only urls with a scheme to avoid false positives
	AllStrict = regexp.MustCompile(allStrict)
)

func init() {
	All.Longest()
	AllStrict.Longest()
}
<|endoftext|>


<commit_before>// Copyright 2012 Gary Burd
//
// 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 redis is a client for the Redis database.
//
// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
// documentation about this package.
//
// Connections
//
// The Conn interface is the primary interface for working with Redis.
// Applications create connections by calling the Dial, DialWithTimeout or
// NewConn functions. In the future, functions will be added for creating
// sharded and other types of connections.
//
// The application must call the connection Close method when the application
// is done with the connection.
//
// Executing Commands
//
// The Conn interface has a generic method for executing Redis commands:
//
//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
//
// The Redis command reference (http://redis.io/commands) lists the available
// commands. An example of using the Redis APPEND command is:
//
//  n, err := conn.Do("APPEND", "key", "value")
//
// The Do method converts command arguments to binary strings for transmission
// to the server as follows:
//
//  Go Type                 Conversion
//  []byte                  Sent as is
//  string                  Sent as is
//  int, int64              strconv.FormatInt(v)
//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
//  bool                    true -> "1", false -> "0"
//  nil                     ""
//  all other types         fmt.Print(v)
//
// Redis command reply types are represented using the following Go types:
//
//  Redis type              Go type
//  error                   redis.Error
//  integer                 int64
//  status                  string
//  bulk                    []byte or nil if value not present.
//  multi-bulk              []interface{} or nil if value not present.
//
// Use type assertions or the reply helper functions to convert from
// interface{} to the specific Go type for the command result.
//
// Pipelining
//
// Connections support pipelining using the Send, Flush and Receive methods.
//
//  Send(commandName string, args ...interface{}) error
//  Flush() error
//  Receive() (reply interface{}, err error)
//
// Send writes the command to the connection's output buffer. Flush flushes the
// connection's output buffer to the server. Receive reads a single reply from
// the server. The following example shows a simple pipeline.
//
//  c.Send("SET", "foo", "bar")
//  c.Send("GET", "foo")
//  c.Flush()
//  c.Receive() // reply from SET
//  v, err = c.Receive() // reply from GET
//
// The Do method combines the functionality of the Send, Flush and Receive
// methods. The Do method starts by writing the command and flushing the output
// buffer. Next, the Do method receives all pending replies including the reply
// for the command just sent by Do. If any of the received replies is an error,
// then Do returns the error. If there are no errors, then Do returns the last
// reply.
//
// Use the Send and Do methods to implement pipelined transactions.
//
//  c.Send("MULTI")
//  c.Send("INCR", "foo")
//  c.Send("INCR", "bar")
//  r, err := c.Do("EXEC")
//  fmt.Println(r) // prints [1, 1]
//
// Concurrency
//
// Connections support a single concurrent caller to the write methods (Send,
// Flush) and a single concurrent caller to the read method (Receive). Because
// Do method combines the functionality of Send, Flush and Receive, the Do
// method cannot be called concurrently with the other methods.
//
// For full concurrent access to Redis, use the thread-safe Pool to get and
// release connections from within a goroutine.
//
// Publish and Subscribe
//
// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
//
//  c.Send("SUBSCRIBE", "example")
//  c.Flush()
//  for {
//      reply, err := c.Receive()
//      if err != nil {
//          return err
//      }
//      // process pushed message
//  }
//
// The PubSubConn type wraps a Conn with convenience methods for implementing
// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
// send and flush a subscription management command. The receive method
// converts a pushed message to convenient types for use in a type switch.
//
//  psc := PubSubConn{c}
//  psc.Subscribe("example")
//  for {
//      switch v := psc.Receive().(type) {
//      case redis.Message:
//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
//      case redis.Subscription:
//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
//      case error:
//          return v
//  }
//
// Reply Helpers
//
// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
// to a value of a specific type. To allow convenient wrapping of calls to the
// connection Do and Receive methods, the functions take a second argument of
// type error.  If the error is non-nil, then the helper function returns the
// error. If the error is nil, the function converts the reply to the specified
// type:
//
//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
//  if err != nil {
//      // handle error return from c.Do or type conversion error.
//  }
//
// The Scan function converts elements of a multi-bulk reply to Go types:
//
//  var value1 int
//  var value2 string
//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
//  if err != nil {
//      // handle error
//  }
//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
//      // handle error
//  }
package redis
<commit_msg>Document Do("")<commit_after>// Copyright 2012 Gary Burd
//
// 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 redis is a client for the Redis database.
//
// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
// documentation about this package.
//
// Connections
//
// The Conn interface is the primary interface for working with Redis.
// Applications create connections by calling the Dial, DialWithTimeout or
// NewConn functions. In the future, functions will be added for creating
// sharded and other types of connections.
//
// The application must call the connection Close method when the application
// is done with the connection.
//
// Executing Commands
//
// The Conn interface has a generic method for executing Redis commands:
//
//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
//
// The Redis command reference (http://redis.io/commands) lists the available
// commands. An example of using the Redis APPEND command is:
//
//  n, err := conn.Do("APPEND", "key", "value")
//
// The Do method converts command arguments to binary strings for transmission
// to the server as follows:
//
//  Go Type                 Conversion
//  []byte                  Sent as is
//  string                  Sent as is
//  int, int64              strconv.FormatInt(v)
//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
//  bool                    true -> "1", false -> "0"
//  nil                     ""
//  all other types         fmt.Print(v)
//
// Redis command reply types are represented using the following Go types:
//
//  Redis type              Go type
//  error                   redis.Error
//  integer                 int64
//  status                  string
//  bulk                    []byte or nil if value not present.
//  multi-bulk              []interface{} or nil if value not present.
//
// Use type assertions or the reply helper functions to convert from
// interface{} to the specific Go type for the command result.
//
// Pipelining
//
// Connections support pipelining using the Send, Flush and Receive methods.
//
//  Send(commandName string, args ...interface{}) error
//  Flush() error
//  Receive() (reply interface{}, err error)
//
// Send writes the command to the connection's output buffer. Flush flushes the
// connection's output buffer to the server. Receive reads a single reply from
// the server. The following example shows a simple pipeline.
//
//  c.Send("SET", "foo", "bar")
//  c.Send("GET", "foo")
//  c.Flush()
//  c.Receive() // reply from SET
//  v, err = c.Receive() // reply from GET
//
// The Do method combines the functionality of the Send, Flush and Receive
// methods. The Do method starts by writing the command and flushing the output
// buffer. Next, the Do method receives all pending replies including the reply
// for the command just sent by Do. If any of the received replies is an error,
// then Do returns the error. If there are no errors, then Do returns the last
// reply. If the command argument to the Do method is "", then the Do method
// will flush the output buffer and receive pending replies without sending a
// command.
//
// Use the Send and Do methods to implement pipelined transactions.
//
//  c.Send("MULTI")
//  c.Send("INCR", "foo")
//  c.Send("INCR", "bar")
//  r, err := c.Do("EXEC")
//  fmt.Println(r) // prints [1, 1]
//
// Concurrency
//
// Connections support a single concurrent caller to the write methods (Send,
// Flush) and a single concurrent caller to the read method (Receive). Because
// Do method combines the functionality of Send, Flush and Receive, the Do
// method cannot be called concurrently with the other methods.
//
// For full concurrent access to Redis, use the thread-safe Pool to get and
// release connections from within a goroutine.
//
// Publish and Subscribe
//
// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
//
//  c.Send("SUBSCRIBE", "example")
//  c.Flush()
//  for {
//      reply, err := c.Receive()
//      if err != nil {
//          return err
//      }
//      // process pushed message
//  }
//
// The PubSubConn type wraps a Conn with convenience methods for implementing
// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
// send and flush a subscription management command. The receive method
// converts a pushed message to convenient types for use in a type switch.
//
//  psc := PubSubConn{c}
//  psc.Subscribe("example")
//  for {
//      switch v := psc.Receive().(type) {
//      case redis.Message:
//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
//      case redis.Subscription:
//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
//      case error:
//          return v
//  }
//
// Reply Helpers
//
// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
// to a value of a specific type. To allow convenient wrapping of calls to the
// connection Do and Receive methods, the functions take a second argument of
// type error.  If the error is non-nil, then the helper function returns the
// error. If the error is nil, the function converts the reply to the specified
// type:
//
//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
//  if err != nil {
//      // handle error return from c.Do or type conversion error.
//  }
//
// The Scan function converts elements of a multi-bulk reply to Go types:
//
//  var value1 int
//  var value2 string
//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
//  if err != nil {
//      // handle error
//  }
//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
//      // handle error
//  }
package redis
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	//"bytes"
	"fmt"
	"io"
	"net"
	"os"
	"sync"
	"time"
)

var wg sync.WaitGroup

type Client struct {
	netType string
	timeout time.Duration
	host    string
	port    string
	address string
}

type Conn struct {
	conn net.Conn
}

func ReadHandle(conn net.Conn) {
	reader := bufio.NewReader(conn)
	for {
		data, err := reader.ReadString('\n')
		if err == io.EOF {
			break
		}
		fmt.Printf("%s", data)
	}
	conn.Close()
}

func WriteHandle(conn net.Conn) {
	writer := bufio.NewReader(os.Stdin)
	for {
		input, err := writer.ReadString('\n')
		if err != nil {
			CheckError(err)
		}
		b := []byte(input)
		_, err = conn.Write(b)
		if err != nil {
			wg.Done()
		}
	}
	conn.Close()
}

func (c Client) GetAddr() string {
	return c.host + ":" + c.port
}

func (c Client) Client() {
	address := c.GetAddr()
	conn, err := net.Dial(c.netType, address)
	CheckError(err)

	wg.Add(1)
	go ReadHandle(conn)
	go WriteHandle(conn)
	wg.Wait()
}

func (c Client) TimeOutClient() {
	fmt.Println("timeoutclient", c.timeout)
	address := c.GetAddr()
	conn, err := net.DialTimeout(c.netType, address, c.timeout)
	CheckError(err)

	wg.Add(1)
	go ReadHandle(conn)
	go WriteHandle(conn)
	wg.Wait()
}

func main() {
	args := GetArgs()

	client := Client{host: args.host, port: args.port}
	if args.netType {
		client.netType = "udp"
	} else {
		client.netType = "tcp"
	}
	if args.timeout != 0 {
		client.timeout = time.Duration(args.timeout) * time.Second
		client.TimeOutClient()
	} else {
		client.Client()
	}

}
<commit_msg>add scanner<commit_after>package main

import (
	"bufio"
	//"bytes"
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
	"sync"
	"time"
)

var wg sync.WaitGroup

type Client struct {
	netType string
	timeout time.Duration
	host    string
	port    string
	address string
}

type Conn struct {
	conn net.Conn
}

func ReadHandle(conn net.Conn) {
	reader := bufio.NewReader(conn)
	for {
		data, err := reader.ReadString('\n')
		if err == io.EOF {
			break
		}
		fmt.Printf("%s", data)
	}
	conn.Close()
}

func WriteHandle(conn net.Conn) {
	writer := bufio.NewReader(os.Stdin)
	for {
		input, err := writer.ReadString('\n')
		if err != nil {
			CheckError(err)
		}
		b := []byte(input)
		_, err = conn.Write(b)
		if err != nil {
			wg.Done()
		}
	}
	conn.Close()
}

func NewClient(host string, port string, netType bool) *Client {
	address := host + ":" + port
	client := Client{host: host, port: port, address: address}
	if netType {
		client.netType = "udp"
	} else {
		client.netType = "tcp"
	}
	return &client
}

func (c *Client) Client() {
	conn, err := net.Dial(c.netType, c.address)
	CheckError(err)

	wg.Add(1)
	go ReadHandle(conn)
	go WriteHandle(conn)
	wg.Wait()
}

func (c *Client) TimeOutClient() {
	conn, err := net.DialTimeout(c.netType, c.address, c.timeout)
	CheckError(err)

	wg.Add(1)
	go ReadHandle(conn)
	go WriteHandle(conn)
	wg.Wait()
}

type Scanner struct {
	host    string
	netType string
	loPort  int
	hiPort  int
}

func NewScanner(host, netType, loPort, hiPort string) *Scanner {
	scanner := Scanner{host: host, netType: netType}
	scanner.loPort, _ = strconv.Atoi(loPort)
	scanner.hiPort, _ = strconv.Atoi(hiPort)
	return &scanner
}

func (s *Scanner) Scan() {
	for port := int(s.loPort); port < int(s.hiPort); port++ {
		port = strconv.Itoa(port)
		client := NewClient(s.host, port, s.netType)
		client.Client()
	}
}

func main() {
	args := GetArgs()
	client := NewClient(args.host, args.port, args.netType)
	if len(args.port) == 2 {
		client.port = args.port[0]
		client.hport = args.port[1]
	}

}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package gerrit implements a gerrit-fetcher using https://github.com/andygrunwald/go-gerrit
package gerrit

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/andygrunwald/go-gerrit"
	"github.com/sirupsen/logrus"

	"k8s.io/test-infra/prow/config"
	"k8s.io/test-infra/prow/kube"
	"k8s.io/test-infra/prow/pjutil"
)

type kubeClient interface {
	CreateProwJob(kube.ProwJob) (kube.ProwJob, error)
}

type gerritAuthentication interface {
	SetCookieAuth(name, value string)
}

type gerritAccount interface {
	GetAccount(name string) (*gerrit.AccountInfo, *gerrit.Response, error)
	SetUsername(accountID string, input *gerrit.UsernameInput) (*string, *gerrit.Response, error)
}

type gerritChange interface {
	QueryChanges(opt *gerrit.QueryChangeOptions) (*[]gerrit.ChangeInfo, *gerrit.Response, error)
	SetReview(changeID, revisionID string, input *gerrit.ReviewInput) (*gerrit.ReviewResult, *gerrit.Response, error)
}

type configAgent interface {
	Config() *config.Config
}

// Controller manages gerrit changes.
type Controller struct {
	ca configAgent

	// go-gerrit change endpoint client
	auth     gerritAuthentication
	account  gerritAccount
	gc       gerritChange
	instance string
	storage  string
	projects []string

	kc kubeClient

	lastUpdate time.Time
}

// NewController returns a new gerrit controller client
func NewController(instance, storage string, projects []string, kc *kube.Client, ca *config.Agent) (*Controller, error) {
	lastUpdate := time.Now()
	if storage != "" {
		buf, err := ioutil.ReadFile(storage)
		if err == nil {
			unix, err := strconv.ParseInt(string(buf), 10, 64)
			if err != nil {
				return nil, err
			} else {
				lastUpdate = time.Unix(unix, 0)
			}
		} else if !os.IsNotExist(err) {
			return nil, err
		}
		// fallback to time.Now() if file does not exist yet
	}

	c, err := gerrit.NewClient(instance, nil)
	if err != nil {
		return nil, err
	}

	return &Controller{
		instance:   instance,
		projects:   projects,
		kc:         kc,
		ca:         ca,
		auth:       c.Authentication,
		account:    c.Accounts,
		gc:         c.Changes,
		lastUpdate: lastUpdate,
		storage:    storage,
	}, nil
}

// Auth authenticates to gerrit server
// Token will expire, so we need to regenerate it once so often
func (c *Controller) Auth() error {
	cmd := exec.Command("python", "./git-cookie-authdaemon")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("Fail to authenticate to gerrit using git-cookie-authdaemon : %v", err)
	}

	raw, err := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), ".git-credential-cache/cookie"))
	if err != nil {
		return err
	}
	fields := strings.Fields(string(raw))
	token := fields[len(fields)-1]

	c.auth.SetCookieAuth("o", token)

	self, _, err := c.account.GetAccount("self")
	if err != nil {
		logrus.WithError(err).Errorf("Fail to auth with token: %s", token)
		return err
	}

	logrus.Infof("Authentication successful, Username: %s", self.Name)

	return nil
}

// SaveLastSync saves last sync time in Unix to a volume
func (c *Controller) SaveLastSync(lastSync time.Time) error {
	if c.storage == "" {
		return nil
	}

	lastSyncUnix := strconv.FormatInt(lastSync.Unix(), 10)
	logrus.Infof("Writing last sync: %s", lastSyncUnix)

	err := ioutil.WriteFile(c.storage+".tmp", []byte(lastSyncUnix), 0644)
	if err != nil {
		return err
	}
	return os.Rename(c.storage+".tmp", c.storage)
}

// Sync looks for newly made gerrit changes
// and creates prowjobs according to presubmit specs
func (c *Controller) Sync() error {
	syncTime := time.Now()
	changes := c.QueryChanges()

	for _, change := range changes {
		if err := c.ProcessChange(change); err != nil {
			logrus.WithError(err).Errorf("Failed process change %v", change.CurrentRevision)
		}
	}

	c.lastUpdate = syncTime
	if err := c.SaveLastSync(syncTime); err != nil {
		logrus.WithError(err).Errorf("last sync %v, cannot save to path %v", syncTime, c.storage)
	}
	logrus.Infof("Processed %d changes", len(changes))
	return nil
}

func (c *Controller) queryProjectChanges(proj string) ([]gerrit.ChangeInfo, error) {
	pending := []gerrit.ChangeInfo{}

	opt := &gerrit.QueryChangeOptions{}
	opt.Query = append(opt.Query, "project:"+proj+"+status:open")
	opt.AdditionalFields = []string{"CURRENT_REVISION", "CURRENT_COMMIT"}

	start := 0

	for {
		opt.Limit = c.ca.Config().Gerrit.RateLimit
		opt.Start = start

		// The change output is sorted by the last update time, most recently updated to oldest updated.
		// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
		changes, _, err := c.gc.QueryChanges(opt)
		if err != nil {
			// should not happen? Let next sync loop catch up
			return pending, fmt.Errorf("failed to query gerrit changes: %v", err)
		}

		logrus.Infof("Find %d changes from query %v", len(*changes), opt.Query)

		if len(*changes) == 0 {
			return pending, nil
		}
		start += len(*changes)

		for _, change := range *changes {
			// if we already processed this change, then we stop the current sync loop
			const layout = "2006-01-02 15:04:05"
			updated, err := time.Parse(layout, change.Updated)
			if err != nil {
				logrus.WithError(err).Errorf("Parse time %v failed", change.Updated)
				continue
			}

			// process if updated later than last updated
			// stop if update was stale
			if updated.After(c.lastUpdate) {
				// we need to make sure the change update is from a new commit change
				rev, ok := change.Revisions[change.CurrentRevision]
				if !ok {
					logrus.WithError(err).Errorf("(should not happen?)cannot find current revision for change %v", change.ID)
					continue
				}

				created, err := time.Parse(layout, rev.Created)
				if err != nil {
					logrus.WithError(err).Errorf("Parse time %v failed", rev.Created)
					continue
				}

				if !created.After(c.lastUpdate) {
					// stale commit
					continue
				}

				pending = append(pending, change)
			} else {
				return pending, nil
			}
		}
	}
}

// QueryChanges will query all valid gerrit changes since controller's last sync loop
func (c *Controller) QueryChanges() []gerrit.ChangeInfo {
	// store a map of changeID:change
	pending := []gerrit.ChangeInfo{}

	// can only query against one project at a time :-(
	for _, proj := range c.projects {
		if res, err := c.queryProjectChanges(proj); err != nil {
			logrus.WithError(err).Errorf("fail to query changes for project %s", proj)
		} else {
			pending = append(pending, res...)
		}
	}

	return pending
}

// ProcessChange creates new presubmit prowjobs base off the gerrit changes
func (c *Controller) ProcessChange(change gerrit.ChangeInfo) error {
	rev, ok := change.Revisions[change.CurrentRevision]
	if !ok {
		return fmt.Errorf("cannot find current revision for change %v", change.ID)
	}

	parentSHA := ""
	if len(rev.Commit.Parents) > 0 {
		parentSHA = rev.Commit.Parents[0].Commit
	}

	logger := logrus.WithField("gerrit change", change.Number)

	type triggeredJob struct {
		Name, URL string
	}
	triggeredJobs := []triggeredJob{}

	for _, spec := range c.ca.Config().Presubmits[c.instance+"/"+change.Project] {
		kr := kube.Refs{
			Org:     c.instance,
			Repo:    change.Project,
			BaseRef: change.Branch,
			BaseSHA: parentSHA,
			Pulls: []kube.Pull{
				{
					Number: change.Number,
					Author: rev.Commit.Author.Name,
					SHA:    change.CurrentRevision,
					Ref:    rev.Ref,
				},
			},
		}

		// TODO(krzyzacy): Support AlwaysRun and RunIfChanged
		pj := pjutil.NewProwJob(pjutil.PresubmitSpec(spec, kr), map[string]string{})
		logger.WithFields(pjutil.ProwJobFields(&pj)).Infof("Creating a new prowjob for change %s.", change.Number)
		if _, err := c.kc.CreateProwJob(pj); err != nil {
			logger.WithError(err).Errorf("fail to create prowjob %v", pj)
		} else {
			var b bytes.Buffer
			template := c.ca.Config().Plank.JobURLTemplate
			if template != nil {
				if err := template.Execute(&b, &pj); err != nil {
					logger.WithFields(pjutil.ProwJobFields(&pj)).Errorf("error executing URL template: %v", err)
				}
				// TODO(krzyzacy): We doesn't have buildID here yet - do a hack to get a proper URL to the PR
				// Remove this once we have proper report interface.

				// mangle
				// https://gubernator.k8s.io/build/gob-prow/pr-logs/pull/some-repo/8940/pull-test-infra-presubmit//
				// to
				// https://gubernator.k8s.io/builds/gob-prow/pr-logs/pull/some-repo/8940/pull-test-infra-presubmit/
				url := b.String()
				url = strings.Replace(url, "builds", "build", 1)
				url = strings.Replace(url, "//", "/", 1)
			}
			triggeredJobs = append(triggeredJobs, triggeredJob{Name: spec.Name, URL: b.String()})
		}
	}

	if len(triggeredJobs) > 0 {
		// comment back to gerrit
		message := "Triggered presubmit:"
		for _, job := range triggeredJobs {
			if job.URL != "" {
				message += fmt.Sprintf("\n  * Name: %s, URL: %s", job.Name, job.URL)
			} else {
				message += fmt.Sprintf("\n  * Name: %s", job.Name)
			}
		}

		if _, _, err := c.gc.SetReview(change.ID, change.CurrentRevision, &gerrit.ReviewInput{
			Message: message,
		}); err != nil {
			return fmt.Errorf("cannot comment to gerrit: %v", err)
		}
	}

	return nil
}
<commit_msg>fix the url hack<commit_after>/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package gerrit implements a gerrit-fetcher using https://github.com/andygrunwald/go-gerrit
package gerrit

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/andygrunwald/go-gerrit"
	"github.com/sirupsen/logrus"

	"k8s.io/test-infra/prow/config"
	"k8s.io/test-infra/prow/kube"
	"k8s.io/test-infra/prow/pjutil"
)

type kubeClient interface {
	CreateProwJob(kube.ProwJob) (kube.ProwJob, error)
}

type gerritAuthentication interface {
	SetCookieAuth(name, value string)
}

type gerritAccount interface {
	GetAccount(name string) (*gerrit.AccountInfo, *gerrit.Response, error)
	SetUsername(accountID string, input *gerrit.UsernameInput) (*string, *gerrit.Response, error)
}

type gerritChange interface {
	QueryChanges(opt *gerrit.QueryChangeOptions) (*[]gerrit.ChangeInfo, *gerrit.Response, error)
	SetReview(changeID, revisionID string, input *gerrit.ReviewInput) (*gerrit.ReviewResult, *gerrit.Response, error)
}

type configAgent interface {
	Config() *config.Config
}

// Controller manages gerrit changes.
type Controller struct {
	ca configAgent

	// go-gerrit change endpoint client
	auth     gerritAuthentication
	account  gerritAccount
	gc       gerritChange
	instance string
	storage  string
	projects []string

	kc kubeClient

	lastUpdate time.Time
}

// NewController returns a new gerrit controller client
func NewController(instance, storage string, projects []string, kc *kube.Client, ca *config.Agent) (*Controller, error) {
	lastUpdate := time.Now()
	if storage != "" {
		buf, err := ioutil.ReadFile(storage)
		if err == nil {
			unix, err := strconv.ParseInt(string(buf), 10, 64)
			if err != nil {
				return nil, err
			} else {
				lastUpdate = time.Unix(unix, 0)
			}
		} else if !os.IsNotExist(err) {
			return nil, err
		}
		// fallback to time.Now() if file does not exist yet
	}

	c, err := gerrit.NewClient(instance, nil)
	if err != nil {
		return nil, err
	}

	return &Controller{
		instance:   instance,
		projects:   projects,
		kc:         kc,
		ca:         ca,
		auth:       c.Authentication,
		account:    c.Accounts,
		gc:         c.Changes,
		lastUpdate: lastUpdate,
		storage:    storage,
	}, nil
}

// Auth authenticates to gerrit server
// Token will expire, so we need to regenerate it once so often
func (c *Controller) Auth() error {
	cmd := exec.Command("python", "./git-cookie-authdaemon")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("Fail to authenticate to gerrit using git-cookie-authdaemon : %v", err)
	}

	raw, err := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), ".git-credential-cache/cookie"))
	if err != nil {
		return err
	}
	fields := strings.Fields(string(raw))
	token := fields[len(fields)-1]

	c.auth.SetCookieAuth("o", token)

	self, _, err := c.account.GetAccount("self")
	if err != nil {
		logrus.WithError(err).Errorf("Fail to auth with token: %s", token)
		return err
	}

	logrus.Infof("Authentication successful, Username: %s", self.Name)

	return nil
}

// SaveLastSync saves last sync time in Unix to a volume
func (c *Controller) SaveLastSync(lastSync time.Time) error {
	if c.storage == "" {
		return nil
	}

	lastSyncUnix := strconv.FormatInt(lastSync.Unix(), 10)
	logrus.Infof("Writing last sync: %s", lastSyncUnix)

	err := ioutil.WriteFile(c.storage+".tmp", []byte(lastSyncUnix), 0644)
	if err != nil {
		return err
	}
	return os.Rename(c.storage+".tmp", c.storage)
}

// Sync looks for newly made gerrit changes
// and creates prowjobs according to presubmit specs
func (c *Controller) Sync() error {
	syncTime := time.Now()
	changes := c.QueryChanges()

	for _, change := range changes {
		if err := c.ProcessChange(change); err != nil {
			logrus.WithError(err).Errorf("Failed process change %v", change.CurrentRevision)
		}
	}

	c.lastUpdate = syncTime
	if err := c.SaveLastSync(syncTime); err != nil {
		logrus.WithError(err).Errorf("last sync %v, cannot save to path %v", syncTime, c.storage)
	}
	logrus.Infof("Processed %d changes", len(changes))
	return nil
}

func (c *Controller) queryProjectChanges(proj string) ([]gerrit.ChangeInfo, error) {
	pending := []gerrit.ChangeInfo{}

	opt := &gerrit.QueryChangeOptions{}
	opt.Query = append(opt.Query, "project:"+proj+"+status:open")
	opt.AdditionalFields = []string{"CURRENT_REVISION", "CURRENT_COMMIT"}

	start := 0

	for {
		opt.Limit = c.ca.Config().Gerrit.RateLimit
		opt.Start = start

		// The change output is sorted by the last update time, most recently updated to oldest updated.
		// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
		changes, _, err := c.gc.QueryChanges(opt)
		if err != nil {
			// should not happen? Let next sync loop catch up
			return pending, fmt.Errorf("failed to query gerrit changes: %v", err)
		}

		logrus.Infof("Find %d changes from query %v", len(*changes), opt.Query)

		if len(*changes) == 0 {
			return pending, nil
		}
		start += len(*changes)

		for _, change := range *changes {
			// if we already processed this change, then we stop the current sync loop
			const layout = "2006-01-02 15:04:05"
			updated, err := time.Parse(layout, change.Updated)
			if err != nil {
				logrus.WithError(err).Errorf("Parse time %v failed", change.Updated)
				continue
			}

			// process if updated later than last updated
			// stop if update was stale
			if updated.After(c.lastUpdate) {
				// we need to make sure the change update is from a new commit change
				rev, ok := change.Revisions[change.CurrentRevision]
				if !ok {
					logrus.WithError(err).Errorf("(should not happen?)cannot find current revision for change %v", change.ID)
					continue
				}

				created, err := time.Parse(layout, rev.Created)
				if err != nil {
					logrus.WithError(err).Errorf("Parse time %v failed", rev.Created)
					continue
				}

				if !created.After(c.lastUpdate) {
					// stale commit
					continue
				}

				pending = append(pending, change)
			} else {
				return pending, nil
			}
		}
	}
}

// QueryChanges will query all valid gerrit changes since controller's last sync loop
func (c *Controller) QueryChanges() []gerrit.ChangeInfo {
	// store a map of changeID:change
	pending := []gerrit.ChangeInfo{}

	// can only query against one project at a time :-(
	for _, proj := range c.projects {
		if res, err := c.queryProjectChanges(proj); err != nil {
			logrus.WithError(err).Errorf("fail to query changes for project %s", proj)
		} else {
			pending = append(pending, res...)
		}
	}

	return pending
}

// ProcessChange creates new presubmit prowjobs base off the gerrit changes
func (c *Controller) ProcessChange(change gerrit.ChangeInfo) error {
	rev, ok := change.Revisions[change.CurrentRevision]
	if !ok {
		return fmt.Errorf("cannot find current revision for change %v", change.ID)
	}

	parentSHA := ""
	if len(rev.Commit.Parents) > 0 {
		parentSHA = rev.Commit.Parents[0].Commit
	}

	logger := logrus.WithField("gerrit change", change.Number)

	type triggeredJob struct {
		Name, URL string
	}
	triggeredJobs := []triggeredJob{}

	for _, spec := range c.ca.Config().Presubmits[c.instance+"/"+change.Project] {
		kr := kube.Refs{
			Org:     c.instance,
			Repo:    change.Project,
			BaseRef: change.Branch,
			BaseSHA: parentSHA,
			Pulls: []kube.Pull{
				{
					Number: change.Number,
					Author: rev.Commit.Author.Name,
					SHA:    change.CurrentRevision,
					Ref:    rev.Ref,
				},
			},
		}

		// TODO(krzyzacy): Support AlwaysRun and RunIfChanged
		pj := pjutil.NewProwJob(pjutil.PresubmitSpec(spec, kr), map[string]string{})
		logger.WithFields(pjutil.ProwJobFields(&pj)).Infof("Creating a new prowjob for change %s.", change.Number)
		if _, err := c.kc.CreateProwJob(pj); err != nil {
			logger.WithError(err).Errorf("fail to create prowjob %v", pj)
		} else {
			var b bytes.Buffer
			template := c.ca.Config().Plank.JobURLTemplate
			if template != nil {
				if err := template.Execute(&b, &pj); err != nil {
					logger.WithFields(pjutil.ProwJobFields(&pj)).Errorf("error executing URL template: %v", err)
				}
				// TODO(krzyzacy): We doesn't have buildID here yet - do a hack to get a proper URL to the PR
				// Remove this once we have proper report interface.

				// mangle
				// https://gubernator.k8s.io/build/gob-prow/pr-logs/pull/some-repo/8940/pull-test-infra-presubmit//
				// to
				// https://gubernator.k8s.io/builds/gob-prow/pr-logs/pull/some-repo/8940/pull-test-infra-presubmit/
				url := b.String()
				url = strings.Replace(url, "build", "builds", 1)
				url = strings.TrimSuffix(url, "//")
			}
			triggeredJobs = append(triggeredJobs, triggeredJob{Name: spec.Name, URL: b.String()})
		}
	}

	if len(triggeredJobs) > 0 {
		// comment back to gerrit
		message := "Triggered presubmit:"
		for _, job := range triggeredJobs {
			if job.URL != "" {
				message += fmt.Sprintf("\n  * Name: %s, URL: %s", job.Name, job.URL)
			} else {
				message += fmt.Sprintf("\n  * Name: %s", job.Name)
			}
		}

		if _, _, err := c.gc.SetReview(change.ID, change.CurrentRevision, &gerrit.ReviewInput{
			Message: message,
		}); err != nil {
			return fmt.Errorf("cannot comment to gerrit: %v", err)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Package instagram implements the OAuth2 protocol for authenticating users through Instagram.
// This package can be used as a reference implementation of an OAuth2 provider for Goth.
package instagram

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

var (
	authURL         = "https://api.instagram.com/oauth/authorize/"
	tokenURL        = "https://api.instagram.com/oauth/access_token"
	endPointProfile = "https://api.instagram.com/v1/users/self/"
)

// New creates a new Instagram provider, and sets up important connection details.
// You should always call `instagram.New` to get a new Provider. Never try to craete
// one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:   clientKey,
		Secret:      secret,
		CallbackURL: callbackURL,
	}
	p.config = newConfig(p, scopes)
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Instagram
type Provider struct {
	ClientKey   string
	Secret      string
	CallbackURL string
	UserAgent   string
	HTTPClient  *http.Client
	config      *oauth2.Config
}

// Name is the name used to retrive this provider later.
func (p *Provider) Name() string {
	return "instagram"
}

func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

//Debug TODO
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Instagram for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.config.AuthCodeURL(state)
	session := &Session{
		AuthURL: url,
	}
	return session, nil
}

// FetchUser will go to Instagram and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken: sess.AccessToken,
		Provider:    p.Name(),
	}

	response, err := p.Client().Get(endPointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))

	if err != nil {
		return user, err
	}
	defer response.Body.Close()

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}
	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}
	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func userFromReader(reader io.Reader, user *goth.User) error {
	u := struct {
		Data struct {
			ID             string `json:"id"`
			UserName       string `json:"username"`
			FullName       string `json:"full_name"`
			ProfilePicture string `json:"profile_picture"`
			Bio            string `json:"bio"`
			Website        string `json:"website"`
			Counts         struct {
				Media      int `json:"media"`
				Follows    int `json:"follows"`
				FollowedBy int `json:"followed_by"`
			} `json:"counts"`
		} `json:"data"`
	}{}
	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return err
	}
	user.Name = u.Data.UserName
	user.NickName = u.Data.UserName
	user.AvatarURL = u.Data.ProfilePicture
	user.Description = u.Data.Bio
	return err
}

func newConfig(p *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     p.ClientKey,
		ClientSecret: p.Secret,
		RedirectURL:  p.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{
			"basic",
		},
	}
	defaultScopes := map[string]struct{}{
		"basic": {},
	}

	for _, scope := range scopes {
		if _, exists := defaultScopes[scope]; !exists {
			c.Scopes = append(c.Scopes, scope)
		}
	}

	return c
}

//RefreshToken refresh token is not provided by instagram
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, errors.New("Refresh token is not provided by instagram")
}

//RefreshTokenAvailable refresh token is not provided by instagram
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}
<commit_msg>add missing UserID to instagram<commit_after>// Package instagram implements the OAuth2 protocol for authenticating users through Instagram.
// This package can be used as a reference implementation of an OAuth2 provider for Goth.
package instagram

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

var (
	authURL         = "https://api.instagram.com/oauth/authorize/"
	tokenURL        = "https://api.instagram.com/oauth/access_token"
	endPointProfile = "https://api.instagram.com/v1/users/self/"
)

// New creates a new Instagram provider, and sets up important connection details.
// You should always call `instagram.New` to get a new Provider. Never try to craete
// one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:   clientKey,
		Secret:      secret,
		CallbackURL: callbackURL,
	}
	p.config = newConfig(p, scopes)
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Instagram
type Provider struct {
	ClientKey   string
	Secret      string
	CallbackURL string
	UserAgent   string
	HTTPClient  *http.Client
	config      *oauth2.Config
}

// Name is the name used to retrive this provider later.
func (p *Provider) Name() string {
	return "instagram"
}

func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

//Debug TODO
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Instagram for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.config.AuthCodeURL(state)
	session := &Session{
		AuthURL: url,
	}
	return session, nil
}

// FetchUser will go to Instagram and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken: sess.AccessToken,
		Provider:    p.Name(),
	}

	response, err := p.Client().Get(endPointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))

	if err != nil {
		return user, err
	}
	defer response.Body.Close()

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}
	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}
	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func userFromReader(reader io.Reader, user *goth.User) error {
	u := struct {
		Data struct {
			ID             string `json:"id"`
			UserName       string `json:"username"`
			FullName       string `json:"full_name"`
			ProfilePicture string `json:"profile_picture"`
			Bio            string `json:"bio"`
			Website        string `json:"website"`
			Counts         struct {
				Media      int `json:"media"`
				Follows    int `json:"follows"`
				FollowedBy int `json:"followed_by"`
			} `json:"counts"`
		} `json:"data"`
	}{}
	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return err
	}
	user.UserID = u.Data.ID
	user.Name = u.Data.UserName
	user.NickName = u.Data.UserName
	user.AvatarURL = u.Data.ProfilePicture
	user.Description = u.Data.Bio
	return err
}

func newConfig(p *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     p.ClientKey,
		ClientSecret: p.Secret,
		RedirectURL:  p.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{
			"basic",
		},
	}
	defaultScopes := map[string]struct{}{
		"basic": {},
	}

	for _, scope := range scopes {
		if _, exists := defaultScopes[scope]; !exists {
			c.Scopes = append(c.Scopes, scope)
		}
	}

	return c
}

//RefreshToken refresh token is not provided by instagram
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, errors.New("Refresh token is not provided by instagram")
}

//RefreshTokenAvailable refresh token is not provided by instagram
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}
<|endoftext|>


<commit_before>// Trigger backups of Cloud Datastore entities to Cloud Storage using the
// datastore v1beta1 API.
//
// See http://go/datastore-backup-example for an example in the APIs Explorer.
package main

import (
	"flag"
	"time"

	"cloud.google.com/go/datastore"
	"go.skia.org/infra/ds/go/backup"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
)

// flags
var (
	promPort = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")
)

const (
	BUCKET  = "skia-backups"
	PROJECT = "google.com:skia-buildbots"
)

func main() {
	common.InitWithMust(
		"datastore_backup",
		common.PrometheusOpt(promPort),
		common.CloudLoggingOpt(),
	)

	ts, err := auth.NewJWTServiceAccountTokenSource("", "", datastore.ScopeDatastore)
	if err != nil {
		sklog.Fatalf("Failed to auth: %s", err)
	}
	// backup package handles retries and specifically handles "resource exhausted" HTTP status code.
	client := httputils.DefaultClientConfig().WithTokenSource(ts).WithoutRetries().Client()
	if err := backup.Step(client, PROJECT, BUCKET); err != nil {
		sklog.Errorf("Failed to do first backup step: %s", err)
	}
	for range time.Tick(24 * time.Hour) {
		if err := backup.Step(client, PROJECT, BUCKET); err != nil {
			sklog.Errorf("Failed to backup: %s", err)
		}
	}
}
<commit_msg>datastore_backup - Move backups to a weekly cadence.<commit_after>// Trigger backups of Cloud Datastore entities to Cloud Storage using the
// datastore v1beta1 API.
//
// See http://go/datastore-backup-example for an example in the APIs Explorer.
package main

import (
	"flag"
	"time"

	"cloud.google.com/go/datastore"
	"go.skia.org/infra/ds/go/backup"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
)

// flags
var (
	promPort = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")
	duration = flag.Duration("duration", time.Hour*24*7, "Time between backups.")
)

const (
	BUCKET  = "skia-backups"
	PROJECT = "google.com:skia-buildbots"
)

func main() {
	common.InitWithMust(
		"datastore_backup",
		common.PrometheusOpt(promPort),
		common.CloudLoggingOpt(),
	)

	ts, err := auth.NewJWTServiceAccountTokenSource("", "", datastore.ScopeDatastore)
	if err != nil {
		sklog.Fatalf("Failed to auth: %s", err)
	}
	// backup package handles retries and specifically handles "resource exhausted" HTTP status code.
	client := httputils.DefaultClientConfig().WithTokenSource(ts).WithoutRetries().Client()
	if err := backup.Step(client, PROJECT, BUCKET); err != nil {
		sklog.Errorf("Failed to do first backup step: %s", err)
	}
	for range time.Tick(*duration) {
		if err := backup.Step(client, PROJECT, BUCKET); err != nil {
			sklog.Errorf("Failed to backup: %s", err)
		}
		sklog.Info("Finished queuing all backups.")
	}
}
<|endoftext|>


<commit_before>//
// tun.go -- tun interface with cgo for linux / bsd
//

package samtun

/*

#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

int tundev_open(char * ifname) {
  int fd = open("/dev/net/tun", O_RDWR);
  if (fd > 0) {
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    if ( ioctl(fd , TUNSETIFF, (void*) &ifr) < 0) {
      close(fd);
      return -1;
    }
  }
  return fd;
}

int tundev_up(char * ifname, char * addr, char * dstaddr, int mtu) {

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
  if ( fd > 0 ) {
    if ( ioctl(fd, SIOCGIFINDEX, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    struct sockaddr_in dst;
    memset(&dst, 0, sizeof(dst));
    dst.sin_addr = inet_addr(dstaddr);
    struct sockaddr_in src;
    memset(&src, 0, sizeof(src));
    src.sin_addr = inet_addr(addr);
    memcpy(&ifr.ifr_addr, src, sizeof(src));
    memcpy(&ifr.ifr_dstaddr, dst, sizeof(dst));
    if ( ioctl(fd, SIOCSIFADDR, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    ifr.ifr_mtu = mtu;
    if ( ioctl(fd, SIOCSIFMTU, &ifr) < 0) {
      close(fd);
      return -1;
    }
    if ( ioctl(fd, SIOCGIFFLAGS, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
    if ( ioctl(fd, SIOCSIFFLAGS, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    close(fd);
    return 0;
  }
  return -1;
}

void tundev_close(int fd) {
  close(fd);
}

*/
import "C"

type tunDev C.int

func newTun(ifname, addr, dstaddr string) (t tunDev, err error) {
  t = C.tundev_open(C.CString(ifname))
  if t == -1 {
    err = errors.New("cannot open tun interface")
  } else {
    if C.tundev_up(C.CString(ifname), C.CString(addr), C.CString(dstaddr), C.int(mtu)) < 0 {
      err = errors.New("cannot put up interface")
    }
  }
  return
}

func (d tunDev) Close() {
  C.tundev_close(d)
}
<commit_msg>more includes<commit_after>//
// tun.go -- tun interface with cgo for linux / bsd
//

package samtun

/*

#include <linux/if.h>
#include <linux/if_tun.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

int tundev_open(char * ifname) {
  int fd = open("/dev/net/tun", O_RDWR);
  if (fd > 0) {
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    if ( ioctl(fd , TUNSETIFF, (void*) &ifr) < 0) {
      close(fd);
      return -1;
    }
  }
  return fd;
}

int tundev_up(char * ifname, char * addr, char * dstaddr, int mtu) {

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
  if ( fd > 0 ) {
    if ( ioctl(fd, SIOCGIFINDEX, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    struct sockaddr_in dst;
    memset(&dst, 0, sizeof(dst));
    dst.sin_addr = inet_addr(dstaddr);
    struct sockaddr_in src;
    memset(&src, 0, sizeof(src));
    src.sin_addr = inet_addr(addr);
    memcpy(&ifr.ifr_addr, src, sizeof(src));
    memcpy(&ifr.ifr_dstaddr, dst, sizeof(dst));
    if ( ioctl(fd, SIOCSIFADDR, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    ifr.ifr_mtu = mtu;
    if ( ioctl(fd, SIOCSIFMTU, &ifr) < 0) {
      close(fd);
      return -1;
    }
    if ( ioctl(fd, SIOCGIFFLAGS, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
    if ( ioctl(fd, SIOCSIFFLAGS, &ifr) < 0 ) {
      close(fd);
      return -1;
    }
    close(fd);
    return 0;
  }
  return -1;
}

void tundev_close(int fd) {
  close(fd);
}

*/
import "C"

type tunDev C.int

func newTun(ifname, addr, dstaddr string) (t tunDev, err error) {
  t = C.tundev_open(C.CString(ifname))
  if t == -1 {
    err = errors.New("cannot open tun interface")
  } else {
    if C.tundev_up(C.CString(ifname), C.CString(addr), C.CString(dstaddr), C.int(mtu)) < 0 {
      err = errors.New("cannot put up interface")
    }
  }
  return
}

func (d tunDev) Close() {
  C.tundev_close(d)
}
<|endoftext|>


<commit_before>package yorm

import (
	"database/sql"
	"errors"
	"reflect"
)

type QuerySetter struct {
	table   string
	dests   []interface{}
	columns []column
}

func QueryOne(i interface{}, row *sql.Row) error {
	if row == nil {
		return errors.New("nil row")
	}
	return convertAssignRow(i, row)
}
func QueryList(i interface{}, rows *sql.Rows) error {
	if rows == nil {
		return errors.New("rows nil")
	}
	return convertAssignRows(i, rows)
}

type sqlScanner interface {
	Scan(dest ...interface{}) error
}

var tableMap map[reflect.Kind]*QuerySetter = make(map[reflect.Kind]*QuerySetter)

func newQuery(ri reflect.Value) *QuerySetter {
	if q, ok := tableMap[ri.Kind()]; ok {
		return q
	}
	if ri.Kind() != reflect.Ptr || ri.IsNil() {
		return nil
	}
	q := new(QuerySetter)
	defer func() {
		tableMap[ri.Kind()] = q
	}()
	table, cs := structToTable(reflect.Indirect(ri).Interface())
	q.table = table
	q.columns = cs
	q.dests = make([]interface{}, len(cs))
	for k, v := range cs {
		q.dests[k] = newInterface(v.typ.Kind())
	}
	return q
}

func newInterface(k reflect.Kind) interface{} {
	var ti interface{}
	switch k {
	case reflect.Int:
		ti = new(int)
	case reflect.Int64:
		ti = new(int64)
	case reflect.String:
		ti = new(string)
	}
	return ti
}

func convertAssignRows(i interface{}, rows *sql.Rows) error {
	typ := reflect.TypeOf(i)
	if typ.Kind() != reflect.Ptr {
		return errors.New("not ptr")
	}
	typ = typ.Elem()
	if typ.Kind() != reflect.Slice {
		return errors.New("need a slice container")
	}
	typ = typ.Elem()
	var q *QuerySetter
	if typ.Kind() == reflect.Struct {
		q = newQuery(reflect.New(typ))
		if q == nil {
			return errors.New("q is not support")
		}
	}
	size := 0
	v := reflect.Indirect(reflect.ValueOf(i))
	ti := newInterface(typ.Kind())
	for rows.Next() {
		if size >= v.Cap() {
			newCap := v.Cap()
			if newCap == 0 {
				newCap = 1
			} else {
				newCap *= 2
			}
			nv := reflect.MakeSlice(v.Type(), v.Len(), newCap)
			reflect.Copy(nv, v)
			v.Set(nv)
		}
		if size >= v.Len() {
			v.SetLen(size + 1)
		}
		st := reflect.New(typ)
		st = st.Elem()
		if q != nil {
			scanValue(rows, q, st)
		} else {
			rows.Scan(ti)
			st.Set(reflect.ValueOf(ti).Elem())
		}
		v.Index(size).Set(st)
		size++
	}
	return nil
}
func convertAssignRow(i interface{}, row *sql.Row) error {
	typ := reflect.TypeOf(i)

	if typ.Kind() == reflect.Ptr && typ.Kind() != reflect.Struct {
		return row.Scan(i)
	}

	q := newQuery(reflect.ValueOf(i))
	if q == nil {
		return errors.New("nil struct")
	}
	st := reflect.ValueOf(i).Elem()
	return scanValue(row, q, st)
}

func scanValue(sc sqlScanner, q *QuerySetter, st reflect.Value) error {
	err := sc.Scan(q.dests...)
	if err != nil {
		return err
	}
	for idx, c := range q.columns {
		// different assign func here
		switch c.typ.Kind() {
		case reflect.Int:
			st.Field(c.fieldNum).SetInt(int64(*(q.dests[idx].(*int))))
		case reflect.Int64:
			st.Field(c.fieldNum).SetInt(int64(*(q.dests[idx].(*int64))))
		case reflect.String:
			st.Field(c.fieldNum).SetString(string(*(q.dests[idx].(*string))))
		}
	}
	return nil
}
<commit_msg>move to query<commit_after>package yorm

import (
	"database/sql"
	"errors"
	"reflect"
)

type querySetter struct {
	table   string
	dests   []interface{}
	columns []column
}

func QueryOne(i interface{}, row *sql.Row) error {
	if row == nil {
		return errors.New("nil row")
	}
	return convertAssignRow(i, row)
}
func QueryList(i interface{}, rows *sql.Rows) error {
	if rows == nil {
		return errors.New("rows nil")
	}
	return convertAssignRows(i, rows)
}

type sqlScanner interface {
	Scan(dest ...interface{}) error
}

var tableMap map[reflect.Kind]*querySetter = make(map[reflect.Kind]*querySetter)

func newQuery(ri reflect.Value) *querySetter {
	if q, ok := tableMap[ri.Kind()]; ok {
		return q
	}
	if ri.Kind() != reflect.Ptr || ri.IsNil() {
		return nil
	}
	q := new(querySetter)
	defer func() {
		tableMap[ri.Kind()] = q
	}()
	table, cs := structToTable(reflect.Indirect(ri).Interface())
	q.table = table
	q.columns = cs
	q.dests = make([]interface{}, len(cs))
	for k, v := range cs {
		q.dests[k] = newInterface(v.typ.Kind())
	}
	return q
}

func newInterface(k reflect.Kind) interface{} {
	var ti interface{}
	switch k {
	case reflect.Int:
		ti = new(int)
	case reflect.Int64:
		ti = new(int64)
	case reflect.String:
		ti = new(string)
	}
	return ti
}

func convertAssignRows(i interface{}, rows *sql.Rows) error {
	typ := reflect.TypeOf(i)
	if typ.Kind() != reflect.Ptr {
		return errors.New("not ptr")
	}
	typ = typ.Elem()
	if typ.Kind() != reflect.Slice {
		return errors.New("need a slice container")
	}
	typ = typ.Elem()
	var q *querySetter
	if typ.Kind() == reflect.Struct {
		q = newQuery(reflect.New(typ))
		if q == nil {
			return errors.New("q is not support")
		}
	}
	size := 0
	v := reflect.Indirect(reflect.ValueOf(i))
	ti := newInterface(typ.Kind())
	for rows.Next() {
		if size >= v.Cap() {
			newCap := v.Cap()
			if newCap == 0 {
				newCap = 1
			} else {
				newCap *= 2
			}
			nv := reflect.MakeSlice(v.Type(), v.Len(), newCap)
			reflect.Copy(nv, v)
			v.Set(nv)
		}
		if size >= v.Len() {
			v.SetLen(size + 1)
		}
		st := reflect.New(typ)
		st = st.Elem()
		if q != nil {
			scanValue(rows, q, st)
		} else {
			rows.Scan(ti)
			st.Set(reflect.ValueOf(ti).Elem())
		}
		v.Index(size).Set(st)
		size++
	}
	return nil
}
func convertAssignRow(i interface{}, row *sql.Row) error {
	typ := reflect.TypeOf(i)

	if typ.Kind() == reflect.Ptr && typ.Kind() != reflect.Struct {
		return row.Scan(i)
	}

	q := newQuery(reflect.ValueOf(i))
	if q == nil {
		return errors.New("nil struct")
	}
	st := reflect.ValueOf(i).Elem()
	return scanValue(row, q, st)
}

func scanValue(sc sqlScanner, q *querySetter, st reflect.Value) error {
	err := sc.Scan(q.dests...)
	if err != nil {
		return err
	}
	for idx, c := range q.columns {
		// different assign func here
		switch c.typ.Kind() {
		case reflect.Int:
			st.Field(c.fieldNum).SetInt(int64(*(q.dests[idx].(*int))))
		case reflect.Int64:
			st.Field(c.fieldNum).SetInt(int64(*(q.dests[idx].(*int64))))
		case reflect.String:
			st.Field(c.fieldNum).SetString(string(*(q.dests[idx].(*string))))
		}
	}
	return nil
}
<|endoftext|>


<commit_before>/**
 * range.go - emit a list of integers separated by spaces starting from
 * first command line parameter to last command line parameter.
 *
 * @author R. S. Doiel, <rsdoiel@gmail.com>
 * copyright (c) 2014 all rights reserved.
 * Released under the Simplified BSD License
 * See: http://opensource.org/licenses/bsd-license.php
 */
package main

import (
	"errors"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

var (
	help          bool
	start         int
	end           int
	increment     int
	randomElement bool
)

var usage = func(exit_code int, msg string) {
	var (
		fh      = os.Stderr
		appname = os.Args[0]
	)

	if exit_code == 0 {
		fh = os.Stdout
	}
	fmt.Fprintf(fh, `%s
 USAGE %s STARTING_INTEGER ENDING_INTEGER [INCREMENT_INTEGER]

 EXAMPLES

 Count from one through five: %s 1 5
 Count from negative two to six: %s -- -2 6
 Count even numbers from two to ten: %s --increment=2 2 10
 Count down from ten to one: %s 10 1
 Pick a random number in range one and ten %s -r 1 10
 Pick a random even number in range two to %s 12 --random --increment=2 2 12

 OPTIONS

`, msg, appname, appname, appname, appname, appname, appname, appname)

	flag.VisitAll(func(f *flag.Flag) {
		fmt.Fprintf(fh, "\t-%s\t(defaults to %s) %s\n", f.Name, f.DefValue, f.Usage)
	})

	fmt.Fprintf(fh, `

 copyright (c) 2014 all rights reserved.
 Released under the Simplified BSD License
 See: http://opensource.org/licenses/bsd-license.php

`)
	os.Exit(exit_code)
}

func init() {
	const (
		helpUsage  = "Display this help document."
		startUsage = "The starting integer."
		endUsage   = "The ending integer."
		incUsage   = "The non-zero integer increment value."
	)

	flag.IntVar(&start, "start", 0, startUsage)
	flag.IntVar(&start, "s", 0, startUsage)
	flag.IntVar(&end, "end", 0, endUsage)
	flag.IntVar(&end, "e", 0, endUsage)
	flag.IntVar(&increment, "increment", 1, incUsage)
	flag.IntVar(&increment, "i", 1, incUsage)
	flag.BoolVar(&randomElement, "r", false, "Pick a range value from range")
	flag.BoolVar(&randomElement, "random", false, "Pick a range value from range")

	flag.BoolVar(&help, "help", help, helpUsage)
	flag.BoolVar(&help, "h", help, helpUsage)
}

func assertOk(e error, failMsg string) {
	if e != nil {
		usage(1, fmt.Sprintf(" %s\n %s\n", failMsg, e))
	}
}

func inRange(i, start, end int) bool {
	if start <= end && i <= end {
		return true
	}
	if start >= end && i >= end {
		return true
	}
	return false
}

func main() {
	flag.Parse()
	if help == true {
		usage(0, "")
	}

	argc := flag.NArg()
	argv := flag.Args()

	if argc < 2 {
		usage(1, "Must include start and end integers.")
	} else if argc > 3 {
		usage(1, "Too many command line arguments.")
	}

	start, err := strconv.Atoi(argv[0])
	assertOk(err, "Start value must be an integer.")
	end, err := strconv.Atoi(argv[1])
	assertOk(err, "End value must be an integer.")
	if argc == 3 {
		increment, err = strconv.Atoi(argv[2])
	} else if increment == 0 {
		err = errors.New("increment was zero")
	}
	assertOk(err, "Increment must be a non-zero integer.")

	if start == end {
		fmt.Printf("%d", start)
		os.Exit(0)
	}

	// Normalize to a positive value.
	if start <= end && increment < 0 {
		increment = increment * -1
	}
	if start > end && increment > 0 {
		increment = increment * -1
	}

	// If randonElement than generate range and pick the ith random element from range
	var (
		ithArray []int
		ith      = 0
	)

	// Now count up or down as appropriate.
	for i := start; inRange(i, start, end) == true; i = i + increment {
		if randomElement == true {
			ithArray = append(ithArray, i)
		} else {
			if i == start {
				fmt.Printf("%d", i)
			} else {
				fmt.Printf(" %d", i)
			}
		}
	}
	// if randomElement we should an array we can pick the elements from
	if randomElement == true {
		rand.Seed(time.Now().Unix())
		ith = rand.Intn(len(ithArray))
		fmt.Printf("%d", ithArray[ith])
	}
}
<commit_msg>Added verion number support<commit_after>/**
 * range.go - emit a list of integers separated by spaces starting from
 * first command line parameter to last command line parameter.
 *
 * @author R. S. Doiel, <rsdoiel@gmail.com>
 * copyright (c) 2014 all rights reserved.
 * Released under the Simplified BSD License
 * See: http://opensource.org/licenses/bsd-license.php
 */
package main

import (
	"errors"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

const version = "0.1.0"

var (
	showVersion   bool
	showHelp      bool
	start         int
	end           int
	increment     int
	randomElement bool
)

var usage = func(exit_code int, msg string) {
	var (
		fh      = os.Stderr
		appname = os.Args[0]
	)

	if exit_code == 0 {
		fh = os.Stdout
	}
	fmt.Fprintf(fh, `%s
 USAGE %s STARTING_INTEGER ENDING_INTEGER [INCREMENT_INTEGER]

 EXAMPLES

 Count from one through five: %s 1 5
 Count from negative two to six: %s -- -2 6
 Count even numbers from two to ten: %s --increment=2 2 10
 Count down from ten to one: %s 10 1
 Pick a random number in range one and ten %s -r 1 10
 Pick a random even number in range two to %s 12 --random --increment=2 2 12

 OPTIONS

`, msg, appname, appname, appname, appname, appname, appname, appname)

	flag.VisitAll(func(f *flag.Flag) {
		fmt.Fprintf(fh, "\t-%s\t(defaults to %s) %s\n", f.Name, f.DefValue, f.Usage)
	})

	fmt.Fprintf(fh, `
 Version %s

 copyright (c) 2014 all rights reserved.
 Released under the Simplified BSD License
 See: http://opensource.org/licenses/bsd-license.php

`, version)
	os.Exit(exit_code)
}

func init() {
	const (
		helpUsage    = "Display this help document."
		versionUsage = "Display version"
		startUsage   = "The starting integer."
		endUsage     = "The ending integer."
		incUsage     = "The non-zero integer increment value."
	)

	flag.IntVar(&start, "start", 0, startUsage)
	flag.IntVar(&start, "s", 0, startUsage)
	flag.IntVar(&end, "end", 0, endUsage)
	flag.IntVar(&end, "e", 0, endUsage)
	flag.IntVar(&increment, "increment", 1, incUsage)
	flag.IntVar(&increment, "i", 1, incUsage)
	flag.BoolVar(&randomElement, "r", false, "Pick a range value from range")
	flag.BoolVar(&randomElement, "random", false, "Pick a range value from range")

	flag.BoolVar(&showHelp, "help", showHelp, helpUsage)
	flag.BoolVar(&showHelp, "h", showHelp, helpUsage)
	flag.BoolVar(&showVersion, "v", showVersion, versionUsage)
	flag.BoolVar(&showVersion, "version", showVersion, versionUsage)
}

func assertOk(e error, failMsg string) {
	if e != nil {
		usage(1, fmt.Sprintf(" %s\n %s\n", failMsg, e))
	}
}

func inRange(i, start, end int) bool {
	if start <= end && i <= end {
		return true
	}
	if start >= end && i >= end {
		return true
	}
	return false
}

func main() {
	flag.Parse()
	if showHelp == true {
		usage(0, "")
	}
	if showVersion == true {
		fmt.Printf("Version %s\n", version)
		os.Exit(0)
	}

	argc := flag.NArg()
	argv := flag.Args()

	if argc < 2 {
		usage(1, "Must include start and end integers.")
	} else if argc > 3 {
		usage(1, "Too many command line arguments.")
	}

	start, err := strconv.Atoi(argv[0])
	assertOk(err, "Start value must be an integer.")
	end, err := strconv.Atoi(argv[1])
	assertOk(err, "End value must be an integer.")
	if argc == 3 {
		increment, err = strconv.Atoi(argv[2])
	} else if increment == 0 {
		err = errors.New("increment was zero")
	}
	assertOk(err, "Increment must be a non-zero integer.")

	if start == end {
		fmt.Printf("%d", start)
		os.Exit(0)
	}

	// Normalize to a positive value.
	if start <= end && increment < 0 {
		increment = increment * -1
	}
	if start > end && increment > 0 {
		increment = increment * -1
	}

	// If randonElement than generate range and pick the ith random element from range
	var (
		ithArray []int
		ith      = 0
	)

	// Now count up or down as appropriate.
	for i := start; inRange(i, start, end) == true; i = i + increment {
		if randomElement == true {
			ithArray = append(ithArray, i)
		} else {
			if i == start {
				fmt.Printf("%d", i)
			} else {
				fmt.Printf(" %d", i)
			}
		}
	}
	// if randomElement we should an array we can pick the elements from
	if randomElement == true {
		rand.Seed(time.Now().Unix())
		ith = rand.Intn(len(ithArray))
		fmt.Printf("%d", ithArray[ith])
	}
}
<|endoftext|>


<commit_before>package hstspreload

import (
	"fmt"
	"net/http"
	"testing"
)

/******** Helper functions tests. ********/

func expectNil(t *testing.T, actual *string) {
	if actual != nil {
		t.Errorf("Expected nil.")
	}
}
func expectString(t *testing.T, actual *string, expected string) {
	if actual == nil {
		t.Errorf("Expected `%s`, actual was nil.", expected)
	} else if *actual != expected {
		t.Errorf("Strings are not equal. Actual: `%s` Expected: `%s`", *actual, expected)
	}
}

/******** Response tests. ********/

func ExamplePreloadableResponse() {
	resp, err := http.Get("localhost:8080")
	if err != nil {
		header, issues := PreloadableResponse(resp)
		fmt.Printf("Header: %s", *header)
		fmt.Printf("Issues: %v", issues)
	}
}

func TestPreloadableResponseGoodHeader(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "max-age=10886400; includeSubDomains; preload"
	resp.Header.Add(key, sentHeader)

	header, issues := PreloadableResponse(resp)
	expectString(t, header, sentHeader)
	expectIssuesEmpty(t, issues)
}

func TestPreloadableResponseEmpty(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := ""
	resp.Header.Add(key, sentHeader)

	header, issues := PreloadableResponse(resp)
	expectString(t, header, sentHeader)
	expectIssuesEqual(t, issues,
		Issues{
			Errors: []string{
				"Header requirement error: Header must contain the `includeSubDomains` directive.",
				"Header requirement error: Header must contain the `preload` directive.",
				"Header requirement error: Header must contain a valid `max-age` directive.",
			},
			Warnings: []string{"Syntax warning: Header is empty."},
		},
	)
}

func TestPreloadableResponseMultipleErrors(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "includeSubDomains; max-age=100"
	resp.Header.Add(key, sentHeader)

	header, issues := PreloadableResponse(resp)

	expectString(t, header, sentHeader)
	expectIssuesEqual(t, issues,
		Issues{
			Errors: []string{
				"Header requirement error: Header must contain the `preload` directive.",
				"Header requirement error: The max-age must be at least 10886400 seconds (== 18 weeks), but the header currently only has max-age=100.",
			},
			Warnings: []string{},
		},
	)
}

func TestPreloadableResponseMissingIncludeSubDomains(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "preload; max-age=10886400"
	resp.Header.Add(key, sentHeader)

	header, issues := PreloadableResponse(resp)

	expectString(t, header, sentHeader)
	expectIssuesEqual(t, issues,
		NewIssues().addErrorf("Header requirement error: Header must contain the `includeSubDomains` directive."),
	)
}

func TestPreloadableResponseWithoutHSTSHeaders(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	header, issues := PreloadableResponse(resp)
	expectNil(t, header)

	expectIssuesEqual(t, issues,
		NewIssues().addErrorf("Response error: No HSTS header is present on the response."),
	)
}

func TestPreloadableResponseMultipleHSTSHeaders(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	resp.Header.Add(key, "max-age=10")
	resp.Header.Add(key, "max-age=20")

	header, issues := PreloadableResponse(resp)
	expectNil(t, header)

	expectIssuesEqual(t, issues,
		NewIssues().addErrorf("Response error: Multiple HSTS headers (number of HSTS headers: 2)."),
	)
}

func TestRemovableResponseNoHeader(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	header, issues := RemovableResponse(resp)
	expectNil(t, header)

	expectIssuesEqual(t, issues,
		NewIssues().addErrorf("Response error: No HSTS header is present on the response."),
	)
}

func TestRemovableResponseNoPreload(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "max-age=15768000; includeSubDomains"
	resp.Header.Add(key, sentHeader)

	header, issues := RemovableResponse(resp)
	expectString(t, header, sentHeader)

	expectIssuesEmpty(t, issues)
}

func TestRemovableResponsePreload(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "max-age=15768000; includeSubDomains; preload"
	resp.Header.Add(key, sentHeader)

	header, issues := RemovableResponse(resp)
	expectString(t, header, sentHeader)

	expectIssuesEqual(t, issues,
		Issues{
			Errors:   []string{"Header requirement error: For preload list removal, the header must not contain the `preload` directive."},
			Warnings: []string{},
		},
	)
}

func TestRemovableResponsePreloadOnly(t *testing.T) {
	resp := &http.Response{}
	resp.Header = http.Header{}

	key := http.CanonicalHeaderKey("Strict-Transport-Security")
	sentHeader := "preload"
	resp.Header.Add(key, sentHeader)

	header, issues := RemovableResponse(resp)
	expectString(t, header, sentHeader)

	expectIssuesEqual(t, issues,
		Issues{
			Errors: []string{
				"Header requirement error: For preload list removal, the header must not contain the `preload` directive.",
				"Header requirement error: Header must contain a valid `max-age` directive.",
			},
			Warnings: []string{},
		},
	)
}
<commit_msg>Consolidate response tests into a single function.<commit_after>package hstspreload

import (
	"fmt"
	"net/http"
	"testing"
)

const (
	headerStringsShouldBeEqual = `Did not receive expected header.
			Actual: "%v"
			Expected: "%v"`
)

/******** Examples. ********/

func ExamplePreloadableResponse() {
	resp, err := http.Get("localhost:8080")
	if err != nil {
		header, issues := PreloadableResponse(resp)
		fmt.Printf("Header: %s", *header)
		fmt.Printf("Issues: %v", issues)
	}
}

/******** Helper functions tests. ********/

func expectNil(t *testing.T, actual *string) {
	if actual != nil {
		t.Errorf("Expected nil.")
	}
}
func expectString(t *testing.T, actual *string, expected string) {
	if actual == nil {
		t.Errorf("Expected `%s`, actual was nil.", expected)
	} else if *actual != expected {
		t.Errorf("Strings are not equal. Actual: `%s` Expected: `%s`", *actual, expected)
	}
}

/******** Response tests. ********/

var responseTests = []struct {
	function       func(resp *http.Response) (header *string, issues Issues)
	description    string
	hstsHeaders    []string
	expectedIssues Issues
}{

	/******** PreloadableResponse() ********/

	{
		PreloadableResponse,
		"good header",
		[]string{"max-age=10886400; includeSubDomains; preload"},
		Issues{},
	},
	{
		PreloadableResponse,
		"missing preload",
		[]string{"max-age=10886400; includeSubDomains"},
		Issues{Errors: []string{"Header requirement error: Header must contain the `preload` directive."}},
	},
	{
		PreloadableResponse,
		"missing includeSubDomains",
		[]string{"preload; max-age=10886400"},
		NewIssues().addErrorf("Header requirement error: Header must contain the `includeSubDomains` directive."),
	},
	{
		PreloadableResponse,
		"single header, multiple errors",
		[]string{"includeSubDomains; max-age=100"},
		Issues{
			Errors: []string{
				"Header requirement error: Header must contain the `preload` directive.",
				"Header requirement error: The max-age must be at least 10886400 seconds (== 18 weeks), but the header currently only has max-age=100.",
			},
		},
	},
	{
		PreloadableResponse,
		"empty header",
		[]string{""},
		Issues{
			Errors: []string{
				"Header requirement error: Header must contain the `includeSubDomains` directive.",
				"Header requirement error: Header must contain the `preload` directive.",
				"Header requirement error: Header must contain a valid `max-age` directive.",
			},
			Warnings: []string{"Syntax warning: Header is empty."},
		},
	},
	{
		PreloadableResponse,
		"missing header",
		[]string{},
		Issues{Errors: []string{"Response error: No HSTS header is present on the response."}},
	},
	{
		PreloadableResponse,
		"multiple headers",
		[]string{"max-age=10", "max-age=20", "max-age=30"},
		Issues{Errors: []string{"Response error: Multiple HSTS headers (number of HSTS headers: 3)."}},
	},

	/******** RemovableResponse() ********/

	{
		RemovableResponse,
		"no preload",
		[]string{"max-age=15768000; includeSubDomains"},
		Issues{},
	},
	{
		RemovableResponse,
		"preload present",
		[]string{"max-age=15768000; includeSubDomains; preload"},
		Issues{Errors: []string{"Header requirement error: For preload list removal, the header must not contain the `preload` directive."}},
	},
	{
		RemovableResponse,
		"preload only",
		[]string{"preload"},
		Issues{
			Errors: []string{
				"Header requirement error: For preload list removal, the header must not contain the `preload` directive.",
				"Header requirement error: Header must contain a valid `max-age` directive.",
			},
		},
	},
}

func TestPreloabableResponseAndRemovableResponse(t *testing.T) {
	for _, tt := range responseTests {

		resp := &http.Response{}
		resp.Header = http.Header{}

		key := http.CanonicalHeaderKey("Strict-Transport-Security")
		for _, h := range tt.hstsHeaders {
			resp.Header.Add(key, h)
		}

		header, issues := tt.function(resp)

		if len(tt.hstsHeaders) == 1 {
			if header == nil {
				t.Errorf("[%s] Did not receive exactly one HSTS header", tt.description)
			} else if *header != tt.hstsHeaders[0] {
				t.Errorf("[%s] "+headerStringsShouldBeEqual, tt.description, *header, tt.hstsHeaders[0])
			}
		} else {
			if header != nil {
				t.Errorf("[%s] Did not expect a header, but received `%s`", tt.description, *header)
			}
		}

		if !issuesEqual(issues, tt.expectedIssues) {
			t.Errorf("[%s] "+issuesShouldBeEqual, tt.description, issues, tt.expectedIssues)
		}
	}
}
<|endoftext|>


<commit_before>package concrete

import (
	"errors"
	"math"
	"strings"

	gr "github.com/gonum/graph"
)

type TileGraph struct {
	tiles            []bool
	numRows, numCols int
}

func NewTileGraph(dimX, dimY int, isPassable bool) *TileGraph {
	tiles := make([]bool, dimX*dimY)
	if isPassable {
		for i, _ := range tiles {
			tiles[i] = true
		}
	}

	return &TileGraph{
		tiles:   tiles,
		numRows: dimX,
		numCols: dimY,
	}
}

func GenerateTileGraph(template string) (*TileGraph, error) {
	rows := strings.Split(strings.TrimSpace(template), "\n")

	tiles := make([]bool, 0)

	colCheck := -1
	for _, colString := range rows {
		colCount := 0
		cols := strings.NewReader(colString)
		for cols.Len() != 0 {
			colCount += 1
			ch, _, err := cols.ReadRune()
			if err != nil {
				return nil, errors.New("Error while reading rune from input string")
			}

			switch ch {
			case '\u2580':
				tiles = append(tiles, false)
			case ' ':
				tiles = append(tiles, true)
			default:
				return nil, errors.New("Unrecognized character while reading input string")
			}
		}

		if colCheck == -1 {
			colCheck = colCount
		} else if colCheck != colCount {
			return nil, errors.New("Jagged rows, cannot generate graph.")
		}
	}

	return &TileGraph{
		tiles:   tiles,
		numRows: len(rows),
		numCols: colCheck,
	}, nil
}

func (graph *TileGraph) SetPassability(row, col int, passability bool) {
	loc := row*graph.numCols + col
	if loc >= len(graph.tiles) || row < 0 || col < 0 {
		return
	}

	graph.tiles[loc] = passability
}

func (graph *TileGraph) String() string {
	var outString string
	for r := 0; r < graph.numRows; r++ {
		for c := 0; c < graph.numCols; c++ {
			if graph.tiles[r*graph.numCols+c] == false {
				outString += "\u2580" // Black square
			} else {
				outString += " " // Space
			}
		}

		outString += "\n"
	}

	return outString[:len(outString)-1] // Kill final newline
}

func (graph *TileGraph) PathString(path []gr.Node) string {
	if path == nil || len(path) == 0 {
		return graph.String()
	}

	var outString string
	for r := 0; r < graph.numRows; r++ {
		for c := 0; c < graph.numCols; c++ {
			if id := r*graph.numCols + c; graph.tiles[id] == false {
				outString += "\u2580" // Black square
			} else if id == path[0].ID() {
				outString += "s"
			} else if id == path[len(path)-1].ID() {
				outString += "g"
			} else {
				toAppend := " "
				for _, num := range path[1 : len(path)-1] {
					if id == num.ID() {
						toAppend = "♥"
					}
				}
				outString += toAppend
			}
		}

		outString += "\n"
	}

	return outString[:len(outString)-1]
}

func (graph *TileGraph) Dimensions() (rows, cols int) {
	return graph.numRows, graph.numCols
}

func (graph *TileGraph) IDToCoords(id int) (row, col int) {
	col = (id % graph.numCols)
	row = (id - col) / graph.numCols

	return row, col
}

func (graph *TileGraph) CoordsToID(row, col int) (id int) {
	if row < 0 || row >= graph.numRows || col < 0 || col >= graph.numCols {
		return -1
	}
	id = row*graph.numCols + col

	return id
}

func (graph *TileGraph) CoordsToNode(row, col int) (node gr.Node) {
	id := graph.CoordsToID(row, col)
	if id == -1 {
		return nil
	} else {
		return Node(id)
	}
}

func (graph *TileGraph) Neighbors(node gr.Node) []gr.Node {
	id := node.ID()
	if !NodeExists(node) {
		return nil
	}

	row, col := graph.IDToCoords(id)

	neighbors := []gr.Node{graph.CoordsToNode(row-1, col), graph.CoordsToNode(row+1, col), graph.CoordsToNode(row, col-1), graph.CoordsToNode(row, col+1)}
	realNeighbors := make([]gr.Node, 0, 4) // Will overallocate sometimes, but not by much. Not a big deal
	for _, neighbor := range neighbors {
		if neighbor != nil && graph.tiles[neighbor.ID()] == true {
			realNeighbors = append(realNeighbors, neighbor)
		}
	}

	return realNeighbors
}

func (graph *TileGraph) EdgeBetween(node, neighbor gr.Node) gr.Edge {
	id, succ := node.ID(), successor.ID()
	if !graph.NodeExists(node.ID()) || !graph.NodeExist(node.ID()) {
		return nil
	}

	r1, c1 := graph.IDToCoords(node.ID())
	r2, c2 := graph.IDToCoords(neighbor.ID())
	if (c1 == c2 && (r2 == r1+1 || r2 == r1-1)) || (r1 == r2 && (c2 == c1+1 || c2 == c1-1)) {
		return Edge{node, neighbor}
	}

	return nil
}

func (graph *TileGraph) NodeExists(node gr.Node) bool {
	id := node.ID()
	return id >= 0 && id < len(graph.tiles) && graph.tiles[id] == true
}

func (graph *TileGraph) Degree(node gr.Node) int {
	return len(graph.Neighbors(node)) * 2
}

func (graph *TileGraph) EdgeList() []gr.Edge {
	edges := make([]gr.Edge, 0)
	for id, passable := range graph.tiles {
		if !passable {
			continue
		}

		for _, succ := range graph.successors(Node(id)) {
			edges = append(edges, Edge{Node(id), succ})
		}
	}

	return edges
}

func (graph *TileGraph) NodeList() []gr.Node {
	nodes := make([]gr.Node, 0)
	for id, passable := range graph.tiles {
		if !passable {
			continue
		}

		nodes = append(nodes, Node(id))
	}

	return nodes
}

func (graph *TileGraph) Cost(e gr.Edge) float64 {
	if edge := graph.EdgeBetween(e.Head(), e.Tail()); edge != nil {
		return 1.0
	}

	return math.Inf(1)
}
<commit_msg>Cleaned up TileGraph<commit_after>package concrete

import (
	"errors"
	"math"
	"strings"

	gr "github.com/gonum/graph"
)

type TileGraph struct {
	tiles            []bool
	numRows, numCols int
}

func NewTileGraph(dimX, dimY int, isPassable bool) *TileGraph {
	tiles := make([]bool, dimX*dimY)
	if isPassable {
		for i, _ := range tiles {
			tiles[i] = true
		}
	}

	return &TileGraph{
		tiles:   tiles,
		numRows: dimX,
		numCols: dimY,
	}
}

func GenerateTileGraph(template string) (*TileGraph, error) {
	rows := strings.Split(strings.TrimSpace(template), "\n")

	tiles := make([]bool, 0)

	colCheck := -1
	for _, colString := range rows {
		colCount := 0
		cols := strings.NewReader(colString)
		for cols.Len() != 0 {
			colCount += 1
			ch, _, err := cols.ReadRune()
			if err != nil {
				return nil, errors.New("Error while reading rune from input string")
			}

			switch ch {
			case '\u2580':
				tiles = append(tiles, false)
			case ' ':
				tiles = append(tiles, true)
			default:
				return nil, errors.New("Unrecognized character while reading input string")
			}
		}

		if colCheck == -1 {
			colCheck = colCount
		} else if colCheck != colCount {
			return nil, errors.New("Jagged rows, cannot generate graph.")
		}
	}

	return &TileGraph{
		tiles:   tiles,
		numRows: len(rows),
		numCols: colCheck,
	}, nil
}

func (graph *TileGraph) SetPassability(row, col int, passability bool) {
	loc := row*graph.numCols + col
	if loc >= len(graph.tiles) || row < 0 || col < 0 {
		return
	}

	graph.tiles[loc] = passability
}

func (graph *TileGraph) String() string {
	var outString string
	for r := 0; r < graph.numRows; r++ {
		for c := 0; c < graph.numCols; c++ {
			if graph.tiles[r*graph.numCols+c] == false {
				outString += "\u2580" // Black square
			} else {
				outString += " " // Space
			}
		}

		outString += "\n"
	}

	return outString[:len(outString)-1] // Kill final newline
}

func (graph *TileGraph) PathString(path []gr.Node) string {
	if path == nil || len(path) == 0 {
		return graph.String()
	}

	var outString string
	for r := 0; r < graph.numRows; r++ {
		for c := 0; c < graph.numCols; c++ {
			if id := r*graph.numCols + c; graph.tiles[id] == false {
				outString += "\u2580" // Black square
			} else if id == path[0].ID() {
				outString += "s"
			} else if id == path[len(path)-1].ID() {
				outString += "g"
			} else {
				toAppend := " "
				for _, num := range path[1 : len(path)-1] {
					if id == num.ID() {
						toAppend = "♥"
					}
				}
				outString += toAppend
			}
		}

		outString += "\n"
	}

	return outString[:len(outString)-1]
}

func (graph *TileGraph) Dimensions() (rows, cols int) {
	return graph.numRows, graph.numCols
}

func (graph *TileGraph) IDToCoords(id int) (row, col int) {
	col = (id % graph.numCols)
	row = (id - col) / graph.numCols

	return row, col
}

func (graph *TileGraph) CoordsToID(row, col int) (id int) {
	if row < 0 || row >= graph.numRows || col < 0 || col >= graph.numCols {
		return -1
	}
	id = row*graph.numCols + col

	return id
}

func (graph *TileGraph) CoordsToNode(row, col int) (node gr.Node) {
	id := graph.CoordsToID(row, col)
	if id == -1 {
		return nil
	} else {
		return Node(id)
	}
}

func (graph *TileGraph) Neighbors(node gr.Node) []gr.Node {
	id := node.ID()
	if !graph.NodeExists(node) {
		return nil
	}

	row, col := graph.IDToCoords(id)

	neighbors := []gr.Node{graph.CoordsToNode(row-1, col), graph.CoordsToNode(row+1, col), graph.CoordsToNode(row, col-1), graph.CoordsToNode(row, col+1)}
	realNeighbors := make([]gr.Node, 0, 4) // Will overallocate sometimes, but not by much. Not a big deal
	for _, neighbor := range neighbors {
		if neighbor != nil && graph.tiles[neighbor.ID()] == true {
			realNeighbors = append(realNeighbors, neighbor)
		}
	}

	return realNeighbors
}

func (graph *TileGraph) EdgeBetween(node, neighbor gr.Node) gr.Edge {
	if !graph.NodeExists(node) || !graph.NodeExists(neighbor) {
		return nil
	}

	r1, c1 := graph.IDToCoords(node.ID())
	r2, c2 := graph.IDToCoords(neighbor.ID())
	if (c1 == c2 && (r2 == r1+1 || r2 == r1-1)) || (r1 == r2 && (c2 == c1+1 || c2 == c1-1)) {
		return Edge{node, neighbor}
	}

	return nil
}

func (graph *TileGraph) NodeExists(node gr.Node) bool {
	id := node.ID()
	return id >= 0 && id < len(graph.tiles) && graph.tiles[id] == true
}

func (graph *TileGraph) Degree(node gr.Node) int {
	return len(graph.Neighbors(node)) * 2
}

func (graph *TileGraph) EdgeList() []gr.Edge {
	edges := make([]gr.Edge, 0)
	for id, passable := range graph.tiles {
		if !passable {
			continue
		}

		for _, succ := range graph.Neighbors(Node(id)) {
			edges = append(edges, Edge{Node(id), succ})
		}
	}

	return edges
}

func (graph *TileGraph) NodeList() []gr.Node {
	nodes := make([]gr.Node, 0)
	for id, passable := range graph.tiles {
		if !passable {
			continue
		}

		nodes = append(nodes, Node(id))
	}

	return nodes
}

func (graph *TileGraph) Cost(e gr.Edge) float64 {
	if edge := graph.EdgeBetween(e.Head(), e.Tail()); edge != nil {
		return 1.0
	}

	return math.Inf(1)
}
<|endoftext|>