<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/c-14/grue/config"
	"os"
)

const version = "0.2.0-alpha"

func usage() string {
	return `usage: grue [--help] {add|fetch|import|init_cfg} ...

Subcommands:
	add <name> <url>
	fetch [-init]
	import <config>
	init_cfg`
}

func add(args []string, conf *config.GrueConfig) error {
	if len(args) != 2 {
		return errors.New("usage: grue add <name> <url>")
	}
	var name string = args[0]
	var uri string = args[1]
	return conf.AddAccount(name, uri)
}

func main() {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, usage())
		os.Exit(EX_USAGE)
	}
	conf, err := config.ReadConfig()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(EX_TEMPFAIL)
	}
	defer conf.Unlock()
	switch cmd := os.Args[1]; cmd {
	case "add":
		err = add(os.Args[2:], conf)
	case "fetch":
		var fetchCmd = flag.NewFlagSet("fetch", flag.ContinueOnError)
		var initFlag = fetchCmd.Bool("init", false, "Don't send emails, only initialize database of read entries")
		err = fetchCmd.Parse(os.Args[2:])
		if err == nil {
			err = fetchFeeds(conf, *initFlag)
		}
	case "import":
		err = config.ImportCfg(os.Args[2:])
	case "init_cfg":
		break
	case "-v":
		fallthrough
	case "--version":
		fmt.Println(version)
	case "-h":
		fallthrough
	case "--help":
		fmt.Println(usage())
	default:
		fmt.Fprintln(os.Stderr, usage())
		conf.Unlock()
		os.Exit(EX_USAGE)
	}
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
}
<commit_msg>Add list command<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/c-14/grue/config"
	"os"
	"text/tabwriter"
)

const version = "0.2.0-alpha"

func usage() string {
	return `usage: grue [--help] {add|fetch|import|init_cfg|list} ...

Subcommands:
	add <name> <url>
	fetch [-init]
	import <config>
	init_cfg
	list [name] [--full]`
}

func add(args []string, conf *config.GrueConfig) error {
	if len(args) != 2 {
		return errors.New("usage: grue add <name> <url>")
	}
	var name string = args[0]
	var uri string = args[1]
	return conf.AddAccount(name, uri)
}

func list(args []string, conf *config.GrueConfig) error {
	const (
		fmtShort = "%s\t%s\n"
		fmtFull  = "%s:\n%s\n"
	)
	var full bool
	var listCmd = flag.NewFlagSet("list", flag.ContinueOnError)
	listCmd.BoolVar(&full, "full", false, "Show full account info")
	if err := listCmd.Parse(args); err != nil {
		return err
	}
	if len(listCmd.Args()) == 0 {
		if full {
			for name, cfg := range conf.Accounts {
				fmt.Printf(fmtFull, name, cfg.String())
			}
			return nil
		}
		w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
		for name, cfg := range conf.Accounts {
			fmt.Fprintf(w, fmtShort, name, cfg.URI)
		}
		w.Flush()
		return nil
	}

	name := listCmd.Args()[0]
	if cfg, ok := conf.Accounts[name]; ok {
		if full {
			fmt.Printf(fmtFull, name, cfg.String())
		} else {
			fmt.Printf(fmtShort, name, cfg.URI)
		}
	}
	return nil
}

func main() {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, usage())
		os.Exit(EX_USAGE)
	}
	conf, err := config.ReadConfig()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(EX_TEMPFAIL)
	}
	defer conf.Unlock()
	switch cmd := os.Args[1]; cmd {
	case "add":
		err = add(os.Args[2:], conf)
	case "fetch":
		var fetchCmd = flag.NewFlagSet("fetch", flag.ContinueOnError)
		var initFlag = fetchCmd.Bool("init", false, "Don't send emails, only initialize database of read entries")
		err = fetchCmd.Parse(os.Args[2:])
		if err == nil {
			err = fetchFeeds(conf, *initFlag)
		}
	case "import":
		err = config.ImportCfg(os.Args[2:])
	case "init_cfg":
		break
	case "list":
		err = list(os.Args[2:], conf)
		break
	case "-v":
		fallthrough
	case "--version":
		fmt.Println(version)
	case "-h":
		fallthrough
	case "--help":
		fmt.Println(usage())
	default:
		fmt.Fprintln(os.Stderr, usage())
		conf.Unlock()
		os.Exit(EX_USAGE)
	}
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import "strconv"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := []Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// an issue. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	if len(tags) == 0 {
		return []byte{}
	}

	// Add each tag in the form of "tag, ".
	var buf []byte
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", ".
	buf = buf[:len(buf)-2]
	return buf
}

// MarshalJSON returns an JSON formatted string slice (or array).
func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	// Add each tag in the form of `"tag", `
	buf := []byte("[")
	for _, tag := range tags {
		qoutedTag := strconv.Quote(tag)
		buf = append(buf, qoutedTag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last "," and a closing bracket.
	buf = append(buf[:len(buf)-2], ']')
	return buf, nil
}
<commit_msg>Fix tags example<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import "strconv"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// an issue. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	if len(tags) == 0 {
		return []byte{}
	}

	// Add each tag in the form of "tag, ".
	var buf []byte
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", ".
	buf = buf[:len(buf)-2]
	return buf
}

// MarshalJSON returns an JSON formatted string slice (or array).
func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	// Add each tag in the form of `"tag", `
	buf := []byte("[")
	for _, tag := range tags {
		qoutedTag := strconv.Quote(tag)
		buf = append(buf, qoutedTag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last "," and a closing bracket.
	buf = append(buf[:len(buf)-2], ']')
	return buf, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"reflect"
)

type Address struct {
	Street1 string  `json:"street_1"`
	Street2 *string `json:"street_2"`
	City    string  `json:"city"`
	Region  string  `json:"state"`
	Zipcode string  `json:"zip_code"`
	//status  bool    `json:"fraud_address"`
}

func main() {
	eric := &Address{
		"1 Main St",
		nil,
		"Buffalo",
		"NY",
		"14086",
		// true,
	}
	displayStructTags(eric)
}

func displayStructTags(s interface{}) {
	// get the value and type of s
	t := reflect.TypeOf(s)
	v := reflect.ValueOf(s)

	// lets make sure we are actually working with a struct
	if t.Kind() != reflect.Struct {
		log.Fatalf("Wow, you can't even get the right type in a demo.... fail!\nKind()  was: %s\n ", t.Kind())
	}
	log.Println(t.Kind())

	// get the number of fields and loop through them
	fieldCount := t.NumField()
	for i := 0; i < fieldCount; i++ {
		// tag is accessed through the type, the value through value.. derp
		fmt.Printf("{\"%s\":\"%s\"}\n", t.Field(i).Tag.Get("json"), v.Field(i))
	}
}

/*
  // check for pointer and get underlying type
  if t.Kind() == reflect.Ptr {
    t = t.Elem()
  }
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

  // check to see if a feed is exported and settable
		if v.Field(i).CanSet() {
*/
<commit_msg>added a few more comments to the tags example<commit_after>package main

import (
	"fmt"
	"log"
	"reflect"
)

type Address struct {
	Street1 string  `json:"street_1"`
	Street2 *string `json:"street_2"`
	City    string  `json:"city"`
	Region  string  `json:"state"`
	Zipcode string  `json:"zip_code"`
	//status  bool    `json:"fraud_address"` --uncomment to test unexported fields
}

func main() {
	eric := &Address{
		"1 Main St",
		nil,
		"Buffalo",
		"NY",
		"14086",
		// true,--uncomment to test unexported fields
	}
	displayStructTags(eric)
}

func displayStructTags(s interface{}) {
	// get the value and type of s
	t := reflect.TypeOf(s)
	v := reflect.ValueOf(s)

	// #1

	// lets make sure we are actually working with a struct
	if t.Kind() != reflect.Struct {
		log.Fatalf("Wow, you can't even get the right type in a demo.... fail!\nKind()  was: %s\n ", t.Kind())
	}
	log.Println(t.Kind())

	// get the number of fields and loop through them
	fieldCount := t.NumField()
	for i := 0; i < fieldCount; i++ {
		// tag is accessed through the type, the value through value.. derp
		// #2 see below
		fmt.Printf("{\"%s\":\"%s\"}\n", t.Field(i).Tag.Get("json"), v.Field(i))
	}
}

/*
  #1 to get the type of the right kin,d use elem which returns the value pointed to by a ptr
  in the real world, it would be necessary to check the underlying type to check for a ptr or nil
  // check for pointer and get underlying type
  if t.Kind() == reflect.Ptr {
    t = t.Elem()
  }
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

  #2 Use CanSet() to see if a field is exported. You can also use the PkgPath to determine if a field is exported
	  if v.Field(i).CanSet() {
		fmt.Printf("{\"%s\":\"%s\"}\n", t.Field(i).Tag.Get("json"), v.Field(i))
	  }
*/
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

const (
	taskAPI = "/task/"
)

type taskStatus struct {
	Creator string

	Repo string
	Rev  string
	PPA  string

	Status  string
	Process string
	Error   string

	WorkingDir string
}

/*
 * @args[0]: task id
 * @args[1](optional): sub-action
 */
func cmdTask(args []string) error {
	taskId := args[0]

	if len(args) == 1 {
		// Get task status

		resp, _ := request("GET", servAddr+taskAPI+taskId, nil, "")
		defer resp.Body.Close()

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

		var ts taskStatus
		if resp.StatusCode == 200 {
			dec := json.NewDecoder(strings.NewReader(string(body)))
			dec.Decode(&ts)
			fmt.Printf("%+v\n", ts)
		}
		return nil
	}

	switch args[1] {
	case "output":
		return cmdTaskOutput(taskId)
	default:
		panic("ERR")
	}

	return nil
}

func cmdTaskOutput(taskId string) error {
	action := "/output"
	resp, _ := request("GET", servAddr+taskAPI+taskId+action, nil, "")
	defer resp.Body.Close()

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

	if resp.StatusCode == 200 {
		fmt.Println(string(body))
	}

	return nil
}
<commit_msg>ID will be recorded in task status<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

const (
	taskAPI = "/task/"
)

type taskStatus struct {
	ID      uint64
	Creator string

	Repo string
	Rev  string
	PPA  string

	Status  string
	Process string
	Error   string

	WorkingDir string
}

/*
 * @args[0]: task id
 * @args[1](optional): sub-action
 */
func cmdTask(args []string) error {
	taskId := args[0]

	if len(args) == 1 {
		// Get task status

		resp, _ := request("GET", servAddr+taskAPI+taskId, nil, "")
		defer resp.Body.Close()

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

		var ts taskStatus
		if resp.StatusCode == 200 {
			dec := json.NewDecoder(strings.NewReader(string(body)))
			dec.Decode(&ts)
			fmt.Printf("%+v\n", ts)
		}
		return nil
	}

	switch args[1] {
	case "output":
		return cmdTaskOutput(taskId)
	default:
		panic("ERR")
	}

	return nil
}

func cmdTaskOutput(taskId string) error {
	action := "/output"
	resp, _ := request("GET", servAddr+taskAPI+taskId+action, nil, "")
	defer resp.Body.Close()

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

	if resp.StatusCode == 200 {
		fmt.Println(string(body))
	}

	return nil
}
<|endoftext|>


<commit_before>package scipipe

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

// Task represents a single static shell command, or go function, to be
// executed, and are scheduled and managed by a corresponding Process
type Task struct {
	Name          string
	Command       string
	CustomExecute func(*Task)
	InIPs         map[string]*FileIP
	OutIPs        map[string]*FileIP
	Params        map[string]string
	Tags          map[string]string
	Done          chan int
	cores         int
	workflow      *Workflow
	process       *Process
}

// ------------------------------------------------------------------------
// Factory method(s)
// ------------------------------------------------------------------------

// NewTask instantiates and initializes a new Task
func NewTask(workflow *Workflow, process *Process, name string, cmdPat string, inIPs map[string]*FileIP, outPathFuncs map[string]func(*Task) string, outPortsDoStream map[string]bool, params map[string]string, tags map[string]string, prepend string, customExecute func(*Task), cores int) *Task {
	t := &Task{
		Name:          name,
		InIPs:         inIPs,
		OutIPs:        make(map[string]*FileIP),
		Params:        params,
		Tags:          tags,
		Command:       "",
		CustomExecute: customExecute,
		Done:          make(chan int),
		cores:         cores,
		workflow:      workflow,
		process:       process,
	}

	// Create Out-IPs
	for oname, outPathFunc := range outPathFuncs {
		oip := NewFileIP(outPathFunc(t))
		if outPortsDoStream[oname] {
			oip.doStream = true
		}
		t.OutIPs[oname] = oip
	}
	t.Command = formatCommand(cmdPat, inIPs, t.OutIPs, params, tags, prepend)
	return t
}

// formatCommand is a helper function for NewTask, that formats a shell command
// based on concrete file paths and parameter values
func formatCommand(cmd string, inIPs map[string]*FileIP, outIPs map[string]*FileIP, params map[string]string, tags map[string]string, prepend string) string {
	r := getShellCommandPlaceHolderRegex()
	placeHolderMatches := r.FindAllStringSubmatch(cmd, -1)
	portInfos := map[string]map[string]string{}
	for _, placeHolderMatch := range placeHolderMatches {
		portName := placeHolderMatch[2]
		portInfos[portName] = map[string]string{}
		portInfos[portName]["match"] = placeHolderMatch[0]
		portInfos[portName]["port_type"] = placeHolderMatch[1]
		portInfos[portName]["port_name"] = portName
		portInfos[portName]["reduce_inputs"] = "false"
		// Identify if the place holder represents a reduce-type in-port
		if len(placeHolderMatch) > 5 {
			portInfos[portName]["reduce_inputs"] = "true"
			portInfos[portName]["sep"] = placeHolderMatch[7]
		}
	}

	for portName, portInfo := range portInfos {
		var filePath string
		switch portInfo["port_type"] {
		case "o":
			if outIPs[portName] == nil {
				Fail("Missing outpath for outport '", portName, "' for command '", cmd, "'")
			}
			filePath = outIPs[portName].TempPath()
		case "os":
			if outIPs[portName] == nil {
				Fail("Missing outpath for outport '", portName, "' for command '", cmd, "'")
			}
			filePath = outIPs[portName].FifoPath()
		case "i":
			if inIPs[portName] == nil {
				Fail("Missing in-IP for inport '", portName, "' for command '", cmd, "'")
			}
			if portInfo["reduce_inputs"] == "true" && inIPs[portName].Path() == "" {
				// Merge multiple input paths from a substream on the IP, into one string
				ips := []*FileIP{}
				for ip := range inIPs[portName].SubStream.Chan {
					ips = append(ips, ip)
				}
				paths := []string{}
				for _, ip := range ips {
					paths = append(paths, parentDirPath(ip.Path()))
				}
				filePath = strings.Join(paths, portInfo["sep"])
			} else {
				if inIPs[portName].Path() == "" {
					Fail("Missing inpath for inport '", portName, "', and no substream, for command '", cmd, "'")
				}
				if inIPs[portName].doStream {
					filePath = parentDirPath(inIPs[portName].FifoPath())
				} else {
					filePath = parentDirPath(inIPs[portName].Path())
				}
			}
		case "p":
			if params[portName] == "" {
				msg := fmt.Sprint("Missing param value for param '", portName, "' for command '", cmd, "'")
				Fail(msg)
			} else {
				filePath = params[portName]
			}
		case "t":
			if tags[portName] == "" {
				msg := fmt.Sprint("Missing tag value for tag '", portName, "' for command '", cmd, "'")
				Fail(msg)
			} else {
				filePath = tags[portName]
			}
		default:
			Fail("Replace failed for port ", portName, " for command '", cmd, "'")
		}
		cmd = strings.Replace(cmd, portInfo["match"], filePath, -1)
	}

	// Add prepend string to the command
	if prepend != "" {
		cmd = fmt.Sprintf("%s %s", prepend, cmd)
	}

	return cmd
}

// ------------------------------------------------------------------------
// Main API methods: Accessor methods
// ------------------------------------------------------------------------

// InIP returns an IP for the in-port with name portName
func (t *Task) InIP(portName string) *FileIP {
	if t.InIPs[portName] == nil {
		Failf("No such in-portname (%s) in task (%s)\n", portName, t.Name)
	}
	return t.InIPs[portName]
}

// InPath returns the path name of an input file for the task
func (t *Task) InPath(portName string) string {
	return t.InIP(portName).Path()
}

// OutIP returns an IP for the in-port with name portName
func (t *Task) OutIP(portName string) *FileIP {
	if t.OutIPs[portName] == nil {
		Failf("No such out-portname (%s) in task (%s)\n", portName, t.Name)
	}
	return t.OutIPs[portName]
}

// OutPath returns the path name of an input file for the task
func (t *Task) OutPath(portName string) string {
	return t.OutIP(portName).Path()
}

// Param returns the value of a param, for the task
func (t *Task) Param(portName string) string {
	if param, ok := t.Params[portName]; ok {
		return param
	}
	Failf("No such param port '%s' for task '%s'\n", portName, t.Name)
	return "invalid"
}

// Tag returns the value of a param, for the task
func (t *Task) Tag(tagName string) string {
	if tag, ok := t.Tags[tagName]; ok {
		return tag
	}
	Failf("No such tag '%s' for task '%s'\n", tagName, t.Name)
	return "invalid"
}

// ------------------------------------------------------------------------
// Execute the task
// ------------------------------------------------------------------------

// Execute executes the task (the shell command or go function in CustomExecute)
func (t *Task) Execute() {
	defer close(t.Done)

	// Do some sanity checks
	if t.anyTempfileExists() {
		Failf("| %-32s | Existing temp files found so existing. Clean up .tmp files before restarting the workflow!", t.Name)
	}

	if t.anyOutputsExist() {
		t.Done <- 1
		return
	}

	// Execute task
	t.workflow.IncConcurrentTasks(t.cores) // Will block if max concurrent tasks is reached
	t.createDirs()                         // Create output directories needed for any outputs
	startTime := time.Now()
	if t.CustomExecute != nil {
		outputsStr := ""
		for oipName, oip := range t.OutIPs {
			outputsStr += " " + oipName + ": " + oip.Path()
		}
		Audit.Printf("| %-32s | Executing: Custom Go function with outputs: %s\n", t.Name, outputsStr)
		t.CustomExecute(t)
		Audit.Printf("| %-32s | Finished:  Custom Go function with outputs: %s\n", t.Name, outputsStr)
	} else {
		Audit.Printf("| %-32s | Executing: %s\n", t.Name, t.Command)
		t.executeCommand(t.Command)
		Audit.Printf("| %-32s | Finished:  %s\n", t.Name, t.Command)
	}
	finishTime := time.Now()
	t.writeAuditLogs(startTime, finishTime)
	t.atomizeIPs()
	t.workflow.DecConcurrentTasks(t.cores)

	t.Done <- 1
}

// ------------------------------------------------------------------------
// Helper methods for the Execute method
// ------------------------------------------------------------------------

// anyTempFileExists checks if any temporary workflow files exist and if so, returns true
func (t *Task) anyTempfileExists() (anyTempfileExists bool) {
	anyTempfileExists = false
	for _, oip := range t.OutIPs {
		if !oip.doStream {
			otmpPath := oip.TempPath()
			if _, err := os.Stat(otmpPath); err == nil {
				Warning.Printf("| %-32s | Temp file already exists: %s (Note: If resuming from a failed run, clean up .tmp files first. Also, make sure that two processes don't produce the same output files!).\n", t.Name, otmpPath)
				anyTempfileExists = true
			}
		}
	}
	return
}

// anyOutputsExist if any output file IP, or temporary file IPs, exist
func (t *Task) anyOutputsExist() (anyFileExists bool) {
	anyFileExists = false
	for _, oip := range t.OutIPs {
		if !oip.doStream {
			opath := oip.Path()
			if _, err := os.Stat(opath); err == nil {
				Audit.Printf("| %-32s | Output file already exists, so skipping: %s\n", t.Name, opath)
				anyFileExists = true
			}
		}
	}
	return
}

// createDirs creates directories for out-IPs of the task
func (t *Task) createDirs() {
	os.MkdirAll(t.TempDir(), 0777)
	for _, oip := range t.OutIPs {
		oipDir := oip.TempDir() // This will create all out dirs, including the temp dir
		if oip.doStream {       // Temp dirs are not created for fifo files
			oipDir = filepath.Dir(oip.FifoPath())
		} else {
			oipDir = t.TempDir() + "/" + oipDir
		}
		err := os.MkdirAll(oipDir, 0777)
		CheckWithMsg(err, "Could not create directory: "+oipDir)
	}

}

// executeCommand executes the shell command cmd via bash
func (t *Task) executeCommand(cmd string) {
	// cd into the task's tempdir, execute the command, and cd back
	out, err := exec.Command("bash", "-c", "cd "+t.TempDir()+" && "+cmd+" && cd ..").CombinedOutput()
	if err != nil {
		Failf("Command failed!\nCommand:\n%s\n\nOutput:\n%s\nOriginal error:%s\n", cmd, string(out), err.Error())
	}
}

func (t *Task) writeAuditLogs(startTime time.Time, finishTime time.Time) {
	// Append audit info for the task to all its output IPs
	auditInfo := NewAuditInfo()
	auditInfo.Command = t.Command
	auditInfo.ProcessName = t.process.Name()
	auditInfo.Params = t.Params
	auditInfo.StartTime = startTime
	auditInfo.FinishTime = finishTime
	auditInfo.ExecTimeMS = finishTime.Sub(startTime) / time.Millisecond
	// Set the audit infos from incoming IPs into the "Upstream" map
	for _, iip := range t.InIPs {
		iipPath := iip.Path()
		iipAuditInfo := iip.AuditInfo()
		auditInfo.Upstream[iipPath] = iipAuditInfo
	}
	// Add the current audit info to output ips and write them to file
	for _, oip := range t.OutIPs {
		oip.SetAuditInfo(auditInfo)
		for _, iip := range t.InIPs {
			oip.AddTags(iip.Tags())
		}
		oip.WriteAuditLogToFile()
	}
}

// atomizeIPs renames temporary output files/directories to their proper paths
func (t *Task) atomizeIPs() {
	for _, oip := range t.OutIPs {
		// Move paths for ports, to final destinations
		if !oip.doStream {
			os.Rename(t.TempDir()+"/"+oip.TempPath(), oip.Path())
		}
	}
	// For remaining paths in temporary execution dir, just move out of it
	filepath.Walk(t.TempDir(), func(tempPath string, fileInfo os.FileInfo, err error) error {
		if !fileInfo.IsDir() {
			newPath := strings.Replace(tempPath, t.TempDir()+"/", "", 1)
			newPath = strings.Replace(newPath, AbsPathPlaceholder+"/", "/", 1)
			newPathDir := filepath.Dir(newPath)
			if _, err := os.Stat(newPathDir); os.IsNotExist(err) {
				os.MkdirAll(newPathDir, 0777)
			}
			Debug.Println("Moving: ", tempPath, " -> ", newPath)
			renameErr := os.Rename(tempPath, newPath)
			CheckWithMsg(renameErr, "Could not rename file "+tempPath+" to "+newPath)
		}
		return err
	})
	// Remove temporary execution dir
	remErr := os.RemoveAll(t.TempDir())
	CheckWithMsg(remErr, "Could not remove temp dir: "+t.TempDir())
}

// TempDir returns a string that is unique to a task, suitable for use
// in file paths. It is built up by merging all input filenames and parameter
// values that a task takes as input, joined with dots.
func (t *Task) TempDir() string {
	pathPcs := []string{"tmp." + t.Name}
	for _, ipName := range sortedFileIPMapKeys(t.InIPs) {
		pathPcs = append(pathPcs, filepath.Base(t.InIP(ipName).Path()))
	}
	for _, paramName := range sortedStringMapKeys(t.Params) {
		pathPcs = append(pathPcs, paramName+"_"+t.Param(paramName))
	}
	for _, tagName := range sortedStringMapKeys(t.Tags) {
		pathPcs = append(pathPcs, tagName+"_"+t.Tag(tagName))
	}
	pathSegment := strings.Join(pathPcs, ".")
	if len(pathSegment) > 255 {
		sha1sum := sha1.Sum([]byte(pathSegment))
		pathSegment = t.Name + "." + hex.EncodeToString(sha1sum[:])
	}
	return pathSegment
}

func parentDirPath(path string) string {
	if path[0] == '/' {
		return path
	}
	// For relative paths, add ".." to get out of current dir
	return "../" + path
}
<commit_msg>Fix bug: Should check for existing temp files with temp dir included<commit_after>package scipipe

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

// Task represents a single static shell command, or go function, to be
// executed, and are scheduled and managed by a corresponding Process
type Task struct {
	Name          string
	Command       string
	CustomExecute func(*Task)
	InIPs         map[string]*FileIP
	OutIPs        map[string]*FileIP
	Params        map[string]string
	Tags          map[string]string
	Done          chan int
	cores         int
	workflow      *Workflow
	process       *Process
}

// ------------------------------------------------------------------------
// Factory method(s)
// ------------------------------------------------------------------------

// NewTask instantiates and initializes a new Task
func NewTask(workflow *Workflow, process *Process, name string, cmdPat string, inIPs map[string]*FileIP, outPathFuncs map[string]func(*Task) string, outPortsDoStream map[string]bool, params map[string]string, tags map[string]string, prepend string, customExecute func(*Task), cores int) *Task {
	t := &Task{
		Name:          name,
		InIPs:         inIPs,
		OutIPs:        make(map[string]*FileIP),
		Params:        params,
		Tags:          tags,
		Command:       "",
		CustomExecute: customExecute,
		Done:          make(chan int),
		cores:         cores,
		workflow:      workflow,
		process:       process,
	}

	// Create Out-IPs
	for oname, outPathFunc := range outPathFuncs {
		oip := NewFileIP(outPathFunc(t))
		if outPortsDoStream[oname] {
			oip.doStream = true
		}
		t.OutIPs[oname] = oip
	}
	t.Command = formatCommand(cmdPat, inIPs, t.OutIPs, params, tags, prepend)
	return t
}

// formatCommand is a helper function for NewTask, that formats a shell command
// based on concrete file paths and parameter values
func formatCommand(cmd string, inIPs map[string]*FileIP, outIPs map[string]*FileIP, params map[string]string, tags map[string]string, prepend string) string {
	r := getShellCommandPlaceHolderRegex()
	placeHolderMatches := r.FindAllStringSubmatch(cmd, -1)
	portInfos := map[string]map[string]string{}
	for _, placeHolderMatch := range placeHolderMatches {
		portName := placeHolderMatch[2]
		portInfos[portName] = map[string]string{}
		portInfos[portName]["match"] = placeHolderMatch[0]
		portInfos[portName]["port_type"] = placeHolderMatch[1]
		portInfos[portName]["port_name"] = portName
		portInfos[portName]["reduce_inputs"] = "false"
		// Identify if the place holder represents a reduce-type in-port
		if len(placeHolderMatch) > 5 {
			portInfos[portName]["reduce_inputs"] = "true"
			portInfos[portName]["sep"] = placeHolderMatch[7]
		}
	}

	for portName, portInfo := range portInfos {
		var filePath string
		switch portInfo["port_type"] {
		case "o":
			if outIPs[portName] == nil {
				Fail("Missing outpath for outport '", portName, "' for command '", cmd, "'")
			}
			filePath = outIPs[portName].TempPath()
		case "os":
			if outIPs[portName] == nil {
				Fail("Missing outpath for outport '", portName, "' for command '", cmd, "'")
			}
			filePath = outIPs[portName].FifoPath()
		case "i":
			if inIPs[portName] == nil {
				Fail("Missing in-IP for inport '", portName, "' for command '", cmd, "'")
			}
			if portInfo["reduce_inputs"] == "true" && inIPs[portName].Path() == "" {
				// Merge multiple input paths from a substream on the IP, into one string
				ips := []*FileIP{}
				for ip := range inIPs[portName].SubStream.Chan {
					ips = append(ips, ip)
				}
				paths := []string{}
				for _, ip := range ips {
					paths = append(paths, parentDirPath(ip.Path()))
				}
				filePath = strings.Join(paths, portInfo["sep"])
			} else {
				if inIPs[portName].Path() == "" {
					Fail("Missing inpath for inport '", portName, "', and no substream, for command '", cmd, "'")
				}
				if inIPs[portName].doStream {
					filePath = parentDirPath(inIPs[portName].FifoPath())
				} else {
					filePath = parentDirPath(inIPs[portName].Path())
				}
			}
		case "p":
			if params[portName] == "" {
				msg := fmt.Sprint("Missing param value for param '", portName, "' for command '", cmd, "'")
				Fail(msg)
			} else {
				filePath = params[portName]
			}
		case "t":
			if tags[portName] == "" {
				msg := fmt.Sprint("Missing tag value for tag '", portName, "' for command '", cmd, "'")
				Fail(msg)
			} else {
				filePath = tags[portName]
			}
		default:
			Fail("Replace failed for port ", portName, " for command '", cmd, "'")
		}
		cmd = strings.Replace(cmd, portInfo["match"], filePath, -1)
	}

	// Add prepend string to the command
	if prepend != "" {
		cmd = fmt.Sprintf("%s %s", prepend, cmd)
	}

	return cmd
}

// ------------------------------------------------------------------------
// Main API methods: Accessor methods
// ------------------------------------------------------------------------

// InIP returns an IP for the in-port with name portName
func (t *Task) InIP(portName string) *FileIP {
	if t.InIPs[portName] == nil {
		Failf("No such in-portname (%s) in task (%s)\n", portName, t.Name)
	}
	return t.InIPs[portName]
}

// InPath returns the path name of an input file for the task
func (t *Task) InPath(portName string) string {
	return t.InIP(portName).Path()
}

// OutIP returns an IP for the in-port with name portName
func (t *Task) OutIP(portName string) *FileIP {
	if t.OutIPs[portName] == nil {
		Failf("No such out-portname (%s) in task (%s)\n", portName, t.Name)
	}
	return t.OutIPs[portName]
}

// OutPath returns the path name of an input file for the task
func (t *Task) OutPath(portName string) string {
	return t.OutIP(portName).Path()
}

// Param returns the value of a param, for the task
func (t *Task) Param(portName string) string {
	if param, ok := t.Params[portName]; ok {
		return param
	}
	Failf("No such param port '%s' for task '%s'\n", portName, t.Name)
	return "invalid"
}

// Tag returns the value of a param, for the task
func (t *Task) Tag(tagName string) string {
	if tag, ok := t.Tags[tagName]; ok {
		return tag
	}
	Failf("No such tag '%s' for task '%s'\n", tagName, t.Name)
	return "invalid"
}

// ------------------------------------------------------------------------
// Execute the task
// ------------------------------------------------------------------------

// Execute executes the task (the shell command or go function in CustomExecute)
func (t *Task) Execute() {
	defer close(t.Done)

	// Do some sanity checks
	if t.anyTempfileExists() {
		Failf("| %-32s | Existing temp files found so existing. Clean up .tmp files before restarting the workflow!", t.Name)
	}

	if t.anyOutputsExist() {
		t.Done <- 1
		return
	}

	// Execute task
	t.workflow.IncConcurrentTasks(t.cores) // Will block if max concurrent tasks is reached
	t.createDirs()                         // Create output directories needed for any outputs
	startTime := time.Now()
	if t.CustomExecute != nil {
		outputsStr := ""
		for oipName, oip := range t.OutIPs {
			outputsStr += " " + oipName + ": " + oip.Path()
		}
		Audit.Printf("| %-32s | Executing: Custom Go function with outputs: %s\n", t.Name, outputsStr)
		t.CustomExecute(t)
		Audit.Printf("| %-32s | Finished:  Custom Go function with outputs: %s\n", t.Name, outputsStr)
	} else {
		Audit.Printf("| %-32s | Executing: %s\n", t.Name, t.Command)
		t.executeCommand(t.Command)
		Audit.Printf("| %-32s | Finished:  %s\n", t.Name, t.Command)
	}
	finishTime := time.Now()
	t.writeAuditLogs(startTime, finishTime)
	t.atomizeIPs()
	t.workflow.DecConcurrentTasks(t.cores)

	t.Done <- 1
}

// ------------------------------------------------------------------------
// Helper methods for the Execute method
// ------------------------------------------------------------------------

// anyTempFileExists checks if any temporary workflow files exist and if so, returns true
func (t *Task) anyTempfileExists() (anyTempfileExists bool) {
	anyTempfileExists = false
	for _, oip := range t.OutIPs {
		if !oip.doStream {
			otmpPath := t.TempDir() + "/" + oip.TempPath()
			if _, err := os.Stat(otmpPath); err == nil {
				Warning.Printf("| %-32s | Temp file already exists: %s (Note: If resuming from a failed run, clean up .tmp files first. Also, make sure that two processes don't produce the same output files!).\n", t.Name, otmpPath)
				anyTempfileExists = true
			}
		}
	}
	return
}

// anyOutputsExist if any output file IP, or temporary file IPs, exist
func (t *Task) anyOutputsExist() (anyFileExists bool) {
	anyFileExists = false
	for _, oip := range t.OutIPs {
		if !oip.doStream {
			opath := oip.Path()
			if _, err := os.Stat(opath); err == nil {
				Audit.Printf("| %-32s | Output file already exists, so skipping: %s\n", t.Name, opath)
				anyFileExists = true
			}
		}
	}
	return
}

// createDirs creates directories for out-IPs of the task
func (t *Task) createDirs() {
	os.MkdirAll(t.TempDir(), 0777)
	for _, oip := range t.OutIPs {
		oipDir := oip.TempDir() // This will create all out dirs, including the temp dir
		if oip.doStream {       // Temp dirs are not created for fifo files
			oipDir = filepath.Dir(oip.FifoPath())
		} else {
			oipDir = t.TempDir() + "/" + oipDir
		}
		err := os.MkdirAll(oipDir, 0777)
		CheckWithMsg(err, "Could not create directory: "+oipDir)
	}

}

// executeCommand executes the shell command cmd via bash
func (t *Task) executeCommand(cmd string) {
	// cd into the task's tempdir, execute the command, and cd back
	out, err := exec.Command("bash", "-c", "cd "+t.TempDir()+" && "+cmd+" && cd ..").CombinedOutput()
	if err != nil {
		Failf("Command failed!\nCommand:\n%s\n\nOutput:\n%s\nOriginal error:%s\n", cmd, string(out), err.Error())
	}
}

func (t *Task) writeAuditLogs(startTime time.Time, finishTime time.Time) {
	// Append audit info for the task to all its output IPs
	auditInfo := NewAuditInfo()
	auditInfo.Command = t.Command
	auditInfo.ProcessName = t.process.Name()
	auditInfo.Params = t.Params
	auditInfo.StartTime = startTime
	auditInfo.FinishTime = finishTime
	auditInfo.ExecTimeMS = finishTime.Sub(startTime) / time.Millisecond
	// Set the audit infos from incoming IPs into the "Upstream" map
	for _, iip := range t.InIPs {
		iipPath := iip.Path()
		iipAuditInfo := iip.AuditInfo()
		auditInfo.Upstream[iipPath] = iipAuditInfo
	}
	// Add the current audit info to output ips and write them to file
	for _, oip := range t.OutIPs {
		oip.SetAuditInfo(auditInfo)
		for _, iip := range t.InIPs {
			oip.AddTags(iip.Tags())
		}
		oip.WriteAuditLogToFile()
	}
}

// atomizeIPs renames temporary output files/directories to their proper paths
func (t *Task) atomizeIPs() {
	for _, oip := range t.OutIPs {
		// Move paths for ports, to final destinations
		if !oip.doStream {
			os.Rename(t.TempDir()+"/"+oip.TempPath(), oip.Path())
		}
	}
	// For remaining paths in temporary execution dir, just move out of it
	filepath.Walk(t.TempDir(), func(tempPath string, fileInfo os.FileInfo, err error) error {
		if !fileInfo.IsDir() {
			newPath := strings.Replace(tempPath, t.TempDir()+"/", "", 1)
			newPath = strings.Replace(newPath, AbsPathPlaceholder+"/", "/", 1)
			newPathDir := filepath.Dir(newPath)
			if _, err := os.Stat(newPathDir); os.IsNotExist(err) {
				os.MkdirAll(newPathDir, 0777)
			}
			Debug.Println("Moving: ", tempPath, " -> ", newPath)
			renameErr := os.Rename(tempPath, newPath)
			CheckWithMsg(renameErr, "Could not rename file "+tempPath+" to "+newPath)
		}
		return err
	})
	// Remove temporary execution dir
	remErr := os.RemoveAll(t.TempDir())
	CheckWithMsg(remErr, "Could not remove temp dir: "+t.TempDir())
}

// TempDir returns a string that is unique to a task, suitable for use
// in file paths. It is built up by merging all input filenames and parameter
// values that a task takes as input, joined with dots.
func (t *Task) TempDir() string {
	pathPcs := []string{"tmp." + t.Name}
	for _, ipName := range sortedFileIPMapKeys(t.InIPs) {
		pathPcs = append(pathPcs, filepath.Base(t.InIP(ipName).Path()))
	}
	for _, paramName := range sortedStringMapKeys(t.Params) {
		pathPcs = append(pathPcs, paramName+"_"+t.Param(paramName))
	}
	for _, tagName := range sortedStringMapKeys(t.Tags) {
		pathPcs = append(pathPcs, tagName+"_"+t.Tag(tagName))
	}
	pathSegment := strings.Join(pathPcs, ".")
	if len(pathSegment) > 255 {
		sha1sum := sha1.Sum([]byte(pathSegment))
		pathSegment = t.Name + "." + hex.EncodeToString(sha1sum[:])
	}
	return pathSegment
}

func parentDirPath(path string) string {
	if path[0] == '/' {
		return path
	}
	// For relative paths, add ".." to get out of current dir
	return "../" + path
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"github.com/olekukonko/tablewriter"
	sf "github.com/snowflakedb/gosnowflake"
	"log"
	"os"
	"strings"
	"time"
)

// Specific for Snowflake db
const (
	loginTimeout  = 5 * time.Second                // by default is 60
	multiStmtName = "multiple statement execution" // https://github.com/snowflakedb/gosnowflake/blob/e909f00ff624a7e60d4f91718f6adc92cbd0d80f/connection.go#L57-L61
)

type SnowFlakeTarget struct {
	Target
	Client *sql.DB
}

func (sft SnowFlakeTarget) IsConnectable() bool {
	client := sft.Client
	err := client.Ping()
	return err == nil
}

func NewSnowflakeTarget(target Target) *SnowFlakeTarget {
	// Note: region connection parameter is deprecated
	var region string
	if target.Region == "us-west-1" {
		region = ""
	} else {
		region = target.Region
	}

	configStr, err := sf.DSN(&sf.Config{
		Region:       region,
		Account:      target.Account,
		User:         target.Username,
		Password:     target.Password,
		Database:     target.Database,
		Warehouse:    target.Warehouse,
		LoginTimeout: loginTimeout,
	})

	if err != nil {
		log.Fatal(err)
	}

	db, err := sql.Open("snowflake", configStr)

	if err != nil {
		log.Fatal(err)
	}

	return &SnowFlakeTarget{target, db}
}

func (sft SnowFlakeTarget) GetTarget() Target {
	return sft.Target
}

// Run a query against the target
func (sft SnowFlakeTarget) RunQuery(query ReadyQuery, dryRun bool, showQueryOutput bool) QueryStatus {
	var affected int64 = 0
	var err error

	if dryRun {
		if sft.IsConnectable() {
			log.Printf("SUCCESS: Able to connect to target database, %s\n.", sft.Account)
		} else {
			log.Printf("ERROR: Cannot connect to target database, %s\n.", sft.Account)
		}

		return QueryStatus{query, query.Path, 0, nil}
	}

	// 0 allows arbitrary number of statements
	ctx, _ := sf.WithMultiStatement(context.Background(), 0)
	script := query.Script

	if len(strings.TrimSpace(script)) > 0 {
		if showQueryOutput {
			rows, err := sft.Client.QueryContext(ctx, script)
			if err != nil {
				return QueryStatus{query, query.Path, int(affected), err}
			}
			defer rows.Close()

			err = printSfTable(rows)
			if err != nil {
				log.Printf("ERROR: %s.", err)
				return QueryStatus{query, query.Path, int(affected), err}
			}

			for rows.NextResultSet() {
				err = printSfTable(rows)
				if err != nil {
					log.Printf("ERROR: %s.", err)
					return QueryStatus{query, query.Path, int(affected), err}
				}
			}
		} else {
			res, err := sft.Client.ExecContext(ctx, script)
			if err != nil {
				return QueryStatus{query, query.Path, int(affected), err}
			}

			aff, _ := res.RowsAffected()
			affected += aff
		}
	}

	return QueryStatus{query, query.Path, int(affected), err}
}

func printSfTable(rows *sql.Rows) error {
	outputBuffer := make([][]string, 0, 10)
	cols, err := rows.Columns()
	if err != nil {
		return errors.New("Unable to read columns")
	}

	// check to prevent rows.Next() on multi-statement
	// see also: https://github.com/snowflakedb/gosnowflake/issues/365
	for _, c := range cols {
		if c == multiStmtName {
			return errors.New("Unable to showQueryOutput for multi-statement queries")
		}
	}

	vals := make([]interface{}, len(cols))
	for i := range cols {
		vals[i] = new(sql.RawBytes)
	}

	for rows.Next() {
		err = rows.Scan(vals...)
		if err != nil {
			return errors.New("Unable to read row")
		}

		if len(vals) > 0 {
			outputBuffer = append(outputBuffer, stringify(vals))
		}
	}

	if len(outputBuffer) > 0 {
		log.Printf("QUERY OUTPUT:\n")
		table := tablewriter.NewWriter(os.Stdout)
		table.SetHeader(cols)
		table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
		table.SetCenterSeparator("|")

		for _, row := range outputBuffer {
			table.Append(row)
		}

		table.Render() // Send output
	}
	return nil
}

func stringify(row []interface{}) []string {
	var line []string
	for _, element := range row {
		line = append(line, fmt.Sprint(element))
	}
	return line
}
<commit_msg>Snowflake: convert query output to string before printing (closes #166)<commit_after>package main

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"github.com/olekukonko/tablewriter"
	sf "github.com/snowflakedb/gosnowflake"
	"log"
	"os"
	"strings"
	"time"
)

// Specific for Snowflake db
const (
	loginTimeout  = 5 * time.Second                // by default is 60
	multiStmtName = "multiple statement execution" // https://github.com/snowflakedb/gosnowflake/blob/e909f00ff624a7e60d4f91718f6adc92cbd0d80f/connection.go#L57-L61
)

type SnowFlakeTarget struct {
	Target
	Client *sql.DB
}

func (sft SnowFlakeTarget) IsConnectable() bool {
	client := sft.Client
	err := client.Ping()
	return err == nil
}

func NewSnowflakeTarget(target Target) *SnowFlakeTarget {
	// Note: region connection parameter is deprecated
	var region string
	if target.Region == "us-west-1" {
		region = ""
	} else {
		region = target.Region
	}

	configStr, err := sf.DSN(&sf.Config{
		Region:       region,
		Account:      target.Account,
		User:         target.Username,
		Password:     target.Password,
		Database:     target.Database,
		Warehouse:    target.Warehouse,
		LoginTimeout: loginTimeout,
	})

	if err != nil {
		log.Fatal(err)
	}

	db, err := sql.Open("snowflake", configStr)

	if err != nil {
		log.Fatal(err)
	}

	return &SnowFlakeTarget{target, db}
}

func (sft SnowFlakeTarget) GetTarget() Target {
	return sft.Target
}

// Run a query against the target
func (sft SnowFlakeTarget) RunQuery(query ReadyQuery, dryRun bool, showQueryOutput bool) QueryStatus {
	var affected int64 = 0
	var err error

	if dryRun {
		if sft.IsConnectable() {
			log.Printf("SUCCESS: Able to connect to target database, %s\n.", sft.Account)
		} else {
			log.Printf("ERROR: Cannot connect to target database, %s\n.", sft.Account)
		}

		return QueryStatus{query, query.Path, 0, nil}
	}

	// 0 allows arbitrary number of statements
	ctx, _ := sf.WithMultiStatement(context.Background(), 0)
	script := query.Script

	if len(strings.TrimSpace(script)) > 0 {
		if showQueryOutput {
			rows, err := sft.Client.QueryContext(ctx, script)
			if err != nil {
				return QueryStatus{query, query.Path, int(affected), err}
			}
			defer rows.Close()

			err = printSfTable(rows)
			if err != nil {
				log.Printf("ERROR: %s.", err)
				return QueryStatus{query, query.Path, int(affected), err}
			}

			for rows.NextResultSet() {
				err = printSfTable(rows)
				if err != nil {
					log.Printf("ERROR: %s.", err)
					return QueryStatus{query, query.Path, int(affected), err}
				}
			}
		} else {
			res, err := sft.Client.ExecContext(ctx, script)
			if err != nil {
				return QueryStatus{query, query.Path, int(affected), err}
			}

			aff, _ := res.RowsAffected()
			affected += aff
		}
	}

	return QueryStatus{query, query.Path, int(affected), err}
}

func printSfTable(rows *sql.Rows) error {
	outputBuffer := make([][]string, 0, 10)
	cols, err := rows.Columns()
	if err != nil {
		return errors.New("Unable to read columns")
	}

	// check to prevent rows.Next() on multi-statement
	// see also: https://github.com/snowflakedb/gosnowflake/issues/365
	for _, c := range cols {
		if c == multiStmtName {
			return errors.New("Unable to showQueryOutput for multi-statement queries")
		}
	}

	vals := make([]interface{}, len(cols))
	rawResult := make([][]byte, len(cols))
	for i := range rawResult {
		vals[i] = &rawResult[i]
	}

	for rows.Next() {
		err = rows.Scan(vals...)
		if err != nil {
			return errors.New("Unable to read row")
		}

		if len(vals) > 0 {
			outputBuffer = append(outputBuffer, stringify(rawResult))
		}
	}

	if len(outputBuffer) > 0 {
		log.Printf("QUERY OUTPUT:\n")
		table := tablewriter.NewWriter(os.Stdout)
		table.SetHeader(cols)
		table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
		table.SetCenterSeparator("|")

		for _, row := range outputBuffer {
			table.Append(row)
		}

		table.Render() // Send output
	}
	return nil
}

func stringify(row [][]byte) []string {
	var line []string
	for _, element := range row {
		line = append(line, fmt.Sprint(string(element)))
	}
	return line
}
<|endoftext|>


<commit_before>package hdf5

// #include "hdf5.h"
// #include "hdf5_hl.h"
// #include <stdlib.h>
// #include <string.h>
import "C"

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"
)

// Table is an hdf5 packet-table.
type Table struct {
	Location
}

func newPacketTable(id C.hid_t) *Table {
	t := &Table{Location{Identifier{id}}}
	runtime.SetFinalizer(t, (*Table).finalizer)
	return t
}

func (t *Table) finalizer() {
	if err := t.Close(); err != nil {
		panic(fmt.Errorf("error closing packet table: %s", err))
	}
}

// Close closes an open packet table.
func (t *Table) Close() error {
	if t.id > 0 {
		err := h5err(C.H5PTclose(t.id))
		if err != nil {
			t.id = 0
		}
		return err
	}
	return nil
}

// IsValid returns whether or not an indentifier points to a packet table.
func (t *Table) IsValid() bool {
	return C.H5PTis_valid(t.id) >= 0
}

func (t *Table) Id() int {
	return int(t.id)
}

// ReadPackets reads a number of packets from a packet table.
func (t *Table) ReadPackets(start, nrecords int, data interface{}) error {
	c_start := C.hsize_t(start)
	c_nrecords := C.size_t(nrecords)
	rv := reflect.Indirect(reflect.ValueOf(data))
	rt := rv.Type()
	c_data := unsafe.Pointer(nil)
	switch rt.Kind() {
	case reflect.Array:
		if rv.Len() < nrecords {
			panic(fmt.Errorf("not enough capacity in array (cap=%d)", rv.Len()))
		}
		c_data = unsafe.Pointer(rv.Index(0).UnsafeAddr())

	case reflect.Slice:
		if rv.Len() < nrecords {
			panic(fmt.Errorf("not enough capacity in slice (cap=%d)", rv.Len()))
		}
		slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(slice.Data)

	default:
		panic(fmt.Errorf("unhandled kind (%s), need slice or array", rt.Kind()))
	}
	err := C.H5PTread_packets(t.id, c_start, c_nrecords, c_data)
	return h5err(err)
}

// Append appends packets to the end of a packet table.
func (t *Table) Append(data interface{}) error {
	rv := reflect.Indirect(reflect.ValueOf(data))
	rt := rv.Type()
	c_nrecords := C.size_t(0)
	c_data := unsafe.Pointer(nil)

	switch rt.Kind() {

	case reflect.Array:
		c_nrecords = C.size_t(rv.Len())
		c_data = unsafe.Pointer(rv.UnsafeAddr())

	case reflect.Slice:
		c_nrecords = C.size_t(rv.Len())
		slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(slice.Data)

	case reflect.String:
		c_nrecords = C.size_t(rv.Len())
		str := (*reflect.StringHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(str.Data)

	case reflect.Ptr:
		c_nrecords = C.size_t(1)
		c_data = unsafe.Pointer(rv.Elem().UnsafeAddr())

	default:
		c_nrecords = C.size_t(1)
		c_data = unsafe.Pointer(rv.UnsafeAddr())
	}

	err := C.H5PTappend(t.id, c_nrecords, c_data)
	return h5err(err)
}

// Next reads packets from a packet table starting at the current index.
func (t *Table) Next(data interface{}) error {
	rt := reflect.TypeOf(data)
	rv := reflect.ValueOf(data)
	n := C.size_t(0)
	cdata := unsafe.Pointer(nil)
	switch rt.Kind() {
	case reflect.Array:
		if rv.Cap() <= 0 {
			panic(fmt.Errorf("not enough capacity in array (cap=%d)", rv.Cap()))
		}
		cdata = unsafe.Pointer(rv.Index(0).UnsafeAddr())
		n = C.size_t(rv.Cap())
	case reflect.Slice:
		if rv.Cap() <= 0 {
			panic(fmt.Errorf("not enough capacity in slice (cap=%d)", rv.Cap()))
		}
		cdata = unsafe.Pointer(rv.Index(0).UnsafeAddr())
		n = C.size_t(rv.Cap())
	default:
		panic(fmt.Errorf("unsupported kind (%s), need slice or array", rt.Kind()))
	}
	err := C.H5PTget_next(t.id, n, cdata)
	return h5err(err)
}

// NumPackets returns the number of packets in a packet table.
func (t *Table) NumPackets() (int, error) {
	c_nrecords := C.hsize_t(0)
	err := C.H5PTget_num_packets(t.id, &c_nrecords)
	return int(c_nrecords), h5err(err)
}

// CreateIndex resets a packet table's index to the first packet.
func (t *Table) CreateIndex() error {
	err := C.H5PTcreate_index(t.id)
	return h5err(err)
}

// SetIndex sets a packet table's index.
func (t *Table) SetIndex(index int) error {
	c_idx := C.hsize_t(index)
	err := C.H5PTset_index(t.id, c_idx)
	return h5err(err)
}

// Type returns an identifier for a copy of the datatype for a dataset.
func (t *Table) Type() (*Datatype, error) {
	hid := C.H5Dget_type(t.id)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return NewDatatype(hid), nil
}

func createTable(id C.hid_t, name string, dtype *Datatype, chunkSize, compression int) (*Table, error) {
	c_name := C.CString(name)
	defer C.free(unsafe.Pointer(c_name))

	chunk := C.hsize_t(chunkSize)
	compr := C.int(compression)
	hid := C.H5PTcreate_fl(id, c_name, dtype.id, chunk, compr)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return newPacketTable(hid), nil
}

func createTableFrom(id C.hid_t, name string, dtype interface{}, chunkSize, compression int) (*Table, error) {
	var err error
	switch dt := dtype.(type) {
	case reflect.Type:
		if hdfDtype, err := NewDataTypeFromType(dt); err == nil {
			return createTable(id, name, hdfDtype, chunkSize, compression)
		}
	case *Datatype:
		return createTable(id, name, dt, chunkSize, compression)
	default:
		if hdfDtype, err := NewDataTypeFromType(reflect.TypeOf(dtype)); err == nil {
			return createTable(id, name, hdfDtype, chunkSize, compression)
		}
	}
	return nil, err
}

func openTable(id C.hid_t, name string) (*Table, error) {
	c_name := C.CString(name)
	defer C.free(unsafe.Pointer(c_name))

	hid := C.H5PTopen(id, c_name)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return newPacketTable(hid), nil
}
<commit_msg>h5pt: enforce Table.Next to take a pointer to an array/slice<commit_after>package hdf5

// #include "hdf5.h"
// #include "hdf5_hl.h"
// #include <stdlib.h>
// #include <string.h>
import "C"

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"
)

// Table is an hdf5 packet-table.
type Table struct {
	Location
}

func newPacketTable(id C.hid_t) *Table {
	t := &Table{Location{Identifier{id}}}
	runtime.SetFinalizer(t, (*Table).finalizer)
	return t
}

func (t *Table) finalizer() {
	if err := t.Close(); err != nil {
		panic(fmt.Errorf("error closing packet table: %s", err))
	}
}

// Close closes an open packet table.
func (t *Table) Close() error {
	if t.id > 0 {
		err := h5err(C.H5PTclose(t.id))
		if err != nil {
			t.id = 0
		}
		return err
	}
	return nil
}

// IsValid returns whether or not an indentifier points to a packet table.
func (t *Table) IsValid() bool {
	return C.H5PTis_valid(t.id) >= 0
}

func (t *Table) Id() int {
	return int(t.id)
}

// ReadPackets reads a number of packets from a packet table.
func (t *Table) ReadPackets(start, nrecords int, data interface{}) error {
	c_start := C.hsize_t(start)
	c_nrecords := C.size_t(nrecords)
	rv := reflect.Indirect(reflect.ValueOf(data))
	rt := rv.Type()
	c_data := unsafe.Pointer(nil)
	switch rt.Kind() {
	case reflect.Array:
		if rv.Len() < nrecords {
			panic(fmt.Errorf("not enough capacity in array (cap=%d)", rv.Len()))
		}
		c_data = unsafe.Pointer(rv.Index(0).UnsafeAddr())

	case reflect.Slice:
		if rv.Len() < nrecords {
			panic(fmt.Errorf("not enough capacity in slice (cap=%d)", rv.Len()))
		}
		slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(slice.Data)

	default:
		panic(fmt.Errorf("unhandled kind (%s), need slice or array", rt.Kind()))
	}
	err := C.H5PTread_packets(t.id, c_start, c_nrecords, c_data)
	return h5err(err)
}

// Append appends packets to the end of a packet table.
func (t *Table) Append(data interface{}) error {
	rv := reflect.Indirect(reflect.ValueOf(data))
	rt := rv.Type()
	c_nrecords := C.size_t(0)
	c_data := unsafe.Pointer(nil)

	switch rt.Kind() {

	case reflect.Array:
		c_nrecords = C.size_t(rv.Len())
		c_data = unsafe.Pointer(rv.UnsafeAddr())

	case reflect.Slice:
		c_nrecords = C.size_t(rv.Len())
		slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(slice.Data)

	case reflect.String:
		c_nrecords = C.size_t(rv.Len())
		str := (*reflect.StringHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		c_data = unsafe.Pointer(str.Data)

	case reflect.Ptr:
		c_nrecords = C.size_t(1)
		c_data = unsafe.Pointer(rv.Elem().UnsafeAddr())

	default:
		c_nrecords = C.size_t(1)
		c_data = unsafe.Pointer(rv.UnsafeAddr())
	}

	err := C.H5PTappend(t.id, c_nrecords, c_data)
	return h5err(err)
}

// Next reads packets from a packet table starting at the current index into the value pointed at by data.
// i.e. data is a pointer to an array or a slice.
func (t *Table) Next(data interface{}) error {
	rt := reflect.TypeOf(data)
	if rt.Kind() != reflect.Ptr {
		return fmt.Errorf("hdf5: invalid value type. got=%v, want pointer", rt.Kind())
	}
	rt = rt.Elem()
	rv := reflect.Indirect(reflect.ValueOf(data))

	n := C.size_t(0)
	cdata := unsafe.Pointer(nil)
	switch rt.Kind() {
	case reflect.Array:
		if rv.Cap() <= 0 {
			panic(fmt.Errorf("not enough capacity in array (cap=%d)", rv.Cap()))
		}
		cdata = unsafe.Pointer(rv.UnsafeAddr())
		n = C.size_t(rv.Cap())

	case reflect.Slice:
		if rv.Cap() <= 0 {
			panic(fmt.Errorf("not enough capacity in slice (cap=%d)", rv.Cap()))
		}
		slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr()))
		cdata = unsafe.Pointer(slice.Data)
		n = C.size_t(rv.Cap())

	default:
		panic(fmt.Errorf("unsupported kind (%s), need slice or array", rt.Kind()))
	}
	err := C.H5PTget_next(t.id, n, cdata)
	return h5err(err)
}

// NumPackets returns the number of packets in a packet table.
func (t *Table) NumPackets() (int, error) {
	c_nrecords := C.hsize_t(0)
	err := C.H5PTget_num_packets(t.id, &c_nrecords)
	return int(c_nrecords), h5err(err)
}

// CreateIndex resets a packet table's index to the first packet.
func (t *Table) CreateIndex() error {
	err := C.H5PTcreate_index(t.id)
	return h5err(err)
}

// SetIndex sets a packet table's index.
func (t *Table) SetIndex(index int) error {
	c_idx := C.hsize_t(index)
	err := C.H5PTset_index(t.id, c_idx)
	return h5err(err)
}

// Type returns an identifier for a copy of the datatype for a dataset.
func (t *Table) Type() (*Datatype, error) {
	hid := C.H5Dget_type(t.id)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return NewDatatype(hid), nil
}

func createTable(id C.hid_t, name string, dtype *Datatype, chunkSize, compression int) (*Table, error) {
	c_name := C.CString(name)
	defer C.free(unsafe.Pointer(c_name))

	chunk := C.hsize_t(chunkSize)
	compr := C.int(compression)
	hid := C.H5PTcreate_fl(id, c_name, dtype.id, chunk, compr)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return newPacketTable(hid), nil
}

func createTableFrom(id C.hid_t, name string, dtype interface{}, chunkSize, compression int) (*Table, error) {
	var err error
	switch dt := dtype.(type) {
	case reflect.Type:
		if hdfDtype, err := NewDataTypeFromType(dt); err == nil {
			return createTable(id, name, hdfDtype, chunkSize, compression)
		}
	case *Datatype:
		return createTable(id, name, dt, chunkSize, compression)
	default:
		if hdfDtype, err := NewDataTypeFromType(reflect.TypeOf(dtype)); err == nil {
			return createTable(id, name, hdfDtype, chunkSize, compression)
		}
	}
	return nil, err
}

func openTable(id C.hid_t, name string) (*Table, error) {
	c_name := C.CString(name)
	defer C.free(unsafe.Pointer(c_name))

	hid := C.H5PTopen(id, c_name)
	if err := checkID(hid); err != nil {
		return nil, err
	}
	return newPacketTable(hid), nil
}
<|endoftext|>


<commit_before>package task

import (
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strings"
	"text/tabwriter"

	"github.com/go-task/task/v3/internal/logger"
	"github.com/go-task/task/v3/taskfile"
)

// ListTasksWithDesc reports tasks that have a description spec.
func (e *Executor) ListTasksWithDesc() {
	e.printTasks(false)
}

// ListAllTasks reports all tasks, with or without a description spec.
func (e *Executor) ListAllTasks() {
	e.printTasks(true)
}

func (e *Executor) printTasks(listAll bool) {
	var tasks []*taskfile.Task
	if listAll {
		tasks = e.allTaskNames()
	} else {
		tasks = e.tasksWithDesc()
	}

	if len(tasks) == 0 {
		if listAll {
			e.Logger.Outf(logger.Yellow, "task: No tasks available")
		} else {
			e.Logger.Outf(logger.Yellow, "task: No tasks with description available. Try --list-all to list all tasks")
		}
		return
	}
	e.Logger.Outf(logger.Default, "task: Available tasks for this project:")

	// Format in tab-separated columns with a tab stop of 8.
	w := tabwriter.NewWriter(e.Stdout, 0, 8, 0, '\t', 0)
	for _, task := range tasks {
		fmt.Fprintf(w, "* %s: \t%s\n", task.Name(), task.Desc)
	}
	w.Flush()
}

func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
	tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
	for _, task := range e.Taskfile.Tasks {
		if !task.Internal {
			tasks = append(tasks, task)
		}
	}
	sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
	return
}

func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
	tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
	for _, task := range e.Taskfile.Tasks {
		if !task.Internal && task.Desc != "" {
			compiledTask, err := e.FastCompiledTask(taskfile.Call{Task: task.Task})
			if err == nil {
				task = compiledTask
			}
			tasks = append(tasks, task)
		}
	}
	sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
	return
}

// PrintTaskNames prints only the task names in a Taskfile.
// Only tasks with a non-empty description are printed if allTasks is false.
// Otherwise, all task names are printed.
func (e *Executor) ListTaskNames(allTasks bool) {
	// if called from cmd/task.go, e.Taskfile has not yet been parsed
	if e.Taskfile == nil {
		if err := e.readTaskfile(); err != nil {
			log.Fatal(err)
			return
		}
	}
	// use stdout if no output defined
	var w io.Writer = os.Stdout
	if e.Stdout != nil {
		w = e.Stdout
	}
	// create a string slice from all map values (*taskfile.Task)
	s := make([]string, 0, len(e.Taskfile.Tasks))
	for _, t := range e.Taskfile.Tasks {
		if (allTasks || t.Desc != "") && !t.Internal {
			s = append(s, strings.TrimRight(t.Task, ":"))
		}
	}
	// sort and print all task names
	sort.Strings(s)
	for _, t := range s {
		fmt.Fprintln(w, t)
	}
}
<commit_msg>Fix task names for `--list` and `--list-all`<commit_after>package task

import (
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strings"
	"text/tabwriter"

	"github.com/go-task/task/v3/internal/logger"
	"github.com/go-task/task/v3/taskfile"
)

// ListTasksWithDesc reports tasks that have a description spec.
func (e *Executor) ListTasksWithDesc() {
	e.printTasks(false)
}

// ListAllTasks reports all tasks, with or without a description spec.
func (e *Executor) ListAllTasks() {
	e.printTasks(true)
}

func (e *Executor) printTasks(listAll bool) {
	var tasks []*taskfile.Task
	if listAll {
		tasks = e.allTaskNames()
	} else {
		tasks = e.tasksWithDesc()
	}

	if len(tasks) == 0 {
		if listAll {
			e.Logger.Outf(logger.Yellow, "task: No tasks available")
		} else {
			e.Logger.Outf(logger.Yellow, "task: No tasks with description available. Try --list-all to list all tasks")
		}
		return
	}
	e.Logger.Outf(logger.Default, "task: Available tasks for this project:")

	// Format in tab-separated columns with a tab stop of 8.
	w := tabwriter.NewWriter(e.Stdout, 0, 8, 0, '\t', 0)
	for _, task := range tasks {
		fmt.Fprintf(w, "* %s: \t%s\n", task.Task, task.Desc)
	}
	w.Flush()
}

func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
	tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
	for _, task := range e.Taskfile.Tasks {
		if !task.Internal {
			tasks = append(tasks, task)
		}
	}
	sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
	return
}

func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
	tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
	for _, task := range e.Taskfile.Tasks {
		if !task.Internal && task.Desc != "" {
			compiledTask, err := e.FastCompiledTask(taskfile.Call{Task: task.Task})
			if err == nil {
				task = compiledTask
			}
			tasks = append(tasks, task)
		}
	}
	sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
	return
}

// PrintTaskNames prints only the task names in a Taskfile.
// Only tasks with a non-empty description are printed if allTasks is false.
// Otherwise, all task names are printed.
func (e *Executor) ListTaskNames(allTasks bool) {
	// if called from cmd/task.go, e.Taskfile has not yet been parsed
	if e.Taskfile == nil {
		if err := e.readTaskfile(); err != nil {
			log.Fatal(err)
			return
		}
	}
	// use stdout if no output defined
	var w io.Writer = os.Stdout
	if e.Stdout != nil {
		w = e.Stdout
	}
	// create a string slice from all map values (*taskfile.Task)
	s := make([]string, 0, len(e.Taskfile.Tasks))
	for _, t := range e.Taskfile.Tasks {
		if (allTasks || t.Desc != "") && !t.Internal {
			s = append(s, strings.TrimRight(t.Task, ":"))
		}
	}
	// sort and print all task names
	sort.Strings(s)
	for _, t := range s {
		fmt.Fprintln(w, t)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strconv"
)

var cmdTest = &Command{
	Usage: "test (all | classname...)",
	Short: "Run apex tests",
	Long: `
Run apex tests

Test Options
  -namespace=<namespace>     Select namespace to run test from

Examples:

  force test all
  force test Test1 Test2 Test3
  force test -namespace=ns Test4
`,
}

func init() {
	cmdTest.Run = runTests
}

var (
	namespaceTestFlag = cmdTest.Flag.String("namespace", "", "namespace to run tests in")
)

func runTests(cmd *Command, args []string) {
	if len(args) < 1 {
		ErrorAndExit("must specify tests to run")
	}
	force, _ := ActiveForce()
	output, err := force.Partner.RunTests(args, *namespaceTestFlag)
	success := false
	if err != nil {
		ErrorAndExit(err.Error())
	} else {
		//working on a better way to do this - catches when no class are found and ran
		if output.NumberRun == 0 {
			fmt.Println("Test classes specified not found")
		} else {
			var percent string
			fmt.Println("Coverage:")
			fmt.Println()
			for index := range output.NumberLocations {
				if output.NumberLocations[index] != 0 {
					percent = strconv.Itoa(((output.NumberLocations[index]-output.NumberLocationsNotCovered[index])/output.NumberLocations[index])*100) + "%"
				} else {
					percent = "0%"
				}
				fmt.Println("  " + percent + "   " + output.Name[index])
			}
			fmt.Println()
			fmt.Println()
			fmt.Println("Results:")
			fmt.Println()
			for index := range output.SMethodNames {
				fmt.Println("  [PASS]  " + output.SClassNames[index] + "::" + output.SMethodNames[index])
			}

			for index := range output.FMethodNames {
				fmt.Println("  [FAIL]  " + output.FClassNames[index] + "::" + output.FMethodNames[index] + ": " + output.FMessage[index])
				fmt.Println("    " + output.FStackTrace[index])
			}
			fmt.Println()
			fmt.Println()

			success = len(output.FMethodNames) == 0
		}

		// Handle notifications
		notifySuccess("test", success)
	}
}
<commit_msg>Add verbose logging to test runs<commit_after>package main

import (
	"fmt"
	"strconv"
)

var cmdTest = &Command{
	Usage: "test (all | classname...)",
	Short: "Run apex tests",
	Long: `
Run apex tests

Test Options
  -namespace=<namespace>     Select namespace to run test from
  -v                         Verbose logging

Examples:

  force test all
  force test Test1 Test2 Test3
  force test -namespace=ns Test4
  force test -v Test1
`,
}

func init() {
	cmdTest.Flag.BoolVar(&verboselogging, "v", false, "set verbose logging")
	cmdTest.Run = runTests
}

var (
	namespaceTestFlag = cmdTest.Flag.String("namespace", "", "namespace to run tests in")
	verboselogging    bool
)

func runTests(cmd *Command, args []string) {
	if len(args) < 1 {
		ErrorAndExit("must specify tests to run")
	}
	force, _ := ActiveForce()
	output, err := force.Partner.RunTests(args, *namespaceTestFlag)
	success := false
	if err != nil {
		ErrorAndExit(err.Error())
	} else {

		if verboselogging {
			fmt.Println(output)
			fmt.Println()
		}
		//working on a better way to do this - catches when no class are found and ran
		if output.NumberRun == 0 {
			fmt.Println("Test classes specified not found")
		} else {
			var percent string
			fmt.Println("Coverage:")
			fmt.Println()
			for index := range output.NumberLocations {
				if output.NumberLocations[index] != 0 {
					percent = strconv.Itoa(((output.NumberLocations[index]-output.NumberLocationsNotCovered[index])/output.NumberLocations[index])*100) + "%"
				} else {
					percent = "0%"
				}
				fmt.Println("  " + percent + "   " + output.Name[index])
			}
			fmt.Println()
			fmt.Println()
			fmt.Println("Results:")
			fmt.Println()
			for index := range output.SMethodNames {
				fmt.Println("  [PASS]  " + output.SClassNames[index] + "::" + output.SMethodNames[index])
			}

			for index := range output.FMethodNames {
				fmt.Println("  [FAIL]  " + output.FClassNames[index] + "::" + output.FMethodNames[index] + ": " + output.FMessage[index])
				fmt.Println("    " + output.FStackTrace[index])
			}
			fmt.Println()
			fmt.Println()

			success = len(output.FMethodNames) == 0
		}

		// Handle notifications
		notifySuccess("test", success)
	}
}
<|endoftext|>


<commit_before>package otp

import (
	"encoding/binary"
	"fmt"
	"math"
	"net/url"
	"strconv"
)

// Hotp is a hotp key
type Hotp struct {
	*otpKey
	Counter int
}

// NewHotp creates a new HOTP key
// keyLen <= 0, defaults to 10
// digits <= 0, defaults to 6
// algorithm == "", defaults to "sha1"
func NewHotp(keyLen int, label, issuer, algorithm string, digits, counter int) (*Hotp, error) {
	k, err := newOtpKey(keyLen, label, issuer, algorithm, digits)
	if err != nil {
		return nil, err
	}
	return &Hotp{otpKey: k, Counter: counter}, nil
}

// NewHotpWithDefaults calls NewHotp with the default values
func NewHotpWithDefaults(label, issuer string) (*Hotp, error) {
	return NewHotp(0, label, issuer, "", 0, 0)
}

func importHotp(k *otpKey, params url.Values) (*Hotp, error) {
	r := &Hotp{otpKey: k}
	// verify counter
	ctr := params.Get("counter")
	if ctr == "" {
		return nil, &Error{ECMissingCounter, "counter parameter is missing", nil}
	}
	if i, err := strconv.Atoi(ctr); err != nil {
		return nil, &Error{ECInvalidCounter, fmt.Sprintf("invalid counter: %v", ctr), nil}
	} else {
		r.Counter = i
	}
	return r, nil
}

// ImportHotp imports an url in the otpauth format
func ImportHotp(u string) (*Hotp, error) {
	// import key
	k, t, p, err := importOtpKey(u)
	if err != nil {
		return nil, err
	}
	// check for HOTP
	if t != TypeHotp {
		return nil, &Error{ECNotHotp, "not a hotp key", nil}
	}
	return importHotp(k, p)
}

// Url returns the key in the otpauth format
func (h *Hotp) Url() string {
	return h.url(TypeHotp, url.Values{"counter": []string{strconv.Itoa(h.Counter)}})
}

// String returns the same as Url()
func (h *Hotp) String() string { return h.Url() }

// Code returns the current code
func (h *Hotp) Code() int {
	c := h.hashTruncateInt(h.Counter)
	return int(binary.BigEndian.Uint32(c)) % int(math.Pow10(h.Digits))
}

// Type returns "hotp"
func (h *Hotp) Type() string { return TypeHotp }
<commit_msg>added CodeCounter function<commit_after>package otp

import (
	"encoding/binary"
	"fmt"
	"math"
	"net/url"
	"strconv"
)

// Hotp is a hotp key
type Hotp struct {
	*otpKey
	Counter int
}

// NewHotp creates a new HOTP key
// keyLen <= 0, defaults to 10
// digits <= 0, defaults to 6
// algorithm == "", defaults to "sha1"
func NewHotp(keyLen int, label, issuer, algorithm string, digits, counter int) (*Hotp, error) {
	k, err := newOtpKey(keyLen, label, issuer, algorithm, digits)
	if err != nil {
		return nil, err
	}
	return &Hotp{otpKey: k, Counter: counter}, nil
}

// NewHotpWithDefaults calls NewHotp with the default values
func NewHotpWithDefaults(label, issuer string) (*Hotp, error) {
	return NewHotp(0, label, issuer, "", 0, 0)
}

func importHotp(k *otpKey, params url.Values) (*Hotp, error) {
	r := &Hotp{otpKey: k}
	// verify counter
	ctr := params.Get("counter")
	if ctr == "" {
		return nil, &Error{ECMissingCounter, "counter parameter is missing", nil}
	}
	if i, err := strconv.Atoi(ctr); err != nil {
		return nil, &Error{ECInvalidCounter, fmt.Sprintf("invalid counter: %v", ctr), nil}
	} else {
		r.Counter = i
	}
	return r, nil
}

// ImportHotp imports an url in the otpauth format
func ImportHotp(u string) (*Hotp, error) {
	// import key
	k, t, p, err := importOtpKey(u)
	if err != nil {
		return nil, err
	}
	// check for HOTP
	if t != TypeHotp {
		return nil, &Error{ECNotHotp, "not a hotp key", nil}
	}
	return importHotp(k, p)
}

// Url returns the key in the otpauth format
func (h *Hotp) Url() string {
	return h.url(TypeHotp, url.Values{"counter": []string{strconv.Itoa(h.Counter)}})
}

// String returns the same as Url()
func (h *Hotp) String() string { return h.Url() }

// Code returns the current code
func (h *Hotp) Code() int { return h.codeCounter(h.Counter) }

// CodeCounter returns the code for the counter c
func (h *Hotp) CodeCounter(c int) int { return h.codeCounter(c) }

// returns the code for counter c
func (h *Hotp) codeCounter(c int) int {
	return int(binary.BigEndian.Uint32(h.hashTruncateInt(c))) % int(math.Pow10(h.Digits))
}

// Type returns "hotp"
func (h *Hotp) Type() string { return TypeHotp }
<|endoftext|>


<commit_before>package deploy

import "testing"

func TestIsEncrypted(t *testing.T) {
	tests := []struct {
		input string
		want  bool
	}{
		{
			``,
			false,
		},
		{
			`{}`,
			false,
		},
		{
			`{"cipher"}`,
			false,
		},
		{
			`{"cipher": "hoge"}`,
			true,
		},
		{
			`{"cipher":{}}`,
			false,
		},
	}

	for _, test := range tests {
		got := isEncrypted([]byte(test.input))
		if got != test.want {
			t.Fatalf("want %q, but %q:", test.want, got)
		}
	}
}
<commit_msg>test case追加<commit_after>package deploy

import "testing"

func TestIsEncrypted(t *testing.T) {
	tests := []struct {
		input string
		want  bool
	}{
		{
			``,
			false,
		},
		{
			`{}`,
			false,
		},
		{
			`{"cipher"}`,
			false,
		},
		{
			`{"cipher": "hoge"}`,
			true,
		},
		{
			`{"cipher":{}}`,
			false,
		},
		{
			`{"hoge":"huga"}`,
			false,
		},
		{
			`{"hoge":"huga", "cipher": "hoge"}`,
			true,
		},
	}

	for _, test := range tests {
		got := isEncrypted([]byte(test.input))
		if got != test.want {
			t.Fatalf("want %q, but %q:", test.want, got)
		}
	}
}
<|endoftext|>


<commit_before>package htcat

import (
	"bufio"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"sync"
)

const (
	_        = iota
	kB int64 = 1 << (10 * iota)
	mB
	gB
	tB
	pB
	eB
)

type HtCat struct {
	io.WriterTo
	d  defrag
	u  *url.URL
	cl *http.Client

	// Protect httpFragGen with a Mutex.
	httpFragGenMu sync.Mutex
	hfg           httpFragGen
}

type HttpStatusError struct {
	error
	Status string
}

func (cat *HtCat) startup(parallelism int) {
	req := http.Request{
		Method:     "GET",
		URL:        cat.u,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Body:       nil,
		Host:       cat.u.Host,
	}

	resp, err := cat.cl.Do(&req)
	if err != nil {
		go cat.d.cancel(err)
		return
	}

	// Check for non-200 OK response codes from the startup-GET.
	if resp.Status != "200 OK" {
		err = HttpStatusError{
			error: fmt.Errorf(
				"Expected HTTP Status 200, received: %q",
				resp.Status),
			Status: resp.Status}
		go cat.d.cancel(err)
		return
	}

	l := resp.Header.Get("Content-Length")

	// Some kinds of small or indeterminate-length files will
	// receive no parallelism.  This procedure helps prepare the
	// HtCat value for a one-HTTP-Request GET.
	noParallel := func(wtc writerToCloser) {
		f := cat.d.nextFragment()
		cat.d.setLast(cat.d.lastAllocated())
		f.contents = wtc
		cat.d.register(f)
	}

	if l == "" {
		// No Content-Length, stream without parallelism nor
		// assumptions about the length of the stream.
		go noParallel(struct {
			io.WriterTo
			io.Closer
		}{
			WriterTo: bufio.NewReader(resp.Body),
			Closer:   resp.Body,
		})
		return
	}

	length, err := strconv.ParseInt(l, 10, 64)
	if err != nil {
		// Invalid integer for Content-Length, defer reporting
		// the error until a WriteTo call is made.
		go cat.d.cancel(err)
		return
	}

	// Set up httpFrag generator state.
	cat.hfg.totalSize = length
	cat.hfg.targetFragSize = length / int64(parallelism)
	if cat.hfg.targetFragSize > 20*mB {
		cat.hfg.targetFragSize = 20 * mB
	}

	// Very small fragments are probably not worthwhile to start
	// up new requests for, but it in this case it was possible to
	// ascertain the size, so take advantage of that to start
	// reading in the background as eagerly as possible.
	if cat.hfg.targetFragSize < 1*mB {
		cat.hfg.curPos = cat.hfg.totalSize
		er := newEagerReader(resp.Body, cat.hfg.totalSize)
		go noParallel(er)
		go er.WaitClosed()
		return
	}

	// None of the other special short-circuit cases have been
	// triggered, so begin preparation for full-blown parallel
	// GET.  One GET worker is started here to take advantage of
	// the already pending response (which has no determinate
	// length, so it must be limited).
	hf := cat.nextFragment()
	go func() {
		er := newEagerReader(
			struct {
				io.Reader
				io.Closer
			}{
				Reader: io.LimitReader(resp.Body, hf.size),
				Closer: resp.Body,
			},
			hf.size)

		hf.fragment.contents = er
		cat.d.register(hf.fragment)
		er.WaitClosed()

		// Chain into being a regular worker, having finished
		// the special start-up segment.
		cat.get()
	}()
}

func New(client *http.Client, u *url.URL, parallelism int) *HtCat {
	cat := HtCat{
		u:  u,
		cl: client,
	}

	cat.d.initDefrag()
	cat.WriterTo = &cat.d
	cat.startup(parallelism)

	if cat.hfg.curPos == cat.hfg.totalSize {
		return &cat
	}

	// Start background workers.
	//
	// "startup" starts one worker that is specially constructed
	// to deal with the first request, so back off by one to
	// prevent performing with too much parallelism.
	for i := 1; i < parallelism; i += 1 {
		go cat.get()
	}

	return &cat
}

func (cat *HtCat) nextFragment() *httpFrag {
	cat.httpFragGenMu.Lock()
	defer cat.httpFragGenMu.Unlock()

	var hf *httpFrag

	if cat.hfg.hasNext() {
		f := cat.d.nextFragment()
		hf = cat.hfg.nextFragment(f)
	} else {
		cat.d.setLast(cat.d.lastAllocated())
	}

	return hf
}

func (cat *HtCat) get() {
	for {
		hf := cat.nextFragment()
		if hf == nil {
			return
		}

		req := http.Request{
			Method:     "GET",
			URL:        cat.u,
			Proto:      "HTTP/1.1",
			ProtoMajor: 1,
			ProtoMinor: 1,
			Header:     hf.header,
			Body:       nil,
			Host:       cat.u.Host,
		}

		resp, err := cat.cl.Do(&req)
		if err != nil {
			cat.d.cancel(err)
			return
		}

		// Check for an acceptable HTTP status code.
		if !(resp.Status == "206 Partial Content" ||
			resp.Status == "200 OK") {
			err = HttpStatusError{
				error: fmt.Errorf("Expected HTTP Status "+
					"206 or 200, received: %q",
					resp.Status),
				Status: resp.Status}
			go cat.d.cancel(err)
			return
		}

		er := newEagerReader(resp.Body, hf.size)
		hf.fragment.contents = er
		cat.d.register(hf.fragment)
		er.WaitClosed()
	}
}
<commit_msg>Round up target fragment size to avoid tiny tail-end request<commit_after>package htcat

import (
	"bufio"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"sync"
)

const (
	_        = iota
	kB int64 = 1 << (10 * iota)
	mB
	gB
	tB
	pB
	eB
)

type HtCat struct {
	io.WriterTo
	d  defrag
	u  *url.URL
	cl *http.Client

	// Protect httpFragGen with a Mutex.
	httpFragGenMu sync.Mutex
	hfg           httpFragGen
}

type HttpStatusError struct {
	error
	Status string
}

func (cat *HtCat) startup(parallelism int) {
	req := http.Request{
		Method:     "GET",
		URL:        cat.u,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Body:       nil,
		Host:       cat.u.Host,
	}

	resp, err := cat.cl.Do(&req)
	if err != nil {
		go cat.d.cancel(err)
		return
	}

	// Check for non-200 OK response codes from the startup-GET.
	if resp.Status != "200 OK" {
		err = HttpStatusError{
			error: fmt.Errorf(
				"Expected HTTP Status 200, received: %q",
				resp.Status),
			Status: resp.Status}
		go cat.d.cancel(err)
		return
	}

	l := resp.Header.Get("Content-Length")

	// Some kinds of small or indeterminate-length files will
	// receive no parallelism.  This procedure helps prepare the
	// HtCat value for a one-HTTP-Request GET.
	noParallel := func(wtc writerToCloser) {
		f := cat.d.nextFragment()
		cat.d.setLast(cat.d.lastAllocated())
		f.contents = wtc
		cat.d.register(f)
	}

	if l == "" {
		// No Content-Length, stream without parallelism nor
		// assumptions about the length of the stream.
		go noParallel(struct {
			io.WriterTo
			io.Closer
		}{
			WriterTo: bufio.NewReader(resp.Body),
			Closer:   resp.Body,
		})
		return
	}

	length, err := strconv.ParseInt(l, 10, 64)
	if err != nil {
		// Invalid integer for Content-Length, defer reporting
		// the error until a WriteTo call is made.
		go cat.d.cancel(err)
		return
	}

	// Set up httpFrag generator state.
	cat.hfg.totalSize = length
	cat.hfg.targetFragSize = 1 + ((length - 1) / int64(parallelism))
	if cat.hfg.targetFragSize > 20*mB {
		cat.hfg.targetFragSize = 20 * mB
	}

	// Very small fragments are probably not worthwhile to start
	// up new requests for, but it in this case it was possible to
	// ascertain the size, so take advantage of that to start
	// reading in the background as eagerly as possible.
	if cat.hfg.targetFragSize < 1*mB {
		cat.hfg.curPos = cat.hfg.totalSize
		er := newEagerReader(resp.Body, cat.hfg.totalSize)
		go noParallel(er)
		go er.WaitClosed()
		return
	}

	// None of the other special short-circuit cases have been
	// triggered, so begin preparation for full-blown parallel
	// GET.  One GET worker is started here to take advantage of
	// the already pending response (which has no determinate
	// length, so it must be limited).
	hf := cat.nextFragment()
	go func() {
		er := newEagerReader(
			struct {
				io.Reader
				io.Closer
			}{
				Reader: io.LimitReader(resp.Body, hf.size),
				Closer: resp.Body,
			},
			hf.size)

		hf.fragment.contents = er
		cat.d.register(hf.fragment)
		er.WaitClosed()

		// Chain into being a regular worker, having finished
		// the special start-up segment.
		cat.get()
	}()
}

func New(client *http.Client, u *url.URL, parallelism int) *HtCat {
	cat := HtCat{
		u:  u,
		cl: client,
	}

	cat.d.initDefrag()
	cat.WriterTo = &cat.d
	cat.startup(parallelism)

	if cat.hfg.curPos == cat.hfg.totalSize {
		return &cat
	}

	// Start background workers.
	//
	// "startup" starts one worker that is specially constructed
	// to deal with the first request, so back off by one to
	// prevent performing with too much parallelism.
	for i := 1; i < parallelism; i += 1 {
		go cat.get()
	}

	return &cat
}

func (cat *HtCat) nextFragment() *httpFrag {
	cat.httpFragGenMu.Lock()
	defer cat.httpFragGenMu.Unlock()

	var hf *httpFrag

	if cat.hfg.hasNext() {
		f := cat.d.nextFragment()
		hf = cat.hfg.nextFragment(f)
	} else {
		cat.d.setLast(cat.d.lastAllocated())
	}

	return hf
}

func (cat *HtCat) get() {
	for {
		hf := cat.nextFragment()
		if hf == nil {
			return
		}

		req := http.Request{
			Method:     "GET",
			URL:        cat.u,
			Proto:      "HTTP/1.1",
			ProtoMajor: 1,
			ProtoMinor: 1,
			Header:     hf.header,
			Body:       nil,
			Host:       cat.u.Host,
		}

		resp, err := cat.cl.Do(&req)
		if err != nil {
			cat.d.cancel(err)
			return
		}

		// Check for an acceptable HTTP status code.
		if !(resp.Status == "206 Partial Content" ||
			resp.Status == "200 OK") {
			err = HttpStatusError{
				error: fmt.Errorf("Expected HTTP Status "+
					"206 or 200, received: %q",
					resp.Status),
				Status: resp.Status}
			go cat.d.cancel(err)
			return
		}

		er := newEagerReader(resp.Body, hf.size)
		hf.fragment.contents = er
		cat.d.register(hf.fragment)
		er.WaitClosed()
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
// Revel Framework source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package revel

import (
	"bytes"
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/net/websocket"
)

// Request Revel's HTTP request object structure
type Request struct {
	*http.Request
	ContentType     string
	Format          string // "html", "xml", "json", or "txt"
	AcceptLanguages AcceptLanguages
	Locale          string
	Websocket       *websocket.Conn
}

// Response Revel's HTTP response object structure
type Response struct {
	Status      int
	ContentType string

	Out http.ResponseWriter
}

// NewResponse returns a Revel's HTTP response instance with given instance
func NewResponse(w http.ResponseWriter) *Response {
	return &Response{Out: w}
}

// NewRequest returns a Revel's HTTP request instance with given HTTP instance
func NewRequest(r *http.Request) *Request {
	return &Request{
		Request:         r,
		ContentType:     ResolveContentType(r),
		Format:          ResolveFormat(r),
		AcceptLanguages: ResolveAcceptLanguage(r),
	}
}

// WriteHeader writes the header (for now, just the status code).
// The status may be set directly by the application (c.Response.Status = 501).
// if it isn't, then fall back to the provided status code.
func (resp *Response) WriteHeader(defaultStatusCode int, defaultContentType string) {
	if resp.Status == 0 {
		resp.Status = defaultStatusCode
	}
	if resp.ContentType == "" {
		resp.ContentType = defaultContentType
	}
	resp.Out.Header().Set("Content-Type", resp.ContentType)
	resp.Out.WriteHeader(resp.Status)
}

// ResolveContentType gets the content type.
// e.g. From "multipart/form-data; boundary=--" to "multipart/form-data"
// If none is specified, returns "text/html" by default.
func ResolveContentType(req *http.Request) string {
	contentType := req.Header.Get("Content-Type")
	if contentType == "" {
		return "text/html"
	}
	return strings.ToLower(strings.TrimSpace(strings.Split(contentType, ";")[0]))
}

// ResolveFormat maps the request's Accept MIME type declaration to
// a Request.Format attribute, specifically "html", "xml", "json", or "txt",
// returning a default of "html" when Accept header cannot be mapped to a
// value above.
func ResolveFormat(req *http.Request) string {
	accept := req.Header.Get("accept")

	switch {
	case accept == "",
		strings.HasPrefix(accept, "*/*"), // */
		strings.Contains(accept, "application/xhtml"),
		strings.Contains(accept, "text/html"):
		return "html"
	case strings.Contains(accept, "application/json"),
		strings.Contains(accept, "text/javascript"),
		strings.Contains(accept, "application/javascript"):
		return "json"
	case strings.Contains(accept, "application/xml"),
		strings.Contains(accept, "text/xml"):
		return "xml"
	case strings.Contains(accept, "text/plain"):
		return "txt"
	}

	return "html"
}

// AcceptLanguage is a single language from the Accept-Language HTTP header.
type AcceptLanguage struct {
	Language string
	Quality  float32
}

// AcceptLanguages is collection of sortable AcceptLanguage instances.
type AcceptLanguages []AcceptLanguage

func (al AcceptLanguages) Len() int           { return len(al) }
func (al AcceptLanguages) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al AcceptLanguages) Less(i, j int) bool { return al[i].Quality > al[j].Quality }
func (al AcceptLanguages) String() string {
	output := bytes.NewBufferString("")
	for i, language := range al {
		if _, err := output.WriteString(fmt.Sprintf("%s (%1.1f)", language.Language, language.Quality)); err != nil {
			ERROR.Println("WriteString failed:", err)
		}
		if i != len(al)-1 {
			if _, err := output.WriteString(", "); err != nil {
				ERROR.Println("WriteString failed:", err)
			}
		}
	}
	return output.String()
}

// ResolveAcceptLanguage returns a sorted list of Accept-Language
// header values.
//
// The results are sorted using the quality defined in the header for each
// language range with the most qualified language range as the first
// element in the slice.
//
// See the HTTP header fields specification
// (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) for more details.
func ResolveAcceptLanguage(req *http.Request) AcceptLanguages {
	header := req.Header.Get("Accept-Language")
	if header == "" {
		return nil
	}

	acceptLanguageHeaderValues := strings.Split(header, ",")
	acceptLanguages := make(AcceptLanguages, len(acceptLanguageHeaderValues))

	for i, languageRange := range acceptLanguageHeaderValues {
		if qualifiedRange := strings.Split(languageRange, ";q="); len(qualifiedRange) == 2 {
			quality, error := strconv.ParseFloat(qualifiedRange[1], 32)
			if error != nil {
				WARN.Printf("Detected malformed Accept-Language header quality in '%s', assuming quality is 1", languageRange)
				acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], 1}
			} else {
				acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], float32(quality)}
			}
		} else {
			acceptLanguages[i] = AcceptLanguage{languageRange, 1}
		}
	}

	sort.Sort(acceptLanguages)
	return acceptLanguages
}
<commit_msg>Based on the "extension" of the requested path, returns an appropriate content type<commit_after>// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
// Revel Framework source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package revel

import (
	"bytes"
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/net/websocket"
	"path/filepath"
)

// Request Revel's HTTP request object structure
type Request struct {
	*http.Request
	ContentType     string
	Format          string // "html", "xml", "json", or "txt"
	AcceptLanguages AcceptLanguages
	Locale          string
	Websocket       *websocket.Conn
}

// Response Revel's HTTP response object structure
type Response struct {
	Status      int
	ContentType string

	Out http.ResponseWriter
}

// NewResponse returns a Revel's HTTP response instance with given instance
func NewResponse(w http.ResponseWriter) *Response {
	return &Response{Out: w}
}

// NewRequest returns a Revel's HTTP request instance with given HTTP instance
func NewRequest(r *http.Request) *Request {
	return &Request{
		Request:         r,
		ContentType:     ResolveContentType(r),
		Format:          ResolveFormat(r),
		AcceptLanguages: ResolveAcceptLanguage(r),
	}
}

// WriteHeader writes the header (for now, just the status code).
// The status may be set directly by the application (c.Response.Status = 501).
// if it isn't, then fall back to the provided status code.
func (resp *Response) WriteHeader(defaultStatusCode int, defaultContentType string) {
	if resp.Status == 0 {
		resp.Status = defaultStatusCode
	}
	if resp.ContentType == "" {
		resp.ContentType = defaultContentType
	}
	resp.Out.Header().Set("Content-Type", resp.ContentType)
	resp.Out.WriteHeader(resp.Status)
}

// ResolveContentType gets the content type.
// e.g. From "multipart/form-data; boundary=--" to "multipart/form-data"
// If none is specified, returns "text/html" by default.
func ResolveContentType(req *http.Request) string {
	contentType := req.Header.Get("Content-Type")
	if contentType == "" {
		return "text/html"
	}
	return strings.ToLower(strings.TrimSpace(strings.Split(contentType, ";")[0]))
}

// ResolveFormat maps the request's Accept MIME type declaration to
// a Request.Format attribute, specifically "html", "xml", "json", or "txt",
// returning a default of "html" when Accept header cannot be mapped to a
// value above.
func ResolveFormat(req *http.Request) string {
	ext := strings.ToLower(filepath.Ext(req.URL.Path))
	switch ext {
	case ".html":
		return "html"
	case ".json":
		return "json"
	case ".xml":
		return "xml"
	case ".txt":
		return "txt"
	}

	accept := req.Header.Get("accept")

	switch {
	case accept == "",
		strings.HasPrefix(accept, "*/*"), // */
		strings.Contains(accept, "application/xhtml"),
		strings.Contains(accept, "text/html"):
		return "html"
	case strings.Contains(accept, "application/json"),
		strings.Contains(accept, "text/javascript"),
		strings.Contains(accept, "application/javascript"):
		return "json"
	case strings.Contains(accept, "application/xml"),
		strings.Contains(accept, "text/xml"):
		return "xml"
	case strings.Contains(accept, "text/plain"):
		return "txt"
	}

	return "html"
}

// AcceptLanguage is a single language from the Accept-Language HTTP header.
type AcceptLanguage struct {
	Language string
	Quality  float32
}

// AcceptLanguages is collection of sortable AcceptLanguage instances.
type AcceptLanguages []AcceptLanguage

func (al AcceptLanguages) Len() int           { return len(al) }
func (al AcceptLanguages) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al AcceptLanguages) Less(i, j int) bool { return al[i].Quality > al[j].Quality }
func (al AcceptLanguages) String() string {
	output := bytes.NewBufferString("")
	for i, language := range al {
		if _, err := output.WriteString(fmt.Sprintf("%s (%1.1f)", language.Language, language.Quality)); err != nil {
			ERROR.Println("WriteString failed:", err)
		}
		if i != len(al)-1 {
			if _, err := output.WriteString(", "); err != nil {
				ERROR.Println("WriteString failed:", err)
			}
		}
	}
	return output.String()
}

// ResolveAcceptLanguage returns a sorted list of Accept-Language
// header values.
//
// The results are sorted using the quality defined in the header for each
// language range with the most qualified language range as the first
// element in the slice.
//
// See the HTTP header fields specification
// (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) for more details.
func ResolveAcceptLanguage(req *http.Request) AcceptLanguages {
	header := req.Header.Get("Accept-Language")
	if header == "" {
		return nil
	}

	acceptLanguageHeaderValues := strings.Split(header, ",")
	acceptLanguages := make(AcceptLanguages, len(acceptLanguageHeaderValues))

	for i, languageRange := range acceptLanguageHeaderValues {
		if qualifiedRange := strings.Split(languageRange, ";q="); len(qualifiedRange) == 2 {
			quality, error := strconv.ParseFloat(qualifiedRange[1], 32)
			if error != nil {
				WARN.Printf("Detected malformed Accept-Language header quality in '%s', assuming quality is 1", languageRange)
				acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], 1}
			} else {
				acceptLanguages[i] = AcceptLanguage{qualifiedRange[0], float32(quality)}
			}
		} else {
			acceptLanguages[i] = AcceptLanguage{languageRange, 1}
		}
	}

	sort.Sort(acceptLanguages)
	return acceptLanguages
}
<|endoftext|>


<commit_before>package main

import (
)

// Store a geolocation
type Location struct {
  lat float64
  long float64
}

// Helper function to take care of errors
func handleErrors(err error) {
  if err != nil {
    panic(err)
  }
}

// Haversine distance computation
// Takes two locations and returns the distance between the two
func haversineDistance(loc0 Location, loc1 Location) float64 {
  return 42.0
}

// Fetches location data from a string postcode
func getLocationFromPostcode(postcode string) Location {
  return Location{0, 0}
}

func main() {

}
<commit_msg>Impl. degreesToRadians<commit_after>package main

import (
  "math"
)

// Store a geolocation
type Location struct {
  lat float64
  long float64
}

// Helper function to take care of errors
func handleErrors(err error) {
  if err != nil {
    panic(err)
  }
}

// Converts degrees into radians
func degreesToRadians(degrees float64) float64 {
  for degrees >= 360.0 {
    degrees -= 360
  }

  return degrees * (math.Pi / 180)
}

// Haversine distance computation
// Takes two locations and returns the distance between the two
func haversineDistance(loc0 Location, loc1 Location) float64 {
  return 42.0
}

// Fetches location data from a string postcode
func getLocationFromPostcode(postcode string) Location {
  return Location{0, 0}
}

func main() {

}
<|endoftext|>