<commit_before>package iftar

import (
	"fmt"
	"math/rand"
	"time"

	"github.com/igungor/ilberbot"
)

func init() {
	ilberbot.RegisterCommand("/okundumu", okundumu)
	ilberbot.RegisterCommand("/iftar", iftar)
	ilberbot.RegisterCommand("/sahur", sahur)

	fill()
}

const (
	timeFormat     = "2 Jan 2006"
	timeFormatLong = "2 Jan 2006 15:04"
)

var no = []string{
	"okunmadi",
	"hayir",
	"Hayir",
	"Hayir.",
	"hayir.",
	"hayir okunmadi",
	"no",
	"no.",
	"NO.",
	"NO!",
	"NO",
	"nope",
	"nicht",
}

type timePair struct {
	iftar time.Time
	sahur time.Time
}

var callTime = map[string]timePair{}

var _callTime = map[string]struct {
	iftar, sahur string
}{
	"18 Jun 2015": {"20:48", "03:22"},
	"19 Jun 2015": {"20:48", "03:22"},
	"20 Jun 2015": {"20:48", "03:22"},
	"21 Jun 2015": {"20:48", "03:22"},
	"22 Jun 2015": {"20:49", "03:23"},
	"23 Jun 2015": {"20:49", "03:23"},
	"24 Jun 2015": {"20:49", "03:23"},
	"25 Jun 2015": {"20:49", "03:23"},
	"26 Jun 2015": {"20:49", "03:24"},
	"27 Jun 2015": {"20:49", "03:24"},
	"28 Jun 2015": {"20:49", "03:25"},
	"29 Jun 2015": {"20:49", "03:26"},
	"30 Jun 2015": {"20:49", "03:26"},
	"1 Jul 2015":  {"20:49", "03:27"},
	"2 Jul 2015":  {"20:49", "03:28"},
	"3 Jul 2015":  {"20:49", "03:28"},
	"4 Jul 2015":  {"20:49", "03:29"},
	"5 Jul 2015":  {"20:48", "03:30"},
	"6 Jul 2015":  {"20:48", "03:31"},
	"7 Jul 2015":  {"20:48", "03:32"},
	"8 Jul 2015":  {"20:48", "03:33"},
	"9 Jul 2015":  {"20:47", "03:35"},
	"10 Jul 2015": {"20:47", "03:35"},
	"11 Jul 2015": {"20:46", "03:37"},
	"12 Jul 2015": {"20:46", "03:38"},
	"13 Jul 2015": {"20:46", "03:39"},
	"14 Jul 2015": {"20:45", "03:40"},
	"15 Jul 2015": {"20:44", "03:41"},
	"16 Jul 2015": {"20:44", "03:43"},
}

func fill() {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	for k, v := range _callTime {
		iftar, _ := time.ParseInLocation(timeFormatLong, fmt.Sprintf("%v %v", k, v.iftar), loc)
		sahur, _ := time.ParseInLocation(timeFormatLong, fmt.Sprintf("%v %v", k, v.sahur), loc)

		callTime[k] = timePair{iftar, sahur}
	}
}

func okundumu(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]
	if !ok {
		return "galiba oruc bitti"
	}

	if now.After(timepair.iftar) {
		return "okundu"
	}

	if now.Before(timepair.sahur) {
		return "sahur daha okunmadi"
	}

	if now.After(timepair.sahur) && now.Hour() < 6 {
		return "sahur okundu da daha iftara cok var"
	}

	// after sahur and before iftar, hence NO
	return no[rand.Intn(len(no))]
}

func iftar(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]

	fmt.Printf("now: %q\n", now)
	fmt.Printf("nowstr: %q\n", nowstr)
	fmt.Println("timepair: ", timepair)

	if !ok {
		return "galiba oruc bitti"
	}

	return timepair.iftar.Format("15:04")
}

func sahur(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]
	fmt.Println(now, nowstr, timepair)

	if !ok {
		return "galiba oruc bitti"
	}

	return timepair.sahur.Format("15:04")
}
<commit_msg>Remove redundant debug lines<commit_after>package iftar

import (
	"fmt"
	"math/rand"
	"time"

	"github.com/igungor/ilberbot"
)

func init() {
	ilberbot.RegisterCommand("/okundumu", okundumu)
	ilberbot.RegisterCommand("/iftar", iftar)
	ilberbot.RegisterCommand("/sahur", sahur)

	fill()
}

const (
	timeFormat     = "2 Jan 2006"
	timeFormatLong = "2 Jan 2006 15:04"
)

var no = []string{
	"okunmadi",
	"hayir",
	"Hayir",
	"Hayir.",
	"hayir.",
	"hayir okunmadi",
	"no",
	"no.",
	"NO.",
	"NO!",
	"NO",
	"nope",
	"nicht",
}

type timePair struct {
	iftar time.Time
	sahur time.Time
}

var callTime = map[string]timePair{}

var _callTime = map[string]struct {
	iftar, sahur string
}{
	"18 Jun 2015": {"20:48", "03:22"},
	"19 Jun 2015": {"20:48", "03:22"},
	"20 Jun 2015": {"20:48", "03:22"},
	"21 Jun 2015": {"20:48", "03:22"},
	"22 Jun 2015": {"20:49", "03:23"},
	"23 Jun 2015": {"20:49", "03:23"},
	"24 Jun 2015": {"20:49", "03:23"},
	"25 Jun 2015": {"20:49", "03:23"},
	"26 Jun 2015": {"20:49", "03:24"},
	"27 Jun 2015": {"20:49", "03:24"},
	"28 Jun 2015": {"20:49", "03:25"},
	"29 Jun 2015": {"20:49", "03:26"},
	"30 Jun 2015": {"20:49", "03:26"},
	"1 Jul 2015":  {"20:49", "03:27"},
	"2 Jul 2015":  {"20:49", "03:28"},
	"3 Jul 2015":  {"20:49", "03:28"},
	"4 Jul 2015":  {"20:49", "03:29"},
	"5 Jul 2015":  {"20:48", "03:30"},
	"6 Jul 2015":  {"20:48", "03:31"},
	"7 Jul 2015":  {"20:48", "03:32"},
	"8 Jul 2015":  {"20:48", "03:33"},
	"9 Jul 2015":  {"20:47", "03:35"},
	"10 Jul 2015": {"20:47", "03:35"},
	"11 Jul 2015": {"20:46", "03:37"},
	"12 Jul 2015": {"20:46", "03:38"},
	"13 Jul 2015": {"20:46", "03:39"},
	"14 Jul 2015": {"20:45", "03:40"},
	"15 Jul 2015": {"20:44", "03:41"},
	"16 Jul 2015": {"20:44", "03:43"},
}

func fill() {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	for k, v := range _callTime {
		iftar, _ := time.ParseInLocation(timeFormatLong, fmt.Sprintf("%v %v", k, v.iftar), loc)
		sahur, _ := time.ParseInLocation(timeFormatLong, fmt.Sprintf("%v %v", k, v.sahur), loc)

		callTime[k] = timePair{iftar, sahur}
	}
}

func okundumu(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]
	if !ok {
		return "galiba oruc bitti"
	}

	if now.After(timepair.iftar) {
		return "okundu"
	}

	if now.Before(timepair.sahur) {
		return "sahur daha okunmadi"
	}

	if now.After(timepair.sahur) && now.Hour() < 6 {
		return "sahur okundu da daha iftara cok var"
	}

	// after sahur and before iftar, hence NO
	return no[rand.Intn(len(no))]
}

func iftar(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]
	if !ok {
		return "galiba oruc bitti"
	}

	return timepair.iftar.Format("15:04")
}

func sahur(args ...string) string {
	loc, _ := time.LoadLocation("Europe/Istanbul")

	now := time.Now().In(loc)
	nowstr := now.Format(timeFormat)

	timepair, ok := callTime[nowstr]
	if !ok {
		return "galiba oruc bitti"
	}

	return timepair.sahur.Format("15:04")
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Ben Morgan. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.

package flac

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/cassava/lackey/music"
	"github.com/dhowden/tag"
)

var ErrNotFLAC = errors.New("file is not an FLAC")

func Assert(file string) error {
	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	_, ft, err := tag.Identify(f)
	if err != nil {
		return err
	}
	if ft != tag.FLAC {
		return ErrNotFLAC
	}
	return nil
}

// ReadMetadata {{{

var metaReader = func(_ string) (int, time.Duration, error) {
	return 0, 0, errors.New("system program to read bitrate and song length missing")
}

func ReadMetadata(file string) (*Metadata, error) {
	if err := Assert(file); err != nil {
		return nil, err
	}

	// Read length and bitrate
	b, d, err := metaReader(file)
	if err != nil {
		return nil, err
	}

	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	tm, err := tag.ReadFrom(f)
	if err != nil {
		return nil, err
	}

	return &Metadata{
		Metadata: tm,
		length:   d,
		bitrate:  b,
		codec:    music.FLAC,
	}, nil
}

func init() {
	readers := []struct {
		name string
		fn   func(string) (int, time.Duration, error)
	}{
		{"metaflac", metaflac},
		{"exiftool", exiftool},
	}
	var found bool
	for _, r := range readers {
		if _, err := exec.LookPath(r.name); err == nil {
			found = true
			metaReader = r.fn
			break
		}
	}
	if found {
		// Ensure that the programs we need for getting the metadata are available.
		music.MetadataReaders[music.FLAC] = func(file string) (music.Metadata, error) {
			return ReadMetadata(file)
		}
	}
}

// for bitrate and time we need to use metaflac...
//
//  metaflac --show-total-samples --show-sample-rate
//
//   s = total/rate
//   bitrate = ((filesize - metadata) * 8) / (s * 1000)

func metaflac(file string) (r int, d time.Duration, err error) {
	fi, err := os.Stat(file)
	if err != nil {
		return 0, 0, err
	}

	cmd := exec.Command("metaflac", "--show-total-samples", "--show-sample-rate", file)
	bs, err := cmd.Output()
	if err != nil {
		return 0, 0, err
	}
	perr := func(err error) (int, time.Duration, error) {
		return 0, 0, fmt.Errorf("cannot parse metaflac output %q: %s", string(bs), err)
	}

	rs := strings.Split(strings.TrimSpace(string(bs)), "\n")
	if len(rs) != 2 {
		return perr(errors.New("incorrect number of fields"))
	}
	samples, err := strconv.ParseInt(rs[0], 10, 0)
	if err != nil {
		return perr(err)
	}
	rate, err := strconv.ParseInt(rs[1], 10, 0)
	if err != nil {
		return perr(err)
	}

	d = time.Duration((samples * int64(time.Second)) / rate)
	r = int((fi.Size() * 8) / (int64(d/time.Second) * 1000))
	return r, d, nil
}

func exiftool(_ string) (int, time.Duration, error) {
	return 0, 0, errors.New("not implemented")
}

// }}}

// WriteMetadata {{{

func WriteMetadata(file string, m music.Metadata) error {
	return errors.New("not implemented")
}

// }}}

// Metadata {{{

var _ = music.Metadata(new(Metadata))

type Metadata struct {
	// Metadata is an interface that already implements:
	//
	//  Format() tag.Format
	//  FileType() tag.FileType
	//
	//  Title() string
	//  Album() string
	//  Artist() string
	//  AlbumArtist() string
	//  Composer() string
	//  Year() int
	//  Genre() string
	//  Track() (int, int)
	//  Disc() (int, int)
	//
	//  Picture() *tag.Picture
	//  Lyrics() string
	//  Raw() map[string]interface{}
	tag.Metadata

	length  time.Duration
	bitrate int
	codec   music.Codec
}

func (m *Metadata) Year() int                { return m.rawInt("date") }
func (m *Metadata) AlbumArtist() string      { return m.rawString("albumartist") }
func (m *Metadata) Length() time.Duration    { return m.length }
func (m *Metadata) Comment() string          { return m.rawString("comment") }
func (m *Metadata) Website() string          { return m.rawString("contact") }
func (m *Metadata) Copyright() string        { return m.rawString("copyright") }
func (m *Metadata) Encoding() music.Codec    { return m.codec }
func (m *Metadata) EncodedBy() string        { return m.rawString("encoded-by") }
func (m *Metadata) EncodingBitrate() int     { return m.bitrate }
func (m *Metadata) EncoderSettings() string  { return "" }
func (m *Metadata) OriginalFilename() string { return "" }
func (m *Metadata) PrivateData() []byte      { return []byte{} }

func (m *Metadata) rawString(key string) string {
	if v, ok := m.Raw()[key]; ok {
		s, ok := v.(string)
		if !ok {
			panic(fmt.Sprintf("expecting string, got %#v", v))
		}
		return s
	}
	return ""
}

func (m *Metadata) rawInt(key string) int {
	if v, ok := m.Raw()[key]; ok {
		if i, ok := v.(int); ok {
			return i
		} else if s, ok := v.(string); ok {
			i, _ := strconv.ParseInt(s, 10, 0)
			return int(i)
		}
	}
	return 0
}

// }}}
<commit_msg>Update: dhowden/tag library updated<commit_after>// Copyright (c) 2016, Ben Morgan. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.

package flac

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/cassava/lackey/music"
	"github.com/dhowden/tag"
)

var ErrNotFLAC = errors.New("file is not an FLAC")

func Assert(file string) error {
	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	_, ft, err := tag.Identify(f)
	if err != nil {
		return err
	}
	if ft != tag.FLAC {
		return ErrNotFLAC
	}
	return nil
}

// ReadMetadata {{{

var metaReader = func(_ string) (int, time.Duration, error) {
	return 0, 0, errors.New("system program to read bitrate and song length missing")
}

func ReadMetadata(file string) (*Metadata, error) {
	if err := Assert(file); err != nil {
		return nil, err
	}

	// Read length and bitrate
	b, d, err := metaReader(file)
	if err != nil {
		return nil, err
	}

	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	tm, err := tag.ReadFrom(f)
	if err != nil {
		return nil, err
	}

	return &Metadata{
		Metadata: tm,
		length:   d,
		bitrate:  b,
		codec:    music.FLAC,
	}, nil
}

func init() {
	readers := []struct {
		name string
		fn   func(string) (int, time.Duration, error)
	}{
		{"metaflac", metaflac},
		{"exiftool", exiftool},
	}
	var found bool
	for _, r := range readers {
		if _, err := exec.LookPath(r.name); err == nil {
			found = true
			metaReader = r.fn
			break
		}
	}
	if found {
		// Ensure that the programs we need for getting the metadata are available.
		music.MetadataReaders[music.FLAC] = func(file string) (music.Metadata, error) {
			return ReadMetadata(file)
		}
	}
}

// for bitrate and time we need to use metaflac...
//
//  metaflac --show-total-samples --show-sample-rate
//
//   s = total/rate
//   bitrate = ((filesize - metadata) * 8) / (s * 1000)

func metaflac(file string) (r int, d time.Duration, err error) {
	fi, err := os.Stat(file)
	if err != nil {
		return 0, 0, err
	}

	cmd := exec.Command("metaflac", "--show-total-samples", "--show-sample-rate", file)
	bs, err := cmd.Output()
	if err != nil {
		return 0, 0, err
	}
	perr := func(err error) (int, time.Duration, error) {
		return 0, 0, fmt.Errorf("cannot parse metaflac output %q: %s", string(bs), err)
	}

	rs := strings.Split(strings.TrimSpace(string(bs)), "\n")
	if len(rs) != 2 {
		return perr(errors.New("incorrect number of fields"))
	}
	samples, err := strconv.ParseInt(rs[0], 10, 0)
	if err != nil {
		return perr(err)
	}
	rate, err := strconv.ParseInt(rs[1], 10, 0)
	if err != nil {
		return perr(err)
	}

	d = time.Duration((samples * int64(time.Second)) / rate)
	r = int((fi.Size() * 8) / (int64(d/time.Second) * 1000))
	return r, d, nil
}

func exiftool(_ string) (int, time.Duration, error) {
	return 0, 0, errors.New("not implemented")
}

// }}}

// WriteMetadata {{{

func WriteMetadata(file string, m music.Metadata) error {
	return errors.New("not implemented")
}

// }}}

// Metadata {{{

var _ = music.Metadata(new(Metadata))

type Metadata struct {
	// Metadata is an interface that already implements:
	//
	//  Format() tag.Format
	//  FileType() tag.FileType
	//
	//  Title() string
	//  Album() string
	//  Artist() string
	//  AlbumArtist() string
	//  Composer() string
	//  Year() int
	//  Genre() string
	//  Track() (int, int)
	//  Disc() (int, int)
	//
	//  Picture() *tag.Picture
	//  Lyrics() string
	//  Raw() map[string]interface{}
	tag.Metadata

	length  time.Duration
	bitrate int
	codec   music.Codec
}

func (m *Metadata) Year() int                { return m.rawInt("date") }
func (m *Metadata) Length() time.Duration    { return m.length }
func (m *Metadata) Comment() string          { return m.rawString("comment") }
func (m *Metadata) Website() string          { return m.rawString("contact") }
func (m *Metadata) Copyright() string        { return m.rawString("copyright") }
func (m *Metadata) Encoding() music.Codec    { return m.codec }
func (m *Metadata) EncodedBy() string        { return m.rawString("encoded-by") }
func (m *Metadata) EncodingBitrate() int     { return m.bitrate }
func (m *Metadata) EncoderSettings() string  { return "" }
func (m *Metadata) OriginalFilename() string { return "" }
func (m *Metadata) PrivateData() []byte      { return []byte{} }

func (m *Metadata) rawString(key string) string {
	if v, ok := m.Raw()[key]; ok {
		s, ok := v.(string)
		if !ok {
			panic(fmt.Sprintf("expecting string, got %#v", v))
		}
		return s
	}
	return ""
}

func (m *Metadata) rawInt(key string) int {
	if v, ok := m.Raw()[key]; ok {
		if i, ok := v.(int); ok {
			return i
		} else if s, ok := v.(string); ok {
			i, _ := strconv.ParseInt(s, 10, 0)
			return int(i)
		}
	}
	return 0
}

// }}}
<|endoftext|>


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

package commands

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"github.com/gohugoio/hugo/config"
	"github.com/gohugoio/hugo/helpers"
	"github.com/gohugoio/hugo/htesting"
	"golang.org/x/net/context"
	"golang.org/x/sync/errgroup"

	qt "github.com/frankban/quicktest"
)

// Issue 9518
func TestServerPanicOnConfigError(t *testing.T) {
	c := qt.New(t)

	config := `
[markup]
[markup.highlight]
linenos='table'
`

	r := runServerTest(c,
		serverTestOptions{
			config: config,
		},
	)

	c.Assert(r.err, qt.IsNotNil)
	c.Assert(r.err.Error(), qt.Contains, "cannot parse 'Highlight.LineNos' as bool:")
}

func TestServer404(t *testing.T) {
	c := qt.New(t)

	r := runServerTest(c,
		serverTestOptions{
			pathsToGet:  []string{"this/does/not/exist"},
			getNumHomes: 1,
		},
	)

	c.Assert(r.err, qt.IsNil)
	pr := r.pathsResults["this/does/not/exist"]
	c.Assert(pr.statusCode, qt.Equals, http.StatusNotFound)
	c.Assert(pr.body, qt.Contains, "404: 404 Page not found|Not Found.")
}

func TestServerPathEncodingIssues(t *testing.T) {
	if htesting.IsGitHubAction() {
		// This test is flaky on CI for some reason. Run it on Windows only for now.
		// TODO(bep)
		if runtime.GOOS != "windows" {
			t.Skip("Skipping test on CI")
		}
	}
	c := qt.New(t)

	// Issue 10287
	c.Run("Unicode paths", func(c *qt.C) {
		r := runServerTest(c,
			serverTestOptions{
				pathsToGet: []string{"hügö/"},
			},
		)

		c.Assert(r.err, qt.IsNil)
		c.Assert(r.pathsResults["hügö/"].body, qt.Contains, "This is hügö")
	})

	// Issue 10314
	c.Run("Windows multilingual 404", func(c *qt.C) {
		config := `
baseURL = 'https://example.org/'
title = 'Hugo Forum Topic #40568'

defaultContentLanguageInSubdir = true

[languages.en]
contentDir = 'content/en'
languageCode = 'en-US'
languageName = 'English'
weight = 1

[languages.es]
contentDir = 'content/es'
languageCode = 'es-ES'
languageName = 'Espanol'
weight = 2

[server]
[[server.redirects]]
from = '/en/**'
to = '/en/404.html'
status = 404

[[server.redirects]]
from = '/es/**'
to = '/es/404.html'
status = 404
`
		r := runServerTest(c,
			serverTestOptions{
				config:     config,
				pathsToGet: []string{"en/this/does/not/exist", "es/this/does/not/exist"},
			},
		)

		c.Assert(r.err, qt.IsNil)
		pr1 := r.pathsResults["en/this/does/not/exist"]
		pr2 := r.pathsResults["es/this/does/not/exist"]
		c.Assert(pr1.statusCode, qt.Equals, http.StatusNotFound)
		c.Assert(pr2.statusCode, qt.Equals, http.StatusNotFound)
		c.Assert(pr1.body, qt.Contains, "404: 404 Page not found|Not Found.")
		c.Assert(pr2.body, qt.Contains, "404: 404 Page not found|Not Found.")

	})

}
func TestServerFlags(t *testing.T) {
	c := qt.New(t)

	assertPublic := func(c *qt.C, r serverTestResult, renderStaticToDisk bool) {
		c.Assert(r.err, qt.IsNil)
		c.Assert(r.homesContent[0], qt.Contains, "Environment: development")
		c.Assert(r.publicDirnames["myfile.txt"], qt.Equals, renderStaticToDisk)

	}

	for _, test := range []struct {
		flag   string
		assert func(c *qt.C, r serverTestResult)
	}{
		{"", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, false)
		}},
		{"--renderToDisk", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, true)
		}},
		{"--renderStaticToDisk", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, true)
		}},
	} {
		c.Run(test.flag, func(c *qt.C) {
			config := `
baseURL="https://example.org"
`

			var args []string
			if test.flag != "" {
				args = strings.Split(test.flag, "=")
			}

			opts := serverTestOptions{
				config:      config,
				args:        args,
				getNumHomes: 1,
			}

			r := runServerTest(c, opts)

			test.assert(c, r)

		})

	}

}

func TestServerBugs(t *testing.T) {
	c := qt.New(t)

	for _, test := range []struct {
		name       string
		config     string
		flag       string
		numservers int
		assert     func(c *qt.C, r serverTestResult)
	}{
		{"PostProcess, memory", "", "", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		// Issue 9788
		{"PostProcess, memory", "", "", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		{"PostProcess, disk", "", "--renderToDisk", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		// Isue 9901
		{"Multihost", `
defaultContentLanguage = 'en'
[languages]
[languages.en]
baseURL = 'https://example.com'
title = 'My blog'
weight = 1
[languages.fr]
baseURL = 'https://example.fr'
title = 'Mon blogue'
weight = 2
`, "", 2, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			for i, s := range []string{"My blog", "Mon blogue"} {
				c.Assert(r.homesContent[i], qt.Contains, s)
			}
		}},
	} {
		c.Run(test.name, func(c *qt.C) {
			if test.config == "" {
				test.config = `
baseURL="https://example.org"
`
			}

			var args []string
			if test.flag != "" {
				args = strings.Split(test.flag, "=")
			}

			opts := serverTestOptions{
				config:      test.config,
				getNumHomes: test.numservers,
				pathsToGet:  []string{"this/does/not/exist"},
				args:        args,
			}

			r := runServerTest(c, opts)
			pr := r.pathsResults["this/does/not/exist"]
			c.Assert(pr.statusCode, qt.Equals, http.StatusNotFound)
			c.Assert(pr.body, qt.Contains, "404: 404 Page not found|Not Found.")
			test.assert(c, r)

		})

	}

}

type serverTestResult struct {
	err            error
	homesContent   []string
	content404     string
	publicDirnames map[string]bool
	pathsResults   map[string]pathResult
}

type pathResult struct {
	statusCode int
	body       string
}

type serverTestOptions struct {
	getNumHomes int
	config      string
	pathsToGet  []string
	args        []string
}

func runServerTest(c *qt.C, opts serverTestOptions) serverTestResult {
	dir := createSimpleTestSite(c, testSiteConfig{configTOML: opts.config})
	result := serverTestResult{
		publicDirnames: make(map[string]bool),
		pathsResults:   make(map[string]pathResult),
	}

	sp, err := helpers.FindAvailablePort()
	c.Assert(err, qt.IsNil)
	port := sp.Port

	defer func() {
		os.RemoveAll(dir)
	}()

	stop := make(chan bool)

	b := newCommandsBuilder()
	scmd := b.newServerCmdSignaled(stop)

	cmd := scmd.getCommand()
	args := append([]string{"-s=" + dir, fmt.Sprintf("-p=%d", port)}, opts.args...)
	cmd.SetArgs(args)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	wg, ctx := errgroup.WithContext(ctx)

	wg.Go(func() error {
		_, err := cmd.ExecuteC()
		return err
	})

	if opts.getNumHomes > 0 {
		// Esp. on slow CI machines, we need to wait a little before the web
		// server is ready.
		wait := 567 * time.Millisecond
		if os.Getenv("CI") != "" {
			wait = 2 * time.Second
		}
		time.Sleep(wait)
		result.homesContent = make([]string, opts.getNumHomes)
		for i := 0; i < opts.getNumHomes; i++ {
			func() {
				resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port+i))
				c.Assert(err, qt.IsNil)
				c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
				if err == nil {
					defer resp.Body.Close()
					result.homesContent[i] = helpers.ReaderToString(resp.Body)
				}
			}()
		}
	}

	for _, path := range opts.pathsToGet {
		func() {
			resp, err := http.Get(fmt.Sprintf("http://localhost:%d/%s", port, path))
			c.Assert(err, qt.IsNil)
			pr := pathResult{
				statusCode: resp.StatusCode,
			}

			if err == nil {
				defer resp.Body.Close()
				pr.body = helpers.ReaderToString(resp.Body)
			}
			result.pathsResults[path] = pr
		}()
	}

	time.Sleep(1 * time.Second)

	select {
	case <-stop:
	case stop <- true:
	}

	pubFiles, err := os.ReadDir(filepath.Join(dir, "public"))
	c.Assert(err, qt.IsNil)
	for _, f := range pubFiles {
		result.publicDirnames[f.Name()] = true
	}

	result.err = wg.Wait()

	return result

}

func TestFixURL(t *testing.T) {
	type data struct {
		TestName   string
		CLIBaseURL string
		CfgBaseURL string
		AppendPort bool
		Port       int
		Result     string
	}
	tests := []data{
		{"Basic http localhost", "", "http://foo.com", true, 1313, "http://localhost:1313/"},
		{"Basic https production, http localhost", "", "https://foo.com", true, 1313, "http://localhost:1313/"},
		{"Basic subdir", "", "http://foo.com/bar", true, 1313, "http://localhost:1313/bar/"},
		{"Basic production", "http://foo.com", "http://foo.com", false, 80, "http://foo.com/"},
		{"Production subdir", "http://foo.com/bar", "http://foo.com/bar", false, 80, "http://foo.com/bar/"},
		{"No http", "", "foo.com", true, 1313, "//localhost:1313/"},
		{"Override configured port", "", "foo.com:2020", true, 1313, "//localhost:1313/"},
		{"No http production", "foo.com", "foo.com", false, 80, "//foo.com/"},
		{"No http production with port", "foo.com", "foo.com", true, 2020, "//foo.com:2020/"},
		{"No config", "", "", true, 1313, "//localhost:1313/"},
	}

	for _, test := range tests {
		t.Run(test.TestName, func(t *testing.T) {
			b := newCommandsBuilder()
			s := b.newServerCmd()
			v := config.NewWithTestDefaults()
			baseURL := test.CLIBaseURL
			v.Set("baseURL", test.CfgBaseURL)
			s.serverAppend = test.AppendPort
			s.serverPort = test.Port
			result, err := s.fixURL(v, baseURL, s.serverPort)
			if err != nil {
				t.Errorf("Unexpected error %s", err)
			}
			if result != test.Result {
				t.Errorf("Expected %q, got %q", test.Result, result)
			}
		})
	}
}

func TestRemoveErrorPrefixFromLog(t *testing.T) {
	c := qt.New(t)
	content := `ERROR 2018/10/07 13:11:12 Error while rendering "home": template: _default/baseof.html:4:3: executing "main" at <partial "logo" .>: error calling partial: template: partials/logo.html:5:84: executing "partials/logo.html" at <$resized.AHeight>: can't evaluate field AHeight in type *resource.Image
ERROR 2018/10/07 13:11:12 Rebuild failed: logged 1 error(s)
`

	withoutError := removeErrorPrefixFromLog(content)

	c.Assert(strings.Contains(withoutError, "ERROR"), qt.Equals, false)
}

func isWindowsCI() bool {
	return runtime.GOOS == "windows" && os.Getenv("CI") != ""
}
<commit_msg>server: Fix flaky TestServerPathEncodingIssues tests<commit_after>// Copyright 2015 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package commands

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"github.com/gohugoio/hugo/config"
	"github.com/gohugoio/hugo/helpers"
	"golang.org/x/net/context"
	"golang.org/x/sync/errgroup"

	qt "github.com/frankban/quicktest"
)

// Issue 9518
func TestServerPanicOnConfigError(t *testing.T) {
	c := qt.New(t)

	config := `
[markup]
[markup.highlight]
linenos='table'
`

	r := runServerTest(c,
		serverTestOptions{
			config: config,
		},
	)

	c.Assert(r.err, qt.IsNotNil)
	c.Assert(r.err.Error(), qt.Contains, "cannot parse 'Highlight.LineNos' as bool:")
}

func TestServer404(t *testing.T) {
	c := qt.New(t)

	r := runServerTest(c,
		serverTestOptions{
			pathsToGet:  []string{"this/does/not/exist"},
			getNumHomes: 1,
		},
	)

	c.Assert(r.err, qt.IsNil)
	pr := r.pathsResults["this/does/not/exist"]
	c.Assert(pr.statusCode, qt.Equals, http.StatusNotFound)
	c.Assert(pr.body, qt.Contains, "404: 404 Page not found|Not Found.")
}

func TestServerPathEncodingIssues(t *testing.T) {
	c := qt.New(t)

	// Issue 10287
	c.Run("Unicode paths", func(c *qt.C) {
		r := runServerTest(c,
			serverTestOptions{
				pathsToGet:  []string{"hügö/"},
				getNumHomes: 1,
			},
		)

		c.Assert(r.err, qt.IsNil)
		c.Assert(r.pathsResults["hügö/"].body, qt.Contains, "This is hügö")
	})

	// Issue 10314
	c.Run("Windows multilingual 404", func(c *qt.C) {
		config := `
baseURL = 'https://example.org/'
title = 'Hugo Forum Topic #40568'

defaultContentLanguageInSubdir = true

[languages.en]
contentDir = 'content/en'
languageCode = 'en-US'
languageName = 'English'
weight = 1

[languages.es]
contentDir = 'content/es'
languageCode = 'es-ES'
languageName = 'Espanol'
weight = 2

[server]
[[server.redirects]]
from = '/en/**'
to = '/en/404.html'
status = 404

[[server.redirects]]
from = '/es/**'
to = '/es/404.html'
status = 404
`
		r := runServerTest(c,
			serverTestOptions{
				config:      config,
				pathsToGet:  []string{"en/this/does/not/exist", "es/this/does/not/exist"},
				getNumHomes: 1,
			},
		)

		c.Assert(r.err, qt.IsNil)
		pr1 := r.pathsResults["en/this/does/not/exist"]
		pr2 := r.pathsResults["es/this/does/not/exist"]
		c.Assert(pr1.statusCode, qt.Equals, http.StatusNotFound)
		c.Assert(pr2.statusCode, qt.Equals, http.StatusNotFound)
		c.Assert(pr1.body, qt.Contains, "404: 404 Page not found|Not Found.")
		c.Assert(pr2.body, qt.Contains, "404: 404 Page not found|Not Found.")

	})

}
func TestServerFlags(t *testing.T) {
	c := qt.New(t)

	assertPublic := func(c *qt.C, r serverTestResult, renderStaticToDisk bool) {
		c.Assert(r.err, qt.IsNil)
		c.Assert(r.homesContent[0], qt.Contains, "Environment: development")
		c.Assert(r.publicDirnames["myfile.txt"], qt.Equals, renderStaticToDisk)

	}

	for _, test := range []struct {
		flag   string
		assert func(c *qt.C, r serverTestResult)
	}{
		{"", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, false)
		}},
		{"--renderToDisk", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, true)
		}},
		{"--renderStaticToDisk", func(c *qt.C, r serverTestResult) {
			assertPublic(c, r, true)
		}},
	} {
		c.Run(test.flag, func(c *qt.C) {
			config := `
baseURL="https://example.org"
`

			var args []string
			if test.flag != "" {
				args = strings.Split(test.flag, "=")
			}

			opts := serverTestOptions{
				config:      config,
				args:        args,
				getNumHomes: 1,
			}

			r := runServerTest(c, opts)

			test.assert(c, r)

		})

	}

}

func TestServerBugs(t *testing.T) {
	c := qt.New(t)

	for _, test := range []struct {
		name       string
		config     string
		flag       string
		numservers int
		assert     func(c *qt.C, r serverTestResult)
	}{
		{"PostProcess, memory", "", "", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		// Issue 9788
		{"PostProcess, memory", "", "", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		{"PostProcess, disk", "", "--renderToDisk", 1, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			c.Assert(r.homesContent[0], qt.Contains, "PostProcess: /foo.min.css")
		}},
		// Isue 9901
		{"Multihost", `
defaultContentLanguage = 'en'
[languages]
[languages.en]
baseURL = 'https://example.com'
title = 'My blog'
weight = 1
[languages.fr]
baseURL = 'https://example.fr'
title = 'Mon blogue'
weight = 2
`, "", 2, func(c *qt.C, r serverTestResult) {
			c.Assert(r.err, qt.IsNil)
			for i, s := range []string{"My blog", "Mon blogue"} {
				c.Assert(r.homesContent[i], qt.Contains, s)
			}
		}},
	} {
		c.Run(test.name, func(c *qt.C) {
			if test.config == "" {
				test.config = `
baseURL="https://example.org"
`
			}

			var args []string
			if test.flag != "" {
				args = strings.Split(test.flag, "=")
			}

			opts := serverTestOptions{
				config:      test.config,
				getNumHomes: test.numservers,
				pathsToGet:  []string{"this/does/not/exist"},
				args:        args,
			}

			r := runServerTest(c, opts)
			pr := r.pathsResults["this/does/not/exist"]
			c.Assert(pr.statusCode, qt.Equals, http.StatusNotFound)
			c.Assert(pr.body, qt.Contains, "404: 404 Page not found|Not Found.")
			test.assert(c, r)

		})

	}

}

type serverTestResult struct {
	err            error
	homesContent   []string
	content404     string
	publicDirnames map[string]bool
	pathsResults   map[string]pathResult
}

type pathResult struct {
	statusCode int
	body       string
}

type serverTestOptions struct {
	getNumHomes int
	config      string
	pathsToGet  []string
	args        []string
}

func runServerTest(c *qt.C, opts serverTestOptions) serverTestResult {
	dir := createSimpleTestSite(c, testSiteConfig{configTOML: opts.config})
	result := serverTestResult{
		publicDirnames: make(map[string]bool),
		pathsResults:   make(map[string]pathResult),
	}

	sp, err := helpers.FindAvailablePort()
	c.Assert(err, qt.IsNil)
	port := sp.Port

	defer func() {
		os.RemoveAll(dir)
	}()

	stop := make(chan bool)

	b := newCommandsBuilder()
	scmd := b.newServerCmdSignaled(stop)

	cmd := scmd.getCommand()
	args := append([]string{"-s=" + dir, fmt.Sprintf("-p=%d", port)}, opts.args...)
	cmd.SetArgs(args)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	wg, ctx := errgroup.WithContext(ctx)

	wg.Go(func() error {
		_, err := cmd.ExecuteC()
		return err
	})

	if opts.getNumHomes > 0 {
		// Esp. on slow CI machines, we need to wait a little before the web
		// server is ready.
		wait := 567 * time.Millisecond
		if os.Getenv("CI") != "" {
			wait = 2 * time.Second
		}
		time.Sleep(wait)
		result.homesContent = make([]string, opts.getNumHomes)
		for i := 0; i < opts.getNumHomes; i++ {
			func() {
				resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port+i))
				c.Assert(err, qt.IsNil)
				c.Assert(resp.StatusCode, qt.Equals, http.StatusOK)
				if err == nil {
					defer resp.Body.Close()
					result.homesContent[i] = helpers.ReaderToString(resp.Body)
				}
			}()
		}
	}

	for _, path := range opts.pathsToGet {
		func() {
			resp, err := http.Get(fmt.Sprintf("http://localhost:%d/%s", port, path))
			c.Assert(err, qt.IsNil)
			pr := pathResult{
				statusCode: resp.StatusCode,
			}

			if err == nil {
				defer resp.Body.Close()
				pr.body = helpers.ReaderToString(resp.Body)
			}
			result.pathsResults[path] = pr
		}()
	}

	time.Sleep(1 * time.Second)

	select {
	case <-stop:
	case stop <- true:
	}

	pubFiles, err := os.ReadDir(filepath.Join(dir, "public"))
	c.Assert(err, qt.IsNil)
	for _, f := range pubFiles {
		result.publicDirnames[f.Name()] = true
	}

	result.err = wg.Wait()

	return result

}

func TestFixURL(t *testing.T) {
	type data struct {
		TestName   string
		CLIBaseURL string
		CfgBaseURL string
		AppendPort bool
		Port       int
		Result     string
	}
	tests := []data{
		{"Basic http localhost", "", "http://foo.com", true, 1313, "http://localhost:1313/"},
		{"Basic https production, http localhost", "", "https://foo.com", true, 1313, "http://localhost:1313/"},
		{"Basic subdir", "", "http://foo.com/bar", true, 1313, "http://localhost:1313/bar/"},
		{"Basic production", "http://foo.com", "http://foo.com", false, 80, "http://foo.com/"},
		{"Production subdir", "http://foo.com/bar", "http://foo.com/bar", false, 80, "http://foo.com/bar/"},
		{"No http", "", "foo.com", true, 1313, "//localhost:1313/"},
		{"Override configured port", "", "foo.com:2020", true, 1313, "//localhost:1313/"},
		{"No http production", "foo.com", "foo.com", false, 80, "//foo.com/"},
		{"No http production with port", "foo.com", "foo.com", true, 2020, "//foo.com:2020/"},
		{"No config", "", "", true, 1313, "//localhost:1313/"},
	}

	for _, test := range tests {
		t.Run(test.TestName, func(t *testing.T) {
			b := newCommandsBuilder()
			s := b.newServerCmd()
			v := config.NewWithTestDefaults()
			baseURL := test.CLIBaseURL
			v.Set("baseURL", test.CfgBaseURL)
			s.serverAppend = test.AppendPort
			s.serverPort = test.Port
			result, err := s.fixURL(v, baseURL, s.serverPort)
			if err != nil {
				t.Errorf("Unexpected error %s", err)
			}
			if result != test.Result {
				t.Errorf("Expected %q, got %q", test.Result, result)
			}
		})
	}
}

func TestRemoveErrorPrefixFromLog(t *testing.T) {
	c := qt.New(t)
	content := `ERROR 2018/10/07 13:11:12 Error while rendering "home": template: _default/baseof.html:4:3: executing "main" at <partial "logo" .>: error calling partial: template: partials/logo.html:5:84: executing "partials/logo.html" at <$resized.AHeight>: can't evaluate field AHeight in type *resource.Image
ERROR 2018/10/07 13:11:12 Rebuild failed: logged 1 error(s)
`

	withoutError := removeErrorPrefixFromLog(content)

	c.Assert(strings.Contains(withoutError, "ERROR"), qt.Equals, false)
}

func isWindowsCI() bool {
	return runtime.GOOS == "windows" && os.Getenv("CI") != ""
}
<|endoftext|>


<commit_before>package routes

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/takonews/takonews-api/app/controllers"
	"github.com/takonews/takonews-api/config"
)

func Router() *http.ServeMux {
	router := gin.Default()

	users := config.Config.Secret.Users
	accounts := make(map[string]string)
	for _, v := range users {
		accounts[v["name"]] = v["password"]
	}
	authorized := router.Group("/")
	authorized.Use(gin.BasicAuth(accounts))
	authorized.GET("/api/v2/articles", controllers.ArticleIndex)
	authorized.GET("/api/v2/articles/:articles_id", controllers.ArticleShow)

	var mux = http.NewServeMux()
	mux.Handle("/", router)

	return mux
}
<commit_msg>Update routes.go<commit_after>package routes

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/takonews/takonews-api/app/controllers"
	"github.com/takonews/takonews-api/config"
)

func Router() *http.ServeMux {
	router := gin.Default()

	users := config.Config.Secret.Users
	accounts := make(map[string]string)
	for _, v := range users {
		accounts[v["name"]] = v["password"]
	}
	authorized := router.Group("/")
	authorized.Use(gin.BasicAuth(accounts))
	authorized.GET("/api/v2/articles", controllers.ArticleIndex)
	authorized.GET("/api/v2/articles/:articles_id", controllers.ArticleShow)

	var mux = http.NewServeMux()
	mux.Handle("/", router)

	return mux
}
<|endoftext|>


<commit_before>package docker

import (
	"errors"
	"fmt"
	"strings"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	. "github.com/weaveworks/weave/common"
)

const (
	InitialInterval = 1 * time.Second
	MaxInterval     = 60 * time.Second
)

// An observer for container events
type ContainerObserver interface {
	ContainerStarted(ident string)
	ContainerDied(ident string)
}

type Client struct {
	*docker.Client
}

// NewClient creates a new Docker client and checks we can talk to Docker
func NewClient(apiPath string) (*Client, error) {
	if apiPath != "" && !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewClient(apiPath)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClient(apiPath string, apiVersionString string) (*Client, error) {
	if !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewVersionedClient(apiPath, apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClientFromEnv(apiVersionString string) (*Client, error) {
	dc, err := docker.NewVersionedClientFromEnv(apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func (c *Client) checkWorking() error {
	_, err := c.Version()
	return err
}

func (c *Client) Info() string {
	if env, err := c.Version(); err != nil {
		return fmt.Sprintf("Docker API error: %s", err)
	} else {
		return fmt.Sprintf("Docker API on %s: %v", c.Endpoint(), env)
	}
}

// AddObserver adds an observer for docker events
func (c *Client) AddObserver(ob ContainerObserver) error {
	go func() {
		retryInterval := InitialInterval
		for {
			events := make(chan *docker.APIEvents)
			if err := c.AddEventListener(events); err != nil {
				Log.Errorf("[docker] Unable to add listener to Docker API: %s - retrying in %ds", err, retryInterval/time.Second)
			} else {
				for event := range events {
					switch event.Status {
					case "start":
						id := event.ID
						ob.ContainerStarted(id)
					case "die":
						id := event.ID
						ob.ContainerDied(id)
					}
				}
				Log.Errorf("[docker] Event listener channel closed - retrying subscription in %ds", retryInterval/time.Second)
			}
			time.Sleep(retryInterval)
			retryInterval = retryInterval * 3 / 2
			if retryInterval > MaxInterval {
				retryInterval = MaxInterval
			}
		}
	}()
	return nil
}

// IsContainerNotRunning returns true if we have checked with Docker that the ID is not running
func (c *Client) IsContainerNotRunning(idStr string) bool {
	container, err := c.InspectContainer(idStr)
	if err == nil {
		return !container.State.Running || container.State.Restarting
	}
	if _, notThere := err.(*docker.NoSuchContainer); notThere {
		return true
	}
	Log.Errorf("[docker] Could not check container status: %s", err)
	return false
}

// This is intended to find an IP address that we can reach the container on;
// if it is on the Docker bridge network then that address; if on the host network
// then localhost
func (c *Client) GetContainerIP(nameOrID string) (string, error) {
	Log.Debugf("Getting IP for container %s", nameOrID)
	info, err := c.InspectContainer(nameOrID)
	if err != nil {
		return "", err
	}
	if info.NetworkSettings.Networks != nil {
		Log.Debugln("Networks: ", info.NetworkSettings.Networks)
		if bridgeNetwork, ok := info.NetworkSettings.Networks["bridge"]; ok {
			return bridgeNetwork.IPAddress, nil
		} else if _, ok := info.NetworkSettings.Networks["host"]; ok {
			return "127.0.0.1", nil
		}
	} else if info.HostConfig.NetworkMode == "host" {
		return "127.0.0.1", nil
	}
	if info.NetworkSettings.IPAddress == "" {
		return "", errors.New("No IP address found for container " + nameOrID)
	}
	return info.NetworkSettings.IPAddress, nil
}
<commit_msg>Reset retry interval if we spent long enough processing events<commit_after>package docker

import (
	"errors"
	"fmt"
	"strings"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	. "github.com/weaveworks/weave/common"
)

const (
	InitialInterval = 1 * time.Second
	MaxInterval     = 60 * time.Second
)

// An observer for container events
type ContainerObserver interface {
	ContainerStarted(ident string)
	ContainerDied(ident string)
}

type Client struct {
	*docker.Client
}

// NewClient creates a new Docker client and checks we can talk to Docker
func NewClient(apiPath string) (*Client, error) {
	if apiPath != "" && !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewClient(apiPath)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClient(apiPath string, apiVersionString string) (*Client, error) {
	if !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewVersionedClient(apiPath, apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClientFromEnv(apiVersionString string) (*Client, error) {
	dc, err := docker.NewVersionedClientFromEnv(apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func (c *Client) checkWorking() error {
	_, err := c.Version()
	return err
}

func (c *Client) Info() string {
	if env, err := c.Version(); err != nil {
		return fmt.Sprintf("Docker API error: %s", err)
	} else {
		return fmt.Sprintf("Docker API on %s: %v", c.Endpoint(), env)
	}
}

// AddObserver adds an observer for docker events
func (c *Client) AddObserver(ob ContainerObserver) error {
	go func() {
		retryInterval := InitialInterval
		for {
			events := make(chan *docker.APIEvents)
			if err := c.AddEventListener(events); err != nil {
				Log.Errorf("[docker] Unable to add listener to Docker API: %s - retrying in %ds", err, retryInterval/time.Second)
			} else {
				start := time.Now()
				for event := range events {
					switch event.Status {
					case "start":
						id := event.ID
						ob.ContainerStarted(id)
					case "die":
						id := event.ID
						ob.ContainerDied(id)
					}
				}
				if time.Since(start) > retryInterval {
					retryInterval = InitialInterval
				}
				Log.Errorf("[docker] Event listener channel closed - retrying subscription in %ds", retryInterval/time.Second)
			}
			time.Sleep(retryInterval)
			retryInterval = retryInterval * 3 / 2
			if retryInterval > MaxInterval {
				retryInterval = MaxInterval
			}
		}
	}()
	return nil
}

// IsContainerNotRunning returns true if we have checked with Docker that the ID is not running
func (c *Client) IsContainerNotRunning(idStr string) bool {
	container, err := c.InspectContainer(idStr)
	if err == nil {
		return !container.State.Running || container.State.Restarting
	}
	if _, notThere := err.(*docker.NoSuchContainer); notThere {
		return true
	}
	Log.Errorf("[docker] Could not check container status: %s", err)
	return false
}

// This is intended to find an IP address that we can reach the container on;
// if it is on the Docker bridge network then that address; if on the host network
// then localhost
func (c *Client) GetContainerIP(nameOrID string) (string, error) {
	Log.Debugf("Getting IP for container %s", nameOrID)
	info, err := c.InspectContainer(nameOrID)
	if err != nil {
		return "", err
	}
	if info.NetworkSettings.Networks != nil {
		Log.Debugln("Networks: ", info.NetworkSettings.Networks)
		if bridgeNetwork, ok := info.NetworkSettings.Networks["bridge"]; ok {
			return bridgeNetwork.IPAddress, nil
		} else if _, ok := info.NetworkSettings.Networks["host"]; ok {
			return "127.0.0.1", nil
		}
	} else if info.HostConfig.NetworkMode == "host" {
		return "127.0.0.1", nil
	}
	if info.NetworkSettings.IPAddress == "" {
		return "", errors.New("No IP address found for container " + nameOrID)
	}
	return info.NetworkSettings.IPAddress, nil
}
<|endoftext|>


<commit_before>package mysql

import (
	"encoding/binary"
	"fmt"
	"math"
	"strconv"

	"github.com/wandoulabs/cm/hack"
)

type RowData []byte
type Value interface{}
type RowValue []Value

func Raw(t byte, val Value, isUnsigned bool) []byte {
	var ret []byte
	switch t {
	case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,
		MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR:
		if isUnsigned {
			ret = []byte(strconv.FormatUint(val.(uint64), 10))
		} else {
			ret = []byte(strconv.FormatInt(val.(int64), 10))
		}

	case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE:
		ret = []byte(strconv.FormatFloat(val.(float64), 'f', 7, 10))
	default:
		ret = val.([]byte)
	}
	return ret
}

func (p RowData) Parse(f []*Field, binary bool) ([]Value, error) {
	if binary {
		return p.ParseBinary(f)
	} else {
		return p.ParseText(f)
	}
}

func (p RowData) ParseText(f []*Field) ([]Value, error) {
	data := make([]Value, len(f))

	var err error
	var v []byte
	var isNull, isUnsigned bool
	var pos int = 0
	var n int = 0

	for i := range f {
		v, isNull, n, err = LengthEnodedString(p[pos:])
		if err != nil {
			return nil, err
		}

		pos += n

		if isNull {
			data[i] = nil
		} else {
			isUnsigned = (f[i].Flag&UNSIGNED_FLAG > 0)

			switch f[i].Type {
			case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,
				MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR:
				if isUnsigned {
					data[i], err = strconv.ParseUint(string(v), 10, 64)
				} else {
					data[i], err = strconv.ParseInt(string(v), 10, 64)
				}
			case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE:
				data[i], err = strconv.ParseFloat(string(v), 64)
			default:
				data[i] = v
			}

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

	return data, nil
}

func (p RowData) ParseBinary(f []*Field) ([]Value, error) {
	data := make([]Value, len(f))

	if p[0] != OK_HEADER {
		return nil, ErrMalformPacket
	}

	pos := 1 + ((len(f) + 7 + 2) >> 3)

	nullBitmap := p[1:pos]

	var isUnsigned bool
	var isNull bool
	var n int
	var err error
	var v []byte
	for i := range data {
		if nullBitmap[(i+2)/8]&(1<<(uint(i+2)%8)) > 0 {
			data[i] = nil
			continue
		}

		isUnsigned = f[i].Flag&UNSIGNED_FLAG > 0

		switch f[i].Type {
		case MYSQL_TYPE_NULL:
			data[i] = nil
			continue

		case MYSQL_TYPE_TINY:
			if isUnsigned {
				data[i] = uint64(p[pos])
			} else {
				data[i] = int64(p[pos])
			}
			pos++
			continue

		case MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR:
			if isUnsigned {
				data[i] = uint64(binary.LittleEndian.Uint16(p[pos : pos+2]))
			} else {
				data[i] = int64((binary.LittleEndian.Uint16(p[pos : pos+2])))
			}
			pos += 2
			continue

		case MYSQL_TYPE_INT24, MYSQL_TYPE_LONG:
			if isUnsigned {
				data[i] = uint64(binary.LittleEndian.Uint32(p[pos : pos+4]))
			} else {
				data[i] = int64(binary.LittleEndian.Uint32(p[pos : pos+4]))
			}
			pos += 4
			continue

		case MYSQL_TYPE_LONGLONG:
			if isUnsigned {
				data[i] = binary.LittleEndian.Uint64(p[pos : pos+8])
			} else {
				data[i] = int64(binary.LittleEndian.Uint64(p[pos : pos+8]))
			}
			pos += 8
			continue

		case MYSQL_TYPE_FLOAT:
			data[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(p[pos : pos+4])))
			pos += 4
			continue

		case MYSQL_TYPE_DOUBLE:
			data[i] = math.Float64frombits(binary.LittleEndian.Uint64(p[pos : pos+8]))
			pos += 8
			continue

		case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR,
			MYSQL_TYPE_BIT, MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB,
			MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
			MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY:
			v, isNull, n, err = LengthEnodedString(p[pos:])
			pos += n
			if err != nil {
				return nil, err
			}

			if !isNull {
				data[i] = v
				continue
			} else {
				data[i] = nil
				continue
			}
		case MYSQL_TYPE_DATE, MYSQL_TYPE_NEWDATE:
			var num uint64
			num, isNull, n = LengthEncodedInt(p[pos:])

			pos += n

			if isNull {
				data[i] = nil
				continue
			}

			data[i], err = FormatBinaryDate(int(num), p[pos:])
			pos += int(num)

			if err != nil {
				return nil, err
			}

		case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME:
			var num uint64
			num, isNull, n = LengthEncodedInt(p[pos:])

			pos += n

			if isNull {
				data[i] = nil
				continue
			}

			data[i], err = FormatBinaryDateTime(int(num), p[pos:])
			pos += int(num)

			if err != nil {
				return nil, err
			}

		case MYSQL_TYPE_TIME:
			var num uint64
			num, isNull, n = LengthEncodedInt(p[pos:])

			pos += n

			if isNull {
				data[i] = nil
				continue
			}

			data[i], err = FormatBinaryTime(int(num), p[pos:])
			pos += int(num)

			if err != nil {
				return nil, err
			}

		default:
			return nil, fmt.Errorf("Stmt Unknown FieldType %d %s", f[i].Type, f[i].Name)
		}
	}

	return data, nil
}

type Resultset struct {
	Fields     []*Field
	FieldNames map[string]int
	Values     []RowValue

	RowDatas []RowData
}

func (r *Resultset) RowNumber() int {
	return len(r.Values)
}

func (r *Resultset) ColumnNumber() int {
	return len(r.Fields)
}

func (r *Resultset) GetValue(row, column int) (interface{}, error) {
	if row >= len(r.Values) || row < 0 {
		return nil, fmt.Errorf("invalid row index %d", row)
	}

	if column >= len(r.Fields) || column < 0 {
		return nil, fmt.Errorf("invalid column index %d", column)
	}

	return r.Values[row][column], nil
}

func (r *Resultset) NameIndex(name string) (int, error) {
	if column, ok := r.FieldNames[name]; ok {
		return column, nil
	} else {
		return 0, fmt.Errorf("invalid field name %s", name)
	}
}

func (r *Resultset) GetValueByName(row int, name string) (interface{}, error) {
	if column, err := r.NameIndex(name); err != nil {
		return nil, err
	} else {
		return r.GetValue(row, column)
	}
}

func (r *Resultset) IsNull(row, column int) (bool, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return false, err
	}

	return d == nil, nil
}

func (r *Resultset) IsNullByName(row int, name string) (bool, error) {
	if column, err := r.NameIndex(name); err != nil {
		return false, err
	} else {
		return r.IsNull(row, column)
	}
}

func (r *Resultset) GetUint(row, column int) (uint64, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return 0, err
	}

	switch v := d.(type) {
	case uint64:
		return v, nil
	case int64:
		return uint64(v), nil
	case float64:
		return uint64(v), nil
	case string:
		return strconv.ParseUint(v, 10, 64)
	case []byte:
		return strconv.ParseUint(string(v), 10, 64)
	case nil:
		return 0, nil
	default:
		return 0, fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetUintByName(row int, name string) (uint64, error) {
	if column, err := r.NameIndex(name); err != nil {
		return 0, err
	} else {
		return r.GetUint(row, column)
	}
}

func (r *Resultset) GetInt(row, column int) (int64, error) {
	v, err := r.GetUint(row, column)
	if err != nil {
		return 0, err
	}

	return int64(v), nil
}

func (r *Resultset) GetIntByName(row int, name string) (int64, error) {
	v, err := r.GetUintByName(row, name)
	if err != nil {
		return 0, err
	}

	return int64(v), nil
}

func (r *Resultset) GetFloat(row, column int) (float64, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return 0, err
	}

	switch v := d.(type) {
	case float64:
		return v, nil
	case uint64:
		return float64(v), nil
	case int64:
		return float64(v), nil
	case string:
		return strconv.ParseFloat(v, 64)
	case []byte:
		return strconv.ParseFloat(string(v), 64)
	case nil:
		return 0, nil
	default:
		return 0, fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetFloatByName(row int, name string) (float64, error) {
	if column, err := r.NameIndex(name); err != nil {
		return 0, err
	} else {
		return r.GetFloat(row, column)
	}
}

func (r *Resultset) GetString(row, column int) (string, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return "", err
	}

	switch v := d.(type) {
	case string:
		return v, nil
	case []byte:
		return hack.String(v), nil
	case int64:
		return strconv.FormatInt(v, 10), nil
	case uint64:
		return strconv.FormatUint(v, 10), nil
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64), nil
	case nil:
		return "", nil
	default:
		return "", fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetStringByName(row int, name string) (string, error) {
	if column, err := r.NameIndex(name); err != nil {
		return "", err
	} else {
		return r.GetString(row, column)
	}
}
<commit_msg>fix bug<commit_after>package mysql

import (
	"fmt"
	"strconv"

	"github.com/wandoulabs/cm/hack"
)

type RowData []byte
type Value interface{}
type RowValue []Value

func Raw(t byte, val Value, isUnsigned bool) []byte {
	var ret []byte
	switch t {
	case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,
		MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR:
		if isUnsigned {
			ret = []byte(strconv.FormatUint(val.(uint64), 10))
		} else {
			ret = []byte(strconv.FormatInt(val.(int64), 10))
		}

	case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE:
		ret = []byte(strconv.FormatFloat(val.(float64), 'f', 7, 10))
	default:
		ret = val.([]byte)
	}
	return ret
}

func (p RowData) Parse(f []*Field, binary bool) (RowValue, error) {
	return p.ParseText(f)
}

func (p RowData) ParseText(f []*Field) (RowValue, error) {
	data := make([]Value, len(f))

	var err error
	var v []byte
	var isNull, isUnsigned bool
	var pos int = 0
	var n int = 0

	for i := range f {
		v, isNull, n, err = LengthEnodedString(p[pos:])
		if err != nil {
			return nil, err
		}

		pos += n

		if isNull {
			data[i] = nil
		} else {
			isUnsigned = (f[i].Flag&UNSIGNED_FLAG > 0)

			switch f[i].Type {
			case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,
				MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR:
				if isUnsigned {
					data[i], err = strconv.ParseUint(string(v), 10, 64)
				} else {
					data[i], err = strconv.ParseInt(string(v), 10, 64)
				}
			case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE:
				data[i], err = strconv.ParseFloat(string(v), 64)
			default:
				data[i] = v
			}

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

	return data, nil
}

type Resultset struct {
	Fields     []*Field
	FieldNames map[string]int
	Values     []RowValue

	RowDatas []RowData
}

func (r *Resultset) RowNumber() int {
	return len(r.Values)
}

func (r *Resultset) ColumnNumber() int {
	return len(r.Fields)
}

func (r *Resultset) GetValue(row, column int) (interface{}, error) {
	if row >= len(r.Values) || row < 0 {
		return nil, fmt.Errorf("invalid row index %d", row)
	}

	if column >= len(r.Fields) || column < 0 {
		return nil, fmt.Errorf("invalid column index %d", column)
	}

	return r.Values[row][column], nil
}

func (r *Resultset) NameIndex(name string) (int, error) {
	if column, ok := r.FieldNames[name]; ok {
		return column, nil
	} else {
		return 0, fmt.Errorf("invalid field name %s", name)
	}
}

func (r *Resultset) GetValueByName(row int, name string) (interface{}, error) {
	if column, err := r.NameIndex(name); err != nil {
		return nil, err
	} else {
		return r.GetValue(row, column)
	}
}

func (r *Resultset) IsNull(row, column int) (bool, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return false, err
	}

	return d == nil, nil
}

func (r *Resultset) IsNullByName(row int, name string) (bool, error) {
	if column, err := r.NameIndex(name); err != nil {
		return false, err
	} else {
		return r.IsNull(row, column)
	}
}

func (r *Resultset) GetUint(row, column int) (uint64, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return 0, err
	}

	switch v := d.(type) {
	case uint64:
		return v, nil
	case int64:
		return uint64(v), nil
	case float64:
		return uint64(v), nil
	case string:
		return strconv.ParseUint(v, 10, 64)
	case []byte:
		return strconv.ParseUint(string(v), 10, 64)
	case nil:
		return 0, nil
	default:
		return 0, fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetUintByName(row int, name string) (uint64, error) {
	if column, err := r.NameIndex(name); err != nil {
		return 0, err
	} else {
		return r.GetUint(row, column)
	}
}

func (r *Resultset) GetInt(row, column int) (int64, error) {
	v, err := r.GetUint(row, column)
	if err != nil {
		return 0, err
	}

	return int64(v), nil
}

func (r *Resultset) GetIntByName(row int, name string) (int64, error) {
	v, err := r.GetUintByName(row, name)
	if err != nil {
		return 0, err
	}

	return int64(v), nil
}

func (r *Resultset) GetFloat(row, column int) (float64, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return 0, err
	}

	switch v := d.(type) {
	case float64:
		return v, nil
	case uint64:
		return float64(v), nil
	case int64:
		return float64(v), nil
	case string:
		return strconv.ParseFloat(v, 64)
	case []byte:
		return strconv.ParseFloat(string(v), 64)
	case nil:
		return 0, nil
	default:
		return 0, fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetFloatByName(row int, name string) (float64, error) {
	if column, err := r.NameIndex(name); err != nil {
		return 0, err
	} else {
		return r.GetFloat(row, column)
	}
}

func (r *Resultset) GetString(row, column int) (string, error) {
	d, err := r.GetValue(row, column)
	if err != nil {
		return "", err
	}

	switch v := d.(type) {
	case string:
		return v, nil
	case []byte:
		return hack.String(v), nil
	case int64:
		return strconv.FormatInt(v, 10), nil
	case uint64:
		return strconv.FormatUint(v, 10), nil
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64), nil
	case nil:
		return "", nil
	default:
		return "", fmt.Errorf("data type is %T", v)
	}
}

func (r *Resultset) GetStringByName(row int, name string) (string, error) {
	if column, err := r.NameIndex(name); err != nil {
		return "", err
	} else {
		return r.GetString(row, column)
	}
}
<|endoftext|>


<commit_before>package command

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"

	"github.com/hashicorp/vault/api"
	"github.com/hashicorp/vault/helper/kv-builder"
	"github.com/hashicorp/vault/helper/password"
	"github.com/mitchellh/mapstructure"
	"github.com/ryanuber/columnize"
)

// AuthHandler is the interface that any auth handlers must implement
// to enable auth via the CLI.
type AuthHandler interface {
	Auth(*api.Client, map[string]string) (string, error)
	Help() string
}

// AuthCommand is a Command that handles authentication.
type AuthCommand struct {
	Meta

	Handlers map[string]AuthHandler

	// The fields below can be overwritten for tests
	testStdin io.Reader
}

func (c *AuthCommand) Run(args []string) int {
	var format string
	var method string
	var methods, methodHelp, noVerify bool
	flags := c.Meta.FlagSet("auth", FlagSetDefault)
	flags.BoolVar(&methods, "methods", false, "")
	flags.BoolVar(&methodHelp, "method-help", false, "")
	flags.BoolVar(&noVerify, "no-verify", false, "")
	flags.StringVar(&method, "method", "", "method")
	flags.StringVar(&format, "format", "table", "")
	flags.Usage = func() { c.Ui.Error(c.Help()) }
	if err := flags.Parse(args); err != nil {
		return 1
	}

	if methods {
		return c.listMethods()
	}

	args = flags.Args()

	tokenHelper, err := c.TokenHelper()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing token helper: %s\n\n"+
				"Please verify that the token helper is available and properly\n"+
				"configured for your system. Please refer to the documentation\n"+
				"on token helpers for more information.",
			err))
		return 1
	}

	// token is where the final token will go
	handler := c.Handlers[method]

	// Read token from stdin if first arg is exactly "-"
	var stdin io.Reader = os.Stdin
	if c.testStdin != nil {
		stdin = c.testStdin
	}

	if len(args) > 0 && args[0] == "-" {
		stdinR := bufio.NewReader(stdin)
		args[0], err = stdinR.ReadString('\n')
		if err != nil && err != io.EOF {
			c.Ui.Error(fmt.Sprintf("Error reading from stdin: %s", err))
			return 1
		}
		args[0] = strings.TrimSpace(args[0])
	}

	if method == "" {
		token := ""
		if len(args) > 0 {
			token = args[0]
		}

		handler = &tokenAuthHandler{Token: token}
		args = nil
	}

	if handler == nil {
		methods := make([]string, 0, len(c.Handlers))
		for k := range c.Handlers {
			methods = append(methods, k)
		}
		sort.Strings(methods)

		c.Ui.Error(fmt.Sprintf(
			"Unknown authentication method: %s\n\n"+
				"Please use a supported authentication method. The list of supported\n"+
				"authentication methods is shown below. Note that this list may not\n"+
				"be exhaustive: Vault may support other auth methods. For auth methods\n"+
				"unsupported by the CLI, please use the HTTP API.\n\n"+
				"%s",
			method,
			strings.Join(methods, ", ")))
		return 1
	}

	if methodHelp {
		c.Ui.Output(handler.Help())
		return 0
	}

	// Warn if the VAULT_TOKEN environment variable is set, as that will take
	// precedence
	if os.Getenv("VAULT_TOKEN") != "" {
		c.Ui.Output("==> WARNING: VAULT_TOKEN environment variable set!\n")
		c.Ui.Output("  The environment variable takes precedence over the value")
		c.Ui.Output("  set by the auth command. Either update the value of the")
		c.Ui.Output("  environment variable or unset it to use the new token.\n")
	}

	var vars map[string]string
	if len(args) > 0 {
		builder := kvbuilder.Builder{Stdin: os.Stdin}
		if err := builder.Add(args...); err != nil {
			c.Ui.Error(err.Error())
			return 1
		}

		if err := mapstructure.Decode(builder.Map(), &vars); err != nil {
			c.Ui.Error(fmt.Sprintf("Error parsing options: %s", err))
			return 1
		}
	}

	// Build the client so we can auth
	client, err := c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client to auth: %s", err))
		return 1
	}

	// Authenticate
	token, err := handler.Auth(client, vars)
	if err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	// Store the token!
	if err := tokenHelper.Store(token); err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error storing token: %s\n\n"+
				"Authentication was not successful and did not persist.\n"+
				"Please reauthenticate, or fix the issue above if possible.",
			err))
		return 1
	}

	// Build the client again so it can read the token we just wrote
	client, err = c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client to verify the token: %s", err))
		return 1
	}

	if noVerify {
		c.Ui.Output(fmt.Sprintf(
			"Authenticated - no token verification has been performed.",
		))

		return 0
	}

	// Verify the token
	secret, err := client.Logical().Read("auth/token/lookup-self")
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error validating token: %s", err))
		return 1
	}
	if secret == nil {
		c.Ui.Error(fmt.Sprintf("Error: Invalid token"))
		return 1
	}

	// Get the policies we have
	policiesRaw, ok := secret.Data["policies"]
	if !ok {
		policiesRaw = []string{"unknown"}
	}
	var policies []string
	for _, v := range policiesRaw.([]interface{}) {
		policies = append(policies, v.(string))
	}

	output := "Successfully authenticated!"
	output += fmt.Sprintf("\ntoken: %s", secret.Data["id"])
	output += fmt.Sprintf("\ntoken_duration: %d", int(secret.Data["ttl"].(float64)))
	if len(policies) > 0 {
		output += fmt.Sprintf("\ntoken_policies: [%s]", strings.Join(policies, ", "))
	}

	c.Ui.Output(output)

	return 0
}

func (c *AuthCommand) listMethods() int {
	client, err := c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client: %s", err))
		return 1
	}

	auth, err := client.Sys().ListAuth()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error reading auth table: %s", err))
		return 1
	}

	paths := make([]string, 0, len(auth))
	for path := range auth {
		paths = append(paths, path)
	}
	sort.Strings(paths)

	columns := []string{"Path | Type | Description"}
	for _, k := range paths {
		a := auth[k]
		columns = append(columns, fmt.Sprintf(
			"%s | %s | %s", k, a.Type, a.Description))
	}

	c.Ui.Output(columnize.SimpleFormat(columns))
	return 0
}

func (c *AuthCommand) Synopsis() string {
	return "Prints information about how to authenticate with Vault"
}

func (c *AuthCommand) Help() string {
	helpText := `
Usage: vault auth [options] [token or config...]

  Authenticate with Vault with the given token or via any supported
  authentication backend.

  If no -method is specified, then the token is expected. If it is not
  given on the command-line, it will be asked via user input. If the
  token is "-", it will be read from stdin.

  By specifying -method, alternate authentication methods can be used
  such as OAuth or TLS certificates. For these, additional values for
  configuration can be specified with "key=value" pairs just like
  "vault write". Specify the "-method-help" flag to get help for a specific
  method.

  If you've mounted a credential backend to a different path, such
  as mounting "github" to "github-private", the "method" flag should
  still be "github." Most credential providers support the "mount" option
  to specify the mount point. See the "-method-help" for more info.

General Options:

  ` + generalOptionsUsage() + `

Auth Options:

  -method=name      Outputs help for the authentication method with the given
                    name for the remote server. If this authentication method
                    is not available, exit with code 1.

  -method-help      If set, the help for the selected method will be shown.

  -methods          List the available auth methods.

  -no-verify        Do not verify the token after creation; avoids a use count
                    decrement.

`
	return strings.TrimSpace(helpText)
}

// tokenAuthHandler handles retrieving the token from the command-line.
type tokenAuthHandler struct {
	Token string
}

func (h *tokenAuthHandler) Auth(*api.Client, map[string]string) (string, error) {
	token := h.Token
	if token == "" {
		var err error

		// No arguments given, read the token from user input
		fmt.Printf("Token (will be hidden): ")
		token, err = password.Read(os.Stdin)
		fmt.Printf("\n")
		if err != nil {
			return "", fmt.Errorf(
				"Error attempting to ask for token. The raw error message\n"+
					"is shown below, but the most common reason for this error is\n"+
					"that you attempted to pipe a value into auth. If you want to\n"+
					"pipe the token, please pass '-' as the token argument.\n\n"+
					"Raw error: %s", err)
		}
	}

	if token == "" {
		return "", fmt.Errorf(
			"A token must be passed to auth. Please view the help\n" +
				"for more information.")
	}

	return token, nil
}

func (h *tokenAuthHandler) Help() string {
	help := `
No method selected with the "-method" flag, so the "auth" command assumes
you'll be using raw token authentication. For this, specify the token to
authenticate as as the parameter to "vault auth". Example:

    vault auth 123456

The token used to authenticate must come from some other source. A root
token is created when Vault is first initialized. After that, subsequent
tokens are created via the API or command line interface (with the
"token"-prefixed commands).
`

	return strings.TrimSpace(help)
}
<commit_msg>Remove format parameter<commit_after>package command

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"

	"github.com/hashicorp/vault/api"
	"github.com/hashicorp/vault/helper/kv-builder"
	"github.com/hashicorp/vault/helper/password"
	"github.com/mitchellh/mapstructure"
	"github.com/ryanuber/columnize"
)

// AuthHandler is the interface that any auth handlers must implement
// to enable auth via the CLI.
type AuthHandler interface {
	Auth(*api.Client, map[string]string) (string, error)
	Help() string
}

// AuthCommand is a Command that handles authentication.
type AuthCommand struct {
	Meta

	Handlers map[string]AuthHandler

	// The fields below can be overwritten for tests
	testStdin io.Reader
}

func (c *AuthCommand) Run(args []string) int {
	var method string
	var methods, methodHelp, noVerify bool
	flags := c.Meta.FlagSet("auth", FlagSetDefault)
	flags.BoolVar(&methods, "methods", false, "")
	flags.BoolVar(&methodHelp, "method-help", false, "")
	flags.BoolVar(&noVerify, "no-verify", false, "")
	flags.StringVar(&method, "method", "", "method")
	flags.Usage = func() { c.Ui.Error(c.Help()) }
	if err := flags.Parse(args); err != nil {
		return 1
	}

	if methods {
		return c.listMethods()
	}

	args = flags.Args()

	tokenHelper, err := c.TokenHelper()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing token helper: %s\n\n"+
				"Please verify that the token helper is available and properly\n"+
				"configured for your system. Please refer to the documentation\n"+
				"on token helpers for more information.",
			err))
		return 1
	}

	// token is where the final token will go
	handler := c.Handlers[method]

	// Read token from stdin if first arg is exactly "-"
	var stdin io.Reader = os.Stdin
	if c.testStdin != nil {
		stdin = c.testStdin
	}

	if len(args) > 0 && args[0] == "-" {
		stdinR := bufio.NewReader(stdin)
		args[0], err = stdinR.ReadString('\n')
		if err != nil && err != io.EOF {
			c.Ui.Error(fmt.Sprintf("Error reading from stdin: %s", err))
			return 1
		}
		args[0] = strings.TrimSpace(args[0])
	}

	if method == "" {
		token := ""
		if len(args) > 0 {
			token = args[0]
		}

		handler = &tokenAuthHandler{Token: token}
		args = nil
	}

	if handler == nil {
		methods := make([]string, 0, len(c.Handlers))
		for k := range c.Handlers {
			methods = append(methods, k)
		}
		sort.Strings(methods)

		c.Ui.Error(fmt.Sprintf(
			"Unknown authentication method: %s\n\n"+
				"Please use a supported authentication method. The list of supported\n"+
				"authentication methods is shown below. Note that this list may not\n"+
				"be exhaustive: Vault may support other auth methods. For auth methods\n"+
				"unsupported by the CLI, please use the HTTP API.\n\n"+
				"%s",
			method,
			strings.Join(methods, ", ")))
		return 1
	}

	if methodHelp {
		c.Ui.Output(handler.Help())
		return 0
	}

	// Warn if the VAULT_TOKEN environment variable is set, as that will take
	// precedence
	if os.Getenv("VAULT_TOKEN") != "" {
		c.Ui.Output("==> WARNING: VAULT_TOKEN environment variable set!\n")
		c.Ui.Output("  The environment variable takes precedence over the value")
		c.Ui.Output("  set by the auth command. Either update the value of the")
		c.Ui.Output("  environment variable or unset it to use the new token.\n")
	}

	var vars map[string]string
	if len(args) > 0 {
		builder := kvbuilder.Builder{Stdin: os.Stdin}
		if err := builder.Add(args...); err != nil {
			c.Ui.Error(err.Error())
			return 1
		}

		if err := mapstructure.Decode(builder.Map(), &vars); err != nil {
			c.Ui.Error(fmt.Sprintf("Error parsing options: %s", err))
			return 1
		}
	}

	// Build the client so we can auth
	client, err := c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client to auth: %s", err))
		return 1
	}

	// Authenticate
	token, err := handler.Auth(client, vars)
	if err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	// Store the token!
	if err := tokenHelper.Store(token); err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error storing token: %s\n\n"+
				"Authentication was not successful and did not persist.\n"+
				"Please reauthenticate, or fix the issue above if possible.",
			err))
		return 1
	}

	// Build the client again so it can read the token we just wrote
	client, err = c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client to verify the token: %s", err))
		return 1
	}

	if noVerify {
		c.Ui.Output(fmt.Sprintf(
			"Authenticated - no token verification has been performed.",
		))

		return 0
	}

	// Verify the token
	secret, err := client.Logical().Read("auth/token/lookup-self")
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error validating token: %s", err))
		return 1
	}
	if secret == nil {
		c.Ui.Error(fmt.Sprintf("Error: Invalid token"))
		return 1
	}

	// Get the policies we have
	policiesRaw, ok := secret.Data["policies"]
	if !ok {
		policiesRaw = []string{"unknown"}
	}
	var policies []string
	for _, v := range policiesRaw.([]interface{}) {
		policies = append(policies, v.(string))
	}

	output := "Successfully authenticated!"
	output += fmt.Sprintf("\ntoken: %s", secret.Data["id"])
	output += fmt.Sprintf("\ntoken_duration: %d", int(secret.Data["ttl"].(float64)))
	if len(policies) > 0 {
		output += fmt.Sprintf("\ntoken_policies: [%s]", strings.Join(policies, ", "))
	}

	c.Ui.Output(output)

	return 0
}

func (c *AuthCommand) listMethods() int {
	client, err := c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client: %s", err))
		return 1
	}

	auth, err := client.Sys().ListAuth()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error reading auth table: %s", err))
		return 1
	}

	paths := make([]string, 0, len(auth))
	for path := range auth {
		paths = append(paths, path)
	}
	sort.Strings(paths)

	columns := []string{"Path | Type | Description"}
	for _, k := range paths {
		a := auth[k]
		columns = append(columns, fmt.Sprintf(
			"%s | %s | %s", k, a.Type, a.Description))
	}

	c.Ui.Output(columnize.SimpleFormat(columns))
	return 0
}

func (c *AuthCommand) Synopsis() string {
	return "Prints information about how to authenticate with Vault"
}

func (c *AuthCommand) Help() string {
	helpText := `
Usage: vault auth [options] [token or config...]

  Authenticate with Vault with the given token or via any supported
  authentication backend.

  If no -method is specified, then the token is expected. If it is not
  given on the command-line, it will be asked via user input. If the
  token is "-", it will be read from stdin.

  By specifying -method, alternate authentication methods can be used
  such as OAuth or TLS certificates. For these, additional values for
  configuration can be specified with "key=value" pairs just like
  "vault write". Specify the "-method-help" flag to get help for a specific
  method.

  If you've mounted a credential backend to a different path, such
  as mounting "github" to "github-private", the "method" flag should
  still be "github." Most credential providers support the "mount" option
  to specify the mount point. See the "-method-help" for more info.

General Options:

  ` + generalOptionsUsage() + `

Auth Options:

  -method=name      Outputs help for the authentication method with the given
                    name for the remote server. If this authentication method
                    is not available, exit with code 1.

  -method-help      If set, the help for the selected method will be shown.

  -methods          List the available auth methods.

  -no-verify        Do not verify the token after creation; avoids a use count
                    decrement.

`
	return strings.TrimSpace(helpText)
}

// tokenAuthHandler handles retrieving the token from the command-line.
type tokenAuthHandler struct {
	Token string
}

func (h *tokenAuthHandler) Auth(*api.Client, map[string]string) (string, error) {
	token := h.Token
	if token == "" {
		var err error

		// No arguments given, read the token from user input
		fmt.Printf("Token (will be hidden): ")
		token, err = password.Read(os.Stdin)
		fmt.Printf("\n")
		if err != nil {
			return "", fmt.Errorf(
				"Error attempting to ask for token. The raw error message\n"+
					"is shown below, but the most common reason for this error is\n"+
					"that you attempted to pipe a value into auth. If you want to\n"+
					"pipe the token, please pass '-' as the token argument.\n\n"+
					"Raw error: %s", err)
		}
	}

	if token == "" {
		return "", fmt.Errorf(
			"A token must be passed to auth. Please view the help\n" +
				"for more information.")
	}

	return token, nil
}

func (h *tokenAuthHandler) Help() string {
	help := `
No method selected with the "-method" flag, so the "auth" command assumes
you'll be using raw token authentication. For this, specify the token to
authenticate as as the parameter to "vault auth". Example:

    vault auth 123456

The token used to authenticate must come from some other source. A root
token is created when Vault is first initialized. After that, subsequent
tokens are created via the API or command line interface (with the
"token"-prefixed commands).
`

	return strings.TrimSpace(help)
}
<|endoftext|>