<commit_before>package main

import (
	"flag"
	"os"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf_http"
	"github.com/cloudfoundry-incubator/converger/converger_process"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/lock_bbs"
	"github.com/cloudfoundry/dropsonde"
	"github.com/cloudfoundry/gunk/workpool"
	"github.com/cloudfoundry/storeadapter/etcdstoreadapter"
	"github.com/nu7hatch/gouuid"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

var etcdCluster = flag.String(
	"etcdCluster",
	"http://127.0.0.1:4001",
	"comma-separated list of etcd addresses (http://ip:port)",
)

var heartbeatInterval = flag.Duration(
	"heartbeatInterval",
	lock_bbs.HEARTBEAT_INTERVAL,
	"the interval between heartbeats to the lock",
)

var convergeRepeatInterval = flag.Duration(
	"convergeRepeatInterval",
	30*time.Second,
	"the interval between runs of the converge process",
)

var kickPendingTaskDuration = flag.Duration(
	"kickPendingTaskDuration",
	30*time.Second,
	"the interval, in seconds, between kicks to pending tasks",
)

var expireCompletedTaskDuration = flag.Duration(
	"expireCompletedTaskDuration",
	120*time.Second,
	"completed, unresolved tasks are deleted after this duration",
)

var expirePendingTaskDuration = flag.Duration(
	"expirePendingTaskDuration",
	30*time.Minute,
	"unclaimed tasks are marked as failed, after this duration",
)

var communicationTimeout = flag.Duration(
	"communicationTimeout",
	10*time.Second,
	"Timeout applied to all HTTP requests.",
)

const (
	dropsondeOrigin      = "converger"
	dropsondeDestination = "localhost:3457"
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	cf_http.Initialize(*communicationTimeout)

	logger := cf_lager.New("converger")

	initializeDropsonde(logger)

	bbs := initializeBBS(logger)

	uuid, err := uuid.NewV4()
	if err != nil {
		logger.Fatal("Couldn't generate uuid", err)
	}

	heartbeater := bbs.NewConvergeLock(uuid.String(), *heartbeatInterval)

	converger := converger_process.New(
		bbs,
		logger,
		clock.NewClock(),
		*convergeRepeatInterval,
		*kickPendingTaskDuration,
		*expirePendingTaskDuration,
		*expireCompletedTaskDuration,
	)

	members := grouper.Members{
		{"heartbeater", heartbeater},
		{"converger", converger},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	logger.Info("started-waiting-for-lock")

	process := ifrit.Invoke(sigmon.New(group))

	logger.Info("acquired-lock")

	err = <-process.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeBBS(logger lager.Logger) Bbs.ConvergerBBS {
	etcdAdapter := etcdstoreadapter.NewETCDStoreAdapter(
		strings.Split(*etcdCluster, ","),
		workpool.NewWorkPool(10),
	)

	err := etcdAdapter.Connect()
	if err != nil {
		logger.Fatal("failed-to-connect-to-etcd", err)
	}

	return Bbs.NewConvergerBBS(etcdAdapter, clock.NewClock(), logger)
}

func initializeDropsonde(logger lager.Logger) {
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed to initialize dropsonde: %v", err)
	}
}
<commit_msg>pass reconfigurable sink to cf-debug-server [#86357448]<commit_after>package main

import (
	"flag"
	"os"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf_http"
	"github.com/cloudfoundry-incubator/converger/converger_process"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/lock_bbs"
	"github.com/cloudfoundry/dropsonde"
	"github.com/cloudfoundry/gunk/workpool"
	"github.com/cloudfoundry/storeadapter/etcdstoreadapter"
	"github.com/nu7hatch/gouuid"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

var etcdCluster = flag.String(
	"etcdCluster",
	"http://127.0.0.1:4001",
	"comma-separated list of etcd addresses (http://ip:port)",
)

var heartbeatInterval = flag.Duration(
	"heartbeatInterval",
	lock_bbs.HEARTBEAT_INTERVAL,
	"the interval between heartbeats to the lock",
)

var convergeRepeatInterval = flag.Duration(
	"convergeRepeatInterval",
	30*time.Second,
	"the interval between runs of the converge process",
)

var kickPendingTaskDuration = flag.Duration(
	"kickPendingTaskDuration",
	30*time.Second,
	"the interval, in seconds, between kicks to pending tasks",
)

var expireCompletedTaskDuration = flag.Duration(
	"expireCompletedTaskDuration",
	120*time.Second,
	"completed, unresolved tasks are deleted after this duration",
)

var expirePendingTaskDuration = flag.Duration(
	"expirePendingTaskDuration",
	30*time.Minute,
	"unclaimed tasks are marked as failed, after this duration",
)

var communicationTimeout = flag.Duration(
	"communicationTimeout",
	10*time.Second,
	"Timeout applied to all HTTP requests.",
)

const (
	dropsondeOrigin      = "converger"
	dropsondeDestination = "localhost:3457"
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	cf_http.Initialize(*communicationTimeout)

	logger, reconfigurableSink := cf_lager.New("converger")

	initializeDropsonde(logger)

	bbs := initializeBBS(logger)

	uuid, err := uuid.NewV4()
	if err != nil {
		logger.Fatal("Couldn't generate uuid", err)
	}

	heartbeater := bbs.NewConvergeLock(uuid.String(), *heartbeatInterval)

	converger := converger_process.New(
		bbs,
		logger,
		clock.NewClock(),
		*convergeRepeatInterval,
		*kickPendingTaskDuration,
		*expirePendingTaskDuration,
		*expireCompletedTaskDuration,
	)

	members := grouper.Members{
		{"heartbeater", heartbeater},
		{"converger", converger},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr, reconfigurableSink)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	logger.Info("started-waiting-for-lock")

	process := ifrit.Invoke(sigmon.New(group))

	logger.Info("acquired-lock")

	err = <-process.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeBBS(logger lager.Logger) Bbs.ConvergerBBS {
	etcdAdapter := etcdstoreadapter.NewETCDStoreAdapter(
		strings.Split(*etcdCluster, ","),
		workpool.NewWorkPool(10),
	)

	err := etcdAdapter.Connect()
	if err != nil {
		logger.Fatal("failed-to-connect-to-etcd", err)
	}

	return Bbs.NewConvergerBBS(etcdAdapter, clock.NewClock(), logger)
}

func initializeDropsonde(logger lager.Logger) {
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed to initialize dropsonde: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"time"
)

//Article init entity
type Article struct {
	Title     string    `json:"title"`
	Content   string    `json:"content"`
	UpdatedAt time.Time `json:"updated_at"`
	CreatedAt time.Time `json:"created_at"`
}
<commit_msg>seperate package<commit_after>package entity

import (
	"time"
)

//Article init entity
type Article struct {
	Title     string    `json:"title"`
	Content   string    `json:"content"`
	UpdatedAt time.Time `json:"updated_at"`
	CreatedAt time.Time `json:"created_at"`
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/jkomoros/sudoku"
)

type model struct {
	grid *sudoku.Grid
}

type modelMutator interface {
	Apply(m *model)
	Undo(m *model)
}

type markMutator struct {
	row, col    int
	marksToggle map[int]bool
}

type numberMutator struct {
	row, col int
	number   int
	//Necessary so we can undo.
	oldNumber int
}

func (m *model) SetGrid(grid *sudoku.Grid) {
	m.grid = grid
}

func (m *model) SetMarks(row, col int, marksToggle map[int]bool) {
	//TODO: add a copy of marksToggle that only has valid marks for the current state.
	//right now if marksToggle has a no-op instruction, it can get in weird states.
	mutator := &markMutator{row, col, marksToggle}
	mutator.Apply(m)
}

func (m *model) SetNumber(row, col int, num int) {
	//TODO: this should also only add an action if the specified cell is not already num.
	cell := m.grid.Cell(row, col)
	if cell == nil {
		return
	}
	mutator := &numberMutator{row, col, num, cell.Number()}
	mutator.Apply(m)
}

func (m *markMutator) Apply(model *model) {
	cell := model.grid.Cell(m.row, m.col)
	if cell == nil {
		return
	}
	for key, value := range m.marksToggle {
		cell.SetMark(key, value)
	}
}

func (m *markMutator) Undo(model *model) {
	cell := model.grid.Cell(m.row, m.col)
	if cell == nil {
		return
	}
	for key, value := range m.marksToggle {
		//Set the opposite since we're undoing.
		cell.SetMark(key, !value)
	}
}

func (n *numberMutator) Apply(model *model) {
	cell := model.grid.Cell(n.row, n.col)
	if cell == nil {
		return
	}
	cell.SetNumber(n.number)
}

func (n *numberMutator) Undo(model *model) {
	//TODO: test this method
	cell := model.grid.Cell(n.row, n.col)
	if cell == nil {
		return
	}
	cell.SetNumber(n.oldNumber)
}
<commit_msg>Added a TODO<commit_after>package main

import (
	"github.com/jkomoros/sudoku"
)

type model struct {
	grid *sudoku.Grid
}

type modelMutator interface {
	Apply(m *model)
	Undo(m *model)
}

type markMutator struct {
	row, col    int
	marksToggle map[int]bool
}

type numberMutator struct {
	row, col int
	number   int
	//Necessary so we can undo.
	oldNumber int
}

func (m *model) SetGrid(grid *sudoku.Grid) {
	m.grid = grid
}

func (m *model) SetMarks(row, col int, marksToggle map[int]bool) {
	//TODO: add a copy of marksToggle that only has valid marks for the current state.
	//right now if marksToggle has a no-op instruction, it can get in weird states.
	mutator := &markMutator{row, col, marksToggle}
	mutator.Apply(m)
}

func (m *model) SetNumber(row, col int, num int) {
	//TODO: this should also only add an action if the specified cell is not already num.
	cell := m.grid.Cell(row, col)
	if cell == nil {
		return
	}
	mutator := &numberMutator{row, col, num, cell.Number()}
	mutator.Apply(m)
}

//TODO: implement model.new{Mark|Number}Mutator, which only return a
//modelMutator if it wouldn't be a no-op. Then, test that they return nil if
//it would be a no op, including omitting marks that would be a no op.

func (m *markMutator) Apply(model *model) {
	cell := model.grid.Cell(m.row, m.col)
	if cell == nil {
		return
	}
	for key, value := range m.marksToggle {
		cell.SetMark(key, value)
	}
}

func (m *markMutator) Undo(model *model) {
	cell := model.grid.Cell(m.row, m.col)
	if cell == nil {
		return
	}
	for key, value := range m.marksToggle {
		//Set the opposite since we're undoing.
		cell.SetMark(key, !value)
	}
}

func (n *numberMutator) Apply(model *model) {
	cell := model.grid.Cell(n.row, n.col)
	if cell == nil {
		return
	}
	cell.SetNumber(n.number)
}

func (n *numberMutator) Undo(model *model) {
	//TODO: test this method
	cell := model.grid.Cell(n.row, n.col)
	if cell == nil {
		return
	}
	cell.SetNumber(n.oldNumber)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"launchpad.net/gnuflag"
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/cmd"
	"launchpad.net/juju-core/environs/config"
	_ "launchpad.net/juju-core/environs/dummy"
	"launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/version"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	stdtesting "testing"
)

func TestPackage(t *stdtesting.T) {
	testing.MgoTestPackage(t)
}

type MainSuite struct{}

var _ = Suite(&MainSuite{})

var (
	flagRunMain = flag.Bool("run-main", false, "Run the application's main function for recursive testing")
)

// Reentrancy point for testing (something as close as possible to) the juju
// tool itself.
func TestRunMain(t *stdtesting.T) {
	if *flagRunMain {
		Main(flag.Args())
	}
}

func badrun(c *C, exit int, args ...string) string {
	localArgs := append([]string{"-test.run", "TestRunMain", "-run-main", "--", "juju"}, args...)
	ps := exec.Command(os.Args[0], localArgs...)
	ps.Env = append(os.Environ(), "JUJU_HOME="+config.JujuHome())
	output, err := ps.CombinedOutput()
	if exit != 0 {
		c.Assert(err, ErrorMatches, fmt.Sprintf("exit status %d", exit))
	}
	return string(output)
}

func helpText(command cmd.Command, name string) string {
	buff := &bytes.Buffer{}
	info := command.Info()
	info.Name = name
	f := gnuflag.NewFlagSet(info.Name, gnuflag.ContinueOnError)
	command.SetFlags(f)
	buff.Write(info.Help(f))
	return buff.String()
}

func deployHelpText() string {
	return helpText(&DeployCommand{}, "juju deploy")
}

func syncToolsHelpText() string {
	return helpText(&SyncToolsCommand{}, "juju sync-tools")
}

var runMainTests = []struct {
	summary string
	args    []string
	code    int
	out     string
}{
	{
		summary: "no params shows help",
		args:    []string{},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help is the same as juju",
		args:    []string{"help"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju --help works too",
		args:    []string{"--help"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help basics is the same as juju",
		args:    []string{"help", "basics"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help foo doesn't exist",
		args:    []string{"help", "foo"},
		code:    1,
		out:     "error: unknown command or topic for foo\n",
	}, {
		summary: "juju help deploy shows the default help without global options",
		args:    []string{"help", "deploy"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "juju --help deploy shows the same help as 'help deploy'",
		args:    []string{"--help", "deploy"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "juju deploy --help shows the same help as 'help deploy'",
		args:    []string{"deploy", "--help"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "unknown command",
		args:    []string{"discombobulate"},
		code:    2,
		out:     "error: unrecognized command: juju discombobulate\n",
	}, {
		summary: "unknown option before command",
		args:    []string{"--cheese", "bootstrap"},
		code:    2,
		out:     "error: flag provided but not defined: --cheese\n",
	}, {
		summary: "unknown option after command",
		args:    []string{"bootstrap", "--cheese"},
		code:    2,
		out:     "error: flag provided but not defined: --cheese\n",
	}, {
		summary: "known option, but specified before command",
		args:    []string{"--environment", "blah", "bootstrap"},
		code:    2,
		out:     "error: flag provided but not defined: --environment\n",
	}, {
		summary: "juju sync-tools registered properly",
		args:    []string{"sync-tools", "--help"},
		code:    0,
		out:     syncToolsHelpText(),
	}, {
		summary: "check version command registered properly",
		args:    []string{"version"},
		code:    0,
		out:     version.Current.String() + "\n",
	},
}

func (s *MainSuite) TestRunMain(c *C) {
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	for i, t := range runMainTests {
		c.Logf("test %d: %s", i, t.summary)
		out := badrun(c, t.code, t.args...)
		c.Assert(out, Equals, t.out)
	}
}

var brokenConfig = `
environments:
    one:
        type: dummy
        state-server: false
        authorized-keys: i-am-a-key
        broken: %s
`

// breakJuju forces the dummy environment to return an error
// when environMethod is called.
func breakJuju(c *C, environMethod string) (msg string) {
	yaml := fmt.Sprintf(brokenConfig, environMethod)
	err := ioutil.WriteFile(config.JujuHomePath("environments.yaml"), []byte(yaml), 0666)
	c.Assert(err, IsNil)

	return fmt.Sprintf("dummy.%s is broken", environMethod)
}

func (s *MainSuite) TestActualRunJujuArgsBeforeCommand(c *C) {
	defer testing.MakeFakeHomeNoEnvironments(c, "one").Restore()
	// Check global args work when specified before command
	msg := breakJuju(c, "Bootstrap")
	logpath := filepath.Join(c.MkDir(), "log")
	out := badrun(c, 1, "--log-file", logpath, "--verbose", "--debug", "bootstrap")
	c.Assert(out, Equals, "error: "+msg+"\n")
	content, err := ioutil.ReadFile(logpath)
	c.Assert(err, IsNil)
	fullmsg := fmt.Sprintf(`.*\n.*ERROR JUJU:juju:bootstrap juju bootstrap command failed: %s\n`, msg)
	c.Assert(string(content), Matches, fullmsg)
}

func (s *MainSuite) TestActualRunJujuArgsAfterCommand(c *C) {
	defer testing.MakeFakeHomeNoEnvironments(c, "one").Restore()
	// Check global args work when specified after command
	msg := breakJuju(c, "Bootstrap")
	logpath := filepath.Join(c.MkDir(), "log")
	out := badrun(c, 1, "bootstrap", "--log-file", logpath, "--verbose", "--debug")
	c.Assert(out, Equals, "error: "+msg+"\n")
	content, err := ioutil.ReadFile(logpath)
	c.Assert(err, IsNil)
	fullmsg := fmt.Sprintf(`.*\n.*ERROR JUJU:juju:bootstrap juju bootstrap command failed: %s\n`, msg)
	c.Assert(string(content), Matches, fullmsg)
}

var commandNames = []string{
	"add-relation",
	"add-unit",
	"bootstrap",
	"debug-log",
	"deploy",
	"destroy-environment",
	"destroy-machine",
	"destroy-relation",
	"destroy-service",
	"destroy-unit",
	"expose",
	"generate-config", // alias for init
	"get",
	"get-constraints",
	"help",
	"init",
	"remove-relation", // alias for destroy-relation
	"remove-unit",     // alias for destroy-unit
	"resolved",
	"scp",
	"set",
	"set-constraints",
	"ssh",
	"stat", // alias for status
	"status",
	"terminate-machine", // alias for destroy-machine
	"unexpose",
	"upgrade-charm",
	"upgrade-juju",
	"version",
}

func (s *MainSuite) TestHelpCommands(c *C) {
	// Check that we have correctly registered all the commands
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "commands")
	lines := strings.Split(out, "\n")
	var names []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 {
			continue
		}
		names = append(names, f[0])
	}
	// The names should be output in alphabetical order, so don't sort.
	c.Assert(names, DeepEquals, commandNames)
}

var topicNames = []string{
	"basics",
	"commands",
	"global-options",
	"topics",
}

func (s *MainSuite) TestHelpTopics(c *C) {
	// Check that we have correctly registered all the topics
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "topics")
	lines := strings.Split(out, "\n")
	var names []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 {
			continue
		}
		names = append(names, f[0])
	}
	// The names should be output in alphabetical order, so don't sort.
	c.Assert(names, DeepEquals, topicNames)
}

var globalFlags = []string{
	"--debug .*",
	"-h, --help .*",
	"--log-file .*",
	"-v, --verbose .*",
}

func (s *MainSuite) TestHelpGlobalOptions(c *C) {
	// Check that we have correctly registered all the topics
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "global-options")
	c.Assert(out, Matches, `Global Options

These options may be used with any command, and may appear in front of any
command\.(.|\n)*`)
	lines := strings.Split(out, "\n")
	var flags []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 || line[0] != '-' {
			continue
		}
		flags = append(flags, line)
	}
	c.Assert(len(flags), Equals, len(globalFlags))
	for i, line := range flags {
		c.Assert(line, Matches, globalFlags[i])
	}
}
<commit_msg>main_test needs to know about the new command.<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"launchpad.net/gnuflag"
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/cmd"
	"launchpad.net/juju-core/environs/config"
	_ "launchpad.net/juju-core/environs/dummy"
	"launchpad.net/juju-core/testing"
	"launchpad.net/juju-core/version"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	stdtesting "testing"
)

func TestPackage(t *stdtesting.T) {
	testing.MgoTestPackage(t)
}

type MainSuite struct{}

var _ = Suite(&MainSuite{})

var (
	flagRunMain = flag.Bool("run-main", false, "Run the application's main function for recursive testing")
)

// Reentrancy point for testing (something as close as possible to) the juju
// tool itself.
func TestRunMain(t *stdtesting.T) {
	if *flagRunMain {
		Main(flag.Args())
	}
}

func badrun(c *C, exit int, args ...string) string {
	localArgs := append([]string{"-test.run", "TestRunMain", "-run-main", "--", "juju"}, args...)
	ps := exec.Command(os.Args[0], localArgs...)
	ps.Env = append(os.Environ(), "JUJU_HOME="+config.JujuHome())
	output, err := ps.CombinedOutput()
	if exit != 0 {
		c.Assert(err, ErrorMatches, fmt.Sprintf("exit status %d", exit))
	}
	return string(output)
}

func helpText(command cmd.Command, name string) string {
	buff := &bytes.Buffer{}
	info := command.Info()
	info.Name = name
	f := gnuflag.NewFlagSet(info.Name, gnuflag.ContinueOnError)
	command.SetFlags(f)
	buff.Write(info.Help(f))
	return buff.String()
}

func deployHelpText() string {
	return helpText(&DeployCommand{}, "juju deploy")
}

func syncToolsHelpText() string {
	return helpText(&SyncToolsCommand{}, "juju sync-tools")
}

var runMainTests = []struct {
	summary string
	args    []string
	code    int
	out     string
}{
	{
		summary: "no params shows help",
		args:    []string{},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help is the same as juju",
		args:    []string{"help"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju --help works too",
		args:    []string{"--help"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help basics is the same as juju",
		args:    []string{"help", "basics"},
		code:    0,
		out:     strings.TrimLeft(helpBasics, "\n"),
	}, {
		summary: "juju help foo doesn't exist",
		args:    []string{"help", "foo"},
		code:    1,
		out:     "error: unknown command or topic for foo\n",
	}, {
		summary: "juju help deploy shows the default help without global options",
		args:    []string{"help", "deploy"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "juju --help deploy shows the same help as 'help deploy'",
		args:    []string{"--help", "deploy"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "juju deploy --help shows the same help as 'help deploy'",
		args:    []string{"deploy", "--help"},
		code:    0,
		out:     deployHelpText(),
	}, {
		summary: "unknown command",
		args:    []string{"discombobulate"},
		code:    2,
		out:     "error: unrecognized command: juju discombobulate\n",
	}, {
		summary: "unknown option before command",
		args:    []string{"--cheese", "bootstrap"},
		code:    2,
		out:     "error: flag provided but not defined: --cheese\n",
	}, {
		summary: "unknown option after command",
		args:    []string{"bootstrap", "--cheese"},
		code:    2,
		out:     "error: flag provided but not defined: --cheese\n",
	}, {
		summary: "known option, but specified before command",
		args:    []string{"--environment", "blah", "bootstrap"},
		code:    2,
		out:     "error: flag provided but not defined: --environment\n",
	}, {
		summary: "juju sync-tools registered properly",
		args:    []string{"sync-tools", "--help"},
		code:    0,
		out:     syncToolsHelpText(),
	}, {
		summary: "check version command registered properly",
		args:    []string{"version"},
		code:    0,
		out:     version.Current.String() + "\n",
	},
}

func (s *MainSuite) TestRunMain(c *C) {
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	for i, t := range runMainTests {
		c.Logf("test %d: %s", i, t.summary)
		out := badrun(c, t.code, t.args...)
		c.Assert(out, Equals, t.out)
	}
}

var brokenConfig = `
environments:
    one:
        type: dummy
        state-server: false
        authorized-keys: i-am-a-key
        broken: %s
`

// breakJuju forces the dummy environment to return an error
// when environMethod is called.
func breakJuju(c *C, environMethod string) (msg string) {
	yaml := fmt.Sprintf(brokenConfig, environMethod)
	err := ioutil.WriteFile(config.JujuHomePath("environments.yaml"), []byte(yaml), 0666)
	c.Assert(err, IsNil)

	return fmt.Sprintf("dummy.%s is broken", environMethod)
}

func (s *MainSuite) TestActualRunJujuArgsBeforeCommand(c *C) {
	defer testing.MakeFakeHomeNoEnvironments(c, "one").Restore()
	// Check global args work when specified before command
	msg := breakJuju(c, "Bootstrap")
	logpath := filepath.Join(c.MkDir(), "log")
	out := badrun(c, 1, "--log-file", logpath, "--verbose", "--debug", "bootstrap")
	c.Assert(out, Equals, "error: "+msg+"\n")
	content, err := ioutil.ReadFile(logpath)
	c.Assert(err, IsNil)
	fullmsg := fmt.Sprintf(`.*\n.*ERROR JUJU:juju:bootstrap juju bootstrap command failed: %s\n`, msg)
	c.Assert(string(content), Matches, fullmsg)
}

func (s *MainSuite) TestActualRunJujuArgsAfterCommand(c *C) {
	defer testing.MakeFakeHomeNoEnvironments(c, "one").Restore()
	// Check global args work when specified after command
	msg := breakJuju(c, "Bootstrap")
	logpath := filepath.Join(c.MkDir(), "log")
	out := badrun(c, 1, "bootstrap", "--log-file", logpath, "--verbose", "--debug")
	c.Assert(out, Equals, "error: "+msg+"\n")
	content, err := ioutil.ReadFile(logpath)
	c.Assert(err, IsNil)
	fullmsg := fmt.Sprintf(`.*\n.*ERROR JUJU:juju:bootstrap juju bootstrap command failed: %s\n`, msg)
	c.Assert(string(content), Matches, fullmsg)
}

var commandNames = []string{
	"add-relation",
	"add-unit",
	"bootstrap",
	"debug-log",
	"deploy",
	"destroy-environment",
	"destroy-machine",
	"destroy-relation",
	"destroy-service",
	"destroy-unit",
	"expose",
	"generate-config", // alias for init
	"get",
	"get-constraints",
	"help",
	"init",
	"remove-relation", // alias for destroy-relation
	"remove-unit",     // alias for destroy-unit
	"resolved",
	"scp",
	"set",
	"set-constraints",
	"ssh",
	"stat", // alias for status
	"status",
	"sync-tools",
	"terminate-machine", // alias for destroy-machine
	"unexpose",
	"upgrade-charm",
	"upgrade-juju",
	"version",
}

func (s *MainSuite) TestHelpCommands(c *C) {
	// Check that we have correctly registered all the commands
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "commands")
	lines := strings.Split(out, "\n")
	var names []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 {
			continue
		}
		names = append(names, f[0])
	}
	// The names should be output in alphabetical order, so don't sort.
	c.Assert(names, DeepEquals, commandNames)
}

var topicNames = []string{
	"basics",
	"commands",
	"global-options",
	"topics",
}

func (s *MainSuite) TestHelpTopics(c *C) {
	// Check that we have correctly registered all the topics
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "topics")
	lines := strings.Split(out, "\n")
	var names []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 {
			continue
		}
		names = append(names, f[0])
	}
	// The names should be output in alphabetical order, so don't sort.
	c.Assert(names, DeepEquals, topicNames)
}

var globalFlags = []string{
	"--debug .*",
	"-h, --help .*",
	"--log-file .*",
	"-v, --verbose .*",
}

func (s *MainSuite) TestHelpGlobalOptions(c *C) {
	// Check that we have correctly registered all the topics
	// by checking the help output.
	defer config.SetJujuHome(config.SetJujuHome(c.MkDir()))
	out := badrun(c, 0, "help", "global-options")
	c.Assert(out, Matches, `Global Options

These options may be used with any command, and may appear in front of any
command\.(.|\n)*`)
	lines := strings.Split(out, "\n")
	var flags []string
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) == 0 || line[0] != '-' {
			continue
		}
		flags = append(flags, line)
	}
	c.Assert(len(flags), Equals, len(globalFlags))
	for i, line := range flags {
		c.Assert(line, Matches, globalFlags[i])
	}
}
<|endoftext|>


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

// Keyserver is a wrapper for a key implementation that presents it as a grpc interface.
package main

import (
	"flag"
	"net/http"
	"strings"

	gContext "golang.org/x/net/context"

	"upspin.io/auth"
	"upspin.io/auth/grpcauth"
	"upspin.io/bind"
	"upspin.io/cloud/https"
	"upspin.io/context"
	"upspin.io/errors"
	"upspin.io/flags"
	"upspin.io/log"
	"upspin.io/metric"
	"upspin.io/upspin"
	"upspin.io/upspin/proto"

	// Load required transports
	_ "upspin.io/key/transports"
)

var project = flag.String("project", "", "The GCP project name, if any.")

// The upspin username for this server.
const serverName = "keyserver"

// Server is a SecureServer that talks to a KeyServer interface and serves gRPC requests.
type Server struct {
	context  upspin.Context
	endpoint upspin.Endpoint
	key      upspin.KeyServer // default user service for looking up keys for unauthenticated users.
	// Automatically handles authentication by implementing the Authenticate server method.
	grpcauth.SecureServer
}

func main() {
	flag.Parse()

	if *project != "" {
		log.Connect(*project, serverName)
		svr, err := metric.NewGCPSaver(*project, "serverName", serverName)
		if err != nil {
			log.Fatalf("Can't start a metric saver for GCP project %q: %s", *project, err)
		} else {
			metric.RegisterSaver(svr)
		}
	}

	endpoint, err := upspin.ParseEndpoint(flags.Endpoint)
	if err != nil {
		log.Fatalf("endpoint parse error: %v", err)
	}

	// All we need in the context is some user name. It does not need to be registered as a "real" user.
	context := context.New().SetUserName(serverName)

	// Get an instance so we can configure it and use it for authenticated connections.
	key, err := bind.KeyServer(context, *endpoint)
	if err != nil {
		log.Fatal(err)
	}

	// If there are configuration options, set them now
	if flags.Config != "" {
		opts := strings.Split(flags.Config, ",")
		// Configure it appropriately.
		log.Printf("Configuring server with options: %v", opts)
		err = key.Configure(opts...)
		if err != nil {
			log.Fatal(err)
		}
		// Now this pre-configured store is the one that will generate new instances for this server.
		err = bind.ReregisterKeyServer(endpoint.Transport, key)
		if err != nil {
			log.Fatal(err)
		}
	}

	s := &Server{
		context:  context,
		endpoint: *endpoint,
		key:      key,
	}
	authConfig := auth.Config{Lookup: s.internalLookup}
	grpcSecureServer, err := grpcauth.NewSecureServer(authConfig)
	if err != nil {
		log.Fatal(err)
	}
	s.SecureServer = grpcSecureServer
	proto.RegisterKeyServer(grpcSecureServer.GRPCServer(), s)

	http.Handle("/", grpcSecureServer.GRPCServer())
	// TODO: this needs to be changed to keyserver. But it involves some metadata on GCP.
	https.ListenAndServe("userserver", flags.HTTPSAddr, nil)
}

func (s *Server) internalLookup(userName upspin.UserName) (upspin.PublicKey, error) {
	user, err := s.key.Lookup(userName)
	return user.PublicKey, err
}

// keyServerFor returns a KeyServer bound to the user specified in the context.
func (s *Server) keyServerFor(ctx gContext.Context) (upspin.KeyServer, error) {
	// Validate that we have a session. If not, it's an auth error.
	session, err := s.GetSessionFromContext(ctx)
	if err != nil {
		return nil, err
	}
	context := s.context.Copy().SetUserName(session.User())
	key, err := bind.KeyServer(context, s.endpoint)
	return key, err
}

// Lookup implements upspin.KeyServer, and does not do any authentication.
func (s *Server) Lookup(ctx gContext.Context, req *proto.KeyLookupRequest) (*proto.KeyLookupResponse, error) {
	log.Printf("Lookup %q", req.UserName)

	user, err := s.key.Lookup(upspin.UserName(req.UserName))
	if err != nil {
		log.Printf("Lookup %q failed: %v", req.UserName, err)
		return &proto.KeyLookupResponse{Error: errors.MarshalError(err)}, nil
	}
	return &proto.KeyLookupResponse{User: proto.UserProto(user)}, nil
}

// keyPutError is
func keyPutError(err error) *proto.KeyPutResponse {
	return &proto.KeyPutResponse{Error: errors.MarshalError(err)}
}

// Put implements upspin.KeyServer.
func (s *Server) Put(ctx gContext.Context, req *proto.KeyPutRequest) (*proto.KeyPutResponse, error) {
	log.Printf("Put %v", req)

	key, err := s.keyServerFor(ctx)
	if err != nil {
		log.Printf("Put %q authentication failed: %v", req.User.Name, err)
		return keyPutError(err), nil

	}
	user := proto.UpspinUser(req.User)
	err = key.Put(user)
	if err != nil {
		log.Printf("Put %q failed: %v", user.Name, err)
		return keyPutError(err), nil
	}
	return &proto.KeyPutResponse{}, nil
}

// Configure implements upspin.Service
func (s *Server) Configure(ctx gContext.Context, req *proto.ConfigureRequest) (*proto.ConfigureResponse, error) {
	log.Printf("Configure %q", req.Options)

	key, err := s.keyServerFor(ctx)
	if err != nil {
		return nil, err
	}
	err = key.Configure(req.Options...)
	if err != nil {
		log.Printf("Configure %q failed: %v", req.Options, err)
		return &proto.ConfigureResponse{Error: errors.MarshalError(err)}, nil
	}
	return nil, nil
}

// Endpoint implements upspin.Service
func (s *Server) Endpoint(ctx gContext.Context, req *proto.EndpointRequest) (*proto.EndpointResponse, error) {
	log.Print("Endpoint")

	key, err := s.keyServerFor(ctx)
	if err != nil {
		return nil, err
	}
	endpoint := key.Endpoint()
	resp := &proto.EndpointResponse{
		Endpoint: &proto.Endpoint{
			Transport: int32(endpoint.Transport),
			NetAddr:   string(endpoint.NetAddr),
		},
	}
	return resp, nil
}
<commit_msg>cmd/keyserver: fix panic on unchecked error<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Keyserver is a wrapper for a key implementation that presents it as a grpc interface.
package main

import (
	"flag"
	"net/http"
	"strings"

	gContext "golang.org/x/net/context"

	"upspin.io/auth"
	"upspin.io/auth/grpcauth"
	"upspin.io/bind"
	"upspin.io/cloud/https"
	"upspin.io/context"
	"upspin.io/errors"
	"upspin.io/flags"
	"upspin.io/log"
	"upspin.io/metric"
	"upspin.io/upspin"
	"upspin.io/upspin/proto"

	// Load required transports
	_ "upspin.io/key/transports"
)

var project = flag.String("project", "", "The GCP project name, if any.")

// The upspin username for this server.
const serverName = "keyserver"

// Server is a SecureServer that talks to a KeyServer interface and serves gRPC requests.
type Server struct {
	context  upspin.Context
	endpoint upspin.Endpoint
	key      upspin.KeyServer // default user service for looking up keys for unauthenticated users.
	// Automatically handles authentication by implementing the Authenticate server method.
	grpcauth.SecureServer
}

func main() {
	flag.Parse()

	if *project != "" {
		log.Connect(*project, serverName)
		svr, err := metric.NewGCPSaver(*project, "serverName", serverName)
		if err != nil {
			log.Fatalf("Can't start a metric saver for GCP project %q: %s", *project, err)
		} else {
			metric.RegisterSaver(svr)
		}
	}

	endpoint, err := upspin.ParseEndpoint(flags.Endpoint)
	if err != nil {
		log.Fatalf("endpoint parse error: %v", err)
	}

	// All we need in the context is some user name. It does not need to be registered as a "real" user.
	context := context.New().SetUserName(serverName)

	// Get an instance so we can configure it and use it for authenticated connections.
	key, err := bind.KeyServer(context, *endpoint)
	if err != nil {
		log.Fatal(err)
	}

	// If there are configuration options, set them now
	if flags.Config != "" {
		opts := strings.Split(flags.Config, ",")
		// Configure it appropriately.
		log.Printf("Configuring server with options: %v", opts)
		err = key.Configure(opts...)
		if err != nil {
			log.Fatal(err)
		}
		// Now this pre-configured store is the one that will generate new instances for this server.
		err = bind.ReregisterKeyServer(endpoint.Transport, key)
		if err != nil {
			log.Fatal(err)
		}
	}

	s := &Server{
		context:  context,
		endpoint: *endpoint,
		key:      key,
	}
	authConfig := auth.Config{Lookup: s.internalLookup}
	grpcSecureServer, err := grpcauth.NewSecureServer(authConfig)
	if err != nil {
		log.Fatal(err)
	}
	s.SecureServer = grpcSecureServer
	proto.RegisterKeyServer(grpcSecureServer.GRPCServer(), s)

	http.Handle("/", grpcSecureServer.GRPCServer())
	// TODO: this needs to be changed to keyserver. But it involves some metadata on GCP.
	https.ListenAndServe("userserver", flags.HTTPSAddr, nil)
}

func (s *Server) internalLookup(userName upspin.UserName) (upspin.PublicKey, error) {
	user, err := s.key.Lookup(userName)
	if err != nil {
		return "", err
	}
	return user.PublicKey, nil
}

// keyServerFor returns a KeyServer bound to the user specified in the context.
func (s *Server) keyServerFor(ctx gContext.Context) (upspin.KeyServer, error) {
	// Validate that we have a session. If not, it's an auth error.
	session, err := s.GetSessionFromContext(ctx)
	if err != nil {
		return nil, err
	}
	context := s.context.Copy().SetUserName(session.User())
	key, err := bind.KeyServer(context, s.endpoint)
	return key, err
}

// Lookup implements upspin.KeyServer, and does not do any authentication.
func (s *Server) Lookup(ctx gContext.Context, req *proto.KeyLookupRequest) (*proto.KeyLookupResponse, error) {
	log.Printf("Lookup %q", req.UserName)

	user, err := s.key.Lookup(upspin.UserName(req.UserName))
	if err != nil {
		log.Printf("Lookup %q failed: %v", req.UserName, err)
		return &proto.KeyLookupResponse{Error: errors.MarshalError(err)}, nil
	}
	return &proto.KeyLookupResponse{User: proto.UserProto(user)}, nil
}

// keyPutError is
func keyPutError(err error) *proto.KeyPutResponse {
	return &proto.KeyPutResponse{Error: errors.MarshalError(err)}
}

// Put implements upspin.KeyServer.
func (s *Server) Put(ctx gContext.Context, req *proto.KeyPutRequest) (*proto.KeyPutResponse, error) {
	log.Printf("Put %v", req)

	key, err := s.keyServerFor(ctx)
	if err != nil {
		log.Printf("Put %q authentication failed: %v", req.User.Name, err)
		return keyPutError(err), nil

	}
	user := proto.UpspinUser(req.User)
	err = key.Put(user)
	if err != nil {
		log.Printf("Put %q failed: %v", user.Name, err)
		return keyPutError(err), nil
	}
	return &proto.KeyPutResponse{}, nil
}

// Configure implements upspin.Service
func (s *Server) Configure(ctx gContext.Context, req *proto.ConfigureRequest) (*proto.ConfigureResponse, error) {
	log.Printf("Configure %q", req.Options)

	key, err := s.keyServerFor(ctx)
	if err != nil {
		return nil, err
	}
	err = key.Configure(req.Options...)
	if err != nil {
		log.Printf("Configure %q failed: %v", req.Options, err)
		return &proto.ConfigureResponse{Error: errors.MarshalError(err)}, nil
	}
	return nil, nil
}

// Endpoint implements upspin.Service
func (s *Server) Endpoint(ctx gContext.Context, req *proto.EndpointRequest) (*proto.EndpointResponse, error) {
	log.Print("Endpoint")

	key, err := s.keyServerFor(ctx)
	if err != nil {
		return nil, err
	}
	endpoint := key.Endpoint()
	resp := &proto.EndpointResponse{
		Endpoint: &proto.Endpoint{
			Transport: int32(endpoint.Transport),
			NetAddr:   string(endpoint.NetAddr),
		},
	}
	return resp, nil
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io/ioutil"
	"os"
	"reflect"
	"strconv"
	"strings"

	"github.com/yosuke-furukawa/json5/encoding/json5"
	"github.com/zyedidia/glob"
)

// The options that the user can set
var globalSettings map[string]interface{}

// InitGlobalSettings initializes the options map and sets all options to their default values
func InitGlobalSettings() {
	defaults := DefaultGlobalSettings()
	var parsed map[string]interface{}

	filename := configDir + "/settings.json"
	writeSettings := false
	if _, e := os.Stat(filename); e == nil {
		input, err := ioutil.ReadFile(filename)
		if !strings.HasPrefix(string(input), "null") {
			if err != nil {
				TermMessage("Error reading settings.json file: " + err.Error())
				return
			}

			err = json5.Unmarshal(input, &parsed)
			if err != nil {
				TermMessage("Error reading settings.json:", err.Error())
			}
		} else {
			writeSettings = true
		}
	}

	globalSettings = make(map[string]interface{})
	for k, v := range defaults {
		globalSettings[k] = v
	}
	for k, v := range parsed {
		if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
			globalSettings[k] = v
		}
	}

	if _, err := os.Stat(filename); os.IsNotExist(err) || writeSettings {
		err := WriteSettings(filename)
		if err != nil {
			TermMessage("Error writing settings.json file: " + err.Error())
		}
	}
}

// InitLocalSettings scans the json in settings.json and sets the options locally based
// on whether the buffer matches the glob
func InitLocalSettings(buf *Buffer) {
	var parsed map[string]interface{}

	filename := configDir + "/settings.json"
	if _, e := os.Stat(filename); e == nil {
		input, err := ioutil.ReadFile(filename)
		if err != nil {
			TermMessage("Error reading settings.json file: " + err.Error())
			return
		}

		err = json5.Unmarshal(input, &parsed)
		if err != nil {
			TermMessage("Error reading settings.json:", err.Error())
		}
	}

	for k, v := range parsed {
		if strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
			g, err := glob.Compile(k)
			if err != nil {
				TermMessage("Error with glob setting ", k, ": ", err)
				continue
			}

			if g.MatchString(buf.Path) {
				for k1, v1 := range v.(map[string]interface{}) {
					buf.Settings[k1] = v1
				}
			}
		}
	}
}

// WriteSettings writes the settings to the specified filename as JSON
func WriteSettings(filename string) error {
	var err error
	if _, e := os.Stat(configDir); e == nil {
		parsed := make(map[string]interface{})

		filename := configDir + "/settings.json"
		for k, v := range globalSettings {
			parsed[k] = v
		}
		if _, e := os.Stat(filename); e == nil {
			input, err := ioutil.ReadFile(filename)
			if string(input) != "null" {
				if err != nil {
					return err
				}

				err = json5.Unmarshal(input, &parsed)
				if err != nil {
					TermMessage("Error reading settings.json:", err.Error())
				}

				for k, v := range parsed {
					if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
						if _, ok := globalSettings[k]; ok {
							parsed[k] = globalSettings[k]
						}
					}
				}
			}
		}

		txt, _ := json5.MarshalIndent(parsed, "", "    ")
		err = ioutil.WriteFile(filename, append(txt, '\n'), 0644)
	}
	return err
}

// AddOption creates a new option. This is meant to be called by plugins to add options.
func AddOption(name string, value interface{}) {
	globalSettings[name] = value
	err := WriteSettings(configDir + "/settings.json")
	if err != nil {
		TermMessage("Error writing settings.json file: " + err.Error())
	}
}

// GetGlobalOption returns the global value of the given option
func GetGlobalOption(name string) interface{} {
	return globalSettings[name]
}

// GetLocalOption returns the local value of the given option
func GetLocalOption(name string, buf *Buffer) interface{} {
	return buf.Settings[name]
}

// GetOption returns the value of the given option
// If there is a local version of the option, it returns that
// otherwise it will return the global version
func GetOption(name string) interface{} {
	if GetLocalOption(name, CurView().Buf) != nil {
		return GetLocalOption(name, CurView().Buf)
	}
	return GetGlobalOption(name)
}

// DefaultGlobalSettings returns the default global settings for micro
// Note that colorscheme is a global only option
func DefaultGlobalSettings() map[string]interface{} {
	return map[string]interface{}{
		"autoindent":   true,
		"colorcolumn":  float64(0),
		"colorscheme":  "zenburn",
		"cursorline":   true,
		"ignorecase":   false,
		"indentchar":   " ",
		"infobar":      true,
		"ruler":        true,
		"savecursor":   false,
		"saveundo":     false,
		"scrollspeed":  float64(2),
		"scrollmargin": float64(3),
		"statusline":   true,
		"syntax":       true,
		"tabsize":      float64(4),
		"tabstospaces": false,
	}
}

// DefaultLocalSettings returns the default local settings
// Note that filetype is a local only option
func DefaultLocalSettings() map[string]interface{} {
	return map[string]interface{}{
		"autoindent":   true,
		"colorcolumn":  float64(0),
		"cursorline":   true,
		"filetype":     "Unknown",
		"ignorecase":   false,
		"indentchar":   " ",
		"ruler":        true,
		"savecursor":   false,
		"saveundo":     false,
		"scrollspeed":  float64(2),
		"scrollmargin": float64(3),
		"statusline":   true,
		"syntax":       true,
		"tabsize":      float64(4),
		"tabstospaces": false,
	}
}

// SetOption attempts to set the given option to the value
// By default it will set the option as global, but if the option
// is local only it will set the local version
// Use setlocal to force an option to be set locally
func SetOption(option, value string) error {
	if option == "colorscheme" {
		if !ColorschemeExists(value) {
			return errors.New(value + " is not a valid colorscheme")
		}
	}

	if _, ok := globalSettings[option]; !ok {
		if _, ok := CurView().Buf.Settings[option]; !ok {
			return errors.New("Invalid option")
		}
		SetLocalOption(option, value, CurView())
		return nil
	}

	kind := reflect.TypeOf(globalSettings[option]).Kind()
	if kind == reflect.Bool {
		b, err := ParseBool(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		globalSettings[option] = b
	} else if kind == reflect.String {
		globalSettings[option] = value
	} else if kind == reflect.Float64 {
		i, err := strconv.Atoi(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		globalSettings[option] = float64(i)
	}

	if option == "colorscheme" {
		LoadSyntaxFiles()
		for _, tab := range tabs {
			for _, view := range tab.views {
				view.Buf.UpdateRules()
				if view.Buf.Settings["syntax"].(bool) {
					view.matches = Match(view)
				}
			}
		}
	}

	if option == "infobar" {
		for _, tab := range tabs {
			tab.Resize()
		}
	}

	if _, ok := CurView().Buf.Settings[option]; ok {
		for _, tab := range tabs {
			for _, view := range tab.views {
				SetLocalOption(option, value, view)
			}
		}
	}

	return nil
}

// SetLocalOption sets the local version of this option
func SetLocalOption(option, value string, view *View) error {
	buf := view.Buf
	if _, ok := buf.Settings[option]; !ok {
		return errors.New("Invalid option")
	}

	kind := reflect.TypeOf(buf.Settings[option]).Kind()
	if kind == reflect.Bool {
		b, err := ParseBool(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		buf.Settings[option] = b
	} else if kind == reflect.String {
		buf.Settings[option] = value
	} else if kind == reflect.Float64 {
		i, err := strconv.Atoi(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		buf.Settings[option] = float64(i)
	}

	if option == "statusline" {
		view.ToggleStatusLine()
		if buf.Settings["syntax"].(bool) {
			view.matches = Match(view)
		}
	}

	if option == "filetype" {
		LoadSyntaxFiles()
		buf.UpdateRules()
		if buf.Settings["syntax"].(bool) {
			view.matches = Match(view)
		}
	}

	return nil
}

// SetOptionAndSettings sets the given option and saves the option setting to the settings config file
func SetOptionAndSettings(option, value string) {
	filename := configDir + "/settings.json"

	err := SetOption(option, value)

	if err != nil {
		messenger.Error(err.Error())
		return
	}

	err = WriteSettings(filename)
	if err != nil {
		messenger.Error("Error writing to settings.json: " + err.Error())
		return
	}
}
<commit_msg>Added ability to validate options values when being set<commit_after>package main

import (
	"errors"
	"io/ioutil"
	"os"
	"reflect"
	"strconv"
	"strings"

	"github.com/yosuke-furukawa/json5/encoding/json5"
	"github.com/zyedidia/glob"
)

type optionValidator func(string, interface{}) error

// The options that the user can set
var globalSettings map[string]interface{}

// Options with validators
var optionValidators = map[string]optionValidator{
	"tabsize":      validatePositiveValue,
	"scrollmargin": validateNonNegativeValue,
	"scrollspeed":  validateNonNegativeValue,
	"colorscheme":  validateColorscheme,
	"colorcolumn":  validateNonNegativeValue,
}

// InitGlobalSettings initializes the options map and sets all options to their default values
func InitGlobalSettings() {
	defaults := DefaultGlobalSettings()
	var parsed map[string]interface{}

	filename := configDir + "/settings.json"
	writeSettings := false
	if _, e := os.Stat(filename); e == nil {
		input, err := ioutil.ReadFile(filename)
		if !strings.HasPrefix(string(input), "null") {
			if err != nil {
				TermMessage("Error reading settings.json file: " + err.Error())
				return
			}

			err = json5.Unmarshal(input, &parsed)
			if err != nil {
				TermMessage("Error reading settings.json:", err.Error())
			}
		} else {
			writeSettings = true
		}
	}

	globalSettings = make(map[string]interface{})
	for k, v := range defaults {
		globalSettings[k] = v
	}
	for k, v := range parsed {
		if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
			globalSettings[k] = v
		}
	}

	if _, err := os.Stat(filename); os.IsNotExist(err) || writeSettings {
		err := WriteSettings(filename)
		if err != nil {
			TermMessage("Error writing settings.json file: " + err.Error())
		}
	}
}

// InitLocalSettings scans the json in settings.json and sets the options locally based
// on whether the buffer matches the glob
func InitLocalSettings(buf *Buffer) {
	var parsed map[string]interface{}

	filename := configDir + "/settings.json"
	if _, e := os.Stat(filename); e == nil {
		input, err := ioutil.ReadFile(filename)
		if err != nil {
			TermMessage("Error reading settings.json file: " + err.Error())
			return
		}

		err = json5.Unmarshal(input, &parsed)
		if err != nil {
			TermMessage("Error reading settings.json:", err.Error())
		}
	}

	for k, v := range parsed {
		if strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
			g, err := glob.Compile(k)
			if err != nil {
				TermMessage("Error with glob setting ", k, ": ", err)
				continue
			}

			if g.MatchString(buf.Path) {
				for k1, v1 := range v.(map[string]interface{}) {
					buf.Settings[k1] = v1
				}
			}
		}
	}
}

// WriteSettings writes the settings to the specified filename as JSON
func WriteSettings(filename string) error {
	var err error
	if _, e := os.Stat(configDir); e == nil {
		parsed := make(map[string]interface{})

		filename := configDir + "/settings.json"
		for k, v := range globalSettings {
			parsed[k] = v
		}
		if _, e := os.Stat(filename); e == nil {
			input, err := ioutil.ReadFile(filename)
			if string(input) != "null" {
				if err != nil {
					return err
				}

				err = json5.Unmarshal(input, &parsed)
				if err != nil {
					TermMessage("Error reading settings.json:", err.Error())
				}

				for k, v := range parsed {
					if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
						if _, ok := globalSettings[k]; ok {
							parsed[k] = globalSettings[k]
						}
					}
				}
			}
		}

		txt, _ := json5.MarshalIndent(parsed, "", "    ")
		err = ioutil.WriteFile(filename, append(txt, '\n'), 0644)
	}
	return err
}

// AddOption creates a new option. This is meant to be called by plugins to add options.
func AddOption(name string, value interface{}) {
	globalSettings[name] = value
	err := WriteSettings(configDir + "/settings.json")
	if err != nil {
		TermMessage("Error writing settings.json file: " + err.Error())
	}
}

// GetGlobalOption returns the global value of the given option
func GetGlobalOption(name string) interface{} {
	return globalSettings[name]
}

// GetLocalOption returns the local value of the given option
func GetLocalOption(name string, buf *Buffer) interface{} {
	return buf.Settings[name]
}

// GetOption returns the value of the given option
// If there is a local version of the option, it returns that
// otherwise it will return the global version
func GetOption(name string) interface{} {
	if GetLocalOption(name, CurView().Buf) != nil {
		return GetLocalOption(name, CurView().Buf)
	}
	return GetGlobalOption(name)
}

// DefaultGlobalSettings returns the default global settings for micro
// Note that colorscheme is a global only option
func DefaultGlobalSettings() map[string]interface{} {
	return map[string]interface{}{
		"autoindent":   true,
		"colorcolumn":  float64(0),
		"colorscheme":  "zenburn",
		"cursorline":   true,
		"ignorecase":   false,
		"indentchar":   " ",
		"infobar":      true,
		"ruler":        true,
		"savecursor":   false,
		"saveundo":     false,
		"scrollspeed":  float64(2),
		"scrollmargin": float64(3),
		"statusline":   true,
		"syntax":       true,
		"tabsize":      float64(4),
		"tabstospaces": false,
	}
}

// DefaultLocalSettings returns the default local settings
// Note that filetype is a local only option
func DefaultLocalSettings() map[string]interface{} {
	return map[string]interface{}{
		"autoindent":   true,
		"colorcolumn":  float64(0),
		"cursorline":   true,
		"filetype":     "Unknown",
		"ignorecase":   false,
		"indentchar":   " ",
		"ruler":        true,
		"savecursor":   false,
		"saveundo":     false,
		"scrollspeed":  float64(2),
		"scrollmargin": float64(3),
		"statusline":   true,
		"syntax":       true,
		"tabsize":      float64(4),
		"tabstospaces": false,
	}
}

// SetOption attempts to set the given option to the value
// By default it will set the option as global, but if the option
// is local only it will set the local version
// Use setlocal to force an option to be set locally
func SetOption(option, value string) error {
	if _, ok := globalSettings[option]; !ok {
		if _, ok := CurView().Buf.Settings[option]; !ok {
			return errors.New("Invalid option")
		}
		SetLocalOption(option, value, CurView())
		return nil
	}

	var nativeValue interface{}

	kind := reflect.TypeOf(globalSettings[option]).Kind()
	if kind == reflect.Bool {
		b, err := ParseBool(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		nativeValue = b
	} else if kind == reflect.String {
		nativeValue = value
	} else if kind == reflect.Float64 {
		i, err := strconv.Atoi(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		nativeValue = float64(i)
	} else {
		return errors.New("Option has unsupported value type")
	}

	if err := optionIsValid(option, nativeValue); err != nil {
		return err
	}

	globalSettings[option] = nativeValue

	if option == "colorscheme" {
		LoadSyntaxFiles()
		for _, tab := range tabs {
			for _, view := range tab.views {
				view.Buf.UpdateRules()
				if view.Buf.Settings["syntax"].(bool) {
					view.matches = Match(view)
				}
			}
		}
	}

	if option == "infobar" {
		for _, tab := range tabs {
			tab.Resize()
		}
	}

	if _, ok := CurView().Buf.Settings[option]; ok {
		for _, tab := range tabs {
			for _, view := range tab.views {
				SetLocalOption(option, value, view)
			}
		}
	}

	return nil
}

// SetLocalOption sets the local version of this option
func SetLocalOption(option, value string, view *View) error {
	buf := view.Buf
	if _, ok := buf.Settings[option]; !ok {
		return errors.New("Invalid option")
	}

	var nativeValue interface{}

	kind := reflect.TypeOf(buf.Settings[option]).Kind()
	if kind == reflect.Bool {
		b, err := ParseBool(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		nativeValue = b
	} else if kind == reflect.String {
		nativeValue = value
	} else if kind == reflect.Float64 {
		i, err := strconv.Atoi(value)
		if err != nil {
			return errors.New("Invalid value")
		}
		nativeValue = float64(i)
	} else {
		return errors.New("Option has unsupported value type")
	}

	if err := optionIsValid(option, nativeValue); err != nil {
		return err
	}

	buf.Settings[option] = nativeValue

	if option == "statusline" {
		view.ToggleStatusLine()
		if buf.Settings["syntax"].(bool) {
			view.matches = Match(view)
		}
	}

	if option == "filetype" {
		LoadSyntaxFiles()
		buf.UpdateRules()
		if buf.Settings["syntax"].(bool) {
			view.matches = Match(view)
		}
	}

	return nil
}

// SetOptionAndSettings sets the given option and saves the option setting to the settings config file
func SetOptionAndSettings(option, value string) {
	filename := configDir + "/settings.json"

	err := SetOption(option, value)

	if err != nil {
		messenger.Error(err.Error())
		return
	}

	err = WriteSettings(filename)
	if err != nil {
		messenger.Error("Error writing to settings.json: " + err.Error())
		return
	}
}

func optionIsValid(option string, value interface{}) error {
	if validator, ok := optionValidators[option]; ok {
		return validator(option, value)
	}

	return nil
}

// Option validators

func validatePositiveValue(option string, value interface{}) error {
	tabsize, ok := value.(float64)

	if !ok {
		return errors.New("Expected numeric type for " + option)
	}

	if tabsize < 1 {
		return errors.New(option + " must be greater than 0")
	}

	return nil
}

func validateNonNegativeValue(option string, value interface{}) error {
	nativeValue, ok := value.(float64)

	if !ok {
		return errors.New("Expected numeric type for " + option)
	}

	if nativeValue < 0 {
		return errors.New(option + " must be non-negative")
	}

	return nil
}

func validateColorscheme(option string, value interface{}) error {
	colorscheme, ok := value.(string)

	if !ok {
		return errors.New("Expected string type for colorscheme")
	}

	if !ColorschemeExists(colorscheme) {
		return errors.New(colorscheme + " is not a valid colorscheme")
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"mips"
	"io"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
)

var header = `MIPS Pipeline Simulator
EECS645 - cline@ku.edu
`

const (
	modeNoForwarding = iota
	modePredictTaken
	modePredictNotTaken
)

var modeNames = map[int]string{
	modeNoForwarding:    "No Forwarding/Bypassing",
	modePredictTaken:    "Predict Branches Taken",
	modePredictNotTaken: "Predict Branches Not Taken",
}

type simulator struct {
	i io.Reader
	o io.Writer
	//e io.Writer
	inputFile, registerFile, timingFile string
	//input, register, timing io.WriteCloser
	simulatorMode int
}

func NewSimulator(i io.Reader, o io.Writer) (*simulator, error) {
	s := new(simulator)
	s.i, s.o = i, o
	//s.e = e
	return s, s.collectInput()
}

type niceReader struct {
	*bufio.Reader
}

func (nr niceReader) ReadLine() (string, error) {
	result, err := nr.ReadString('\n')
	return strings.TrimRight(result, "\n"), err
}

func (s *simulator) collectInput() (err error) {
	buf := niceReader{bufio.NewReader(s.i)}

	// input
	fmt.Fprintf(s.o, "Enter input filename: ")
	if s.inputFile, err = buf.ReadLine(); err != nil {
		return err
	}

	// mode
	for _, mode := range []int{
		modeNoForwarding,
		modePredictTaken,
		modePredictNotTaken,
	} {
		fmt.Fprintf(s.o, "%d: %s\n", mode, modeNames[mode])
	}
	fmt.Fprintf(s.o, "\nSelect Mode: ")
	if strMode, err := buf.ReadLine(); err != nil {
		return err
	} else if s.simulatorMode, err = strconv.Atoi(strMode); err != nil {
		return err
	}

	// register
	fmt.Fprintf(s.o, "\nEnter register filename: ")
	if s.registerFile, err = buf.ReadLine(); err != nil {
		return err
	}

	// input
	fmt.Fprintf(s.o, "\nEnter timing filename: ")
	if s.timingFile, err = buf.ReadLine(); err != nil {
		return err
	}

	return nil
}

func (s *simulator) xcollectFiles() error {

	for _, info := range []struct {
		name string
		dest *string
	}{
		{"input", &s.inputFile},
		{"timing", &s.timingFile},
		{"register", &s.registerFile},
	} {

		fmt.Fprintf(s.o, "Enter %s filename: ", info.name)
		b := bufio.NewReader(s.i)
		str, err := b.ReadString('\n')
		*(info.dest) = str
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *simulator) run() error {
	input, err := ioutil.ReadFile(s.inputFile)
	if err != nil {
		return err
	}

	cpu, err := mips.ParseCPUString(string(input))
	if err != nil {
		return err
	}

	switch s.simulatorMode {
	case modeNoForwarding:
		cpu.ForwardingEnabled = false
		cpu.BranchMode = mips.BranchPolicyFlush
	case modePredictTaken:
		cpu.ForwardingEnabled = true
		cpu.BranchMode = mips.BranchPolicyPredictTaken
	case modePredictNotTaken:
		cpu.ForwardingEnabled = true
		cpu.BranchMode = mips.BranchPolicyPredictTaken
	}

	fmt.Fprintln(s.o, "\nRunning Simulation.\n")
	if err := cpu.Run(10000); err != nil {
		fmt.Fprintln(os.Stderr, "Error running simulation:", err)
		return err
	}

	if err := ioutil.WriteFile(s.timingFile, []byte(cpu.RenderTiming()), 0666); err != nil {
		return err
	}
	fmt.Fprintln(s.o, "Wrote timing to", s.timingFile)
	if err := ioutil.WriteFile(s.registerFile, []byte(cpu.Registers.String()), 0666); err != nil {
		return err
	}
	fmt.Fprintln(s.o, "Wrote register contents to", s.registerFile)
	return nil
}

func main() {
	// @todo prompt user for input and output files
	//m := mips.NewMachine()

	fmt.Println(header)
	s, err := NewSimulator(os.Stdin, os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
	if err := s.run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	fmt.Println("done.")
}
<commit_msg>fix import path<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	"github.com/tmc/mips"
)

var header = `MIPS Pipeline Simulator
EECS645 - cline@ku.edu
`

const (
	modeNoForwarding = iota
	modePredictTaken
	modePredictNotTaken
)

var modeNames = map[int]string{
	modeNoForwarding:    "No Forwarding/Bypassing",
	modePredictTaken:    "Predict Branches Taken",
	modePredictNotTaken: "Predict Branches Not Taken",
}

type simulator struct {
	i io.Reader
	o io.Writer
	//e io.Writer
	inputFile, registerFile, timingFile string
	//input, register, timing io.WriteCloser
	simulatorMode int
}

func NewSimulator(i io.Reader, o io.Writer) (*simulator, error) {
	s := new(simulator)
	s.i, s.o = i, o
	//s.e = e
	return s, s.collectInput()
}

type niceReader struct {
	*bufio.Reader
}

func (nr niceReader) ReadLine() (string, error) {
	result, err := nr.ReadString('\n')
	return strings.TrimRight(result, "\n"), err
}

func (s *simulator) collectInput() (err error) {
	buf := niceReader{bufio.NewReader(s.i)}

	// input
	fmt.Fprintf(s.o, "Enter input filename: ")
	if s.inputFile, err = buf.ReadLine(); err != nil {
		return err
	}

	// mode
	for _, mode := range []int{
		modeNoForwarding,
		modePredictTaken,
		modePredictNotTaken,
	} {
		fmt.Fprintf(s.o, "%d: %s\n", mode, modeNames[mode])
	}
	fmt.Fprintf(s.o, "\nSelect Mode: ")
	if strMode, err := buf.ReadLine(); err != nil {
		return err
	} else if s.simulatorMode, err = strconv.Atoi(strMode); err != nil {
		return err
	}

	// register
	fmt.Fprintf(s.o, "\nEnter register filename: ")
	if s.registerFile, err = buf.ReadLine(); err != nil {
		return err
	}

	// input
	fmt.Fprintf(s.o, "\nEnter timing filename: ")
	if s.timingFile, err = buf.ReadLine(); err != nil {
		return err
	}

	return nil
}

func (s *simulator) xcollectFiles() error {

	for _, info := range []struct {
		name string
		dest *string
	}{
		{"input", &s.inputFile},
		{"timing", &s.timingFile},
		{"register", &s.registerFile},
	} {

		fmt.Fprintf(s.o, "Enter %s filename: ", info.name)
		b := bufio.NewReader(s.i)
		str, err := b.ReadString('\n')
		*(info.dest) = str
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *simulator) run() error {
	input, err := ioutil.ReadFile(s.inputFile)
	if err != nil {
		return err
	}

	cpu, err := mips.ParseCPUString(string(input))
	if err != nil {
		return err
	}

	switch s.simulatorMode {
	case modeNoForwarding:
		cpu.ForwardingEnabled = false
		cpu.BranchMode = mips.BranchPolicyFlush
	case modePredictTaken:
		cpu.ForwardingEnabled = true
		cpu.BranchMode = mips.BranchPolicyPredictTaken
	case modePredictNotTaken:
		cpu.ForwardingEnabled = true
		cpu.BranchMode = mips.BranchPolicyPredictTaken
	}

	fmt.Fprintln(s.o, "\nRunning Simulation.\n")
	if err := cpu.Run(10000); err != nil {
		fmt.Fprintln(os.Stderr, "Error running simulation:", err)
		return err
	}

	if err := ioutil.WriteFile(s.timingFile, []byte(cpu.RenderTiming()), 0666); err != nil {
		return err
	}
	fmt.Fprintln(s.o, "Wrote timing to", s.timingFile)
	if err := ioutil.WriteFile(s.registerFile, []byte(cpu.Registers.String()), 0666); err != nil {
		return err
	}
	fmt.Fprintln(s.o, "Wrote register contents to", s.registerFile)
	return nil
}

func main() {
	// @todo prompt user for input and output files
	//m := mips.NewMachine()

	fmt.Println(header)
	s, err := NewSimulator(os.Stdin, os.Stdout)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
	if err := s.run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	fmt.Println("done.")
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"html/template"
	"log"

	cautiouspancake "github.com/tam7t/cautious-pancake"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
)

func main() {
	flag.Parse()

	conf := loader.Config{Build: &build.Default}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(flag.Args(), false)
	if err != nil {
		log.Fatal(err)
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	cg := cautiouspancake.NewCallGraph(iprog)
	err = cg.Analyze()
	if err != nil {
		log.Fatal(err)
	}

	for _, v := range cg.Pure() {
		fmt.Println("--")
		fmt.Println(PrintFuzz(v))
	}
}

const fuzzTemp = `package main

import (
	"fmt"

	"github.com/google/gofuzz"
	"{{.Package.Pkg.Path}}"
)

func main() { {{ $length := len .Params }}{{if gt $length 0}}
	f := fuzz.New(){{end}}
{{range $i, $v := .Params}}	var p{{$i}} {{$v.Type.String}}
{{end}}
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("found panic", r){{range $i, $v := .Params}}
			fmt.Printf("p{{$i}}: %v\n", p{{$i}}){{end}}
		}
	}()
	for { {{range $i, $v := .Params}}
		f.Fuzz(&p{{$i}}){{end}}
		{{.Package.Pkg.Name}}.{{.Name}}({{range $i, $v := .Params}}{{if $i}}, {{end}}p{{$i}}{{end}})
	}
}`

func PrintFuzz(f *ssa.Function) string {
	var out bytes.Buffer
	tmpl := template.Must(template.New("").Parse(fuzzTemp))
	tmpl.Execute(&out, f)
	return out.String()
}
<commit_msg>types.Type.String() has full path that does not work in generated code<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"html/template"
	"log"
	"path"

	cautiouspancake "github.com/tam7t/cautious-pancake"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
)

func main() {
	flag.Parse()

	conf := loader.Config{Build: &build.Default}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(flag.Args(), false)
	if err != nil {
		log.Fatal(err)
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	cg := cautiouspancake.NewCallGraph(iprog)
	err = cg.Analyze()
	if err != nil {
		log.Fatal(err)
	}

	for _, v := range cg.Pure() {
		fmt.Println("--")
		fmt.Println(PrintFuzz(v))
	}
}

const fuzzTemp = `package main

import (
	"fmt"

	"github.com/google/gofuzz"
	"{{.Package.Pkg.Path}}"
)

func main() { {{ $length := len .Params }}{{if gt $length 0}}
	f := fuzz.New(){{end}}
{{range $i, $v := .Params}}	var p{{$i}} {{$v.Type.String | strippkg}}
{{end}}
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("found panic", r){{range $i, $v := .Params}}
			fmt.Printf("p{{$i}}: %v\n", p{{$i}}){{end}}
		}
	}()
	for { {{range $i, $v := .Params}}
		f.Fuzz(&p{{$i}}){{end}}
		{{.Package.Pkg.Name}}.{{.Name}}({{range $i, $v := .Params}}{{if $i}}, {{end}}p{{$i}}{{end}})
	}
}`

func PrintFuzz(f *ssa.Function) string {
	var out bytes.Buffer
	tmpl := template.Must(template.New("").Funcs(template.FuncMap{"strippkg": func(a interface{}) string {
		return path.Base(a.(string))
	}}).Parse(fuzzTemp))
	tmpl.Execute(&out, f)
	return out.String()
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestNewCheckNmkAbs(t *testing.T) {
	savedGOPATH := os.Getenv("GOPATH")
	defer os.Setenv("GOPATH", savedGOPATH)
	pwd, err := os.Getwd()
	if err != nil {
		t.Fatalf("Could not determine current working directory: %s", err)
	}

	isNil := func(e error) bool { return e == nil }

	testTable := []struct {
		base, wd, a,
		wantP string
		wantE func(e error) bool
	}{{
		base:  filepath.Join(pwd, "test-fixtures", "new"),
		wd:    filepath.Join("src", "existing"),
		a:     ".",
		wantP: filepath.Join(pwd, "test-fixtures", "new", "src", "existing"),
		wantE: os.IsExist,
	}, {
		base:  filepath.Join(pwd, "test-fixtures", "new"),
		wd:    filepath.Join(""),
		a:     "non-existing",
		wantP: filepath.Join(pwd, "test-fixtures", "new", "src", "non-existing"),
		wantE: isNil,
	}}

	for _, test := range testTable {
		os.Setenv("GOPATH", test.base)
		err = os.Chdir(filepath.Join(test.base, test.wd))
		if err != nil {
			t.Fatalf("could not setup base: %s", err)
		}
		got, gotE := checkNmkAbs(test.a)
		if got != test.wantP {
			t.Errorf("got '%s', want: '%s'", got, test.wantP)
		}
		if !test.wantE(gotE) {
			t.Errorf("got error '%s'", gotE)
		}
	}
}
<commit_msg>add more tests for 'ponzu new' - run with 'go test . -run Check -v'<commit_after>package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestNewCheckNmkAbs(t *testing.T) {
	savedGOPATH := os.Getenv("GOPATH")
	defer os.Setenv("GOPATH", savedGOPATH)
	pwd, err := os.Getwd()
	if err != nil {
		t.Fatalf("Could not determine current working directory: %s", err)
	}

	isNil := func(e error) bool { return e == nil }
	isNonNil := func(e error) bool { return e != nil }

	baseDir := filepath.Join(pwd, "test-fixtures", "new")

	testTable := []struct {
		gopath, wd, a,
		wantP string
		wantE func(e error) bool
	}{{
		gopath: baseDir,
		wd:     filepath.Join("src", "existing"),
		a:      ".",
		wantP:  filepath.Join(pwd, "test-fixtures", "new", "src", "existing"),
		wantE:  os.IsExist,
	}, {
		gopath: baseDir,
		wd:     filepath.Join(""),
		a:      "non-existing",
		wantP:  filepath.Join(pwd, "test-fixtures", "new", "src", "non-existing"),
		wantE:  isNil,
	}, {
		gopath: baseDir,
		wd:     filepath.Join(""),
		a:      ".",
		wantP:  "",
		wantE:  isNonNil,
	}, {
		gopath: baseDir,
		wd:     "..",
		a:      ".",
		wantP:  "",
		wantE:  isNonNil,
	}}

	for _, test := range testTable {
		os.Setenv("GOPATH", test.gopath)
		err = os.Chdir(filepath.Join(test.gopath, test.wd))
		if err != nil {
			t.Fatalf("could not setup base: %s", err)
		}
		got, gotE := checkNmkAbs(test.a)
		if got != test.wantP {
			t.Errorf("got '%s', want: '%s'", got, test.wantP)
		}
		if !test.wantE(gotE) {
			t.Errorf("got error '%s'", gotE)
		}
	}
}
<|endoftext|>


<commit_before>package meow-ml-kmeans

import (
	"math"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-data-structures"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-ml"
)

type meowKmeans struct {
	dots *meow-data-structures.meowArrayList
	num_of_clusters int
	meowta float64
}

// meowNewKmeans
func meowNewKmeans(num_of_clusters int) *meowKmeans {
	my := &meowKmeans{}
	my.dots = meow-data-structures.meowNewArrayList()
	my.num_of_clusters = num_of_clusters
	my.meowta = 0.001
	return my
}

// setMeowta
func (my *meowKmeans) setMeowta(meowta float64) {
	my.meowta = meowta
}<commit_msg>add meowAddDots<commit_after>package meow-ml-kmeans

import (
	"math"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-data-structures"
	"ashumeow/ml-kmeans/meow-ml-kmeans/meow-ml"
)

type meowKmeans struct {
	dots *meow-data-structures.meowArrayList
	num_of_clusters int
	meowta float64
}

// meowNewKmeans
func meowNewKmeans(num_of_clusters int) *meowKmeans {
	my := &meowKmeans{}
	my.dots = meow-data-structures.meowNewArrayList()
	my.num_of_clusters = num_of_clusters
	my.meowta = 0.001
	return my
}

// setMeowta
func (my *meowKmeans) setMeowta(meowta float64) {
	my.meowta = meowta
}

// meowAddDots
func (my *meowKmeans) meowAddDots(dot *meow-ml.meowPoint) {
	my.dots.meowAdd(dot)
}<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/containers/image/docker"
	"github.com/containers/image/manifest"
	"github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

// inspectOutput is the output format of (skopeo inspect), primarily so that we can format it with a simple json.MarshalIndent.
type inspectOutput struct {
	Name          string `json:",omitempty"`
	Tag           string `json:",omitempty"`
	Digest        digest.Digest
	RepoTags      []string
	Created       time.Time
	DockerVersion string
	Labels        map[string]string
	Architecture  string
	Os            string
	Layers        []string
}

var inspectCmd = cli.Command{
	Name:      "inspect",
	Usage:     "Inspect image IMAGE-NAME",
	ArgsUsage: "IMAGE-NAME",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "cert-dir",
			Value: "",
			Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the registry",
		},
		cli.BoolTFlag{
			Name:  "tls-verify",
			Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
		},
		cli.BoolFlag{
			Name:  "raw",
			Usage: "output raw manifest",
		},
		cli.StringFlag{
			Name:  "creds",
			Value: "",
			Usage: "Use `USERNAME[:PASSWORD]` for accessing the registry",
		},
	},
	Action: func(c *cli.Context) (retErr error) {
		img, err := parseImage(c)
		if err != nil {
			return err
		}

		defer func() {
			if err := img.Close(); err != nil {
				retErr = errors.Wrapf(retErr, fmt.Sprintf("(could not close image: %v) ", err))
			}
		}()

		rawManifest, _, err := img.Manifest()
		if err != nil {
			return err
		}
		if c.Bool("raw") {
			_, err := c.App.Writer.Write(rawManifest)
			if err != nil {
				return fmt.Errorf("Error writing manifest to standard output: %v", err)
			}
			return nil
		}
		imgInspect, err := img.Inspect()
		if err != nil {
			return err
		}
		outputData := inspectOutput{
			Name: "", // Possibly overridden for a docker.Image.
			Tag:  imgInspect.Tag,
			// Digest is set below.
			RepoTags:      []string{}, // Possibly overriden for a docker.Image.
			Created:       imgInspect.Created,
			DockerVersion: imgInspect.DockerVersion,
			Labels:        imgInspect.Labels,
			Architecture:  imgInspect.Architecture,
			Os:            imgInspect.Os,
			Layers:        imgInspect.Layers,
		}
		outputData.Digest, err = manifest.Digest(rawManifest)
		if err != nil {
			return fmt.Errorf("Error computing manifest digest: %v", err)
		}
		if dockerImg, ok := img.(*docker.Image); ok {
			outputData.Name = dockerImg.SourceRefFullName()
			outputData.RepoTags, err = dockerImg.GetRepositoryTags()
			if err != nil {
				return fmt.Errorf("Error determining repository tags: %v", err)
			}
		}
		out, err := json.MarshalIndent(outputData, "", "    ")
		if err != nil {
			return err
		}
		fmt.Fprintln(c.App.Writer, string(out))
		return nil
	},
}
<commit_msg>Allow inspect to work even if tag list blocked<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/containers/image/docker"
	"github.com/containers/image/manifest"
	"github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

// inspectOutput is the output format of (skopeo inspect), primarily so that we can format it with a simple json.MarshalIndent.
type inspectOutput struct {
	Name          string `json:",omitempty"`
	Tag           string `json:",omitempty"`
	Digest        digest.Digest
	RepoTags      []string
	Created       time.Time
	DockerVersion string
	Labels        map[string]string
	Architecture  string
	Os            string
	Layers        []string
}

var inspectCmd = cli.Command{
	Name:      "inspect",
	Usage:     "Inspect image IMAGE-NAME",
	ArgsUsage: "IMAGE-NAME",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "cert-dir",
			Value: "",
			Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the registry",
		},
		cli.BoolTFlag{
			Name:  "tls-verify",
			Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
		},
		cli.BoolFlag{
			Name:  "raw",
			Usage: "output raw manifest",
		},
		cli.StringFlag{
			Name:  "creds",
			Value: "",
			Usage: "Use `USERNAME[:PASSWORD]` for accessing the registry",
		},
	},
	Action: func(c *cli.Context) (retErr error) {
		img, err := parseImage(c)
		if err != nil {
			return err
		}

		defer func() {
			if err := img.Close(); err != nil {
				retErr = errors.Wrapf(retErr, fmt.Sprintf("(could not close image: %v) ", err))
			}
		}()

		rawManifest, _, err := img.Manifest()
		if err != nil {
			return err
		}
		if c.Bool("raw") {
			_, err := c.App.Writer.Write(rawManifest)
			if err != nil {
				return fmt.Errorf("Error writing manifest to standard output: %v", err)
			}
			return nil
		}
		imgInspect, err := img.Inspect()
		if err != nil {
			return err
		}
		outputData := inspectOutput{
			Name: "", // Possibly overridden for a docker.Image.
			Tag:  imgInspect.Tag,
			// Digest is set below.
			RepoTags:      []string{}, // Possibly overriden for a docker.Image.
			Created:       imgInspect.Created,
			DockerVersion: imgInspect.DockerVersion,
			Labels:        imgInspect.Labels,
			Architecture:  imgInspect.Architecture,
			Os:            imgInspect.Os,
			Layers:        imgInspect.Layers,
		}
		outputData.Digest, err = manifest.Digest(rawManifest)
		if err != nil {
			return fmt.Errorf("Error computing manifest digest: %v", err)
		}
		if dockerImg, ok := img.(*docker.Image); ok {
			outputData.Name = dockerImg.SourceRefFullName()
			outputData.RepoTags, err = dockerImg.GetRepositoryTags()
			if err != nil {
				// some registries may decide to block the "list all tags" endpoint
				// gracefully allow the inspect to continue in this case. Currently
				// the IBM Bluemix container registry has this restriction.
				if !strings.Contains(err.Error(), "401") {
					return fmt.Errorf("Error determining repository tags: %v", err)
				}
				logrus.Warnf("Registry disallows tag list retrieval; skipping")
			}
		}
		out, err := json.MarshalIndent(outputData, "", "    ")
		if err != nil {
			return err
		}
		fmt.Fprintln(c.App.Writer, string(out))
		return nil
	},
}
<|endoftext|>


<commit_before>package pipe_test

import (
	"errors"
	"io"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/sync/errgroup"

	"v2ray.com/core/common"
	"v2ray.com/core/common/buf"
	. "v2ray.com/core/transport/pipe"
)

func TestPipeReadWrite(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))

	b := buf.New()
	b.WriteString("abcd")
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))

	b2 := buf.New()
	b2.WriteString("efg")
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b2}))

	rb, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if r := cmp.Diff(rb.String(), "abcdefg"); r != "" {
		t.Error(r)
	}
}

func TestPipeInterrupt(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))
	payload := []byte{'a', 'b', 'c', 'd'}
	b := buf.New()
	b.Write(payload)
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
	pWriter.Interrupt()

	rb, err := pReader.ReadMultiBuffer()
	if err != io.ErrClosedPipe {
		t.Fatal("expect io.ErrClosePipe, but got ", err)
	}
	if !rb.IsEmpty() {
		t.Fatal("expect empty buffer, but got ", rb.Len())
	}
}

func TestPipeClose(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))
	payload := []byte{'a', 'b', 'c', 'd'}
	b := buf.New()
	common.Must2(b.Write(payload))
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
	common.Must(pWriter.Close())

	rb, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if rb.String() != string(payload) {
		t.Fatal("expect content ", string(payload), " but actually ", rb.String())
	}

	rb, err = pReader.ReadMultiBuffer()
	if err != io.EOF {
		t.Fatal("expected EOF, but got ", err)
	}
	if !rb.IsEmpty() {
		t.Fatal("expect empty buffer, but got ", rb.String())
	}
}

func TestPipeLimitZero(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(0))
	bb := buf.New()
	common.Must2(bb.Write([]byte{'a', 'b'}))
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{bb}))

	var errg errgroup.Group
	errg.Go(func() error {
		b := buf.New()
		b.Write([]byte{'c', 'd'})
		return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
	})
	errg.Go(func() error {
		time.Sleep(time.Second)

		var container buf.MultiBufferContainer
		if err := buf.Copy(pReader, &container); err != nil {
			return err
		}

		if r := cmp.Diff(container.String(), "abcd"); r != "" {
			return errors.New(r)
		}
		return nil
	})
	errg.Go(func() error {
		time.Sleep(time.Second * 2)
		return pWriter.Close()
	})
	if err := errg.Wait(); err != nil {
		t.Error(err)
	}
}

func TestPipeWriteMultiThread(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(0))

	var errg errgroup.Group
	for i := 0; i < 10; i++ {
		errg.Go(func() error {
			b := buf.New()
			b.WriteString("abcd")
			return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
		})
	}
	errg.Wait()

	b, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if r := cmp.Diff(b[0].Bytes(), []byte{'a', 'b', 'c', 'd'}); r != "" {
		t.Error(r)
	}
}

func TestInterfaces(t *testing.T) {
	_ = (buf.Reader)(new(Reader))
	_ = (buf.TimeoutReader)(new(Reader))
}

func BenchmarkPipeReadWrite(b *testing.B) {
	reader, writer := New(WithoutSizeLimit())
	a := buf.New()
	a.Extend(buf.Size)
	c := buf.MultiBuffer{a}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		common.Must(writer.WriteMultiBuffer(c))
		d, err := reader.ReadMultiBuffer()
		common.Must(err)
		c = d
	}
}
<commit_msg>fix pipe test<commit_after>package pipe_test

import (
	"errors"
	"io"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/sync/errgroup"

	"v2ray.com/core/common"
	"v2ray.com/core/common/buf"
	. "v2ray.com/core/transport/pipe"
)

func TestPipeReadWrite(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))

	b := buf.New()
	b.WriteString("abcd")
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))

	b2 := buf.New()
	b2.WriteString("efg")
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b2}))

	rb, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if r := cmp.Diff(rb.String(), "abcdefg"); r != "" {
		t.Error(r)
	}
}

func TestPipeInterrupt(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))
	payload := []byte{'a', 'b', 'c', 'd'}
	b := buf.New()
	b.Write(payload)
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
	pWriter.Interrupt()

	rb, err := pReader.ReadMultiBuffer()
	if err != io.ErrClosedPipe {
		t.Fatal("expect io.ErrClosePipe, but got ", err)
	}
	if !rb.IsEmpty() {
		t.Fatal("expect empty buffer, but got ", rb.Len())
	}
}

func TestPipeClose(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(1024))
	payload := []byte{'a', 'b', 'c', 'd'}
	b := buf.New()
	common.Must2(b.Write(payload))
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
	common.Must(pWriter.Close())

	rb, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if rb.String() != string(payload) {
		t.Fatal("expect content ", string(payload), " but actually ", rb.String())
	}

	rb, err = pReader.ReadMultiBuffer()
	if err != io.EOF {
		t.Fatal("expected EOF, but got ", err)
	}
	if !rb.IsEmpty() {
		t.Fatal("expect empty buffer, but got ", rb.String())
	}
}

func TestPipeLimitZero(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(0))
	bb := buf.New()
	common.Must2(bb.Write([]byte{'a', 'b'}))
	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{bb}))

	var errg errgroup.Group
	errg.Go(func() error {
		b := buf.New()
		b.Write([]byte{'c', 'd'})
		return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
	})
	errg.Go(func() error {
		time.Sleep(time.Second)

		var container buf.MultiBufferContainer
		if err := buf.Copy(pReader, &container); err != nil {
			return err
		}

		if r := cmp.Diff(container.String(), "abcd"); r != "" {
			return errors.New(r)
		}
		return nil
	})
	errg.Go(func() error {
		time.Sleep(time.Second * 2)
		return pWriter.Close()
	})
	if err := errg.Wait(); err != nil {
		t.Error(err)
	}
}

func TestPipeWriteMultiThread(t *testing.T) {
	pReader, pWriter := New(WithSizeLimit(0))

	var errg errgroup.Group
	for i := 0; i < 10; i++ {
		errg.Go(func() error {
			b := buf.New()
			b.WriteString("abcd")
			return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
		})
	}
	time.Sleep(time.Millisecond * 100)
	pWriter.Close()
	errg.Wait()

	b, err := pReader.ReadMultiBuffer()
	common.Must(err)
	if r := cmp.Diff(b[0].Bytes(), []byte{'a', 'b', 'c', 'd'}); r != "" {
		t.Error(r)
	}
}

func TestInterfaces(t *testing.T) {
	_ = (buf.Reader)(new(Reader))
	_ = (buf.TimeoutReader)(new(Reader))
}

func BenchmarkPipeReadWrite(b *testing.B) {
	reader, writer := New(WithoutSizeLimit())
	a := buf.New()
	a.Extend(buf.Size)
	c := buf.MultiBuffer{a}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		common.Must(writer.WriteMultiBuffer(c))
		d, err := reader.ReadMultiBuffer()
		common.Must(err)
		c = d
	}
}
<|endoftext|>