<commit_before>package pan

import (
	"database/sql"
	"database/sql/driver"
	"strings"
	"sync/atomic"
)

// DB is a logical database with multiple underlying physical databases
// forming a single master multiple slaves topology.
// Reads and writes are automatically directed to the correct physical db.
type DB struct {
	pdbs  []*sql.DB // Physical databases
	count uint64    // Monotonically incrementing counter on each query
}

// Open constructs a DB struct by splitting dataSourceNames into multiple
// connection strings (separated by ';').
// For each connection string it creates a *sql.DB or returns an error if it fails.
// The first connection string is assumed to be the master
// while the rest are used for the slaves.
func Open(driverName, dataSourceNames string) (*DB, error) {
	conns := strings.Split(dataSourceNames, ";")
	db := &DB{pdbs: make([]*sql.DB, len(conns))}

	var err error
	for i, conn := range conns {
		if db.pdbs[i], err = sql.Open(driverName, conn); err != nil {
			return nil, err
		}
	}

	return db, nil
}

// Close closes all physical databases concurrently, releasing any open resources.
func (db *DB) Close() error {
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) { errors <- db.pdbs[i].Close() }(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return err
		}
	}

	return nil
}

// Driver returns the physical database's underlying driver.
func (db *DB) Driver() driver.Driver {
	return db.pdbs[0].Driver()
}

// Begin starts a transaction on the master. The isolation level is dependent on the driver.
func (db *DB) Begin() (*sql.Tx, error) {
	return db.pdbs[0].Begin()
}

// Exec executes a query without returning any rows.
// The args are for any placeholder parameters in the query.
// Exec uses the master as the underlying physical db.
func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
	return db.pdbs[0].Exec(query, args...)
}

// Ping verifies if a connection to each physical database is still alive,
// establishing a connection if necessary.
func (db *DB) Ping() error {
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) { errors <- db.pdbs[i].Ping() }(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return err
		}
	}

	return nil
}

// Prepare creates a prepared statement for later queries or executions
// on each physical database, concurrently.
func (db *DB) Prepare(query string) (*Stmt, error) {
	stmts := make([]*sql.Stmt, len(db.pdbs))
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) {
			var err error
			stmts[i], err = db.pdbs[i].Prepare(query)
			errors <- err
		}(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return nil, err
		}
	}

	return &Stmt{DB: db, stmts: stmts}, nil
}

// Query executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
// Query uses a slave as the physical db.
func (db *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
	return db.pdbs[db.slave(len(db.pdbs))].Query(query, args...)
}

// QueryRow executes a query that is expected to return at most one row.
// QueryRow always return a non-nil value.
// Errors are deferred until Row's Scan method is called.
// QueryRow uses a slave as the physical db.
func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row {
	return db.pdbs[db.slave(len(db.pdbs))].QueryRow(query, args...)
}

// SetMaxIdleConns sets the maximum number of connections in the idle
// connection pool for each underlying physical db.
// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns then the
// new MaxIdleConns will be reduced to match the MaxOpenConns limit
// If n <= 0, no idle connections are retained.
func (db *DB) SetMaxIdleConns(n int) {
	for i := range db.pdbs {
		db.pdbs[i].SetMaxIdleConns(n)
	}
}

// SetMaxOpenConns sets the maximum number of open connections
// to each physical database.
// If MaxIdleConns is greater than 0 and the new MaxOpenConns
// is less than MaxIdleConns, then MaxIdleConns will be reduced to match
// the new MaxOpenConns limit. If n <= 0, then there is no limit on the number
// of open connections. The default is 0 (unlimited).
func (db *DB) SetMaxOpenConns(n int) {
  for i := range db.pdbs {
    db.pdbs[i].SetMaxOpenConns(n)
  }
}

// Slave returns one of the physical databases which is a slave
func (db *DB) Slave() *sql.DB {
	return db.pdbs[db.slave(len(db.pdbs))]
}

// Master returns the master physical database
func (db *DB) Master() *sql.DB {
	return db.pdbs[0]
}

func (db *DB) slave(n int) int {
	if n <= 1 {
		return 0
	}
	return int(1 + (atomic.AddUint64(&db.count, 1) % uint64(n-1)))
}
<commit_msg>Go fmt<commit_after>package pan

import (
	"database/sql"
	"database/sql/driver"
	"strings"
	"sync/atomic"
)

// DB is a logical database with multiple underlying physical databases
// forming a single master multiple slaves topology.
// Reads and writes are automatically directed to the correct physical db.
type DB struct {
	pdbs  []*sql.DB // Physical databases
	count uint64    // Monotonically incrementing counter on each query
}

// Open constructs a DB struct by splitting dataSourceNames into multiple
// connection strings (separated by ';').
// For each connection string it creates a *sql.DB or returns an error if it fails.
// The first connection string is assumed to be the master
// while the rest are used for the slaves.
func Open(driverName, dataSourceNames string) (*DB, error) {
	conns := strings.Split(dataSourceNames, ";")
	db := &DB{pdbs: make([]*sql.DB, len(conns))}

	var err error
	for i, conn := range conns {
		if db.pdbs[i], err = sql.Open(driverName, conn); err != nil {
			return nil, err
		}
	}

	return db, nil
}

// Close closes all physical databases concurrently, releasing any open resources.
func (db *DB) Close() error {
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) { errors <- db.pdbs[i].Close() }(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return err
		}
	}

	return nil
}

// Driver returns the physical database's underlying driver.
func (db *DB) Driver() driver.Driver {
	return db.pdbs[0].Driver()
}

// Begin starts a transaction on the master. The isolation level is dependent on the driver.
func (db *DB) Begin() (*sql.Tx, error) {
	return db.pdbs[0].Begin()
}

// Exec executes a query without returning any rows.
// The args are for any placeholder parameters in the query.
// Exec uses the master as the underlying physical db.
func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
	return db.pdbs[0].Exec(query, args...)
}

// Ping verifies if a connection to each physical database is still alive,
// establishing a connection if necessary.
func (db *DB) Ping() error {
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) { errors <- db.pdbs[i].Ping() }(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return err
		}
	}

	return nil
}

// Prepare creates a prepared statement for later queries or executions
// on each physical database, concurrently.
func (db *DB) Prepare(query string) (*Stmt, error) {
	stmts := make([]*sql.Stmt, len(db.pdbs))
	errors := make(chan error, len(db.pdbs))

	for i := range db.pdbs {
		go func(i int) {
			var err error
			stmts[i], err = db.pdbs[i].Prepare(query)
			errors <- err
		}(i)
	}

	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil {
			return nil, err
		}
	}

	return &Stmt{DB: db, stmts: stmts}, nil
}

// Query executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
// Query uses a slave as the physical db.
func (db *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
	return db.pdbs[db.slave(len(db.pdbs))].Query(query, args...)
}

// QueryRow executes a query that is expected to return at most one row.
// QueryRow always return a non-nil value.
// Errors are deferred until Row's Scan method is called.
// QueryRow uses a slave as the physical db.
func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row {
	return db.pdbs[db.slave(len(db.pdbs))].QueryRow(query, args...)
}

// SetMaxIdleConns sets the maximum number of connections in the idle
// connection pool for each underlying physical db.
// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns then the
// new MaxIdleConns will be reduced to match the MaxOpenConns limit
// If n <= 0, no idle connections are retained.
func (db *DB) SetMaxIdleConns(n int) {
	for i := range db.pdbs {
		db.pdbs[i].SetMaxIdleConns(n)
	}
}

// SetMaxOpenConns sets the maximum number of open connections
// to each physical database.
// If MaxIdleConns is greater than 0 and the new MaxOpenConns
// is less than MaxIdleConns, then MaxIdleConns will be reduced to match
// the new MaxOpenConns limit. If n <= 0, then there is no limit on the number
// of open connections. The default is 0 (unlimited).
func (db *DB) SetMaxOpenConns(n int) {
	for i := range db.pdbs {
		db.pdbs[i].SetMaxOpenConns(n)
	}
}

// Slave returns one of the physical databases which is a slave
func (db *DB) Slave() *sql.DB {
	return db.pdbs[db.slave(len(db.pdbs))]
}

// Master returns the master physical database
func (db *DB) Master() *sql.DB {
	return db.pdbs[0]
}

func (db *DB) slave(n int) int {
	if n <= 1 {
		return 0
	}
	return int(1 + (atomic.AddUint64(&db.count, 1) % uint64(n-1)))
}
<|endoftext|>


<commit_before>package genfs

import (
	"bytes"
	"errors"
	"io"
	"net/http"
	"os"
	"path"
	"time"
)

// NewFS returns a new FS for the given files.
func NewFS(files ...*File) *FS {
	fs := &FS{
		l: make([]*File, len(files)),
		m: make(map[string]*File, len(files)),
	}
	for i, file := range files {
		// Clone file so that the same file can be used with multiple FS instances.
		clone := &File{}
		*clone = *file
		clone.fs = fs
		fs.m[file.path] = clone
		fs.l[i] = clone
	}
	return fs
}

// Dir returns a new FS for the given path.
func Dir(path string) (*FS, error) {
	files, err := Files(path, FilterNone)
	if err != nil {
		return nil, err
	}
	return NewFS(files...), nil
}

// FS is an in-memory file system that implements http.FileSystem.
type FS struct {
	m map[string]*File
	l []*File
}

// check interface compliance
var _ = http.FileSystem(&FS{})

// Open is part of http.FileSystem.
func (f *FS) Open(name string) (http.File, error) {
	name = path.Clean(name)
	file := f.m[name]
	if file == nil {
		// @TODO Path error?
		return nil, os.ErrNotExist
	}
	// Return a clone so that concurrently opened files can have their own read
	// state.
	clone := &File{}
	*clone = *file
	clone.Reader = bytes.NewReader(clone.data)
	return clone, nil
}

// NewFile returns a new in-memory file with the given properties.
func NewFile(path, name string, size int64, mode os.FileMode, t time.Time, isDir bool, data []byte) *File {
	return &File{
		path:    path,
		name:    name,
		size:    size,
		mode:    mode,
		modTime: t,
		isDir:   isDir,
		data:    data,
		Reader:  bytes.NewReader(data),
	}
}

// File is an in-memory file that implements http.File and os.FileInfo.
type File struct {
	io.Reader

	path    string
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	isDir   bool
	data    []byte

	fs *FS
}

// check interface compliance
var _ = os.FileInfo(&File{})
var _ = http.File(&File{})

// Close is part of http.File.
func (f *File) Close() error {
	// @TODO return err when closing twice?
	return nil
}

// Seek is part of http.File.
func (f *File) Seek(offset int64, whence int) (int64, error) {
	// @TODO(fg) implement
	return 0, nil
}

// Stat is part of http.File.
func (f *File) Stat() (os.FileInfo, error) {
	// @TODO(fg) implement
	return f, nil
}

// Readdir is part of http.File.
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
	// @TODO(fg) support full Readdir semantics, including EOF, etc.
	if count <= 0 {
		return nil, errors.New("genfs: only count <= 0 is supported right now")
	}
	var files []os.FileInfo
	// TODO(fg) make this faster using binary search or a tree structure
	for _, file := range f.fs.l {
		if path.Clean(path.Join(f.path, file.name)) == file.path {
			files = append(files, file)
		}
	}
	return files, nil
}

// IsDir is part of os.FileInfo.
func (f *File) IsDir() bool { return f.isDir }

// ModTime is part of os.FileInfo.
func (f *File) ModTime() time.Time { return f.modTime }

// Mode is part of os.FileInfo.
func (f *File) Mode() os.FileMode { return f.mode }

// Name is part of os.FileInfo.
func (f *File) Name() string { return f.name }

// Size is part of os.FileInfo.
func (f *File) Size() int64 { return f.size }

// Sys is part of os.FileInfo.
func (f *File) Sys() interface{} { return nil }

// Path returns the path of the file. It's needed for WriteSource.
func (f *File) Path() string { return f.path }

// String returns the file data as a string. It's needed for WriteSource.
func (f *File) String() string { return string(f.data) }

// MustTime parses and returns the given time as RFC3339 or panics.
func MustTime(s string) time.Time {
	t, err := time.Parse(time.RFC3339, s)
	if err != nil {
		panic(err)
	}
	return t
}
<commit_msg>fix typo regression in previous patch<commit_after>package genfs

import (
	"bytes"
	"errors"
	"io"
	"net/http"
	"os"
	"path"
	"time"
)

// NewFS returns a new FS for the given files.
func NewFS(files ...*File) *FS {
	fs := &FS{
		l: make([]*File, len(files)),
		m: make(map[string]*File, len(files)),
	}
	for i, file := range files {
		// Clone file so that the same file can be used with multiple FS instances.
		clone := &File{}
		*clone = *file
		clone.fs = fs
		fs.m[file.path] = clone
		fs.l[i] = clone
	}
	return fs
}

// Dir returns a new FS for the given path.
func Dir(path string) (*FS, error) {
	files, err := Files(path, FilterNone)
	if err != nil {
		return nil, err
	}
	return NewFS(files...), nil
}

// FS is an in-memory file system that implements http.FileSystem.
type FS struct {
	m map[string]*File
	l []*File
}

// check interface compliance
var _ = http.FileSystem(&FS{})

// Open is part of http.FileSystem.
func (f *FS) Open(name string) (http.File, error) {
	name = path.Clean(name)
	file := f.m[name]
	if file == nil {
		// @TODO Path error?
		return nil, os.ErrNotExist
	}
	// Return a clone so that concurrently opened files can have their own read
	// state.
	clone := &File{}
	*clone = *file
	clone.Reader = bytes.NewReader(clone.data)
	return clone, nil
}

// NewFile returns a new in-memory file with the given properties.
func NewFile(path, name string, size int64, mode os.FileMode, t time.Time, isDir bool, data []byte) *File {
	return &File{
		path:    path,
		name:    name,
		size:    size,
		mode:    mode,
		modTime: t,
		isDir:   isDir,
		data:    data,
		Reader:  bytes.NewReader(data),
	}
}

// File is an in-memory file that implements http.File and os.FileInfo.
type File struct {
	io.Reader

	path    string
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	isDir   bool
	data    []byte

	fs *FS
}

// check interface compliance
var _ = os.FileInfo(&File{})
var _ = http.File(&File{})

// Close is part of http.File.
func (f *File) Close() error {
	// @TODO return err when closing twice?
	return nil
}

// Seek is part of http.File.
func (f *File) Seek(offset int64, whence int) (int64, error) {
	// @TODO(fg) implement
	return 0, nil
}

// Stat is part of http.File.
func (f *File) Stat() (os.FileInfo, error) {
	// @TODO(fg) implement
	return f, nil
}

// Readdir is part of http.File.
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
	// @TODO(fg) support full Readdir semantics, including EOF, etc.
	if count > 0 {
		return nil, errors.New("genfs: only count <= 0 is supported right now")
	}
	var files []os.FileInfo
	// TODO(fg) make this faster using binary search or a tree structure
	for _, file := range f.fs.l {
		if path.Clean(path.Join(f.path, file.name)) == file.path {
			files = append(files, file)
		}
	}
	return files, nil
}

// IsDir is part of os.FileInfo.
func (f *File) IsDir() bool { return f.isDir }

// ModTime is part of os.FileInfo.
func (f *File) ModTime() time.Time { return f.modTime }

// Mode is part of os.FileInfo.
func (f *File) Mode() os.FileMode { return f.mode }

// Name is part of os.FileInfo.
func (f *File) Name() string { return f.name }

// Size is part of os.FileInfo.
func (f *File) Size() int64 { return f.size }

// Sys is part of os.FileInfo.
func (f *File) Sys() interface{} { return nil }

// Path returns the path of the file. It's needed for WriteSource.
func (f *File) Path() string { return f.path }

// String returns the file data as a string. It's needed for WriteSource.
func (f *File) String() string { return string(f.data) }

// MustTime parses and returns the given time as RFC3339 or panics.
func MustTime(s string) time.Time {
	t, err := time.Parse(time.RFC3339, s)
	if err != nil {
		panic(err)
	}
	return t
}
<|endoftext|>


<commit_before>package fs

import (
	"io/ioutil"
	"strings"
)

var (
	Local    = LocalFileSystem{DefaultCreatePermissions: UserGroupReadWrite}
	Registry = []FileSystem{Local}
)

func Select(uri string) FileSystem {
	for _, fs := range Registry {
		if strings.HasPrefix(uri, fs.Prefix()) {
			return fs
		}
	}
	return Local
}

func SelectFile(uri string) File {
	return Select(uri).File(uri)
}

func Touch(uri string, perm ...Permissions) (File, error) {
	file := SelectFile(uri)
	err := file.Touch(perm...)
	if err != nil {
		return nil, err
	}
	return file, nil
}

func MakeDir(uri string, perm ...Permissions) (File, error) {
	file := SelectFile(uri)
	err := file.MakeDir(perm...)
	if err != nil {
		return nil, err
	}
	return file, nil
}

func Read(uri string) ([]byte, error) {
	reader, err := SelectFile(uri).OpenReader()
	if err != nil {
		return nil, err
	}
	defer reader.Close()
	return ioutil.ReadAll(reader)
}

func Write(uri string, data []byte, perm ...Permissions) error {
	writer, err := SelectFile(uri).OpenWriter(perm...)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = writer.Write(data)
	return err
}

func Append(uri string, data []byte, perm ...Permissions) error {
	writer, err := SelectFile(uri).OpenAppendWriter(perm...)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = writer.Write(data)
	return err
}

func ReadString(uri string) (string, error) {
	data, err := Read(uri)
	if data == nil || err != nil {
		return "", err
	}
	return string(data), nil
}

func WriteString(uri string, data string, perm ...Permissions) error {
	return Write(uri, []byte(data), perm...)
}

func AppendString(uri string, data string, perm ...Permissions) error {
	return Append(uri, []byte(data), perm...)
}

func Truncate(uri string, size int64) error {
	return SelectFile(uri).Truncate(size)
}

func Remove(uri string) error {
	return SelectFile(uri).Remove()
}
<commit_msg>build fix<commit_after>package fs

import (
	"io/ioutil"
	"strings"
)

var (
	Local    = LocalFileSystem{DefaultCreatePermissions: UserAndGroupReadWrite}
	Registry = []FileSystem{Local}
)

func Select(uri string) FileSystem {
	for _, fs := range Registry {
		if strings.HasPrefix(uri, fs.Prefix()) {
			return fs
		}
	}
	return Local
}

func SelectFile(uri string) File {
	return Select(uri).File(uri)
}

func Touch(uri string, perm ...Permissions) (File, error) {
	file := SelectFile(uri)
	err := file.Touch(perm...)
	if err != nil {
		return nil, err
	}
	return file, nil
}

func MakeDir(uri string, perm ...Permissions) (File, error) {
	file := SelectFile(uri)
	err := file.MakeDir(perm...)
	if err != nil {
		return nil, err
	}
	return file, nil
}

func Read(uri string) ([]byte, error) {
	reader, err := SelectFile(uri).OpenReader()
	if err != nil {
		return nil, err
	}
	defer reader.Close()
	return ioutil.ReadAll(reader)
}

func Write(uri string, data []byte, perm ...Permissions) error {
	writer, err := SelectFile(uri).OpenWriter(perm...)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = writer.Write(data)
	return err
}

func Append(uri string, data []byte, perm ...Permissions) error {
	writer, err := SelectFile(uri).OpenAppendWriter(perm...)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = writer.Write(data)
	return err
}

func ReadString(uri string) (string, error) {
	data, err := Read(uri)
	if data == nil || err != nil {
		return "", err
	}
	return string(data), nil
}

func WriteString(uri string, data string, perm ...Permissions) error {
	return Write(uri, []byte(data), perm...)
}

func AppendString(uri string, data string, perm ...Permissions) error {
	return Append(uri, []byte(data), perm...)
}

func Truncate(uri string, size int64) error {
	return SelectFile(uri).Truncate(size)
}

func Remove(uri string) error {
	return SelectFile(uri).Remove()
}
<|endoftext|>


<commit_before>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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.

// A command that consumes the output of a `comeback verify` run (--fast mode
// is okay), assuming that the roots were all backup jobs of interest. Any
// score that is in the bucket but not represented in the verify output is
// cloned to a garbage/ prefix in the bucket, and deleted from the blobs/
// prefix.

package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"
	"time"

	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/wiring"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/syncutil"
	"golang.org/x/net/context"
)

var cmdGC = &Command{
	Name: "gc",
}

var fInput = cmdGC.Flags.String(
	"input",
	"",
	"Path to a file containing the output of a verify run.")

func init() {
	cmdGC.Run = runGC // Break flag-related dependency loop.
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Parse the supplied input line, returning a list of all scores mentioned.
func parseInputLine(
	line []byte) (scores []blob.Score, err error) {
	// We expect space-separate components.
	components := bytes.Split(line, []byte{' '})
	if len(components) < 2 {
		err = fmt.Errorf(
			"Expected at least two components, got %d.",
			len(components))

		return
	}

	// The first should be the timestmap.
	_, err = time.Parse(time.RFC3339, string(components[0]))
	if err != nil {
		err = fmt.Errorf("time.Parse(%q): %v", components[0], err)
		return
	}

	// The rest are hex scores.
	for i := 1; i < len(components); i++ {
		hexScore := string(components[i])

		var score blob.Score
		score, err = blob.ParseHexScore(hexScore)
		if err != nil {
			err = fmt.Errorf("ParseHexScore(%q): %v", hexScore, err)
			return
		}

		scores = append(scores, score)
	}

	return
}

// Parse the verify output, returning a list of all scores encountered.
func parseInput(
	r io.Reader) (scores []blob.Score, err error) {
	scanner := bufio.NewScanner(r)
	defer func() {
		scanErr := scanner.Err()
		if err == nil && scanErr != nil {
			err = fmt.Errorf("Scanner: %v", scanErr)
		}
	}()

	// Scan each line.
	for scanner.Scan() {
		var lineScores []blob.Score
		lineScores, err = parseInputLine(scanner.Bytes())
		if err != nil {
			err = fmt.Errorf("parseInputLine(%q): %v", scanner.Text(), err)
			return
		}

		scores = append(scores, lineScores...)
	}

	return
}

// Filter out scores that are in the list of non-garbage accessible scores,
// passing on only garbage.
func filterToGarbage(
	ctx context.Context,
	accessible []blob.Score,
	allScores <-chan blob.Score,
	garbageScores chan<- blob.Score) (err error) {
	err = errors.New("TODO: filterToGarbage")
	return
}

// Count the scores that pass through.
func countScores(
	ctx context.Context,
	in <-chan blob.Score,
	out chan<- blob.Score) (count uint64, err error) {
	err = errors.New("TODO: countScores")
	return
}

// Clone garbage blobs into a new location. Pass on the names of the source
// objects that were cloned.
func cloneGarbage(
	ctx context.Context,
	bucket gcs.Bucket,
	garbageScores <-chan blob.Score,
	garbageObjects chan<- string) (err error) {
	err = errors.New("TODO: cloneGarbage")
	return
}

// Delete all objects whose name come in on the supplied channel.
func deleteObjects(
	ctx context.Context,
	bucket gcs.Bucket,
	names <-chan string) (err error) {
	err = errors.New("TODO: deleteObjects")
	return
}

////////////////////////////////////////////////////////////////////////
// GC
////////////////////////////////////////////////////////////////////////

func runGC(args []string) {
	// Allow parallelism.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Die on error.
	var err error
	defer func() {
		if err != nil {
			log.Fatalln(err)
		}
	}()

	// Grab dependencies.
	bucket := getBucket()

	// Open the input file.
	if *fInput == "" {
		err = fmt.Errorf("You must set --input.")
		return
	}

	inputFile, err := os.Open(*fInput)
	if err != nil {
		err = fmt.Errorf("Open: %v", err)
		return
	}

	// Parse it.
	accessibleScores, err := parseInput(inputFile)
	inputFile.Close()

	if err != nil {
		err = fmt.Errorf("parseInput: %v", err)
		return
	}

	b := syncutil.NewBundle(context.Background())

	// List all extant scores into a channel.
	allScores := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(allScores)
		err = blob.ListScores(ctx, bucket, wiring.BlobObjectNamePrefix, allScores)
		if err != nil {
			err = fmt.Errorf("ListScores: %v", err)
			return
		}

		return
	})

	// Count the total number of scores.
	var allScoresCount uint64
	allScoresAfterCounting := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(allScoresAfterCounting)
		allScoresCount, err = countScores(
			ctx,
			allScores,
			allScoresAfterCounting)

		if err != nil {
			err = fmt.Errorf("countScores: %v", err)
			return
		}

		return
	})

	// Filter to garbage scores.
	garbageScores := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(garbageScores)
		err = filterToGarbage(
			ctx,
			accessibleScores,
			allScoresAfterCounting,
			garbageScores)

		if err != nil {
			err = fmt.Errorf("filterToGarbage: %v", err)
			return
		}

		return
	})

	// Count the number of garbage scores.
	var garbageScoresCount uint64
	garbageScoresAfterCounting := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(garbageScoresAfterCounting)
		garbageScoresCount, err = countScores(
			ctx,
			garbageScores,
			garbageScoresAfterCounting)

		if err != nil {
			err = fmt.Errorf("countScores: %v", err)
			return
		}

		return
	})

	// Clone garbage blobs into a backup location.
	toDelete := make(chan string, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(toDelete)
		err = cloneGarbage(
			ctx,
			bucket,
			garbageScoresAfterCounting,
			toDelete)
		if err != nil {
			err = fmt.Errorf("cloneGarbage: %v", err)
			return
		}

		return
	})

	// Delete the original objects.
	b.Add(func(ctx context.Context) (err error) {
		err = deleteObjects(ctx, bucket, toDelete)
		if err != nil {
			err = fmt.Errorf("deleteObjects: %v", err)
			return
		}

		return
	})

	err = b.Join()
	if err != nil {
		return
	}

	// Print a summary.
	log.Printf(
		"Deleted %d objects out of %d total.",
		garbageScoresCount,
		allScoresCount)
}
<commit_msg>filterToGarbage<commit_after>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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.

// A command that consumes the output of a `comeback verify` run (--fast mode
// is okay), assuming that the roots were all backup jobs of interest. Any
// score that is in the bucket but not represented in the verify output is
// cloned to a garbage/ prefix in the bucket, and deleted from the blobs/
// prefix.

package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"
	"time"

	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/wiring"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/syncutil"
	"golang.org/x/net/context"
)

var cmdGC = &Command{
	Name: "gc",
}

var fInput = cmdGC.Flags.String(
	"input",
	"",
	"Path to a file containing the output of a verify run.")

func init() {
	cmdGC.Run = runGC // Break flag-related dependency loop.
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Parse the supplied input line, returning a list of all scores mentioned.
func parseInputLine(
	line []byte) (scores []blob.Score, err error) {
	// We expect space-separate components.
	components := bytes.Split(line, []byte{' '})
	if len(components) < 2 {
		err = fmt.Errorf(
			"Expected at least two components, got %d.",
			len(components))

		return
	}

	// The first should be the timestmap.
	_, err = time.Parse(time.RFC3339, string(components[0]))
	if err != nil {
		err = fmt.Errorf("time.Parse(%q): %v", components[0], err)
		return
	}

	// The rest are hex scores.
	for i := 1; i < len(components); i++ {
		hexScore := string(components[i])

		var score blob.Score
		score, err = blob.ParseHexScore(hexScore)
		if err != nil {
			err = fmt.Errorf("ParseHexScore(%q): %v", hexScore, err)
			return
		}

		scores = append(scores, score)
	}

	return
}

// Parse the verify output, returning a list of all scores encountered.
func parseInput(
	r io.Reader) (scores []blob.Score, err error) {
	scanner := bufio.NewScanner(r)
	defer func() {
		scanErr := scanner.Err()
		if err == nil && scanErr != nil {
			err = fmt.Errorf("Scanner: %v", scanErr)
		}
	}()

	// Scan each line.
	for scanner.Scan() {
		var lineScores []blob.Score
		lineScores, err = parseInputLine(scanner.Bytes())
		if err != nil {
			err = fmt.Errorf("parseInputLine(%q): %v", scanner.Text(), err)
			return
		}

		scores = append(scores, lineScores...)
	}

	return
}

// Filter out scores that are in the list of non-garbage accessible scores,
// passing on only garbage.
func filterToGarbage(
	ctx context.Context,
	accessible []blob.Score,
	allScores <-chan blob.Score,
	garbageScores chan<- blob.Score) (err error) {
	// Create a map indexing the accessible scores.
	accessibleMap := make(map[blob.Score]struct{})
	for _, score := range accessible {
		accessibleMap[score] = struct{}{}
	}

	// Process each score.
	for score := range allScores {
		// Is this score accessible?
		if _, ok := accessibleMap[score]; ok {
			continue
		}

		// Send it down the garbage chute.
		select {
		case <-ctx.Done():
			err = ctx.Err()
			return

		case garbageScores <- score:
		}
	}

	return
}

// Count the scores that pass through.
func countScores(
	ctx context.Context,
	in <-chan blob.Score,
	out chan<- blob.Score) (count uint64, err error) {
	err = errors.New("TODO: countScores")
	return
}

// Clone garbage blobs into a new location. Pass on the names of the source
// objects that were cloned.
func cloneGarbage(
	ctx context.Context,
	bucket gcs.Bucket,
	garbageScores <-chan blob.Score,
	garbageObjects chan<- string) (err error) {
	err = errors.New("TODO: cloneGarbage")
	return
}

// Delete all objects whose name come in on the supplied channel.
func deleteObjects(
	ctx context.Context,
	bucket gcs.Bucket,
	names <-chan string) (err error) {
	err = errors.New("TODO: deleteObjects")
	return
}

////////////////////////////////////////////////////////////////////////
// GC
////////////////////////////////////////////////////////////////////////

func runGC(args []string) {
	// Allow parallelism.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Die on error.
	var err error
	defer func() {
		if err != nil {
			log.Fatalln(err)
		}
	}()

	// Grab dependencies.
	bucket := getBucket()

	// Open the input file.
	if *fInput == "" {
		err = fmt.Errorf("You must set --input.")
		return
	}

	inputFile, err := os.Open(*fInput)
	if err != nil {
		err = fmt.Errorf("Open: %v", err)
		return
	}

	// Parse it.
	accessibleScores, err := parseInput(inputFile)
	inputFile.Close()

	if err != nil {
		err = fmt.Errorf("parseInput: %v", err)
		return
	}

	b := syncutil.NewBundle(context.Background())

	// List all extant scores into a channel.
	allScores := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(allScores)
		err = blob.ListScores(ctx, bucket, wiring.BlobObjectNamePrefix, allScores)
		if err != nil {
			err = fmt.Errorf("ListScores: %v", err)
			return
		}

		return
	})

	// Count the total number of scores.
	var allScoresCount uint64
	allScoresAfterCounting := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(allScoresAfterCounting)
		allScoresCount, err = countScores(
			ctx,
			allScores,
			allScoresAfterCounting)

		if err != nil {
			err = fmt.Errorf("countScores: %v", err)
			return
		}

		return
	})

	// Filter to garbage scores.
	garbageScores := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(garbageScores)
		err = filterToGarbage(
			ctx,
			accessibleScores,
			allScoresAfterCounting,
			garbageScores)

		if err != nil {
			err = fmt.Errorf("filterToGarbage: %v", err)
			return
		}

		return
	})

	// Count the number of garbage scores.
	var garbageScoresCount uint64
	garbageScoresAfterCounting := make(chan blob.Score, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(garbageScoresAfterCounting)
		garbageScoresCount, err = countScores(
			ctx,
			garbageScores,
			garbageScoresAfterCounting)

		if err != nil {
			err = fmt.Errorf("countScores: %v", err)
			return
		}

		return
	})

	// Clone garbage blobs into a backup location.
	toDelete := make(chan string, 100)
	b.Add(func(ctx context.Context) (err error) {
		defer close(toDelete)
		err = cloneGarbage(
			ctx,
			bucket,
			garbageScoresAfterCounting,
			toDelete)
		if err != nil {
			err = fmt.Errorf("cloneGarbage: %v", err)
			return
		}

		return
	})

	// Delete the original objects.
	b.Add(func(ctx context.Context) (err error) {
		err = deleteObjects(ctx, bucket, toDelete)
		if err != nil {
			err = fmt.Errorf("deleteObjects: %v", err)
			return
		}

		return
	})

	err = b.Join()
	if err != nil {
		return
	}

	// Print a summary.
	log.Printf(
		"Deleted %d objects out of %d total.",
		garbageScoresCount,
		allScoresCount)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var spool = filepath.Join(os.TempDir(), "godep")

var cmdGo = &Command{
	Usage: "go command [args...]",
	Short: "run the go tool in a sandbox",
	Long: `
Go runs the go tool in a temporary GOPATH sandbox
with the dependencies listed in file Godeps.
`,
	Run: runGo,
}

// Set up a sandbox and run the go tool. The sandbox is built
// out of specific checked-out revisions of repos. We keep repos
// and revs materialized on disk under the assumption that disk
// space is cheap and plentiful, and writing files is slow.
// Everything is kept in the spool directory.
func runGo(cmd *Command, args []string) {
	gopath := prepareGopath()
	if s := os.Getenv("GOPATH"); s != "" {
		gopath += ":" + os.Getenv("GOPATH")
	}
	c := exec.Command("go", args...)
	c.Env = append(envNoGopath(), "GOPATH="+gopath)
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	err := c.Run()
	if err != nil {
		log.Fatalln("go", err)
	}
}

// prepareGopath reads dependency information from the filesystem
// entry name, fetches any necessary code, and returns a gopath
// causing the specified dependencies to be used.
func prepareGopath() (gopath string) {
	const name = "Godeps"
	dir, isDir := findInParents(name)
	if isDir {
		return filepath.Join(dir, name, "_workspace")
	}
	g, err := ReadGodeps(filepath.Join(dir, name))
	if err != nil {
		log.Fatalln(err)
	}
	gopath, err = sandboxAll(g.Deps)
	if err != nil {
		log.Fatalln(err)
	}
	return gopath
}

// findInParents returns the path to the directory containing file name
// in the current directory or any ancestor, and whether name itself
// is a directory.
func findInParents(name string) (dir string, isDir bool) {
	wd, err := os.Getwd()
	if err != nil {
		log.Fatalln(err)
	}
	for {
		fi, err := os.Stat(filepath.Join(wd, name))
		if os.IsNotExist(err) && wd == "/" {
			log.Fatalln("No", name, "found (or in any parent directory)")
		}
		if os.IsNotExist(err) {
			wd = filepath.Dir(wd)
			continue
		}
		if err != nil {
			log.Fatalln(err)
		}
		return wd, fi.IsDir()
	}
}

func envNoGopath() (a []string) {
	for _, s := range os.Environ() {
		if !strings.HasPrefix(s, "GOPATH=") {
			a = append(a, s)
		}
	}
	return a
}

// sandboxAll ensures that the commits in deps are available
// on disk, and returns a GOPATH string that will cause them
// to be used.
func sandboxAll(a []Dependency) (gopath string, err error) {
	var path []string
	for _, dep := range a {
		dir, err := sandbox(dep)
		if err != nil {
			return "", err
		}
		path = append(path, dir)
	}
	return strings.Join(path, ":"), nil
}

// sandbox ensures that commit d is available on disk,
// and returns a GOPATH string that will cause it to be used.
func sandbox(d Dependency) (gopath string, err error) {
	if !exists(d.RepoPath()) {
		if err = d.CreateRepo("fast", "main"); err != nil {
			return "", fmt.Errorf("create repo: %s", err)
		}
	}
	err = d.checkout()
	if err != nil && d.FastRemotePath() != "" {
		err = d.fetchAndCheckout("fast")
	}
	if err != nil {
		err = d.fetchAndCheckout("main")
	}
	if err != nil {
		return "", err
	}
	return d.Gopath(), nil
}
<commit_msg>refactor<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var spool = filepath.Join(os.TempDir(), "godep")

var cmdGo = &Command{
	Usage: "go command [args...]",
	Short: "run the go tool in a sandbox",
	Long: `
Go runs the go tool in a temporary GOPATH sandbox
with the dependencies listed in file Godeps.
`,
	Run: runGo,
}

// Set up a sandbox and run the go tool. The sandbox is built
// out of specific checked-out revisions of repos. We keep repos
// and revs materialized on disk under the assumption that disk
// space is cheap and plentiful, and writing files is slow.
// Everything is kept in the spool directory.
func runGo(cmd *Command, args []string) {
	gopath := prepareGopath()
	if s := os.Getenv("GOPATH"); s != "" {
		gopath += ":" + os.Getenv("GOPATH")
	}
	c := exec.Command("go", args...)
	c.Env = append(envNoGopath(), "GOPATH="+gopath)
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	err := c.Run()
	if err != nil {
		log.Fatalln("go", err)
	}
}

// prepareGopath reads dependency information from the filesystem
// entry name, fetches any necessary code, and returns a gopath
// causing the specified dependencies to be used.
func prepareGopath() (gopath string) {
	const name = "Godeps"
	wd, err := os.Getwd()
	if err != nil {
		log.Fatalln(err)
	}
	dir, isDir := findInParents(wd, name)
	if dir == "" {
		log.Fatalln("No", name, "found (or in any parent directory)")
	}
	if isDir {
		return filepath.Join(dir, name, "_workspace")
	}
	g, err := ReadGodeps(filepath.Join(dir, name))
	if err != nil {
		log.Fatalln(err)
	}
	gopath, err = sandboxAll(g.Deps)
	if err != nil {
		log.Fatalln(err)
	}
	return gopath
}

// findInParents returns the path to the directory containing name
// in dir or any ancestor, and whether name itself is a directory.
// If name cannot be found, findInParents returns the empty string.
func findInParents(dir, name string) (container string, isDir bool) {
	for {
		fi, err := os.Stat(filepath.Join(dir, name))
		if os.IsNotExist(err) && dir == "/" {
			return "", false
		}
		if os.IsNotExist(err) {
			dir = filepath.Dir(dir)
			continue
		}
		if err != nil {
			log.Fatalln(err)
		}
		return dir, fi.IsDir()
	}
}

func envNoGopath() (a []string) {
	for _, s := range os.Environ() {
		if !strings.HasPrefix(s, "GOPATH=") {
			a = append(a, s)
		}
	}
	return a
}

// sandboxAll ensures that the commits in deps are available
// on disk, and returns a GOPATH string that will cause them
// to be used.
func sandboxAll(a []Dependency) (gopath string, err error) {
	var path []string
	for _, dep := range a {
		dir, err := sandbox(dep)
		if err != nil {
			return "", err
		}
		path = append(path, dir)
	}
	return strings.Join(path, ":"), nil
}

// sandbox ensures that commit d is available on disk,
// and returns a GOPATH string that will cause it to be used.
func sandbox(d Dependency) (gopath string, err error) {
	if !exists(d.RepoPath()) {
		if err = d.CreateRepo("fast", "main"); err != nil {
			return "", fmt.Errorf("create repo: %s", err)
		}
	}
	err = d.checkout()
	if err != nil && d.FastRemotePath() != "" {
		err = d.fetchAndCheckout("fast")
	}
	if err != nil {
		err = d.fetchAndCheckout("main")
	}
	if err != nil {
		return "", err
	}
	return d.Gopath(), nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"time"
)

type route struct {
	to   int32
	cost int32
}

type node struct {
	neighbours []route
}

func readPlaces() ([]node, int) {
	f, err := os.Open("agraph")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	var numNodes int
	if _, err := fmt.Fscanln(f, &numNodes); err != nil {
		panic(err)
	}

	nodes := make([]node, numNodes)
	for i := range nodes {
		nodes[i].neighbours = make([]route, 0, numNodes/2)
	}

	for {
		var node int32
		var r route

		switch _, err := fmt.Fscanln(f, &node, &r.to, &r.cost); {
		case err == io.EOF:
			return nodes, numNodes
		case err != nil:
			panic(err)
		}
		nodes[node].neighbours = append(nodes[node].neighbours, r)
	}
}

func getLongestPath(nodes []node, nodeID int32, visited []bool) int32 {
	visited[nodeID] = true
	var max int32
	for _, neighbour := range nodes[nodeID].neighbours {
		if !visited[neighbour.to] {
			dist := neighbour.cost + getLongestPath(nodes, neighbour.to, visited)
			if dist > max {
				max = dist
			}
		}

	}
	visited[nodeID] = false
	return max
}

func main() {
	nodes, nNodes := readPlaces()
	visited := make([]bool, nNodes)
	start := time.Now()
	len := getLongestPath(nodes, 0, visited)
	duration := time.Since(start).Nanoseconds() / 1000000
	fmt.Printf("%v LANGUAGE Go %v\n", len, duration)
}
<commit_msg>Speed up Go program just a tiny bit<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"time"
)

type route struct {
	to   int32
	cost int32
}

type node struct {
	neighbours []route
}

func readPlaces() ([]node, int) {
	f, err := os.Open("agraph")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	var numNodes int
	if _, err := fmt.Fscanln(f, &numNodes); err != nil {
		panic(err)
	}

	nodes := make([]node, numNodes)
	for i := range nodes {
		nodes[i].neighbours = make([]route, 0, numNodes/2)
	}

	for {
		var node int32
		var r route

		switch _, err := fmt.Fscanln(f, &node, &r.to, &r.cost); {
		case err == io.EOF:
			return nodes, numNodes
		case err != nil:
			panic(err)
		}
		nodes[node].neighbours = append(nodes[node].neighbours, r)
	}
}

func getLongestPath(nodes []node, nodeID int32, visited []bool) int32 {
	visited[nodeID] = true
	var max int32
	for _, neighbour := range nodes[nodeID].neighbours {
		if visited[neighbour.to] {
			continue
		}
		dist := neighbour.cost + getLongestPath(nodes, neighbour.to, visited)
		if dist > max {
			max = dist
		}
	}
	visited[nodeID] = false
	return max
}

func main() {
	nodes, nNodes := readPlaces()
	visited := make([]bool, nNodes)
	start := time.Now()
	len := getLongestPath(nodes, 0, visited)
	duration := time.Since(start).Nanoseconds() / 1000000
	fmt.Printf("%v LANGUAGE Go %v\n", len, duration)
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package io

import (
	"fmt"
	"io/ioutil"
	"os"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apimachinery/registered"
	"k8s.io/kubernetes/pkg/runtime"
)

// LoadPodFromFile will read, decode, and return a Pod from a file.
func LoadPodFromFile(filePath string) (*api.Pod, error) {
	if filePath == "" {
		return nil, fmt.Errorf("file path not specified")
	}
	podDef, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
	}
	if len(podDef) == 0 {
		return nil, fmt.Errorf("file was empty: %s", filePath)
	}
	pod := &api.Pod{}

	codec := api.Codecs.LegacyCodec(registered.GroupOrDie(api.GroupName).GroupVersion)
	if err := runtime.DecodeInto(codec, podDef, pod); err != nil {
		return nil, fmt.Errorf("failed decoding file: %v", err)
	}
	return pod, nil
}

// SavePodToFile will encode and save a pod to a given path & permissions
func SavePodToFile(pod *api.Pod, filePath string, perm os.FileMode) error {
	if filePath == "" {
		return fmt.Errorf("file path not specified")
	}
	codec := api.Codecs.LegacyCodec(registered.GroupOrDie(api.GroupName).GroupVersion)
	data, err := runtime.Encode(codec, pod)
	if err != nil {
		return fmt.Errorf("failed encoding pod: %v", err)
	}
	return ioutil.WriteFile(filePath, data, perm)
}
<commit_msg>pkg/util<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package io

import (
	"fmt"
	"io/ioutil"
	"os"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/pkg/apimachinery/registered"
	"k8s.io/kubernetes/pkg/runtime"
)

// LoadPodFromFile will read, decode, and return a Pod from a file.
func LoadPodFromFile(filePath string) (*v1.Pod, error) {
	if filePath == "" {
		return nil, fmt.Errorf("file path not specified")
	}
	podDef, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
	}
	if len(podDef) == 0 {
		return nil, fmt.Errorf("file was empty: %s", filePath)
	}
	pod := &v1.Pod{}

	codec := api.Codecs.LegacyCodec(registered.GroupOrDie(v1.GroupName).GroupVersion)
	if err := runtime.DecodeInto(codec, podDef, pod); err != nil {
		return nil, fmt.Errorf("failed decoding file: %v", err)
	}
	return pod, nil
}

// SavePodToFile will encode and save a pod to a given path & permissions
func SavePodToFile(pod *v1.Pod, filePath string, perm os.FileMode) error {
	if filePath == "" {
		return fmt.Errorf("file path not specified")
	}
	codec := api.Codecs.LegacyCodec(registered.GroupOrDie(v1.GroupName).GroupVersion)
	data, err := runtime.Encode(codec, pod)
	if err != nil {
		return fmt.Errorf("failed encoding pod: %v", err)
	}
	return ioutil.WriteFile(filePath, data, perm)
}
<|endoftext|>


<commit_before>package cairo

//#cgo pkg-config: cairo
//#include <stdlib.h>
//#include <cairo/cairo.h>
//
//extern cairo_status_t go_write_callback(void*, unsigned char*, unsigned int);
//
//extern void go_write_callback_reaper(void*);
//
//extern cairo_status_t go_read_callback(void*, unsigned char*, unsigned int);
//
//extern void go_read_callback_reaper(void*);
//
//static cairo_user_data_key_t* new_user_key() {
//	return malloc(sizeof(cairo_user_data_key_t));
//}
//
//
//static cairo_status_t c_write_callback(void* w, unsigned char* data, unsigned int length) {
//	return go_write_callback(w, data, length);
//}
//
//typedef cairo_status_t (*wcallback_pass_back)(void*, unsigned char*, unsigned int);
//
///*This is required to expose the c callback wrapping the go callback back to Go*/
//static wcallback_pass_back callback_getter() {
//	return &c_write_callback;
//}
//
//static void c_write_callback_reaper(void *data) {
//	go_write_callback_reaper(data);
//}
//
//typedef void (*wreaper_pass_back)(void*);
//
//static wreaper_pass_back wreaper_getter() {
//	return &c_write_callback_reaper;
//}
import "C"

import (
	"io"
	"sync"
	"unsafe"
)

//IOShutdowner provides a hook that cairo calls on Readers and Writers
//that are passed through to libcairo to respond to being no longer needed.
//The error parameter is the error from the last read or write,
//which may be nil.
//
//This will not be called until the object owning the Reader or Writer is
//destroyed by libcairo.
//
//This is entirely optional.
type IOShutdowner interface {
	IOShutdown(error)
}

//Writer is just an io.Writer and this type exists to mention these points:
//
//Readers and Writers are passed to libcairo and the binding cannot
//send errors back out.
//If there is an error, you will only get a generic IO failure error.
//If you need to know the nature of the error, see IOShutdowner.
//
//Once a Reader or Writer returns an error, it will halt.
//If you handle temporary errors, like those provided by the net package,
//you need to wrap the Reader or Writer appropriately to handle this
//in situ.
type Writer interface {
	io.Writer
}

var (
	wmap = map[*writer]struct{}{}
	mux  = new(sync.Mutex)
)

type writer struct {
	key *C.cairo_user_data_key_t
	w   Writer
	err error
}

func (w *writer) write(p []byte) error {
	if w.err != nil {
		return w.err
	}
	n, err := w.w.Write(p)
	if err != nil {
		w.err = err
	}
	if n == len(p) {
		return w.err
	}
	w.err = io.ErrShortWrite
	return w.err
}

//XtensionCairoWriteFuncT is a cairo_write_func_t that expects as its closure
//argument the result of calling XtensionWrapWriter on a Writer.
//The surface or device created with this pair must be used to register
//the wrapped Writer with that objects XtensionRegisterWriter method.
//
//Anything less will cause at best memory leaks and at worst random errors.
//
//See XtensionWrapWriter for more information.
var XtensionCairoWriteFuncT = C.callback_getter()

//export go_write_callback
func go_write_callback(w unsafe.Pointer, data *C.uchar, length C.uint) C.cairo_status_t {
	W := (*writer)(w)

	bs := C.GoBytes(unsafe.Pointer(data), C.int(length))
	if err := W.write(bs); err == nil {
		return errSuccess
	}

	return errWriteError
}

//export go_write_callback_reaper
func go_write_callback_reaper(w unsafe.Pointer) {
	W := (*writer)(w)
	mux.Lock()
	defer mux.Unlock()
	delete(wmap, W)

	if s, ok := W.w.(IOShutdowner); ok {
		s.IOShutdown(W.err)
	}

	W.w = nil
	W.err = nil
	C.free(unsafe.Pointer(W.key))
}

//XtensionRegisterWriter registers the writer wrapped by XtensionWrapWriter
//with the surface so that it does not get garbage collected until libcairo
//releases the surface.
//
//See XtensionWrapWriter for more information.
func (s *XtensionSurface) XtensionRegisterWriter(w unsafe.Pointer) {
	if err := s.Err(); err != nil {
		go_write_callback_reaper(w)
	}
	W := (*writer)(w)
	C.cairo_surface_set_user_data(s.s, W.key, w, C.wreaper_getter())
}

//XtensionRegisterWriter registers the writer wrapped by XtensionWrapWriter
//with the surface so that it does not get garbage collected until libcairo
//releases the device.
//
//See XtensionWrapWriter for more information.
func (d *XtensionDevice) XtensionRegisterWriter(w unsafe.Pointer) {
	if err := d.Err(); err != nil {
		go_write_callback_reaper(w)
	}
	W := (*writer)(w)
	C.cairo_device_set_user_data(d.d, W.key, w, C.wreaper_getter())
}

//XtensionWrapWriter wraps a writer in a special container to communicate
//with libcairo.
//
//It also stores the returned value so that it is not garbage collected.
//
//You must use this along with XtensionCairoWriteFuncT when wrapping any
//of libcairo's _create_for_stream factories.
//
//After the surface or device is created the returned pointer must
//be registered with the surface or device using its XtensionRegisterWriter
//method.
//
//Example
//
//Say you wanted to wrap an X surface created with
//cairo_X_surface_create_for_stream.
//
//In the factory for your Go surface, you need code like the following:
//	wrapped := cairo.XtensionWrapWriter(iowriter)
//	s := C.cairo_X_surface_create_for_stream(cairo.XtensionCairoWriteFuncT, wrapped)
//	S := cairo.NewXtensionSurface(s)
//	S.XtensionRegisterWriter(wrapped)
func XtensionWrapWriter(w Writer) (closure unsafe.Pointer) {
	key := C.new_user_key()
	W := &writer{w: w, key: key}

	mux.Lock()
	defer mux.Unlock()
	wmap[W] = struct{}{}

	return unsafe.Pointer(W)
}
<commit_msg>simplify writer key management<commit_after>package cairo

//#cgo pkg-config: cairo
//#include <stdlib.h>
//#include <cairo/cairo.h>
//
//extern cairo_status_t go_write_callback(void*, unsigned char*, unsigned int);
//
//extern void go_write_callback_reaper(void*);
//
//extern cairo_status_t go_read_callback(void*, unsigned char*, unsigned int);
//
//extern void go_read_callback_reaper(void*);
//
//static cairo_status_t c_write_callback(void* w, unsigned char* data, unsigned int length) {
//	return go_write_callback(w, data, length);
//}
//
//typedef cairo_status_t (*wcallback_pass_back)(void*, unsigned char*, unsigned int);
//
///*This is required to expose the c callback wrapping the go callback back to Go*/
//static wcallback_pass_back callback_getter() {
//	return &c_write_callback;
//}
//
//static void c_write_callback_reaper(void *data) {
//	go_write_callback_reaper(data);
//}
//
//typedef void (*wreaper_pass_back)(void*);
//
//static wreaper_pass_back wreaper_getter() {
//	return &c_write_callback_reaper;
//}
import "C"

import (
	"io"
	"sync"
	"unsafe"
)

//IOShutdowner provides a hook that cairo calls on Readers and Writers
//that are passed through to libcairo to respond to being no longer needed.
//The error parameter is the error from the last read or write,
//which may be nil.
//
//This will not be called until the object owning the Reader or Writer is
//destroyed by libcairo.
//
//This is entirely optional.
type IOShutdowner interface {
	IOShutdown(error)
}

//Writer is just an io.Writer and this type exists to mention these points:
//
//Readers and Writers are passed to libcairo and the binding cannot
//send errors back out.
//If there is an error, you will only get a generic IO failure error.
//If you need to know the nature of the error, see IOShutdowner.
//
//Once a Reader or Writer returns an error, it will halt.
//If you handle temporary errors, like those provided by the net package,
//you need to wrap the Reader or Writer appropriately to handle this
//in situ.
type Writer interface {
	io.Writer
}

var (
	wmap = map[*writer]struct{}{}
	mux  = new(sync.Mutex)
	//there will only ever be one writer per object.
	wkey = &C.cairo_user_data_key_t{}
)

type writer struct {
	w   Writer
	err error
}

func (w *writer) write(p []byte) error {
	if w.err != nil {
		return w.err
	}
	n, err := w.w.Write(p)
	if err != nil {
		w.err = err
	}
	if n == len(p) {
		return w.err
	}
	w.err = io.ErrShortWrite
	return w.err
}

//XtensionCairoWriteFuncT is a cairo_write_func_t that expects as its closure
//argument the result of calling XtensionWrapWriter on a Writer.
//The surface or device created with this pair must be used to register
//the wrapped Writer with that objects XtensionRegisterWriter method.
//
//Anything less will cause at best memory leaks and at worst random errors.
//
//See XtensionWrapWriter for more information.
var XtensionCairoWriteFuncT = C.callback_getter()

//export go_write_callback
func go_write_callback(w unsafe.Pointer, data *C.uchar, length C.uint) C.cairo_status_t {
	W := (*writer)(w)

	bs := C.GoBytes(unsafe.Pointer(data), C.int(length))
	if err := W.write(bs); err == nil {
		return errSuccess
	}

	return errWriteError
}

//export go_write_callback_reaper
func go_write_callback_reaper(w unsafe.Pointer) {
	W := (*writer)(w)
	mux.Lock()
	defer mux.Unlock()
	delete(wmap, W)

	if s, ok := W.w.(IOShutdowner); ok {
		s.IOShutdown(W.err)
	}

	W.w = nil
	W.err = nil
}

//XtensionRegisterWriter registers the writer wrapped by XtensionWrapWriter
//with the surface so that it does not get garbage collected until libcairo
//releases the surface.
//
//See XtensionWrapWriter for more information.
func (s *XtensionSurface) XtensionRegisterWriter(w unsafe.Pointer) {
	if err := s.Err(); err != nil {
		go_write_callback_reaper(w)
	}
	C.cairo_surface_set_user_data(s.s, wkey, w, C.wreaper_getter())
}

//XtensionRegisterWriter registers the writer wrapped by XtensionWrapWriter
//with the surface so that it does not get garbage collected until libcairo
//releases the device.
//
//See XtensionWrapWriter for more information.
func (d *XtensionDevice) XtensionRegisterWriter(w unsafe.Pointer) {
	if err := d.Err(); err != nil {
		go_write_callback_reaper(w)
	}
	C.cairo_device_set_user_data(d.d, wkey, w, C.wreaper_getter())
}

//XtensionWrapWriter wraps a writer in a special container to communicate
//with libcairo.
//
//It also stores the returned value so that it is not garbage collected.
//
//You must use this along with XtensionCairoWriteFuncT when wrapping any
//of libcairo's _create_for_stream factories.
//
//After the surface or device is created the returned pointer must
//be registered with the surface or device using its XtensionRegisterWriter
//method.
//
//Example
//
//Say you wanted to wrap an X surface created with
//cairo_X_surface_create_for_stream.
//
//In the factory for your Go surface, you need code like the following:
//	wrapped := cairo.XtensionWrapWriter(iowriter)
//	s := C.cairo_X_surface_create_for_stream(cairo.XtensionCairoWriteFuncT, wrapped)
//	S := cairo.NewXtensionSurface(s)
//	S.XtensionRegisterWriter(wrapped)
func XtensionWrapWriter(w Writer) (closure unsafe.Pointer) {
	W := &writer{w: w}

	mux.Lock()
	defer mux.Unlock()
	wmap[W] = struct{}{}

	return unsafe.Pointer(W)
}
<|endoftext|>


<commit_before>package ui

import (
	"bufio"
	"bytes"
	"strings"

	"github.com/mitchellh/colorstring"
)

// Styled is a wrapper around an existing UI that automatically
// adds formatting around the UI text.
type Styled struct {
	Ui
}

func (u *Styled) Header(msg string) {
	u.Ui.Header(u.prefix("[bold]==> ", msg))
}

func (u *Styled) Message(msg string) {
	u.Ui.Message(u.prefix("    ", msg))
}

func (u *Styled) prefix(prefix, msg string) string {
	var buf bytes.Buffer
	buf.WriteString(colorstring.ColorPrefix(msg))

	scan := bufio.NewScanner(strings.NewReader(msg))
	for scan.Scan() {
		buf.WriteString(prefix)
		buf.WriteString(scan.Text() + "\n")
	}

	str := buf.String()
	if msg != "" {
		str = str[:len(str)-1]
	}

	return str
}
<commit_msg>ui: comment<commit_after>package ui

import (
	"bufio"
	"bytes"
	"strings"

	"github.com/mitchellh/colorstring"
)

// Styled is a wrapper around an existing UI that automatically
// adds formatting around the UI text.
type Styled struct {
	Ui
}

func (u *Styled) Header(msg string) {
	u.Ui.Header(u.prefix("[bold]==> ", msg))
}

func (u *Styled) Message(msg string) {
	u.Ui.Message(u.prefix("    ", msg))
}

func (u *Styled) prefix(prefix, msg string) string {
	var buf bytes.Buffer

	// We first write the color sequence (if any) of our message.
	// This makes it so that our prefix inherits the color properly
	// of any message.
	buf.WriteString(colorstring.ColorPrefix(msg))

	scan := bufio.NewScanner(strings.NewReader(msg))
	for scan.Scan() {
		buf.WriteString(prefix)
		buf.WriteString(scan.Text() + "\n")
	}

	str := buf.String()
	if msg != "" {
		str = str[:len(str)-1]
	}

	return str
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Palm Stone Games, Inc.

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

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

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

package polymer

import (
	"reflect"
	"regexp"
	"time"
	"unicode"

	"github.com/gopherjs/gopherjs/js"
)

var propertyEventNameRegExp *regexp.Regexp

func init() {
	var err error
	propertyEventNameRegExp, err = regexp.Compile("([a-z])([A-Z])")
	if err != nil {
		panic(err)
	}
}

const DateTimeLocalFormat = "2006-01-02T15:04:05"

// DateTimeLocal is a time.Time that properly encodes and decodes to the format expected datetime-local input fields
// The format is as follows, as per the format definition of the time package: "2006-01-02T15:04:05"
type DateTimeLocal time.Time

type AsyncHandle struct {
	jsHandle *js.Object
}

func (t DateTimeLocal) Encode() (*js.Object, bool) {
	return InterfaceToJsObject(time.Time(t).Local().Format(DateTimeLocalFormat)), !time.Time(t).IsZero()
}

func (t *DateTimeLocal) Decode(val *js.Object) error {
	if val == js.Undefined || val == nil || val.String() == "" {
		*t = DateTimeLocal{}
		return nil
	}

	parsedTime, err := time.ParseInLocation(DateTimeLocalFormat, val.String(), time.Local)
	if err != nil {
		return err
	}

	*t = DateTimeLocal(parsedTime)
	return nil
}

func Log(args ...interface{}) {
	js.Global.Get("console").Call("log", args...)
}

func getJsName(fieldName string) string {
	endIndex := len(fieldName) - 1
	newFieldName := ""
	for i, rune := range fieldName {
		newFieldName += string(unicode.ToLower(rune))
		if unicode.IsLower(rune) {
			endIndex = i
			break
		}
	}

	newFieldName += fieldName[endIndex+1:]
	return newFieldName
}

func getJsType(t reflect.Type) *js.Object {
	switch t.Kind() {
	case reflect.String:
		return js.Global.Get("String")
	case reflect.Bool:
		return js.Global.Get("Boolean")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Float32, reflect.Float64:
		return js.Global.Get("Number")
	default:
		return js.Global.Get("Object")
	}
}

func getJsPropertyChangedEvent(fieldName string) string {
	return js.Global.Get("Polymer").Get("CaseMap").Call("camelToDashCase", fieldName).String() + "-changed"
}

// Async calls the given callback asynchronously.
// If the specified wait time is -1, the callback will be ran with microtask timing (after the current method finishes, but before the next event from the event queue is processed)
// Otherwise, its ran waitTime milliseconds in the future. A waitTime of 1 can be useful to run a callback after all events currently in the queue have been processed.
// Returns a handle that can be used to cancel the task
func Async(waitTime int, f func()) *AsyncHandle {
	handle := &AsyncHandle{}
	if waitTime == -1 {
		handle.jsHandle = js.Global.Get("Polymer").Get("Async").Call("run", f)
	} else {
		handle.jsHandle = js.Global.Get("Polymer").Get("Async").Call("run", f, waitTime)
	}

	return handle
}

func (p *Proto) CancelAsync(handle *AsyncHandle) {
	js.Global.Get("Polymer").Get("Async").Call("cancel", handle.jsHandle)
}
<commit_msg>Remove unnecessary regexp code (Thanks cwbriscoe)<commit_after>/*
Copyright 2015 Palm Stone Games, Inc.

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

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

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

package polymer

import (
	"reflect"
	"time"
	"unicode"

	"github.com/gopherjs/gopherjs/js"
)

const DateTimeLocalFormat = "2006-01-02T15:04:05"

// DateTimeLocal is a time.Time that properly encodes and decodes to the format expected datetime-local input fields
// The format is as follows, as per the format definition of the time package: "2006-01-02T15:04:05"
type DateTimeLocal time.Time

type AsyncHandle struct {
	jsHandle *js.Object
}

func (t DateTimeLocal) Encode() (*js.Object, bool) {
	return InterfaceToJsObject(time.Time(t).Local().Format(DateTimeLocalFormat)), !time.Time(t).IsZero()
}

func (t *DateTimeLocal) Decode(val *js.Object) error {
	if val == js.Undefined || val == nil || val.String() == "" {
		*t = DateTimeLocal{}
		return nil
	}

	parsedTime, err := time.ParseInLocation(DateTimeLocalFormat, val.String(), time.Local)
	if err != nil {
		return err
	}

	*t = DateTimeLocal(parsedTime)
	return nil
}

func Log(args ...interface{}) {
	js.Global.Get("console").Call("log", args...)
}

func getJsName(fieldName string) string {
	endIndex := len(fieldName) - 1
	newFieldName := ""
	for i, rune := range fieldName {
		newFieldName += string(unicode.ToLower(rune))
		if unicode.IsLower(rune) {
			endIndex = i
			break
		}
	}

	newFieldName += fieldName[endIndex+1:]
	return newFieldName
}

func getJsType(t reflect.Type) *js.Object {
	switch t.Kind() {
	case reflect.String:
		return js.Global.Get("String")
	case reflect.Bool:
		return js.Global.Get("Boolean")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Float32, reflect.Float64:
		return js.Global.Get("Number")
	default:
		return js.Global.Get("Object")
	}
}

func getJsPropertyChangedEvent(fieldName string) string {
	return js.Global.Get("Polymer").Get("CaseMap").Call("camelToDashCase", fieldName).String() + "-changed"
}

// Async calls the given callback asynchronously.
// If the specified wait time is -1, the callback will be ran with microtask timing (after the current method finishes, but before the next event from the event queue is processed)
// Otherwise, its ran waitTime milliseconds in the future. A waitTime of 1 can be useful to run a callback after all events currently in the queue have been processed.
// Returns a handle that can be used to cancel the task
func Async(waitTime int, f func()) *AsyncHandle {
	handle := &AsyncHandle{}
	if waitTime == -1 {
		handle.jsHandle = js.Global.Get("Polymer").Get("Async").Call("run", f)
	} else {
		handle.jsHandle = js.Global.Get("Polymer").Get("Async").Call("run", f, waitTime)
	}

	return handle
}

func (p *Proto) CancelAsync(handle *AsyncHandle) {
	js.Global.Get("Polymer").Get("Async").Call("cancel", handle.jsHandle)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/masterzen/winrm/winrm"
	"github.com/mitchellh/cli"
)

type lsCommand struct {
	shutdown <-chan struct{}
	ui       cli.Ui
}

func (c *lsCommand) Help() string {
	text := `
Usage: winrmfs ls [options] directory

  List files of a remote directory.

Options:

  -addr=127.0.0.1:5985    Host and port of the remote machine
  -user=""                Name of the user to authenticate as
  -pass=""                Password to authenticate with
`
	return strings.TrimSpace(text)
}

func (c *lsCommand) Synopsis() string {
	return "List files of a remote directory"
}

func (c *lsCommand) Run(args []string) int {
	var user string
	var pass string

	flags := flag.NewFlagSet("ls", flag.ContinueOnError)
	flags.Usage = func() { c.ui.Output(c.Help()) }
	flags.StringVar(&user, "user", "", "auth name")
	flags.StringVar(&pass, "pass", "", "auth password")
	addr := addrFlag(flags)

	if err := flags.Parse(args); err != nil {
		return 1
	}

	args = flags.Args()
	if len(args) < 1 {
		c.ui.Error("A directory is required.\n")
		c.ui.Error(c.Help())
		return 1
	}
	if len(args) > 1 {
		c.ui.Error("Too many arguments. Only a directory is required.\n")
		c.ui.Error(c.Help())
		return 1
	}

	dir := args[0]
	endpoint, err := parseEndpoint(*addr)
	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	client := winrm.NewClient(endpoint, user, pass)
	shell, err := client.CreateShell()

	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	defer shell.Close()
	cmd, err := shell.Execute("powershell", "Get-ChildItem", friendlyPath(dir))
	//cmd, err := shell.Execute("powershell", "Get-ChildItem", dir, "|Format-Table -Property Attributes,LastWriteTime,Length,Name -AutoSize")
	//cmd, err := shell.Execute("powershell",
	//	fmt.Sprintf("-Command \"Get-ChildItem %s | Format-Table -Property Attributes,LastWriteTime,Length,Name -AutoSize\"", dir))
	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	go io.Copy(os.Stdout, cmd.Stdout)
	go io.Copy(os.Stderr, cmd.Stderr)
	cmd.Wait()

	return 0
}

func friendlyPath(path string) string {
	if len(path) == 0 {
		return path
	}

	if strings.Contains(path, " ") {
		path = fmt.Sprintf("'%s'", strings.Trim(path, "'\""))
	}

	return strings.Replace(path, "/", "\\", -1)
}
<commit_msg>ls returns accurate exit-code.<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/masterzen/winrm/winrm"
	"github.com/mitchellh/cli"
)

type lsCommand struct {
	shutdown <-chan struct{}
	ui       cli.Ui
}

func (c *lsCommand) Help() string {
	text := `
Usage: winrmfs ls [options] directory

  List files of a remote directory.

Options:

  -addr=127.0.0.1:5985    Host and port of the remote machine
  -user=""                Name of the user to authenticate as
  -pass=""                Password to authenticate with
`
	return strings.TrimSpace(text)
}

func (c *lsCommand) Synopsis() string {
	return "List files of a remote directory"
}

func (c *lsCommand) Run(args []string) int {
	var user string
	var pass string

	flags := flag.NewFlagSet("ls", flag.ContinueOnError)
	flags.Usage = func() { c.ui.Output(c.Help()) }
	flags.StringVar(&user, "user", "", "auth name")
	flags.StringVar(&pass, "pass", "", "auth password")
	addr := addrFlag(flags)

	if err := flags.Parse(args); err != nil {
		return 1
	}

	args = flags.Args()
	if len(args) < 1 {
		c.ui.Error("A directory is required.\n")
		c.ui.Error(c.Help())
		return 1
	}
	if len(args) > 1 {
		c.ui.Error("Too many arguments. Only a directory is required.\n")
		c.ui.Error(c.Help())
		return 1
	}

	dir := args[0]
	endpoint, err := parseEndpoint(*addr)
	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	client := winrm.NewClient(endpoint, user, pass)
	shell, err := client.CreateShell()

	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	defer shell.Close()
	cmd, err := shell.Execute("powershell", "Get-ChildItem", friendlyPath(dir))
	//cmd, err := shell.Execute("powershell", "Get-ChildItem", dir, "|Format-Table -Property Attributes,LastWriteTime,Length,Name -AutoSize")
	//cmd, err := shell.Execute("powershell",
	//	fmt.Sprintf("-Command \"Get-ChildItem %s | Format-Table -Property Attributes,LastWriteTime,Length,Name -AutoSize\"", dir))
	if err != nil {
		c.ui.Error(err.Error())
		return 1
	}

	go io.Copy(os.Stdout, cmd.Stdout)
	go io.Copy(os.Stderr, cmd.Stderr)
	cmd.Wait()
	cmd.Close()

	return cmd.ExitCode()
}

func friendlyPath(path string) string {
	if len(path) == 0 {
		return path
	}

	if strings.Contains(path, " ") {
		path = fmt.Sprintf("'%s'", strings.Trim(path, "'\""))
	}

	return strings.Replace(path, "/", "\\", -1)
}
<|endoftext|>


<commit_before>// Simple console progress bars
package pb

import (
	"fmt"
	"io"
	"math"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"unicode/utf8"
)

// Current version
const Version = "1.0.20"

const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)

// DEPRECATED
// variables for backward compatibility, from now do not work
// use pb.Format and pb.SetRefreshRate
var (
	DefaultRefreshRate                         = DEFAULT_REFRESH_RATE
	BarStart, BarEnd, Empty, Current, CurrentN string
)

// Create new progress bar object
func New(total int) *ProgressBar {
	return New64(int64(total))
}

// Create new progress bar object using int64 as total
func New64(total int64) *ProgressBar {
	pb := &ProgressBar{
		Total:         total,
		RefreshRate:   DEFAULT_REFRESH_RATE,
		ShowPercent:   true,
		ShowCounters:  true,
		ShowBar:       true,
		ShowTimeLeft:  true,
		ShowFinalTime: true,
		Units:         U_NO,
		ManualUpdate:  false,
		finish:        make(chan struct{}),
	}
	return pb.Format(FORMAT)
}

// Create new object and start
func StartNew(total int) *ProgressBar {
	return New(total).Start()
}

// Callback for custom output
// For example:
// bar.Callback = func(s string) {
//     mySuperPrint(s)
// }
//
type Callback func(out string)

type ProgressBar struct {
	current  int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
	previous int64

	Total                            int64
	RefreshRate                      time.Duration
	ShowPercent, ShowCounters        bool
	ShowSpeed, ShowTimeLeft, ShowBar bool
	ShowFinalTime                    bool
	Output                           io.Writer
	Callback                         Callback
	NotPrint                         bool
	Units                            Units
	Width                            int
	ForceWidth                       bool
	ManualUpdate                     bool
	AutoStat                         bool

	// Default width for the time box.
	UnitsWidth   int
	TimeBoxWidth int

	finishOnce sync.Once //Guards isFinish
	finish     chan struct{}
	isFinish   bool

	startTime  time.Time
	startValue int64

	changeTime time.Time

	prefix, postfix string

	mu        sync.Mutex
	lastPrint string

	BarStart string
	BarEnd   string
	Empty    string
	Current  string
	CurrentN string

	AlwaysUpdate bool
}

// Start print
func (pb *ProgressBar) Start() *ProgressBar {
	pb.startTime = time.Now()
	pb.startValue = atomic.LoadInt64(&pb.current)
	if pb.Total == 0 {
		pb.ShowTimeLeft = false
		pb.ShowPercent = false
		pb.AutoStat = false
	}
	if !pb.ManualUpdate {
		pb.Update() // Initial printing of the bar before running the bar refresher.
		go pb.refresher()
	}
	return pb
}

// Increment current value
func (pb *ProgressBar) Increment() int {
	return pb.Add(1)
}

// Get current value
func (pb *ProgressBar) Get() int64 {
	c := atomic.LoadInt64(&pb.current)
	return c
}

// Set current value
func (pb *ProgressBar) Set(current int) *ProgressBar {
	return pb.Set64(int64(current))
}

// Set64 sets the current value as int64
func (pb *ProgressBar) Set64(current int64) *ProgressBar {
	atomic.StoreInt64(&pb.current, current)
	return pb
}

// Add to current value
func (pb *ProgressBar) Add(add int) int {
	return int(pb.Add64(int64(add)))
}

func (pb *ProgressBar) Add64(add int64) int64 {
	return atomic.AddInt64(&pb.current, add)
}

// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
	pb.prefix = prefix
	return pb
}

// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
	pb.postfix = postfix
	return pb
}

// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
	var formatEntries []string
	if utf8.RuneCountInString(format) == 5 {
		formatEntries = strings.Split(format, "")
	} else {
		formatEntries = strings.Split(format, "\x00")
	}
	if len(formatEntries) == 5 {
		pb.BarStart = formatEntries[0]
		pb.BarEnd = formatEntries[4]
		pb.Empty = formatEntries[3]
		pb.Current = formatEntries[1]
		pb.CurrentN = formatEntries[2]
	}
	return pb
}

// Set bar refresh rate
func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
	pb.RefreshRate = rate
	return pb
}

// Set units
// bar.SetUnits(U_NO) - by default
// bar.SetUnits(U_BYTES) - for Mb, Kb, etc
func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
	pb.Units = units
	return pb
}

// Set max width, if width is bigger than terminal width, will be ignored
func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = false
	return pb
}

// Set bar width
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = true
	return pb
}

// End print
func (pb *ProgressBar) Finish() {
	//Protect multiple calls
	pb.finishOnce.Do(func() {
		close(pb.finish)
		pb.write(atomic.LoadInt64(&pb.current))
		pb.mu.Lock()
		defer pb.mu.Unlock()
		switch {
		case pb.Output != nil:
			fmt.Fprintln(pb.Output)
		case !pb.NotPrint:
			fmt.Println()
		}
		pb.isFinish = true
	})
}

// IsFinished return boolean
func (pb *ProgressBar) IsFinished() bool {
	pb.mu.Lock()
	defer pb.mu.Unlock()
	return pb.isFinish
}

// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
	pb.Finish()
	if pb.Output != nil {
		fmt.Fprintln(pb.Output, str)
	} else {
		fmt.Println(str)
	}
}

// implement io.Writer
func (pb *ProgressBar) Write(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// implement io.Reader
func (pb *ProgressBar) Read(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// Create new proxy reader over bar
// Takes io.Reader or io.ReadCloser
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
	return &Reader{r, pb}
}

func (pb *ProgressBar) write(current int64) {
	width := pb.GetWidth()

	var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string

	// percents
	if pb.ShowPercent {
		var percent float64
		if pb.Total > 0 {
			percent = float64(current) / (float64(pb.Total) / float64(100))
		} else {
			percent = float64(current) / float64(100)
		}
		percentBox = fmt.Sprintf(" %6.02f%%", percent)
	}

	// counters
	if pb.ShowCounters {
		current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
		if pb.Total > 0 {
			total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth)
			countersBox = fmt.Sprintf(" %s / %s ", current, total)
		} else {
			countersBox = fmt.Sprintf(" %s / ? ", current)
		}
	}

	// time left
	pb.mu.Lock()
	currentFromStart := current - pb.startValue
	fromStart := time.Now().Sub(pb.startTime)
	lastChangeTime := pb.changeTime
	fromChange := lastChangeTime.Sub(pb.startTime)
	pb.mu.Unlock()
	select {
	case <-pb.finish:
		if pb.ShowFinalTime {
			var left time.Duration
			left = (fromStart / time.Second) * time.Second
			timeLeftBox = fmt.Sprintf(" %s", left.String())
		}
	default:
		if pb.ShowTimeLeft && currentFromStart > 0 {
			perEntry := fromChange / time.Duration(currentFromStart)
			var left time.Duration
			if pb.Total > 0 {
				left = time.Duration(pb.Total-currentFromStart) * perEntry
				left -= time.Since(lastChangeTime)
				left = (left / time.Second) * time.Second
			} else {
				left = time.Duration(currentFromStart) * perEntry
				left = (left / time.Second) * time.Second
			}
			if left > 0 {
				timeLeft := Format(int64(left)).To(U_DURATION).String()
				timeLeftBox = fmt.Sprintf(" %s", timeLeft)
			}
		}
	}

	if len(timeLeftBox) < pb.TimeBoxWidth {
		timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
	}

	// speed
	if pb.ShowSpeed && currentFromStart > 0 {
		fromStart := time.Now().Sub(pb.startTime)
		speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
		speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String()
	}

	barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
	// bar
	if pb.ShowBar {
		size := width - barWidth
		if size > 0 {
			if pb.Total > 0 {
				curSize := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
				emptySize := size - curSize
				barBox = pb.BarStart
				if emptySize < 0 {
					emptySize = 0
				}
				if curSize > size {
					curSize = size
				}

				cursorLen := escapeAwareRuneCountInString(pb.Current)
				if emptySize <= 0 {
					barBox += strings.Repeat(pb.Current, curSize/cursorLen)
				} else if curSize > 0 {
					cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN)
					cursorRepetitions := (curSize - cursorEndLen) / cursorLen
					barBox += strings.Repeat(pb.Current, cursorRepetitions)
					barBox += pb.CurrentN
				}

				emptyLen := escapeAwareRuneCountInString(pb.Empty)
				barBox += strings.Repeat(pb.Empty, emptySize/emptyLen)
				barBox += pb.BarEnd
			} else {
				pos := size - int(current)%int(size)
				barBox = pb.BarStart
				if pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, pos-1)
				}
				barBox += pb.Current
				if size-pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, size-pos-1)
				}
				barBox += pb.BarEnd
			}
		}
	}

	// check len
	out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
	if cl := escapeAwareRuneCountInString(out); cl < width {
		end = strings.Repeat(" ", width-cl)
	}

	// and print!
	pb.mu.Lock()
	pb.lastPrint = out + end
	isFinish := pb.isFinish
	pb.mu.Unlock()
	switch {
	case isFinish:
		return
	case pb.Output != nil:
		fmt.Fprint(pb.Output, "\r"+out+end)
	case pb.Callback != nil:
		pb.Callback(out + end)
	case !pb.NotPrint:
		fmt.Print("\r" + out + end)
	}
}

// GetTerminalWidth - returns terminal width for all platforms.
func GetTerminalWidth() (int, error) {
	return terminalWidth()
}

func (pb *ProgressBar) GetWidth() int {
	if pb.ForceWidth {
		return pb.Width
	}

	width := pb.Width
	termWidth, _ := terminalWidth()
	if width == 0 || termWidth <= width {
		width = termWidth
	}

	return width
}

// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
	c := atomic.LoadInt64(&pb.current)
	p := atomic.LoadInt64(&pb.previous)
	if p != c {
		pb.mu.Lock()
		pb.changeTime = time.Now()
		pb.mu.Unlock()
		atomic.StoreInt64(&pb.previous, c)
	}
	pb.write(c)
	if pb.AutoStat {
		if c == 0 {
			pb.startTime = time.Now()
			pb.startValue = 0
		} else if c >= pb.Total && pb.isFinish != true {
			pb.Finish()
		}
	}
}

// String return the last bar print
func (pb *ProgressBar) String() string {
	pb.mu.Lock()
	defer pb.mu.Unlock()
	return pb.lastPrint
}

// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
	for {
		select {
		case <-pb.finish:
			return
		case <-time.After(pb.RefreshRate):
			pb.Update()
		}
	}
}
<commit_msg>1.0.21<commit_after>// Simple console progress bars
package pb

import (
	"fmt"
	"io"
	"math"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"unicode/utf8"
)

// Current version
const Version = "1.0.21"

const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)

// DEPRECATED
// variables for backward compatibility, from now do not work
// use pb.Format and pb.SetRefreshRate
var (
	DefaultRefreshRate                         = DEFAULT_REFRESH_RATE
	BarStart, BarEnd, Empty, Current, CurrentN string
)

// Create new progress bar object
func New(total int) *ProgressBar {
	return New64(int64(total))
}

// Create new progress bar object using int64 as total
func New64(total int64) *ProgressBar {
	pb := &ProgressBar{
		Total:         total,
		RefreshRate:   DEFAULT_REFRESH_RATE,
		ShowPercent:   true,
		ShowCounters:  true,
		ShowBar:       true,
		ShowTimeLeft:  true,
		ShowFinalTime: true,
		Units:         U_NO,
		ManualUpdate:  false,
		finish:        make(chan struct{}),
	}
	return pb.Format(FORMAT)
}

// Create new object and start
func StartNew(total int) *ProgressBar {
	return New(total).Start()
}

// Callback for custom output
// For example:
// bar.Callback = func(s string) {
//     mySuperPrint(s)
// }
//
type Callback func(out string)

type ProgressBar struct {
	current  int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
	previous int64

	Total                            int64
	RefreshRate                      time.Duration
	ShowPercent, ShowCounters        bool
	ShowSpeed, ShowTimeLeft, ShowBar bool
	ShowFinalTime                    bool
	Output                           io.Writer
	Callback                         Callback
	NotPrint                         bool
	Units                            Units
	Width                            int
	ForceWidth                       bool
	ManualUpdate                     bool
	AutoStat                         bool

	// Default width for the time box.
	UnitsWidth   int
	TimeBoxWidth int

	finishOnce sync.Once //Guards isFinish
	finish     chan struct{}
	isFinish   bool

	startTime  time.Time
	startValue int64

	changeTime time.Time

	prefix, postfix string

	mu        sync.Mutex
	lastPrint string

	BarStart string
	BarEnd   string
	Empty    string
	Current  string
	CurrentN string

	AlwaysUpdate bool
}

// Start print
func (pb *ProgressBar) Start() *ProgressBar {
	pb.startTime = time.Now()
	pb.startValue = atomic.LoadInt64(&pb.current)
	if pb.Total == 0 {
		pb.ShowTimeLeft = false
		pb.ShowPercent = false
		pb.AutoStat = false
	}
	if !pb.ManualUpdate {
		pb.Update() // Initial printing of the bar before running the bar refresher.
		go pb.refresher()
	}
	return pb
}

// Increment current value
func (pb *ProgressBar) Increment() int {
	return pb.Add(1)
}

// Get current value
func (pb *ProgressBar) Get() int64 {
	c := atomic.LoadInt64(&pb.current)
	return c
}

// Set current value
func (pb *ProgressBar) Set(current int) *ProgressBar {
	return pb.Set64(int64(current))
}

// Set64 sets the current value as int64
func (pb *ProgressBar) Set64(current int64) *ProgressBar {
	atomic.StoreInt64(&pb.current, current)
	return pb
}

// Add to current value
func (pb *ProgressBar) Add(add int) int {
	return int(pb.Add64(int64(add)))
}

func (pb *ProgressBar) Add64(add int64) int64 {
	return atomic.AddInt64(&pb.current, add)
}

// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
	pb.prefix = prefix
	return pb
}

// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
	pb.postfix = postfix
	return pb
}

// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
	var formatEntries []string
	if utf8.RuneCountInString(format) == 5 {
		formatEntries = strings.Split(format, "")
	} else {
		formatEntries = strings.Split(format, "\x00")
	}
	if len(formatEntries) == 5 {
		pb.BarStart = formatEntries[0]
		pb.BarEnd = formatEntries[4]
		pb.Empty = formatEntries[3]
		pb.Current = formatEntries[1]
		pb.CurrentN = formatEntries[2]
	}
	return pb
}

// Set bar refresh rate
func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
	pb.RefreshRate = rate
	return pb
}

// Set units
// bar.SetUnits(U_NO) - by default
// bar.SetUnits(U_BYTES) - for Mb, Kb, etc
func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
	pb.Units = units
	return pb
}

// Set max width, if width is bigger than terminal width, will be ignored
func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = false
	return pb
}

// Set bar width
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
	pb.Width = width
	pb.ForceWidth = true
	return pb
}

// End print
func (pb *ProgressBar) Finish() {
	//Protect multiple calls
	pb.finishOnce.Do(func() {
		close(pb.finish)
		pb.write(atomic.LoadInt64(&pb.current))
		pb.mu.Lock()
		defer pb.mu.Unlock()
		switch {
		case pb.Output != nil:
			fmt.Fprintln(pb.Output)
		case !pb.NotPrint:
			fmt.Println()
		}
		pb.isFinish = true
	})
}

// IsFinished return boolean
func (pb *ProgressBar) IsFinished() bool {
	pb.mu.Lock()
	defer pb.mu.Unlock()
	return pb.isFinish
}

// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
	pb.Finish()
	if pb.Output != nil {
		fmt.Fprintln(pb.Output, str)
	} else {
		fmt.Println(str)
	}
}

// implement io.Writer
func (pb *ProgressBar) Write(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// implement io.Reader
func (pb *ProgressBar) Read(p []byte) (n int, err error) {
	n = len(p)
	pb.Add(n)
	return
}

// Create new proxy reader over bar
// Takes io.Reader or io.ReadCloser
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
	return &Reader{r, pb}
}

func (pb *ProgressBar) write(current int64) {
	width := pb.GetWidth()

	var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string

	// percents
	if pb.ShowPercent {
		var percent float64
		if pb.Total > 0 {
			percent = float64(current) / (float64(pb.Total) / float64(100))
		} else {
			percent = float64(current) / float64(100)
		}
		percentBox = fmt.Sprintf(" %6.02f%%", percent)
	}

	// counters
	if pb.ShowCounters {
		current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
		if pb.Total > 0 {
			total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth)
			countersBox = fmt.Sprintf(" %s / %s ", current, total)
		} else {
			countersBox = fmt.Sprintf(" %s / ? ", current)
		}
	}

	// time left
	pb.mu.Lock()
	currentFromStart := current - pb.startValue
	fromStart := time.Now().Sub(pb.startTime)
	lastChangeTime := pb.changeTime
	fromChange := lastChangeTime.Sub(pb.startTime)
	pb.mu.Unlock()
	select {
	case <-pb.finish:
		if pb.ShowFinalTime {
			var left time.Duration
			left = (fromStart / time.Second) * time.Second
			timeLeftBox = fmt.Sprintf(" %s", left.String())
		}
	default:
		if pb.ShowTimeLeft && currentFromStart > 0 {
			perEntry := fromChange / time.Duration(currentFromStart)
			var left time.Duration
			if pb.Total > 0 {
				left = time.Duration(pb.Total-currentFromStart) * perEntry
				left -= time.Since(lastChangeTime)
				left = (left / time.Second) * time.Second
			} else {
				left = time.Duration(currentFromStart) * perEntry
				left = (left / time.Second) * time.Second
			}
			if left > 0 {
				timeLeft := Format(int64(left)).To(U_DURATION).String()
				timeLeftBox = fmt.Sprintf(" %s", timeLeft)
			}
		}
	}

	if len(timeLeftBox) < pb.TimeBoxWidth {
		timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
	}

	// speed
	if pb.ShowSpeed && currentFromStart > 0 {
		fromStart := time.Now().Sub(pb.startTime)
		speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
		speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String()
	}

	barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
	// bar
	if pb.ShowBar {
		size := width - barWidth
		if size > 0 {
			if pb.Total > 0 {
				curSize := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
				emptySize := size - curSize
				barBox = pb.BarStart
				if emptySize < 0 {
					emptySize = 0
				}
				if curSize > size {
					curSize = size
				}

				cursorLen := escapeAwareRuneCountInString(pb.Current)
				if emptySize <= 0 {
					barBox += strings.Repeat(pb.Current, curSize/cursorLen)
				} else if curSize > 0 {
					cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN)
					cursorRepetitions := (curSize - cursorEndLen) / cursorLen
					barBox += strings.Repeat(pb.Current, cursorRepetitions)
					barBox += pb.CurrentN
				}

				emptyLen := escapeAwareRuneCountInString(pb.Empty)
				barBox += strings.Repeat(pb.Empty, emptySize/emptyLen)
				barBox += pb.BarEnd
			} else {
				pos := size - int(current)%int(size)
				barBox = pb.BarStart
				if pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, pos-1)
				}
				barBox += pb.Current
				if size-pos-1 > 0 {
					barBox += strings.Repeat(pb.Empty, size-pos-1)
				}
				barBox += pb.BarEnd
			}
		}
	}

	// check len
	out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
	if cl := escapeAwareRuneCountInString(out); cl < width {
		end = strings.Repeat(" ", width-cl)
	}

	// and print!
	pb.mu.Lock()
	pb.lastPrint = out + end
	isFinish := pb.isFinish
	pb.mu.Unlock()
	switch {
	case isFinish:
		return
	case pb.Output != nil:
		fmt.Fprint(pb.Output, "\r"+out+end)
	case pb.Callback != nil:
		pb.Callback(out + end)
	case !pb.NotPrint:
		fmt.Print("\r" + out + end)
	}
}

// GetTerminalWidth - returns terminal width for all platforms.
func GetTerminalWidth() (int, error) {
	return terminalWidth()
}

func (pb *ProgressBar) GetWidth() int {
	if pb.ForceWidth {
		return pb.Width
	}

	width := pb.Width
	termWidth, _ := terminalWidth()
	if width == 0 || termWidth <= width {
		width = termWidth
	}

	return width
}

// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
	c := atomic.LoadInt64(&pb.current)
	p := atomic.LoadInt64(&pb.previous)
	if p != c {
		pb.mu.Lock()
		pb.changeTime = time.Now()
		pb.mu.Unlock()
		atomic.StoreInt64(&pb.previous, c)
	}
	pb.write(c)
	if pb.AutoStat {
		if c == 0 {
			pb.startTime = time.Now()
			pb.startValue = 0
		} else if c >= pb.Total && pb.isFinish != true {
			pb.Finish()
		}
	}
}

// String return the last bar print
func (pb *ProgressBar) String() string {
	pb.mu.Lock()
	defer pb.mu.Unlock()
	return pb.lastPrint
}

// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
	for {
		select {
		case <-pb.finish:
			return
		case <-time.After(pb.RefreshRate):
			pb.Update()
		}
	}
}
<|endoftext|>


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

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/sdboyer/gps"
)

// Singletons aren't the best, but it's sufficient for experimentation
var sm *gps.SourceMgr

func getSourceManager() (*gps.SourceMgr, error) {
	if sm != nil {
		return sm, nil
	}

	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return nil, fmt.Errorf("GOPATH is not set")
	}
	// Use the first entry in GOPATH for the depcache
	first := filepath.SplitList(gopath)[0]

	return gps.NewSourceManager(analyzer{}, filepath.Join(first, "depcache"))
}
<commit_msg>Get rid of package-level var for SourceMgr<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/sdboyer/gps"
)

func getSourceManager() (*gps.SourceMgr, error) {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return nil, fmt.Errorf("GOPATH is not set")
	}
	// Use the first entry in GOPATH for the depcache
	first := filepath.SplitList(gopath)[0]

	return gps.NewSourceManager(analyzer{}, filepath.Join(first, "depcache"))
}
<|endoftext|>