<commit_before>package main

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

	"github.com/facebookgo/parse"
	"github.com/facebookgo/stackerr"
	"github.com/spf13/cobra"
)

type newCmd struct {
	addApplication bool

	noCode       bool   // do not setup/download code
	createNewApp bool   // create a new app
	parseAppName string // name of parse app
	codeLocation string // location of cloud code project
}

var newProjectFiles = []struct {
	dirname, filename, content string
}{
	{"cloud", "main.js", sampleSource},
	{"public", "index.html", sampleHTML},
}

func (n *newCmd) curlCommand(app *app) string {
	return fmt.Sprintf(
		`curl -X POST \
 -H "X-Parse-Application-Id: %s" \
 -H "X-Parse-REST-API-Key: %s" \
 -H "Content-Type: application/json" \
 -d '{}' \
 https://api.parse.com/1/functions/hello
`,
		app.ApplicationID,
		app.RestKey,
	)
}

func (n *newCmd) cloudCodeHelpMessage(e *env, app *app) string {
	return fmt.Sprintf(
		`Your Cloud Code has been created at %s.
Next, you might want to deploy this code with "parse deploy".
This includes a "Hello world" cloud function, so once you deploy
you can test that it works, with:

%s
`,
		e.Root,
		n.curlCommand(app),
	)
}

func (n *newCmd) getCloudCodeDir(e *env, appName string, isNew bool) (string, error) {
	var cloudCodeDir string
	if isNew {
		fmt.Fprintf(e.Out,
			`Awesome! Now it's time to setup some Cloud Code for the app: %q,
Next we will create a directory to hold your Cloud Code.
Please enter the name to use for this directory,
or hit ENTER to use %q as the directory name.

Directory Name: `,
			appName,
			appName,
		)
	} else {
		fmt.Fprintf(e.Out,
			`Please enter the name of the folder where we can download the latest deployed
Cloud Code for your app %q

Directory Name: `,
			appName,
		)
	}

	fmt.Scanf("%s\n", &cloudCodeDir)
	cloudCodeDir = strings.TrimSpace(cloudCodeDir)
	if cloudCodeDir == "" {
		cloudCodeDir = appName
	}

	helpMsg := "Next time, please select the same app you selected now."
	if isNew {
		helpMsg = `Next time, please select to add Cloud Code to an 'existing' app
and select the app you just created.`
	}

	configFile := filepath.Join(e.Root, cloudCodeDir, legacyConfigFile)
	if _, err := os.Lstat(configFile); err == nil {
		return "", stackerr.Newf(
			`Sorry, we are unable to create Cloud Code at %s.
It seems that you already have Cloud Code at %s.
Please run "parse new" again.
%s
Please choose a different name for your Cloud Code directory,
so it does not conflict with any other Cloud Code in the current directory.
`,
			cloudCodeDir,
			cloudCodeDir,
			helpMsg,
		)
	}

	cloudCodeDirInfo, err := os.Stat(filepath.Join(e.Root, cloudCodeDir))
	if err == nil {
		if !cloudCodeDirInfo.IsDir() {
			return "", stackerr.Newf(`Sorry, we are unable to create Cloud Code at %s.
In the current directory a file named: %s already exists.
Please run "parse new" again.
%s
Please choose a different name for your Cloud Code directory,
so it does not conflict with any other Cloud Code in the current directory.
`,
				cloudCodeDir,
				cloudCodeDir,
				helpMsg,
			)

		}
		return "", nil
	}
	if !os.IsNotExist(err) {
		return "", stackerr.Wrap(err)
	}
	return cloudCodeDir, nil
}

func (n *newCmd) createConfigWithContent(path, content string) error {
	file, err := os.OpenFile(
		path,
		os.O_RDWR|os.O_CREATE|os.O_TRUNC,
		0600,
	)
	if err != nil && !os.IsExist(err) {
		return stackerr.Wrap(err)
	}
	defer file.Close()
	if _, err := file.WriteString(content); err != nil {
		return stackerr.Wrap(err)
	}
	if err := file.Close(); err != nil {
		return stackerr.Wrap(err)
	}
	return nil
}

func (n *newCmd) promptCreateNewApp(e *env, nonInteractive bool) (string, error) {
	if nonInteractive {
		if n.createNewApp {
			return "new", nil
		}
		return "existing", nil
	}

	msg := `"new" and "existing" are the only valid options.
Please try again ...`

	var decision string
	for i := 0; i < 3; i++ {
		fmt.Fprintf(e.Out,
			`Would you like to create a new app, or add Cloud Code to an existing app?
Type "(n)ew" or "(e)xisting": `,
		)
		fmt.Fscanf(e.In, "%s\n", &decision)
		decision = strings.ToLower(decision)

		if decision == "new" || decision == "n" || decision == "existing" || decision == "e" {
			return decision, nil
		}
		fmt.Fprintln(e.Err, msg)
	}
	return "", stackerr.New(msg)
}

func (n *newCmd) setupSample(e *env, app *app, isNew bool, nonInteractive bool) (bool, error) {
	found := isProjectDir(getProjectRoot(e, e.Root))
	if !found {
		root := getLegacyProjectRoot(e, e.Root)
		_, err := os.Lstat(filepath.Join(root, legacyConfigFile))
		found = err == nil
	}
	if found {
		return false, stackerr.New(
			`Detected that you are already inside a Parse project.
Please refrain from creating a Parse project inside another Parse project.
`,
		)
	}

	var (
		cloudCodeDir string
		err          error
	)

	if nonInteractive {
		cloudCodeDir = n.codeLocation
	} else {
		cloudCodeDir, err = n.getCloudCodeDir(e, app.Name, isNew)
		if err != nil {
			return false, err
		}
	}
	e.Root = filepath.Join(e.Root, cloudCodeDir)

	switch e.Type {
	case parseFormat:
		dumpTemplate := false
		if !isNew && !n.noCode {
			// if parse app was already created try to fetch cloud code and populate dir
			e.ParseAPIClient = e.ParseAPIClient.WithCredentials(
				parse.MasterKey{
					ApplicationID: app.ApplicationID,
					MasterKey:     app.MasterKey,
				},
			)

			d := &downloadCmd{destination: e.Root}
			err = d.run(e, nil)
			if err != nil {
				if err == errNoFiles {
					dumpTemplate = true
				} else {
					fmt.Fprintln(
						e.Out,
						`
NOTE: If you like to fetch the latest deployed Cloud Code from Parse,
you can use the "parse download" command after finishing the set up.
This will download Cloud Code to a temporary location.
`,
					)
				}
			}
		}
		dumpTemplate = (isNew || dumpTemplate) && !n.noCode
		return dumpTemplate, n.cloneSampleCloudCode(e, dumpTemplate)
	}
	return false, stackerr.Newf("Unknown project type: %d", e.Type)
}

func (n *newCmd) configureSample(
	add *addCmd,
	name string,
	appConfig appConfig,
	args []string,
	e *env,
) error {
	if err := add.addSelectedApp(name, appConfig, args, e); err != nil {
		return err
	}

	masterKey, err := appConfig.getMasterKey(e)
	if err != nil {
		return err
	}
	e.ParseAPIClient = e.ParseAPIClient.WithCredentials(
		parse.MasterKey{
			ApplicationID: appConfig.getApplicationID(),
			MasterKey:     masterKey,
		},
	)

	if e.Type == parseFormat {
		return useLatestJSSDK(e)
	}
	return nil
}

func (n *newCmd) run(e *env) error {
	apps := &apps{}
	addCmd := &addCmd{MakeDefault: true, apps: apps}

	if err := apps.login.authUser(e); err != nil {
		return err
	}
	var (
		app *app
		err error
	)

	nonInteractive := n.parseAppName != "" && n.codeLocation != ""
	decision, err := n.promptCreateNewApp(e, nonInteractive)
	if err != nil {
		return err
	}
	isNew := false

	switch decision {
	case "new", "n":
		isNew = true
		app, err = apps.createApp(e, n.parseAppName)
		if err != nil {
			return err
		}
	case "existing", "e":
		app, err = addCmd.selectApp(e, n.parseAppName)
		if err != nil {
			return err
		}
	}

	e.Type = parseFormat
	appConfig := addCmd.getParseAppConfig(app)

	dumpTemplate, err := n.setupSample(e, app, isNew, nonInteractive)
	if err != nil {
		return err
	}
	if err := n.configureSample(addCmd, app.Name, appConfig, nil, e); err != nil {
		return err
	}
	if token := apps.login.credentials.token; token != "" {
		email, err := apps.login.authToken(e, token)
		if err != nil {
			return err
		}
		if err := (&configureCmd{}).parserEmail(e, []string{email}); err != nil {
			return err
		}
	}

	if dumpTemplate {
		fmt.Fprintf(e.Out, n.cloudCodeHelpMessage(e, app))
	}

	return nil
}

func newNewCmd(e *env) *cobra.Command {
	nc := newCmd{addApplication: true}
	cmd := &cobra.Command{
		Use:   "new",
		Short: "Adds Cloud Code to an existing Parse app, additional can create a new Parse app",
		Long: `Adds Cloud Code to an existing Parse app, additional can create a new Parse app.
You can also use it in non-interactive mode by using the various flags available.
`,
		Run: runNoArgs(e, nc.run),
	}
	cmd.Flags().BoolVarP(&nc.noCode, "init", "i", nc.noCode,
		"Create a Cloud Code project only with configuration, no code.")
	cmd.Flags().BoolVarP(&nc.createNewApp, "create", "c", nc.createNewApp,
		"Set this flag to true if you want to create a new Parse app.")
	cmd.Flags().StringVarP(&nc.parseAppName, "app", "a", nc.parseAppName,
		"Name of the Parse app you want to create or set up Cloud Code project for.")
	cmd.Flags().StringVarP(&nc.codeLocation, "loc", "l", nc.codeLocation,
		"Location at which the Cloud Code project will be setup.")
	return cmd
}
<commit_msg>[new] refactor new cmd setup sample<commit_after>package main

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

	"github.com/facebookgo/parse"
	"github.com/facebookgo/stackerr"
	"github.com/spf13/cobra"
)

type newCmd struct {
	addApplication bool

	noCode       bool   // do not setup/download code
	createNewApp bool   // create a new app
	parseAppName string // name of parse app
	codeLocation string // location of cloud code project
}

var newProjectFiles = []struct {
	dirname, filename, content string
}{
	{"cloud", "main.js", sampleSource},
	{"public", "index.html", sampleHTML},
}

func (n *newCmd) curlCommand(app *app) string {
	return fmt.Sprintf(
		`curl -X POST \
 -H "X-Parse-Application-Id: %s" \
 -H "X-Parse-REST-API-Key: %s" \
 -H "Content-Type: application/json" \
 -d '{}' \
 https://api.parse.com/1/functions/hello
`,
		app.ApplicationID,
		app.RestKey,
	)
}

func (n *newCmd) cloudCodeHelpMessage(e *env, app *app) string {
	return fmt.Sprintf(
		`Your Cloud Code has been created at %s.
Next, you might want to deploy this code with "parse deploy".
This includes a "Hello world" cloud function, so once you deploy
you can test that it works, with:

%s
`,
		e.Root,
		n.curlCommand(app),
	)
}

func (n *newCmd) getCloudCodeDir(e *env, appName string, isNew bool) (string, error) {
	var cloudCodeDir string
	if isNew {
		fmt.Fprintf(e.Out,
			`Awesome! Now it's time to setup some Cloud Code for the app: %q,
Next we will create a directory to hold your Cloud Code.
Please enter the name to use for this directory,
or hit ENTER to use %q as the directory name.

Directory Name: `,
			appName,
			appName,
		)
	} else {
		fmt.Fprintf(e.Out,
			`Please enter the name of the folder where we can download the latest deployed
Cloud Code for your app %q

Directory Name: `,
			appName,
		)
	}

	fmt.Scanf("%s\n", &cloudCodeDir)
	cloudCodeDir = strings.TrimSpace(cloudCodeDir)
	if cloudCodeDir == "" {
		cloudCodeDir = appName
	}

	helpMsg := "Next time, please select the same app you selected now."
	if isNew {
		helpMsg = `Next time, please select to add Cloud Code to an 'existing' app
and select the app you just created.`
	}

	configFile := filepath.Join(e.Root, cloudCodeDir, legacyConfigFile)
	if _, err := os.Lstat(configFile); err == nil {
		return "", stackerr.Newf(
			`Sorry, we are unable to create Cloud Code at %s.
It seems that you already have Cloud Code at %s.
Please run "parse new" again.
%s
Please choose a different name for your Cloud Code directory,
so it does not conflict with any other Cloud Code in the current directory.
`,
			cloudCodeDir,
			cloudCodeDir,
			helpMsg,
		)
	}

	cloudCodeDirInfo, err := os.Stat(filepath.Join(e.Root, cloudCodeDir))
	if err == nil {
		if !cloudCodeDirInfo.IsDir() {
			return "", stackerr.Newf(`Sorry, we are unable to create Cloud Code at %s.
In the current directory a file named: %s already exists.
Please run "parse new" again.
%s
Please choose a different name for your Cloud Code directory,
so it does not conflict with any other Cloud Code in the current directory.
`,
				cloudCodeDir,
				cloudCodeDir,
				helpMsg,
			)

		}
		return "", nil
	}
	if !os.IsNotExist(err) {
		return "", stackerr.Wrap(err)
	}
	return cloudCodeDir, nil
}

func (n *newCmd) createConfigWithContent(path, content string) error {
	file, err := os.OpenFile(
		path,
		os.O_RDWR|os.O_CREATE|os.O_TRUNC,
		0600,
	)
	if err != nil && !os.IsExist(err) {
		return stackerr.Wrap(err)
	}
	defer file.Close()
	if _, err := file.WriteString(content); err != nil {
		return stackerr.Wrap(err)
	}
	if err := file.Close(); err != nil {
		return stackerr.Wrap(err)
	}
	return nil
}

func (n *newCmd) promptCreateNewApp(e *env, nonInteractive bool) (string, error) {
	if nonInteractive {
		if n.createNewApp {
			return "new", nil
		}
		return "existing", nil
	}

	msg := `"new" and "existing" are the only valid options.
Please try again ...`

	var decision string
	for i := 0; i < 3; i++ {
		fmt.Fprintf(e.Out,
			`Would you like to create a new app, or add Cloud Code to an existing app?
Type "(n)ew" or "(e)xisting": `,
		)
		fmt.Fscanf(e.In, "%s\n", &decision)
		decision = strings.ToLower(decision)

		if decision == "new" || decision == "n" || decision == "existing" || decision == "e" {
			return decision, nil
		}
		fmt.Fprintln(e.Err, msg)
	}
	return "", stackerr.New(msg)
}

func (n *newCmd) setupSample(
	e *env,
	name string,
	appConfig appConfig,
	isNew bool,
	nonInteractive bool,
) (bool, error) {
	found := isProjectDir(getProjectRoot(e, e.Root))
	if !found {
		root := getLegacyProjectRoot(e, e.Root)
		_, err := os.Lstat(filepath.Join(root, legacyConfigFile))
		found = err == nil
	}
	if found {
		return false, stackerr.New(
			`Detected that you are already inside a Parse project.
Please refrain from creating a Parse project inside another Parse project.
`,
		)
	}

	var (
		cloudCodeDir string
		err          error
	)

	if nonInteractive {
		cloudCodeDir = n.codeLocation
	} else {
		cloudCodeDir, err = n.getCloudCodeDir(e, name, isNew)
		if err != nil {
			return false, err
		}
	}
	e.Root = filepath.Join(e.Root, cloudCodeDir)

	switch e.Type {
	case parseFormat:
		dumpTemplate := false
		if !isNew && !n.noCode {
			// if parse app was already created try to fetch cloud code and populate dir
			masterKey, err := appConfig.getMasterKey(e)
			if err != nil {
				return false, err
			}
			e.ParseAPIClient = e.ParseAPIClient.WithCredentials(
				parse.MasterKey{
					ApplicationID: appConfig.getApplicationID(),
					MasterKey:     masterKey,
				},
			)

			d := &downloadCmd{destination: e.Root}
			err = d.run(e, nil)
			if err != nil {
				if err == errNoFiles {
					dumpTemplate = true
				} else {
					fmt.Fprintln(
						e.Out,
						`
NOTE: If you like to fetch the latest deployed Cloud Code from Parse,
you can use the "parse download" command after finishing the set up.
This will download Cloud Code to a temporary location.
`,
					)
				}
			}
		}
		dumpTemplate = (isNew || dumpTemplate) && !n.noCode
		return dumpTemplate, n.cloneSampleCloudCode(e, dumpTemplate)
	}
	return false, stackerr.Newf("Unknown project type: %d", e.Type)
}

func (n *newCmd) configureSample(
	add *addCmd,
	name string,
	appConfig appConfig,
	args []string,
	e *env,
) error {
	if err := add.addSelectedApp(name, appConfig, args, e); err != nil {
		return err
	}

	masterKey, err := appConfig.getMasterKey(e)
	if err != nil {
		return err
	}
	e.ParseAPIClient = e.ParseAPIClient.WithCredentials(
		parse.MasterKey{
			ApplicationID: appConfig.getApplicationID(),
			MasterKey:     masterKey,
		},
	)

	if e.Type == parseFormat {
		return useLatestJSSDK(e)
	}
	return nil
}

func (n *newCmd) run(e *env) error {
	apps := &apps{}
	addCmd := &addCmd{MakeDefault: true, apps: apps}

	if err := apps.login.authUser(e); err != nil {
		return err
	}
	var (
		app *app
		err error
	)

	nonInteractive := n.parseAppName != "" && n.codeLocation != ""
	decision, err := n.promptCreateNewApp(e, nonInteractive)
	if err != nil {
		return err
	}
	isNew := false

	switch decision {
	case "new", "n":
		isNew = true
		app, err = apps.createApp(e, n.parseAppName)
		if err != nil {
			return err
		}
	case "existing", "e":
		app, err = addCmd.selectApp(e, n.parseAppName)
		if err != nil {
			return err
		}
	}

	e.Type = parseFormat
	appConfig := addCmd.getParseAppConfig(app)

	dumpTemplate, err := n.setupSample(e, app.Name, appConfig, isNew, nonInteractive)
	if err != nil {
		return err
	}
	if err := n.configureSample(addCmd, app.Name, appConfig, nil, e); err != nil {
		return err
	}
	if token := apps.login.credentials.token; token != "" {
		email, err := apps.login.authToken(e, token)
		if err != nil {
			return err
		}
		if err := (&configureCmd{}).parserEmail(e, []string{email}); err != nil {
			return err
		}
	}

	if dumpTemplate {
		fmt.Fprintf(e.Out, n.cloudCodeHelpMessage(e, app))
	}

	return nil
}

func newNewCmd(e *env) *cobra.Command {
	nc := newCmd{addApplication: true}
	cmd := &cobra.Command{
		Use:   "new",
		Short: "Adds Cloud Code to an existing Parse app, additional can create a new Parse app",
		Long: `Adds Cloud Code to an existing Parse app, additional can create a new Parse app.
You can also use it in non-interactive mode by using the various flags available.
`,
		Run: runNoArgs(e, nc.run),
	}
	cmd.Flags().BoolVarP(&nc.noCode, "init", "i", nc.noCode,
		"Create a Cloud Code project only with configuration, no code.")
	cmd.Flags().BoolVarP(&nc.createNewApp, "create", "c", nc.createNewApp,
		"Set this flag to true if you want to create a new Parse app.")
	cmd.Flags().StringVarP(&nc.parseAppName, "app", "a", nc.parseAppName,
		"Name of the Parse app you want to create or set up Cloud Code project for.")
	cmd.Flags().StringVarP(&nc.codeLocation, "loc", "l", nc.codeLocation,
		"Location at which the Cloud Code project will be setup.")
	return cmd
}
<|endoftext|>


<commit_before>// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package build

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/google/syzkaller/pkg/mgrconfig"
	"github.com/google/syzkaller/pkg/osutil"
	"github.com/google/syzkaller/pkg/report"
	"github.com/google/syzkaller/vm"
)

type netbsd struct{}

func (ctx netbsd) build(params *Params) error {
	const kernelName = "GENERIC_SYZKALLER"
	confDir := fmt.Sprintf("%v/sys/arch/%v/conf", params.KernelDir, params.TargetArch)
	compileDir := fmt.Sprintf("%v/sys/arch/%v/compile/obj/%v", params.KernelDir, params.TargetArch, kernelName)

	if err := osutil.WriteFile(filepath.Join(confDir, kernelName), params.Config); err != nil {
		return err
	}

	// Clear the tools
	if _, err := osutil.RunCmd(5*time.Minute, params.KernelDir, "rm", "-rf", "obj/"); err != nil {
		return err
	}

	// Clear the build files
	if _, err := osutil.RunCmd(5*time.Minute, params.KernelDir, "rm", "-rf", compileDir); err != nil {
		return err
	}

	if strings.HasSuffix(params.Compiler, "clang++") {
		// Build tools before building kernel
		if _, err := osutil.RunCmd(60*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no",
			"-V", "MKLLVM=yes", "-V", "MKGCC=no", "-V", "HAVE_LLVM=yes", "tools"); err != nil {
			return err
		}

		// Build kernel
		if _, err := osutil.RunCmd(20*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no",
			"-V", "MKLLVM=yes", "-V", "MKGCC=no", "-V", "HAVE_LLVM=yes", "kernel="+kernelName); err != nil {
			return err
		}
	} else if strings.HasSuffix(params.Compiler, "g++") {
		if _, err := osutil.RunCmd(30*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no", "tools"); err != nil {
			return err
		}

		if _, err := osutil.RunCmd(20*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no", "kernel="+kernelName); err != nil {
			return err
		}
	}

	for _, s := range []struct{ dir, src, dst string }{
		{compileDir, "netbsd.gdb", "obj/netbsd.gdb"},
		{params.UserspaceDir, "image", "image"},
		{params.UserspaceDir, "key", "key"},
	} {
		fullSrc := filepath.Join(s.dir, s.src)
		fullDst := filepath.Join(params.OutputDir, s.dst)
		if err := osutil.CopyFile(fullSrc, fullDst); err != nil {
			return fmt.Errorf("failed to copy %v -> %v: %v", fullSrc, fullDst, err)
		}
	}
	return ctx.copyKernelToDisk(params.TargetArch, params.VMType, params.OutputDir,
		filepath.Join(compileDir, "netbsd"))
}

func (ctx netbsd) clean(kernelDir, targetArch string) error {
	_, err := osutil.RunCmd(10*time.Minute, kernelDir, "./build.sh", "-m", targetArch,
		"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "cleandir")
	return err
}

// Copy the compiled kernel to the qemu disk image using ssh.
func (ctx netbsd) copyKernelToDisk(targetArch, vmType, outputDir, kernel string) error {
	vmConfig := `
{
	"snapshot": false,
	"mem": 1024
}`
	// Create config for booting the disk image.
	cfg := &mgrconfig.Config{
		Workdir:      outputDir,
		Image:        filepath.Join(outputDir, "image"),
		SSHKey:       filepath.Join(outputDir, "key"),
		SSHUser:      "root",
		TargetOS:     "netbsd",
		TargetArch:   targetArch,
		TargetVMArch: targetArch,
		Type:         "qemu",
		VM:           json.RawMessage([]byte(vmConfig)),
	}
	// Create a VM pool.
	pool, err := vm.Create(cfg, false)
	if err != nil {
		return fmt.Errorf("failed to create a VM Pool: %v", err)
	}
	// Create a new reporter instance.
	reporter, err := report.NewReporter(cfg)
	if err != nil {
		return fmt.Errorf("failed to create a Reporter: %v", err)
	}
	// Create a VM instance (we need only one).
	inst, err := pool.Create(0)
	if err != nil {
		return fmt.Errorf("failed to create the VM Instance: %v", err)
	}
	defer inst.Close()
	// Copy the kernel into the disk image and replace it
	kernel, err = inst.Copy(kernel)
	if err != nil {
		return fmt.Errorf("error copying the kernel: %v", err)
	}
	if kernel != "/netbsd" {
		return fmt.Errorf("kernel is copied into wrong location: %v", kernel)
	}
	commands := []string{"touch /fastboot"} // /fastboot file prevents disk check on start.
	if vmType == "gce" {
		commands = append(commands, []string{
			// We expect boot disk to be wd0a for the qemu (that's how qemu exposes -hda disk).
			// GCE exposes boot disk as sd0a.
			`sed -i 's#wd0#sd0#g' /etc/fstab`,
			// GCE provides vioif0 interface.
			`echo '!dhcpcd vioif0' > /etc/ifconfig.vioif0`,
			`echo 'mtu 1460' >> /etc/ifconfig.vioif0`,
		}...)
	}
	commands = append(commands, "sync") // Run sync so that the copied image is stored properly.
	outc, errc, err := inst.Run(time.Minute, nil, strings.Join(commands, ";"))
	if err != nil {
		return fmt.Errorf("error syncing the instance %v", err)
	}
	// Make sure that the command has executed properly.
	rep := inst.MonitorExecution(outc, errc, reporter, vm.ExitNormal)
	if rep != nil {
		return fmt.Errorf("error executing sync: %v", rep.Title)
	}
	return nil
}
<commit_msg>pkg/build: create /dev/vhci on NetBSD<commit_after>// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package build

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/google/syzkaller/pkg/mgrconfig"
	"github.com/google/syzkaller/pkg/osutil"
	"github.com/google/syzkaller/pkg/report"
	"github.com/google/syzkaller/vm"
)

type netbsd struct{}

func (ctx netbsd) build(params *Params) error {
	const kernelName = "GENERIC_SYZKALLER"
	confDir := fmt.Sprintf("%v/sys/arch/%v/conf", params.KernelDir, params.TargetArch)
	compileDir := fmt.Sprintf("%v/sys/arch/%v/compile/obj/%v", params.KernelDir, params.TargetArch, kernelName)

	if err := osutil.WriteFile(filepath.Join(confDir, kernelName), params.Config); err != nil {
		return err
	}

	// Clear the tools
	if _, err := osutil.RunCmd(5*time.Minute, params.KernelDir, "rm", "-rf", "obj/"); err != nil {
		return err
	}

	// Clear the build files
	if _, err := osutil.RunCmd(5*time.Minute, params.KernelDir, "rm", "-rf", compileDir); err != nil {
		return err
	}

	if strings.HasSuffix(params.Compiler, "clang++") {
		// Build tools before building kernel
		if _, err := osutil.RunCmd(60*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no",
			"-V", "MKLLVM=yes", "-V", "MKGCC=no", "-V", "HAVE_LLVM=yes", "tools"); err != nil {
			return err
		}

		// Build kernel
		if _, err := osutil.RunCmd(20*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no",
			"-V", "MKLLVM=yes", "-V", "MKGCC=no", "-V", "HAVE_LLVM=yes", "kernel="+kernelName); err != nil {
			return err
		}
	} else if strings.HasSuffix(params.Compiler, "g++") {
		if _, err := osutil.RunCmd(30*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no", "tools"); err != nil {
			return err
		}

		if _, err := osutil.RunCmd(20*time.Minute, params.KernelDir, "./build.sh", "-m", params.TargetArch,
			"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "-V", "MKCTF=no", "kernel="+kernelName); err != nil {
			return err
		}
	}

	for _, s := range []struct{ dir, src, dst string }{
		{compileDir, "netbsd.gdb", "obj/netbsd.gdb"},
		{params.UserspaceDir, "image", "image"},
		{params.UserspaceDir, "key", "key"},
	} {
		fullSrc := filepath.Join(s.dir, s.src)
		fullDst := filepath.Join(params.OutputDir, s.dst)
		if err := osutil.CopyFile(fullSrc, fullDst); err != nil {
			return fmt.Errorf("failed to copy %v -> %v: %v", fullSrc, fullDst, err)
		}
	}
	return ctx.copyKernelToDisk(params.TargetArch, params.VMType, params.OutputDir,
		filepath.Join(compileDir, "netbsd"))
}

func (ctx netbsd) clean(kernelDir, targetArch string) error {
	_, err := osutil.RunCmd(10*time.Minute, kernelDir, "./build.sh", "-m", targetArch,
		"-U", "-j"+strconv.Itoa(runtime.NumCPU()), "cleandir")
	return err
}

// Copy the compiled kernel to the qemu disk image using ssh.
func (ctx netbsd) copyKernelToDisk(targetArch, vmType, outputDir, kernel string) error {
	vmConfig := `
{
	"snapshot": false,
	"mem": 1024
}`
	// Create config for booting the disk image.
	cfg := &mgrconfig.Config{
		Workdir:      outputDir,
		Image:        filepath.Join(outputDir, "image"),
		SSHKey:       filepath.Join(outputDir, "key"),
		SSHUser:      "root",
		TargetOS:     "netbsd",
		TargetArch:   targetArch,
		TargetVMArch: targetArch,
		Type:         "qemu",
		VM:           json.RawMessage([]byte(vmConfig)),
	}
	// Create a VM pool.
	pool, err := vm.Create(cfg, false)
	if err != nil {
		return fmt.Errorf("failed to create a VM Pool: %v", err)
	}
	// Create a new reporter instance.
	reporter, err := report.NewReporter(cfg)
	if err != nil {
		return fmt.Errorf("failed to create a Reporter: %v", err)
	}
	// Create a VM instance (we need only one).
	inst, err := pool.Create(0)
	if err != nil {
		return fmt.Errorf("failed to create the VM Instance: %v", err)
	}
	defer inst.Close()
	// Copy the kernel into the disk image and replace it
	kernel, err = inst.Copy(kernel)
	if err != nil {
		return fmt.Errorf("error copying the kernel: %v", err)
	}
	if kernel != "/netbsd" {
		return fmt.Errorf("kernel is copied into wrong location: %v", kernel)
	}
	commands := []string{"touch /fastboot"} // /fastboot file prevents disk check on start.
	if vmType == "gce" {
		commands = append(commands, []string{
			// We expect boot disk to be wd0a for the qemu (that's how qemu exposes -hda disk).
			// GCE exposes boot disk as sd0a.
			`sed -i 's#wd0#sd0#g' /etc/fstab`,
			// GCE provides vioif0 interface.
			`echo '!dhcpcd vioif0' > /etc/ifconfig.vioif0`,
			`echo 'mtu 1460' >> /etc/ifconfig.vioif0`,
		}...)
	}
	commands = append(commands, "cd /dev && ./MAKEDEV vhci")
	commands = append(commands, "sync") // Run sync so that the copied image is stored properly.
	outc, errc, err := inst.Run(time.Minute, nil, strings.Join(commands, ";"))
	if err != nil {
		return fmt.Errorf("error syncing the instance %v", err)
	}
	// Make sure that the command has executed properly.
	rep := inst.MonitorExecution(outc, errc, reporter, vm.ExitNormal)
	if rep != nil {
		return fmt.Errorf("error executing sync: %v", rep.Title)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"os"
)

type TempFactory struct {
	path string
	files []string
}

// Create a new temporary file factory.
// defer Cleanup() if you want the files removed.
func NewTempFactory(path string) TempFactory {
	if (path == "") {
		path = DefaultTempPath()
	}
	return TempFactory{path: path}
}

// Default temporary file path
func DefaultTempPath() string {
	return ""
}

// Create a temp file with given value. Returns the path.
func (tf *TempFactory) Push(value string) (string, error) {
	f, err := ioutil.TempFile(tf.path, "cauldron")
	if err != nil {
		return "", err
	}
	defer f.Close()

	f.Write([]byte(value))
	name := f.Name()
	tf.files = append(tf.files, name)
	return name, nil
}

// Remove the temporary files created with this factory.
func (tf *TempFactory) Cleanup() {
	for _, file := range tf.files {
		os.Remove(file)
	}
	tf = nil
}
<commit_msg>Write tempfiles to the SHM if possible<commit_after>package main

import (
	"io/ioutil"
	"os"
)

type TempFactory struct {
	path string
	files []string
}

// Create a new temporary file factory.
// defer Cleanup() if you want the files removed.
func NewTempFactory(path string) TempFactory {
	if (path == "") {
		path = DefaultTempPath()
	}
	return TempFactory{path: path}
}

// Default temporary file path; returns /dev/shm if it is a directory
// else returns the system default
func DefaultTempPath() string {
	fi, err := os.Stat("/dev/shm")
	if err == nil && fi.Mode().IsDir() {
		return "/dev/shm"
	}
	return os.TempDir()
}

// Create a temp file with given value. Returns the path.
func (tf *TempFactory) Push(value string) (string, error) {
	f, err := ioutil.TempFile(tf.path, "cauldron")
	if err != nil {
		return "", err
	}
	defer f.Close()

	f.Write([]byte(value))
	name := f.Name()
	tf.files = append(tf.files, name)
	return name, nil
}

// Remove the temporary files created with this factory.
func (tf *TempFactory) Cleanup() {
	for _, file := range tf.files {
		os.Remove(file)
	}
	tf = nil
}
<|endoftext|>


<commit_before>package peppy

import (
	"strconv"
	"strings"

	"git.zxq.co/ripple/rippleapi/common"
	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
	"github.com/thehowl/go-osuapi"
)

// GetBeatmap retrieves general beatmap information.
func GetBeatmap(c *gin.Context, db *sqlx.DB) {
	var whereClauses []string
	var params []interface{}
	limit := strconv.Itoa(common.InString(1, c.Query("limit"), 500, 500))

	// since value is not stored, silently ignore
	if c.Query("s") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmapset_id = ?")
		params = append(params, c.Query("s"))
	}
	if c.Query("b") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmap_id = ?")
		params = append(params, c.Query("b"))
		// b is unique, so change limit to 1
		limit = "1"
	}
	// creator is not stored, silently ignore u and type
	if c.Query("m") != "" {
		m := genmode(c.Query("m"))
		if m == "std" {
			// Since STD beatmaps are converted, all of the diffs must be != 0
			for _, i := range modes {
				whereClauses = append(whereClauses, "beatmaps.difficulty_"+i+" != 0")
			}
		} else {
			whereClauses = append(whereClauses, "beatmaps.difficulty_"+m+" != 0")
			if c.Query("a") == "1" {
				whereClauses = append(whereClauses, "beatmaps.difficulty_std = 0")
			}
		}
	}
	if c.Query("h") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmap_md5 = ?")
		params = append(params, c.Query("h"))
	}

	where := strings.Join(whereClauses, " AND ")
	if where != "" {
		where = "WHERE " + where
	}

	rows, err := db.Query(`SELECT
	beatmapset_id, beatmap_id, ranked, hit_length,
	song_name, beatmap_md5, ar, od, bpm, playcount,
	passcount, max_combo, difficulty_std, difficulty_taiko, difficulty_ctb, difficulty_mania,
	latest_update

FROM beatmaps `+where+" ORDER BY id DESC LIMIT "+limit,
		params...)
	if err != nil {
		c.Error(err)
		c.JSON(200, defaultResponse)
		return
	}

	var bms []osuapi.Beatmap
	for rows.Next() {
		var (
			bm              osuapi.Beatmap
			rawRankedStatus int
			rawName         string
			rawLastUpdate   common.UnixTimestamp
			diffs           [4]float64
		)
		err := rows.Scan(
			&bm.BeatmapSetID, &bm.BeatmapID, &rawRankedStatus, &bm.HitLength,
			&rawName, &bm.FileMD5, &bm.ApproachRate, &bm.OverallDifficulty, &bm.BPM, &bm.Playcount,
			&bm.Passcount, &bm.MaxCombo, &diffs[0], &diffs[1], &diffs[2], &diffs[3],
			&rawLastUpdate,
		)
		if err != nil {
			c.Error(err)
			continue
		}
		bm.TotalLength = bm.HitLength
		bm.LastUpdate = osuapi.MySQLDate(rawLastUpdate)
		if rawRankedStatus >= 2 {
			bm.ApprovedDate = osuapi.MySQLDate(rawLastUpdate)
		}
		// zero value of ApprovedStatus == osuapi.StatusPending, so /shrug
		bm.Approved = rippleToOsuRankedStatus[rawRankedStatus]
		bm.Artist, bm.Title, bm.DiffName = parseDiffName(rawName)
		for i, diffVal := range diffs {
			if diffVal != 0 {
				bm.Mode = osuapi.Mode(i)
				bm.DifficultyRating = diffVal
				break
			}
		}
		bms = append(bms, bm)
	}

	c.JSON(200, bms)
}

var rippleToOsuRankedStatus = map[int]osuapi.ApprovedStatus{
	0: osuapi.StatusPending,
	1: osuapi.StatusWIP, // it means "needs updating", as the one in the db needs to be updated, but whatever
	2: osuapi.StatusRanked,
	3: osuapi.StatusApproved,
	4: osuapi.StatusQualified,
}

// buggy diffname parser
func parseDiffName(name string) (author string, title string, diffName string) {
	parts := strings.SplitN(name, " - ", 2)
	author = parts[0]
	if len(parts) > 1 {
		title = parts[1]
		if s := strings.Index(title, " ["); s != -1 {
			diffName = title[s+2:]
			if len(diffName) != 0 && diffName[len(diffName)-1] == ']' {
				diffName = diffName[:len(diffName)-1]
			}
			title = title[:s]
		}
	}
	return
}
<commit_msg>StatusLoved<commit_after>package peppy

import (
	"strconv"
	"strings"

	"git.zxq.co/ripple/rippleapi/common"
	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
	"github.com/thehowl/go-osuapi"
)

// GetBeatmap retrieves general beatmap information.
func GetBeatmap(c *gin.Context, db *sqlx.DB) {
	var whereClauses []string
	var params []interface{}
	limit := strconv.Itoa(common.InString(1, c.Query("limit"), 500, 500))

	// since value is not stored, silently ignore
	if c.Query("s") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmapset_id = ?")
		params = append(params, c.Query("s"))
	}
	if c.Query("b") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmap_id = ?")
		params = append(params, c.Query("b"))
		// b is unique, so change limit to 1
		limit = "1"
	}
	// creator is not stored, silently ignore u and type
	if c.Query("m") != "" {
		m := genmode(c.Query("m"))
		if m == "std" {
			// Since STD beatmaps are converted, all of the diffs must be != 0
			for _, i := range modes {
				whereClauses = append(whereClauses, "beatmaps.difficulty_"+i+" != 0")
			}
		} else {
			whereClauses = append(whereClauses, "beatmaps.difficulty_"+m+" != 0")
			if c.Query("a") == "1" {
				whereClauses = append(whereClauses, "beatmaps.difficulty_std = 0")
			}
		}
	}
	if c.Query("h") != "" {
		whereClauses = append(whereClauses, "beatmaps.beatmap_md5 = ?")
		params = append(params, c.Query("h"))
	}

	where := strings.Join(whereClauses, " AND ")
	if where != "" {
		where = "WHERE " + where
	}

	rows, err := db.Query(`SELECT
	beatmapset_id, beatmap_id, ranked, hit_length,
	song_name, beatmap_md5, ar, od, bpm, playcount,
	passcount, max_combo, difficulty_std, difficulty_taiko, difficulty_ctb, difficulty_mania,
	latest_update

FROM beatmaps `+where+" ORDER BY id DESC LIMIT "+limit,
		params...)
	if err != nil {
		c.Error(err)
		c.JSON(200, defaultResponse)
		return
	}

	var bms []osuapi.Beatmap
	for rows.Next() {
		var (
			bm              osuapi.Beatmap
			rawRankedStatus int
			rawName         string
			rawLastUpdate   common.UnixTimestamp
			diffs           [4]float64
		)
		err := rows.Scan(
			&bm.BeatmapSetID, &bm.BeatmapID, &rawRankedStatus, &bm.HitLength,
			&rawName, &bm.FileMD5, &bm.ApproachRate, &bm.OverallDifficulty, &bm.BPM, &bm.Playcount,
			&bm.Passcount, &bm.MaxCombo, &diffs[0], &diffs[1], &diffs[2], &diffs[3],
			&rawLastUpdate,
		)
		if err != nil {
			c.Error(err)
			continue
		}
		bm.TotalLength = bm.HitLength
		bm.LastUpdate = osuapi.MySQLDate(rawLastUpdate)
		if rawRankedStatus >= 2 {
			bm.ApprovedDate = osuapi.MySQLDate(rawLastUpdate)
		}
		// zero value of ApprovedStatus == osuapi.StatusPending, so /shrug
		bm.Approved = rippleToOsuRankedStatus[rawRankedStatus]
		bm.Artist, bm.Title, bm.DiffName = parseDiffName(rawName)
		for i, diffVal := range diffs {
			if diffVal != 0 {
				bm.Mode = osuapi.Mode(i)
				bm.DifficultyRating = diffVal
				break
			}
		}
		bms = append(bms, bm)
	}

	c.JSON(200, bms)
}

var rippleToOsuRankedStatus = map[int]osuapi.ApprovedStatus{
	0: osuapi.StatusPending,
	1: osuapi.StatusWIP, // it means "needs updating", as the one in the db needs to be updated, but whatever
	2: osuapi.StatusRanked,
	3: osuapi.StatusApproved,
	4: osuapi.StatusQualified,
	5: osuapi.StatusLoved,
}

// buggy diffname parser
func parseDiffName(name string) (author string, title string, diffName string) {
	parts := strings.SplitN(name, " - ", 2)
	author = parts[0]
	if len(parts) > 1 {
		title = parts[1]
		if s := strings.Index(title, " ["); s != -1 {
			diffName = title[s+2:]
			if len(diffName) != 0 && diffName[len(diffName)-1] == ']' {
				diffName = diffName[:len(diffName)-1]
			}
			title = title[:s]
		}
	}
	return
}
<|endoftext|>


<commit_before>package dsdk

import (
	"context"
	"fmt"
	_path "path"

	greq "github.com/levigross/grequests"
)

type IOMetric string
type HWMetric string

const (
	Reads        IOMetric = "reads"
	Writes       IOMetric = "writes"
	BytesRead    IOMetric = "bytes_read"
	BytesWritten IOMetric = "bytes_written"
	IOPSRead     IOMetric = "iops_read"
	IOPSWrite    IOMetric = "iops_write"
	ThptRead     IOMetric = "thpt_read"
	ThptWrite    IOMetric = "thpt_write"
	LatAvgRead   IOMetric = "lat_avg_read"
	LatAvgWrite  IOMetric = "lat_avg_write"
	Lat50Read    IOMetric = "lat_50_read"
	Lat90Read    IOMetric = "lat_90_read"
	Lat100Read   IOMetric = "lat_100_read"
	Lat50Write   IOMetric = "lat_50_write"
	Lat90Write   IOMetric = "lat_90_write"
	Lat100Write  IOMetric = "lat_100_write"
)

func (io IOMetric) Validate() error {
	switch io {
	case Reads, Writes, BytesRead, BytesWritten, IOPSRead, IOPSWrite, ThptRead, ThptWrite, LatAvgRead,
		LatAvgWrite, Lat50Read, Lat50Write, Lat90Read, Lat90Write, Lat100Read, Lat100Write:
		return nil
	default:
		return fmt.Errorf("%s is not a valid IO metric", io)
	}
}

const (
	CPUUsage HWMetric = "cpu_usage"
)

func (hw HWMetric) Validate() error {
	switch hw {
	case CPUUsage:
		return nil
	default:
		return fmt.Errorf("%s is not a valid HW metric", hw)
	}
}

type MetricsParams struct {
	ListRangeParams
	Ival string
	UUID string
	Path string
}

func (mp MetricsParams) ToMap() map[string]string {
	r := mp.ListRangeParams.ToMap()
	if mp.Ival != "" {
		r["ival"] = mp.Ival
	}
	if mp.UUID != "" {
		r["uuid"] = mp.UUID
	}
	if mp.Path != "" {
		r["path"] = mp.Path
	}

	return r
}

type Metrics struct {
	EntityPath string  `json:"entity_path" mapstructure:"entity_path"`
	Tenant     string  `json:"tenant" mapstructure:"tenant"`
	Points     []Point `json:"points" mapstructure:"points"`
}

type Point struct {
	Time  int64   `json:"time" mapstructure:"time"`
	Value float64 `json:"value" mapstructure:"value"`
}

type IOMetricsRequest struct {
	Ctxt   context.Context `json:"-"`
	Type   IOMetric        `json:"-"`
	Params MetricsParams   `json:"params,omitempty"`
}

type HWMetricsRequest struct {
	Ctxt   context.Context `json:"-"`
	Type   IOMetric        `json:"-"`
	Params MetricsParams   `json:"params,omitempty"`
}

type IOMetrics struct {
	Path string
}

type HWMetrics struct {
	Path string
}

func newIOMetrics(path string) *IOMetrics {
	return &IOMetrics{
		Path: _path.Join(path, "metrics", "io"),
	}
}

func newHWMetrics(path string) *HWMetrics {
	return &HWMetrics{
		Path: _path.Join(path, "metrics", "hw"),
	}
}

func (m *IOMetrics) Get(ro *IOMetricsRequest) ([]*Metrics, *ApiErrorResponse, error) {
	if err := ro.Type.Validate(); err != nil {
		return nil, nil, err
	}

	gro := &greq.RequestOptions{
		JSON:   ro,
		Params: ro.Params.ToMap(),
	}

	rs, apierr, err := GetConn(ro.Ctxt).GetList(ro.Ctxt, _path.Join(m.Path, string(ro.Type)), gro)
	if apierr != nil {
		return nil, apierr, err
	}

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

	resp := []*Metrics{}
	for _, data := range rs.Data {
		elem := &Metrics{}
		edata := data.(map[string]interface{})
		if err = FillStruct(edata, elem); err != nil {
			return nil, nil, err
		}
		resp = append(resp, elem)
	}

	return resp, nil, nil
}

func (m *HWMetrics) Get(ro *HWMetricsRequest) ([]*Metrics, *ApiErrorResponse, error) {
	if err := ro.Type.Validate(); err != nil {
		return nil, nil, err
	}

	gro := &greq.RequestOptions{
		JSON:   ro,
		Params: ro.Params.ToMap(),
	}

	rs, apierr, err := GetConn(ro.Ctxt).GetList(ro.Ctxt, _path.Join(m.Path, string(ro.Type)), gro)
	if apierr != nil {
		return nil, apierr, err
	}

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

	resp := []*Metrics{}
	for _, data := range rs.Data {
		elem := &Metrics{}
		edata := data.(map[string]interface{})
		if err = FillStruct(edata, elem); err != nil {
			return nil, nil, err
		}
		resp = append(resp, elem)
	}

	return resp, nil, nil
}
<commit_msg>Update metrics function names for consistency<commit_after>package dsdk

import (
	"context"
	"fmt"
	_path "path"

	greq "github.com/levigross/grequests"
)

type IOMetric string
type HWMetric string

const (
	Reads        IOMetric = "reads"
	Writes       IOMetric = "writes"
	BytesRead    IOMetric = "bytes_read"
	BytesWritten IOMetric = "bytes_written"
	IOPSRead     IOMetric = "iops_read"
	IOPSWrite    IOMetric = "iops_write"
	ThptRead     IOMetric = "thpt_read"
	ThptWrite    IOMetric = "thpt_write"
	LatAvgRead   IOMetric = "lat_avg_read"
	LatAvgWrite  IOMetric = "lat_avg_write"
	Lat50Read    IOMetric = "lat_50_read"
	Lat90Read    IOMetric = "lat_90_read"
	Lat100Read   IOMetric = "lat_100_read"
	Lat50Write   IOMetric = "lat_50_write"
	Lat90Write   IOMetric = "lat_90_write"
	Lat100Write  IOMetric = "lat_100_write"
)

func (io IOMetric) Validate() error {
	switch io {
	case Reads, Writes, BytesRead, BytesWritten, IOPSRead, IOPSWrite, ThptRead, ThptWrite, LatAvgRead,
		LatAvgWrite, Lat50Read, Lat50Write, Lat90Read, Lat90Write, Lat100Read, Lat100Write:
		return nil
	default:
		return fmt.Errorf("%s is not a valid IO metric", io)
	}
}

const (
	CPUUsage HWMetric = "cpu_usage"
)

func (hw HWMetric) Validate() error {
	switch hw {
	case CPUUsage:
		return nil
	default:
		return fmt.Errorf("%s is not a valid HW metric", hw)
	}
}

type MetricsParams struct {
	ListRangeParams
	Ival string
	UUID string
	Path string
}

func (mp MetricsParams) ToMap() map[string]string {
	r := mp.ListRangeParams.ToMap()
	if mp.Ival != "" {
		r["ival"] = mp.Ival
	}
	if mp.UUID != "" {
		r["uuid"] = mp.UUID
	}
	if mp.Path != "" {
		r["path"] = mp.Path
	}

	return r
}

type Metrics struct {
	EntityPath string  `json:"entity_path" mapstructure:"entity_path"`
	Tenant     string  `json:"tenant" mapstructure:"tenant"`
	Points     []Point `json:"points" mapstructure:"points"`
}

type Point struct {
	Time  int64   `json:"time" mapstructure:"time"`
	Value float64 `json:"value" mapstructure:"value"`
}

type IOMetricsRequest struct {
	Ctxt   context.Context `json:"-"`
	Type   IOMetric        `json:"-"`
	Params MetricsParams   `json:"params,omitempty"`
}

type HWMetricsRequest struct {
	Ctxt   context.Context `json:"-"`
	Type   IOMetric        `json:"-"`
	Params MetricsParams   `json:"params,omitempty"`
}

type IOMetrics struct {
	Path string
}

type HWMetrics struct {
	Path string
}

func newIOMetrics(path string) *IOMetrics {
	return &IOMetrics{
		Path: _path.Join(path, "metrics", "io"),
	}
}

func newHWMetrics(path string) *HWMetrics {
	return &HWMetrics{
		Path: _path.Join(path, "metrics", "hw"),
	}
}

func (m *IOMetrics) List(ro *IOMetricsRequest) ([]*Metrics, *ApiErrorResponse, error) {
	if err := ro.Type.Validate(); err != nil {
		return nil, nil, err
	}

	gro := &greq.RequestOptions{
		JSON:   ro,
		Params: ro.Params.ToMap(),
	}

	rs, apierr, err := GetConn(ro.Ctxt).GetList(ro.Ctxt, _path.Join(m.Path, string(ro.Type)), gro)
	if apierr != nil {
		return nil, apierr, err
	}

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

	resp := []*Metrics{}
	for _, data := range rs.Data {
		elem := &Metrics{}
		edata := data.(map[string]interface{})
		if err = FillStruct(edata, elem); err != nil {
			return nil, nil, err
		}
		resp = append(resp, elem)
	}

	return resp, nil, nil
}

func (m *HWMetrics) List(ro *HWMetricsRequest) ([]*Metrics, *ApiErrorResponse, error) {
	if err := ro.Type.Validate(); err != nil {
		return nil, nil, err
	}

	gro := &greq.RequestOptions{
		JSON:   ro,
		Params: ro.Params.ToMap(),
	}

	rs, apierr, err := GetConn(ro.Ctxt).GetList(ro.Ctxt, _path.Join(m.Path, string(ro.Type)), gro)
	if apierr != nil {
		return nil, apierr, err
	}

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

	resp := []*Metrics{}
	for _, data := range rs.Data {
		elem := &Metrics{}
		edata := data.(map[string]interface{})
		if err = FillStruct(edata, elem); err != nil {
			return nil, nil, err
		}
		resp = append(resp, elem)
	}

	return resp, nil, nil
}
<|endoftext|>


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

package math

func sinus(x float64, quad int) float64 {
	// Coefficients are #3370 from Hart & Cheney (18.80D).
	const (
		P0	= .1357884097877375669092680e8;
		P1	= -.4942908100902844161158627e7;
		P2	= .4401030535375266501944918e6;
		P3	= -.1384727249982452873054457e5;
		P4	= .1459688406665768722226959e3;
		Q0	= .8644558652922534429915149e7;
		Q1	= .4081792252343299749395779e6;
		Q2	= .9463096101538208180571257e4;
		Q3	= .1326534908786136358911494e3;
	)
	if x < 0 {
		x = -x;
		quad = quad + 2;
	}
	x = x * (2 / Pi);	/* underflow? */
	var y float64;
	if x > 32764 {
		var e float64;
		e, y = Modf(x);
		e = e + float64(quad);
		_, f := Modf(0.25 * e);
		quad = int(e - 4*f);
	} else {
		k := int32(x);
		y = x - float64(k);
		quad = (quad + int(k)) & 3;
	}

	if quad&1 != 0 {
		y = 1 - y
	}
	if quad > 1 {
		y = -y
	}

	yy := y * y;
	temp1 := ((((P4*yy+P3)*yy+P2)*yy+P1)*yy + P0) * y;
	temp2 := ((((yy+Q3)*yy+Q2)*yy+Q1)*yy + Q0);
	return temp1 / temp2;
}

// Cos returns the cosine of x.
func Cos(x float64) float64 {
	if x < 0 {
		x = -x
	}
	return sinus(x, 1);
}

// Sin returns the sine of x.
func Sin(x float64) float64	{ return sinus(x, 0) }
<commit_msg>bad sin/cos for large angles. fixes issue 326.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package math

func sinus(x float64, quad int) float64 {
	// Coefficients are #3370 from Hart & Cheney (18.80D).
	const (
		P0	= .1357884097877375669092680e8;
		P1	= -.4942908100902844161158627e7;
		P2	= .4401030535375266501944918e6;
		P3	= -.1384727249982452873054457e5;
		P4	= .1459688406665768722226959e3;
		Q0	= .8644558652922534429915149e7;
		Q1	= .4081792252343299749395779e6;
		Q2	= .9463096101538208180571257e4;
		Q3	= .1326534908786136358911494e3;
	)
	if x < 0 {
		x = -x;
		quad = quad + 2;
	}
	x = x * (2 / Pi);	/* underflow? */
	var y float64;
	if x > 32764 {
		var e float64;
		e, y = Modf(x);
		e = e + float64(quad);
		f, _ := Modf(0.25 * e);
		quad = int(e - 4*f);
	} else {
		k := int32(x);
		y = x - float64(k);
		quad = (quad + int(k)) & 3;
	}

	if quad&1 != 0 {
		y = 1 - y
	}
	if quad > 1 {
		y = -y
	}

	yy := y * y;
	temp1 := ((((P4*yy+P3)*yy+P2)*yy+P1)*yy + P0) * y;
	temp2 := ((((yy+Q3)*yy+Q2)*yy+Q1)*yy + Q0);
	return temp1 / temp2;
}

// Cos returns the cosine of x.
func Cos(x float64) float64 {
	if x < 0 {
		x = -x
	}
	return sinus(x, 1);
}

// Sin returns the sine of x.
func Sin(x float64) float64	{ return sinus(x, 0) }
<|endoftext|>


<commit_before>package pool

import (
	"container/list"
	"testing"
)

const (
	poolSize = 4
	itemsNum = 10
	maxNum   = 4
)

func TestPool(t *testing.T) {
	p := New(poolSize)
	if p.Get() != nil {
		t.Error("Should be nil")
		t.Fail()
	}

	if err := p.Put(nil); err != nil {
		t.Errorf("Unexpected error: %s", err)
		t.Fail()
	}
	i := 0
	p.New = func() interface{} {
		i++
		return i
	}
	for x := 1; x <= itemsNum; x++ {
		a := p.Get()
		if b, ok := a.(int); !ok {
			t.Errorf("Wrong value: %v", a)
			t.Fail()
		} else if b != x {
			t.Errorf("Wrong number: %d, Expected: %d", b, x)
			t.Fail()
		} else {
			t.Logf("Number: %d", b)
		}
	}

	if p.Len() != 0 {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), 0)
		t.Fail()
	}

	for x := 1; x <= itemsNum; x++ {
		if err := p.Put(x); err != nil {
			t.Errorf("Unexpected error: %s", err)
			t.Fail()
		}
	}

	if p.Len() != itemsNum {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), itemsNum)
		t.Fail()
	}

	p.MaxLen(maxNum)

	if p.Len() != maxNum {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), maxNum)
		t.Fail()
	}
}

func dump(t *testing.T, data *list.List) {
	t.Log("----dump----BGN----")
	for elem := data.Front(); elem.Next() != nil; elem = elem.Next() {
		t.Logf("%v", elem.Value)
	}
	t.Log("----dump----END----")
}
<commit_msg>fixed the testcase<commit_after>package pool

import (
	"container/list"
	"testing"
)

const (
	itemsNum = 10
	maxNum   = 4
)

func TestPool(t *testing.T) {
	p := New()
	if p.Get() != nil {
		t.Error("Should be nil")
		t.Fail()
	}

	if err := p.Put(nil); err != nil {
		t.Errorf("Unexpected error: %s", err)
		t.Fail()
	}
	i := 0
	p.New = func() interface{} {
		i++
		return i
	}
	for x := 1; x <= itemsNum; x++ {
		a := p.Get()
		if b, ok := a.(int); !ok {
			t.Errorf("Wrong value: %v", a)
			t.Fail()
		} else if b != x {
			t.Errorf("Wrong number: %d, Expected: %d", b, x)
			t.Fail()
		} else {
			t.Logf("Number: %d", b)
		}
	}

	if p.Len() != 0 {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), 0)
		t.Fail()
	}

	for x := 1; x <= itemsNum; x++ {
		if err := p.Put(x); err != nil {
			t.Errorf("Unexpected error: %s", err)
			t.Fail()
		}
	}

	if p.Len() != itemsNum {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), itemsNum)
		t.Fail()
	}

	p.MaxLen(maxNum)

	if p.Len() != maxNum {
		t.Errorf("Wrong Pool size: %d, expected: %d", p.Len(), maxNum)
		t.Fail()
	}
}

func dump(t *testing.T, data *list.List) {
	t.Log("----dump----BGN----")
	for elem := data.Front(); elem.Next() != nil; elem = elem.Next() {
		t.Logf("%v", elem.Value)
	}
	t.Log("----dump----END----")
}
<|endoftext|>


<commit_before>package errors

import "net/http"

var (
	// ErrInvalidID represents an invalid identifier
	ErrInvalidID = New(http.StatusBadRequest, "Please provide a valid ID")
	// ErrProxyExists occurs when you try to register an already registered proxy
	ErrProxyExists = New(http.StatusBadRequest, "Proxy already registered")
	// ErrAuthorizationFieldNotFound is used when the http Authorization header is missing from the request
	ErrAuthorizationFieldNotFound = New(http.StatusBadRequest, "authorization field missing")
	// ErrBearerMalformed is used when the Bearer string in the Authorization header is not found or is malformed
	ErrBearerMalformed = New(http.StatusBadRequest, "bearer token malformed")
	// ErrAccessTokenNotAuthorized is used when the access token is not found on the storage
	ErrAccessTokenNotAuthorized = New(http.StatusUnauthorized, "access token not authorized")
	// ErrInvalidScheme is used when the access token is not found on the storage
	ErrInvalidScheme = New(http.StatusBadRequest, "the scheme is not supported")
)
<commit_msg>Added errors<commit_after>package errors

import "net/http"

var (
	// ErrRouteNotFound happens when no route was matched
	ErrRouteNotFound = New(http.StatusNotFound, "no API found with those values")
	// ErrInvalidID represents an invalid identifier
	ErrInvalidID = New(http.StatusBadRequest, "please provide a valid ID")
	// ErrProxyExists occurs when you try to register an already registered proxy
	ErrProxyExists = New(http.StatusBadRequest, "proxy already registered")
	// ErrAuthorizationFieldNotFound is used when the http Authorization header is missing from the request
	ErrAuthorizationFieldNotFound = New(http.StatusBadRequest, "authorization field missing")
	// ErrBearerMalformed is used when the Bearer string in the Authorization header is not found or is malformed
	ErrBearerMalformed = New(http.StatusBadRequest, "bearer token malformed")
	// ErrAccessTokenNotAuthorized is used when the access token is not found on the storage
	ErrAccessTokenNotAuthorized = New(http.StatusUnauthorized, "access token not authorized")
	// ErrInvalidScheme is used when the access token is not found on the storage
	ErrInvalidScheme = New(http.StatusBadRequest, "scheme is not supported")
)
<|endoftext|>


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

package net

import (
	"errors"
	"time"
)

// A DialOption modifies a DialOpt call.
type DialOption interface {
	dialOption()
}

var (
	// TCP is a dial option to dial with TCP (over IPv4 or IPv6).
	TCP = Network("tcp")

	// UDP is a dial option to dial with UDP (over IPv4 or IPv6).
	UDP = Network("udp")
)

// Network returns a DialOption to dial using the given network.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// For IP networks, net must be "ip", "ip4" or "ip6" followed
// by a colon and a protocol number or name, such as
// "ipv4:1" or "ip6:ospf".
func Network(net string) DialOption {
	return dialNetwork(net)
}

type dialNetwork string

func (dialNetwork) dialOption() {}

// Deadline returns a DialOption to fail a dial that doesn't
// complete before t.
func Deadline(t time.Time) DialOption {
	return dialDeadline(t)
}

// Timeout returns a DialOption to fail a dial that doesn't
// complete within the provided duration.
func Timeout(d time.Duration) DialOption {
	return dialDeadline(time.Now().Add(d))
}

type dialDeadline time.Time

func (dialDeadline) dialOption() {}

type tcpFastOpen struct{}

func (tcpFastOpen) dialOption() {}

// TODO(bradfitz): implement this (golang.org/issue/4842) and unexport this.
//
// TCPFastTimeout returns an option to use TCP Fast Open (TFO) when
// doing this dial. It is only valid for use with TCP connections.
// Data sent over a TFO connection may be processed by the peer
// multiple times, so should be used with caution.
func todo_TCPFastTimeout() DialOption {
	return tcpFastOpen{}
}

type localAddrOption struct {
	la Addr
}

func (localAddrOption) dialOption() {}

// LocalAddress returns a dial option to perform a dial with the
// provided local address. The address must be of a compatible type
// for the network being dialed.
func LocalAddress(addr Addr) DialOption {
	return localAddrOption{addr}
}

func parseNetwork(net string) (afnet string, proto int, err error) {
	i := last(net, ':')
	if i < 0 { // no colon
		switch net {
		case "tcp", "tcp4", "tcp6":
		case "udp", "udp4", "udp6":
		case "ip", "ip4", "ip6":
		case "unix", "unixgram", "unixpacket":
		default:
			return "", 0, UnknownNetworkError(net)
		}
		return net, 0, nil
	}
	afnet = net[:i]
	switch afnet {
	case "ip", "ip4", "ip6":
		protostr := net[i+1:]
		proto, i, ok := dtoi(protostr, 0)
		if !ok || i != len(protostr) {
			proto, err = lookupProtocol(protostr)
			if err != nil {
				return "", 0, err
			}
		}
		return afnet, proto, nil
	}
	return "", 0, UnknownNetworkError(net)
}

func resolveAddr(op, net, addr string, deadline time.Time) (Addr, error) {
	afnet, _, err := parseNetwork(net)
	if err != nil {
		return nil, &OpError{op, net, nil, err}
	}
	if op == "dial" && addr == "" {
		return nil, &OpError{op, net, nil, errMissingAddress}
	}
	switch afnet {
	case "unix", "unixgram", "unixpacket":
		return ResolveUnixAddr(afnet, addr)
	}
	return resolveInternetAddr(afnet, addr, deadline)
}

// Dial connects to the address addr on the network net.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// For TCP and UDP networks, addresses have the form host:port.
// If host is a literal IPv6 address, it must be enclosed
// in square brackets.  The functions JoinHostPort and SplitHostPort
// manipulate addresses in this form.
//
// Examples:
//	Dial("tcp", "12.34.56.78:80")
//	Dial("tcp", "google.com:80")
//	Dial("tcp", "[de:ad:be:ef::ca:fe]:80")
//
// For IP networks, net must be "ip", "ip4" or "ip6" followed
// by a colon and a protocol number or name.
//
// Examples:
//	Dial("ip4:1", "127.0.0.1")
//	Dial("ip6:ospf", "::1")
//
func Dial(net, addr string) (Conn, error) {
	return DialOpt(addr, dialNetwork(net))
}

func netFromOptions(opts []DialOption) string {
	for _, opt := range opts {
		if p, ok := opt.(dialNetwork); ok {
			return string(p)
		}
	}
	return "tcp"
}

func deadlineFromOptions(opts []DialOption) time.Time {
	for _, opt := range opts {
		if d, ok := opt.(dialDeadline); ok {
			return time.Time(d)
		}
	}
	return noDeadline
}

var noLocalAddr Addr // nil

func localAddrFromOptions(opts []DialOption) Addr {
	for _, opt := range opts {
		if o, ok := opt.(localAddrOption); ok {
			return o.la
		}
	}
	return noLocalAddr
}

// DialOpt dials addr using the provided options.
// If no options are provided, DialOpt(addr) is equivalent
// to Dial("tcp", addr). See Dial for the syntax of addr.
func DialOpt(addr string, opts ...DialOption) (Conn, error) {
	net := netFromOptions(opts)
	deadline := deadlineFromOptions(opts)
	la := localAddrFromOptions(opts)
	ra, err := resolveAddr("dial", net, addr, deadline)
	if err != nil {
		return nil, err
	}
	return dial(net, addr, la, ra, deadline)
}

func dial(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
	if la != nil && la.Network() != ra.Network() {
		return nil, &OpError{"dial", net, ra, errors.New("mismatched local addr type " + la.Network())}
	}
	switch ra := ra.(type) {
	case *TCPAddr:
		la, _ := la.(*TCPAddr)
		c, err = dialTCP(net, la, ra, deadline)
	case *UDPAddr:
		la, _ := la.(*UDPAddr)
		c, err = dialUDP(net, la, ra, deadline)
	case *IPAddr:
		la, _ := la.(*IPAddr)
		c, err = dialIP(net, la, ra, deadline)
	case *UnixAddr:
		la, _ := la.(*UnixAddr)
		c, err = dialUnix(net, la, ra, deadline)
	default:
		err = &OpError{"dial", net + " " + addr, ra, UnknownNetworkError(net)}
	}
	if err != nil {
		return nil, err
	}
	return
}

// DialTimeout acts like Dial but takes a timeout.
// The timeout includes name resolution, if required.
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
	return dialTimeout(net, addr, timeout)
}

// dialTimeoutRace is the old implementation of DialTimeout, still used
// on operating systems where the deadline hasn't been pushed down
// into the pollserver.
// TODO: fix this on plan9.
func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
	t := time.NewTimer(timeout)
	defer t.Stop()
	type pair struct {
		Conn
		error
	}
	ch := make(chan pair, 1)
	resolvedAddr := make(chan Addr, 1)
	go func() {
		ra, err := resolveAddr("dial", net, addr, noDeadline)
		if err != nil {
			ch <- pair{nil, err}
			return
		}
		resolvedAddr <- ra // in case we need it for OpError
		c, err := dial(net, addr, noLocalAddr, ra, noDeadline)
		ch <- pair{c, err}
	}()
	select {
	case <-t.C:
		// Try to use the real Addr in our OpError, if we resolved it
		// before the timeout. Otherwise we just use stringAddr.
		var ra Addr
		select {
		case a := <-resolvedAddr:
			ra = a
		default:
			ra = &stringAddr{net, addr}
		}
		err := &OpError{
			Op:   "dial",
			Net:  net,
			Addr: ra,
			Err:  &timeoutError{},
		}
		return nil, err
	case p := <-ch:
		return p.Conn, p.error
	}
	panic("unreachable")
}

type stringAddr struct {
	net, addr string
}

func (a stringAddr) Network() string { return a.net }
func (a stringAddr) String() string  { return a.addr }

// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented network:
// "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
func Listen(net, laddr string) (Listener, error) {
	la, err := resolveAddr("listen", net, laddr, noDeadline)
	if err != nil {
		return nil, err
	}
	switch la := la.(type) {
	case *TCPAddr:
		return ListenTCP(net, la)
	case *UnixAddr:
		return ListenUnix(net, la)
	}
	return nil, UnknownNetworkError(net)
}

// ListenPacket announces on the local network address laddr.
// The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
func ListenPacket(net, laddr string) (PacketConn, error) {
	la, err := resolveAddr("listen", net, laddr, noDeadline)
	if err != nil {
		return nil, err
	}
	switch la := la.(type) {
	case *UDPAddr:
		return ListenUDP(net, la)
	case *IPAddr:
		return ListenIP(net, la)
	case *UnixAddr:
		return ListenUnixgram(net, la)
	}
	return nil, UnknownNetworkError(net)
}
<commit_msg>net: evaluate the timeout dial opt's deadline at dial time<commit_after>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"errors"
	"time"
)

// A DialOption modifies a DialOpt call.
type DialOption interface {
	setDialOpt(*dialOpts)
}

var noLocalAddr Addr // nil

// dialOpts holds all the dial options, populated by a DialOption's
// setDialOpt.
//
// All fields may be their zero value.
type dialOpts struct {
	deadline        time.Time
	localAddr       Addr
	network         string // if empty, "tcp"
	deferredConnect bool
}

func (o *dialOpts) net() string {
	if o.network == "" {
		return "tcp"
	}
	return o.network
}

var (
	// TCP is a dial option to dial with TCP (over IPv4 or IPv6).
	TCP = Network("tcp")

	// UDP is a dial option to dial with UDP (over IPv4 or IPv6).
	UDP = Network("udp")
)

// Network returns a DialOption to dial using the given network.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// For IP networks, net must be "ip", "ip4" or "ip6" followed
// by a colon and a protocol number or name, such as
// "ipv4:1" or "ip6:ospf".
func Network(net string) DialOption {
	return dialNetwork(net)
}

type dialNetwork string

func (s dialNetwork) setDialOpt(o *dialOpts) {
	o.network = string(s)
}

// Deadline returns a DialOption to fail a dial that doesn't
// complete before t.
func Deadline(t time.Time) DialOption {
	return dialDeadline(t)
}

type dialDeadline time.Time

func (t dialDeadline) setDialOpt(o *dialOpts) {
	o.deadline = time.Time(t)
}

// Timeout returns a DialOption to fail a dial that doesn't
// complete within the provided duration.
func Timeout(d time.Duration) DialOption {
	return dialTimeoutOpt(d)
}

type dialTimeoutOpt time.Duration

func (d dialTimeoutOpt) setDialOpt(o *dialOpts) {
	o.deadline = time.Now().Add(time.Duration(d))
}

type tcpFastOpen struct{}

func (tcpFastOpen) setDialOpt(o *dialOpts) {
	o.deferredConnect = true
}

// TODO(bradfitz): implement this (golang.org/issue/4842) and unexport this.
//
// TCPFastTimeout returns an option to use TCP Fast Open (TFO) when
// doing this dial. It is only valid for use with TCP connections.
// Data sent over a TFO connection may be processed by the peer
// multiple times, so should be used with caution.
func todo_TCPFastTimeout() DialOption {
	return tcpFastOpen{}
}

type localAddrOption struct {
	la Addr
}

func (a localAddrOption) setDialOpt(o *dialOpts) {
	o.localAddr = a.la
}

// LocalAddress returns a dial option to perform a dial with the
// provided local address. The address must be of a compatible type
// for the network being dialed.
func LocalAddress(addr Addr) DialOption {
	return localAddrOption{addr}
}

func parseNetwork(net string) (afnet string, proto int, err error) {
	i := last(net, ':')
	if i < 0 { // no colon
		switch net {
		case "tcp", "tcp4", "tcp6":
		case "udp", "udp4", "udp6":
		case "ip", "ip4", "ip6":
		case "unix", "unixgram", "unixpacket":
		default:
			return "", 0, UnknownNetworkError(net)
		}
		return net, 0, nil
	}
	afnet = net[:i]
	switch afnet {
	case "ip", "ip4", "ip6":
		protostr := net[i+1:]
		proto, i, ok := dtoi(protostr, 0)
		if !ok || i != len(protostr) {
			proto, err = lookupProtocol(protostr)
			if err != nil {
				return "", 0, err
			}
		}
		return afnet, proto, nil
	}
	return "", 0, UnknownNetworkError(net)
}

func resolveAddr(op, net, addr string, deadline time.Time) (Addr, error) {
	afnet, _, err := parseNetwork(net)
	if err != nil {
		return nil, &OpError{op, net, nil, err}
	}
	if op == "dial" && addr == "" {
		return nil, &OpError{op, net, nil, errMissingAddress}
	}
	switch afnet {
	case "unix", "unixgram", "unixpacket":
		return ResolveUnixAddr(afnet, addr)
	}
	return resolveInternetAddr(afnet, addr, deadline)
}

// Dial connects to the address addr on the network net.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// For TCP and UDP networks, addresses have the form host:port.
// If host is a literal IPv6 address, it must be enclosed
// in square brackets.  The functions JoinHostPort and SplitHostPort
// manipulate addresses in this form.
//
// Examples:
//	Dial("tcp", "12.34.56.78:80")
//	Dial("tcp", "google.com:80")
//	Dial("tcp", "[de:ad:be:ef::ca:fe]:80")
//
// For IP networks, net must be "ip", "ip4" or "ip6" followed
// by a colon and a protocol number or name.
//
// Examples:
//	Dial("ip4:1", "127.0.0.1")
//	Dial("ip6:ospf", "::1")
//
func Dial(net, addr string) (Conn, error) {
	return DialOpt(addr, dialNetwork(net))
}

// DialOpt dials addr using the provided options.
// If no options are provided, DialOpt(addr) is equivalent
// to Dial("tcp", addr). See Dial for the syntax of addr.
func DialOpt(addr string, opts ...DialOption) (Conn, error) {
	var o dialOpts
	for _, opt := range opts {
		opt.setDialOpt(&o)
	}
	ra, err := resolveAddr("dial", o.net(), addr, o.deadline)
	if err != nil {
		return nil, err
	}
	return dial(o.net(), addr, o.localAddr, ra, o.deadline)
}

func dial(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
	if la != nil && la.Network() != ra.Network() {
		return nil, &OpError{"dial", net, ra, errors.New("mismatched local addr type " + la.Network())}
	}
	switch ra := ra.(type) {
	case *TCPAddr:
		la, _ := la.(*TCPAddr)
		c, err = dialTCP(net, la, ra, deadline)
	case *UDPAddr:
		la, _ := la.(*UDPAddr)
		c, err = dialUDP(net, la, ra, deadline)
	case *IPAddr:
		la, _ := la.(*IPAddr)
		c, err = dialIP(net, la, ra, deadline)
	case *UnixAddr:
		la, _ := la.(*UnixAddr)
		c, err = dialUnix(net, la, ra, deadline)
	default:
		err = &OpError{"dial", net + " " + addr, ra, UnknownNetworkError(net)}
	}
	if err != nil {
		return nil, err
	}
	return
}

// DialTimeout acts like Dial but takes a timeout.
// The timeout includes name resolution, if required.
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
	return dialTimeout(net, addr, timeout)
}

// dialTimeoutRace is the old implementation of DialTimeout, still used
// on operating systems where the deadline hasn't been pushed down
// into the pollserver.
// TODO: fix this on plan9.
func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
	t := time.NewTimer(timeout)
	defer t.Stop()
	type pair struct {
		Conn
		error
	}
	ch := make(chan pair, 1)
	resolvedAddr := make(chan Addr, 1)
	go func() {
		ra, err := resolveAddr("dial", net, addr, noDeadline)
		if err != nil {
			ch <- pair{nil, err}
			return
		}
		resolvedAddr <- ra // in case we need it for OpError
		c, err := dial(net, addr, noLocalAddr, ra, noDeadline)
		ch <- pair{c, err}
	}()
	select {
	case <-t.C:
		// Try to use the real Addr in our OpError, if we resolved it
		// before the timeout. Otherwise we just use stringAddr.
		var ra Addr
		select {
		case a := <-resolvedAddr:
			ra = a
		default:
			ra = &stringAddr{net, addr}
		}
		err := &OpError{
			Op:   "dial",
			Net:  net,
			Addr: ra,
			Err:  &timeoutError{},
		}
		return nil, err
	case p := <-ch:
		return p.Conn, p.error
	}
	panic("unreachable")
}

type stringAddr struct {
	net, addr string
}

func (a stringAddr) Network() string { return a.net }
func (a stringAddr) String() string  { return a.addr }

// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented network:
// "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
func Listen(net, laddr string) (Listener, error) {
	la, err := resolveAddr("listen", net, laddr, noDeadline)
	if err != nil {
		return nil, err
	}
	switch la := la.(type) {
	case *TCPAddr:
		return ListenTCP(net, la)
	case *UnixAddr:
		return ListenUnix(net, la)
	}
	return nil, UnknownNetworkError(net)
}

// ListenPacket announces on the local network address laddr.
// The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
func ListenPacket(net, laddr string) (PacketConn, error) {
	la, err := resolveAddr("listen", net, laddr, noDeadline)
	if err != nil {
		return nil, err
	}
	switch la := la.(type) {
	case *UDPAddr:
		return ListenUDP(net, la)
	case *IPAddr:
		return ListenIP(net, la)
	case *UnixAddr:
		return ListenUnixgram(net, la)
	}
	return nil, UnknownNetworkError(net)
}
<|endoftext|>


<commit_before>package main

import "flag"
import "fmt"
import "log"
import "os"
import "os/exec"
import "path"
import "strings"
import "sync"
import "time"

/*

# the plan

qst: run things quickly

qst - detects the current project type and runs it
qst hello.rb - runs `ruby hello.rb`
qst hello.go - compiles & runs hello.go

qst -watch hello.go - watches changes to hello.go and recompiles and runs it on changes

*/

var mappings = map[string]func(string) string{
	".go": func(name string) string {
		return fmt.Sprintf("go build %s && ./%s", name, strings.TrimSuffix(name, path.Ext(name)))
	},
}

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s <file>\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()
	args := flag.Args()

	if len(args) < 1 {
		flag.Usage()
		os.Exit(1)
	}

	file := os.Args[1]
	if !isFile(file) {
		fmt.Fprintf(os.Stderr, "Error: %s is not a file.\n", file)
		os.Exit(1)
	}

	ext := path.Ext(file)
	fn, found := mappings[ext]
	if found {
		runAndWatch(file, fn(file))
	} else {
		fmt.Fprintf(os.Stderr, "Error: No command defined for %s files", ext)
		os.Exit(1)
	}
}

func runAndWatch(file string, cmdLine string) {
	// run command, if file changes (mtime) restart command
	lastMtime := time.Now()
	cmd := ShellCmd(cmdLine)
	cmd.Start()

	for {
		info, err := os.Stat(file)
		if err != nil {
			log.Fatalf("Error: %s disappeared, exiting.", file)
		}

		mtime := info.ModTime()
		if mtime.After(lastMtime) {
			log.Printf("%s changed, rerunning", file)
			cmd.Restart()
		}

		lastMtime = mtime
		time.Sleep(1 * time.Second)
	}
}

type RestartableCommand struct {
	Cmd  *exec.Cmd
	Lock sync.Mutex
	Name string
	Args []string
}

func ShellCmd(cmd string) RestartableCommand {
	return RestartableCommand{nil, sync.Mutex{}, "sh", []string{"-c", cmd}}
}

func (c *RestartableCommand) Start() {
	c.Cmd = exec.Command(c.Name, c.Args...)
	c.Cmd.Stderr = os.Stderr
	c.Cmd.Stdout = os.Stdout
	c.Lock.Lock()
	go func() {
		c.Cmd.Run()
		c.Lock.Unlock()
	}()
}

func (c *RestartableCommand) Restart() {
	c.Cmd.Process.Kill()
	c.Start()
}

func runShellCmd(cmd string) {
	log.Printf("Running: `%s'", cmd)
	output, err := exec.Command("sh", "-c", cmd).CombinedOutput()
	os.Stderr.Write(output)
	log.Printf("Error running command: %s\n", err.Error())
}

func isFile(file string) bool {
	info, err := os.Stat(file)
	return err == nil && !info.IsDir()
}
<commit_msg>support the simplest possible ruby & python projects.<commit_after>package main

import "flag"
import "fmt"
import "log"
import "os"
import "os/exec"
import "path"
import "strings"
import "sync"
import "time"

/*

# the plan

qst: run things quickly

qst - detects the current project type and runs it
qst hello.rb - runs `ruby hello.rb`
qst hello.go - compiles & runs hello.go

qst -watch hello.go - watches changes to hello.go and recompiles and runs it on changes

*/

var mappings = map[string]func(string) string{
	".go": func(name string) string {
		return fmt.Sprintf("go build %s && ./%s", name, strings.TrimSuffix(name, path.Ext(name)))
	},
	".rb": func(name string) string {
		return fmt.Sprintf("ruby %s", name)
	},
	".py": func(name string) string {
		return fmt.Sprintf("python %s", name)
	},
}

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s <file>\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()
	args := flag.Args()

	if len(args) < 1 {
		flag.Usage()
		os.Exit(1)
	}

	file := os.Args[1]
	if !isFile(file) {
		fmt.Fprintf(os.Stderr, "Error: %s is not a file.\n", file)
		os.Exit(1)
	}

	ext := path.Ext(file)
	fn, found := mappings[ext]
	if found {
		runAndWatch(file, fn(file))
	} else {
		fmt.Fprintf(os.Stderr, "Error: No command defined for %s files", ext)
		os.Exit(1)
	}
}

func runAndWatch(file string, cmdLine string) {
	// run command, if file changes (mtime) restart command
	lastMtime := time.Now()
	cmd := ShellCmd(cmdLine)
	cmd.Start()

	for {
		info, err := os.Stat(file)
		if err != nil {
			log.Fatalf("Error: %s disappeared, exiting.", file)
		}

		mtime := info.ModTime()
		if mtime.After(lastMtime) {
			log.Printf("%s changed, rerunning", file)
			cmd.Restart()
		}

		lastMtime = mtime
		time.Sleep(1 * time.Second)
	}
}

type RestartableCommand struct {
	Cmd  *exec.Cmd
	Lock sync.Mutex
	Name string
	Args []string
}

func ShellCmd(cmd string) RestartableCommand {
	return RestartableCommand{nil, sync.Mutex{}, "sh", []string{"-c", cmd}}
}

func (c *RestartableCommand) Start() {
	c.Cmd = exec.Command(c.Name, c.Args...)
	c.Cmd.Stderr = os.Stderr
	c.Cmd.Stdout = os.Stdout
	c.Lock.Lock()
	go func() {
		c.Cmd.Run()
		c.Lock.Unlock()
	}()
}

func (c *RestartableCommand) Restart() {
	c.Cmd.Process.Kill()
	c.Start()
}

func runShellCmd(cmd string) {
	log.Printf("Running: `%s'", cmd)
	output, err := exec.Command("sh", "-c", cmd).CombinedOutput()
	os.Stderr.Write(output)
	log.Printf("Error running command: %s\n", err.Error())
}

func isFile(file string) bool {
	info, err := os.Stat(file)
	return err == nil && !info.IsDir()
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestZoneCacheVariants(t *testing.T) {
	setup()
	defer teardown()

	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
		w.Header().Set("content-type", "application/json")
		// JSON data from: https://api.cloudflare.com/#zone-cache-settings-get-variants-setting
		_, _ = fmt.Fprintf(w, `{
			"success": true,
			"errors": [],
			"messages": [],
			"result": {
			  "id": "variants",
			  "modified_on": "2014-01-01T05:20:00.12345Z",
			  "value": {
				"avif": [
				  "image/webp",
				  "image/jpeg"
				],
				"bmp": [
				  "image/webp",
				  "image/jpeg"
				]
			  }
			}
		  }`)
	}

	testZoneId := "foo"
	mux.HandleFunc("/zones/"+testZoneId+"/cache/variants", handler)

	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
	want := ZoneCacheVariants{
		ModifiedOn: modifiedOn,
		Value: ZoneCacheVariantsValues{
			Avif: []string{
				"image/webp",
				"image/jpeg",
			},
			Bmp: []string{
				"image/webp",
				"image/jpeg",
			},
		},
	}

	actual, err := client.ZoneCacheVariants(context.Background(), testZoneId)

	if assert.NoError(t, err) {
		assert.Equal(t, want, actual)
	}
}

func TestUpdateZoneCacheVariants(t *testing.T) {
	setup()
	defer teardown()

	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)

		b, err := ioutil.ReadAll(r.Body)
		defer r.Body.Close()

		if assert.NoError(t, err) {
			assert.JSONEq(t, `{"value":{"avif":["image/webp","image/jpeg"],"bmp":["image/webp","image/jpeg"]}}`, string(b))
		}

		w.Header().Set("content-type", "application/json")
		// JSON data from: https://api.cloudflare.com/#zone-cache-settings-change-variants-setting
		_, _ = fmt.Fprintf(w, `{
			"success": true,
			"errors": [],
			"messages": [],
			"result": {
			  "id": "variants",
			  "modified_on": "2014-01-01T05:20:00.12345Z",
			  "value": {
				"avif": [
				  "image/webp",
				  "image/jpeg"
				],
				"bmp": [
				  "image/webp",
				  "image/jpeg"
				]
			  }
			}
		  }`)
	}

	testZoneId := "foo"
	mux.HandleFunc("/zones/"+testZoneId+"/cache/variants", handler)

	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")

	want := ZoneCacheVariants{
		ModifiedOn: modifiedOn,
		Value: ZoneCacheVariantsValues{
			Avif: []string{
				"image/webp",
				"image/jpeg",
			},
			Bmp: []string{
				"image/webp",
				"image/jpeg",
			},
		},
	}

	zoneCacheVariants := ZoneCacheVariantsValues{
		Avif: []string{
			"image/webp",
			"image/jpeg",
		},
		Bmp: []string{
			"image/webp",
			"image/jpeg",
		}}

	actual, err := client.UpdateZoneCacheVariants(context.Background(), testZoneId, zoneCacheVariants)

	if assert.NoError(t, err) {
		assert.Equal(t, want, actual)
	}
}

func TestDeleteZoneCacheVariants(t *testing.T) {
	setup()
	defer teardown()

	apiCalled := false

	handler := func(w http.ResponseWriter, r *http.Request) {
		apiCalled = true
		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)

		w.Header().Set("content-type", "application/json")
		// JSON data from: https://api.cloudflare.com/#zone-cache-settings-delete-variants-setting
		_, _ = fmt.Fprintf(w, `{
			"success": true,
			"errors": [],
			"messages": [],
			"result": {
			  "id": "variants",
			  "modified_on": "2014-01-01T05:20:00.12345Z"
			}
		  }`)
	}

	testZoneId := "foo"
	mux.HandleFunc("/zones/"+testZoneId+"/cache/variants", handler)

	err := client.DeleteZoneCacheVariants(context.Background(), testZoneId)

	assert.NoError(t, err)
	assert.True(t, apiCalled)
}
<commit_msg>follow up from #805<commit_after>package cloudflare

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestZoneCacheVariants(t *testing.T) {
	setup()
	defer teardown()

	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
		w.Header().Set("content-type", "application/json")
		fmt.Fprintf(w, `
        {
          "success": true,
          "errors": [],
          "messages": [],
          "result": {
            "id": "variants",
            "modified_on": "2014-01-01T05:20:00.12345Z",
            "value": {
              "avif": [
                "image/webp",
                "image/jpeg"
              ],
              "bmp": [
                "image/webp",
                "image/jpeg"
              ]
            }
          }
        }`)
	}

	mux.HandleFunc("/zones/"+testZoneID+"/cache/variants", handler)

	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
	want := ZoneCacheVariants{
		ModifiedOn: modifiedOn,
		Value: ZoneCacheVariantsValues{
			Avif: []string{
				"image/webp",
				"image/jpeg",
			},
			Bmp: []string{
				"image/webp",
				"image/jpeg",
			},
		},
	}

	actual, err := client.ZoneCacheVariants(context.Background(), testZoneID)

	if assert.NoError(t, err) {
		assert.Equal(t, want, actual)
	}
}

func TestZoneCacheVariantsUpdate(t *testing.T) {
	setup()
	defer teardown()

	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)

		b, err := ioutil.ReadAll(r.Body)
		defer r.Body.Close()

		if assert.NoError(t, err) {
			assert.JSONEq(t, `{"value":{"avif":["image/webp","image/jpeg"],"bmp":["image/webp","image/jpeg"]}}`, string(b))
		}

		w.Header().Set("content-type", "application/json")
		fmt.Fprintf(w, `
        {
		  "success": true,
          "errors": [],
          "messages": [],
          "result": {
		    "id": "variants",
            "modified_on": "2014-01-01T05:20:00.12345Z",
            "value": {
			  "avif": [
			    "image/webp",
                "image/jpeg"
              ],
			  "bmp": [
				"image/webp",
				"image/jpeg"
			  ]
            }
          }
        }`)
	}

	mux.HandleFunc("/zones/"+testZoneID+"/cache/variants", handler)

	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")

	want := ZoneCacheVariants{
		ModifiedOn: modifiedOn,
		Value: ZoneCacheVariantsValues{
			Avif: []string{
				"image/webp",
				"image/jpeg",
			},
			Bmp: []string{
				"image/webp",
				"image/jpeg",
			},
		},
	}

	zoneCacheVariants := ZoneCacheVariantsValues{
		Avif: []string{
			"image/webp",
			"image/jpeg",
		},
		Bmp: []string{
			"image/webp",
			"image/jpeg",
		}}

	actual, err := client.UpdateZoneCacheVariants(context.Background(), testZoneID, zoneCacheVariants)

	if assert.NoError(t, err) {
		assert.Equal(t, want, actual)
	}
}

func TestZoneCacheVariantsDelete(t *testing.T) {
	setup()
	defer teardown()

	apiCalled := false

	handler := func(w http.ResponseWriter, r *http.Request) {
		apiCalled = true
		assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)

		w.Header().Set("content-type", "application/json")
		fmt.Fprintf(w, `
        {
		  "success": true,
          "errors": [],
          "messages": [],
          "result": {
            "id": "variants",
            "modified_on": "2014-01-01T05:20:00.12345Z"
          }
        }`)
	}

	mux.HandleFunc("/zones/"+testZoneID+"/cache/variants", handler)

	err := client.DeleteZoneCacheVariants(context.Background(), testZoneID)

	assert.NoError(t, err)
	assert.True(t, apiCalled)
}
<|endoftext|>


<commit_before>package rss

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

// Parse RSS or Atom data.
func Parse(data []byte) (*Feed, error) {
	if strings.Contains(string(data), "<rss") {
		return parseRSS2(data, database)
	} else if strings.Contains(string(data), "xmlns=\"http://purl.org/rss/1.0/\"") {
		return parseRSS1(data, database)
	} else {
		return parseAtom(data, database)
	}

	panic("Unreachable.")
}

// Fetch downloads and parses the RSS feed at the given URL
func Fetch(url string) (*Feed, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return Parse(body)
}

// Feed is the top-level structure.
type Feed struct {
	Title       string
	Description string
	Link        string
	Image       *Image
	Items       []*Item
	Refresh     time.Time
	Unread      uint32
}

func (f *Feed) String() string {
	buf := new(bytes.Buffer)
	buf.WriteString(fmt.Sprintf("Feed %q\n\t%q\n\t%q\n\t%s\n\tRefresh at %s\n\tUnread: %d\n\tItems:\n",
		f.Title, f.Description, f.Link, f.Image, f.Refresh.Format("Mon 2 Jan 2006 15:04:05 MST"), f.Unread))
	for _, item := range f.Items {
		buf.WriteString(fmt.Sprintf("\t%s\n", item.Format("\t\t")))
	}
	return buf.String()
}

// Item represents a single story.
type Item struct {
	Title   string
	Content string
	Link    string
	Date    time.Time
	ID      string
	Read    bool
}

func (i *Item) String() string {
	return i.Format("")
}

func (i *Item) Format(s string) string {
	return fmt.Sprintf("Item %q\n\t%s%q\n\t%s%s\n\t%s%q\n\t%sRead: %v\n\t%s%q", i.Title, s, i.Link, s,
		i.Date.Format("Mon 2 Jan 2006 15:04:05 MST"), s, i.ID, s, i.Read, s, i.Content)
}

type Image struct {
	Title   string
	Url     string
	Height  uint32
	Width   uint32
}

func (i *Image) String() string {
	return fmt.Sprintf("Image %q", i.Title)
}
<commit_msg>go fmt rss.go<commit_after>package rss

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

// Parse RSS or Atom data.
func Parse(data []byte) (*Feed, error) {
	if strings.Contains(string(data), "<rss") {
		return parseRSS2(data, database)
	} else if strings.Contains(string(data), "xmlns=\"http://purl.org/rss/1.0/\"") {
		return parseRSS1(data, database)
	} else {
		return parseAtom(data, database)
	}

	panic("Unreachable.")
}

// Fetch downloads and parses the RSS feed at the given URL
func Fetch(url string) (*Feed, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return Parse(body)
}

// Feed is the top-level structure.
type Feed struct {
	Title       string
	Description string
	Link        string
	Image       *Image
	Items       []*Item
	Refresh     time.Time
	Unread      uint32
}

func (f *Feed) String() string {
	buf := new(bytes.Buffer)
	buf.WriteString(fmt.Sprintf("Feed %q\n\t%q\n\t%q\n\t%s\n\tRefresh at %s\n\tUnread: %d\n\tItems:\n",
		f.Title, f.Description, f.Link, f.Image, f.Refresh.Format("Mon 2 Jan 2006 15:04:05 MST"), f.Unread))
	for _, item := range f.Items {
		buf.WriteString(fmt.Sprintf("\t%s\n", item.Format("\t\t")))
	}
	return buf.String()
}

// Item represents a single story.
type Item struct {
	Title   string
	Content string
	Link    string
	Date    time.Time
	ID      string
	Read    bool
}

func (i *Item) String() string {
	return i.Format("")
}

func (i *Item) Format(s string) string {
	return fmt.Sprintf("Item %q\n\t%s%q\n\t%s%s\n\t%s%q\n\t%sRead: %v\n\t%s%q", i.Title, s, i.Link, s,
		i.Date.Format("Mon 2 Jan 2006 15:04:05 MST"), s, i.ID, s, i.Read, s, i.Content)
}

type Image struct {
	Title  string
	Url    string
	Height uint32
	Width  uint32
}

func (i *Image) String() string {
	return fmt.Sprintf("Image %q", i.Title)
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"io"
	"log"
	"net"
	"net/http/httputil"
	"net/url"
	"os"
	"strconv"
	"strings"

	"github.com/remind101/emp/Godeps/_workspace/src/github.com/bgentry/heroku-go"
	"github.com/remind101/emp/Godeps/_workspace/src/github.com/docker/docker/pkg/term"
)

var (
	detachedRun bool
	dynoSize    string
)

var cmdRun = &Command{
	Run:      runRun,
	Usage:    "run [-s <size>] [-d] <command> [<argument>...]",
	NeedsApp: true,
	Category: "dyno",
	Short:    "run a process in a dyno",
	Long: `
Run a process on Heroku. Flags such as` + " `-a` " + `may be parsed out of
the command unless the command is quoted or provided after a
double-dash (--).

Options:

    -s <size>  set the size for this dyno (e.g. 2X)
    -d         run in detached mode instead of attached to terminal

Examples:

    $ emp run echo "hello"
    Running ` + "`echo \"hello\"`" + ` on myapp as run.1234:
    "hello"

    $ emp run console
    Running ` + "`console`" + ` on myapp as run.5678:
    Loading production environment (Rails 3.2.14)
    irb(main):001:0> ...

    $ emp run -d -s 2X bin/my_worker
    Ran ` + "`bin/my_worker`" + ` on myapp as run.4321, detached.

    $ emp run -a myapp -- ls -a /
    Running ` + "`ls -a bin /`" + ` on myapp as run.8650:
    /:
    .  ..  app  bin  dev  etc  home  lib  lib64  lost+found  proc  sbin  tmp  usr  var
`,
}

func init() {
	cmdRun.Flag.BoolVarP(&detachedRun, "detached", "d", false, "detached")
	cmdRun.Flag.StringVarP(&dynoSize, "size", "s", "", "dyno size")
}

func runRun(cmd *Command, args []string) {
	if len(args) == 0 {
		cmd.PrintUsage()
		os.Exit(2)
	}
	appname := mustApp()

	w, err := term.GetWinsize(inFd)
	if err != nil {
		printFatal(err.Error())
	}

	attached := !detachedRun
	opts := heroku.DynoCreateOpts{Attach: &attached}
	if attached {
		env := map[string]string{
			"COLUMNS": strconv.Itoa(int(w.Width)),
			"LINES":   strconv.Itoa(int(w.Height)),
			"TERM":    os.Getenv("TERM"),
		}
		opts.Env = &env
	}
	if dynoSize != "" {
		if !strings.HasSuffix(dynoSize, "X") {
			cmd.PrintUsage()
			os.Exit(2)
		}
		opts.Size = &dynoSize
	}

	command := strings.Join(args, " ")
	if detachedRun {
		dyno, err := client.DynoCreate(appname, command, &opts)
		must(err)

		log.Printf("Ran `%s` on %s as %s, detached.", dyno.Command, appname, dyno.Name)
		return
	}

	params := struct {
		Command string             `json:"command"`
		Attach  *bool              `json:"attach,omitempty"`
		Env     *map[string]string `json:"env,omitempty"`
		Size    *string            `json:"size,omitempty"`
	}{
		Command: command,
		Attach:  opts.Attach,
		Env:     opts.Env,
		Size:    opts.Size,
	}
	req, err := client.NewRequest("POST", "/apps/"+appname+"/dynos", params)
	must(err)

	u, err := url.Parse(apiURL)
	must(err)

	protocol := u.Scheme
	address := u.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = u.Host
	}

	if u.Scheme == "https" {
		address = address + ":443"
	}

	var dial net.Conn
	if u.Scheme == "https" {
		dial, err = tlsDial(protocol, address, &tls.Config{})
		if err != nil {
			printFatal(err.Error())
		}
	} else {
		dial, err = net.Dial(protocol, address)
		if err != nil {
			printFatal(err.Error())
		}
	}

	clientconn := httputil.NewClientConn(dial, nil)
	defer clientconn.Close()
	clientconn.Do(req)
	rwc, br := clientconn.Hijack()
	defer rwc.Close()

	if isTerminalIn && isTerminalOut {
		state, err := term.SetRawTerminal(inFd)
		if err != nil {
			printFatal(err.Error())
		}
		defer term.RestoreTerminal(inFd, state)
	}

	errChanOut := make(chan error, 1)
	errChanIn := make(chan error, 1)
	exit := make(chan bool)
	go func() {
		defer close(exit)
		defer close(errChanOut)
		var err error
		_, err = io.Copy(os.Stdout, br)
		errChanOut <- err
	}()
	go func() {
		_, err := io.Copy(rwc, os.Stdin)
		errChanIn <- err
		rwc.(interface {
			CloseWrite() error
		}).CloseWrite()
	}()
	<-exit
	select {
	case err = <-errChanIn:
		must(err)
	case err = <-errChanOut:
		must(err)
	}
}
<commit_msg>Set default window size.<commit_after>package main

import (
	"crypto/tls"
	"io"
	"log"
	"net"
	"net/http/httputil"
	"net/url"
	"os"
	"strconv"
	"strings"

	"github.com/remind101/emp/Godeps/_workspace/src/github.com/bgentry/heroku-go"
	"github.com/remind101/emp/Godeps/_workspace/src/github.com/docker/docker/pkg/term"
)

var (
	detachedRun bool
	dynoSize    string
)

var cmdRun = &Command{
	Run:      runRun,
	Usage:    "run [-s <size>] [-d] <command> [<argument>...]",
	NeedsApp: true,
	Category: "dyno",
	Short:    "run a process in a dyno",
	Long: `
Run a process on Heroku. Flags such as` + " `-a` " + `may be parsed out of
the command unless the command is quoted or provided after a
double-dash (--).

Options:

    -s <size>  set the size for this dyno (e.g. 2X)
    -d         run in detached mode instead of attached to terminal

Examples:

    $ emp run echo "hello"
    Running ` + "`echo \"hello\"`" + ` on myapp as run.1234:
    "hello"

    $ emp run console
    Running ` + "`console`" + ` on myapp as run.5678:
    Loading production environment (Rails 3.2.14)
    irb(main):001:0> ...

    $ emp run -d -s 2X bin/my_worker
    Ran ` + "`bin/my_worker`" + ` on myapp as run.4321, detached.

    $ emp run -a myapp -- ls -a /
    Running ` + "`ls -a bin /`" + ` on myapp as run.8650:
    /:
    .  ..  app  bin  dev  etc  home  lib  lib64  lost+found  proc  sbin  tmp  usr  var
`,
}

func init() {
	cmdRun.Flag.BoolVarP(&detachedRun, "detached", "d", false, "detached")
	cmdRun.Flag.StringVarP(&dynoSize, "size", "s", "", "dyno size")
}

func runRun(cmd *Command, args []string) {
	if len(args) == 0 {
		cmd.PrintUsage()
		os.Exit(2)
	}
	appname := mustApp()

	w, err := term.GetWinsize(inFd)
	if err != nil {
		// If syscall.TIOCGWINSZ is not supported by the device, we're
		// probably trying to run tests. Set w to some sensible default.
		if err.Error() == "operation not supported by device" {
			w = &term.Winsize{
				Height: 20,
				Width:  80,
			}
		} else {
			printFatal(err.Error())
		}
	}

	attached := !detachedRun
	opts := heroku.DynoCreateOpts{Attach: &attached}
	if attached {
		env := map[string]string{
			"COLUMNS": strconv.Itoa(int(w.Width)),
			"LINES":   strconv.Itoa(int(w.Height)),
			"TERM":    os.Getenv("TERM"),
		}
		opts.Env = &env
	}
	if dynoSize != "" {
		if !strings.HasSuffix(dynoSize, "X") {
			cmd.PrintUsage()
			os.Exit(2)
		}
		opts.Size = &dynoSize
	}

	command := strings.Join(args, " ")
	if detachedRun {
		dyno, err := client.DynoCreate(appname, command, &opts)
		must(err)

		log.Printf("Ran `%s` on %s as %s, detached.", dyno.Command, appname, dyno.Name)
		return
	}

	params := struct {
		Command string             `json:"command"`
		Attach  *bool              `json:"attach,omitempty"`
		Env     *map[string]string `json:"env,omitempty"`
		Size    *string            `json:"size,omitempty"`
	}{
		Command: command,
		Attach:  opts.Attach,
		Env:     opts.Env,
		Size:    opts.Size,
	}
	req, err := client.NewRequest("POST", "/apps/"+appname+"/dynos", params)
	must(err)

	u, err := url.Parse(apiURL)
	must(err)

	protocol := u.Scheme
	address := u.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = u.Host
	}

	if u.Scheme == "https" {
		address = address + ":443"
	}

	var dial net.Conn
	if u.Scheme == "https" {
		dial, err = tlsDial(protocol, address, &tls.Config{})
		if err != nil {
			printFatal(err.Error())
		}
	} else {
		dial, err = net.Dial(protocol, address)
		if err != nil {
			printFatal(err.Error())
		}
	}

	clientconn := httputil.NewClientConn(dial, nil)
	defer clientconn.Close()
	clientconn.Do(req)
	rwc, br := clientconn.Hijack()
	defer rwc.Close()

	if isTerminalIn && isTerminalOut {
		state, err := term.SetRawTerminal(inFd)
		if err != nil {
			printFatal(err.Error())
		}
		defer term.RestoreTerminal(inFd, state)
	}

	errChanOut := make(chan error, 1)
	errChanIn := make(chan error, 1)
	exit := make(chan bool)
	go func() {
		defer close(exit)
		defer close(errChanOut)
		var err error
		_, err = io.Copy(os.Stdout, br)
		errChanOut <- err
	}()
	go func() {
		_, err := io.Copy(rwc, os.Stdin)
		errChanIn <- err
		rwc.(interface {
			CloseWrite() error
		}).CloseWrite()
	}()
	<-exit
	select {
	case err = <-errChanIn:
		must(err)
	case err = <-errChanOut:
		must(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
  "bytes"
  "encoding/json"
  "errors"
  "fmt"
  "io/ioutil"
  "log"
  "os"
  "path/filepath"
  "strings"
)

type Commands map[string]string

func getCommands() (Commands, error) {
  var commands Commands
  jsonStream, err := ioutil.ReadFile("./commands.json")
  if err != nil {
    return commands, err
  }

  decoder := json.NewDecoder(bytes.NewReader(jsonStream))
  if err := decoder.Decode(&commands); err != nil {
    return commands, err
  }

  return commands, nil
}

func commandForFile(path string) (string, error) {
  commands, err := getCommands()
  if err != nil {
    return "", err
  }

  extension := strings.Replace(filepath.Ext(path), ".", "", -1)

  if command := commands[extension]; command != "" {
    return strings.Replace(command, "%", path, -1), nil
  }
  return "", errors.New("run could not determine how to run this file because it does not have a known extension")
}

func start(args []string) error {
  if len(args) <= 1 {
    return errors.New("no files given")
  }
  command, err := commandForFile(args[1])
  if err != nil {
    log.Fatal(err)
  }
  fmt.Println(command)
  return nil
}

func main() {
  if err := start(os.Args); err != nil {
    log.Fatal(err)
  }
}
<commit_msg>Don't use log.Fatal() outside of main()<commit_after>package main

import (
  "bytes"
  "encoding/json"
  "errors"
  "fmt"
  "io/ioutil"
  "log"
  "os"
  "path/filepath"
  "strings"
)

type Commands map[string]string

func getCommands() (Commands, error) {
  var commands Commands
  jsonStream, err := ioutil.ReadFile("./commands.json")
  if err != nil {
    return commands, err
  }

  decoder := json.NewDecoder(bytes.NewReader(jsonStream))
  if err := decoder.Decode(&commands); err != nil {
    return commands, err
  }

  return commands, nil
}

func commandForFile(path string) (string, error) {
  commands, err := getCommands()
  if err != nil {
    return "", err
  }

  extension := strings.Replace(filepath.Ext(path), ".", "", -1)

  if command := commands[extension]; command != "" {
    return strings.Replace(command, "%", path, -1), nil
  }
  return "", errors.New("run could not determine how to run this file because it does not have a known extension")
}

func start(args []string) error {
  if len(args) <= 1 {
    return errors.New("no files given")
  }
  command, err := commandForFile(args[1])
  if err != nil {
    return err
  }
  fmt.Println(command)
  return nil
}

func main() {
  if err := start(os.Args); err != nil {
    log.Fatal(err)
  }
}
<|endoftext|>