<commit_before>package null

import (
	gossh "code.google.com/p/gosshold/ssh"
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/communicator/ssh"
	"io/ioutil"
)

// SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address
func SSHAddress(host string, port int) func(multistep.StateBag) (string, error) {
	return func(state multistep.StateBag) (string, error) {
		return fmt.Sprintf("%s:%d", host, port), nil
	}
}

// SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the specified host via SSH
// private_key_file has precedence over password!
func SSHConfig(username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
	return func(state multistep.StateBag) (*gossh.ClientConfig, error) {

		if privateKeyFile != "" {
			// key based auth

			bytes, err := ioutil.ReadFile(privateKeyFile)
			if err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}
			privateKey := string(bytes)

			keyring := new(ssh.SimpleKeychain)
			if err := keyring.AddPEMKey(privateKey); err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.ClientAuth{
					gossh.ClientAuthKeyring(keyring),
				},
			}, nil
		} else {
			// password based auth

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.ClientAuth{
					gossh.ClientAuthPassword(ssh.Password(password)),
					gossh.ClientAuthKeyboardInteractive(ssh.PasswordKeyboardInteractive(password)),
				},
			}, nil
		}
	}
}
<commit_msg>builder/null: pass SSH tests<commit_after>package null

import (
	gossh "code.google.com/p/go.crypto/ssh"
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/communicator/ssh"
	"io/ioutil"
)

// SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address
func SSHAddress(host string, port int) func(multistep.StateBag) (string, error) {
	return func(state multistep.StateBag) (string, error) {
		return fmt.Sprintf("%s:%d", host, port), nil
	}
}

// SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the specified host via SSH
// private_key_file has precedence over password!
func SSHConfig(username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
	return func(state multistep.StateBag) (*gossh.ClientConfig, error) {

		if privateKeyFile != "" {
			// key based auth

			bytes, err := ioutil.ReadFile(privateKeyFile)
			if err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}
			privateKey := string(bytes)

			signer, err := gossh.ParsePrivateKey([]byte(privateKey))
			if err != nil {
				return nil, fmt.Errorf("Error setting up SSH config: %s", err)
			}

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.AuthMethod{
					gossh.PublicKeys(signer),
				},
			}, nil
		} else {
			// password based auth

			return &gossh.ClientConfig{
				User: username,
				Auth: []gossh.AuthMethod{
					gossh.Password(password),
					gossh.KeyboardInteractive(
						ssh.PasswordKeyboardInteractive(password)),
				},
			}, nil
		}
	}
}
<|endoftext|>


<commit_before>/*
Package arrow provides C-style date formating and parsing, along with other date goodies.

See the github project page at http://github.com/bmuller/arrow for more info.
*/
package arrow

import (
	"strconv"
	"strings"
	"time"
)

type Arrow struct {
	time.Time
}

// Like time's constants, but with Day and Week
const (
	Nanosecond  time.Duration = 1
	Microsecond               = 1000 * Nanosecond
	Millisecond               = 1000 * Microsecond
	Second                    = 1000 * Millisecond
	Minute                    = 60 * Second
	Hour                      = 60 * Minute
	Day                       = 24 * Hour
	Week                      = 7 * Day
)

func New(t time.Time) Arrow {
	return Arrow{t}
}

func UTC() Arrow {
	return New(time.Now().UTC())
}

func Unix(sec int64, nsec int64) Arrow {
	return New(time.Unix(sec, nsec))
}

func Epoch() Arrow {
	return Unix(0, 0)
}

func Now() Arrow {
	return New(time.Now())
}

func Yesterday() Arrow {
	return Now().Yesterday()
}

func Tomorrow() Arrow {
	return Now().Tomorrow()
}

func NextSecond() Arrow {
	return Now().AddSeconds(1).AtBeginningOfSecond()
}

func NextMinute() Arrow {
	return Now().AddMinutes(1).AtBeginningOfMinute()
}

func NextHour() Arrow {
	return Now().AddHours(1).AtBeginningOfHour()
}

func NextDay() Arrow {
	return Now().AddDays(1).AtBeginningOfDay()
}

func SleepUntil(t Arrow) {
	time.Sleep(t.Sub(Now()))
}

// Get the current time in the given timezone.
// The timezone parameter should correspond to a file in the IANA Time Zone database,
// such as "America/New_York".  "UTC" and "Local" are also acceptable.  If the timezone
// given isn't valid, then no change to the timezone is made.
func InTimezone(timezone string) Arrow {
	return Now().InTimezone(timezone)
}

func (a Arrow) Before(b Arrow) bool {
	return a.Time.Before(b.Time)
}

func (a Arrow) After(b Arrow) bool {
	return a.Time.After(b.Time)
}

func (a Arrow) Equal(b Arrow) bool {
	return a.Time.Equal(b.Time)
}

// Return an array of Arrow's from this one up to the given one,
// by duration.  For instance, Now().UpTo(Tomorrow(), Hour)
// will return an array of Arrow's from now until tomorrow by
// hour (inclusive of a and b).
func (a Arrow) UpTo(b Arrow, by time.Duration) []Arrow {
	var result []Arrow
	if a.After(b) {
		a, b = b, a
	}
	for a.Before(b) || a.Equal(b) {
		result = append(result, a)
		a = a.Add(by)
	}
	return result
}

func (a Arrow) Yesterday() Arrow {
	return a.AddDays(-1)
}

func (a Arrow) Tomorrow() Arrow {
	return a.AddDays(1)
}

func (a Arrow) UTC() Arrow {
	return New(a.Time.UTC())
}

func (a Arrow) Sub(b Arrow) time.Duration {
	return a.Time.Sub(b.Time)
}

// Add any duration parseable by time.ParseDuration
func (a Arrow) AddDuration(duration string) Arrow {
	if pduration, err := time.ParseDuration(duration); err == nil {
		return a.Add(pduration)
	}
	return a
}

func (a Arrow) Add(d time.Duration) Arrow {
	return New(a.Time.Add(d))
}

// The timezone parameter should correspond to a file in the IANA Time Zone database,
// such as "America/New_York".  "UTC" and "Local" are also acceptable.  If the timezone
// given isn't valid, then no change to the timezone is made.
func (a Arrow) InTimezone(timezone string) Arrow {
	if location, err := time.LoadLocation(timezone); err == nil {
		return New(a.In(location))
	}
	return a
}

func (a Arrow) AddDays(days int) Arrow {
	return New(a.AddDate(0, 0, days))
}

func (a Arrow) AddHours(hours int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour+hours, min, sec, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AddMinutes(minutes int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour, min+minutes, sec, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AddSeconds(seconds int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour, min, sec+seconds, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AtBeginningOfSecond() Arrow {
	return New(a.Truncate(Second))
}

func (a Arrow) AtBeginningOfMinute() Arrow {
	return New(a.Truncate(Minute))
}

func (a Arrow) AtBeginningOfHour() Arrow {
	return New(a.Truncate(Hour))
}

func (a Arrow) AtBeginningOfDay() Arrow {
	d := time.Duration(-a.Hour()) * Hour
	return a.AtBeginningOfHour().Add(d)
}

func (a Arrow) AtBeginningOfWeek() Arrow {
	days := time.Duration(-1*int(a.Weekday())) * Day
	return a.AtBeginningOfDay().Add(days)
}

func (a Arrow) AtBeginningOfMonth() Arrow {
	days := time.Duration(-1*int(a.Day())+1) * Day
	return a.AtBeginningOfDay().Add(days)
}

func (a Arrow) AtBeginningOfYear() Arrow {
	days := time.Duration(-1*int(a.YearDay())+1) * Day
	return a.AtBeginningOfDay().Add(days)
}

// Add any durations parseable by time.ParseDuration
func (a Arrow) AddDurations(durations ...string) Arrow {
	for _, duration := range durations {
		a = a.AddDuration(duration)
	}
	return a
}

func formatConvert(format string) string {
	// create mapping from strftime to time in Go
	strftimeMapping := map[string]string{
		"%a": "Mon",
		"%A": "Monday",
		"%b": "Jan",
		"%B": "January",
		"%c": "", // locale not supported
		"%C": "06",
		"%d": "02",
		"%D": "01/02/06",
		"%e": "_2",
		"%E": "", // modifiers not supported
		"%F": "2006-01-02",
		"%G": "%G", // special case, see below
		"%g": "%g", // special case, see below
		"%h": "Jan",
		"%H": "15",
		"%I": "03",
		"%j": "%j", // special case, see below
		"%k": "%k", // special case, see below
		"%l": "_3",
		"%m": "01",
		"%M": "04",
		"%n": "\n",
		"%O": "", // modifiers not supported
		"%p": "PM",
		"%P": "pm",
		"%r": "03:04:05 PM",
		"%R": "15:04",
		"%s": "%s", // special case, see below
		"%S": "05",
		"%t": "\t",
		"%T": "15:04:05",
		"%u": "%u", // special case, see below
		"%U": "%U", // special case, see below
		"%V": "%V", // special case, see below
		"%w": "%w", // special case, see below
		"%W": "%W", // special case, see below
		"%x": "%x", // locale not supported
		"%X": "%X", // locale not supported
		"%y": "06",
		"%Y": "2006",
		"%z": "-0700",
		"%Z": "MST",
		"%+": "Mon Jan _2 15:04:05 MST 2006",
		"%%": "%%", // special case, see below
	}

	for fmt, conv := range strftimeMapping {
		format = strings.Replace(format, fmt, conv, -1)
	}

	return format
}

// Parse the time using the same format string types as strftime
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParse(layout, value string) (Arrow, error) {
	t, e := time.Parse(formatConvert(layout), value)
	return New(t), e
}

// Parse the time using the same format string types as strftime,
// within the given location.
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParseInLocation(layout, value string, loc *time.Location) (Arrow, error) {
	t, e := time.ParseInLocation(formatConvert(layout), value, loc)
	return New(t), e
}

// Parse the time using the same format string types as strftime,
// within the given location (string value for timezone).
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParseInStringLocation(layout, value, timezone string) (Arrow, error) {
	if location, err := time.LoadLocation(timezone); err == nil {
		return CParseInLocation(layout, value, location)
	} else {
		return New(time.Time{}), err
	}
}

// Format the time using the same format string types as strftime.
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func (a Arrow) CFormat(format string) string {
	format = a.Format(formatConvert(format))

	year, week := a.ISOWeek()
	yearday := a.YearDay()
	weekday := a.Weekday()
	syear := strconv.Itoa(year)
	sweek := strconv.Itoa(week)
	syearday := strconv.Itoa(yearday)
	sweekday := strconv.Itoa(int(weekday))

	if a.Year() > 999 {
		format = strings.Replace(format, "%G", syear, -1)
		format = strings.Replace(format, "%g", syear[2:4], -1)
	}

	format = strings.Replace(format, "%j", syearday, -1)
	if a.Hour() < 10 {
		shour := " " + strconv.Itoa(a.Hour())
		format = strings.Replace(format, "%k", shour, -1)
	}
	format = strings.Replace(format, "%s", strconv.FormatInt(a.Unix(), 10), -1)

	if weekday == 0 {
		format = strings.Replace(format, "%u", "7", -1)
	} else {
		format = strings.Replace(format, "%u", sweekday, -1)
	}

	format = strings.Replace(format, "%U", weekNumber(a, time.Sunday), -1)
	format = strings.Replace(format, "%U", sweek, -1)
	format = strings.Replace(format, "%w", sweekday, -1)
	format = strings.Replace(format, "%W", weekNumber(a, time.Monday), -1)
	return strings.Replace(format, "%%", "%", -1)
}

// Used for %U and %W:
// %U: The week number of the current year as a decimal number, range
// 00 to 53, starting with the first Sunday as the first day of week 01.
//
// %W: The week number of the current year as a decimal number, range
// 00 to 53, starting with the first Monday as the first day of week 01.
func weekNumber(a Arrow, firstday time.Weekday) string {
	dayone := a.AtBeginningOfYear()
	for dayone.Weekday() != time.Sunday {
		dayone = dayone.AddDays(1)
	}
	week := int(a.Sub(dayone.AddDays(-7)) / Week)
	return strconv.Itoa(week)
}
<commit_msg>added new AddMonths/Years functions<commit_after>/*
Package arrow provides C-style date formating and parsing, along with other date goodies.

See the github project page at http://github.com/bmuller/arrow for more info.
*/
package arrow

import (
	"strconv"
	"strings"
	"time"
)

type Arrow struct {
	time.Time
}

// Like time's constants, but with Day and Week
const (
	Nanosecond  time.Duration = 1
	Microsecond               = 1000 * Nanosecond
	Millisecond               = 1000 * Microsecond
	Second                    = 1000 * Millisecond
	Minute                    = 60 * Second
	Hour                      = 60 * Minute
	Day                       = 24 * Hour
	Week                      = 7 * Day
)

func New(t time.Time) Arrow {
	return Arrow{t}
}

func UTC() Arrow {
	return New(time.Now().UTC())
}

func Unix(sec int64, nsec int64) Arrow {
	return New(time.Unix(sec, nsec))
}

func Epoch() Arrow {
	return Unix(0, 0)
}

func Now() Arrow {
	return New(time.Now())
}

func Yesterday() Arrow {
	return Now().Yesterday()
}

func Tomorrow() Arrow {
	return Now().Tomorrow()
}

func NextSecond() Arrow {
	return Now().AddSeconds(1).AtBeginningOfSecond()
}

func NextMinute() Arrow {
	return Now().AddMinutes(1).AtBeginningOfMinute()
}

func NextHour() Arrow {
	return Now().AddHours(1).AtBeginningOfHour()
}

func NextDay() Arrow {
	return Now().AddDays(1).AtBeginningOfDay()
}

func SleepUntil(t Arrow) {
	time.Sleep(t.Sub(Now()))
}

// Get the current time in the given timezone.
// The timezone parameter should correspond to a file in the IANA Time Zone database,
// such as "America/New_York".  "UTC" and "Local" are also acceptable.  If the timezone
// given isn't valid, then no change to the timezone is made.
func InTimezone(timezone string) Arrow {
	return Now().InTimezone(timezone)
}

func (a Arrow) Before(b Arrow) bool {
	return a.Time.Before(b.Time)
}

func (a Arrow) After(b Arrow) bool {
	return a.Time.After(b.Time)
}

func (a Arrow) Equal(b Arrow) bool {
	return a.Time.Equal(b.Time)
}

// Return an array of Arrow's from this one up to the given one,
// by duration.  For instance, Now().UpTo(Tomorrow(), Hour)
// will return an array of Arrow's from now until tomorrow by
// hour (inclusive of a and b).
func (a Arrow) UpTo(b Arrow, by time.Duration) []Arrow {
	var result []Arrow
	if a.After(b) {
		a, b = b, a
	}
	for a.Before(b) || a.Equal(b) {
		result = append(result, a)
		a = a.Add(by)
	}
	return result
}

func (a Arrow) Yesterday() Arrow {
	return a.AddDays(-1)
}

func (a Arrow) Tomorrow() Arrow {
	return a.AddDays(1)
}

func (a Arrow) UTC() Arrow {
	return New(a.Time.UTC())
}

func (a Arrow) Sub(b Arrow) time.Duration {
	return a.Time.Sub(b.Time)
}

// Add any duration parseable by time.ParseDuration
func (a Arrow) AddDuration(duration string) Arrow {
	if pduration, err := time.ParseDuration(duration); err == nil {
		return a.Add(pduration)
	}
	return a
}

func (a Arrow) Add(d time.Duration) Arrow {
	return New(a.Time.Add(d))
}

// The timezone parameter should correspond to a file in the IANA Time Zone database,
// such as "America/New_York".  "UTC" and "Local" are also acceptable.  If the timezone
// given isn't valid, then no change to the timezone is made.
func (a Arrow) InTimezone(timezone string) Arrow {
	if location, err := time.LoadLocation(timezone); err == nil {
		return New(a.In(location))
	}
	return a
}

func (a Arrow) AddDays(days int) Arrow {
	return New(a.AddDate(0, 0, days))
}

func (a Arrow) AddMonths(months int) Arrow {
	return New(a.AddDate(0, months, 0))
}

func (a Arrow) AddYears(years int) Arrow {
	return New(a.AddDate(years, 0, 0))
}

func (a Arrow) AddHours(hours int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour+hours, min, sec, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AddMinutes(minutes int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour, min+minutes, sec, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AddSeconds(seconds int) Arrow {
	year, month, day := a.Time.Date()
	hour, min, sec := a.Time.Clock()
	d := time.Date(year, month, day, hour, min, sec+seconds, a.Nanosecond(), a.Location())
	return New(d)
}

func (a Arrow) AtBeginningOfSecond() Arrow {
	return New(a.Truncate(Second))
}

func (a Arrow) AtBeginningOfMinute() Arrow {
	return New(a.Truncate(Minute))
}

func (a Arrow) AtBeginningOfHour() Arrow {
	return New(a.Truncate(Hour))
}

func (a Arrow) AtBeginningOfDay() Arrow {
	d := time.Duration(-a.Hour()) * Hour
	return a.AtBeginningOfHour().Add(d)
}

func (a Arrow) AtBeginningOfWeek() Arrow {
	days := time.Duration(-1*int(a.Weekday())) * Day
	return a.AtBeginningOfDay().Add(days)
}

func (a Arrow) AtBeginningOfMonth() Arrow {
	days := time.Duration(-1*int(a.Day())+1) * Day
	return a.AtBeginningOfDay().Add(days)
}

func (a Arrow) AtBeginningOfYear() Arrow {
	days := time.Duration(-1*int(a.YearDay())+1) * Day
	return a.AtBeginningOfDay().Add(days)
}

// Add any durations parseable by time.ParseDuration
func (a Arrow) AddDurations(durations ...string) Arrow {
	for _, duration := range durations {
		a = a.AddDuration(duration)
	}
	return a
}

func formatConvert(format string) string {
	// create mapping from strftime to time in Go
	strftimeMapping := map[string]string{
		"%a": "Mon",
		"%A": "Monday",
		"%b": "Jan",
		"%B": "January",
		"%c": "", // locale not supported
		"%C": "06",
		"%d": "02",
		"%D": "01/02/06",
		"%e": "_2",
		"%E": "", // modifiers not supported
		"%F": "2006-01-02",
		"%G": "%G", // special case, see below
		"%g": "%g", // special case, see below
		"%h": "Jan",
		"%H": "15",
		"%I": "03",
		"%j": "%j", // special case, see below
		"%k": "%k", // special case, see below
		"%l": "_3",
		"%m": "01",
		"%M": "04",
		"%n": "\n",
		"%O": "", // modifiers not supported
		"%p": "PM",
		"%P": "pm",
		"%r": "03:04:05 PM",
		"%R": "15:04",
		"%s": "%s", // special case, see below
		"%S": "05",
		"%t": "\t",
		"%T": "15:04:05",
		"%u": "%u", // special case, see below
		"%U": "%U", // special case, see below
		"%V": "%V", // special case, see below
		"%w": "%w", // special case, see below
		"%W": "%W", // special case, see below
		"%x": "%x", // locale not supported
		"%X": "%X", // locale not supported
		"%y": "06",
		"%Y": "2006",
		"%z": "-0700",
		"%Z": "MST",
		"%+": "Mon Jan _2 15:04:05 MST 2006",
		"%%": "%%", // special case, see below
	}

	for fmt, conv := range strftimeMapping {
		format = strings.Replace(format, fmt, conv, -1)
	}

	return format
}

// Parse the time using the same format string types as strftime
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParse(layout, value string) (Arrow, error) {
	t, e := time.Parse(formatConvert(layout), value)
	return New(t), e
}

// Parse the time using the same format string types as strftime,
// within the given location.
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParseInLocation(layout, value string, loc *time.Location) (Arrow, error) {
	t, e := time.ParseInLocation(formatConvert(layout), value, loc)
	return New(t), e
}

// Parse the time using the same format string types as strftime,
// within the given location (string value for timezone).
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func CParseInStringLocation(layout, value, timezone string) (Arrow, error) {
	if location, err := time.LoadLocation(timezone); err == nil {
		return CParseInLocation(layout, value, location)
	} else {
		return New(time.Time{}), err
	}
}

// Format the time using the same format string types as strftime.
// See http://man7.org/linux/man-pages/man3/strftime.3.html for more info.
func (a Arrow) CFormat(format string) string {
	format = a.Format(formatConvert(format))

	year, week := a.ISOWeek()
	yearday := a.YearDay()
	weekday := a.Weekday()
	syear := strconv.Itoa(year)
	sweek := strconv.Itoa(week)
	syearday := strconv.Itoa(yearday)
	sweekday := strconv.Itoa(int(weekday))

	if a.Year() > 999 {
		format = strings.Replace(format, "%G", syear, -1)
		format = strings.Replace(format, "%g", syear[2:4], -1)
	}

	format = strings.Replace(format, "%j", syearday, -1)
	if a.Hour() < 10 {
		shour := " " + strconv.Itoa(a.Hour())
		format = strings.Replace(format, "%k", shour, -1)
	}
	format = strings.Replace(format, "%s", strconv.FormatInt(a.Unix(), 10), -1)

	if weekday == 0 {
		format = strings.Replace(format, "%u", "7", -1)
	} else {
		format = strings.Replace(format, "%u", sweekday, -1)
	}

	format = strings.Replace(format, "%U", weekNumber(a, time.Sunday), -1)
	format = strings.Replace(format, "%U", sweek, -1)
	format = strings.Replace(format, "%w", sweekday, -1)
	format = strings.Replace(format, "%W", weekNumber(a, time.Monday), -1)
	return strings.Replace(format, "%%", "%", -1)
}

// Used for %U and %W:
// %U: The week number of the current year as a decimal number, range
// 00 to 53, starting with the first Sunday as the first day of week 01.
//
// %W: The week number of the current year as a decimal number, range
// 00 to 53, starting with the first Monday as the first day of week 01.
func weekNumber(a Arrow, firstday time.Weekday) string {
	dayone := a.AtBeginningOfYear()
	for dayone.Weekday() != time.Sunday {
		dayone = dayone.AddDays(1)
	}
	week := int(a.Sub(dayone.AddDays(-7)) / Week)
	return strconv.Itoa(week)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"

	"github.com/codegangsta/cli"
	"github.com/hashicorp/atlas-go/v1"
)

var (
	Version string
)

func init() {
	log.SetOutput(ioutil.Discard)
}

func ToJson(obj interface{}) (interface{}, error) {
	data, err := json.Marshal(obj)
	if err != nil {
		return nil, err
	}
	return string(data), nil
}

func search(c *cli.Context) {
	searchOpts := &atlas.ArtifactSearchOpts{
		User: c.String("user"),
		Name: c.String("artifact"),
		Type: c.String("type"),
	}
	if len(c.StringSlice("meta")) > 0 {
		filter := map[string]string{}
		for _, m := range c.StringSlice("meta") {
			pair := strings.Split(m, "=")
			filter[pair[0]] = pair[1]
		}
		fmt.Printf("FILTER: %#v\n", filter)
		searchOpts.Metadata = filter
	}
	client := atlas.DefaultClient()

	versions, err := client.ArtifactSearch(searchOpts)
	if err != nil {
		fmt.Errorf("search error: %#v", err)
		os.Exit(1)
	}

	fnMap := template.FuncMap{}
	fnMap["json"] = ToJson
	tmpl, err := template.New("artifact").Funcs(fnMap).Parse(c.String("format"))
	if err != nil {
		panic(err)
	}

	for _, v := range versions {
		//fmt.Println("ver: %#v", v)
		err = tmpl.Execute(os.Stdout, v)
		if err != nil {
			panic(err)
		}
	}

}

func main() {
	fmt.Fprintln(os.Stderr, "Search atlas.hashicorp artifacts ...")

	app := cli.NewApp()
	app.Name = "atlifacts"
	app.Usage = "query atlas.hashicorp.com artifacts"
	app.Version = Version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "user, u",
			Value:  "sequenceiq",
			Usage:  "atlas user",
			EnvVar: "ATLAS_USER",
		},
		cli.StringFlag{
			Name:   "artifact, a",
			Value:  "cloudbreak",
			Usage:  "atlas artifact",
			EnvVar: "ATLAS_ARTIFACT_NAME",
		},
		cli.StringFlag{
			Name:   "type, t",
			Value:  "openstack.image",
			Usage:  "atlas artifact type",
			EnvVar: "ATLAS_ARTIFACT_TYPE",
		},
		cli.StringFlag{
			Name:  "format, f",
			Value: "{{.Slug}}\n",
			Usage: "output format in golang template",
		},
		cli.StringSliceFlag{
			Name:  "meta, m",
			Usage: "meta field as fielter",
		},
	}
	app.Action = search

	app.Run(os.Args)

}
<commit_msg>remove default values<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"

	"github.com/codegangsta/cli"
	"github.com/hashicorp/atlas-go/v1"
)

var (
	Version string
)

func init() {
	log.SetOutput(ioutil.Discard)
}

func ToJson(obj interface{}) (interface{}, error) {
	data, err := json.Marshal(obj)
	if err != nil {
		return nil, err
	}
	return string(data), nil
}

func search(c *cli.Context) {

	if c.String("user") == "" || c.String("artifact") == "" || c.String("type") == "" {
		cli.ShowAppHelp(c)
		os.Exit(1)
	}

	searchOpts := &atlas.ArtifactSearchOpts{
		User: c.String("user"),
		Name: c.String("artifact"),
		Type: c.String("type"),
	}
	if len(c.StringSlice("meta")) > 0 {
		filter := map[string]string{}
		for _, m := range c.StringSlice("meta") {
			pair := strings.Split(m, "=")
			filter[pair[0]] = pair[1]
		}
		fmt.Printf("FILTER: %#v\n", filter)
		searchOpts.Metadata = filter
	}
	client := atlas.DefaultClient()

	versions, err := client.ArtifactSearch(searchOpts)
	if err != nil {
		fmt.Errorf("search error: %#v", err)
		os.Exit(1)
	}

	fnMap := template.FuncMap{}
	fnMap["json"] = ToJson
	tmpl, err := template.New("artifact").Funcs(fnMap).Parse(c.String("format"))
	if err != nil {
		panic(err)
	}

	for _, v := range versions {
		//fmt.Println("ver: %#v", v)
		err = tmpl.Execute(os.Stdout, v)
		if err != nil {
			panic(err)
		}
	}

}

func main() {
	fmt.Fprintln(os.Stderr, "Search atlas.hashicorp artifacts ...")

	app := cli.NewApp()
	app.Name = "atlifacts"
	app.Usage = "query atlas.hashicorp.com artifacts"
	app.Version = Version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "user, u",
			Usage:  "atlas user",
			EnvVar: "ATLAS_USER",
		},
		cli.StringFlag{
			Name:   "artifact, a",
			Usage:  "atlas artifact",
			EnvVar: "ATLAS_ARTIFACT_NAME",
		},
		cli.StringFlag{
			Name:   "type, t",
			Usage:  "atlas artifact type",
			EnvVar: "ATLAS_ARTIFACT_TYPE",
		},
		cli.StringFlag{
			Name:  "format, f",
			Value: "{{.Slug}}\n",
			Usage: "output format in golang template",
		},
		cli.StringSliceFlag{
			Name:  "meta, m",
			Usage: "meta field as fielter",
		},
	}
	app.Action = search

	app.Run(os.Args)

}
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"

	"github.com/thinkofdeath/steven/audio"
	"github.com/thinkofdeath/steven/console"
	"github.com/thinkofdeath/steven/resource"
)

const (
	assetsVersion    = "1.8"
	assetIndexURL    = "https://s3.amazonaws.com/Minecraft.Download/indexes/%s.json"
	assetResourceURL = "http://resources.download.minecraft.net/%s"
)

var (
	assets       assetIndex
	loadedSounds = map[pluginKey]audio.SoundBuffer{}
	soundList    []audio.Sound
)

type assetIndex struct {
	Objects map[string]struct {
		Hash string `json:"hash"`
		Size int    `json:"size"`
	} `json:"objects"`
}

func PlaySound(plugin, name string) {
	key := pluginKey{plugin, name}
	sb, ok := loadedSounds[key]
	if !ok {
		f, err := resource.Open(plugin, "sounds/"+name+".ogg")
		if err != nil {
			v, ok := assets.Objects[fmt.Sprintf("%s/sounds/%s.ogg", plugin, name)]
			if !ok {
				console.Text("Missing sound %s", key)
				return
			}
			loc := fmt.Sprintf("./resources/%s", hashPath(v.Hash))
			f, err = os.Open(loc)
			if err != nil {
				console.Text("Missing sound %s", key)
				return
			}
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			panic(err)
		}
		sb = audio.NewSoundBufferData(data)
		loadedSounds[key] = sb
	}
	for _, s := range soundList {
		if s.Status() == audio.StatStopped {
			s.SetBuffer(sb)
			s.SetVolume(100.0)
			s.Play()
			return
		}
	}
	s := audio.NewSound()
	s.SetBuffer(sb)
	s.Play()
	s.SetVolume(100.0)
	soundList = append(soundList, s)
}

func init() {
	defLocation := "./resources"
	loc := fmt.Sprintf("%s/%s.index", defLocation, assetsVersion)
	_, err := os.Stat(loc)
	if os.IsNotExist(err) {
		getAssetIndex()
	} else {
		f, err := os.Open(fmt.Sprintf("./resources/%s.index", assetsVersion))
		if err != nil {
			panic(err)
		}
		defer f.Close()
		err = json.NewDecoder(f).Decode(&assets)
		if err != nil {
			panic(err)
		}
	}
	go downloadAssets()
}

func getAssetIndex() {
	defLocation := "./resources"
	resp, err := http.Get(fmt.Sprintf(assetIndexURL, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	if err := json.NewDecoder(resp.Body).Decode(&assets); err != nil {
		panic(err)
	}
	os.MkdirAll("./resources", 0777)
	f, err := os.Create(fmt.Sprintf("%s/%s.index", defLocation, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer f.Close()
	json.NewEncoder(f).Encode(assets)
}

func downloadAssets() {
	defLocation := "./resources"
	for _, v := range assets.Objects {
		path := hashPath(v.Hash)
		loc := fmt.Sprintf("%s/%s", defLocation, path)
		_, err := os.Stat(loc)
		if !os.IsNotExist(err) {
			continue
		}
		func() {
			resp, err := http.Get(fmt.Sprintf(assetResourceURL, path))
			if err != nil {
				panic(err)
			}
			defer resp.Body.Close()
			os.MkdirAll(filepath.Dir(loc), 0777)
			f, err := os.Create(loc + ".tmp")
			if err != nil {
				panic(err)
			}
			defer f.Close()
			n, err := io.Copy(f, resp.Body)
			if err != nil {
				panic(err)
			}
			if n != int64(v.Size) {
				panic(fmt.Sprintf("Got: %d, Wanted: %d for %s", n, v.Size, fmt.Sprintf(assetResourceURL, path)))
			}
			console.Text("Downloaded: %s", loc)
		}()
		os.Rename(loc+".tmp", loc)
	}
}
func hashPath(hash string) string {
	return hash[:2] + "/" + hash
}
<commit_msg>steven: add some logging to getting the asset index<commit_after>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"

	"github.com/thinkofdeath/steven/audio"
	"github.com/thinkofdeath/steven/console"
	"github.com/thinkofdeath/steven/resource"
)

const (
	assetsVersion    = "1.8"
	assetIndexURL    = "https://s3.amazonaws.com/Minecraft.Download/indexes/%s.json"
	assetResourceURL = "http://resources.download.minecraft.net/%s"
)

var (
	assets       assetIndex
	loadedSounds = map[pluginKey]audio.SoundBuffer{}
	soundList    []audio.Sound
)

type assetIndex struct {
	Objects map[string]struct {
		Hash string `json:"hash"`
		Size int    `json:"size"`
	} `json:"objects"`
}

func PlaySound(plugin, name string) {
	key := pluginKey{plugin, name}
	sb, ok := loadedSounds[key]
	if !ok {
		f, err := resource.Open(plugin, "sounds/"+name+".ogg")
		if err != nil {
			v, ok := assets.Objects[fmt.Sprintf("%s/sounds/%s.ogg", plugin, name)]
			if !ok {
				console.Text("Missing sound %s", key)
				return
			}
			loc := fmt.Sprintf("./resources/%s", hashPath(v.Hash))
			f, err = os.Open(loc)
			if err != nil {
				console.Text("Missing sound %s", key)
				return
			}
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			panic(err)
		}
		sb = audio.NewSoundBufferData(data)
		loadedSounds[key] = sb
	}
	for _, s := range soundList {
		if s.Status() == audio.StatStopped {
			s.SetBuffer(sb)
			s.SetVolume(100.0)
			s.Play()
			return
		}
	}
	s := audio.NewSound()
	s.SetBuffer(sb)
	s.Play()
	s.SetVolume(100.0)
	soundList = append(soundList, s)
}

func init() {
	defLocation := "./resources"
	loc := fmt.Sprintf("%s/%s.index", defLocation, assetsVersion)
	_, err := os.Stat(loc)
	if os.IsNotExist(err) {
		getAssetIndex()
	} else {
		f, err := os.Open(fmt.Sprintf("./resources/%s.index", assetsVersion))
		if err != nil {
			panic(err)
		}
		defer f.Close()
		err = json.NewDecoder(f).Decode(&assets)
		if err != nil {
			panic(err)
		}
	}
	go downloadAssets()
}

func getAssetIndex() {
	console.Text("Getting asset index")
	defLocation := "./resources"
	resp, err := http.Get(fmt.Sprintf(assetIndexURL, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	if err := json.NewDecoder(resp.Body).Decode(&assets); err != nil {
		panic(err)
	}
	os.MkdirAll("./resources", 0777)
	f, err := os.Create(fmt.Sprintf("%s/%s.index", defLocation, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer f.Close()
	json.NewEncoder(f).Encode(assets)
	console.Text("Got asset index for %s", assetsVersion)
}

func downloadAssets() {
	defLocation := "./resources"
	for _, v := range assets.Objects {
		path := hashPath(v.Hash)
		loc := fmt.Sprintf("%s/%s", defLocation, path)
		_, err := os.Stat(loc)
		if !os.IsNotExist(err) {
			continue
		}
		func() {
			resp, err := http.Get(fmt.Sprintf(assetResourceURL, path))
			if err != nil {
				panic(err)
			}
			defer resp.Body.Close()
			os.MkdirAll(filepath.Dir(loc), 0777)
			f, err := os.Create(loc + ".tmp")
			if err != nil {
				panic(err)
			}
			defer f.Close()
			n, err := io.Copy(f, resp.Body)
			if err != nil {
				panic(err)
			}
			if n != int64(v.Size) {
				panic(fmt.Sprintf("Got: %d, Wanted: %d for %s", n, v.Size, fmt.Sprintf(assetResourceURL, path)))
			}
			console.Text("Downloaded: %s", loc)
		}()
		os.Rename(loc+".tmp", loc)
	}
}
func hashPath(hash string) string {
	return hash[:2] + "/" + hash
}
<|endoftext|>


<commit_before>package basex
//basex is an go implementation to generate alpha id (alpha numeric id) for big integers.
//This will be very helpful to shorten the URL
import (
	"math/big"
	"strconv"
)

var vDICTIONARY_16 []char
var vDICTIONARY_32 []char
var vDICTIONARY_62 []char
var vDICTIONARY_89 []char
var dictionary []char

func intit() {
	vDICTIONARY_16 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
	vDICTIONARY_32 = []char{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
	vDICTIONARY_62 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
	vDICTIONARY_89 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '+', '"', '@', '*', '#', '%', '&', '/', '|', '(', ')', '=', '?', '~', '[', ']', '{', '}', '$', '-', '_', '.', ':', ',', ';', '<', '>'}
	dictionary = vDICTIONARY_62
}

//These lines are mandatory to use the char in golang
type char byte
func (c char)String()string{
  return string(c)
}

//Converts the big integer to alpha id(An alpha numeric id with mixed cases)
func Encode(val string) string{
	//Initialize dictionary
	intit()
	var result []char
	var index int
	var strVal string

	base := big.NewInt(int64(len(dictionary)))
	a := big.NewInt(0)
	b := big.NewInt(0)
	c := big.NewInt(0)
	d := big.NewInt(0)

	exponent := 1

	remaining := big.NewInt(0)
	remaining.SetString(val, 10)

	for remaining.Cmp(big.NewInt(0)) != 0 {

		a.Exp(base, big.NewInt(int64(exponent)), nil) //16^1 = 16
		b := b.Mod(remaining, a)   //119 % 16 = 7 | 112 % 256 = 112
		c := c.Exp(base, big.NewInt(int64(exponent - 1)), nil)
		d := d.Div(b, c)

		//if d > dictionary.length, we have a problem. but BigInteger doesnt have
		//a greater than method :-(  hope for the best. theoretically, d is always
		//an index of the dictionary!
		strVal = d.String()
		index,_ = strconv.Atoi(strVal)
		result = append(result, dictionary[index])
		remaining = remaining.Sub(remaining, b) //119 - 7 = 112 | 112 - 112 = 0
		exponent = exponent + 1
	}

	//need to reverse it, since the start of the list contains the least significant values
	 return reverse(stringVal(result))
}

//Converts the alpha id to big integer
func Decode(s string) string {
	//Initialize dictionary
	intit()
    //reverse it, coz its already reversed!
    chars2 := sliceVal(reverse(s))

    //for efficiency, make a map
    var dictMap map[char]*big.Int
	dictMap = make(map[char]*big.Int)

    j := 0
    for _,val := range dictionary {
    	dictMap[val] = big.NewInt(int64(j))
    	j = j+1
    }

    bi := big.NewInt(0)
	base := big.NewInt(int64(len(dictionary)))

    exponent := 0;
	a := big.NewInt(0)
	b := big.NewInt(0)
	intermed := big.NewInt(0)

    for _,c := range chars2 {
      a = dictMap[c]
      intermed = intermed.Exp(base, big.NewInt(int64(exponent)), nil)
      b = b.Mul(intermed, a)
      bi = bi.Add(bi, b)
      exponent = exponent+1
    }
    return bi.String()
}

func stringVal(s []char) string {
	var str string
	for _,val := range s {
		str = str + string(val)
	}

	return str
}

func sliceVal(s string) []char {
	var ch char
	var p []char // == nil
	for i := 0; i < len(s); i++ {
		ch = char([]rune(s)[i])
            p = append(p, ch)
        }
    return p
}

func reverse(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}
<commit_msg>Updated intit to initialize for better naming convention<commit_after>package basex
//basex is an go implementation to generate alpha id (alpha numeric id) for big integers.
//This will be very helpful to shorten the URL
import (
	"math/big"
	"strconv"
)

var vDICTIONARY_16 []char
var vDICTIONARY_32 []char
var vDICTIONARY_62 []char
var vDICTIONARY_89 []char
var dictionary []char

func initialize() {
	vDICTIONARY_16 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
	vDICTIONARY_32 = []char{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
	vDICTIONARY_62 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
	vDICTIONARY_89 = []char{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '+', '"', '@', '*', '#', '%', '&', '/', '|', '(', ')', '=', '?', '~', '[', ']', '{', '}', '$', '-', '_', '.', ':', ',', ';', '<', '>'}
	dictionary = vDICTIONARY_62
}

//These lines are mandatory to use the char in golang
type char byte
func (c char)String()string{
  return string(c)
}

//Converts the big integer to alpha id(An alpha numeric id with mixed cases)
func Encode(val string) string{
	//Initialize dictionary
	initialize()
	var result []char
	var index int
	var strVal string

	base := big.NewInt(int64(len(dictionary)))
	a := big.NewInt(0)
	b := big.NewInt(0)
	c := big.NewInt(0)
	d := big.NewInt(0)

	exponent := 1

	remaining := big.NewInt(0)
	remaining.SetString(val, 10)

	for remaining.Cmp(big.NewInt(0)) != 0 {

		a.Exp(base, big.NewInt(int64(exponent)), nil) //16^1 = 16
		b := b.Mod(remaining, a)   //119 % 16 = 7 | 112 % 256 = 112
		c := c.Exp(base, big.NewInt(int64(exponent - 1)), nil)
		d := d.Div(b, c)

		//if d > dictionary.length, we have a problem. but BigInteger doesnt have
		//a greater than method :-(  hope for the best. theoretically, d is always
		//an index of the dictionary!
		strVal = d.String()
		index,_ = strconv.Atoi(strVal)
		result = append(result, dictionary[index])
		remaining = remaining.Sub(remaining, b) //119 - 7 = 112 | 112 - 112 = 0
		exponent = exponent + 1
	}

	//need to reverse it, since the start of the list contains the least significant values
	 return reverse(stringVal(result))
}

//Converts the alpha id to big integer
func Decode(s string) string {
	//Initialize dictionary
	initialize()
    //reverse it, coz its already reversed!
    chars2 := sliceVal(reverse(s))

    //for efficiency, make a map
    var dictMap map[char]*big.Int
	dictMap = make(map[char]*big.Int)

    j := 0
    for _,val := range dictionary {
    	dictMap[val] = big.NewInt(int64(j))
    	j = j+1
    }

    bi := big.NewInt(0)
	base := big.NewInt(int64(len(dictionary)))

    exponent := 0;
	a := big.NewInt(0)
	b := big.NewInt(0)
	intermed := big.NewInt(0)

    for _,c := range chars2 {
      a = dictMap[c]
      intermed = intermed.Exp(base, big.NewInt(int64(exponent)), nil)
      b = b.Mul(intermed, a)
      bi = bi.Add(bi, b)
      exponent = exponent+1
    }
    return bi.String()
}

func stringVal(s []char) string {
	var str string
	for _,val := range s {
		str = str + string(val)
	}

	return str
}

func sliceVal(s string) []char {
	var ch char
	var p []char // == nil
	for i := 0; i < len(s); i++ {
		ch = char([]rune(s)[i])
            p = append(p, ch)
        }
    return p
}

func reverse(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}
<|endoftext|>


<commit_before>// Copyright 2015-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// bb converts standalone u-root tools to shell builtins.
// It copies and converts a set of u-root utilities into a directory called bbsh.
// It assumes nothing; all files it needs are always copied, no matter what
// is in bbsh.
// bb needs to know where the uroot you are using is so it can find command source.
// UROOT=/home/rminnich/projects/u-root/u-root/
// bb needs to know the arch:
// GOARCH=amd64
// bb needs to know where the tools are, and they are in two places, the place it created them
// and the place where packages live:
// GOPATH=/home/rminnich/projects/u-root/u-root/bb/bbsh:/home/rminnich/projects/u-root/u-root
// bb needs to have a GOROOT
// GOROOT=/home/rminnich/projects/u-root/go1.5/go/
// There are no defaults.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"reflect"
	"text/template"

	"golang.org/x/tools/imports"
)

const (
	cmdFunc = `package main
import "github.com/u-root/u-root/bb/bbsh/cmds/{{.CmdName}}"
func _forkbuiltin_{{.CmdName}}(c *Command) (err error) {
os.Args = fixArgs("{{.CmdName}}", append([]string{c.cmd}, c.argv...))
{{.CmdName}}.Main()
return
}

func {{.CmdName}}Init() {
	addForkBuiltIn("{{.CmdName}}", _forkbuiltin_{{.CmdName}})
	{{.Init}}
}
`
	fixArgs = `
package main

func fixArgs(cmd string, args[]string) (s []string) {
	for _, v := range args {
		if v[0] == '-' {
			v = "-" + cmd + "." + v[1:]
		}
		s = append(s, v)
	}
	return
}
`
	initGo = `
package main
import (
	"flag"
	"fmt"
	"log"
	"os"
	"path"
	"strings"

	"github.com/u-root/u-root/uroot"
)

func usage () {
	n := path.Base(os.Args[0])
	fmt.Fprintf(os.Stderr, "Usage: %s:\n", n)
	flag.VisitAll(func(f *flag.Flag) {
		if ! strings.HasPrefix(f.Name, n+".") {
			return
		}
		fmt.Fprintf(os.Stderr, "\tFlag %s: '%s', Default %v, Value %v\n", f.Name[len(n)+1:], f.Usage, f.Value, f.DefValue)
	})
}

func init() {
	flag.Usage = usage
	// This getpid adds a bit of cost to each invocation (not much really)
	// but it allows us to merge init and sh. The 600K we save is worth it.
	// Figure out which init to run. We must always do this.

	log.Printf("init: os is %v, initMap %v", path.Base(os.Args[0]), initMap)
	// we use path.Base in case they type something like ./cmd
	if f, ok := initMap[path.Base(os.Args[0])]; ok {
		log.Printf("run the Init function for %v: run %v", os.Args[0], f)
		f()
	}

	if os.Args[0] != "/init" {
		log.Printf("Skipping root file system setup since we are not /init")
		return
	}
	if os.Getpid() != 1 {
		log.Printf("Skipping root file system setup since /init is not pid 1")
		return
	}
	uroot.Rootfs()

	for n := range forkBuiltins {
		t := path.Join("/ubin", n)
		if err := os.Symlink("/init", t); err != nil {
			log.Printf("Symlink /init to %v: %v", t, err)
		}
	}
	return
}
`
)

func debugPrint(f string, s ...interface{}) {
	log.Printf(f, s...)
}

func nodebugPrint(f string, s ...interface{}) {
}

const cmds = "cmds"

var (
	debug      = nodebugPrint
	defaultCmd = []string{
		"cat",
		"cmp",
		"comm",
		"cp",
		"date",
		"dd",
		"dmesg",
		"echo",
		"freq",
		"grep",
		"ip",
		"kexec",
		"ls",
		"mkdir",
		"mount",
		"netcat",
		"ping",
		"printenv",
		"rm",
		"seq",
		"srvfiles",
		"tcz",
		"uname",
		"uniq",
		"unshare",
		"wc",
		"wget",
	}

	// fixFlag tells by existence if an argument needs to be fixed.
	// The value tells which argument.
	fixFlag = map[string]int{
		"Bool":        0,
		"BoolVar":     1,
		"Duration":    0,
		"DurationVar": 1,
		"Float64":     0,
		"Float64Var":  1,
		"Int":         0,
		"Int64":       0,
		"Int64Var":    1,
		"IntVar":      1,
		"String":      0,
		"StringVar":   1,
		"Uint":        0,
		"Uint64":      0,
		"Uint64Var":   1,
		"UintVar":     1,
		"Var":         1,
	}
	dumpAST = flag.Bool("D", false, "Dump the AST")
	initMap = "package main\nvar initMap = map[string] func() {\n"
)

var config struct {
	Args     []string
	CmdName  string
	FullPath string
	Init string
	Src      string
	Uroot    string
	Cwd      string
	Bbsh     string

	Goroot    string
	Gosrcroot string
	Arch      string
	Goos      string
	Gopath    string
	TempDir   string
	Go        string
	Debug     bool
	Fail      bool
}

func oneFile(dir, s string, fset *token.FileSet, f *ast.File) error {
	// Inspect the AST and change all instances of main()
	isMain := false
	// yeah, this is awful, sorry.
	config.Init = ""
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.File:
			x.Name.Name = config.CmdName
		case *ast.FuncDecl:
			if x.Name.Name == "main" {
				x.Name.Name = fmt.Sprintf("Main")
				// Append a return.
				x.Body.List = append(x.Body.List, &ast.ReturnStmt{})
				isMain = true
			}
			if x.Name.Name == "init" {
				x.Name.Name = fmt.Sprintf("Init")
				config.Init = config.CmdName + ".Init()"
			}

		case *ast.CallExpr:
			debug("%v %v\n", reflect.TypeOf(n), n)
			switch z := x.Fun.(type) {
			case *ast.SelectorExpr:
				// somebody tell me how to do this.
				sel := fmt.Sprintf("%v", z.X)
				// TODO: Need to have fixFlag and fixFlagVar
				// as the Var variation has name in the SECOND argument.
				if sel == "flag" {
					if ix, ok := fixFlag[z.Sel.Name]; ok {
						switch zz := x.Args[ix].(type) {
						case *ast.BasicLit:
							zz.Value = "\"" + config.CmdName + "." + zz.Value[1:]
						}
					}
				}
			}
		}
		return true
	})

	if *dumpAST {
		ast.Fprint(os.Stderr, fset, f, nil)
	}
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, f); err != nil {
		panic(err)
	}
	debug("%s", buf.Bytes())
	out := string(buf.Bytes())

	// fix up any imports. We may have forced the issue
	// with os.Args
	opts := imports.Options{
		Fragment:  true,
		AllErrors: true,
		Comments:  true,
		TabIndent: true,
		TabWidth:  8,
	}
	fullCode, err := imports.Process("commandline", []byte(out), &opts)
	if err != nil {
		log.Fatalf("bad parse: '%v': %v", out, err)
	}

	of := path.Join(dir, path.Base(s))
	if err := ioutil.WriteFile(of, []byte(fullCode), 0666); err != nil {
		log.Fatalf("%v\n", err)
	}

	// fun: must write the file first so the import fixup works :-)
	if isMain {
		// Write the file to interface to the command package.
		t := template.Must(template.New("cmdFunc").Parse(cmdFunc))
		var b bytes.Buffer
		if err := t.Execute(&b, config); err != nil {
			log.Fatalf("spec %v: %v\n", cmdFunc, err)
		}
		fullCode, err := imports.Process("commandline", []byte(b.Bytes()), &opts)
		if err != nil {
			log.Fatalf("bad parse: '%v': %v", out, err)
		}
		if err := ioutil.WriteFile(path.Join(config.Bbsh, "cmd_"+config.CmdName+".go"), fullCode, 0444); err != nil {
			log.Fatalf("%v\n", err)
		}
	}

	return nil
}

func oneCmd() {
	// Create the directory for the package.
	// For now, ./cmds/<package name>
	packageDir := path.Join(config.Bbsh, "cmds", config.CmdName)
	if err := os.MkdirAll(packageDir, 0755); err != nil {
		log.Fatalf("Can't create target directory: %v", err)
	}

	fset := token.NewFileSet()
	config.FullPath = path.Join(config.Uroot, cmds, config.CmdName)
	p, err := parser.ParseDir(fset, config.FullPath, nil, 0)
	if err != nil {
		panic(err)
	}

	for _, f := range p {
		for n, v := range f.Files {
			oneFile(packageDir, n, fset, v)
		}
	}
	initMap += "\n\t\"" + config.CmdName + "\":" + config.CmdName + "Init,"
}
func main() {
	var err error
	doConfig()

	if err := os.MkdirAll(config.Bbsh, 0755); err != nil {
		log.Fatalf("%v", err)
	}

	if len(flag.Args()) > 0 {
		config.Args = []string{}
		for _, v := range flag.Args() {
			v = path.Join(config.Uroot, "cmds", v)
			g, err := filepath.Glob(v)
			if err != nil {
				log.Fatalf("Glob error: %v", err)
			}

			for i := range g {
				g[i] = path.Base(g[i])
			}
			config.Args = append(config.Args, g...)
		}
	}

	for _, v := range config.Args {
		// Yes, gross. Fix me.
		config.CmdName = v
		oneCmd()
	}

	if err := ioutil.WriteFile(path.Join(config.Bbsh, "init.go"), []byte(initGo), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}
	// copy all shell files

	err = filepath.Walk(path.Join(config.Uroot, cmds, "rush"), func(name string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if fi.IsDir() {
			return nil
		}
		b, err := ioutil.ReadFile(name)
		if err != nil {
			return err
		}
		if err := ioutil.WriteFile(path.Join(config.Bbsh, fi.Name()), b, 0644); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		log.Fatalf("%v", err)
	}

	if err := ioutil.WriteFile(path.Join(config.Bbsh, "fixargs.go"), []byte(fixArgs), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}

	initMap += "\n}"
	if err := ioutil.WriteFile(path.Join(config.Bbsh, "initmap.go"), []byte(initMap), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}

	buildinit()
	ramfs()
}
<commit_msg>Fixed so as to iterate over initMap (instead of forkBuiltin) while initializing.<commit_after>// Copyright 2015-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// bb converts standalone u-root tools to shell builtins.
// It copies and converts a set of u-root utilities into a directory called bbsh.
// It assumes nothing; all files it needs are always copied, no matter what
// is in bbsh.
// bb needs to know where the uroot you are using is so it can find command source.
// UROOT=/home/rminnich/projects/u-root/u-root/
// bb needs to know the arch:
// GOARCH=amd64
// bb needs to know where the tools are, and they are in two places, the place it created them
// and the place where packages live:
// GOPATH=/home/rminnich/projects/u-root/u-root/bb/bbsh:/home/rminnich/projects/u-root/u-root
// bb needs to have a GOROOT
// GOROOT=/home/rminnich/projects/u-root/go1.5/go/
// There are no defaults.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"reflect"
	"text/template"

	"golang.org/x/tools/imports"
)

const (
	cmdFunc = `package main
import "github.com/u-root/u-root/bb/bbsh/cmds/{{.CmdName}}"
func _forkbuiltin_{{.CmdName}}(c *Command) (err error) {
os.Args = fixArgs("{{.CmdName}}", append([]string{c.cmd}, c.argv...))
{{.CmdName}}.Main()
return
}

func {{.CmdName}}Init() {
	addForkBuiltIn("{{.CmdName}}", _forkbuiltin_{{.CmdName}})
	{{.Init}}
}
`
	fixArgs = `
package main

func fixArgs(cmd string, args[]string) (s []string) {
	for _, v := range args {
		if v[0] == '-' {
			v = "-" + cmd + "." + v[1:]
		}
		s = append(s, v)
	}
	return
}
`
	initGo = `
package main
import (
	"flag"
	"fmt"
	"log"
	"os"
	"path"
	"strings"

	"github.com/u-root/u-root/uroot"
)

func usage () {
	n := path.Base(os.Args[0])
	fmt.Fprintf(os.Stderr, "Usage: %s:\n", n)
	flag.VisitAll(func(f *flag.Flag) {
		if ! strings.HasPrefix(f.Name, n+".") {
			return
		}
		fmt.Fprintf(os.Stderr, "\tFlag %s: '%s', Default %v, Value %v\n", f.Name[len(n)+1:], f.Usage, f.Value, f.DefValue)
	})
}

func init() {
	flag.Usage = usage
	// This getpid adds a bit of cost to each invocation (not much really)
	// but it allows us to merge init and sh. The 600K we save is worth it.
	// Figure out which init to run. We must always do this.

	log.Printf("init: os is %v, initMap %v", path.Base(os.Args[0]), initMap)
	// we use path.Base in case they type something like ./cmd
	if f, ok := initMap[path.Base(os.Args[0])]; ok {
		log.Printf("run the Init function for %v: run %v", os.Args[0], f)
		f()
	}

	if os.Args[0] != "/init" {
		log.Printf("Skipping root file system setup since we are not /init")
		return
	}
	if os.Getpid() != 1 {
		log.Printf("Skipping root file system setup since /init is not pid 1")
		return
	}
	uroot.Rootfs()

	for n := range initMap {
		t := path.Join("/ubin", n)
		if err := os.Symlink("/init", t); err != nil {
			log.Printf("Symlink /init to %v: %v", t, err)
		}
	}
	return
}
`
)

func debugPrint(f string, s ...interface{}) {
	log.Printf(f, s...)
}

func nodebugPrint(f string, s ...interface{}) {
}

const cmds = "cmds"

var (
	debug      = nodebugPrint
	defaultCmd = []string{
		"cat",
		"cmp",
		"comm",
		"cp",
		"date",
		"dd",
		"dmesg",
		"echo",
		"freq",
		"grep",
		"ip",
		"kexec",
		"ls",
		"mkdir",
		"mount",
		"netcat",
		"ping",
		"printenv",
		"rm",
		"seq",
		"srvfiles",
		"tcz",
		"uname",
		"uniq",
		"unshare",
		"wc",
		"wget",
	}

	// fixFlag tells by existence if an argument needs to be fixed.
	// The value tells which argument.
	fixFlag = map[string]int{
		"Bool":        0,
		"BoolVar":     1,
		"Duration":    0,
		"DurationVar": 1,
		"Float64":     0,
		"Float64Var":  1,
		"Int":         0,
		"Int64":       0,
		"Int64Var":    1,
		"IntVar":      1,
		"String":      0,
		"StringVar":   1,
		"Uint":        0,
		"Uint64":      0,
		"Uint64Var":   1,
		"UintVar":     1,
		"Var":         1,
	}
	dumpAST = flag.Bool("D", false, "Dump the AST")
	initMap = "package main\nvar initMap = map[string] func() {\n"
)

var config struct {
	Args     []string
	CmdName  string
	FullPath string
	Init     string
	Src      string
	Uroot    string
	Cwd      string
	Bbsh     string

	Goroot    string
	Gosrcroot string
	Arch      string
	Goos      string
	Gopath    string
	TempDir   string
	Go        string
	Debug     bool
	Fail      bool
}

func oneFile(dir, s string, fset *token.FileSet, f *ast.File) error {
	// Inspect the AST and change all instances of main()
	isMain := false
	// yeah, this is awful, sorry.
	config.Init = ""
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.File:
			x.Name.Name = config.CmdName
		case *ast.FuncDecl:
			if x.Name.Name == "main" {
				x.Name.Name = fmt.Sprintf("Main")
				// Append a return.
				x.Body.List = append(x.Body.List, &ast.ReturnStmt{})
				isMain = true
			}
			if x.Name.Name == "init" {
				x.Name.Name = fmt.Sprintf("Init")
				config.Init = config.CmdName + ".Init()"
			}

		case *ast.CallExpr:
			debug("%v %v\n", reflect.TypeOf(n), n)
			switch z := x.Fun.(type) {
			case *ast.SelectorExpr:
				// somebody tell me how to do this.
				sel := fmt.Sprintf("%v", z.X)
				// TODO: Need to have fixFlag and fixFlagVar
				// as the Var variation has name in the SECOND argument.
				if sel == "flag" {
					if ix, ok := fixFlag[z.Sel.Name]; ok {
						switch zz := x.Args[ix].(type) {
						case *ast.BasicLit:
							zz.Value = "\"" + config.CmdName + "." + zz.Value[1:]
						}
					}
				}
			}
		}
		return true
	})

	if *dumpAST {
		ast.Fprint(os.Stderr, fset, f, nil)
	}
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, f); err != nil {
		panic(err)
	}
	debug("%s", buf.Bytes())
	out := string(buf.Bytes())

	// fix up any imports. We may have forced the issue
	// with os.Args
	opts := imports.Options{
		Fragment:  true,
		AllErrors: true,
		Comments:  true,
		TabIndent: true,
		TabWidth:  8,
	}
	fullCode, err := imports.Process("commandline", []byte(out), &opts)
	if err != nil {
		log.Fatalf("bad parse: '%v': %v", out, err)
	}

	of := path.Join(dir, path.Base(s))
	if err := ioutil.WriteFile(of, []byte(fullCode), 0666); err != nil {
		log.Fatalf("%v\n", err)
	}

	// fun: must write the file first so the import fixup works :-)
	if isMain {
		// Write the file to interface to the command package.
		t := template.Must(template.New("cmdFunc").Parse(cmdFunc))
		var b bytes.Buffer
		if err := t.Execute(&b, config); err != nil {
			log.Fatalf("spec %v: %v\n", cmdFunc, err)
		}
		fullCode, err := imports.Process("commandline", []byte(b.Bytes()), &opts)
		if err != nil {
			log.Fatalf("bad parse: '%v': %v", out, err)
		}
		if err := ioutil.WriteFile(path.Join(config.Bbsh, "cmd_"+config.CmdName+".go"), fullCode, 0444); err != nil {
			log.Fatalf("%v\n", err)
		}
	}

	return nil
}

func oneCmd() {
	// Create the directory for the package.
	// For now, ./cmds/<package name>
	packageDir := path.Join(config.Bbsh, "cmds", config.CmdName)
	if err := os.MkdirAll(packageDir, 0755); err != nil {
		log.Fatalf("Can't create target directory: %v", err)
	}

	fset := token.NewFileSet()
	config.FullPath = path.Join(config.Uroot, cmds, config.CmdName)
	p, err := parser.ParseDir(fset, config.FullPath, nil, 0)
	if err != nil {
		panic(err)
	}

	for _, f := range p {
		for n, v := range f.Files {
			oneFile(packageDir, n, fset, v)
		}
	}
	initMap += "\n\t\"" + config.CmdName + "\":" + config.CmdName + "Init,"
}
func main() {
	var err error
	doConfig()

	if err := os.MkdirAll(config.Bbsh, 0755); err != nil {
		log.Fatalf("%v", err)
	}

	if len(flag.Args()) > 0 {
		config.Args = []string{}
		for _, v := range flag.Args() {
			v = path.Join(config.Uroot, "cmds", v)
			g, err := filepath.Glob(v)
			if err != nil {
				log.Fatalf("Glob error: %v", err)
			}

			for i := range g {
				g[i] = path.Base(g[i])
			}
			config.Args = append(config.Args, g...)
		}
	}

	for _, v := range config.Args {
		// Yes, gross. Fix me.
		config.CmdName = v
		oneCmd()
	}

	if err := ioutil.WriteFile(path.Join(config.Bbsh, "init.go"), []byte(initGo), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}
	// copy all shell files

	err = filepath.Walk(path.Join(config.Uroot, cmds, "rush"), func(name string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if fi.IsDir() {
			return nil
		}
		b, err := ioutil.ReadFile(name)
		if err != nil {
			return err
		}
		if err := ioutil.WriteFile(path.Join(config.Bbsh, fi.Name()), b, 0644); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		log.Fatalf("%v", err)
	}

	if err := ioutil.WriteFile(path.Join(config.Bbsh, "fixargs.go"), []byte(fixArgs), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}

	initMap += "\n}"
	if err := ioutil.WriteFile(path.Join(config.Bbsh, "initmap.go"), []byte(initMap), 0644); err != nil {
		log.Fatalf("%v\n", err)
	}

	buildinit()
	ramfs()
}
<|endoftext|>


<commit_before><commit_msg>Extract estimateCapacity function<commit_after><|endoftext|>


<commit_before><commit_msg>uid: make sure USERSIG and ESCROWSIG are not set<commit_after><|endoftext|>


<commit_before>package dbus

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
)

// Variant represents the D-Bus variant type.
type Variant struct {
	sig   Signature
	value interface{}
}

// MakeVariant converts the given value to a Variant. It panics if v cannot be
// represented as a D-Bus type.
func MakeVariant(v interface{}) Variant {
	return Variant{SignatureOf(v), v}
}

// ParseVariant parses the given string as a variant as described at
// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not
// empty, it is taken to be the expected signature for the variant.
func ParseVariant(s string, sig Signature) (Variant, error) {
	tokens := varLex(s)
	p := &varParser{tokens: tokens}
	n, err := varMakeNode(p)
	if err != nil {
		return Variant{}, err
	}
	if sig.str == "" {
		sig, err = varInfer(n)
		if err != nil {
			return Variant{}, err
		}
	}
	v, err := n.Value(sig)
	if err != nil {
		return Variant{}, err
	}
	return MakeVariant(v), nil
}

// format returns a formatted version of v and whether this string can be parsed
// unambigously.
func (v Variant) format() (string, bool) {
	switch v.sig.str[0] {
	case 'b', 'i':
		return fmt.Sprint(v.value), true
	case 'n', 'q', 'u', 'x', 't', 'd', 'h':
		return fmt.Sprint(v.value), false
	case 's':
		return strconv.Quote(v.value.(string)), true
	case 'o':
		return strconv.Quote(string(v.value.(ObjectPath))), false
	case 'g':
		return strconv.Quote(v.value.(Signature).str), false
	case 'v':
		s, unamb := v.value.(Variant).format()
		if !unamb {
			return "<@" + v.value.(Variant).sig.str + " " + s + ">", true
		}
		return "<" + s + ">", true
	case 'y':
		return fmt.Sprintf("%#x", v.value.(byte)), false
	}
	rv := reflect.ValueOf(v.value)
	switch rv.Kind() {
	case reflect.Slice:
		if rv.Len() == 0 {
			return "[]", false
		}
		unamb := true
		buf := bytes.NewBuffer([]byte("["))
		for i := 0; i < rv.Len(); i++ {
			// TODO: slooow
			s, b := MakeVariant(rv.Index(i).Interface()).format()
			unamb = unamb && b
			buf.WriteString(s)
			if i != rv.Len()-1 {
				buf.WriteString(", ")
			}
		}
		buf.WriteByte(']')
		return buf.String(), unamb
	case reflect.Map:
		if rv.Len() == 0 {
			return "{}", false
		}
		unamb := true
		buf := bytes.NewBuffer([]byte("{"))
		for i, k := range rv.MapKeys() {
			s, b := MakeVariant(k.Interface()).format()
			unamb = unamb && b
			buf.WriteString(s)
			buf.WriteString(": ")
			s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
			unamb = unamb && b
			buf.WriteString(s)
			if i != rv.Len()-1 {
				buf.WriteString(", ")
			}
		}
		buf.WriteByte('}')
		return buf.String(), unamb
	}
	return `"INVALID"`, true
}

// Signature returns the D-Bus signature of the underlying value of v.
func (v Variant) Signature() Signature {
	return v.sig
}

// String returns the string representation of the underlying value of v as
// described at https://developer.gnome.org/glib/unstable/gvariant-text.html.
func (v Variant) String() string {
	s, unamb := v.format()
	if !unamb {
		return "@" + v.sig.str + " " + s
	}
	return s
}

// Value returns the underlying value of v.
func (v Variant) Value() interface{} {
	return v.value
}
<commit_msg>Fix flaky tests: don't rely on map iteration order.<commit_after>package dbus

import (
	"bytes"
	"fmt"
	"reflect"
	"sort"
	"strconv"
)

// Variant represents the D-Bus variant type.
type Variant struct {
	sig   Signature
	value interface{}
}

// MakeVariant converts the given value to a Variant. It panics if v cannot be
// represented as a D-Bus type.
func MakeVariant(v interface{}) Variant {
	return Variant{SignatureOf(v), v}
}

// ParseVariant parses the given string as a variant as described at
// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not
// empty, it is taken to be the expected signature for the variant.
func ParseVariant(s string, sig Signature) (Variant, error) {
	tokens := varLex(s)
	p := &varParser{tokens: tokens}
	n, err := varMakeNode(p)
	if err != nil {
		return Variant{}, err
	}
	if sig.str == "" {
		sig, err = varInfer(n)
		if err != nil {
			return Variant{}, err
		}
	}
	v, err := n.Value(sig)
	if err != nil {
		return Variant{}, err
	}
	return MakeVariant(v), nil
}

// format returns a formatted version of v and whether this string can be parsed
// unambigously.
func (v Variant) format() (string, bool) {
	switch v.sig.str[0] {
	case 'b', 'i':
		return fmt.Sprint(v.value), true
	case 'n', 'q', 'u', 'x', 't', 'd', 'h':
		return fmt.Sprint(v.value), false
	case 's':
		return strconv.Quote(v.value.(string)), true
	case 'o':
		return strconv.Quote(string(v.value.(ObjectPath))), false
	case 'g':
		return strconv.Quote(v.value.(Signature).str), false
	case 'v':
		s, unamb := v.value.(Variant).format()
		if !unamb {
			return "<@" + v.value.(Variant).sig.str + " " + s + ">", true
		}
		return "<" + s + ">", true
	case 'y':
		return fmt.Sprintf("%#x", v.value.(byte)), false
	}
	rv := reflect.ValueOf(v.value)
	switch rv.Kind() {
	case reflect.Slice:
		if rv.Len() == 0 {
			return "[]", false
		}
		unamb := true
		buf := bytes.NewBuffer([]byte("["))
		for i := 0; i < rv.Len(); i++ {
			// TODO: slooow
			s, b := MakeVariant(rv.Index(i).Interface()).format()
			unamb = unamb && b
			buf.WriteString(s)
			if i != rv.Len()-1 {
				buf.WriteString(", ")
			}
		}
		buf.WriteByte(']')
		return buf.String(), unamb
	case reflect.Map:
		if rv.Len() == 0 {
			return "{}", false
		}
		unamb := true
		var buf bytes.Buffer
		kvs := make([]string, rv.Len())
		for i, k := range rv.MapKeys() {
			s, b := MakeVariant(k.Interface()).format()
			unamb = unamb && b
			buf.Reset()
			buf.WriteString(s)
			buf.WriteString(": ")
			s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
			unamb = unamb && b
			buf.WriteString(s)
			kvs[i] = buf.String()
		}
		buf.Reset()
		buf.WriteByte('{')
		sort.Strings(kvs)
		for i, kv := range kvs {
			if i > 0 {
				buf.WriteString(", ")
			}
			buf.WriteString(kv)
		}
		buf.WriteByte('}')
		return buf.String(), unamb
	}
	return `"INVALID"`, true
}

// Signature returns the D-Bus signature of the underlying value of v.
func (v Variant) Signature() Signature {
	return v.sig
}

// String returns the string representation of the underlying value of v as
// described at https://developer.gnome.org/glib/unstable/gvariant-text.html.
func (v Variant) String() string {
	s, unamb := v.format()
	if !unamb {
		return "@" + v.sig.str + " " + s
	}
	return s
}

// Value returns the underlying value of v.
func (v Variant) Value() interface{} {
	return v.value
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 1
	appPatch uint = 2

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<commit_msg>Bump for v0.1.3<commit_after>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 1
	appPatch uint = 3

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<|endoftext|>


<commit_before>package soko

const Version = "0.0.1"
<commit_msg>Version bump<commit_after>package soko

const Version = "0.0.2"
<|endoftext|>


<commit_before>package transport

const (
	VERSION = "0.1.1.092517_beta"
)
<commit_msg>Update Version<commit_after>package transport

const (
	VERSION = "0.1.5.092517_beta"
)
<|endoftext|>


<commit_before>// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tally

// Version is the current version of the library.
const Version = "3.4.1"
<commit_msg>Prepare v3.4.2 release<commit_after>// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tally

// Version is the current version of the library.
const Version = "3.4.2"
<|endoftext|>


<commit_before>package main

func getVersion() string {
	return "v1.0.0-2-g19b00bc"
}
<commit_msg>version.go: bump to version v1.1.0-0-gf225c83<commit_after>package main

func getVersion() string {
	return "v1.1.0-0-gf225c83"
}
<|endoftext|>


<commit_before>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 13
const VersionPatch = 0
<commit_msg>Bump version<commit_after>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 13
const VersionPatch = 1
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"runtime"
)

const (
	AppName         = "whatunga"
	AppVersionMajor = 0
	AppVersionMinor = 2
)

// revision part of the program version.
// This will be set automatically at build time like so:
//
//     go build -ldflags "-X main.AppVersionRev `date -u +%s`"
var AppVersionRev string

func Version() string {
	if len(AppVersionRev) == 0 {
		AppVersionRev = "0"
	}

	return fmt.Sprintf("%s %d.%d.%s (Go runtime %s).",
		AppName, AppVersionMajor, AppVersionMinor, AppVersionRev, runtime.Version())
}

// the xmlns version of the config files
//var ModelVersions = map[string]ProductVersion{
//	"2.0": {WildFly, "8.0"},
//	"2.1": {WildFly, "8.1"},
//	"1.6": {EAP, "6.3"},
//}
<commit_msg>Bump to 0.3<commit_after>package main

import (
	"fmt"
	"runtime"
)

const (
	AppName         = "whatunga"
	AppVersionMajor = 0
	AppVersionMinor = 3
)

// revision part of the program version.
// This will be set automatically at build time like so:
//
//     go build -ldflags "-X main.AppVersionRev `date -u +%s`"
var AppVersionRev string

func Version() string {
	if len(AppVersionRev) == 0 {
		AppVersionRev = "0"
	}

	return fmt.Sprintf("%s %d.%d.%s (Go runtime %s).",
		AppName, AppVersionMajor, AppVersionMinor, AppVersionRev, runtime.Version())
}

// the xmlns version of the config files
//var ModelVersions = map[string]ProductVersion{
//	"2.0": {WildFly, "8.0"},
//	"2.1": {WildFly, "8.1"},
//	"1.6": {EAP, "6.3"},
//}
<|endoftext|>


<commit_before>package gherkin

const VERSION = "v0.1.6"
<commit_msg>version bump v0.1.7<commit_after>package gherkin

const VERSION = "v0.1.7"
<|endoftext|>


<commit_before>package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

var (
	// ErrNothingAdded is an error that occurs when a Watcher's Start() method is
	// called and no files or folders have been added to the Watcher's watchlist.
	ErrNothingAdded = errors.New("error: no files added to the watchlist")

	// ErrWatchedFileDeleted is an error that occurs when a file or folder that was
	// being watched has been deleted.
	ErrWatchedFileDeleted = errors.New("error: watched file or folder deleted")
)

// An EventType is a type that is used to describe what type
// of event has occured during the watching process.
type EventType int

const (
	EventFileAdded EventType = 1 << iota
	EventFileDeleted
	EventFileModified
)

// An Option is a type that is used to set options for a Watcher.
type Option int

const (
	// NonRecursive sets the watcher to not watch directories recursively.
	NonRecursive Option = 1 << iota

	// IgnoreDotFiles sets the watcher to ignore dot files.
	IgnoreDotFiles
)

// String returns a small string depending on what
// type of event it is.
func (e EventType) String() string {
	switch e {
	case EventFileAdded:
		return "FILE/FOLDER ADDED"
	case EventFileDeleted:
		return "FILE/FOLDER DELETED"
	case EventFileModified:
		return "FILE/FOLDER MODIFIED"
	default:
		return "UNRECOGNIZED EVENT"
	}
}

type Event struct {
	EventType
	os.FileInfo
}

// A Watcher describes a file watcher.
type Watcher struct {
	Event chan Event
	Error chan error

	options []Option

	maxEventsPerCycle int

	// mu protects Files and Names.
	mu    *sync.Mutex
	Files map[string]os.FileInfo
	Names []string
}

// New returns a new initialized *Watcher.
func New(options ...Option) *Watcher {
	return &Watcher{
		Event:   make(chan Event),
		Error:   make(chan error),
		options: options,
		mu:      new(sync.Mutex),
		Files:   make(map[string]os.FileInfo),
		Names:   []string{},
	}
}

// SetMaxEvents controls the maximum amount of events that are sent on
// the Event channel per watching cycle. If max events is less than 1, there is
// no limit, which is the default.
func (w *Watcher) SetMaxEvents(amount int) {
	w.mu.Lock()
	w.maxEventsPerCycle = amount
	w.mu.Unlock()
}

// fileInfo is an implementation of os.FileInfo that can be used
// as a mocked os.FileInfo when triggering an event when the specified
// os.FileInfo is nil.
type fileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	sys     interface{}
}

func (fs *fileInfo) IsDir() bool {
	return false
}
func (fs *fileInfo) ModTime() time.Time {
	return fs.modTime
}
func (fs *fileInfo) Mode() os.FileMode {
	return fs.mode
}
func (fs *fileInfo) Name() string {
	return fs.name
}
func (fs *fileInfo) Size() int64 {
	return fs.size
}
func (fs *fileInfo) Sys() interface{} {
	return fs.sys
}

// Add adds either a single file or recursed directory to
// the Watcher's file list.
func (w *Watcher) Add(name string) error {
	// Add the name from w's Names list.
	w.mu.Lock()
	w.Names = append(w.Names, name)
	w.mu.Unlock()

	// Make sure name exists.
	fInfo, err := os.Stat(name)
	if err != nil {
		return err
	}

	// If watching a single file, add it and return.
	if !fInfo.IsDir() {
		w.mu.Lock()
		w.Files[fInfo.Name()] = fInfo
		w.mu.Unlock()
		return nil
	}

	// Retrieve a list of all of the os.FileInfo's to add to w.Files.
	fInfoList, err := ListFiles(name, w.options...)
	if err != nil {
		return err
	}
	w.mu.Lock()
	for k, v := range fInfoList {
		w.Files[k] = v
	}
	w.mu.Unlock()
	return nil
}

// Remove removes either a single file or recursed directory from
// the Watcher's file list.
func (w *Watcher) Remove(name string) error {
	// Remove the name from w's Names list.
	w.mu.Lock()
	for i := range w.Names {
		if w.Names[i] == name {
			w.Names = append(w.Names[:i], w.Names[i+1:]...)
		}
	}
	w.mu.Unlock()

	// Make sure name exists.
	fInfo, err := os.Stat(name)
	if err != nil {
		return err
	}

	// If name is a single file, remove it and return.
	if !fInfo.IsDir() {
		w.mu.Lock()
		delete(w.Files, fInfo.Name())
		w.mu.Unlock()
		return nil
	}

	// Retrieve a list of all of the os.FileInfo's to delete from w.Files.
	fInfoList, err := ListFiles(name, w.options...)
	if err != nil {
		return err
	}

	// Remove the appropriate os.FileInfo's from w's os.FileInfo list.
	w.mu.Lock()
	for path := range fInfoList {
		delete(w.Files, path)
	}
	w.mu.Unlock()
	return nil
}

// TriggerEvent is a method that can be used to trigger an event, separate to
// the file watching process.
func (w *Watcher) TriggerEvent(eventType EventType, file os.FileInfo) {
	if file == nil {
		file = &fileInfo{name: "triggered event", modTime: time.Now()}
	}
	w.Event <- Event{eventType, file}
}

// Start starts the watching process and checks for changes every `pollInterval`
// amount of milliseconds. If pollInterval is 0, the default is 100ms.
func (w *Watcher) Start(pollInterval time.Duration) error {
	if pollInterval <= 0 {
		pollInterval = time.Millisecond * 100
	}

	if len(w.Names) < 1 {
		return ErrNothingAdded
	}

	for {
		fileList := make(map[string]os.FileInfo)
		for _, name := range w.Names {
			// Retrieve the list of os.FileInfo's from w.Name.
			list, err := ListFiles(name, w.options...)
			if err != nil {
				if os.IsNotExist(err) {
					w.Error <- ErrWatchedFileDeleted
				} else {
					w.Error <- err
				}
			}
			for k, v := range list {
				fileList[k] = v
			}
		}

		numEvents := 0
		if len(fileList) > len(w.Files) {
			// Check for new files.
			for path, fInfo := range fileList {
				if _, found := w.Files[path]; !found {
					if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
						break
					}
					w.Event <- Event{EventType: EventFileAdded, FileInfo: fInfo}
					numEvents++
				}
			}
			w.Files = fileList
		} else if len(fileList) < len(w.Files) {
			// Check for deleted files.
			for path, fInfo := range w.Files {
				if _, found := fileList[path]; !found {
					if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
						break
					}
					w.Event <- Event{EventType: EventFileDeleted, FileInfo: fInfo}
					numEvents++
				}
			}
			w.Files = fileList
		}

		// Check for modified files.
		for i, file := range w.Files {
			if fileList[i].ModTime() != file.ModTime() {
				if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
					break
				}
				w.Event <- Event{EventType: EventFileModified, FileInfo: file}
				numEvents++
			}
		}
		w.Files = fileList

		// Sleep for a little bit.
		time.Sleep(pollInterval)
	}

	return nil
}

func hasOption(option Option, options []Option) bool {
	for _, o := range options {
		if option&o != 0 {
			return true
		}
	}
	return false
}

// ListFiles returns a map of all os.FileInfo's recursively
// contained in a directory. If name is a single file, it returns
// an os.FileInfo map containing a single os.FileInfo.
func ListFiles(name string, options ...Option) (map[string]os.FileInfo, error) {
	fileList := make(map[string]os.FileInfo)

	name = filepath.Clean(name)

	nonRecursive := hasOption(NonRecursive, options)
	ignoreDotFiles := hasOption(IgnoreDotFiles, options)

	if nonRecursive {
		f, err := os.Open(name)
		if err != nil {
			return nil, err
		}
		defer f.Close()
		info, err := os.Stat(name)
		if err != nil {
			return nil, err
		}
		// Add the name to fileList.
		if !info.IsDir() && ignoreDotFiles && strings.HasPrefix(name, ".") {
			return fileList, nil
		}
		fileList[name] = info
		if !info.IsDir() {
			return fileList, nil
		}
		// It's a directory, read it's contents.
		fInfoList, err := f.Readdir(-1)
		if err != nil {
			return nil, err
		}
		// Add all of the FileInfo's returned from f.ReadDir to fileList.
		for _, fInfo := range fInfoList {
			if ignoreDotFiles && strings.HasPrefix(fInfo.Name(), ".") {
				continue
			}
			fileList[filepath.Join(name, fInfo.Name())] = fInfo
		}
		return fileList, nil
	}

	var currentDir string
	if err := filepath.Walk(name, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if ignoreDotFiles && strings.HasPrefix(info.Name(), ".") {
			return nil
		}

		if info.IsDir() {
			fileList[filepath.Join(currentDir, info.Name())] = info
			currentDir = filepath.Join(currentDir, info.Name())
		} else {
			fileList[filepath.Join(currentDir, info.Name())] = info
		}

		return nil
	}); err != nil {
		return nil, err
	}

	return fileList, nil
}
<commit_msg>fixed directory path structure<commit_after>package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

var (
	// ErrNothingAdded is an error that occurs when a Watcher's Start() method is
	// called and no files or folders have been added to the Watcher's watchlist.
	ErrNothingAdded = errors.New("error: no files added to the watchlist")

	// ErrWatchedFileDeleted is an error that occurs when a file or folder that was
	// being watched has been deleted.
	ErrWatchedFileDeleted = errors.New("error: watched file or folder deleted")
)

// An EventType is a type that is used to describe what type
// of event has occured during the watching process.
type EventType int

const (
	EventFileAdded EventType = 1 << iota
	EventFileDeleted
	EventFileModified
)

// An Option is a type that is used to set options for a Watcher.
type Option int

const (
	// NonRecursive sets the watcher to not watch directories recursively.
	NonRecursive Option = 1 << iota

	// IgnoreDotFiles sets the watcher to ignore dot files.
	IgnoreDotFiles
)

// String returns a small string depending on what
// type of event it is.
func (e EventType) String() string {
	switch e {
	case EventFileAdded:
		return "FILE/FOLDER ADDED"
	case EventFileDeleted:
		return "FILE/FOLDER DELETED"
	case EventFileModified:
		return "FILE/FOLDER MODIFIED"
	default:
		return "UNRECOGNIZED EVENT"
	}
}

type Event struct {
	EventType
	os.FileInfo
}

// A Watcher describes a file watcher.
type Watcher struct {
	Event chan Event
	Error chan error

	options []Option

	maxEventsPerCycle int

	// mu protects Files and Names.
	mu    *sync.Mutex
	Files map[string]os.FileInfo
	Names []string
}

// New returns a new initialized *Watcher.
func New(options ...Option) *Watcher {
	return &Watcher{
		Event:   make(chan Event),
		Error:   make(chan error),
		options: options,
		mu:      new(sync.Mutex),
		Files:   make(map[string]os.FileInfo),
		Names:   []string{},
	}
}

// SetMaxEvents controls the maximum amount of events that are sent on
// the Event channel per watching cycle. If max events is less than 1, there is
// no limit, which is the default.
func (w *Watcher) SetMaxEvents(amount int) {
	w.mu.Lock()
	w.maxEventsPerCycle = amount
	w.mu.Unlock()
}

// fileInfo is an implementation of os.FileInfo that can be used
// as a mocked os.FileInfo when triggering an event when the specified
// os.FileInfo is nil.
type fileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	sys     interface{}
}

func (fs *fileInfo) IsDir() bool {
	return false
}
func (fs *fileInfo) ModTime() time.Time {
	return fs.modTime
}
func (fs *fileInfo) Mode() os.FileMode {
	return fs.mode
}
func (fs *fileInfo) Name() string {
	return fs.name
}
func (fs *fileInfo) Size() int64 {
	return fs.size
}
func (fs *fileInfo) Sys() interface{} {
	return fs.sys
}

// Add adds either a single file or recursed directory to
// the Watcher's file list.
func (w *Watcher) Add(name string) error {
	// Add the name from w's Names list.
	w.mu.Lock()
	w.Names = append(w.Names, name)
	w.mu.Unlock()

	// Make sure name exists.
	fInfo, err := os.Stat(name)
	if err != nil {
		return err
	}

	// If watching a single file, add it and return.
	if !fInfo.IsDir() {
		w.mu.Lock()
		w.Files[fInfo.Name()] = fInfo
		w.mu.Unlock()
		return nil
	}

	// Retrieve a list of all of the os.FileInfo's to add to w.Files.
	fInfoList, err := ListFiles(name, w.options...)
	if err != nil {
		return err
	}
	w.mu.Lock()
	for k, v := range fInfoList {
		w.Files[k] = v
	}
	w.mu.Unlock()
	return nil
}

// Remove removes either a single file or recursed directory from
// the Watcher's file list.
func (w *Watcher) Remove(name string) error {
	// Remove the name from w's Names list.
	w.mu.Lock()
	for i := range w.Names {
		if w.Names[i] == name {
			w.Names = append(w.Names[:i], w.Names[i+1:]...)
		}
	}
	w.mu.Unlock()

	// Make sure name exists.
	fInfo, err := os.Stat(name)
	if err != nil {
		return err
	}

	// If name is a single file, remove it and return.
	if !fInfo.IsDir() {
		w.mu.Lock()
		delete(w.Files, fInfo.Name())
		w.mu.Unlock()
		return nil
	}

	// Retrieve a list of all of the os.FileInfo's to delete from w.Files.
	fInfoList, err := ListFiles(name, w.options...)
	if err != nil {
		return err
	}

	// Remove the appropriate os.FileInfo's from w's os.FileInfo list.
	w.mu.Lock()
	for path := range fInfoList {
		delete(w.Files, path)
	}
	w.mu.Unlock()
	return nil
}

// TriggerEvent is a method that can be used to trigger an event, separate to
// the file watching process.
func (w *Watcher) TriggerEvent(eventType EventType, file os.FileInfo) {
	if file == nil {
		file = &fileInfo{name: "triggered event", modTime: time.Now()}
	}
	w.Event <- Event{eventType, file}
}

// Start starts the watching process and checks for changes every `pollInterval`
// amount of milliseconds. If pollInterval is 0, the default is 100ms.
func (w *Watcher) Start(pollInterval time.Duration) error {
	if pollInterval <= 0 {
		pollInterval = time.Millisecond * 100
	}

	if len(w.Names) < 1 {
		return ErrNothingAdded
	}

	for {
		fileList := make(map[string]os.FileInfo)
		for _, name := range w.Names {
			// Retrieve the list of os.FileInfo's from w.Name.
			list, err := ListFiles(name, w.options...)
			if err != nil {
				if os.IsNotExist(err) {
					w.Error <- ErrWatchedFileDeleted
				} else {
					w.Error <- err
				}
			}
			for k, v := range list {
				fileList[k] = v
			}
		}

		numEvents := 0
		if len(fileList) > len(w.Files) {
			// Check for new files.
			for path, fInfo := range fileList {
				if _, found := w.Files[path]; !found {
					if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
						break
					}
					w.Event <- Event{EventType: EventFileAdded, FileInfo: fInfo}
					numEvents++
				}
			}
			w.Files = fileList
		} else if len(fileList) < len(w.Files) {
			// Check for deleted files.
			for path, fInfo := range w.Files {
				if _, found := fileList[path]; !found {
					if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
						break
					}
					w.Event <- Event{EventType: EventFileDeleted, FileInfo: fInfo}
					numEvents++
				}
			}
			w.Files = fileList
		}

		// Check for modified files.
		for i, file := range w.Files {
			if fileList[i].ModTime() != file.ModTime() {
				if w.maxEventsPerCycle > 0 && numEvents >= w.maxEventsPerCycle {
					break
				}
				w.Event <- Event{EventType: EventFileModified, FileInfo: file}
				numEvents++
			}
		}
		w.Files = fileList

		// Sleep for a little bit.
		time.Sleep(pollInterval)
	}

	return nil
}

func hasOption(option Option, options []Option) bool {
	for _, o := range options {
		if option&o != 0 {
			return true
		}
	}
	return false
}

// ListFiles returns a map of all os.FileInfo's recursively
// contained in a directory. If name is a single file, it returns
// an os.FileInfo map containing a single os.FileInfo.
func ListFiles(name string, options ...Option) (map[string]os.FileInfo, error) {
	fileList := make(map[string]os.FileInfo)

	name = filepath.Clean(name)

	nonRecursive := hasOption(NonRecursive, options)
	ignoreDotFiles := hasOption(IgnoreDotFiles, options)

	if nonRecursive {
		f, err := os.Open(name)
		if err != nil {
			return nil, err
		}
		defer f.Close()
		info, err := os.Stat(name)
		if err != nil {
			return nil, err
		}
		// Add the name to fileList.
		if !info.IsDir() && ignoreDotFiles && strings.HasPrefix(name, ".") {
			return fileList, nil
		}
		fileList[name] = info
		if !info.IsDir() {
			return fileList, nil
		}
		// It's a directory, read it's contents.
		fInfoList, err := f.Readdir(-1)
		if err != nil {
			return nil, err
		}
		// Add all of the FileInfo's returned from f.ReadDir to fileList.
		for _, fInfo := range fInfoList {
			if ignoreDotFiles && strings.HasPrefix(fInfo.Name(), ".") {
				continue
			}
			fileList[filepath.Join(name, fInfo.Name())] = fInfo
		}
		return fileList, nil
	}

	if err := filepath.Walk(name, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if ignoreDotFiles && strings.HasPrefix(info.Name(), ".") {
			return nil
		}

		fileList[path] = info

		return nil
	}); err != nil {
		return nil, err
	}

	return fileList, nil
}
<|endoftext|>