<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	filepath "path"
	"strings"
)

const (
	LUNCHY_VERSION = "0.1.6"
)

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func fileCopy(src string, dst string) error {
	s, err := os.Open(src)
	if err != nil {
		return err
	}

	defer s.Close()

	d, err := os.Create(dst)
	if err != nil {
		return err
	}

	if _, err := io.Copy(d, s); err != nil {
		d.Close()
		return err
	}

	return d.Close()
}

func findPlists(path string) []string {
	output, err := exec.Command("find", path, "-name", "homebrew.*.plist", "-type", "f").Output()
	if err != nil {
		return []string{}
	}

	lines := strings.Split(strings.TrimSpace(string(output)), "\n")
	plists := []string{}

	for _, line := range lines {
		plists = append(plists, strings.Replace(filepath.Base(line), ".plist", "", 1))
	}

	return plists
}

func getPlists() []string {
	path := fmt.Sprintf("%s/Library/LaunchAgents", os.Getenv("HOME"))
	files := findPlists(path)

	return files
}

func getPlist(name string) string {
	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			return plist
		}
	}

	return ""
}

func sliceIncludes(slice []string, match string) bool {
	for _, val := range slice {
		if val == match {
			return true
		}
	}

	return false
}

func printUsage() {
	fmt.Printf("Lunchy %s, the friendly launchctl wrapper\n", LUNCHY_VERSION)
	fmt.Println("Usage: lunchy [start|stop|restart|list|status|install|show|edit|remove|scan] [options]")
}

func printList() {
	for _, file := range getPlists() {
		fmt.Println(file)
	}
}

func printStatus(args []string) {
	out, err := exec.Command("launchctl", "list").Output()

	if err != nil {
		fatal("failed to get process list")
	}

	pattern := ""

	if len(args) == 3 {
		pattern = args[2]
	}

	installed := getPlists()
	lines := strings.Split(strings.TrimSpace(string(out)), "\n")

	for _, line := range lines {
		chunks := strings.Split(line, "\t")
		clean_line := strings.Replace(line, "\t", " ", -1)

		if len(pattern) > 0 {
			if strings.Index(chunks[2], pattern) != -1 {
				if sliceIncludes(installed, chunks[2]) {
					fmt.Println(clean_line)
				}
			}
		} else {
			if sliceIncludes(installed, chunks[2]) {
				fmt.Println(clean_line)
			}
		}
	}
}

func exitWithInvalidArgs(args []string, msg string) {
	if len(args) < 3 {
		fmt.Println(msg)
		os.Exit(1)
	}
}

func startDaemons(args []string) {
	// Check if name pattern is not given and try profiles
	if len(args) == 2 {
		if profileExists() {
			startProfile()
			return
		} else {
			exitWithInvalidArgs(args, "name required")
		}
	}

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			startDaemon(plist)
		}
	}
}

func startDaemon(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	_, err := exec.Command("launchctl", "load", path).Output()

	if err != nil {
		fmt.Println("failed to start", name)
		return
	}

	fmt.Println("started", name)
}

func stopDaemons(args []string) {
	// Check if name pattern is not given and try profiles
	if len(args) == 2 {
		if profileExists() {
			stopProfile()
			return
		} else {
			exitWithInvalidArgs(args, "name required")
		}
	}

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			stopDaemon(plist)
		}
	}
}

func stopDaemon(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	_, err := exec.Command("launchctl", "unload", path).Output()

	if err != nil {
		fmt.Println("failed to stop", name)
		return
	}

	fmt.Println("stopped", name)
}

func restartDaemons(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			stopDaemon(plist)
			startDaemon(plist)
		}
	}
}

func showPlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			printPlistContent(plist)
			return
		}
	}
}

func printPlistContent(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	contents, err := ioutil.ReadFile(path)

	if err != nil {
		fatal("unable to read plist")
	}

	fmt.Printf(string(contents))
}

func editPlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			editPlistContent(plist)
			return
		}
	}
}

func editPlistContent(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	editor := os.Getenv("EDITOR")

	if len(editor) == 0 {
		fatal("EDITOR environment variable is not set")
	}

	cmd := exec.Command(editor, path)

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout

	cmd.Start()
	cmd.Wait()
}

func installPlist(args []string) {
	exitWithInvalidArgs(args, "path required")

	path := args[2]

	if !fileExists(path) {
		fatal("source file does not exist")
	}

	info, _ := os.Stat(path)
	base_path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")
	new_path := fmt.Sprintf("%s/%s", base_path, info.Name())

	if fileExists(new_path) && os.Remove(new_path) != nil {
		fatal("unable to delete existing plist")
	}

	if fileCopy(path, new_path) != nil {
		fatal("failed to copy file")
	}

	fmt.Println(path, "installed to", base_path)
}

func removePlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]
	base_path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			path := fmt.Sprintf("%s/%s.plist", base_path, plist)

			if os.Remove(path) == nil {
				fmt.Println("removed", path)
			} else {
				fmt.Println("failed to remove", path)
			}
		}
	}
}

func scanPath(args []string) {
	path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")

	if len(args) >= 3 {
		path = args[2]
	}

	// This is a handy override to find all homebrew-based lists
	if path == "homebrew" {
		path = "/usr/local/Cellar"
	}

	for _, f := range findPlists(path) {
		fmt.Println(f)
	}
}

// Get full path to lunchy profile file
func profilePath() string {
	dir, err := os.Getwd()
	if err != nil {
		return ""
	}
	return dir + "/.lunchy"
}

// Check if profile file exists
func profileExists() bool {
	return fileExists(profilePath())
}

// Get daemon names specified in lunchy profile
func readProfile() []string {
	path := profilePath()
	if path == "" {
		return []string{}
	}

	buff, err := ioutil.ReadFile(path)
	if err != nil {
		return []string{}
	}

	result := []string{}
	lines := strings.Split(strings.TrimSpace(string(buff)), "\n")

	for _, l := range lines {
		result = append(result, strings.TrimSpace(l))
	}

	return result
}

func startProfile() {
	fmt.Println("Starting daemons in profile:", profilePath())

	for _, name := range readProfile() {
		for _, plist := range getPlists() {
			if strings.Index(plist, name) != -1 {
				startDaemon(plist)
			}
		}
	}
}

func stopProfile() {
	fmt.Println("Stopping daemons in profile:", profilePath())

	for _, name := range readProfile() {
		for _, plist := range getPlists() {
			if strings.Index(plist, name) != -1 {
				stopDaemon(plist)
			}
		}
	}
}

func fatal(message string) {
	fmt.Println(message)
	os.Exit(1)
}

func main() {
	args := os.Args

	if len(args) == 1 {
		printUsage()
		os.Exit(1)
	}

	switch args[1] {
	default:
		printUsage()
		os.Exit(1)
	case "help":
		printUsage()
		return
	case "list", "ls":
		printList()
		return
	case "status", "ps":
		printStatus(args)
		return
	case "start":
		startDaemons(args)
		return
	case "stop":
		stopDaemons(args)
		return
	case "restart":
		restartDaemons(args)
		return
	case "show":
		showPlist(args)
		return
	case "edit":
		editPlist(args)
		return
	case "install", "add":
		installPlist(args)
		return
	case "remove", "rm":
		removePlist(args)
		return
	case "scan":
		scanPath(args)
		return
	}
}
<commit_msg>Add restart profile support<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	filepath "path"
	"strings"
)

const (
	LUNCHY_VERSION = "0.1.6"
)

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func fileCopy(src string, dst string) error {
	s, err := os.Open(src)
	if err != nil {
		return err
	}

	defer s.Close()

	d, err := os.Create(dst)
	if err != nil {
		return err
	}

	if _, err := io.Copy(d, s); err != nil {
		d.Close()
		return err
	}

	return d.Close()
}

func findPlists(path string) []string {
	output, err := exec.Command("find", path, "-name", "homebrew.*.plist", "-type", "f").Output()
	if err != nil {
		return []string{}
	}

	lines := strings.Split(strings.TrimSpace(string(output)), "\n")
	plists := []string{}

	for _, line := range lines {
		plists = append(plists, strings.Replace(filepath.Base(line), ".plist", "", 1))
	}

	return plists
}

func getPlists() []string {
	path := fmt.Sprintf("%s/Library/LaunchAgents", os.Getenv("HOME"))
	files := findPlists(path)

	return files
}

func getPlist(name string) string {
	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			return plist
		}
	}

	return ""
}

func sliceIncludes(slice []string, match string) bool {
	for _, val := range slice {
		if val == match {
			return true
		}
	}

	return false
}

func printUsage() {
	fmt.Printf("Lunchy %s, the friendly launchctl wrapper\n", LUNCHY_VERSION)
	fmt.Println("Usage: lunchy [start|stop|restart|list|status|install|show|edit|remove|scan] [options]")
}

func printList() {
	for _, file := range getPlists() {
		fmt.Println(file)
	}
}

func printStatus(args []string) {
	out, err := exec.Command("launchctl", "list").Output()

	if err != nil {
		fatal("failed to get process list")
	}

	pattern := ""

	if len(args) == 3 {
		pattern = args[2]
	}

	installed := getPlists()
	lines := strings.Split(strings.TrimSpace(string(out)), "\n")

	for _, line := range lines {
		chunks := strings.Split(line, "\t")
		clean_line := strings.Replace(line, "\t", " ", -1)

		if len(pattern) > 0 {
			if strings.Index(chunks[2], pattern) != -1 {
				if sliceIncludes(installed, chunks[2]) {
					fmt.Println(clean_line)
				}
			}
		} else {
			if sliceIncludes(installed, chunks[2]) {
				fmt.Println(clean_line)
			}
		}
	}
}

func exitWithInvalidArgs(args []string, msg string) {
	if len(args) < 3 {
		fmt.Println(msg)
		os.Exit(1)
	}
}

func startDaemons(args []string) {
	// Check if name pattern is not given and try profiles
	if len(args) == 2 {
		if profileExists() {
			startProfile()
			return
		} else {
			exitWithInvalidArgs(args, "name required")
		}
	}

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			startDaemon(plist)
		}
	}
}

func startDaemon(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	_, err := exec.Command("launchctl", "load", path).Output()

	if err != nil {
		fmt.Println("failed to start", name)
		return
	}

	fmt.Println("started", name)
}

func stopDaemons(args []string) {
	// Check if name pattern is not given and try profiles
	if len(args) == 2 {
		if profileExists() {
			stopProfile()
			return
		} else {
			exitWithInvalidArgs(args, "name required")
		}
	}

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			stopDaemon(plist)
		}
	}
}

func stopDaemon(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	_, err := exec.Command("launchctl", "unload", path).Output()

	if err != nil {
		fmt.Println("failed to stop", name)
		return
	}

	fmt.Println("stopped", name)
}

func restartDaemons(args []string) {
	// Check if name pattern is not given and try profiles
	if len(args) == 2 {
		if profileExists() {
			restartProfile()
			return
		} else {
			exitWithInvalidArgs(args, "name required")
		}
	}

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			stopDaemon(plist)
			startDaemon(plist)
		}
	}
}

func showPlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			printPlistContent(plist)
			return
		}
	}
}

func printPlistContent(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	contents, err := ioutil.ReadFile(path)

	if err != nil {
		fatal("unable to read plist")
	}

	fmt.Printf(string(contents))
}

func editPlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			editPlistContent(plist)
			return
		}
	}
}

func editPlistContent(name string) {
	path := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), name)
	editor := os.Getenv("EDITOR")

	if len(editor) == 0 {
		fatal("EDITOR environment variable is not set")
	}

	cmd := exec.Command(editor, path)

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout

	cmd.Start()
	cmd.Wait()
}

func installPlist(args []string) {
	exitWithInvalidArgs(args, "path required")

	path := args[2]

	if !fileExists(path) {
		fatal("source file does not exist")
	}

	info, _ := os.Stat(path)
	base_path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")
	new_path := fmt.Sprintf("%s/%s", base_path, info.Name())

	if fileExists(new_path) && os.Remove(new_path) != nil {
		fatal("unable to delete existing plist")
	}

	if fileCopy(path, new_path) != nil {
		fatal("failed to copy file")
	}

	fmt.Println(path, "installed to", base_path)
}

func removePlist(args []string) {
	exitWithInvalidArgs(args, "name required")

	name := args[2]
	base_path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")

	for _, plist := range getPlists() {
		if strings.Index(plist, name) != -1 {
			path := fmt.Sprintf("%s/%s.plist", base_path, plist)

			if os.Remove(path) == nil {
				fmt.Println("removed", path)
			} else {
				fmt.Println("failed to remove", path)
			}
		}
	}
}

func scanPath(args []string) {
	path := fmt.Sprintf("%s/%s", os.Getenv("HOME"), "Library/LaunchAgents")

	if len(args) >= 3 {
		path = args[2]
	}

	// This is a handy override to find all homebrew-based lists
	if path == "homebrew" {
		path = "/usr/local/Cellar"
	}

	for _, f := range findPlists(path) {
		fmt.Println(f)
	}
}

// Get full path to lunchy profile file
func profilePath() string {
	dir, err := os.Getwd()
	if err != nil {
		return ""
	}
	return dir + "/.lunchy"
}

// Check if profile file exists
func profileExists() bool {
	return fileExists(profilePath())
}

// Get daemon names specified in lunchy profile
func readProfile() []string {
	path := profilePath()
	if path == "" {
		return []string{}
	}

	buff, err := ioutil.ReadFile(path)
	if err != nil {
		return []string{}
	}

	result := []string{}
	lines := strings.Split(strings.TrimSpace(string(buff)), "\n")

	for _, l := range lines {
		result = append(result, strings.TrimSpace(l))
	}

	return result
}

func startProfile() {
	fmt.Println("Starting daemons in profile:", profilePath())

	for _, name := range readProfile() {
		for _, plist := range getPlists() {
			if strings.Index(plist, name) != -1 {
				startDaemon(plist)
			}
		}
	}
}

func stopProfile() {
	fmt.Println("Stopping daemons in profile:", profilePath())

	for _, name := range readProfile() {
		for _, plist := range getPlists() {
			if strings.Index(plist, name) != -1 {
				stopDaemon(plist)
			}
		}
	}
}

func restartProfile() {
	fmt.Println("Restarting daemons in profile:", profilePath())

	for _, name := range readProfile() {
		for _, plist := range getPlists() {
			if strings.Index(plist, name) != -1 {
				stopDaemon(plist)
				startDaemon(plist)
			}
		}
	}
}

func fatal(message string) {
	fmt.Println(message)
	os.Exit(1)
}

func main() {
	args := os.Args

	if len(args) == 1 {
		printUsage()
		os.Exit(1)
	}

	switch args[1] {
	default:
		printUsage()
		os.Exit(1)
	case "help":
		printUsage()
		return
	case "list", "ls":
		printList()
		return
	case "status", "ps":
		printStatus(args)
		return
	case "start":
		startDaemons(args)
		return
	case "stop":
		stopDaemons(args)
		return
	case "restart":
		restartDaemons(args)
		return
	case "show":
		showPlist(args)
		return
	case "edit":
		editPlist(args)
		return
	case "install", "add":
		installPlist(args)
		return
	case "remove", "rm":
		removePlist(args)
		return
	case "scan":
		scanPath(args)
		return
	}
}
<|endoftext|>


<commit_before>package concrete

import (
	"errors"
	"math"
	"strings"

	gr "github.com/gonum/graph"
)

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

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

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

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

	tiles := make([]bool, 0)

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

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

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

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

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

	graph.tiles[loc] = passability
}

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

		outString += "\n"
	}

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

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

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

		outString += "\n"
	}

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

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

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

	return row, col
}

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

	return id
}

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

func (graph *TileGraph) successors(node gr.Node) []gr.Node {
	id := node.ID()
	if id < 0 || id >= len(graph.tiles) || graph.tiles[id] == false {
		return nil
	}

	row, col := graph.IDToCoords(id)

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

	return realNeighbors
}

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

func (graph *TileGraph) predecessors(node gr.Node) []gr.Node {
	return graph.successors(node)
}

func (graph *TileGraph) isPredecessor(node, pred gr.Node) bool {
	return graph.isSuccessor(node, pred)
}

func (graph *TileGraph) Neighbors(node gr.Node) []gr.Node {
	return graph.successors(node)
}

func (graph *TileGraph) IsNeighbor(id, neighbor gr.Node) bool {
	return graph.isSuccessor(id, neighbor)
}

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

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

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

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

	return edges
}

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

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

	return nodes
}

func (graph *TileGraph) IsDirected() bool {
	return false
}

func (graph *TileGraph) Cost(node1, node2 gr.Node) float64 {
	if graph.IsNeighbor(node1, node2) {
		return 1.0
	} else {
		return math.Inf(1)
	}
}
<commit_msg>Gofmt'd renamed edge and node<commit_after>package concrete

import (
	"errors"
	"math"
	"strings"

	gr "github.com/gonum/graph"
)

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

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

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

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

	tiles := make([]bool, 0)

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

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

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

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

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

	graph.tiles[loc] = passability
}

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

		outString += "\n"
	}

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

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

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

		outString += "\n"
	}

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

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

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

	return row, col
}

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

	return id
}

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

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

	row, col := graph.IDToCoords(id)

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

	return realNeighbors
}

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

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

	return nil
}

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

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

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

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

	return edges
}

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

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

	return nodes
}

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

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


<commit_before>package snakes

import (
    "math/big"
    "testing"
)

func check(t *testing.T, a, b, c int) {
    big_a := big.NewInt(int64(a))
    big_b := big.NewInt(int64(b))
    big_c := big.NewInt(int64(c))
    z := new(big.Int)
    z.Exp(big_a, big_b, big_c)
    got := MontgomeryLadderExp(big_a, big_b, big_c)
    if (got.Cmp(z) != 0) {
        t.Errorf("pow(%d, %d, %d) Expected: %s, got %s", a, b, c, z.String(), got.String())
    }
}

func TestMontgomeryLadderModExp(t *testing.T) {
    check(t, 0, 0, 1)
    check(t, 0, 1, 1)
    check(t, 1, 0, 1)
    check(t, 2, 10, 1)
    check(t, 4, 13, 1)
    check(t, 13, 4, 1)
    check(t, 2, 10, 15)
    check(t, 3, 10, 15)
    check(t, 13, 4, 7)
    check(t, 19, 65, 3)
    check(t, 1432, 432, 123)
}
<commit_msg>More readable<commit_after>package snakes

import (
    "math/big"
    "testing"
)

func check(t *testing.T, a, b, c int) {
    big_a := big.NewInt(int64(a))
    big_b := big.NewInt(int64(b))
    big_c := big.NewInt(int64(c))
    z := new(big.Int).Exp(big_a, big_b, big_c)
    got := MontgomeryLadderExp(big_a, big_b, big_c)
    if (got.Cmp(z) != 0) {
        t.Errorf("pow(%d, %d, %d) Expected: %s, got %s", a, b, c, z.String(), got.String())
    }
}

func TestMontgomeryLadderModExp(t *testing.T) {
    check(t, 0, 0, 1)
    check(t, 0, 1, 1)
    check(t, 1, 0, 1)
    check(t, 2, 10, 1)
    check(t, 4, 13, 1)
    check(t, 13, 4, 1)
    check(t, 2, 10, 15)
    check(t, 3, 10, 15)
    check(t, 13, 4, 7)
    check(t, 19, 65, 3)
    check(t, 1432, 432, 123)
}
<|endoftext|>


<commit_before>/*
Copyright 2017 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 util

import (
	"encoding/json"
	"fmt"
	"go/build"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// K8s returns $GOPATH/src/k8s.io/...
func K8s(projectName string, parts ...string) string {
	return getProjectDir("k8s.io", projectName, parts...)
}

// K8sSigs returns $GOPATH/src/sigs.k8s.io/...
func K8sSigs(projectName string, parts ...string) string {
	return getProjectDir("sigs.k8s.io", projectName, parts...)
}

// GetProjectDir returns $GOPATH/src/<project-namespace>/...
func getProjectDir(namespace, projectName string, parts ...string) string {
	gopathList := filepath.SplitList(build.Default.GOPATH)
	found := false
	var projectDir string
	for _, gopath := range gopathList {
		projectDir = filepath.Join(gopath, "src", namespace, projectName)
		if _, err := os.Stat(projectDir); !os.IsNotExist(err) {
			found = true
			break
		}
	}
	if !found {
		// Default to the first item in GOPATH list.
		projectDir = filepath.Join(gopathList[0], "src", "k8s.io", projectName)
		log.Printf(
			"Warning: Couldn't find directory src/%s/%s under any of GOPATH %s, defaulting to %s",
			namespace, projectName, build.Default.GOPATH, projectDir)
	}
	p := []string{projectDir}
	p = append(p, parts...)
	return filepath.Join(p...)
}

// AppendError does append(errs, err) if err != nil
func AppendError(errs []error, err error) []error {
	if err != nil {
		return append(errs, err)
	}
	return errs
}

// Home returns $HOME/part/part/part
func Home(parts ...string) string {
	p := []string{os.Getenv("HOME")}
	for _, a := range parts {
		p = append(p, a)
	}
	return filepath.Join(p...)
}

// InsertPath does export PATH=path:$PATH
func InsertPath(path string) error {
	return os.Setenv("PATH", fmt.Sprintf("%v:%v", path, os.Getenv("PATH")))
}

// OptionalAbsPath returns an absolute path if the provided path wasn't empty, and otherwise
// returns an empty string.
func OptionalAbsPath(path string) (string, error) {
	if path == "" {
		return "", nil
	}

	return filepath.Abs(path)
}

// JoinURL converts input (gs://foo, "bar") to gs://foo/bar
func JoinURL(urlPath, path string) (string, error) {
	u, err := url.Parse(urlPath)
	if err != nil {
		return "", err
	}
	u.Path = filepath.Join(u.Path, path)
	return u.String(), nil
}

// Pushd will Chdir() to dir and return a function to cd back to Getwd()
func Pushd(dir string) (func() error, error) {
	old, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("failed to os.Getwd(): %v", err)
	}
	if err = os.Chdir(dir); err != nil {
		return nil, err
	}
	return func() error {
		return os.Chdir(old)
	}, nil
}

// PushEnv pushes env=value and return a function that resets env
func PushEnv(env, value string) (func() error, error) {
	prev, present := os.LookupEnv(env)
	if err := os.Setenv(env, value); err != nil {
		return nil, fmt.Errorf("could not set %s: %v", env, err)
	}
	return func() error {
		if present {
			return os.Setenv(env, prev)
		}
		return os.Unsetenv(env)
	}, nil
}

// MigratedOption is an option that was an ENV that is now a --flag
type MigratedOption struct {
	Env      string  // env associated with --flag
	Option   *string // Value of --flag
	Name     string  // --flag name
	SkipPush bool    // Push option to env if false
}

// MigrateOptions reads value from ENV if --flag unset, optionally pushing to ENV
func MigrateOptions(m []MigratedOption) error {
	for _, s := range m {
		if *s.Option == "" {
			// Jobs may not be using --foo instead of FOO just yet, so ease the transition
			// TODO(fejta): require --foo instead of FOO
			v := os.Getenv(s.Env) // expected Getenv
			if v != "" {
				// Tell people to use --foo=blah instead of FOO=blah
				log.Printf("Please use kubetest %s=%s (instead of deprecated %s=%s)", s.Name, v, s.Env, v)
				*s.Option = v
			}
		}
		if s.SkipPush {
			continue
		}
		// Script called by kubetest may expect these values to be set, so set them
		// TODO(fejta): refactor the scripts below kubetest to use explicit config
		if *s.Option == "" {
			continue
		}
		if err := os.Setenv(s.Env, *s.Option); err != nil {
			return fmt.Errorf("could not set %s=%s: %v", s.Env, *s.Option, err)
		}
	}
	return nil
}

// AppendField will append prefix to the flag value.
//
// For example, AppendField(fields, "--foo", "bar") if fields is empty or does
// not contain a "--foo" it will simply append a "--foo=bar" value.
// Otherwise if fields contains "--foo=current" it will replace this value with
// "--foo=current-bar
func AppendField(fields []string, flag, prefix string) []string {
	fields, cur, _ := ExtractField(fields, flag)
	if len(cur) == 0 {
		cur = prefix
	} else {
		cur += "-" + prefix
	}
	return append(fields, flag+"="+cur)
}

// SetFieldDefault sets the value of flag to val if flag is not present in fields.
//
// For example, SetFieldDefault(fields, "--foo", "bar") will append "--foo=bar" if
// fields is empty or does not include a "--foo" flag.
// It returns fields unchanged if "--foo" is present.
func SetFieldDefault(fields []string, flag, val string) []string {
	fields, cur, present := ExtractField(fields, flag)
	if !present {
		cur = val
	}
	return append(fields, flag+"="+cur)
}

// ExtractField input ("--a=this --b=that --c=other", "--b") returns [--a=this, --c=other"], "that", true
//
// In other words, it will remove "--b" from fields and return the previous value of "--b" if it was set.
func ExtractField(fields []string, target string) ([]string, string, bool) {
	f := []string{}
	prefix := target + "="
	consumeNext := false
	done := false
	r := ""
	for _, field := range fields {
		switch {
		case done:
			f = append(f, field)
		case consumeNext:
			r = field
			done = true
		case field == target:
			consumeNext = true
		case strings.HasPrefix(field, prefix):
			r = strings.SplitN(field, "=", 2)[1]
			done = true
		default:
			f = append(f, field)
		}
	}
	return f, r, done
}

// ExecError returns a string format of err including stderr if the
// err is an ExitError, useful for errors from e.g. exec.Cmd.Output().
func ExecError(err error) string {
	if ee, ok := err.(*exec.ExitError); ok {
		return fmt.Sprintf("%v (output: %q)", err, string(ee.Stderr))
	}
	return err.Error()
}

// EnsureExecutable sets the executable file mode bits, for all users, to ensure that we can execute a file
func EnsureExecutable(p string) error {
	s, err := os.Stat(p)
	if err != nil {
		return fmt.Errorf("error doing stat on %q: %v", p, err)
	}
	if err := os.Chmod(p, s.Mode()|0111); err != nil {
		return fmt.Errorf("error doing chmod on %q: %v", p, err)
	}
	return nil
}

// JSONForDebug returns a json representation of the value, or a string representation of an error
// It is useful for an easy implementation of fmt.Stringer
func JSONForDebug(o interface{}) string {
	if o == nil {
		return "nil"
	}
	v, err := json.Marshal(o)
	if err != nil {
		return fmt.Sprintf("error[%v]", err)
	}
	return string(v)
}

// FlushMem will try to reduce the memory usage of the container it is running in
// run this after a build
func FlushMem() {
	log.Println("Flushing memory.")
	// it's ok if these fail
	// flush memory buffers
	err := exec.Command("sync").Run()
	if err != nil {
		log.Printf("flushMem error (sync): %v", err)
	}
	// clear page cache
	err = exec.Command("bash", "-c", "echo 1 > /proc/sys/vm/drop_caches").Run()
	if err != nil {
		log.Printf("flushMem error (page cache): %v", err)
	}
}
<commit_msg>Stop assuming GOPATH is non-empty<commit_after>/*
Copyright 2017 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 util

import (
	"encoding/json"
	"fmt"
	"go/build"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// K8s returns $GOPATH/src/k8s.io/...
func K8s(projectName string, parts ...string) string {
	return getProjectDir("k8s.io", projectName, parts...)
}

// K8sSigs returns $GOPATH/src/sigs.k8s.io/...
func K8sSigs(projectName string, parts ...string) string {
	return getProjectDir("sigs.k8s.io", projectName, parts...)
}

// GetProjectDir returns $GOPATH/src/<project-namespace>/...
func getProjectDir(namespace, projectName string, parts ...string) string {
	gopathList := filepath.SplitList(build.Default.GOPATH)
	var found bool
	var projectDir string
	for _, gopath := range gopathList {
		projectDir = filepath.Join(gopath, "src", namespace, projectName)
		if _, err := os.Stat(projectDir); !os.IsNotExist(err) {
			found = true
			break
		}
	}
	if !found && len(gopathList) > 0 {
		// Default to the first item in GOPATH list.
		projectDir = filepath.Join(gopathList[0], "src", "k8s.io", projectName)
		log.Printf(
			"Warning: Couldn't find directory src/%s/%s under any of GOPATH %s, defaulting to %s",
			namespace, projectName, build.Default.GOPATH, projectDir)
	}
	p := []string{projectDir}
	p = append(p, parts...)
	return filepath.Join(p...)
}

// AppendError does append(errs, err) if err != nil
func AppendError(errs []error, err error) []error {
	if err != nil {
		return append(errs, err)
	}
	return errs
}

// Home returns $HOME/part/part/part
func Home(parts ...string) string {
	p := []string{os.Getenv("HOME")}
	for _, a := range parts {
		p = append(p, a)
	}
	return filepath.Join(p...)
}

// InsertPath does export PATH=path:$PATH
func InsertPath(path string) error {
	return os.Setenv("PATH", fmt.Sprintf("%v:%v", path, os.Getenv("PATH")))
}

// OptionalAbsPath returns an absolute path if the provided path wasn't empty, and otherwise
// returns an empty string.
func OptionalAbsPath(path string) (string, error) {
	if path == "" {
		return "", nil
	}

	return filepath.Abs(path)
}

// JoinURL converts input (gs://foo, "bar") to gs://foo/bar
func JoinURL(urlPath, path string) (string, error) {
	u, err := url.Parse(urlPath)
	if err != nil {
		return "", err
	}
	u.Path = filepath.Join(u.Path, path)
	return u.String(), nil
}

// Pushd will Chdir() to dir and return a function to cd back to Getwd()
func Pushd(dir string) (func() error, error) {
	old, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("failed to os.Getwd(): %v", err)
	}
	if err = os.Chdir(dir); err != nil {
		return nil, err
	}
	return func() error {
		return os.Chdir(old)
	}, nil
}

// PushEnv pushes env=value and return a function that resets env
func PushEnv(env, value string) (func() error, error) {
	prev, present := os.LookupEnv(env)
	if err := os.Setenv(env, value); err != nil {
		return nil, fmt.Errorf("could not set %s: %v", env, err)
	}
	return func() error {
		if present {
			return os.Setenv(env, prev)
		}
		return os.Unsetenv(env)
	}, nil
}

// MigratedOption is an option that was an ENV that is now a --flag
type MigratedOption struct {
	Env      string  // env associated with --flag
	Option   *string // Value of --flag
	Name     string  // --flag name
	SkipPush bool    // Push option to env if false
}

// MigrateOptions reads value from ENV if --flag unset, optionally pushing to ENV
func MigrateOptions(m []MigratedOption) error {
	for _, s := range m {
		if *s.Option == "" {
			// Jobs may not be using --foo instead of FOO just yet, so ease the transition
			// TODO(fejta): require --foo instead of FOO
			v := os.Getenv(s.Env) // expected Getenv
			if v != "" {
				// Tell people to use --foo=blah instead of FOO=blah
				log.Printf("Please use kubetest %s=%s (instead of deprecated %s=%s)", s.Name, v, s.Env, v)
				*s.Option = v
			}
		}
		if s.SkipPush {
			continue
		}
		// Script called by kubetest may expect these values to be set, so set them
		// TODO(fejta): refactor the scripts below kubetest to use explicit config
		if *s.Option == "" {
			continue
		}
		if err := os.Setenv(s.Env, *s.Option); err != nil {
			return fmt.Errorf("could not set %s=%s: %v", s.Env, *s.Option, err)
		}
	}
	return nil
}

// AppendField will append prefix to the flag value.
//
// For example, AppendField(fields, "--foo", "bar") if fields is empty or does
// not contain a "--foo" it will simply append a "--foo=bar" value.
// Otherwise if fields contains "--foo=current" it will replace this value with
// "--foo=current-bar
func AppendField(fields []string, flag, prefix string) []string {
	fields, cur, _ := ExtractField(fields, flag)
	if len(cur) == 0 {
		cur = prefix
	} else {
		cur += "-" + prefix
	}
	return append(fields, flag+"="+cur)
}

// SetFieldDefault sets the value of flag to val if flag is not present in fields.
//
// For example, SetFieldDefault(fields, "--foo", "bar") will append "--foo=bar" if
// fields is empty or does not include a "--foo" flag.
// It returns fields unchanged if "--foo" is present.
func SetFieldDefault(fields []string, flag, val string) []string {
	fields, cur, present := ExtractField(fields, flag)
	if !present {
		cur = val
	}
	return append(fields, flag+"="+cur)
}

// ExtractField input ("--a=this --b=that --c=other", "--b") returns [--a=this, --c=other"], "that", true
//
// In other words, it will remove "--b" from fields and return the previous value of "--b" if it was set.
func ExtractField(fields []string, target string) ([]string, string, bool) {
	f := []string{}
	prefix := target + "="
	consumeNext := false
	done := false
	r := ""
	for _, field := range fields {
		switch {
		case done:
			f = append(f, field)
		case consumeNext:
			r = field
			done = true
		case field == target:
			consumeNext = true
		case strings.HasPrefix(field, prefix):
			r = strings.SplitN(field, "=", 2)[1]
			done = true
		default:
			f = append(f, field)
		}
	}
	return f, r, done
}

// ExecError returns a string format of err including stderr if the
// err is an ExitError, useful for errors from e.g. exec.Cmd.Output().
func ExecError(err error) string {
	if ee, ok := err.(*exec.ExitError); ok {
		return fmt.Sprintf("%v (output: %q)", err, string(ee.Stderr))
	}
	return err.Error()
}

// EnsureExecutable sets the executable file mode bits, for all users, to ensure that we can execute a file
func EnsureExecutable(p string) error {
	s, err := os.Stat(p)
	if err != nil {
		return fmt.Errorf("error doing stat on %q: %v", p, err)
	}
	if err := os.Chmod(p, s.Mode()|0111); err != nil {
		return fmt.Errorf("error doing chmod on %q: %v", p, err)
	}
	return nil
}

// JSONForDebug returns a json representation of the value, or a string representation of an error
// It is useful for an easy implementation of fmt.Stringer
func JSONForDebug(o interface{}) string {
	if o == nil {
		return "nil"
	}
	v, err := json.Marshal(o)
	if err != nil {
		return fmt.Sprintf("error[%v]", err)
	}
	return string(v)
}

// FlushMem will try to reduce the memory usage of the container it is running in
// run this after a build
func FlushMem() {
	log.Println("Flushing memory.")
	// it's ok if these fail
	// flush memory buffers
	err := exec.Command("sync").Run()
	if err != nil {
		log.Printf("flushMem error (sync): %v", err)
	}
	// clear page cache
	err = exec.Command("bash", "-c", "echo 1 > /proc/sys/vm/drop_caches").Run()
	if err != nil {
		log.Printf("flushMem error (page cache): %v", err)
	}
}
<|endoftext|>


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

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file provides a REPL.

package golisp

import (
	"fmt"
)

func Repl() {
	fmt.Printf("Welcome to GoLisp\n")
	fmt.Printf("Copyright 2014 SteelSeries\n")
	fmt.Printf("Evaluate '(quit)' to exit.\n\n")
	prompt := "> "
	LoadHistoryFromFile(".golisp_history")
	lastInput := ""
	for true {
		input := *ReadLine(&prompt)
		if input != "" {
			if input != lastInput {
				AddHistory(input)
			}
			lastInput = input
			code, err := Parse(input)
			if err != nil {
				fmt.Printf("Error: %s\n", err)
			} else {
				d, err := Eval(code, Global)
				if err != nil {
					fmt.Printf("Error in evaluation: %s\n", err)
				} else {
					fmt.Printf("==> %s\n", String(d))
				}
			}
		}
	}
}
<commit_msg>Improve repl error handling<commit_after>// Copyright 2014 SteelSeries ApS.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This package implements a basic LISP interpretor for embedding in a go program for scripting.
// This file provides a REPL.

package golisp

import (
	"fmt"
)

func Repl() {
	fmt.Printf("Welcome to GoLisp\n")
	fmt.Printf("Copyright 2014 SteelSeries\n")
	fmt.Printf("Evaluate '(quit)' to exit.\n\n")
	prompt := "> "
	LoadHistoryFromFile(".golisp_history")
	lastInput := ""
	for true {
		defer func() {
			if x := recover(); x != nil {
				println("BANG!")
			}
		}()
		input := *ReadLine(&prompt)
		if input != "" {
			if input != lastInput {
				AddHistory(input)
			}
			lastInput = input
			code, err := Parse(input)
			if err != nil {
				fmt.Printf("Error: %s\n", err)
			} else {
				d, err := Eval(code, Global)
				if err != nil {
					fmt.Printf("Error in evaluation: %s\n", err)
				} else {
					fmt.Printf("==> %s\n", String(d))
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>// Package vcs provides the ability to work with varying version control systems
// (VCS),  also known as source control systems (SCM) though the same interface.
//
// This package includes a function that attempts to detect the repo type from
// the remote URL and return the proper type. For example,
//
//     remote := "https://github.com/Masterminds/vcs"
//     local, _ := ioutil.TempDir("", "go-vcs")
//     repo, err := NewRepo(remote, local)
//
// In this case repo will be a GitRepo instance. NewRepo can detect the VCS for
// numerous popular VCS and from the URL. For example, a URL ending in .git
// that's not from one of the popular VCS will be detected as a Git repo and
// the correct type will be returned.
//
// If you know the repository type and would like to create an instance of a
// specific type you can use one of constructors for a type. They are NewGitRepo,
// NewSvnRepo, NewBzrRepo, and NewHgRepo. The definition and usage is the same
// as NewRepo.
//
// Once you have an object implementing the Repo interface the operations are
// the same no matter which VCS you're using. There are some caveats. For
// example, each VCS has its own version formats that need to be respected and
// checkout out branches, if a branch is being worked with, is different in
// each VCS.
package vcs

import (
	"errors"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"regexp"
)

var (
	// ErrWrongVCS is returned when an action is tried on the wrong VCS.
	ErrWrongVCS = errors.New("Wrong VCS detected")

	// ErrCannotDetectVCS is returned when VCS cannot be detected from URI string.
	ErrCannotDetectVCS = errors.New("Cannot detect VCS")

	// ErrWrongRemote occurs when the passed in remote does not match the VCS
	// configured endpoint.
	ErrWrongRemote = errors.New("The Remote does not match the VCS endpoint")
)

// Logger is where you can provide a logger, implementing the log.Logger interface,
// where verbose output from each VCS will be written. The default logger does
// not log data. To log data supply your own logger or change the output location
// of the provided logger.
var Logger *log.Logger

func init() {
	// Initialize the logger to one that does not actually log anywhere. This is
	// to be overridden by the package user by setting vcs.Logger to a different
	// logger.
	Logger = log.New(ioutil.Discard, "go-vcs", log.LstdFlags)
}

// Type describes the type of VCS
type Type string

// VCS types
const (
	NoVCS Type = ""
	Git   Type = "git"
	Svn   Type = "svn"
	Bzr   Type = "bzr"
	Hg    Type = "hg"
)

// Repo provides an interface to work with repositories using different source
// control systems such as Git, Bzr, Mercurial, and SVN. For implementations
// of this interface see BzrRepo, GitRepo, HgRepo, and SvnRepo.
type Repo interface {

	// Vcs retrieves the underlying VCS being implemented.
	Vcs() Type

	// Remote retrieves the remote location for a repo.
	Remote() string

	// LocalPath retrieves the local file system location for a repo.
	LocalPath() string

	// Get is used to perform an initial clone/checkout of a repository.
	Get() error

	// Update performs an update to an existing checkout of a repository.
	Update() error

	// UpdateVersion sets the version of a package of a repository.
	UpdateVersion(string) error

	// Version retrieves the current version.
	Version() (string, error)

	// CheckLocal verifies the local location is of the correct VCS type
	CheckLocal() bool

	// // Branches returns a list of available branches on the repository.
	// Branches() []string
	//
	// // Tags returns a list of available tags on the repository.
	// Tags() []string
}

// NewRepo returns a Repo based on trying to detect the source control from the
// remote and local locations. The appropriate implementation will be returned
// or an ErrCannotDetectVCS if the VCS type cannot be detected.
// Note, this function may make calls to the Internet to determind help determine
// the VCS.
func NewRepo(remote, local string) (Repo, error) {
	vtype, remote, err := detectVcsFromRemote(remote)

	// From the remote URL the VCS could not be detected. See if the local
	// repo contains enough information to figure out the VCS. The reason the
	// local repo is not checked first is because of the potential for VCS type
	// switches which will be detected in each of the type builders.
	if err == ErrCannotDetectVCS {
		vtype, err = DetectVcsFromFS(local)
	}

	if err != nil {
		return nil, err
	}

	switch vtype {
	case Git:
		return NewGitRepo(remote, local)
	case Svn:
		return NewSvnRepo(remote, local)
	case Hg:
		return NewHgRepo(remote, local)
	case Bzr:
		return NewBzrRepo(remote, local)
	}

	// Should never fall through to here but just in case.
	return nil, ErrCannotDetectVCS
}

type base struct {
	remote, local string
	Logger        *log.Logger
}

func (b *base) log(v interface{}) {
	b.Logger.Printf("%s", v)
}

// Remote retrieves the remote location for a repo.
func (b *base) Remote() string {
	return b.remote
}

// LocalPath retrieves the local file system location for a repo.
func (b *base) LocalPath() string {
	return b.local
}

func (b *base) setRemote(remote string) {
	b.remote = remote
}

func (b *base) setLocalPath(local string) {
	b.local = local
}

func (b base) run(cmd string, args ...string) ([]byte, error) {
	out, err := exec.Command(cmd, args...).CombinedOutput()
	b.log(out)
	return out, err
}

func (b *base) runFromDir(cmd string, args ...string) ([]byte, error) {
	oldDir, err := os.Getwd()
	if err != nil {
		return []byte(""), err
	}
	os.Chdir(b.local)
	defer os.Chdir(oldDir)

	out, err := b.run(cmd, args...)

	return out, err
}

func (b *base) referenceList(c, r string) []string {
	var out []string
	re := regexp.MustCompile(r)
	for _, m := range re.FindAllStringSubmatch(c, -1) {
		out = append(out, m[1])
	}

	return out
}
<commit_msg>Updated the interface for the new branches and tags<commit_after>// Package vcs provides the ability to work with varying version control systems
// (VCS),  also known as source control systems (SCM) though the same interface.
//
// This package includes a function that attempts to detect the repo type from
// the remote URL and return the proper type. For example,
//
//     remote := "https://github.com/Masterminds/vcs"
//     local, _ := ioutil.TempDir("", "go-vcs")
//     repo, err := NewRepo(remote, local)
//
// In this case repo will be a GitRepo instance. NewRepo can detect the VCS for
// numerous popular VCS and from the URL. For example, a URL ending in .git
// that's not from one of the popular VCS will be detected as a Git repo and
// the correct type will be returned.
//
// If you know the repository type and would like to create an instance of a
// specific type you can use one of constructors for a type. They are NewGitRepo,
// NewSvnRepo, NewBzrRepo, and NewHgRepo. The definition and usage is the same
// as NewRepo.
//
// Once you have an object implementing the Repo interface the operations are
// the same no matter which VCS you're using. There are some caveats. For
// example, each VCS has its own version formats that need to be respected and
// checkout out branches, if a branch is being worked with, is different in
// each VCS.
package vcs

import (
	"errors"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"regexp"
)

var (
	// ErrWrongVCS is returned when an action is tried on the wrong VCS.
	ErrWrongVCS = errors.New("Wrong VCS detected")

	// ErrCannotDetectVCS is returned when VCS cannot be detected from URI string.
	ErrCannotDetectVCS = errors.New("Cannot detect VCS")

	// ErrWrongRemote occurs when the passed in remote does not match the VCS
	// configured endpoint.
	ErrWrongRemote = errors.New("The Remote does not match the VCS endpoint")
)

// Logger is where you can provide a logger, implementing the log.Logger interface,
// where verbose output from each VCS will be written. The default logger does
// not log data. To log data supply your own logger or change the output location
// of the provided logger.
var Logger *log.Logger

func init() {
	// Initialize the logger to one that does not actually log anywhere. This is
	// to be overridden by the package user by setting vcs.Logger to a different
	// logger.
	Logger = log.New(ioutil.Discard, "go-vcs", log.LstdFlags)
}

// Type describes the type of VCS
type Type string

// VCS types
const (
	NoVCS Type = ""
	Git   Type = "git"
	Svn   Type = "svn"
	Bzr   Type = "bzr"
	Hg    Type = "hg"
)

// Repo provides an interface to work with repositories using different source
// control systems such as Git, Bzr, Mercurial, and SVN. For implementations
// of this interface see BzrRepo, GitRepo, HgRepo, and SvnRepo.
type Repo interface {

	// Vcs retrieves the underlying VCS being implemented.
	Vcs() Type

	// Remote retrieves the remote location for a repo.
	Remote() string

	// LocalPath retrieves the local file system location for a repo.
	LocalPath() string

	// Get is used to perform an initial clone/checkout of a repository.
	Get() error

	// Update performs an update to an existing checkout of a repository.
	Update() error

	// UpdateVersion sets the version of a package of a repository.
	UpdateVersion(string) error

	// Version retrieves the current version.
	Version() (string, error)

	// CheckLocal verifies the local location is of the correct VCS type
	CheckLocal() bool

	// Branches returns a list of available branches on the repository.
	Branches() ([]string, error)

	// Tags returns a list of available tags on the repository.
	Tags() ([]string, error)
}

// NewRepo returns a Repo based on trying to detect the source control from the
// remote and local locations. The appropriate implementation will be returned
// or an ErrCannotDetectVCS if the VCS type cannot be detected.
// Note, this function may make calls to the Internet to determind help determine
// the VCS.
func NewRepo(remote, local string) (Repo, error) {
	vtype, remote, err := detectVcsFromRemote(remote)

	// From the remote URL the VCS could not be detected. See if the local
	// repo contains enough information to figure out the VCS. The reason the
	// local repo is not checked first is because of the potential for VCS type
	// switches which will be detected in each of the type builders.
	if err == ErrCannotDetectVCS {
		vtype, err = DetectVcsFromFS(local)
	}

	if err != nil {
		return nil, err
	}

	switch vtype {
	case Git:
		return NewGitRepo(remote, local)
	case Svn:
		return NewSvnRepo(remote, local)
	case Hg:
		return NewHgRepo(remote, local)
	case Bzr:
		return NewBzrRepo(remote, local)
	}

	// Should never fall through to here but just in case.
	return nil, ErrCannotDetectVCS
}

type base struct {
	remote, local string
	Logger        *log.Logger
}

func (b *base) log(v interface{}) {
	b.Logger.Printf("%s", v)
}

// Remote retrieves the remote location for a repo.
func (b *base) Remote() string {
	return b.remote
}

// LocalPath retrieves the local file system location for a repo.
func (b *base) LocalPath() string {
	return b.local
}

func (b *base) setRemote(remote string) {
	b.remote = remote
}

func (b *base) setLocalPath(local string) {
	b.local = local
}

func (b base) run(cmd string, args ...string) ([]byte, error) {
	out, err := exec.Command(cmd, args...).CombinedOutput()
	b.log(out)
	return out, err
}

func (b *base) runFromDir(cmd string, args ...string) ([]byte, error) {
	oldDir, err := os.Getwd()
	if err != nil {
		return []byte(""), err
	}
	os.Chdir(b.local)
	defer os.Chdir(oldDir)

	out, err := b.run(cmd, args...)

	return out, err
}

func (b *base) referenceList(c, r string) []string {
	var out []string
	re := regexp.MustCompile(r)
	for _, m := range re.FindAllStringSubmatch(c, -1) {
		out = append(out, m[1])
	}

	return out
}
<|endoftext|>


<commit_before>// Package repr attempts to represent Go values in a form that can be copy-and-pasted into source
// code directly.
//
// Some values (such as pointers to basic types) can not be represented directly in
// Go. These values will be output as `&<value>`. eg. `&23`
package repr

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"reflect"
	"sort"
	"time"
	"unsafe"
)

var (
	// "Real" names of basic kinds, used to differentiate type aliases.
	realKindName = map[reflect.Kind]string{
		reflect.Bool:       "bool",
		reflect.Int:        "int",
		reflect.Int8:       "int8",
		reflect.Int16:      "int16",
		reflect.Int32:      "int32",
		reflect.Int64:      "int64",
		reflect.Uint:       "uint",
		reflect.Uint8:      "uint8",
		reflect.Uint16:     "uint16",
		reflect.Uint32:     "uint32",
		reflect.Uint64:     "uint64",
		reflect.Uintptr:    "uintptr",
		reflect.Float32:    "float32",
		reflect.Float64:    "float64",
		reflect.Complex64:  "complex64",
		reflect.Complex128: "complex128",
		reflect.Array:      "array",
		reflect.Chan:       "chan",
		reflect.Func:       "func",
		reflect.Map:        "map",
		reflect.Slice:      "slice",
		reflect.String:     "string",
	}

	goStringerType = reflect.TypeOf((*fmt.GoStringer)(nil)).Elem()

	byteSliceType = reflect.TypeOf([]byte{})
)

// Default prints to os.Stdout with two space indentation.
var Default = New(os.Stdout, Indent("  "))

// An Option modifies the default behaviour of a Printer.
type Option func(o *Printer)

// Indent output by this much.
func Indent(indent string) Option { return func(o *Printer) { o.indent = indent } }

// NoIndent disables indenting.
func NoIndent() Option { return Indent("") }

// OmitEmpty sets whether empty field members should be omitted from output.
func OmitEmpty(omitEmpty bool) Option { return func(o *Printer) { o.omitEmpty = omitEmpty } }

// ExplicitTypes adds explicit typing to slice and map struct values that would normally be inferred by Go.
func ExplicitTypes(ok bool) Option { return func(o *Printer) { o.explicitTypes = true } }

// IgnoreGoStringer disables use of the .GoString() method.
func IgnoreGoStringer() Option { return func(o *Printer) { o.ignoreGoStringer = true } }

// Hide excludes the given types from representation, instead just printing the name of the type.
func Hide(ts ...interface{}) Option {
	return func(o *Printer) {
		for _, t := range ts {
			rt := reflect.Indirect(reflect.ValueOf(t)).Type()
			o.exclude[rt] = true
		}
	}
}

// AlwaysIncludeType always includes explicit type information for each item.
func AlwaysIncludeType() Option { return func(o *Printer) { o.alwaysIncludeType = true } }

// Printer represents structs in a printable manner.
type Printer struct {
	indent            string
	omitEmpty         bool
	ignoreGoStringer  bool
	alwaysIncludeType bool
	explicitTypes     bool
	exclude           map[reflect.Type]bool
	w                 io.Writer
}

// New creates a new Printer on w with the given Options.
func New(w io.Writer, options ...Option) *Printer {
	p := &Printer{
		w:         w,
		indent:    "  ",
		omitEmpty: true,
		exclude:   map[reflect.Type]bool{},
	}
	for _, option := range options {
		option(p)
	}
	return p
}

func (p *Printer) nextIndent(indent string) string {
	if p.indent != "" {
		return indent + p.indent
	}
	return ""
}

func (p *Printer) thisIndent(indent string) string {
	if p.indent != "" {
		return indent
	}
	return ""
}

// Print the values.
func (p *Printer) Print(vs ...interface{}) {
	for i, v := range vs {
		if i > 0 {
			fmt.Fprint(p.w, " ")
		}
		p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "", true)
	}
}

// Println prints each value on a new line.
func (p *Printer) Println(vs ...interface{}) {
	for i, v := range vs {
		if i > 0 {
			fmt.Fprint(p.w, " ")
		}
		p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "", true)
	}
	fmt.Fprintln(p.w)
}

func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent string, showType bool) { // nolint: gocyclo
	if seen[v] {
		fmt.Fprint(p.w, "...")
		return
	}
	seen[v] = true
	defer delete(seen, v)

	if v.Kind() == reflect.Invalid || (v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Chan || v.Kind() == reflect.Slice || v.Kind() == reflect.Func || v.Kind() == reflect.Interface) && v.IsNil() {
		fmt.Fprint(p.w, "nil")
		return
	}
	if p.exclude[v.Type()] {
		fmt.Fprintf(p.w, "%s...", v.Type().Name())
		return
	}
	t := v.Type()

	if t == byteSliceType {
		fmt.Fprintf(p.w, "[]byte(%q)", v.Bytes())
		return
	}

	// If we can't access a private field directly with reflection, try and do so via unsafe.
	if !v.CanInterface() && v.CanAddr() {
		uv := reflect.NewAt(t, unsafe.Pointer(v.UnsafeAddr())).Elem()
		if uv.CanInterface() {
			v = uv
		}
	}
	// Attempt to use fmt.GoStringer interface.
	if !p.ignoreGoStringer && t.Implements(goStringerType) {
		fmt.Fprint(p.w, v.Interface().(fmt.GoStringer).GoString())
		return
	}
	in := p.thisIndent(indent)
	ni := p.nextIndent(indent)
	switch v.Kind() {
	case reflect.Slice, reflect.Array:
		fmt.Fprintf(p.w, "%s{", v.Type())
		if v.Len() == 0 {
			fmt.Fprint(p.w, "}")
		} else {
			if p.indent != "" {
				fmt.Fprintf(p.w, "\n")
			}
			for i := 0; i < v.Len(); i++ {
				e := v.Index(i)
				fmt.Fprintf(p.w, "%s", ni)
				p.reprValue(seen, e, ni, p.alwaysIncludeType || p.explicitTypes)
				if p.indent != "" {
					fmt.Fprintf(p.w, ",\n")
				} else if i < v.Len()-1 {
					fmt.Fprintf(p.w, ", ")
				}
			}
			fmt.Fprintf(p.w, "%s}", in)
		}

	case reflect.Chan:
		fmt.Fprintf(p.w, "make(")
		fmt.Fprintf(p.w, "%s", v.Type())
		fmt.Fprintf(p.w, ", %d)", v.Cap())

	case reflect.Map:
		fmt.Fprintf(p.w, "%s{", v.Type())
		if p.indent != "" && v.Len() != 0 {
			fmt.Fprintf(p.w, "\n")
		}
		keys := v.MapKeys()
		sort.Slice(keys, func(i, j int) bool {
			return fmt.Sprint(keys[i]) < fmt.Sprint(keys[j])
		})
		for i, k := range keys {
			kv := v.MapIndex(k)
			fmt.Fprintf(p.w, "%s", ni)
			p.reprValue(seen, k, ni, p.alwaysIncludeType || p.explicitTypes)
			fmt.Fprintf(p.w, ": ")
			p.reprValue(seen, kv, ni, true)
			if p.indent != "" {
				fmt.Fprintf(p.w, ",\n")
			} else if i < v.Len()-1 {
				fmt.Fprintf(p.w, ", ")
			}
		}
		fmt.Fprintf(p.w, "%s}", in)

	case reflect.Struct:
		if td, ok := asTime(v); ok {
			timeToGo(p.w, td)
		} else {
			if showType {
				fmt.Fprintf(p.w, "%s{", v.Type())
			} else {
				fmt.Fprint(p.w, "{")
			}
			if p.indent != "" && v.NumField() != 0 {
				fmt.Fprintf(p.w, "\n")
			}
			for i := 0; i < v.NumField(); i++ {
				t := v.Type().Field(i)
				f := v.Field(i)
				if p.omitEmpty && isZero(f) {
					continue
				}
				fmt.Fprintf(p.w, "%s%s: ", ni, t.Name)
				p.reprValue(seen, f, ni, true)
				if p.indent != "" {
					fmt.Fprintf(p.w, ",\n")
				} else if i < v.NumField()-1 {
					fmt.Fprintf(p.w, ", ")
				}
			}
			fmt.Fprintf(p.w, "%s}", indent)
		}
	case reflect.Ptr:
		if v.IsNil() {
			fmt.Fprintf(p.w, "nil")
			return
		}
		if showType {
			fmt.Fprintf(p.w, "&")
		}
		p.reprValue(seen, v.Elem(), indent, showType)

	case reflect.String:
		if t.Name() != "string" || p.alwaysIncludeType {
			fmt.Fprintf(p.w, "%s(%q)", t, v.String())
		} else {
			fmt.Fprintf(p.w, "%q", v.String())
		}

	case reflect.Interface:
		if v.IsNil() {
			fmt.Fprintf(p.w, "interface {}(nil)")
		} else {
			p.reprValue(seen, v.Elem(), indent, true)
		}

	default:
		if t.Name() != realKindName[t.Kind()] || p.alwaysIncludeType {
			fmt.Fprintf(p.w, "%s(%v)", t, v)
		} else {
			fmt.Fprintf(p.w, "%v", v)
		}
	}
}

func asTime(v reflect.Value) (time.Time, bool) {
	if !v.CanInterface() {
		return time.Time{}, false
	}
	t, ok := v.Interface().(time.Time)
	return t, ok
}

// String returns a string representing v.
func String(v interface{}, options ...Option) string {
	w := bytes.NewBuffer(nil)
	options = append([]Option{NoIndent()}, options...)
	p := New(w, options...)
	p.Print(v)
	return w.String()
}

func extractOptions(vs ...interface{}) (args []interface{}, options []Option) {
	for _, v := range vs {
		if o, ok := v.(Option); ok {
			options = append(options, o)
		} else {
			args = append(args, v)
		}
	}
	return
}

// Println prints v to os.Stdout, one per line.
func Println(vs ...interface{}) {
	args, options := extractOptions(vs...)
	New(os.Stdout, options...).Println(args...)
}

// Print writes a representation of v to os.Stdout, separated by spaces.
func Print(vs ...interface{}) {
	args, options := extractOptions(vs...)
	New(os.Stdout, options...).Print(args...)
}

func isZero(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Array, reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	}
	return false
}

func timeToGo(w io.Writer, t time.Time) {
	if t.IsZero() {
		fmt.Fprint(w, "time.Time{}")
		return
	}

	var zone string
	switch loc := t.Location(); loc {
	case nil:
		zone = "nil"
	case time.UTC:
		zone = "time.UTC"
	case time.Local:
		zone = "time.Local"
	default:
		n, off := t.Zone()
		zone = fmt.Sprintf("time.FixedZone(%q, %d)", n, off)
	}
	y, m, d := t.Date()
	fmt.Fprintf(w, `time.Date(%d, %d, %d, %d, %d, %d, %d, %s)`, y, m, d, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), zone)
}
<commit_msg>fix: use stdlib IsZero()<commit_after>// Package repr attempts to represent Go values in a form that can be copy-and-pasted into source
// code directly.
//
// Some values (such as pointers to basic types) can not be represented directly in
// Go. These values will be output as `&<value>`. eg. `&23`
package repr

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"reflect"
	"sort"
	"time"
	"unsafe"
)

var (
	// "Real" names of basic kinds, used to differentiate type aliases.
	realKindName = map[reflect.Kind]string{
		reflect.Bool:       "bool",
		reflect.Int:        "int",
		reflect.Int8:       "int8",
		reflect.Int16:      "int16",
		reflect.Int32:      "int32",
		reflect.Int64:      "int64",
		reflect.Uint:       "uint",
		reflect.Uint8:      "uint8",
		reflect.Uint16:     "uint16",
		reflect.Uint32:     "uint32",
		reflect.Uint64:     "uint64",
		reflect.Uintptr:    "uintptr",
		reflect.Float32:    "float32",
		reflect.Float64:    "float64",
		reflect.Complex64:  "complex64",
		reflect.Complex128: "complex128",
		reflect.Array:      "array",
		reflect.Chan:       "chan",
		reflect.Func:       "func",
		reflect.Map:        "map",
		reflect.Slice:      "slice",
		reflect.String:     "string",
	}

	goStringerType = reflect.TypeOf((*fmt.GoStringer)(nil)).Elem()

	byteSliceType = reflect.TypeOf([]byte{})
)

// Default prints to os.Stdout with two space indentation.
var Default = New(os.Stdout, Indent("  "))

// An Option modifies the default behaviour of a Printer.
type Option func(o *Printer)

// Indent output by this much.
func Indent(indent string) Option { return func(o *Printer) { o.indent = indent } }

// NoIndent disables indenting.
func NoIndent() Option { return Indent("") }

// OmitEmpty sets whether empty field members should be omitted from output.
func OmitEmpty(omitEmpty bool) Option { return func(o *Printer) { o.omitEmpty = omitEmpty } }

// ExplicitTypes adds explicit typing to slice and map struct values that would normally be inferred by Go.
func ExplicitTypes(ok bool) Option { return func(o *Printer) { o.explicitTypes = true } }

// IgnoreGoStringer disables use of the .GoString() method.
func IgnoreGoStringer() Option { return func(o *Printer) { o.ignoreGoStringer = true } }

// Hide excludes the given types from representation, instead just printing the name of the type.
func Hide(ts ...interface{}) Option {
	return func(o *Printer) {
		for _, t := range ts {
			rt := reflect.Indirect(reflect.ValueOf(t)).Type()
			o.exclude[rt] = true
		}
	}
}

// AlwaysIncludeType always includes explicit type information for each item.
func AlwaysIncludeType() Option { return func(o *Printer) { o.alwaysIncludeType = true } }

// Printer represents structs in a printable manner.
type Printer struct {
	indent            string
	omitEmpty         bool
	ignoreGoStringer  bool
	alwaysIncludeType bool
	explicitTypes     bool
	exclude           map[reflect.Type]bool
	w                 io.Writer
}

// New creates a new Printer on w with the given Options.
func New(w io.Writer, options ...Option) *Printer {
	p := &Printer{
		w:         w,
		indent:    "  ",
		omitEmpty: true,
		exclude:   map[reflect.Type]bool{},
	}
	for _, option := range options {
		option(p)
	}
	return p
}

func (p *Printer) nextIndent(indent string) string {
	if p.indent != "" {
		return indent + p.indent
	}
	return ""
}

func (p *Printer) thisIndent(indent string) string {
	if p.indent != "" {
		return indent
	}
	return ""
}

// Print the values.
func (p *Printer) Print(vs ...interface{}) {
	for i, v := range vs {
		if i > 0 {
			fmt.Fprint(p.w, " ")
		}
		p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "", true)
	}
}

// Println prints each value on a new line.
func (p *Printer) Println(vs ...interface{}) {
	for i, v := range vs {
		if i > 0 {
			fmt.Fprint(p.w, " ")
		}
		p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "", true)
	}
	fmt.Fprintln(p.w)
}

func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent string, showType bool) { // nolint: gocyclo
	if seen[v] {
		fmt.Fprint(p.w, "...")
		return
	}
	seen[v] = true
	defer delete(seen, v)

	if v.Kind() == reflect.Invalid || (v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Chan || v.Kind() == reflect.Slice || v.Kind() == reflect.Func || v.Kind() == reflect.Interface) && v.IsNil() {
		fmt.Fprint(p.w, "nil")
		return
	}
	if p.exclude[v.Type()] {
		fmt.Fprintf(p.w, "%s...", v.Type().Name())
		return
	}
	t := v.Type()

	if t == byteSliceType {
		fmt.Fprintf(p.w, "[]byte(%q)", v.Bytes())
		return
	}

	// If we can't access a private field directly with reflection, try and do so via unsafe.
	if !v.CanInterface() && v.CanAddr() {
		uv := reflect.NewAt(t, unsafe.Pointer(v.UnsafeAddr())).Elem()
		if uv.CanInterface() {
			v = uv
		}
	}
	// Attempt to use fmt.GoStringer interface.
	if !p.ignoreGoStringer && t.Implements(goStringerType) {
		fmt.Fprint(p.w, v.Interface().(fmt.GoStringer).GoString())
		return
	}
	in := p.thisIndent(indent)
	ni := p.nextIndent(indent)
	switch v.Kind() {
	case reflect.Slice, reflect.Array:
		fmt.Fprintf(p.w, "%s{", v.Type())
		if v.Len() == 0 {
			fmt.Fprint(p.w, "}")
		} else {
			if p.indent != "" {
				fmt.Fprintf(p.w, "\n")
			}
			for i := 0; i < v.Len(); i++ {
				e := v.Index(i)
				fmt.Fprintf(p.w, "%s", ni)
				p.reprValue(seen, e, ni, p.alwaysIncludeType || p.explicitTypes)
				if p.indent != "" {
					fmt.Fprintf(p.w, ",\n")
				} else if i < v.Len()-1 {
					fmt.Fprintf(p.w, ", ")
				}
			}
			fmt.Fprintf(p.w, "%s}", in)
		}

	case reflect.Chan:
		fmt.Fprintf(p.w, "make(")
		fmt.Fprintf(p.w, "%s", v.Type())
		fmt.Fprintf(p.w, ", %d)", v.Cap())

	case reflect.Map:
		fmt.Fprintf(p.w, "%s{", v.Type())
		if p.indent != "" && v.Len() != 0 {
			fmt.Fprintf(p.w, "\n")
		}
		keys := v.MapKeys()
		sort.Slice(keys, func(i, j int) bool {
			return fmt.Sprint(keys[i]) < fmt.Sprint(keys[j])
		})
		for i, k := range keys {
			kv := v.MapIndex(k)
			fmt.Fprintf(p.w, "%s", ni)
			p.reprValue(seen, k, ni, p.alwaysIncludeType || p.explicitTypes)
			fmt.Fprintf(p.w, ": ")
			p.reprValue(seen, kv, ni, true)
			if p.indent != "" {
				fmt.Fprintf(p.w, ",\n")
			} else if i < v.Len()-1 {
				fmt.Fprintf(p.w, ", ")
			}
		}
		fmt.Fprintf(p.w, "%s}", in)

	case reflect.Struct:
		if td, ok := asTime(v); ok {
			timeToGo(p.w, td)
		} else {
			if showType {
				fmt.Fprintf(p.w, "%s{", v.Type())
			} else {
				fmt.Fprint(p.w, "{")
			}
			if p.indent != "" && v.NumField() != 0 {
				fmt.Fprintf(p.w, "\n")
			}
			for i := 0; i < v.NumField(); i++ {
				t := v.Type().Field(i)
				f := v.Field(i)
				if p.omitEmpty && f.IsZero() {
					continue
				}
				fmt.Fprintf(p.w, "%s%s: ", ni, t.Name)
				p.reprValue(seen, f, ni, true)
				if p.indent != "" {
					fmt.Fprintf(p.w, ",\n")
				} else if i < v.NumField()-1 {
					fmt.Fprintf(p.w, ", ")
				}
			}
			fmt.Fprintf(p.w, "%s}", indent)
		}
	case reflect.Ptr:
		if v.IsNil() {
			fmt.Fprintf(p.w, "nil")
			return
		}
		if showType {
			fmt.Fprintf(p.w, "&")
		}
		p.reprValue(seen, v.Elem(), indent, showType)

	case reflect.String:
		if t.Name() != "string" || p.alwaysIncludeType {
			fmt.Fprintf(p.w, "%s(%q)", t, v.String())
		} else {
			fmt.Fprintf(p.w, "%q", v.String())
		}

	case reflect.Interface:
		if v.IsNil() {
			fmt.Fprintf(p.w, "interface {}(nil)")
		} else {
			p.reprValue(seen, v.Elem(), indent, true)
		}

	default:
		if t.Name() != realKindName[t.Kind()] || p.alwaysIncludeType {
			fmt.Fprintf(p.w, "%s(%v)", t, v)
		} else {
			fmt.Fprintf(p.w, "%v", v)
		}
	}
}

func asTime(v reflect.Value) (time.Time, bool) {
	if !v.CanInterface() {
		return time.Time{}, false
	}
	t, ok := v.Interface().(time.Time)
	return t, ok
}

// String returns a string representing v.
func String(v interface{}, options ...Option) string {
	w := bytes.NewBuffer(nil)
	options = append([]Option{NoIndent()}, options...)
	p := New(w, options...)
	p.Print(v)
	return w.String()
}

func extractOptions(vs ...interface{}) (args []interface{}, options []Option) {
	for _, v := range vs {
		if o, ok := v.(Option); ok {
			options = append(options, o)
		} else {
			args = append(args, v)
		}
	}
	return
}

// Println prints v to os.Stdout, one per line.
func Println(vs ...interface{}) {
	args, options := extractOptions(vs...)
	New(os.Stdout, options...).Println(args...)
}

// Print writes a representation of v to os.Stdout, separated by spaces.
func Print(vs ...interface{}) {
	args, options := extractOptions(vs...)
	New(os.Stdout, options...).Print(args...)
}

func timeToGo(w io.Writer, t time.Time) {
	if t.IsZero() {
		fmt.Fprint(w, "time.Time{}")
		return
	}

	var zone string
	switch loc := t.Location(); loc {
	case nil:
		zone = "nil"
	case time.UTC:
		zone = "time.UTC"
	case time.Local:
		zone = "time.Local"
	default:
		n, off := t.Zone()
		zone = fmt.Sprintf("time.FixedZone(%q, %d)", n, off)
	}
	y, m, d := t.Date()
	fmt.Fprintf(w, `time.Date(%d, %d, %d, %d, %d, %d, %d, %s)`, y, m, d, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), zone)
}
<|endoftext|>


<commit_before>package config

import (
	"encoding/json"
	"testing"
)

func TestNewConfigStorage(t *testing.T) {
	config, err := NewConfigStorage("$GOPATH/src/github.com/resourced/resourced/tests/data/config-reader", "$GOPATH/src/github.com/resourced/resourced/tests/data/config-writer")
	if err != nil {
		t.Fatalf("Initializing ConfigStorage should work. Error: %v", err)
	}

	if len(config.Readers) <= 0 {
		t.Errorf("Length of reader config should > 0. config.Readers: %v", config.Readers)
	}
	if len(config.Writers) != 4 {
		t.Errorf("Length of reader config should == 3. config.Writers: %v", config.Writers)
	}
}

func TestNewReaderConfig(t *testing.T) {
	config, err := NewConfig("$GOPATH/src/github.com/resourced/resourced/tests/data/config-reader/gostruct-docker-container-memory.toml", "reader")
	if err != nil {
		t.Fatalf("Initializing Config should work. Error: %v", err)
	}

	if config.GoStruct != "DockerContainersMemory" {
		t.Fatalf("Config is initialized incorrectly. config.GoStruct: %v", config.GoStruct)
	}
	if config.Path != "/docker/containers/memory" {
		t.Fatalf("Config is initialized incorrectly. config.Path: %v", config.Path)
	}
	if config.Interval != "3s" {
		t.Fatalf("Config is initialized incorrectly. config.Interval: %v", config.Interval)
	}
	if config.GoStructFields["CgroupBasePath"] != "/sys/fs/cgroup/cpuacct/docker" {
		inJson, _ := json.Marshal(config.GoStructFields)
		t.Fatalf("Config is initialized incorrectly. config.GoStructFields: %v", string(inJson))
	}
}

func TestNewWriterConfigWithJsonProcessor(t *testing.T) {
	config, err := NewConfig("$GOPATH/src/github.com/resourced/resourced/tests/data/config-writer/gostruct-stdout.toml", "reader")
	if err != nil {
		t.Fatalf("Initializing Config should work. Error: %v", err)
	}
	if config.GoStructFields["JsonProcessor"] == "" {
		inJson, _ := json.Marshal(config.GoStructFields)
		t.Fatalf("Config is initialized incorrectly. config.GoStructFields: %v", string(inJson))
	}
}
<commit_msg>Fix small inconsistency in test.<commit_after>package config

import (
	"encoding/json"
	"testing"
)

func TestNewConfigStorage(t *testing.T) {
	config, err := NewConfigStorage("$GOPATH/src/github.com/resourced/resourced/tests/data/config-reader", "$GOPATH/src/github.com/resourced/resourced/tests/data/config-writer")
	if err != nil {
		t.Fatalf("Initializing ConfigStorage should work. Error: %v", err)
	}

	if len(config.Readers) <= 0 {
		t.Errorf("Length of reader config should > 0. config.Readers: %v", config.Readers)
	}
	if len(config.Writers) != 4 {
		t.Errorf("Length of reader config should == 3. config.Writers: %v", config.Writers)
	}
}

func TestNewReaderConfig(t *testing.T) {
	config, err := NewConfig("$GOPATH/src/github.com/resourced/resourced/tests/data/config-reader/gostruct-docker-container-memory.toml", "reader")
	if err != nil {
		t.Fatalf("Initializing Config should work. Error: %v", err)
	}

	if config.GoStruct != "DockerContainersMemory" {
		t.Fatalf("Config is initialized incorrectly. config.GoStruct: %v", config.GoStruct)
	}
	if config.Path != "/docker/containers/memory" {
		t.Fatalf("Config is initialized incorrectly. config.Path: %v", config.Path)
	}
	if config.Interval != "3s" {
		t.Fatalf("Config is initialized incorrectly. config.Interval: %v", config.Interval)
	}
	if config.GoStructFields["CgroupBasePath"] != "/sys/fs/cgroup/cpuacct/docker" {
		inJson, _ := json.Marshal(config.GoStructFields)
		t.Fatalf("Config is initialized incorrectly. config.GoStructFields: %v", string(inJson))
	}
}

func TestNewWriterConfigWithJsonProcessor(t *testing.T) {
	config, err := NewConfig("$GOPATH/src/github.com/resourced/resourced/tests/data/config-writer/gostruct-stdout.toml", "writer")
	if err != nil {
		t.Fatalf("Initializing Config should work. Error: %v", err)
	}
	if config.GoStructFields["JsonProcessor"] == "" {
		inJson, _ := json.Marshal(config.GoStructFields)
		t.Fatalf("Config is initialized incorrectly. config.GoStructFields: %v", string(inJson))
	}
}
<|endoftext|>


<commit_before>// +build linux

package libcontainer

import (
	"fmt"
	"strings"

	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/syndtr/gocapability/capability"
)

const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS

var capabilityMap map[string]capability.Cap

func init() {
	capabilityMap = make(map[string]capability.Cap)
	for _, c := range capability.List() {
		if c > capability.CAP_LAST_CAP {
			continue
		}
		capabilityMap["CAP_"+strings.ToUpper(c.String())] = c
	}
}

func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
	bounding := []capability.Cap{}
	for _, c := range capConfig.Bounding {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		bounding = append(bounding, v)
	}
	effective := []capability.Cap{}
	for _, c := range capConfig.Effective {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		effective = append(effective, v)
	}
	inheritable := []capability.Cap{}
	for _, c := range capConfig.Inheritable {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		inheritable = append(inheritable, v)
	}
	permitted := []capability.Cap{}
	for _, c := range capConfig.Permitted {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		permitted = append(permitted, v)
	}
	ambient := []capability.Cap{}
	for _, c := range capConfig.Ambient {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		ambient = append(ambient, v)
	}
	pid, err := capability.NewPid2(0)
	if err != nil {
		return nil, err
	}
	err = pid.Load()
	if err != nil {
		return nil, err
	}
	return &containerCapabilities{
		bounding:    bounding,
		effective:   effective,
		inheritable: inheritable,
		permitted:   permitted,
		ambient:     ambient,
		pid:         pid,
	}, nil
}

type containerCapabilities struct {
	pid         capability.Capabilities
	bounding    []capability.Cap
	effective   []capability.Cap
	inheritable []capability.Cap
	permitted   []capability.Cap
	ambient     []capability.Cap
}

// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
func (c *containerCapabilities) ApplyBoundingSet() error {
	c.pid.Clear(capability.BOUNDS)
	c.pid.Set(capability.BOUNDS, c.bounding...)
	return c.pid.Apply(capability.BOUNDS)
}

// Apply sets all the capabilities for the current process in the config.
func (c *containerCapabilities) ApplyCaps() error {
	c.pid.Clear(allCapabilityTypes)
	c.pid.Set(capability.BOUNDS, c.bounding...)
	c.pid.Set(capability.PERMITTED, c.permitted...)
	c.pid.Set(capability.INHERITABLE, c.inheritable...)
	c.pid.Set(capability.EFFECTIVE, c.effective...)
	c.pid.Set(capability.AMBIENT, c.ambient...)
	return c.pid.Apply(allCapabilityTypes)
}
<commit_msg>libcontainer: initialize slices with length<commit_after>// +build linux

package libcontainer

import (
	"fmt"
	"strings"

	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/syndtr/gocapability/capability"
)

const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS

var capabilityMap map[string]capability.Cap

func init() {
	capabilityMap = make(map[string]capability.Cap, capability.CAP_LAST_CAP+1)
	for _, c := range capability.List() {
		if c > capability.CAP_LAST_CAP {
			continue
		}
		capabilityMap["CAP_"+strings.ToUpper(c.String())] = c
	}
}

func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
	bounding := make([]capability.Cap, len(capConfig.Bounding))
	for i, c := range capConfig.Bounding {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		bounding[i] = v
	}
	effective := make([]capability.Cap, len(capConfig.Effective))
	for i, c := range capConfig.Effective {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		effective[i] = v
	}
	inheritable := make([]capability.Cap, len(capConfig.Inheritable))
	for i, c := range capConfig.Inheritable {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		inheritable[i] = v
	}
	permitted := make([]capability.Cap, len(capConfig.Permitted))
	for i, c := range capConfig.Permitted {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		permitted[i] = v
	}
	ambient := make([]capability.Cap, len(capConfig.Ambient))
	for i, c := range capConfig.Ambient {
		v, ok := capabilityMap[c]
		if !ok {
			return nil, fmt.Errorf("unknown capability %q", c)
		}
		ambient[i] = v
	}
	pid, err := capability.NewPid2(0)
	if err != nil {
		return nil, err
	}
	err = pid.Load()
	if err != nil {
		return nil, err
	}
	return &containerCapabilities{
		bounding:    bounding,
		effective:   effective,
		inheritable: inheritable,
		permitted:   permitted,
		ambient:     ambient,
		pid:         pid,
	}, nil
}

type containerCapabilities struct {
	pid         capability.Capabilities
	bounding    []capability.Cap
	effective   []capability.Cap
	inheritable []capability.Cap
	permitted   []capability.Cap
	ambient     []capability.Cap
}

// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
func (c *containerCapabilities) ApplyBoundingSet() error {
	c.pid.Clear(capability.BOUNDS)
	c.pid.Set(capability.BOUNDS, c.bounding...)
	return c.pid.Apply(capability.BOUNDS)
}

// Apply sets all the capabilities for the current process in the config.
func (c *containerCapabilities) ApplyCaps() error {
	c.pid.Clear(allCapabilityTypes)
	c.pid.Set(capability.BOUNDS, c.bounding...)
	c.pid.Set(capability.PERMITTED, c.permitted...)
	c.pid.Set(capability.INHERITABLE, c.inheritable...)
	c.pid.Set(capability.EFFECTIVE, c.effective...)
	c.pid.Set(capability.AMBIENT, c.ambient...)
	return c.pid.Apply(allCapabilityTypes)
}
<|endoftext|>