<commit_before>package check

import (
	"bufio"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
)

var (
	skipDirs     = []string{"Godeps", "vendor", "third_party"}
	skipSuffixes = []string{".pb.go", ".pb.gw.go", ".generated.go", "bindata.go"}
)

func addSkipDirs(params []string) []string {
	for _, dir := range skipDirs {
		params = append(params, fmt.Sprintf("--skip=%s", dir))
	}
	return params
}

// GoFiles returns a slice of Go filenames
// in a given directory.
func GoFiles(dir string) ([]string, error) {
	var filenames []string
	visit := func(fp string, fi os.FileInfo, err error) error {
		for _, skip := range skipDirs {
			if strings.Contains(fp, fmt.Sprintf("/%s/", skip)) {
				return nil
			}
		}
		if err != nil {
			fmt.Println(err) // can't walk here,
			return nil       // but continue walking elsewhere
		}
		if fi.IsDir() {
			return nil // not a file.  ignore.
		}
		fiName := fi.Name()
		for _, skip := range skipSuffixes {
			if strings.HasSuffix(fiName, skip) {
				return nil
			}
		}
		ext := filepath.Ext(fiName)
		if ext == ".go" {
			filenames = append(filenames, fp)
		}
		return nil
	}

	err := filepath.Walk(dir, visit)

	return filenames, err
}

// lineCount returns the number of lines in a given file
func lineCount(filepath string) (int, error) {
	out, err := exec.Command("wc", "-l", filepath).Output()
	if err != nil {
		return 0, err
	}
	// wc output is like: 999 filename.go
	count, err := strconv.Atoi(strings.Split(strings.TrimSpace(string(out)), " ")[0])
	if err != nil {
		return 0, err
	}

	return count, nil
}

// Error contains the line number and the reason for
// an error output from a command
type Error struct {
	LineNumber  int    `json:"line_number"`
	ErrorString string `json:"error_string"`
}

// FileSummary contains the filename, location of the file
// on GitHub, and all of the errors related to the file
type FileSummary struct {
	Filename string  `json:"filename"`
	FileURL  string  `json:"file_url"`
	Errors   []Error `json:"errors"`
}

// AddError adds an Error to FileSummary
func (fs *FileSummary) AddError(out string) error {
	s := strings.SplitN(out, ":", 2)
	msg := strings.SplitAfterN(s[1], ":", 3)[2]

	e := Error{ErrorString: msg}
	ls := strings.Split(s[1], ":")
	ln, err := strconv.Atoi(ls[0])
	if err != nil {
		return err
	}
	e.LineNumber = ln

	fs.Errors = append(fs.Errors, e)

	return nil
}

// GoTool runs a given go command (for example gofmt, go tool vet)
// on a directory
func GoTool(dir string, filenames, command []string) (float64, []FileSummary, error) {
	params := command[1:]
	params = addSkipDirs(params)
	params = append(params, dir+"/...")

	cmd := exec.Command(command[0], params...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return 0, []FileSummary{}, err
	}

	err = cmd.Start()
	if err != nil {
		return 0, []FileSummary{}, err
	}

	out := bufio.NewScanner(stdout)

	// the same file can appear multiple times out of order
	// in the output, so we can't go line by line, have to store
	// a map of filename to FileSummary
	fsMap := map[string]FileSummary{}
	var failed = []FileSummary{}
outer:
	for out.Scan() {
		filename := strings.Split(out.Text(), ":")[0]
		filename = strings.TrimPrefix(filename, "repos/src")
		for _, skip := range skipSuffixes {
			if strings.HasSuffix(filename, skip) {
				continue outer
			}
		}
		var fileURL string
		base := strings.TrimPrefix(dir, "repos/src/")
		switch {
		case strings.HasPrefix(base, "golang.org/x/"):
			var pkg string
			if len(strings.Split(base, "/")) >= 3 {
				pkg = strings.Split(base, "/")[2]
			}
			fileURL = fmt.Sprintf("https://github.com/golang/%s/blob/master%s", pkg, strings.TrimPrefix(filename, "/"+base))
		default:
			fileURL = fmt.Sprintf("https://%s/blob/master%s", base, strings.TrimPrefix(filename, "/"+base))
		}
		fs := fsMap[filename]
		if fs.Filename == "" {
			fs.Filename = filename
			if strings.HasPrefix(filename, "/github.com") {
				sp := strings.Split(filename, "/")
				if len(sp) > 3 {
					fs.Filename = strings.Join(sp[3:], "/")
				}

			}
			fs.FileURL = fileURL
		}
		err = fs.AddError(out.Text())
		if err != nil {
			return 0, []FileSummary{}, err
		}
		fsMap[filename] = fs
	}
	if err := out.Err(); err != nil {
		return 0, []FileSummary{}, err
	}

	for _, v := range fsMap {
		failed = append(failed, v)
	}

	err = cmd.Wait()
	if exitErr, ok := err.(*exec.ExitError); ok {
		// The program has exited with an exit code != 0

		if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
			// some commands exit 1 when files fail to pass (for example go vet)
			if status.ExitStatus() != 1 {
				return 0, failed, err
				// return 0, Error{}, err
			}
		}
	}

	if len(filenames) == 1 {
		lc, err := lineCount(filenames[0])
		if err != nil {
			return 0, failed, err
		}

		var errors int
		if len(failed) != 0 {
			errors = len(failed[0].Errors)
		}

		return float64(lc-errors) / float64(lc), failed, nil
	}

	return float64(len(filenames)-len(failed)) / float64(len(filenames)), failed, nil
}
<commit_msg>#136 fix links when package is a sub-dir package<commit_after>package check

import (
	"bufio"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
)

var (
	skipDirs     = []string{"Godeps", "vendor", "third_party"}
	skipSuffixes = []string{".pb.go", ".pb.gw.go", ".generated.go", "bindata.go"}
)

func addSkipDirs(params []string) []string {
	for _, dir := range skipDirs {
		params = append(params, fmt.Sprintf("--skip=%s", dir))
	}
	return params
}

// GoFiles returns a slice of Go filenames
// in a given directory.
func GoFiles(dir string) ([]string, error) {
	var filenames []string
	visit := func(fp string, fi os.FileInfo, err error) error {
		for _, skip := range skipDirs {
			if strings.Contains(fp, fmt.Sprintf("/%s/", skip)) {
				return nil
			}
		}
		if err != nil {
			fmt.Println(err) // can't walk here,
			return nil       // but continue walking elsewhere
		}
		if fi.IsDir() {
			return nil // not a file.  ignore.
		}
		fiName := fi.Name()
		for _, skip := range skipSuffixes {
			if strings.HasSuffix(fiName, skip) {
				return nil
			}
		}
		ext := filepath.Ext(fiName)
		if ext == ".go" {
			filenames = append(filenames, fp)
		}
		return nil
	}

	err := filepath.Walk(dir, visit)

	return filenames, err
}

// lineCount returns the number of lines in a given file
func lineCount(filepath string) (int, error) {
	out, err := exec.Command("wc", "-l", filepath).Output()
	if err != nil {
		return 0, err
	}
	// wc output is like: 999 filename.go
	count, err := strconv.Atoi(strings.Split(strings.TrimSpace(string(out)), " ")[0])
	if err != nil {
		return 0, err
	}

	return count, nil
}

// Error contains the line number and the reason for
// an error output from a command
type Error struct {
	LineNumber  int    `json:"line_number"`
	ErrorString string `json:"error_string"`
}

// FileSummary contains the filename, location of the file
// on GitHub, and all of the errors related to the file
type FileSummary struct {
	Filename string  `json:"filename"`
	FileURL  string  `json:"file_url"`
	Errors   []Error `json:"errors"`
}

// AddError adds an Error to FileSummary
func (fs *FileSummary) AddError(out string) error {
	s := strings.SplitN(out, ":", 2)
	msg := strings.SplitAfterN(s[1], ":", 3)[2]

	e := Error{ErrorString: msg}
	ls := strings.Split(s[1], ":")
	ln, err := strconv.Atoi(ls[0])
	if err != nil {
		return err
	}
	e.LineNumber = ln

	fs.Errors = append(fs.Errors, e)

	return nil
}

// GoTool runs a given go command (for example gofmt, go tool vet)
// on a directory
func GoTool(dir string, filenames, command []string) (float64, []FileSummary, error) {
	params := command[1:]
	params = addSkipDirs(params)
	params = append(params, dir+"/...")

	cmd := exec.Command(command[0], params...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return 0, []FileSummary{}, err
	}

	err = cmd.Start()
	if err != nil {
		return 0, []FileSummary{}, err
	}

	out := bufio.NewScanner(stdout)

	// the same file can appear multiple times out of order
	// in the output, so we can't go line by line, have to store
	// a map of filename to FileSummary
	fsMap := map[string]FileSummary{}
	var failed = []FileSummary{}
outer:
	for out.Scan() {
		filename := strings.Split(out.Text(), ":")[0]
		filename = strings.TrimPrefix(filename, "repos/src")
		for _, skip := range skipSuffixes {
			if strings.HasSuffix(filename, skip) {
				continue outer
			}
		}
		var fileURL string
		base := strings.TrimPrefix(dir, "repos/src/")
		switch {
		case strings.HasPrefix(base, "golang.org/x/"):
			var pkg string
			if len(strings.Split(base, "/")) >= 3 {
				pkg = strings.Split(base, "/")[2]
			}
			fileURL = fmt.Sprintf("https://github.com/golang/%s/blob/master%s", pkg, strings.TrimPrefix(filename, "/"+base))
		case strings.HasPrefix(base, "github.com/"):
			if len(strings.Split(base, "/")) == 4 {
				base = strings.Join(strings.Split(base, "/")[0:3], "/")
			}
			fileURL = fmt.Sprintf("https://%s/blob/master%s", base, strings.TrimPrefix(filename, "/"+base))
		}
		fs := fsMap[filename]
		if fs.Filename == "" {
			fs.Filename = filename
			if strings.HasPrefix(filename, "/github.com") {
				sp := strings.Split(filename, "/")
				if len(sp) > 3 {
					fs.Filename = strings.Join(sp[3:], "/")
				}

			}
			fs.FileURL = fileURL
		}
		err = fs.AddError(out.Text())
		if err != nil {
			return 0, []FileSummary{}, err
		}
		fsMap[filename] = fs
	}
	if err := out.Err(); err != nil {
		return 0, []FileSummary{}, err
	}

	for _, v := range fsMap {
		failed = append(failed, v)
	}

	err = cmd.Wait()
	if exitErr, ok := err.(*exec.ExitError); ok {
		// The program has exited with an exit code != 0

		if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
			// some commands exit 1 when files fail to pass (for example go vet)
			if status.ExitStatus() != 1 {
				return 0, failed, err
				// return 0, Error{}, err
			}
		}
	}

	if len(filenames) == 1 {
		lc, err := lineCount(filenames[0])
		if err != nil {
			return 0, failed, err
		}

		var errors int
		if len(failed) != 0 {
			errors = len(failed[0].Errors)
		}

		return float64(lc-errors) / float64(lc), failed, nil
	}

	return float64(len(filenames)-len(failed)) / float64(len(filenames)), failed, nil
}
<|endoftext|>


<commit_before>package php

import (
	"stephensearles.com/php/ast"
	"stephensearles.com/php/token"
)

func (p *Parser) parseArrayLookup(e ast.Expression) ast.Expression {
	p.expectCurrent(token.ArrayLookupOperatorLeft, token.BlockBegin)
	switch typ := p.peek().typ; typ {
	case token.ArrayLookupOperatorRight, token.BlockBegin:
		p.expect(token.ArrayLookupOperatorRight, token.BlockEnd)
		return ast.ArrayAppendExpression{Array: e}
	}
	p.next()
	expr := &ast.ArrayLookupExpression{
		Array: e,
		Index: p.parseExpression(),
	}
	p.expect(token.ArrayLookupOperatorRight, token.BlockEnd)
	return expr
}

func (p *Parser) parseArrayDeclaration() ast.Expression {
	p.expectCurrent(token.Array)
	pairs := make([]ast.ArrayPair, 0)
	p.expect(token.OpenParen)
ArrayLoop:
	for {
		var key, val ast.Expression
		switch p.peek().typ {
		case token.CloseParen:
			break ArrayLoop
		default:
			val = p.parseNextExpression()
		}
		switch p.peek().typ {
		case token.Comma:
			p.expect(token.Comma)
		case token.CloseParen:
			pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
			break ArrayLoop
		case token.ArrayKeyOperator:
			p.expect(token.ArrayKeyOperator)
			key = val
			val = p.parseNextExpression()
			if p.peek().typ == token.CloseParen {
				pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
				break ArrayLoop
			}
			p.expect(token.Comma)
		default:
			p.errorf("expected => or ,")
			return nil
		}
		pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
	}
	p.expect(token.CloseParen)
	return &ast.ArrayExpression{Pairs: pairs}
}

func (p *Parser) parseList() ast.Expression {
	l := &ast.ListStatement{
		Assignees: make([]ast.Assignable, 0),
	}
	p.expect(token.OpenParen)
	for {
		p.next()
		op, ok := p.parseOperand().(ast.Assignable)
		if ok {
			l.Assignees = append(l.Assignees, op)
		} else {
			p.errorf("%v is not assignable", op)
		}
		if p.peek().typ != token.Comma {
			break
		}
		p.expect(token.Comma)
	}
	p.expect(token.CloseParen)
	p.expect(token.AssignmentOperator)
	l.Operator = p.current.val
	l.Value = p.parseNextExpression()
	return l

}
<commit_msg>Allowing for skipped elements when doing array deconstruction with list<commit_after>package php

import (
	"stephensearles.com/php/ast"
	"stephensearles.com/php/token"
)

func (p *Parser) parseArrayLookup(e ast.Expression) ast.Expression {
	p.expectCurrent(token.ArrayLookupOperatorLeft, token.BlockBegin)
	switch typ := p.peek().typ; typ {
	case token.ArrayLookupOperatorRight, token.BlockBegin:
		p.expect(token.ArrayLookupOperatorRight, token.BlockEnd)
		return ast.ArrayAppendExpression{Array: e}
	}
	p.next()
	expr := &ast.ArrayLookupExpression{
		Array: e,
		Index: p.parseExpression(),
	}
	p.expect(token.ArrayLookupOperatorRight, token.BlockEnd)
	return expr
}

func (p *Parser) parseArrayDeclaration() ast.Expression {
	p.expectCurrent(token.Array)
	pairs := make([]ast.ArrayPair, 0)
	p.expect(token.OpenParen)
ArrayLoop:
	for {
		var key, val ast.Expression
		switch p.peek().typ {
		case token.CloseParen:
			break ArrayLoop
		default:
			val = p.parseNextExpression()
		}
		switch p.peek().typ {
		case token.Comma:
			p.expect(token.Comma)
		case token.CloseParen:
			pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
			break ArrayLoop
		case token.ArrayKeyOperator:
			p.expect(token.ArrayKeyOperator)
			key = val
			val = p.parseNextExpression()
			if p.peek().typ == token.CloseParen {
				pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
				break ArrayLoop
			}
			p.expect(token.Comma)
		default:
			p.errorf("expected => or ,")
			return nil
		}
		pairs = append(pairs, ast.ArrayPair{Key: key, Value: val})
	}
	p.expect(token.CloseParen)
	return &ast.ArrayExpression{Pairs: pairs}
}

func (p *Parser) parseList() ast.Expression {
	l := &ast.ListStatement{
		Assignees: make([]ast.Assignable, 0),
	}
	p.expect(token.OpenParen)
	for {
		if p.peek().typ == token.Comma {
			p.next()
			continue
		}
		p.next()
		op, ok := p.parseOperand().(ast.Assignable)
		if ok {
			l.Assignees = append(l.Assignees, op)
		} else {
			p.errorf("%v is not assignable", op)
		}
		if p.peek().typ != token.Comma {
			break
		}
		p.expect(token.Comma)
	}
	p.expect(token.CloseParen)
	p.expect(token.AssignmentOperator)
	l.Operator = p.current.val
	l.Value = p.parseNextExpression()
	return l

}
<|endoftext|>


<commit_before>package configuration

import (
	"encoding/json"
	"io/ioutil"
	"log"
)

type Configuration struct {
	Web struct {
		Address string `json:"address"`
	} `json:"web"`
	Cache struct {
		TTL     int    `json:"ttl"`
		Address string `json:"address"`
	} `json:"cache"`
	TMDb struct {
		APIKEY string `json:"api_key"`
	} `json:"tmdb"`
}

func Init() Configuration {
	var conf Configuration

	content, err := ioutil.ReadFile("wintergarten.conf")

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

	err = json.Unmarshal(content, &conf)

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

	return conf
}
<commit_msg>Checked multiple paths for the configuration file<commit_after>package configuration

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
)

type Configuration struct {
	Web struct {
		Address string `json:"address"`
	} `json:"web"`
	Cache struct {
		TTL     int    `json:"ttl"`
		Address string `json:"address"`
	} `json:"cache"`
	TMDb struct {
		APIKEY string `json:"api_key"`
	} `json:"tmdb"`
}

func Init() Configuration {
	var conf Configuration
	var confPath string
	confPaths := []string{"/etc/wintergarten.conf", "/etc/wintergarten.json", "wintergarten.conf", "wintergarten.json"}

	for _, path := range confPaths {
		if _, err := os.Stat(path); err == nil {
			confPath = path
			break
		}
	}

	if confPath == "" {
		log.Fatal("No configuration found.")
	}

	content, err := ioutil.ReadFile(confPath)

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

	err = json.Unmarshal(content, &conf)

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

	return conf
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"flag"
	"log"

	pb "github.com/datacommonsorg/mixer/proto"
	"google.golang.org/grpc"
)

var (
	addr = flag.String("addr", "127.0.0.1:12345", "Address of grpc server.")
)

func main() {
	flag.Parse()

	// Set up a connection to the server.
	conn, err := grpc.Dial(*addr, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewMixerClient(conn)

	ctx := context.Background()

	// Send a bunch of Sparql query and print out its response.
	qStrs := []string{
		`
		BASE <http://schema.org/>
		SELECT ?MeanTemp
		WHERE {
			?o typeOf WeatherObservation .
			?o measuredProperty temperature .
			?o meanValue ?MeanTemp .
			?o observationDate "2018-01" .
			?o observedNode ?place .
			?place dcid geoId/4261000
		}
		LIMIT 10`,
		`
		BASE <http://schema.org/>
		SELECT  ?Unemployment
		WHERE {
		  ?pop typeOf StatisticalPopulation .
		  ?o typeOf Observation .
		  ?pop dcid ("dc/p/qep2q2lcc3rcc" "dc/p/gmw3cn8tmsnth" "dc/p/92cxc027krdcd") .
		  ?o observedNode ?pop .
		  ?o measuredValue ?Unemployment
		}
		ORDER BY DESC(?Unemployment)
		LIMIT 10`,
		`SELECT ?a WHERE {?a typeof USC_RaceCodeEnum}`,
	}
	for _, str := range qStrs {
		r, err := c.Query(ctx, &pb.QueryRequest{Sparql: str})
		if err != nil {
			log.Fatalf("could not Query: %v", err)
		}
		log.Printf("Query: %v", r.GetRows())
	}

	// Send a transate request and print the response.
	sm := `
	Node: E:StatisticalPopulation->E1
	typeOf: StatisticalPopulation
	dcid: C:StatisticalPopulation->Col.row_info.id
	location: E:StatisticalPopulation->E2
	functionalDeps: dcid

	Node: E:StatisticalPopulation->E2
	typeOf: Place
	dcid: C:StatisticalPopulation->Col.place_key
	functionalDeps: dcid

	Node: E:Place->E1
	typeOf: Place
	subType: C:Place->Col.type
	dcid: C:Place->Col.row_info.id
	name: C:Place->Col.name
	functionalDeps: dcid

	Node: E:Triple->E1
	dcid: C:Triple->Col.subject_id
	provenance: E:Triple->E2
	C:Triple->Col.predicate: C:Triple->Col.object_value
	functionalDeps: dcid

	Node: E:Triple->E2
	typeOf: Provenance
	dcid: C:Triple->Col.row_info.prov_id
	functionalDeps: dcid
	`
	q := `
	SELECT ?dcid
	WHERE {
		?pop typeOf StatisticalPopulation .
		?place typeOf State .
		?pop location ?place .
		?pop dcid ?dcid
		?place name "California" .
	}
	`
	r, err := c.Translate(ctx, &pb.TranslateRequest{
		Sparql:        q,
		SchemaMapping: sm,
	})
	if err != nil {
		log.Fatalf("could not Transate: %v", err)
	}
	log.Printf("Query: %v", r.GetTranslation())
}
<commit_msg>Fix a bad query in demo (#69)<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"flag"
	"log"

	pb "github.com/datacommonsorg/mixer/proto"
	"google.golang.org/grpc"
)

var (
	addr = flag.String("addr", "127.0.0.1:12345", "Address of grpc server.")
)

func main() {
	flag.Parse()

	// Set up a connection to the server.
	conn, err := grpc.Dial(*addr, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewMixerClient(conn)

	ctx := context.Background()

	// Send a bunch of Sparql query and print out its response.
	qStrs := []string{
		`
		BASE <http://schema.org/>
		SELECT ?MeanTemp
		WHERE {
			?o typeOf WeatherObservation .
			?o measuredProperty temperature .
			?o meanValue ?MeanTemp .
			?o observationDate "2018-01" .
			?o observedNode ?place .
			?place dcid geoId/4261000
		}
		LIMIT 10`,
		`
		BASE <http://schema.org/>
		SELECT  ?Unemployment
		WHERE {
		  ?pop typeOf StatisticalPopulation .
		  ?o typeOf Observation .
		  ?pop dcid ("dc/p/qep2q2lcc3rcc" "dc/p/gmw3cn8tmsnth" "dc/p/92cxc027krdcd") .
		  ?o observedNode ?pop .
		  ?o measuredValue ?Unemployment
		}
		ORDER BY DESC(?Unemployment)
		LIMIT 10`,
		`SELECT ?a WHERE {?a typeof USC_RaceCodeEnum}`,
	}
	for _, str := range qStrs {
		r, err := c.Query(ctx, &pb.QueryRequest{Sparql: str})
		if err != nil {
			log.Fatalf("could not Query: %v", err)
		}
		log.Printf("Query: %v", r.GetRows())
	}

	// Send a transate request and print the response.
	sm := `
	Node: E:StatisticalPopulation->E1
	typeOf: StatisticalPopulation
	dcid: C:StatisticalPopulation->Col.row_info.id
	location: E:StatisticalPopulation->E2
	functionalDeps: dcid

	Node: E:StatisticalPopulation->E2
	typeOf: Place
	dcid: C:StatisticalPopulation->Col.place_key
	functionalDeps: dcid

	Node: E:Place->E1
	typeOf: Place
	subType: C:Place->Col.type
	dcid: C:Place->Col.row_info.id
	name: C:Place->Col.name
	functionalDeps: dcid

	Node: E:Triple->E1
	dcid: C:Triple->Col.subject_id
	provenance: E:Triple->E2
	C:Triple->Col.predicate: C:Triple->Col.object_value
	functionalDeps: dcid

	Node: E:Triple->E2
	typeOf: Provenance
	dcid: C:Triple->Col.row_info.prov_id
	functionalDeps: dcid
	`
	q := `
	SELECT ?dcid
	WHERE {
		?pop typeOf StatisticalPopulation .
		?place typeOf State .
		?pop location ?place .
		?pop dcid ?dcid .
		?place name "California" .
	}
	`
	r, err := c.Translate(ctx, &pb.TranslateRequest{
		Sparql:        q,
		SchemaMapping: sm,
	})
	if err != nil {
		log.Fatalf("could not Transate: %v", err)
	}
	log.Printf("Query: %v", r.GetTranslation())
}
<|endoftext|>


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

package os

import syscall "syscall"
import os "os"

// FDs are wrappers for file descriptors
export type FD struct {
	fd int64
}

export func NewFD(fd int64) *FD {
	if fd < 0 {
		return nil
	}
	return &FD{fd}
}

export var (
	Stdin = NewFD(0);
	Stdout = NewFD(1);
	Stderr = NewFD(2);
)

export const (
	O_RDONLY = syscall.O_RDONLY;
	O_WRONLY = syscall.O_WRONLY;
	O_RDWR = syscall.O_RDWR;
	O_APPEND = syscall.O_APPEND;
	O_ASYNC = syscall.O_ASYNC;
	O_CREAT = syscall.O_CREAT;
	O_NOCTTY = syscall.O_NOCTTY;
	O_NONBLOCK = syscall.O_NONBLOCK;
	O_NDELAY = O_NONBLOCK;
	O_SYNC = syscall.O_SYNC;
	O_TRUNC = syscall.O_TRUNC;
)

export func Open(name string, mode int, flags int) (fd *FD, err *Error) {
	r, e := syscall.open(name, int64(mode), int64(flags));
	return NewFD(r), ErrnoToError(e)
}

func (fd *FD) Close() *Error {
	if fd == nil {
		return EINVAL
	}
	r, e := syscall.close(fd.fd);
	fd.fd = -1;  // so it can't be closed again
	return ErrnoToError(e)
}

func (fd *FD) Read(b *[]byte) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	r, e := syscall.read(fd.fd, &b[0], int64(len(b)));
	return int(r), ErrnoToError(e)
}

func (fd *FD) Write(b *[]byte) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	r, e := syscall.write(fd.fd, &b[0], int64(len(b)));
	return int(r), ErrnoToError(e)
}

func (fd *FD) WriteString(s string) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	b := new([]byte, len(s)+1);
	if !syscall.StringToBytes(b, s) {
		return -1, EINVAL
	}
	r, e := syscall.write(fd.fd, &b[0], int64(len(s)));
	return int(r), ErrnoToError(e)
}

export func Pipe() (fd1 *FD, fd2 *FD, err *Error) {
	var p [2]int64;
	r, e := syscall.pipe(&p);
	if e != 0 {
		return nil, nil, ErrnoToError(e)
	}
	return NewFD(p[0]), NewFD(p[1]), nil
}

export func Mkdir(name string, perm int) *Error {
	r, e := syscall.mkdir(name, int64(perm));
	return ErrnoToError(e)
}
<commit_msg>buf fix: make FD.Read, FD.Write work for empty buffers<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import syscall "syscall"
import os "os"

// FDs are wrappers for file descriptors
export type FD struct {
	fd int64
}

export func NewFD(fd int64) *FD {
	if fd < 0 {
		return nil
	}
	return &FD{fd}
}

export var (
	Stdin = NewFD(0);
	Stdout = NewFD(1);
	Stderr = NewFD(2);
)

export const (
	O_RDONLY = syscall.O_RDONLY;
	O_WRONLY = syscall.O_WRONLY;
	O_RDWR = syscall.O_RDWR;
	O_APPEND = syscall.O_APPEND;
	O_ASYNC = syscall.O_ASYNC;
	O_CREAT = syscall.O_CREAT;
	O_NOCTTY = syscall.O_NOCTTY;
	O_NONBLOCK = syscall.O_NONBLOCK;
	O_NDELAY = O_NONBLOCK;
	O_SYNC = syscall.O_SYNC;
	O_TRUNC = syscall.O_TRUNC;
)

export func Open(name string, mode int, flags int) (fd *FD, err *Error) {
	r, e := syscall.open(name, int64(mode), int64(flags));
	return NewFD(r), ErrnoToError(e)
}

func (fd *FD) Close() *Error {
	if fd == nil {
		return EINVAL
	}
	r, e := syscall.close(fd.fd);
	fd.fd = -1;  // so it can't be closed again
	return ErrnoToError(e)
}

func (fd *FD) Read(b *[]byte) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	var r, e int64;
	if len(b) > 0 {  // because we access b[0]
		r, e = syscall.read(fd.fd, &b[0], int64(len(b)));
	}
	return int(r), ErrnoToError(e)
}

func (fd *FD) Write(b *[]byte) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	var r, e int64;
	if len(b) > 0 {  // because we access b[0]
		r, e = syscall.write(fd.fd, &b[0], int64(len(b)));
	}
	return int(r), ErrnoToError(e)
}

func (fd *FD) WriteString(s string) (ret int, err *Error) {
	if fd == nil {
		return -1, EINVAL
	}
	b := new([]byte, len(s)+1);
	if !syscall.StringToBytes(b, s) {
		return -1, EINVAL
	}
	r, e := syscall.write(fd.fd, &b[0], int64(len(s)));
	return int(r), ErrnoToError(e)
}

export func Pipe() (fd1 *FD, fd2 *FD, err *Error) {
	var p [2]int64;
	r, e := syscall.pipe(&p);
	if e != 0 {
		return nil, nil, ErrnoToError(e)
	}
	return NewFD(p[0]), NewFD(p[1]), nil
}

export func Mkdir(name string, perm int) *Error {
	r, e := syscall.mkdir(name, int64(perm));
	return ErrnoToError(e)
}
<|endoftext|>


<commit_before>package cli

import (
	"encoding/json"
	"fmt"
	"github.com/drewsonne/go-gocd/gocd"
	"github.com/urfave/cli"
)

// GetCliCommands returns a list of all CLI Command structs
func GetCliCommands() []cli.Command {
	return []cli.Command{
		*configureCommand(),
		*listAgentsCommand(),
		*listPipelineTemplatesCommand(),
		*getAgentCommand(),
		*getPipelineTemplateCommand(),
		*createPipelineTemplateCommand(),
		*updateAgentCommand(),
		*updateAgentsCommand(),
		*updatePipelineConfigCommand(),
		*updatePipelineTemplateCommand(),
		*deleteAgentCommand(),
		*deleteAgentsCommand(),
		*deletePipelineTemplateCommand(),
		*deletePipelineConfigCommand(),
		*listPipelineGroupsCommand(),
		*getPipelineHistoryCommand(),
		*getPipelineCommand(),
		*createPipelineConfigCommand(),
		*generateJSONSchemaCommand(),
		*getPipelineStatusCommand(),
		*pausePipelineCommand(),
		*unpausePipelineCommand(),
		*releasePipelineLockCommand(),
		*getConfigurationCommand(),
		*encryptCommand(),
		*getVersionCommand(),
		*listPluginsCommand(),
		*getPluginCommand(),
		*listScheduledJobsCommand(),
		*getPipelineConfigCommand(),
		*listEnvironmentsCommand(),
		*getEnvironmentCommand(),
		*addPipelinesToEnvironmentCommand(),
		*removePipelinesFromEnvironmentCommand(),
		*listPropertiesCommand(),
		*createPropertyCommand(),
	}
}

// NewCliClient creates a new gocd client for use by cli actions.
func NewCliClient(c *cli.Context) (*gocd.Client, error) {
	var profile string

	if profile = c.String("profile"); profile == "" {
		profile = "default"
	}

	cfg := &gocd.Configuration{}
	cfgErr := gocd.LoadConfigByName(profile, cfg)

	setStringFromContext(&cfg.Server, "server",c)

	if cfg.Server == "" {
		if cfgErr != nil {
			return nil, cfgErr
		} else {
			// If we didn't have any errors, and our server is empty, use the local.
			cfg.Server = "https://127.0.0.1:8154/go/"
		}
	}

	setStringFromContext(&cfg.Username, "username",c)
	setStringFromContext(&cfg.Password, "password",c)

	cfg.SkipSslCheck = cfg.SkipSslCheck || c.Bool("skip_ssl_check")

	return cfg.Client(), nil
}

func setStringFromContext(dest *string, key string, c *cli.Context) {
	var value string
	if value = c.String(key); value != "" {
		*dest = value
	}
}

func handleOutput(r interface{}, reqType string) cli.ExitCoder {
	o := map[string]interface{}{
		fmt.Sprintf("%s-response", reqType): r,
	}
	b, err := json.MarshalIndent(o, "", "    ")
	if err != nil {
		panic(err)
	}

	fmt.Println(string(b))
	return nil
}

type ActionWrapperFunc func(client *gocd.Client, c *cli.Context) (interface{}, *gocd.APIResponse, error)

func ActionWrapper(callback ActionWrapperFunc) interface{} {
	return func(c *cli.Context) error {
		cl := c.App.Metadata["c"].(func(c *cli.Context) (*gocd.Client, error))
		client, err := cl(c.Parent())
		if err != nil {
			return NewCliError(c.Command.Name, nil, err)
		}
		v, resp, err := callback(client, c)
		if err != nil {
			return NewCliError(c.Command.Name, resp, err)
		}
		return handleOutput(v, c.Command.Name)
	}
}
<commit_msg>Fixed formatting<commit_after>package cli

import (
	"encoding/json"
	"fmt"
	"github.com/drewsonne/go-gocd/gocd"
	"github.com/urfave/cli"
)

// GetCliCommands returns a list of all CLI Command structs
func GetCliCommands() []cli.Command {
	return []cli.Command{
		*configureCommand(),
		*listAgentsCommand(),
		*listPipelineTemplatesCommand(),
		*getAgentCommand(),
		*getPipelineTemplateCommand(),
		*createPipelineTemplateCommand(),
		*updateAgentCommand(),
		*updateAgentsCommand(),
		*updatePipelineConfigCommand(),
		*updatePipelineTemplateCommand(),
		*deleteAgentCommand(),
		*deleteAgentsCommand(),
		*deletePipelineTemplateCommand(),
		*deletePipelineConfigCommand(),
		*listPipelineGroupsCommand(),
		*getPipelineHistoryCommand(),
		*getPipelineCommand(),
		*createPipelineConfigCommand(),
		*generateJSONSchemaCommand(),
		*getPipelineStatusCommand(),
		*pausePipelineCommand(),
		*unpausePipelineCommand(),
		*releasePipelineLockCommand(),
		*getConfigurationCommand(),
		*encryptCommand(),
		*getVersionCommand(),
		*listPluginsCommand(),
		*getPluginCommand(),
		*listScheduledJobsCommand(),
		*getPipelineConfigCommand(),
		*listEnvironmentsCommand(),
		*getEnvironmentCommand(),
		*addPipelinesToEnvironmentCommand(),
		*removePipelinesFromEnvironmentCommand(),
		*listPropertiesCommand(),
		*createPropertyCommand(),
	}
}

// NewCliClient creates a new gocd client for use by cli actions.
func NewCliClient(c *cli.Context) (*gocd.Client, error) {
	var profile string

	if profile = c.String("profile"); profile == "" {
		profile = "default"
	}

	cfg := &gocd.Configuration{}
	cfgErr := gocd.LoadConfigByName(profile, cfg)

	setStringFromContext(&cfg.Server, "server", c)

	if cfg.Server == "" {
		if cfgErr != nil {
			return nil, cfgErr
		} else {
			// If we didn't have any errors, and our server is empty, use the local.
			cfg.Server = "https://127.0.0.1:8154/go/"
		}
	}

	setStringFromContext(&cfg.Username, "username", c)
	setStringFromContext(&cfg.Password, "password", c)

	cfg.SkipSslCheck = cfg.SkipSslCheck || c.Bool("skip_ssl_check")

	return cfg.Client(), nil
}

func setStringFromContext(dest *string, key string, c *cli.Context) {
	var value string
	if value = c.String(key); value != "" {
		*dest = value
	}
}

func handleOutput(r interface{}, reqType string) cli.ExitCoder {
	o := map[string]interface{}{
		fmt.Sprintf("%s-response", reqType): r,
	}
	b, err := json.MarshalIndent(o, "", "    ")
	if err != nil {
		panic(err)
	}

	fmt.Println(string(b))
	return nil
}

type ActionWrapperFunc func(client *gocd.Client, c *cli.Context) (interface{}, *gocd.APIResponse, error)

func ActionWrapper(callback ActionWrapperFunc) interface{} {
	return func(c *cli.Context) error {
		cl := c.App.Metadata["c"].(func(c *cli.Context) (*gocd.Client, error))
		client, err := cl(c.Parent())
		if err != nil {
			return NewCliError(c.Command.Name, nil, err)
		}
		v, resp, err := callback(client, c)
		if err != nil {
			return NewCliError(c.Command.Name, resp, err)
		}
		return handleOutput(v, c.Command.Name)
	}
}
<|endoftext|>


<commit_before>// +build windows

package container

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

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/utils"
	"github.com/docker/docker/volume"
)

// Container holds fields specific to the Windows implementation. See
// CommonContainer for standard fields common to all containers.
type Container struct {
	CommonContainer

	HostnamePath   string
	HostsPath      string
	ResolvConfPath string
	// Fields below here are platform specific.
}

// ExitStatus provides exit reasons for a container.
type ExitStatus struct {
	// The exit code with which the container exited.
	ExitCode int
}

// CreateDaemonEnvironment creates a new environment variable slice for this container.
func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string {
	// because the env on the container can override certain default values
	// we need to replace the 'env' keys where they match and append anything
	// else.
	return utils.ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env)
}

// UnmountIpcMounts unmounts Ipc related mounts.
// This is a NOOP on windows.
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
}

// IpcMounts returns the list of Ipc related mounts.
func (container *Container) IpcMounts() []Mount {
	return nil
}

// UnmountVolumes explicitly unmounts volumes from the container.
func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
	return nil
}

// TmpfsMounts returns the list of tmpfs mounts
func (container *Container) TmpfsMounts() []Mount {
	var mounts []Mount
	return mounts
}

// UpdateContainer updates configuration of a container
func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
	container.Lock()
	defer container.Unlock()
	resources := hostConfig.Resources
	if resources.BlkioWeight != 0 || resources.CPUShares != 0 ||
		resources.CPUPeriod != 0 || resources.CPUQuota != 0 ||
		resources.CpusetCpus != "" || resources.CpusetMems != "" ||
		resources.Memory != 0 || resources.MemorySwap != 0 ||
		resources.MemoryReservation != 0 || resources.KernelMemory != 0 {
		return fmt.Errorf("Resource updating isn't supported on Windows")
	}
	// update HostConfig of container
	if hostConfig.RestartPolicy.Name != "" {
		if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
			return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
		}
		container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
	}
	return nil
}

// appendNetworkMounts appends any network mounts to the array of mount points passed in.
// Windows does not support network mounts (not to be confused with SMB network mounts), so
// this is a no-op.
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
	return volumeMounts, nil
}

// cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
// to combine with a volume path
func cleanResourcePath(path string) string {
	if len(path) >= 2 {
		c := path[0]
		if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
			path = path[2:]
		}
	}
	return filepath.Join(string(os.PathSeparator), path)
}

// BuildHostnameFile writes the container's hostname file.
func (container *Container) BuildHostnameFile() error {
	return nil
}

// canMountFS determines if the file system for the container
// can be mounted locally. In the case of Windows, this is not possible
// for Hyper-V containers during WORKDIR execution for example.
func (container *Container) canMountFS() bool {
	return !containertypes.Isolation.IsHyperV(container.HostConfig.Isolation)
}
<commit_msg>Call "VolumeDriver.Unmount" during container stop.<commit_after>// +build windows

package container

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

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/utils"
	"github.com/docker/docker/volume"
)

// Container holds fields specific to the Windows implementation. See
// CommonContainer for standard fields common to all containers.
type Container struct {
	CommonContainer

	HostnamePath   string
	HostsPath      string
	ResolvConfPath string
	// Fields below here are platform specific.
}

// ExitStatus provides exit reasons for a container.
type ExitStatus struct {
	// The exit code with which the container exited.
	ExitCode int
}

// CreateDaemonEnvironment creates a new environment variable slice for this container.
func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string {
	// because the env on the container can override certain default values
	// we need to replace the 'env' keys where they match and append anything
	// else.
	return utils.ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env)
}

// UnmountIpcMounts unmounts Ipc related mounts.
// This is a NOOP on windows.
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
}

// IpcMounts returns the list of Ipc related mounts.
func (container *Container) IpcMounts() []Mount {
	return nil
}

// UnmountVolumes explicitly unmounts volumes from the container.
func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
	var (
		volumeMounts []volume.MountPoint
		err          error
	)

	for _, mntPoint := range container.MountPoints {
		dest, err := container.GetResourcePath(mntPoint.Destination)
		if err != nil {
			return err
		}
		volumeMounts = append(volumeMounts, volume.MountPoint{Destination: dest, Volume: mntPoint.Volume, ID: mntPoint.ID})

	}

	// atm, this is a no-op.
	if volumeMounts, err = appendNetworkMounts(container, volumeMounts); err != nil {
		return err
	}

	for _, volumeMount := range volumeMounts {
		if volumeMount.Volume != nil {
			if err := volumeMount.Volume.Unmount(volumeMount.ID); err != nil {
				return err
			}
			volumeMount.ID = ""

			attributes := map[string]string{
				"driver":    volumeMount.Volume.DriverName(),
				"container": container.ID,
			}
			volumeEventLog(volumeMount.Volume.Name(), "unmount", attributes)
		}
	}

	return nil
}

// TmpfsMounts returns the list of tmpfs mounts
func (container *Container) TmpfsMounts() []Mount {
	var mounts []Mount
	return mounts
}

// UpdateContainer updates configuration of a container
func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
	container.Lock()
	defer container.Unlock()
	resources := hostConfig.Resources
	if resources.BlkioWeight != 0 || resources.CPUShares != 0 ||
		resources.CPUPeriod != 0 || resources.CPUQuota != 0 ||
		resources.CpusetCpus != "" || resources.CpusetMems != "" ||
		resources.Memory != 0 || resources.MemorySwap != 0 ||
		resources.MemoryReservation != 0 || resources.KernelMemory != 0 {
		return fmt.Errorf("Resource updating isn't supported on Windows")
	}
	// update HostConfig of container
	if hostConfig.RestartPolicy.Name != "" {
		if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
			return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
		}
		container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
	}
	return nil
}

// appendNetworkMounts appends any network mounts to the array of mount points passed in.
// Windows does not support network mounts (not to be confused with SMB network mounts), so
// this is a no-op.
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
	return volumeMounts, nil
}

// cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
// to combine with a volume path
func cleanResourcePath(path string) string {
	if len(path) >= 2 {
		c := path[0]
		if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
			path = path[2:]
		}
	}
	return filepath.Join(string(os.PathSeparator), path)
}

// BuildHostnameFile writes the container's hostname file.
func (container *Container) BuildHostnameFile() error {
	return nil
}

// canMountFS determines if the file system for the container
// can be mounted locally. In the case of Windows, this is not possible
// for Hyper-V containers during WORKDIR execution for example.
func (container *Container) canMountFS() bool {
	return !containertypes.Isolation.IsHyperV(container.HostConfig.Isolation)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"sort"
	"strconv"
	"syscall"
	"time"

	"github.com/gophergala2016/goad"
	"github.com/gophergala2016/goad/Godeps/_workspace/src/github.com/nsf/termbox-go"
	"github.com/gophergala2016/goad/queue"
)

var (
	url         string
	concurrency uint
	requests    uint
	timeout     uint
	region      string
)

const coldef = termbox.ColorDefault
const nano = 1000000000

func main() {
	flag.UintVar(&concurrency, "c", 10, "number of concurrent requests")
	flag.UintVar(&requests, "n", 1000, "number of total requests to make")
	flag.UintVar(&timeout, "t", 15, "request timeout in seconds")
	flag.StringVar(&region, "r", "us-east-1", "AWS region")
	flag.Parse()

	if len(flag.Args()) < 1 {
		fmt.Println("You must specify a URL")
		os.Exit(1)
	}

	url = flag.Args()[0]

	test, testerr := goad.NewTest(&goad.TestConfig{
		URL:            url,
		Concurrency:    concurrency,
		TotalRequests:  requests,
		RequestTimeout: time.Duration(timeout) * time.Second,
		Region:         region,
	})
	if testerr != nil {
		fmt.Println(testerr)
		os.Exit(1)
	}

	var finalResult queue.RegionsAggData
	defer printSummary(&finalResult)

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // but interrupts from kbd are blocked by termbox

	start(test, &finalResult, sigChan)
}

func start(test *goad.Test, finalResult *queue.RegionsAggData, sigChan chan os.Signal) {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}

	defer termbox.Close()

	resultChan := test.Start()
	termbox.Sync()
	renderString(0, 0, "Launching on AWS...", coldef, coldef)
	_, h := termbox.Size()
	renderString(0, h-1, "Press ctrl-c to interrupt", coldef, coldef)
	termbox.Flush()

	go func() {
		for {
			event := termbox.PollEvent()
			if event.Key == 3 {
				sigChan <- syscall.SIGINT
			}
		}
	}()

outer:
	for {
		select {
		case result, ok := <-resultChan:
			if !ok {
				break outer
			}
			//		result.Regions["eu-west-1"] = result.Regions["us-east-1"]
			// sort so that regions always appear in the same order
			var regions []string
			for key := range result.Regions {
				regions = append(regions, key)
			}
			sort.Strings(regions)
			y := 3
			totalReqs := 0
			for _, region := range regions {
				data := result.Regions[region]
				totalReqs += data.TotalReqs
				y = renderRegion(data, y)
				y++
			}

			y = 0
			percentDone := float64(totalReqs) / float64(result.TotalExpectedRequests)
			drawProgressBar(percentDone, y)

			termbox.Flush()
			finalResult.Regions = result.Regions

		case <-sigChan:
			break outer
		}
	}
}

// renderRegion returns the y for the next empty line
func renderRegion(data queue.AggData, y int) int {
	x := 0
	renderString(x, y, "Region: ", termbox.ColorWhite, termbox.ColorBlue)
	x += 8
	regionStr := fmt.Sprintf("%-10s", data.Region)
	renderString(x, y, regionStr, termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlue)
	x = 0
	y++
	headingStr := "   TotReqs   TotBytes    AvgTime   AvgReq/s"
	renderString(x, y, headingStr, coldef|termbox.AttrBold, coldef)
	y++
	resultStr := fmt.Sprintf("%10d %10d   %7.3fs %10.2f", data.TotalReqs, data.TotBytesRead, float64(data.AveTimeForReq)/nano, data.AveReqPerSec)
	renderString(x, y, resultStr, coldef, coldef)
	y++
	headingStr = "   Slowest    Fastest   Timeouts  TotErrors"
	renderString(x, y, headingStr, coldef|termbox.AttrBold, coldef)
	y++
	resultStr = fmt.Sprintf("  %7.3fs   %7.3fs %10d %10d", float64(data.Slowest)/nano, float64(data.Fastest)/nano, data.TotalTimedOut, totErrors(&data))
	renderString(x, y, resultStr, coldef, coldef)
	y++

	return y
}

func totErrors(data *queue.AggData) int {
	var okReqs int
	for statusStr, value := range data.Statuses {
		status, _ := strconv.Atoi(statusStr)
		if status >= 200 && status <= 299 {
			okReqs += value
		}
	}
	return data.TotalReqs - okReqs
}

func drawProgressBar(percent float64, y int) {
	x := 0
	percentStr := fmt.Sprintf("%5.1f%%            ", percent*100)
	renderString(x, y, percentStr, coldef, coldef)
	y++

	hashes := int(percent * 50)
	if percent > 0.98 {
		hashes = 50
	}
	renderString(x, y, "[", coldef, coldef)

	for x++; x <= hashes; x++ {
		renderString(x, y, "#", coldef, coldef)
	}
	renderString(51, y, "]", coldef, coldef)
}

func renderString(x int, y int, str string, f termbox.Attribute, b termbox.Attribute) {
	for i, c := range str {
		termbox.SetCell(x+i, y, c, f, b)
	}
}

func boldPrintln(msg string) {
	fmt.Printf("\033[1m%s\033[0m\n", msg)
}

func printData(data *queue.AggData) {
	boldPrintln("   TotReqs   TotBytes    AvgTime   AvgReq/s")
	fmt.Printf("%10d %10d   %7.3fs %10.2f\n", data.TotalReqs, data.TotBytesRead, float64(data.AveTimeForReq)/nano, data.AveReqPerSec)
	boldPrintln("   Slowest    Fastest   Timeouts  TotErrors")
	fmt.Printf("  %7.3fs   %7.3fs %10d %10d", float64(data.Slowest)/nano, float64(data.Fastest)/nano, data.TotalTimedOut, totErrors(data))
	fmt.Println("")
}

func printSummary(result *queue.RegionsAggData) {
	if len(result.Regions) == 0 {
		boldPrintln("No results received")
		return
	}
	boldPrintln("Regional results")
	fmt.Println("")

	for region, data := range result.Regions {
		fmt.Println("Region: " + region)
		printData(&data)
	}

	overall := queue.SumRegionResults(result)

	fmt.Println("")
	boldPrintln("Overall")
	fmt.Println("")
	printData(overall)

	boldPrintln("HTTPStatus   Requests")
	for statusStr, value := range overall.Statuses {
		fmt.Printf("%10s %10d\n", statusStr, value)
	}
	fmt.Println("")
}
<commit_msg>Minor CLI flag improvements<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"sort"
	"strconv"
	"syscall"
	"time"

	"github.com/gophergala2016/goad"
	"github.com/gophergala2016/goad/Godeps/_workspace/src/github.com/nsf/termbox-go"
	"github.com/gophergala2016/goad/queue"
)

var (
	url         string
	concurrency uint
	requests    uint
	timeout     uint
	region      string
)

const coldef = termbox.ColorDefault
const nano = 1000000000

func main() {
	flag.UintVar(&concurrency, "c", 10, "number of concurrent requests")
	flag.UintVar(&requests, "n", 1000, "number of total requests to make")
	flag.UintVar(&timeout, "t", 15, "request timeout in seconds")
	flag.StringVar(&region, "r", "us-east-1", "AWS regions to run in")
	flag.Parse()

	if len(flag.Args()) < 1 {
		fmt.Println("You must specify a URL as a last argument")
		os.Exit(1)
	}

	url = flag.Args()[0]

	test, testerr := goad.NewTest(&goad.TestConfig{
		URL:            url,
		Concurrency:    concurrency,
		TotalRequests:  requests,
		RequestTimeout: time.Duration(timeout) * time.Second,
		Region:         region,
	})
	if testerr != nil {
		fmt.Println(testerr)
		os.Exit(1)
	}

	var finalResult queue.RegionsAggData
	defer printSummary(&finalResult)

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // but interrupts from kbd are blocked by termbox

	start(test, &finalResult, sigChan)
}

func start(test *goad.Test, finalResult *queue.RegionsAggData, sigChan chan os.Signal) {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}

	defer termbox.Close()

	resultChan := test.Start()
	termbox.Sync()
	renderString(0, 0, "Launching on AWS...", coldef, coldef)
	_, h := termbox.Size()
	renderString(0, h-1, "Press ctrl-c to interrupt", coldef, coldef)
	termbox.Flush()

	go func() {
		for {
			event := termbox.PollEvent()
			if event.Key == 3 {
				sigChan <- syscall.SIGINT
			}
		}
	}()

outer:
	for {
		select {
		case result, ok := <-resultChan:
			if !ok {
				break outer
			}
			//		result.Regions["eu-west-1"] = result.Regions["us-east-1"]
			// sort so that regions always appear in the same order
			var regions []string
			for key := range result.Regions {
				regions = append(regions, key)
			}
			sort.Strings(regions)
			y := 3
			totalReqs := 0
			for _, region := range regions {
				data := result.Regions[region]
				totalReqs += data.TotalReqs
				y = renderRegion(data, y)
				y++
			}

			y = 0
			percentDone := float64(totalReqs) / float64(result.TotalExpectedRequests)
			drawProgressBar(percentDone, y)

			termbox.Flush()
			finalResult.Regions = result.Regions

		case <-sigChan:
			break outer
		}
	}
}

// renderRegion returns the y for the next empty line
func renderRegion(data queue.AggData, y int) int {
	x := 0
	renderString(x, y, "Region: ", termbox.ColorWhite, termbox.ColorBlue)
	x += 8
	regionStr := fmt.Sprintf("%-10s", data.Region)
	renderString(x, y, regionStr, termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlue)
	x = 0
	y++
	headingStr := "   TotReqs   TotBytes    AvgTime   AvgReq/s"
	renderString(x, y, headingStr, coldef|termbox.AttrBold, coldef)
	y++
	resultStr := fmt.Sprintf("%10d %10d   %7.3fs %10.2f", data.TotalReqs, data.TotBytesRead, float64(data.AveTimeForReq)/nano, data.AveReqPerSec)
	renderString(x, y, resultStr, coldef, coldef)
	y++
	headingStr = "   Slowest    Fastest   Timeouts  TotErrors"
	renderString(x, y, headingStr, coldef|termbox.AttrBold, coldef)
	y++
	resultStr = fmt.Sprintf("  %7.3fs   %7.3fs %10d %10d", float64(data.Slowest)/nano, float64(data.Fastest)/nano, data.TotalTimedOut, totErrors(&data))
	renderString(x, y, resultStr, coldef, coldef)
	y++

	return y
}

func totErrors(data *queue.AggData) int {
	var okReqs int
	for statusStr, value := range data.Statuses {
		status, _ := strconv.Atoi(statusStr)
		if status >= 200 && status <= 299 {
			okReqs += value
		}
	}
	return data.TotalReqs - okReqs
}

func drawProgressBar(percent float64, y int) {
	x := 0
	percentStr := fmt.Sprintf("%5.1f%%            ", percent*100)
	renderString(x, y, percentStr, coldef, coldef)
	y++

	hashes := int(percent * 50)
	if percent > 0.98 {
		hashes = 50
	}
	renderString(x, y, "[", coldef, coldef)

	for x++; x <= hashes; x++ {
		renderString(x, y, "#", coldef, coldef)
	}
	renderString(51, y, "]", coldef, coldef)
}

func renderString(x int, y int, str string, f termbox.Attribute, b termbox.Attribute) {
	for i, c := range str {
		termbox.SetCell(x+i, y, c, f, b)
	}
}

func boldPrintln(msg string) {
	fmt.Printf("\033[1m%s\033[0m\n", msg)
}

func printData(data *queue.AggData) {
	boldPrintln("   TotReqs   TotBytes    AvgTime   AvgReq/s")
	fmt.Printf("%10d %10d   %7.3fs %10.2f\n", data.TotalReqs, data.TotBytesRead, float64(data.AveTimeForReq)/nano, data.AveReqPerSec)
	boldPrintln("   Slowest    Fastest   Timeouts  TotErrors")
	fmt.Printf("  %7.3fs   %7.3fs %10d %10d", float64(data.Slowest)/nano, float64(data.Fastest)/nano, data.TotalTimedOut, totErrors(data))
	fmt.Println("")
}

func printSummary(result *queue.RegionsAggData) {
	if len(result.Regions) == 0 {
		boldPrintln("No results received")
		return
	}
	boldPrintln("Regional results")
	fmt.Println("")

	for region, data := range result.Regions {
		fmt.Println("Region: " + region)
		printData(&data)
	}

	overall := queue.SumRegionResults(result)

	fmt.Println("")
	boldPrintln("Overall")
	fmt.Println("")
	printData(overall)

	boldPrintln("HTTPStatus   Requests")
	for statusStr, value := range overall.Statuses {
		fmt.Printf("%10s %10d\n", statusStr, value)
	}
	fmt.Println("")
}
<|endoftext|>


<commit_before>package cli

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"os"
	"strings"
)

//Command -
type Command struct {
	Name, Description string
	Aliases           []string
	Fn                commandFunc
}

//Response -
type Response string
type commandFunc func(...interface{}) (Response, error)

var availableCommands = make(map[string]*Command)
var commandMap = make(map[string]*Command)

func makeAvailableCommands() {
	for name, command := range map[string]*Command{
		"quit": &Command{
			Name:        "quit",
			Aliases:     []string{"exit", "bye"},
			Description: "Exit",
			Fn:          quit,
		},
		"help": &Command{
			Name:        "help",
			Aliases:     []string{"?", "usage"},
			Description: "Show usage syntax",
			Fn:          help,
		},
	} {
		availableCommands[name] = command
	}
}

func makeCommandMap() {
	for name, command := range availableCommands {
		commandMap[name] = command
		for _, alias := range command.Aliases {
			commandMap[alias] = command
		}
	}
}

func init() {
	makeAvailableCommands()
	makeCommandMap()
}

//MatchCommand - match a command or an alias to the actual command struct
func MatchCommand(search string) (*Command, error) {
	if command, ok := commandMap[search]; ok {
		return command, nil
	}

	return nil, fmt.Errorf("Command %q not found", search)
}

//Admin - read commands from stdin and execute them
func Admin() {
	waitC := make(chan struct{})

	inputCommands := make(chan string)
	go readCommands(waitC, inputCommands)

	for command := range inputCommands {
		parts := strings.Split(command, " ")
		command, args := parts[0], parts[1:]

		action, err := MatchCommand(command)
		if err != nil {
			log.Printf("error: %s", err.Error())
			action, _ = MatchCommand("help")
		}

		response, err := action.Fn(args)
		if err != nil {
			log.Print(err)
		}
		log.Print(response)
		waitC <- struct{}{}
	}
}

func readCommands(waitC chan struct{}, c chan string) {
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("> ")
		command, err := reader.ReadString('\n')
		if err != nil {
			log.Panic(err)
		}
		command = strings.TrimSpace(command)

		c <- command
		<-waitC
	}
}

func help(...interface{}) (Response, error) {
	usage := bytes.NewBufferString("Usage:\n")

	for name, command := range availableCommands {
		usage.WriteString(fmt.Sprintf("\t%s - %s\n", name, command.Description))
	}

	return Response(usage.String()), nil
}

func quit(...interface{}) (Response, error) {
	log.Print("Bye!")
	os.Exit(0)
	return "", nil
}
<commit_msg>pass args properly to cli commands<commit_after>package cli

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"os"
	"strings"
)

//Command -
type Command struct {
	Name, Description string
	Aliases           []string
	Fn                commandFunc
}

//Response -
type Response string
type commandFunc func(...string) (Response, error)

var availableCommands = make(map[string]*Command)
var commandMap = make(map[string]*Command)

func makeAvailableCommands() {
	for name, command := range map[string]*Command{
		"quit": &Command{
			Name:        "quit",
			Aliases:     []string{"exit", "bye"},
			Description: "Exit",
			Fn:          quit,
		},
		"help": &Command{
			Name:        "help",
			Aliases:     []string{"?", "usage"},
			Description: "Show usage syntax",
			Fn:          help,
		},
	} {
		availableCommands[name] = command
	}
}

func makeCommandMap() {
	for name, command := range availableCommands {
		commandMap[name] = command
		for _, alias := range command.Aliases {
			commandMap[alias] = command
		}
	}
}

func init() {
	makeAvailableCommands()
	makeCommandMap()
}

//MatchCommand - match a command or an alias to the actual command struct
func MatchCommand(search string) (*Command, error) {
	if command, ok := commandMap[search]; ok {
		return command, nil
	}

	return nil, fmt.Errorf("Command %q not found", search)
}

//Admin - read commands from stdin and execute them
func Admin() {
	waitC := make(chan struct{})

	inputCommands := make(chan string)
	go readCommands(waitC, inputCommands)

	for command := range inputCommands {
		parts := strings.Split(command, " ")
		command, args := parts[0], parts[1:]

		action, err := MatchCommand(command)
		if err != nil {
			log.Printf("error: %s", err.Error())
			action, _ = MatchCommand("help")
		}

		response, err := action.Fn(args...)
		if err != nil {
			log.Print(err)
		}
		log.Print(response)
		waitC <- struct{}{}
	}
}

func readCommands(waitC chan struct{}, c chan string) {
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("> ")
		command, err := reader.ReadString('\n')
		if err != nil {
			log.Panic(err)
		}
		command = strings.TrimSpace(command)

		c <- command
		<-waitC
	}
}

func help(args ...string) (Response, error) {
	usage := bytes.NewBufferString("Usage:\n")

	for name, command := range availableCommands {
		usage.WriteString(fmt.Sprintf("\t%s - %s\n", name, command.Description))
	}

	return Response(usage.String()), nil
}

func quit(args ...string) (Response, error) {
	log.Print("Bye!")
	os.Exit(0)
	return "", nil
}
<|endoftext|>


<commit_before>package cli

import (
	"gopkg.in/readline.v1"
)

type Readline struct {
	instance *readline.Instance
}

func Init(prompt string) *Readline {
	var (
		r   Readline
		err error
	)
	r.instance, err = readline.NewEx(&readline.Config{
		Prompt:          prompt + "> ",
		HistoryFile:     "/tmp/myping",
		InterruptPrompt: "^C",
		EOFPrompt:       "exit",
	})
	if err != nil {
		panic(err)
	}
	return &r
}

func (r *Readline) SetPrompt(p string) {
	r.instance.SetPrompt(p + "> ")
}

func (r *Readline) Run(cmd chan<- string, next chan struct{}) {
	func() {
		for {
			line, err := r.instance.Readline()
			if err != nil { // io.EOF, readline.ErrInterrupt
				break
			}
			cmd <- line
			<-next
		}
	}()
}
<commit_msg>added banner<commit_after>package cli

import (
	"github.com/mehrdadrad/myping/banner"
	"gopkg.in/readline.v1"
)

type Readline struct {
	instance *readline.Instance
}

func Init(prompt string) *Readline {
	var (
		r   Readline
		err error
	)
	r.instance, err = readline.NewEx(&readline.Config{
		Prompt:          prompt + "> ",
		HistoryFile:     "/tmp/myping",
		InterruptPrompt: "^C",
		EOFPrompt:       "exit",
	})
	if err != nil {
		panic(err)
	}
	banner.Println()
	return &r
}

func (r *Readline) SetPrompt(p string) {
	r.instance.SetPrompt(p + "> ")
}

func (r *Readline) Run(cmd chan<- string, next chan struct{}) {
	func() {
		for {
			line, err := r.instance.Readline()
			if err != nil { // io.EOF, readline.ErrInterrupt
				break
			}
			cmd <- line
			<-next
		}
	}()
}
<|endoftext|>


<commit_before>package main

import "testing"

var filetests = []string{
	"http://localhost:6060/",
	"localhost",
	"www.google.com",
}

func TestReadHosts(t *testing.T) {
	readHosts()
	for i, f := range filetests {
		if hosts[i].name != f {
			t.Errorf("hosts[%d]: got host{name: %s}, want host{name: %s}", i, hosts[i].name, f)
		}
	}
}

func TestPing(t *testing.T) {
	// TODO: Improve this when ping() has output.
	s := make([]string, 0)
	addrs := append(s, "127.0.0.1")
	host{name: "localhost", addrs: addrs}.ping()

	//s := make([]string, 0)
	//addrs := append(s, "127.0.0.1")
	host{name: "localhost", addrs: addrs}.ping()
}

func TestHtoI(t *testing.T) {
	h := host{name: "localhost"}
	want := "127.0.0.1"
	err := h.htoi()
	if err != nil {
		t.Fatal(err)
	}
	got := h.addrs[0]
	if got != want {
		t.Errorf("h.addrs: got %s, want %s", got, want)
	}
}
<commit_msg>Remove superfluous tests<commit_after>package main

import "testing"

var filetests = []string{
	"http://localhost:6060/",
	"localhost",
	"www.google.com",
}

func TestReadHosts(t *testing.T) {
	readHosts()
	for i, f := range filetests {
		if hosts[i].name != f {
			t.Errorf("hosts[%d]: got host{name: %s}, want host{name: %s}", i, hosts[i].name, f)
		}
	}
}

func TestPing(t *testing.T) {
	// TODO: Improve this when ping() has output.
	s := make([]string, 0)
	addrs := append(s, "127.0.0.1")
	host{name: "localhost", addrs: addrs}.ping()
}

func TestHtoI(t *testing.T) {
	h := host{name: "localhost"}
	want := "127.0.0.1"
	err := h.htoi()
	if err != nil {
		t.Fatal(err)
	}
	got := h.addrs[0]
	if got != want {
		t.Errorf("h.addrs: got %s, want %s", got, want)
	}
}
<|endoftext|>


<commit_before>package btcwallet

import (
	"encoding/hex"
	"errors"
	"fmt"

	"github.com/roasbeef/btcd/chaincfg/chainhash"
	"github.com/roasbeef/btcd/wire"

	"github.com/lightninglabs/neutrino"
	"github.com/lightningnetwork/lnd/lnwallet"
	"github.com/roasbeef/btcwallet/chain"
	"github.com/roasbeef/btcwallet/waddrmgr"
)

var (
	// ErrOutputSpent is returned by the GetUtxo method if the target output
	// for lookup has already been spent.
	ErrOutputSpent = errors.New("target output has been spent")
)

// GetBestBlock returns the current height and hash of the best known block
// within the main chain.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBestBlock() (*chainhash.Hash, int32, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		header, height, err := backend.CS.BlockHeaders.ChainTip()
		if err != nil {
			return nil, -1, err
		}

		blockHash := header.BlockHash()
		return &blockHash, int32(height), nil

	case *chain.RPCClient:
		return backend.GetBestBlock()

	default:
		return nil, -1, fmt.Errorf("unknown backend")
	}
}

// GetUtxo returns the original output referenced by the passed outpoint.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetUtxo(op *wire.OutPoint, heightHint uint32) (*wire.TxOut, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		spendReport, err := backend.CS.GetUtxo(
			neutrino.WatchOutPoints(*op),
			neutrino.StartBlock(&waddrmgr.BlockStamp{
				Height: int32(heightHint),
			}),
		)
		if err != nil {
			return nil, err
		}

		if spendReport != nil && spendReport.SpendingTx != nil {
			return nil, ErrOutputSpent
		}

		return spendReport.Output, nil

	case *chain.RPCClient:
		txout, err := backend.GetTxOut(&op.Hash, op.Index, false)
		if err != nil {
			return nil, err
		} else if txout == nil {
			return nil, ErrOutputSpent
		}

		pkScript, err := hex.DecodeString(txout.ScriptPubKey.Hex)
		if err != nil {
			return nil, err
		}

		return &wire.TxOut{
			// Sadly, gettxout returns the output value in BTC
			// instead of satoshis.
			Value:    int64(txout.Value * 1e8),
			PkScript: pkScript,
		}, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// GetBlock returns a raw block from the server given its hash.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		block, err := backend.CS.GetBlockFromNetwork(*blockHash)
		if err != nil {
			return nil, err
		}

		return block.MsgBlock(), nil

	case *chain.RPCClient:
		block, err := backend.GetBlock(blockHash)
		if err != nil {
			return nil, err
		}

		return block, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// GetBlockHash returns the hash of the block in the best blockchain at the
// given height.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		height := uint32(blockHeight)
		blockHeader, err := backend.CS.BlockHeaders.FetchHeaderByHeight(height)
		if err != nil {
			return nil, err
		}

		blockHash := blockHeader.BlockHash()
		return &blockHash, nil

	case *chain.RPCClient:
		blockHash, err := backend.GetBlockHash(blockHeight)
		if err != nil {
			return nil, err
		}

		return blockHash, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// A compile time check to ensure that BtcWallet implements the BlockChainIO
// interface.
var _ lnwallet.WalletController = (*BtcWallet)(nil)
<commit_msg>lnwallet/btcwallet/blockchain: properly handle nil spend report<commit_after>package btcwallet

import (
	"encoding/hex"
	"errors"
	"fmt"

	"github.com/roasbeef/btcd/chaincfg/chainhash"
	"github.com/roasbeef/btcd/wire"

	"github.com/lightninglabs/neutrino"
	"github.com/lightningnetwork/lnd/lnwallet"
	"github.com/roasbeef/btcwallet/chain"
	"github.com/roasbeef/btcwallet/waddrmgr"
)

var (
	// ErrOutputSpent is returned by the GetUtxo method if the target output
	// for lookup has already been spent.
	ErrOutputSpent = errors.New("target output has been spent")

	// ErrOutputNotFound signals that the desired output could not be
	// located.
	ErrOutputNotFound = errors.New("target output was not found")
)

// GetBestBlock returns the current height and hash of the best known block
// within the main chain.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBestBlock() (*chainhash.Hash, int32, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		header, height, err := backend.CS.BlockHeaders.ChainTip()
		if err != nil {
			return nil, -1, err
		}

		blockHash := header.BlockHash()
		return &blockHash, int32(height), nil

	case *chain.RPCClient:
		return backend.GetBestBlock()

	default:
		return nil, -1, fmt.Errorf("unknown backend")
	}
}

// GetUtxo returns the original output referenced by the passed outpoint.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetUtxo(op *wire.OutPoint, heightHint uint32) (*wire.TxOut, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		spendReport, err := backend.CS.GetUtxo(
			neutrino.WatchOutPoints(*op),
			neutrino.StartBlock(&waddrmgr.BlockStamp{
				Height: int32(heightHint),
			}),
		)
		if err != nil {
			return nil, err
		}

		// If the spend report is nil, then the output was not found in
		// the rescan.
		if spendReport == nil {
			return nil, ErrOutputNotFound
		}

		// If the spending transaction is populated in the spend report,
		// this signals that the output has already been spent.
		if spendReport.SpendingTx != nil {
			return nil, ErrOutputSpent
		}

		// Otherwise, the output is assumed to be in the UTXO.
		return spendReport.Output, nil

	case *chain.RPCClient:
		txout, err := backend.GetTxOut(&op.Hash, op.Index, false)
		if err != nil {
			return nil, err
		} else if txout == nil {
			return nil, ErrOutputSpent
		}

		pkScript, err := hex.DecodeString(txout.ScriptPubKey.Hex)
		if err != nil {
			return nil, err
		}

		return &wire.TxOut{
			// Sadly, gettxout returns the output value in BTC
			// instead of satoshis.
			Value:    int64(txout.Value * 1e8),
			PkScript: pkScript,
		}, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// GetBlock returns a raw block from the server given its hash.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		block, err := backend.CS.GetBlockFromNetwork(*blockHash)
		if err != nil {
			return nil, err
		}

		return block.MsgBlock(), nil

	case *chain.RPCClient:
		block, err := backend.GetBlock(blockHash)
		if err != nil {
			return nil, err
		}

		return block, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// GetBlockHash returns the hash of the block in the best blockchain at the
// given height.
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
	switch backend := b.chain.(type) {

	case *chain.NeutrinoClient:
		height := uint32(blockHeight)
		blockHeader, err := backend.CS.BlockHeaders.FetchHeaderByHeight(height)
		if err != nil {
			return nil, err
		}

		blockHash := blockHeader.BlockHash()
		return &blockHash, nil

	case *chain.RPCClient:
		blockHash, err := backend.GetBlockHash(blockHeight)
		if err != nil {
			return nil, err
		}

		return blockHash, nil

	default:
		return nil, fmt.Errorf("unknown backend")
	}
}

// A compile time check to ensure that BtcWallet implements the BlockChainIO
// interface.
var _ lnwallet.WalletController = (*BtcWallet)(nil)
<|endoftext|>


<commit_before>package static

import (
	"bytes"
	"github.com/viant/toolbox/storage"
	"log"
)

func init() {
	var memStorage = storage.NewMemoryService()
	{
		err := memStorage.Upload("mem://github.com/viant/endly/Version", bytes.NewReader([]byte{48, 46, 49, 52, 46, 48, 10}))
		if err != nil {
			log.Printf("failed to upload: mem://github.com/viant/endly/Version %v", err)
		}
	}
}
<commit_msg>reformated<commit_after>package static

import (
	"bytes"
	"github.com/viant/toolbox/storage"
	"log"
)

func init() {
	var memStorage = storage.NewMemoryService()
	{
		err := memStorage.Upload("mem://github.com/viant/endly/Version", bytes.NewReader([]byte{48, 46, 49, 52, 46, 49, 10}))
		if err != nil {
			log.Printf("failed to upload: mem://github.com/viant/endly/Version %v", err)
		}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"context"
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/arn"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsSsmParameter() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSsmParameterPut,
		Read:   resourceAwsSsmParameterRead,
		Update: resourceAwsSsmParameterPut,
		Delete: resourceAwsSsmParameterDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"tier": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  ssm.ParameterTierStandard,
				ValidateFunc: validation.StringInSlice([]string{
					ssm.ParameterTierStandard,
					ssm.ParameterTierAdvanced,
				}, false),
			},
			"type": {
				Type:     schema.TypeString,
				Required: true,
				ValidateFunc: validation.StringInSlice([]string{
					ssm.ParameterTypeString,
					ssm.ParameterTypeStringList,
					ssm.ParameterTypeSecureString,
				}, false),
			},
			"value": {
				Type:      schema.TypeString,
				Required:  true,
				Sensitive: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"key_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"data_type": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ValidateFunc: validation.StringInSlice([]string{
					"aws:ec2:image",
					"text",
				}, false),
			},
			"overwrite": {
				Type:     schema.TypeBool,
				Optional: true,
			},
			"allowed_pattern": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"version": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"tags": tagsSchema(),
		},

		CustomizeDiff: customdiff.All(
			// Prevent the following error during tier update from Advanced to Standard:
			// ValidationException: This parameter uses the advanced-parameter tier. You can't downgrade a parameter from the advanced-parameter tier to the standard-parameter tier. If necessary, you can delete the advanced parameter and recreate it as a standard parameter.
			customdiff.ForceNewIfChange("tier", func(_ context.Context, old, new, meta interface{}) bool {
				return old.(string) == ssm.ParameterTierAdvanced && new.(string) == ssm.ParameterTierStandard
			}),
		),
	}
}

func resourceAwsSsmParameterRead(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	log.Printf("[DEBUG] Reading SSM Parameter: %s", d.Id())

	resp, err := ssmconn.GetParameter(&ssm.GetParameterInput{
		Name:           aws.String(d.Id()),
		WithDecryption: aws.Bool(true),
	})

	if isAWSErr(err, ssm.ErrCodeParameterNotFound, "") && d.IsNewResource() && d.Get("data_type").(string) == "aws:ec2:image" {
		return fmt.Errorf("error reading SSM Parameter (%s) after creation: this can indicate that the provided parameter value could not be validated by SSM", d.Id())
	}

	if isAWSErr(err, ssm.ErrCodeParameterNotFound, "") && !d.IsNewResource() {
		log.Printf("[WARN] SSM Parameter (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error reading SSM Parameter (%s): %w", d.Id(), err)
	}

	param := resp.Parameter
	name := *param.Name
	d.Set("name", name)
	d.Set("type", param.Type)
	d.Set("value", param.Value)
	d.Set("version", param.Version)

	describeParamsInput := &ssm.DescribeParametersInput{
		ParameterFilters: []*ssm.ParameterStringFilter{
			{
				Key:    aws.String("Name"),
				Option: aws.String("Equals"),
				Values: []*string{aws.String(name)},
			},
		},
	}
	describeResp, err := ssmconn.DescribeParameters(describeParamsInput)
	if err != nil {
		return fmt.Errorf("error describing SSM parameter: %s", err)
	}

	if describeResp == nil || len(describeResp.Parameters) == 0 || describeResp.Parameters[0] == nil {
		log.Printf("[WARN] SSM Parameter %q not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	detail := describeResp.Parameters[0]
	d.Set("key_id", detail.KeyId)
	d.Set("description", detail.Description)
	d.Set("tier", ssm.ParameterTierStandard)
	if detail.Tier != nil {
		d.Set("tier", detail.Tier)
	}
	d.Set("allowed_pattern", detail.AllowedPattern)
	d.Set("data_type", detail.DataType)

	tags, err := keyvaluetags.SsmListTags(ssmconn, name, ssm.ResourceTypeForTaggingParameter)

	if err != nil {
		return fmt.Errorf("error listing tags for SSM Parameter (%s): %s", name, err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	arn := arn.ARN{
		Partition: meta.(*AWSClient).partition,
		Region:    meta.(*AWSClient).region,
		Service:   "ssm",
		AccountID: meta.(*AWSClient).accountid,
		Resource:  fmt.Sprintf("parameter/%s", strings.TrimPrefix(d.Id(), "/")),
	}
	d.Set("arn", arn.String())

	return nil
}

func resourceAwsSsmParameterDelete(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn

	log.Printf("[INFO] Deleting SSM Parameter: %s", d.Id())

	_, err := ssmconn.DeleteParameter(&ssm.DeleteParameterInput{
		Name: aws.String(d.Get("name").(string)),
	})
	if err != nil {
		return fmt.Errorf("error deleting SSM Parameter (%s): %s", d.Id(), err)
	}

	return nil
}

func resourceAwsSsmParameterPut(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn

	log.Printf("[INFO] Creating SSM Parameter: %s", d.Get("name").(string))

	paramInput := &ssm.PutParameterInput{
		Name:           aws.String(d.Get("name").(string)),
		Type:           aws.String(d.Get("type").(string)),
		Tier:           aws.String(d.Get("tier").(string)),
		Value:          aws.String(d.Get("value").(string)),
		Overwrite:      aws.Bool(shouldUpdateSsmParameter(d)),
		AllowedPattern: aws.String(d.Get("allowed_pattern").(string)),
	}

	if v, ok := d.GetOk("data_type"); ok {
		paramInput.DataType = aws.String(v.(string))
	}

	if d.HasChange("description") {
		_, n := d.GetChange("description")
		paramInput.Description = aws.String(n.(string))
	}

	if keyID, ok := d.GetOk("key_id"); ok && d.Get("type").(string) == ssm.ParameterTypeSecureString {
		paramInput.SetKeyId(keyID.(string))
	}

	log.Printf("[DEBUG] Waiting for SSM Parameter %v to be updated", d.Get("name"))
	_, err := ssmconn.PutParameter(paramInput)

	if isAWSErr(err, "ValidationException", "Tier is not supported") {
		paramInput.Tier = nil
		_, err = ssmconn.PutParameter(paramInput)
	}

	if err != nil {
		return fmt.Errorf("error creating SSM parameter: %s", err)
	}

	name := d.Get("name").(string)
	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.SsmUpdateTags(ssmconn, name, ssm.ResourceTypeForTaggingParameter, o, n); err != nil {
			return fmt.Errorf("error updating SSM Parameter (%s) tags: %s", name, err)
		}
	}

	d.SetId(d.Get("name").(string))

	return resourceAwsSsmParameterRead(d, meta)
}

func shouldUpdateSsmParameter(d *schema.ResourceData) bool {
	// If the user has specified a preference, return their preference
	if value, ok := d.GetOkExists("overwrite"); ok {
		return value.(bool)
	}

	// Since the user has not specified a preference, obey lifecycle rules
	// if it is not a new resource, otherwise overwrite should be set to false.
	return !d.IsNewResource()
}
<commit_msg>resource/aws_ssm_parameter: Handle data_type retries after creation for asynchronous validation process (#14514)<commit_after>package aws

import (
	"context"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/arn"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

const (
	// Maximum amount of time to wait for asynchronous validation on SSM Parameter creation.
	ssmParameterCreationValidationTimeout = 2 * time.Minute
)

func resourceAwsSsmParameter() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSsmParameterPut,
		Read:   resourceAwsSsmParameterRead,
		Update: resourceAwsSsmParameterPut,
		Delete: resourceAwsSsmParameterDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"tier": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  ssm.ParameterTierStandard,
				ValidateFunc: validation.StringInSlice([]string{
					ssm.ParameterTierStandard,
					ssm.ParameterTierAdvanced,
				}, false),
			},
			"type": {
				Type:     schema.TypeString,
				Required: true,
				ValidateFunc: validation.StringInSlice([]string{
					ssm.ParameterTypeString,
					ssm.ParameterTypeStringList,
					ssm.ParameterTypeSecureString,
				}, false),
			},
			"value": {
				Type:      schema.TypeString,
				Required:  true,
				Sensitive: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"key_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"data_type": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ValidateFunc: validation.StringInSlice([]string{
					"aws:ec2:image",
					"text",
				}, false),
			},
			"overwrite": {
				Type:     schema.TypeBool,
				Optional: true,
			},
			"allowed_pattern": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"version": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"tags": tagsSchema(),
		},

		CustomizeDiff: customdiff.All(
			// Prevent the following error during tier update from Advanced to Standard:
			// ValidationException: This parameter uses the advanced-parameter tier. You can't downgrade a parameter from the advanced-parameter tier to the standard-parameter tier. If necessary, you can delete the advanced parameter and recreate it as a standard parameter.
			customdiff.ForceNewIfChange("tier", func(_ context.Context, old, new, meta interface{}) bool {
				return old.(string) == ssm.ParameterTierAdvanced && new.(string) == ssm.ParameterTierStandard
			}),
		),
	}
}

func resourceAwsSsmParameterRead(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	log.Printf("[DEBUG] Reading SSM Parameter: %s", d.Id())

	input := &ssm.GetParameterInput{
		Name:           aws.String(d.Id()),
		WithDecryption: aws.Bool(true),
	}

	var resp *ssm.GetParameterOutput
	err := resource.Retry(ssmParameterCreationValidationTimeout, func() *resource.RetryError {
		var err error
		resp, err = ssmconn.GetParameter(input)

		if isAWSErr(err, ssm.ErrCodeParameterNotFound, "") && d.IsNewResource() && d.Get("data_type").(string) == "aws:ec2:image" {
			return resource.RetryableError(fmt.Errorf("error reading SSM Parameter (%s) after creation: this can indicate that the provided parameter value could not be validated by SSM", d.Id()))
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return nil
	})

	if isResourceTimeoutError(err) {
		resp, err = ssmconn.GetParameter(input)
	}

	if isAWSErr(err, ssm.ErrCodeParameterNotFound, "") && !d.IsNewResource() {
		log.Printf("[WARN] SSM Parameter (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error reading SSM Parameter (%s): %w", d.Id(), err)
	}

	param := resp.Parameter
	name := *param.Name
	d.Set("name", name)
	d.Set("type", param.Type)
	d.Set("value", param.Value)
	d.Set("version", param.Version)

	describeParamsInput := &ssm.DescribeParametersInput{
		ParameterFilters: []*ssm.ParameterStringFilter{
			{
				Key:    aws.String("Name"),
				Option: aws.String("Equals"),
				Values: []*string{aws.String(name)},
			},
		},
	}
	describeResp, err := ssmconn.DescribeParameters(describeParamsInput)
	if err != nil {
		return fmt.Errorf("error describing SSM parameter: %s", err)
	}

	if describeResp == nil || len(describeResp.Parameters) == 0 || describeResp.Parameters[0] == nil {
		log.Printf("[WARN] SSM Parameter %q not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	detail := describeResp.Parameters[0]
	d.Set("key_id", detail.KeyId)
	d.Set("description", detail.Description)
	d.Set("tier", ssm.ParameterTierStandard)
	if detail.Tier != nil {
		d.Set("tier", detail.Tier)
	}
	d.Set("allowed_pattern", detail.AllowedPattern)
	d.Set("data_type", detail.DataType)

	tags, err := keyvaluetags.SsmListTags(ssmconn, name, ssm.ResourceTypeForTaggingParameter)

	if err != nil {
		return fmt.Errorf("error listing tags for SSM Parameter (%s): %s", name, err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	arn := arn.ARN{
		Partition: meta.(*AWSClient).partition,
		Region:    meta.(*AWSClient).region,
		Service:   "ssm",
		AccountID: meta.(*AWSClient).accountid,
		Resource:  fmt.Sprintf("parameter/%s", strings.TrimPrefix(d.Id(), "/")),
	}
	d.Set("arn", arn.String())

	return nil
}

func resourceAwsSsmParameterDelete(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn

	log.Printf("[INFO] Deleting SSM Parameter: %s", d.Id())

	_, err := ssmconn.DeleteParameter(&ssm.DeleteParameterInput{
		Name: aws.String(d.Get("name").(string)),
	})
	if err != nil {
		return fmt.Errorf("error deleting SSM Parameter (%s): %s", d.Id(), err)
	}

	return nil
}

func resourceAwsSsmParameterPut(d *schema.ResourceData, meta interface{}) error {
	ssmconn := meta.(*AWSClient).ssmconn

	log.Printf("[INFO] Creating SSM Parameter: %s", d.Get("name").(string))

	paramInput := &ssm.PutParameterInput{
		Name:           aws.String(d.Get("name").(string)),
		Type:           aws.String(d.Get("type").(string)),
		Tier:           aws.String(d.Get("tier").(string)),
		Value:          aws.String(d.Get("value").(string)),
		Overwrite:      aws.Bool(shouldUpdateSsmParameter(d)),
		AllowedPattern: aws.String(d.Get("allowed_pattern").(string)),
	}

	if v, ok := d.GetOk("data_type"); ok {
		paramInput.DataType = aws.String(v.(string))
	}

	if d.HasChange("description") {
		_, n := d.GetChange("description")
		paramInput.Description = aws.String(n.(string))
	}

	if keyID, ok := d.GetOk("key_id"); ok && d.Get("type").(string) == ssm.ParameterTypeSecureString {
		paramInput.SetKeyId(keyID.(string))
	}

	log.Printf("[DEBUG] Waiting for SSM Parameter %v to be updated", d.Get("name"))
	_, err := ssmconn.PutParameter(paramInput)

	if isAWSErr(err, "ValidationException", "Tier is not supported") {
		paramInput.Tier = nil
		_, err = ssmconn.PutParameter(paramInput)
	}

	if err != nil {
		return fmt.Errorf("error creating SSM parameter: %s", err)
	}

	name := d.Get("name").(string)
	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.SsmUpdateTags(ssmconn, name, ssm.ResourceTypeForTaggingParameter, o, n); err != nil {
			return fmt.Errorf("error updating SSM Parameter (%s) tags: %s", name, err)
		}
	}

	d.SetId(d.Get("name").(string))

	return resourceAwsSsmParameterRead(d, meta)
}

func shouldUpdateSsmParameter(d *schema.ResourceData) bool {
	// If the user has specified a preference, return their preference
	if value, ok := d.GetOkExists("overwrite"); ok {
		return value.(bool)
	}

	// Since the user has not specified a preference, obey lifecycle rules
	// if it is not a new resource, otherwise overwrite should be set to false.
	return !d.IsNewResource()
}
<|endoftext|>