<commit_before>package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"geo"
	"graph"
	"kdtree"
	"log"
	"mm"
	"os"
	"path"
	"runtime"
	"sort"
)

const (
	MaxThreads = 8
)

var (
	FlagBaseDir string
)

func init() {
	flag.StringVar(&FlagBaseDir, "dir", "", "directory of the graph files")
}

func main() {
	runtime.GOMAXPROCS(MaxThreads)
	flag.Parse()

	clusterGraph, err := graph.OpenClusterGraph(FlagBaseDir, false /* loadMatrices */)
	if err != nil {
		log.Fatal("Loading graph: ", err)
	}

	fmt.Printf("Create k-d trees for the subgraphs\n")
	bboxes := make([]geo.BBox, len(clusterGraph.Cluster))
	ready := make(chan int, len(clusterGraph.Cluster))
	for i, g := range clusterGraph.Cluster {
		clusterDir := fmt.Sprintf("/cluster%d", i+1)
		go writeKdTreeSubgraph(ready, path.Join(FlagBaseDir, clusterDir), g.(*graph.GraphFile), bboxes, i)
	}
	for _, _ = range clusterGraph.Cluster {
		<-ready
	}

	// write bounding boxes to file
	fmt.Printf("Write bounding boxes\n")
	var bboxesFile []int32
	err = mm.Create(path.Join(FlagBaseDir, "bboxes.ftf"), len(bboxes)*4, &bboxesFile)
	if err != nil {
		log.Fatal("mm.Create failed: ", err)
	}
	for i, b := range bboxes {
		encodedBox := b.Encode()
		for j := 0; j < 4; j++ {
			bboxesFile[4*i+j] = encodedBox[j]
		}
	}
	err = mm.Close(&bboxesFile)
	if err != nil {
		log.Fatal("mm.Close failed: ", err)
	}

	fmt.Printf("Create k-d trees for the overlay graph\n")
	writeKdTreeOverlay(path.Join(FlagBaseDir, "/overlay"), clusterGraph.Overlay.(*graph.OverlayGraphFile))
}

type byLat struct {
	kdtree.KdTree
}

func (x byLat) Less(i, j int) bool {
	return x.KdTree.Coordinates[i].Lat < x.KdTree.Coordinates[j].Lat
}

type byLng struct {
	kdtree.KdTree
}

func (x byLng) Less(i, j int) bool {
	return x.KdTree.Coordinates[i].Lng < x.KdTree.Coordinates[j].Lng
}

func createKdTreeSubgraph(g *graph.GraphFile) (kdtree.KdTree, geo.BBox) {
	estimatedSize := g.VertexCount() + 4*g.EdgeCount()
	EncodedSteps := make([]uint32, 0, estimatedSize)
	coordinates := make([]geo.Coordinate, 0, estimatedSize)

	bbox := geo.NewBBoxPoint(g.VertexCoordinate(graph.Vertex(0)))

	// line up all coordinates and their encodings in the graph
	edges := []graph.Edge(nil)
	for i := 0; i < g.VertexCount(); i++ {
		vertex := graph.Vertex(i)
		coordinates = append(coordinates, g.VertexCoordinate(vertex))
		EncodedSteps = append(EncodedSteps, encodeCoordinate(i, kdtree.MaxEdgeOffset, kdtree.MaxStepOffset))
		bbox.Union(geo.NewBBoxPoint(g.VertexCoordinate(vertex)))

		edges = g.VertexRawEdges(vertex, edges)
		for j, e := range edges {
			steps := g.EdgeSteps(e, vertex)

			if len(steps) > 2000 {
				panic("steps > 2000")
			}

			for k, s := range steps {
				coordinates = append(coordinates, s)
				EncodedSteps = append(EncodedSteps, encodeCoordinate(i, j, k))
				bbox.Union(geo.NewBBoxPoint(s))
			}
		}
	}

	t := kdtree.KdTree{Graph: g, EncodedSteps: EncodedSteps, Coordinates: coordinates}
	createSubTree(t, true)
	return t, bbox
}

func createKdTreeOverlay(g *graph.OverlayGraphFile) kdtree.KdTree {
	estimatedSize := g.VertexCount() + 4*g.EdgeCount()
	EncodedSteps := make([]uint32, 0, estimatedSize)
	coordinates := make([]geo.Coordinate, 0, estimatedSize)

	// line up all coordinates and their encodings in the graph
	edges := []graph.Edge(nil)
	for i := 0; i < g.VertexCount(); i++ {
		vertex := graph.Vertex(i)
		coordinates = append(coordinates, g.VertexCoordinate(vertex))
		EncodedSteps = append(EncodedSteps, encodeCoordinate(i, kdtree.MaxEdgeOffset, kdtree.MaxStepOffset))

		g.VertexRawEdges(vertex, edges)
		for j, e := range edges {
			steps := g.EdgeSteps(e, vertex)
			for k, s := range steps {
				coordinates = append(coordinates, s)
				EncodedSteps = append(EncodedSteps, encodeCoordinate(i, j, k))
			}
		}
	}

	t := kdtree.KdTree{Graph: g, EncodedSteps: EncodedSteps, Coordinates: coordinates}
	createSubTree(t, true)
	return t
}

func subKdTree(t kdtree.KdTree, from, to int) kdtree.KdTree {
	return kdtree.KdTree{Graph: t.Graph, EncodedSteps: t.EncodedSteps[from:to], Coordinates: t.Coordinates[from:to]}
}

func createSubTree(t kdtree.KdTree, compareLat bool) {
	if t.Len() <= 1 {
		return
	}
	if compareLat {
		sort.Sort(byLat{t})
	} else {
		sort.Sort(byLng{t})
	}
	middle := t.Len() / 2
	createSubTree(subKdTree(t, 0, middle), !compareLat)
	createSubTree(subKdTree(t, middle+1, t.Len()), !compareLat)
}

// writeKdTreeSubgraph creates and stores the k-d tree for the given cluster graph
func writeKdTreeSubgraph(ready chan<- int, baseDir string, g *graph.GraphFile, bboxes []geo.BBox, pos int) {
	t, bbox := createKdTreeSubgraph(g)
	err := writeToFile(t, baseDir)
	if err != nil {
		log.Fatal("Creating k-d tree: ", err)
	}
	// TODO add margin?
	bboxes[pos] = bbox
	ready <- 1
}

// writeKdTree creates and stores the k-d tree for the given graph
func writeKdTreeOverlay(baseDir string, g *graph.OverlayGraphFile) {
	t := createKdTreeOverlay(g)
	err := writeToFile(t, baseDir)
	if err != nil {
		log.Fatal("Creating k-d tree: ", err)
	}
}

// writeToFile stores the permitation created by the k-d tree
func writeToFile(t kdtree.KdTree, baseDir string) error {
	output, err := os.Create(path.Join(baseDir, "kdtree.ftf"))
	defer output.Close()
	if err != nil {
		return err
	}
	writeErr := binary.Write(output, binary.LittleEndian, t.EncodedSteps)
	if writeErr != nil {
		return writeErr
	}
	return nil
}

func encodeCoordinate(vertexIndex, edgeOffset, stepOffset int) uint32 {
	if vertexIndex > kdtree.MaxVertexIndex {
		panic("vertex index too large")
	}
	// both offsets are at max if only a vertex is encoded
	if edgeOffset != kdtree.MaxEdgeOffset && stepOffset != kdtree.MaxStepOffset {
		if edgeOffset >= kdtree.MaxEdgeOffset {
			panic("edge offset too large")
		}
		if stepOffset >= kdtree.MaxStepOffset {
			fmt.Printf("vertex: %d, edge offset: %v, step offset: %v\n", vertexIndex, edgeOffset, stepOffset)
			panic("step offset too large")
		}
	}

	ec := uint32(vertexIndex) << (kdtree.EdgeOffsetBits + kdtree.StepOffsetBits)
	ec |= uint32(edgeOffset) << kdtree.StepOffsetBits
	ec |= uint32(stepOffset)
	return ec
}
<commit_msg>adjusted k-d tree builder<commit_after>package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"geo"
	"graph"
	"kdtree"
	"log"
	"mm"
	"os"
	"path"
	"runtime"
	"sort"
)

const (
	MaxThreads = 8
)

var (
	FlagBaseDir string
)

func init() {
	flag.StringVar(&FlagBaseDir, "dir", "", "directory of the graph files")
}

func main() {
	runtime.GOMAXPROCS(MaxThreads)
	flag.Parse()

	clusterGraph, err := graph.OpenClusterGraph(FlagBaseDir, false /* loadMatrices */)
	if err != nil {
		log.Fatal("Loading graph: ", err)
	}

	fmt.Printf("Create k-d trees for the subgraphs\n")
	bboxes := make([]geo.BBox, len(clusterGraph.Cluster))
	ready := make(chan int, len(clusterGraph.Cluster))
	for i, g := range clusterGraph.Cluster {
		clusterDir := fmt.Sprintf("/cluster%d", i+1)
		go writeKdTreeSubgraph(ready, path.Join(FlagBaseDir, clusterDir), g.(*graph.GraphFile), bboxes, i)
	}
	for _, _ = range clusterGraph.Cluster {
		<-ready
	}

	// write bounding boxes to file
	fmt.Printf("Write bounding boxes\n")
	var bboxesFile []int32
	err = mm.Create(path.Join(FlagBaseDir, "bboxes.ftf"), len(bboxes)*4, &bboxesFile)
	if err != nil {
		log.Fatal("mm.Create failed: ", err)
	}
	for i, b := range bboxes {
		encodedBox := b.Encode()
		for j := 0; j < 4; j++ {
			bboxesFile[4*i+j] = encodedBox[j]
		}
	}
	err = mm.Close(&bboxesFile)
	if err != nil {
		log.Fatal("mm.Close failed: ", err)
	}

	fmt.Printf("Create k-d trees for the overlay graph\n")
	writeKdTreeOverlay(path.Join(FlagBaseDir, "/overlay"), clusterGraph.Overlay.(*graph.OverlayGraphFile))
}

type byLat struct {
	*kdtree.KdTree
}

func (x byLat) Less(i, j int) bool {
	return x.KdTree.Coordinates[i].Lat < x.KdTree.Coordinates[j].Lat
}

type byLng struct {
	*kdtree.KdTree
}

func (x byLng) Less(i, j int) bool {
	return x.KdTree.Coordinates[i].Lng < x.KdTree.Coordinates[j].Lng
}

func createKdTreeSubgraph(g *graph.GraphFile) (*kdtree.KdTree, geo.BBox) {
	estimatedSize := (kdtree.TypeSize * (g.VertexCount() + 4*g.EdgeCount())) / kdtree.TotalBits
	encodedSteps := make([]uint64, 0, estimatedSize)
	coordinates := make([]geo.Coordinate, 0, estimatedSize)

	bbox := geo.NewBBoxPoint(g.VertexCoordinate(graph.Vertex(0)))

	t := &kdtree.KdTree{Graph: g, EncodedSteps: encodedSteps, Coordinates: coordinates}

	// line up all coordinates and their encodings in the graph
	edges := []graph.Edge(nil)
	for i := 0; i < g.VertexCount(); i++ {
		vertex := graph.Vertex(i)
		coordinates = append(coordinates, g.VertexCoordinate(vertex))
		t.AppendEncodedStep(encodeCoordinate(i, kdtree.MaxEdgeOffset, kdtree.MaxStepOffset))
		bbox.Union(geo.NewBBoxPoint(g.VertexCoordinate(vertex)))

		edges = g.VertexRawEdges(vertex, edges)
		for j, e := range edges {
			steps := g.EdgeSteps(e, vertex)

			if len(steps) > 2000 {
				panic("steps > 2000")
			}

			for k, s := range steps {
				coordinates = append(coordinates, s)
				t.AppendEncodedStep(encodeCoordinate(i, j, k))
				bbox.Union(geo.NewBBoxPoint(s))
			}
		}
	}
	createSubTree(t, true)
	return t, bbox
}

func createKdTreeOverlay(g *graph.OverlayGraphFile) *kdtree.KdTree {
	estimatedSize := (kdtree.TypeSize * (g.VertexCount() + 4*g.EdgeCount())) / kdtree.TotalBits
	encodedSteps := make([]uint64, 0, estimatedSize)
	coordinates := make([]geo.Coordinate, 0, estimatedSize)

	t := &kdtree.KdTree{Graph: g, EncodedSteps: encodedSteps, Coordinates: coordinates}

	// line up all coordinates and their encodings in the graph
	edges := []graph.Edge(nil)
	fmt.Printf("Vertex count: %d\n", g.VertexCount())
	for i := 0; i < g.VertexCount(); i++ {
		vertex := graph.Vertex(i)
		coordinates = append(coordinates, g.VertexCoordinate(vertex))
		t.AppendEncodedStep(encodeCoordinate(i, kdtree.MaxEdgeOffset, kdtree.MaxStepOffset))

		edges = g.VertexRawEdges(vertex, edges)
		for j, e := range edges {
			steps := g.EdgeSteps(e, vertex)
			for k, s := range steps {
				coordinates = append(coordinates, s)
				t.AppendEncodedStep(encodeCoordinate(i, j, k))
			}
		}
	}

	createSubTree(t, true)
	return t
}

func subKdTree(t *kdtree.KdTree, from, to int) *kdtree.KdTree {
	return &kdtree.KdTree{Graph: t.Graph, EncodedSteps: t.EncodedSteps[from:to], Coordinates: t.Coordinates[from:to]}
}

func createSubTree(t *kdtree.KdTree, compareLat bool) {
	if t.Len() <= 1 {
		return
	}
	if compareLat {
		sort.Sort(byLat{t})
	} else {
		sort.Sort(byLng{t})
	}
	middle := t.Len() / 2
	createSubTree(subKdTree(t, 0, middle), !compareLat)
	createSubTree(subKdTree(t, middle+1, t.Len()), !compareLat)
}

// writeKdTreeSubgraph creates and stores the k-d tree for the given cluster graph
func writeKdTreeSubgraph(ready chan<- int, baseDir string, g *graph.GraphFile, bboxes []geo.BBox, pos int) {
	t, bbox := createKdTreeSubgraph(g)
	err := writeToFile(t, baseDir)
	if err != nil {
		log.Fatal("Creating k-d tree: ", err)
	}
	// TODO add margin?
	bboxes[pos] = bbox
	ready <- 1
}

// writeKdTree creates and stores the k-d tree for the given graph
func writeKdTreeOverlay(baseDir string, g *graph.OverlayGraphFile) {
	t := createKdTreeOverlay(g)
	err := writeToFile(t, baseDir)
	if err != nil {
		log.Fatal("Creating k-d tree: ", err)
	}
}

// writeToFile stores the permitation created by the k-d tree
func writeToFile(t *kdtree.KdTree, baseDir string) error {
	output, err := os.Create(path.Join(baseDir, "kdtree.ftf"))
	defer output.Close()
	if err != nil {
		return err
	}
	writeErr := binary.Write(output, binary.LittleEndian, t.EncodedSteps)
	if writeErr != nil {
		return writeErr
	}
	return nil
}

func encodeCoordinate(vertexIndex, edgeOffset, stepOffset int) uint64 {
	if vertexIndex > kdtree.MaxVertexIndex {
		panic("vertex index too large")
	}
	// both offsets are at max if only a vertex is encoded
	if edgeOffset != kdtree.MaxEdgeOffset && stepOffset != kdtree.MaxStepOffset {
		if edgeOffset >= kdtree.MaxEdgeOffset {
			panic("edge offset too large")
		}
		if stepOffset >= kdtree.MaxStepOffset {
			fmt.Printf("vertex: %d, edge offset: %v, step offset: %v\n", vertexIndex, edgeOffset, stepOffset)
			panic("step offset too large")
		}
	}

	ec := uint64(vertexIndex) << (kdtree.EdgeOffsetBits + kdtree.StepOffsetBits)
	ec |= uint64(edgeOffset) << kdtree.StepOffsetBits
	ec |= uint64(stepOffset)
	return ec
}
<|endoftext|>


<commit_before>package client

import (
	"keyvalue/server"
	"log"
	"testing"

	"strconv"
	"time"
)

func TestClient(t *testing.T) {
	server.Init(12345)
	c := clientInit("localhost:12345")
	//c := clientInit("adelie-01:12345")
	sanityTest(c)
	correctnessTest(c)
	performanceTest(c)
}

func clientInit(server string) *Client {
	status, client := Init(server)

	if status != 0 {
		log.Fatal("Client inited with nonzero status")
	}
	if client == nil {
		log.Fatal("Client inited returned nil value")
	}

	log.Printf("Successfully connected to Server at, %s", server)
	return client
}

func sanityTest(client *Client) {
	printTestStart("Sanity Test")
	result, old := client.Set("key1", "value1")
	log.Printf("Called Set(key=%s, value=%s) Received(result=%d, value=%s)\n", "key1", "value1", result, old)
	result, value := client.Get("key1")
	log.Printf("Called Get(key=%s) Received(result=%d, value=%s)\n", "key1", result, value)
}

func correctnessTest(client *Client) {
	printTestStart("Correctness Test")

	var value string = "This is a sample test value of type string"
	var result int
	var out string

	// Test Case 1: Write a new key
	result, out = client.Set("New_key_1", value)
	if result != 1 {
		log.Fatal("TC 1: Server did not return status 1 for writing a new key. Received : ", result)
	}
	if out != "" {
		log.Fatal("TC 1: Server returned old value for writing a new key. Received value : ", out)
	}

	// Test Case 2: Overwrite an existing key
	var new_value string = "A different sample string value"
	result, out = client.Set("New_key_1", new_value)
	if result != 0 {
		log.Fatal("TC 2: Server did not return status 0 for writing to an existing key. Received : ", result)
	}
	if out != value {
		log.Fatalf("TC 2: Server did not return the expected old value for writing to an existing key. Expecting: %s, Received: %s ", value, out)
	}

	// Test Case 3: Read an existing key
	result, out = client.Get("New_key_1")
	if result != 0 {
		log.Fatal("TC 3: Server did not return status 0 for reading an existing key. Received : ", result)
	}
	if out != new_value {
		log.Fatalf("TC 3: Server did not return the expected value for reading an existing key. Expecting: %s, Received: %s ", new_value, out)
	}

	// Test Case 4: Read a non-existent key
	result, out = client.Get("Madeup_key")
	if result != 1 {
		log.Fatal("TC 4: Server did not return status 1 for reading a non-existent key. Received : ", result)
	}
	if out != "" {
		log.Fatalf("TC 4: Server returned a value for a non-existent key. Received: %s", out)
	}

	log.Printf("PASS")

}

func performanceTest(client *Client) {
	printTestStart("Performance Test")

	var value string = "This is a sample test value of type string"
	var elapsed time.Duration
	var startTime time.Time

	startTime = time.Now()
	seqWrite(client, 1000, value)
	elapsed = time.Since(startTime)
	log.Printf("Write test - Keys: %d, Total time: %s, %f ops/sec", 1000, elapsed, 1000/elapsed.Seconds())

	startTime = time.Now()
	seqRead(client, 1000, value)
	elapsed = time.Since(startTime)
	log.Printf("SeqRead test - Keys: %d, Total time: %s, %f ops/sec", 1000, elapsed, 1000/elapsed.Seconds())

	log.Printf("PASS")
}

func seqWrite(client *Client, numKeys int, value string) {
	for i := 1; i < numKeys; i++ {
		key := strconv.Itoa(i)
		result, _ := client.Set(key, value)

		if result == -1 {
			log.Fatalf("Write failure. Failed to write key: %s", key)
		}
	}
}

func seqRead(client *Client, numKeys int, value string) {
	for i := 1; i < numKeys; i++ {
		key := strconv.Itoa(i)
		result, out := client.Get(key)

		if result == -1 {
			log.Fatalf("Read failure. Failed to read key: %s", key)
		}

		if out != value {
			log.Fatalf("Inconsistent data on read. Result: %d, Expecting: %s, Received: %s", result, value, out)
		}
	}
}

func printTestStart(testName string) {
	log.Printf("----------------- %s ------------------", testName)
}
<commit_msg>Unify operations number<commit_after>package client

import (
	"keyvalue/server"

	"log"
	"os"
	"strconv"
	"testing"
	"time"
)

func TestClient(t *testing.T) {
	os.RemoveAll(server.LogDir)
	server.Init(12345)
	c := clientInit("localhost:12345")
	//c := clientInit("adelie-01:12345")
	sanityTest(c)
	correctnessTest(c)
	performanceTest(c)
}

func clientInit(server string) *Client {
	status, client := Init(server)

	if status != 0 {
		log.Fatal("Client inited with nonzero status")
	}
	if client == nil {
		log.Fatal("Client inited returned nil value")
	}

	log.Printf("Successfully connected to Server at, %s", server)
	return client
}

func sanityTest(client *Client) {
	printTestStart("Sanity Test")
	result, old := client.Set("key1", "value1")
	log.Printf("Called Set(key=%s, value=%s) Received(result=%d, value=%s)\n", "key1", "value1", result, old)
	result, value := client.Get("key1")
	log.Printf("Called Get(key=%s) Received(result=%d, value=%s)\n", "key1", result, value)
}

func correctnessTest(client *Client) {
	printTestStart("Correctness Test")

	var value string = "This is a sample test value of type string"
	var result int
	var out string

	// Test Case 1: Write a new key
	result, out = client.Set("New_key_1", value)
	if result != 1 {
		log.Fatal("TC 1: Server did not return status 1 for writing a new key. Received : ", result)
	}
	if out != "" {
		log.Fatal("TC 1: Server returned old value for writing a new key. Received value : ", out)
	}

	// Test Case 2: Overwrite an existing key
	var new_value string = "A different sample string value"
	result, out = client.Set("New_key_1", new_value)
	if result != 0 {
		log.Fatal("TC 2: Server did not return status 0 for writing to an existing key. Received : ", result)
	}
	if out != value {
		log.Fatalf("TC 2: Server did not return the expected old value for writing to an existing key. Expecting: %s, Received: %s ", value, out)
	}

	// Test Case 3: Read an existing key
	result, out = client.Get("New_key_1")
	if result != 0 {
		log.Fatal("TC 3: Server did not return status 0 for reading an existing key. Received : ", result)
	}
	if out != new_value {
		log.Fatalf("TC 3: Server did not return the expected value for reading an existing key. Expecting: %s, Received: %s ", new_value, out)
	}

	// Test Case 4: Read a non-existent key
	result, out = client.Get("Madeup_key")
	if result != 1 {
		log.Fatal("TC 4: Server did not return status 1 for reading a non-existent key. Received : ", result)
	}
	if out != "" {
		log.Fatalf("TC 4: Server returned a value for a non-existent key. Received: %s", out)
	}

	log.Printf("PASS")

}

func performanceTest(client *Client) {
	printTestStart("Performance Test")

	value := "This is a sample test value of type string"
	operations := 1000

	startTime := time.Now()
	seqWrite(client, operations, value)
	elapsed := time.Since(startTime)
	log.Printf("Write test - Keys: %d, Total time: %s, %f ops/sec", operations, elapsed, float64(operations)/elapsed.Seconds())

	startTime = time.Now()
	seqRead(client, operations, value)
	elapsed = time.Since(startTime)
	log.Printf("SeqRead test - Keys: %d, Total time: %s, %f ops/sec", operations, elapsed, float64(operations)/elapsed.Seconds())

	log.Printf("PASS")
}

func seqWrite(client *Client, numKeys int, value string) {
	for i := 1; i < numKeys; i++ {
		key := strconv.Itoa(i)
		result, _ := client.Set(key, value)

		if result == -1 {
			log.Fatalf("Write failure. Failed to write key: %s", key)
		}
	}
}

func seqRead(client *Client, numKeys int, value string) {
	for i := 1; i < numKeys; i++ {
		key := strconv.Itoa(i)
		result, out := client.Get(key)

		if result == -1 {
			log.Fatalf("Read failure. Failed to read key: %s", key)
		}

		if out != value {
			log.Fatalf("Inconsistent data on read. Result: %d, Expecting: %s, Received: %s", result, value, out)
		}
	}
}

func printTestStart(testName string) {
	log.Printf("----------------- %s ------------------", testName)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"cred-alert/inflator"
	"cred-alert/kolsch"
	"cred-alert/mimetype"
	"cred-alert/scanners"
	"cred-alert/scanners/diffscanner"
	"cred-alert/scanners/dirscanner"
	"cred-alert/scanners/filescanner"
	"cred-alert/sniff"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"code.cloudfoundry.org/lager"

	"github.com/jessevdk/go-flags"
)

type Opts struct {
	File string `short:"f" long:"file" description:"the file to scan" value-name:"FILE"`
	Diff bool   `long:"diff" description:"content to be scanned is a git diff"`
}

func main() {
	var opts Opts

	_, err := flags.ParseArgs(&opts, os.Args)
	if err != nil {
		os.Exit(1)
	}

	logger := kolsch.NewLogger()
	sniffer := sniff.NewDefaultSniffer()
	inflate := inflator.New()
	defer inflate.Close()

	if opts.File != "" {
		fh, err := os.Open(opts.File)
		if err != nil {
			log.Fatalln(err.Error())
		}

		destination, err := ioutil.TempDir("", "cred-alert-cli")
		if err != nil {
			log.Fatalln(err.Error())
		}

		defer os.RemoveAll(destination)

		br := bufio.NewReader(fh)
		mime, isArchive := mimetype.IsArchive(logger, br)
		if isArchive {
			err := inflate.Inflate(logger, opts.File, destination)
			if err != nil {
				log.Fatalln(err.Error())
			}

			dirScanner := dirscanner.New(handleViolation, sniffer)
			err = dirScanner.Scan(logger, destination)
			if err != nil {
				log.Fatalln(err.Error())
			}

			fmt.Println()
			fmt.Println("Scan complete!")
			fmt.Println()
			fmt.Println("Any archive inflation errors can be found in: ", inflate.LogPath())
		} else {
			if strings.HasPrefix(mime, "text") {
				scanFile(logger, sniffer, br, opts.File)
			}
		}
	} else if opts.Diff {
		handleDiff(logger, opts)
	} else {
		scanFile(logger, sniffer, os.Stdin, "STDIN")
	}
}

func handleViolation(logger lager.Logger, line scanners.Line) error {
	fmt.Printf("Line matches pattern! File: %s, Line Number: %d, Content: %s\n", line.Path, line.LineNumber, line.Content)

	return nil
}

func scanFile(
	logger lager.Logger,
	sniffer sniff.Sniffer,
	f io.Reader,
	name string,
) {
	scanner := filescanner.New(f, name)
	sniffer.Sniff(logger, scanner, handleViolation)
}

func handleDiff(logger lager.Logger, opts Opts) {
	logger.Session("handle-diff")
	diff, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		logger.Error("read-error", err)
	}

	scanner := diffscanner.NewDiffScanner(string(diff))
	sniffer := sniff.NewDefaultSniffer()

	sniffer.Sniff(logger, scanner, handleViolation)
}
<commit_msg>show time taken to scan archive<commit_after>package main

import (
	"bufio"
	"cred-alert/inflator"
	"cred-alert/kolsch"
	"cred-alert/mimetype"
	"cred-alert/scanners"
	"cred-alert/scanners/diffscanner"
	"cred-alert/scanners/dirscanner"
	"cred-alert/scanners/filescanner"
	"cred-alert/sniff"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"time"

	"code.cloudfoundry.org/lager"

	"github.com/jessevdk/go-flags"
)

type Opts struct {
	File string `short:"f" long:"file" description:"the file to scan" value-name:"FILE"`
	Diff bool   `long:"diff" description:"content to be scanned is a git diff"`
}

func main() {
	var opts Opts

	_, err := flags.ParseArgs(&opts, os.Args)
	if err != nil {
		os.Exit(1)
	}

	logger := kolsch.NewLogger()
	sniffer := sniff.NewDefaultSniffer()
	inflate := inflator.New()
	defer inflate.Close()

	if opts.File != "" {
		start := time.Now()

		fh, err := os.Open(opts.File)
		if err != nil {
			log.Fatalln(err.Error())
		}

		destination, err := ioutil.TempDir("", "cred-alert-cli")
		if err != nil {
			log.Fatalln(err.Error())
		}

		defer os.RemoveAll(destination)

		br := bufio.NewReader(fh)
		mime, isArchive := mimetype.IsArchive(logger, br)
		if isArchive {
			err := inflate.Inflate(logger, opts.File, destination)
			if err != nil {
				log.Fatalln(err.Error())
			}

			dirScanner := dirscanner.New(handleViolation, sniffer)
			err = dirScanner.Scan(logger, destination)
			if err != nil {
				log.Fatalln(err.Error())
			}

			duration := time.Since(start)

			fmt.Println()
			fmt.Println("Scan complete! Time taken:", duration)
			fmt.Println()
			fmt.Println("Any archive inflation errors can be found in: ", inflate.LogPath())
		} else {
			if strings.HasPrefix(mime, "text") {
				scanFile(logger, sniffer, br, opts.File)
			}
		}
	} else if opts.Diff {
		handleDiff(logger, opts)
	} else {
		scanFile(logger, sniffer, os.Stdin, "STDIN")
	}
}

func handleViolation(logger lager.Logger, line scanners.Line) error {
	fmt.Printf("Line matches pattern! File: %s, Line Number: %d, Content: %s\n", line.Path, line.LineNumber, line.Content)

	return nil
}

func scanFile(
	logger lager.Logger,
	sniffer sniff.Sniffer,
	f io.Reader,
	name string,
) {
	scanner := filescanner.New(f, name)
	sniffer.Sniff(logger, scanner, handleViolation)
}

func handleDiff(logger lager.Logger, opts Opts) {
	logger.Session("handle-diff")
	diff, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		logger.Error("read-error", err)
	}

	scanner := diffscanner.NewDiffScanner(string(diff))
	sniffer := sniff.NewDefaultSniffer()

	sniffer.Sniff(logger, scanner, handleViolation)
}
<|endoftext|>


<commit_before>package match

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
	"github.com/tisp-lang/tisp/src/lib/scalar"
)

type desugarer struct {
	lets []interface{}
}

func newDesugarer() *desugarer {
	return &desugarer{nil}
}

func (d *desugarer) desugar(x interface{}) interface{} {
	switch x := x.(type) {
	case ast.App:
		return ast.NewApp(
			d.desugar(x.Function()),
			d.desugar(x.Arguments()).(ast.Arguments),
			x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, d.desugar(p).(ast.PositionalArgument))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, d.desugar(k).(ast.KeywordArgument))
		}

		dicts := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, dict := range x.ExpandedDicts() {
			dicts = append(dicts, d.desugar(dict))
		}

		return ast.NewArguments(ps, ks, dicts)
	case ast.KeywordArgument:
		return ast.NewKeywordArgument(x.Name(), d.desugar(x.Value()))
	case ast.LetFunction:
		ls := make([]interface{}, 0, len(x.Lets()))

		for _, l := range x.Lets() {
			l := d.desugar(l)
			ls = append(ls, append(d.lets, l)...)
			d.lets = nil
		}

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			ls,
			d.desugar(x.Body()),
			x.DebugInfo())
	case ast.LetVar:
		return ast.NewLetVar(x.Name(), d.desugar(x.Expr()))
	case ast.Match:
		cs := x.Cases()
		new := make([]ast.MatchCase, 0, len(cs))

		for _, c := range cs {
			new = append(new, ast.NewMatchCase(c.Pattern(), d.desugar(c.Value())))
		}

		return app(d.createMatchFunction(new), d.desugar(x.Value()))
	case ast.Output:
		return ast.NewOutput(d.desugar(x.Expr()), x.Expanded())
	case ast.PositionalArgument:
		return ast.NewPositionalArgument(d.desugar(x.Value()), x.Expanded())
	default:
		return x
	}
}

func (d *desugarer) letVar(s string, v interface{}) {
	d.lets = append(d.lets, ast.NewLetVar(s, v))
}

func (d *desugarer) createMatchFunction(cs []ast.MatchCase) interface{} {
	arg := gensym.GenSym("match", "argument")
	body := d.casesToBody(arg, cs)

	f := ast.NewLetFunction(
		gensym.GenSym("match", "function"),
		ast.NewSignature([]string{arg}, nil, "", nil, nil, ""),
		d.lets,
		body,
		debug.NewGoInfo(0))

	d.lets = []interface{}{f}

	return f.Name()
}

func (d *desugarer) casesToBody(arg string, cs []ast.MatchCase) interface{} {
	cs = renameBoundNamesInCases(cs)
	body := app("error", "\"MatchError\"", "\"Failed to match a value with patterns.\"")

	for _, cs := range groupCases(cs) {
		result, ok := d.matchCasesOfSamePatterns(arg, cs)
		body = app("if", ok, result, body)
	}

	return body
}

func renameBoundNamesInCases(cs []ast.MatchCase) []ast.MatchCase {
	new := make([]ast.MatchCase, 0, len(cs))

	for _, c := range cs {
		new = append(new, renameBoundNamesInCase(c))
	}

	return new
}

func renameBoundNamesInCase(c ast.MatchCase) ast.MatchCase {
	p, ns := newPatternRenamer().rename(c.Pattern())
	return ast.NewMatchCase(p, newValueRenamer(ns).rename(c.Value()))
}

func app(f interface{}, args ...interface{}) interface{} {
	return ast.NewPApp(f, args, debug.NewGoInfo(0))
}

func (d *desugarer) matchCasesOfSamePatterns(v interface{}, cs []ast.MatchCase) (interface{}, interface{}) {
	switch getPatternType(cs[0].Pattern()) {
	case listPattern:
		panic("Not implemented")
	case dictPattern:
		panic("Not implemented")
	case scalarPattern:
		ss := make([]interface{}, 0, 2*len(cs))

		for _, c := range cs {
			ss = append(ss, c.Pattern(), c.Value())
		}

		dict := gensym.GenSym("match", "scalar", "dict")
		d.letVar(dict, app("dict", ss...))

		return app(dict, v), app("include", dict, v)
	case namePattern:
		if len(cs) != 1 {
			panic(fmt.Errorf("Duplicate name patterns: %v", len(cs)))
		}

		c := cs[0]
		d.letVar(c.Pattern().(string), v)
		return c.Value(), "true"
	}

	panic(fmt.Errorf("Invalid cases: %#v", cs))
}

// func matchType(v string, typ string) interface{} {
//	return app("=", app("typeOf", v), typ)
// }

func groupCases(cs []ast.MatchCase) map[patternType][]ast.MatchCase {
	m := map[patternType][]ast.MatchCase{}

	for _, c := range cs {
		p := getPatternType(c.Pattern())
		m[p] = append(m[p], c)
	}

	return m
}

func getPatternType(p interface{}) patternType {
	switch x := p.(type) {
	case string:
		if scalar.Defined(x) {
			return scalarPattern
		}

		return namePattern
	case ast.App:
		if len(x.Arguments().Positionals()) == 0 {
			return scalarPattern
		}

		switch x.Function().(string) {
		case "$list":
			return listPattern
		case "$dict":
			return dictPattern
		}
	}

	panic(fmt.Errorf("Invalid pattern: %#v", p))
}
<commit_msg>Fix non-initialized let statements of match expression desugarer<commit_after>package match

import (
	"fmt"

	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
	"github.com/tisp-lang/tisp/src/lib/gensym"
	"github.com/tisp-lang/tisp/src/lib/scalar"
)

type desugarer struct {
	lets []interface{}
}

func newDesugarer() *desugarer {
	return &desugarer{nil}
}

func (d *desugarer) desugar(x interface{}) interface{} {
	switch x := x.(type) {
	case ast.App:
		return ast.NewApp(
			d.desugar(x.Function()),
			d.desugar(x.Arguments()).(ast.Arguments),
			x.DebugInfo())
	case ast.Arguments:
		ps := make([]ast.PositionalArgument, 0, len(x.Positionals()))

		for _, p := range x.Positionals() {
			ps = append(ps, d.desugar(p).(ast.PositionalArgument))
		}

		ks := make([]ast.KeywordArgument, 0, len(x.Keywords()))

		for _, k := range x.Keywords() {
			ks = append(ks, d.desugar(k).(ast.KeywordArgument))
		}

		dicts := make([]interface{}, 0, len(x.ExpandedDicts()))

		for _, dict := range x.ExpandedDicts() {
			dicts = append(dicts, d.desugar(dict))
		}

		return ast.NewArguments(ps, ks, dicts)
	case ast.KeywordArgument:
		return ast.NewKeywordArgument(x.Name(), d.desugar(x.Value()))
	case ast.LetFunction:
		ls := make([]interface{}, 0, len(x.Lets()))

		for _, l := range x.Lets() {
			l := d.desugar(l)
			ls = append(ls, append(d.takeLets(), l)...)
		}

		b := d.desugar(x.Body())
		ls = append(ls, d.takeLets()...)

		return ast.NewLetFunction(
			x.Name(),
			x.Signature(),
			ls,
			b,
			x.DebugInfo())
	case ast.LetVar:
		return ast.NewLetVar(x.Name(), d.desugar(x.Expr()))
	case ast.Match:
		cs := x.Cases()
		new := make([]ast.MatchCase, 0, len(cs))

		for _, c := range cs {
			new = append(new, ast.NewMatchCase(c.Pattern(), d.desugar(c.Value())))
		}

		return app(d.createMatchFunction(new), d.desugar(x.Value()))
	case ast.Output:
		return ast.NewOutput(d.desugar(x.Expr()), x.Expanded())
	case ast.PositionalArgument:
		return ast.NewPositionalArgument(d.desugar(x.Value()), x.Expanded())
	default:
		return x
	}
}

func (d *desugarer) takeLets() []interface{} {
	ls := d.lets
	d.lets = nil
	return ls
}

func (d *desugarer) letVar(s string, v interface{}) {
	d.lets = append(d.lets, ast.NewLetVar(s, v))
}

func (d *desugarer) createMatchFunction(cs []ast.MatchCase) interface{} {
	arg := gensym.GenSym("match", "argument")
	body := d.casesToBody(arg, cs)

	f := ast.NewLetFunction(
		gensym.GenSym("match", "function"),
		ast.NewSignature([]string{arg}, nil, "", nil, nil, ""),
		d.takeLets(),
		body,
		debug.NewGoInfo(0))

	d.lets = []interface{}{f}

	return f.Name()
}

func (d *desugarer) casesToBody(arg string, cs []ast.MatchCase) interface{} {
	cs = renameBoundNamesInCases(cs)
	body := app("error", "\"MatchError\"", "\"Failed to match a value with patterns.\"")

	for _, cs := range groupCases(cs) {
		result, ok := d.matchCasesOfSamePatterns(arg, cs)
		body = app("if", ok, result, body)
	}

	return body
}

func renameBoundNamesInCases(cs []ast.MatchCase) []ast.MatchCase {
	new := make([]ast.MatchCase, 0, len(cs))

	for _, c := range cs {
		new = append(new, renameBoundNamesInCase(c))
	}

	return new
}

func renameBoundNamesInCase(c ast.MatchCase) ast.MatchCase {
	p, ns := newPatternRenamer().rename(c.Pattern())
	return ast.NewMatchCase(p, newValueRenamer(ns).rename(c.Value()))
}

func app(f interface{}, args ...interface{}) interface{} {
	return ast.NewPApp(f, args, debug.NewGoInfo(0))
}

func (d *desugarer) matchCasesOfSamePatterns(v interface{}, cs []ast.MatchCase) (interface{}, interface{}) {
	switch getPatternType(cs[0].Pattern()) {
	case listPattern:
		panic("Not implemented")
	case dictPattern:
		panic("Not implemented")
	case scalarPattern:
		ss := make([]interface{}, 0, 2*len(cs))

		for _, c := range cs {
			ss = append(ss, c.Pattern(), c.Value())
		}

		dict := gensym.GenSym("match", "scalar", "dict")
		d.letVar(dict, app("dict", ss...))

		return app(dict, v), app("include", dict, v)
	case namePattern:
		if len(cs) != 1 {
			panic(fmt.Errorf("Duplicate name patterns: %v", len(cs)))
		}

		c := cs[0]
		d.letVar(c.Pattern().(string), v)
		return c.Value(), "true"
	}

	panic(fmt.Errorf("Invalid cases: %#v", cs))
}

// func matchType(v string, typ string) interface{} {
//	return app("=", app("typeOf", v), typ)
// }

func groupCases(cs []ast.MatchCase) map[patternType][]ast.MatchCase {
	m := map[patternType][]ast.MatchCase{}

	for _, c := range cs {
		p := getPatternType(c.Pattern())
		m[p] = append(m[p], c)
	}

	return m
}

func getPatternType(p interface{}) patternType {
	switch x := p.(type) {
	case string:
		if scalar.Defined(x) {
			return scalarPattern
		}

		return namePattern
	case ast.App:
		if len(x.Arguments().Positionals()) == 0 {
			return scalarPattern
		}

		switch x.Function().(string) {
		case "$list":
			return listPattern
		case "$dict":
			return dictPattern
		}
	}

	panic(fmt.Errorf("Invalid pattern: %#v", p))
}
<|endoftext|>


<commit_before><commit_msg>filters: only apply to file paths, not dir paths<commit_after><|endoftext|>


<commit_before><commit_msg>fix bug<commit_after><|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// Checks if the packageName is checked out into one of the GOPATH entries
// under GOPATH[i]/src/packageName.
func main() {
	var packageName string
	flag.StringVar(&packageName, "packageName", "github.com/fabric8-services/fabric8-wit", "Package Name (e.g.)")
	flag.Parse()

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	for _, p := range strings.Split(os.Getenv("GOPATH"), string(filepath.ListSeparator)) {
		// Check if p is a directory
		if info, err := os.Stat(p); err == nil && info.IsDir() {
			// Make sure we have an absolute path
			abs, err := filepath.Abs(p)
			if err != nil {
				log.Fatal(err)
			}
			if wd == filepath.Join(abs, "src", packageName) {
				os.Exit(0)
			}
		}
	}

	goPathStr := path.Join("$GOPATH", "src", packageName)
	if runtime.GOOS == windows {
		goPathStr := path.Join("%GOPATH%", "src", packageName)
	}
	log.Fatal(fmt.Errorf("Make sure you've checked out your project in %s", goPathStr)

}
<commit_msg>Fixed compaling issues (#1574)<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

// Checks if the packageName is checked out into one of the GOPATH entries
// under GOPATH[i]/src/packageName.
func main() {
	var packageName string
	flag.StringVar(&packageName, "packageName", "github.com/fabric8-services/fabric8-wit", "Package Name (e.g.)")
	flag.Parse()

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	for _, p := range strings.Split(os.Getenv("GOPATH"), string(filepath.ListSeparator)) {
		// Check if p is a directory
		if info, err := os.Stat(p); err == nil && info.IsDir() {
			// Make sure we have an absolute path
			abs, err := filepath.Abs(p)
			if err != nil {
				log.Fatal(err)
			}
			if wd == filepath.Join(abs, "src", packageName) {
				os.Exit(0)
			}
		}
	}

	goPathStr := path.Join("$GOPATH", "src", packageName)
	if runtime.GOOS == "windows" {
		goPathStr = path.Join("%GOPATH%", "src", packageName)
	}
	log.Fatal(fmt.Errorf("Make sure you've checked out your project in %s", goPathStr))

}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"github.com/yamamoto-febc/libsacloud/sacloud"
	"time"
)

//HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため
//      ロードバランサ/VPCルータそれぞれでリクエスト/レスポンスデータ型を定義する。

type SearchLoadBalancerResponse struct {
	Total         int                    `json:",omitempty"`
	From          int                    `json:",omitempty"`
	Count         int                    `json:",omitempty"`
	LoadBalancers []sacloud.LoadBalancer `json:"Appliances,omitempty"`
}

type loadBalancerRequest struct {
	LoadBalander *sacloud.LoadBalancer  `json:"Appliance,omitempty"`
	From         int                    `json:",omitempty"`
	Count        int                    `json:",omitempty"`
	Sort         []string               `json:",omitempty"`
	Filter       map[string]interface{} `json:",omitempty"`
	Exclude      []string               `json:",omitempty"`
	Include      []string               `json:",omitempty"`
}

type loadBalanderResponse struct {
	*sacloud.ResultFlagValue
	*sacloud.LoadBalancer `json:"Appliance,omitempty"`
	Success               interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
}

type LoadBalancerAPI struct {
	*baseAPI
}

func NewLoadBalancerAPI(client *Client) *LoadBalancerAPI {
	return &LoadBalancerAPI{
		&baseAPI{
			client: client,
			FuncGetResourceURL: func() string {
				return "appliance"
			},
			FuncBaseSearchCondition: func() *sacloud.Request {
				res := &sacloud.Request{}
				res.AddFilter("Class", "loadbalancer")
				return res
			},
		},
	}
}

func (api *LoadBalancerAPI) Find() (*SearchLoadBalancerResponse, error) {
	data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
	if err != nil {
		return nil, err
	}
	var res SearchLoadBalancerResponse
	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}
	return &res, nil
}

func (api *LoadBalancerAPI) request(f func(*loadBalanderResponse) error) (*sacloud.LoadBalancer, error) {
	res := &loadBalanderResponse{}
	err := f(res)
	if err != nil {
		return nil, err
	}
	return res.LoadBalancer, nil
}

func (api *LoadBalancerAPI) createRequest(value *sacloud.LoadBalancer) *loadBalanderResponse {
	return &loadBalanderResponse{LoadBalancer: value}
}

//func (api *LoadBalancerAPI) New() *sacloud.LoadBalancer {
//	return sacloud.CreateNewLoadBalancer()
//}

func (api *LoadBalancerAPI) Create(value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalanderResponse) error {
		return api.create(api.createRequest(value), res)
	})
}

func (api *LoadBalancerAPI) Read(id string) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalanderResponse) error {
		return api.read(id, nil, res)
	})
}

func (api *LoadBalancerAPI) Update(id string, value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalanderResponse) error {
		return api.update(id, api.createRequest(value), res)
	})
}

func (api *LoadBalancerAPI) Delete(id string) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalanderResponse) error {
		return api.delete(id, nil, res)
	})
}

func (api *LoadBalancerAPI) Config(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/config", api.getResourceURL(), id)
	)
	return api.modify(method, uri, nil)
}

func (api *LoadBalancerAPI) IsUp(id string) (bool, error) {
	lb, err := api.Read(id)
	if err != nil {
		return false, err
	}
	return lb.Instance.IsUp(), nil
}

func (api *LoadBalancerAPI) IsDown(id string) (bool, error) {
	lb, err := api.Read(id)
	if err != nil {
		return false, err
	}
	return lb.Instance.IsDown(), nil
}

// Boot power on
func (api *LoadBalancerAPI) Boot(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)
	return api.modify(method, uri, nil)
}

// Shutdown power off
func (api *LoadBalancerAPI) Shutdown(id string) (bool, error) {
	var (
		method = "DELETE"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)

	return api.modify(method, uri, nil)
}

// Stop force shutdown
func (api *LoadBalancerAPI) Stop(id string) (bool, error) {
	var (
		method = "DELETE"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)

	return api.modify(method, uri, map[string]bool{"Force": true})
}

func (api *LoadBalancerAPI) RebootForce(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/reset", api.getResourceURL(), id)
	)

	return api.modify(method, uri, nil)
}

func (api *LoadBalancerAPI) ResetForce(id string, recycleProcess bool) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/reset", api.getResourceURL(), id)
	)

	return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
}

func (api *LoadBalancerAPI) SleepUntilUp(id string, timeout time.Duration) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	for {

		up, err := api.IsUp(id)
		if err != nil {
			return err
		}

		if up {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: WaitforAvailable")
		}
	}
}

func (api *LoadBalancerAPI) SleepUntilDown(id string, timeout time.Duration) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	for {

		down, err := api.IsDown(id)
		if err != nil {
			return err
		}

		if down {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: WaitforAvailable")
		}
	}
}

// SleepWhileCopying wait until became to available
func (api *LoadBalancerAPI) SleepWhileCopying(id string, timeout time.Duration, maxRetryCount int) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	errCount := 0

	for {
		loadBalancer, err := api.Read(id)
		if err != nil {
			errCount++
			if errCount > maxRetryCount {
				return err
			}
		}

		if loadBalancer != nil && loadBalancer.IsAvailable() {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: SleepWhileCopying")
		}
	}
}
<commit_msg>Fix typo<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"github.com/yamamoto-febc/libsacloud/sacloud"
	"time"
)

//HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため
//      ロードバランサ/VPCルータそれぞれでリクエスト/レスポンスデータ型を定義する。

type SearchLoadBalancerResponse struct {
	Total         int                    `json:",omitempty"`
	From          int                    `json:",omitempty"`
	Count         int                    `json:",omitempty"`
	LoadBalancers []sacloud.LoadBalancer `json:"Appliances,omitempty"`
}

type loadBalancerRequest struct {
	LoadBalancer *sacloud.LoadBalancer  `json:"Appliance,omitempty"`
	From         int                    `json:",omitempty"`
	Count        int                    `json:",omitempty"`
	Sort         []string               `json:",omitempty"`
	Filter       map[string]interface{} `json:",omitempty"`
	Exclude      []string               `json:",omitempty"`
	Include      []string               `json:",omitempty"`
}

type loadBalancerResponse struct {
	*sacloud.ResultFlagValue
	*sacloud.LoadBalancer `json:"Appliance,omitempty"`
	Success               interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
}

type LoadBalancerAPI struct {
	*baseAPI
}

func NewLoadBalancerAPI(client *Client) *LoadBalancerAPI {
	return &LoadBalancerAPI{
		&baseAPI{
			client: client,
			FuncGetResourceURL: func() string {
				return "appliance"
			},
			FuncBaseSearchCondition: func() *sacloud.Request {
				res := &sacloud.Request{}
				res.AddFilter("Class", "loadbalancer")
				return res
			},
		},
	}
}

func (api *LoadBalancerAPI) Find() (*SearchLoadBalancerResponse, error) {
	data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
	if err != nil {
		return nil, err
	}
	var res SearchLoadBalancerResponse
	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}
	return &res, nil
}

func (api *LoadBalancerAPI) request(f func(*loadBalancerResponse) error) (*sacloud.LoadBalancer, error) {
	res := &loadBalancerResponse{}
	err := f(res)
	if err != nil {
		return nil, err
	}
	return res.LoadBalancer, nil
}

func (api *LoadBalancerAPI) createRequest(value *sacloud.LoadBalancer) *loadBalancerResponse {
	return &loadBalancerResponse{LoadBalancer: value}
}

//func (api *LoadBalancerAPI) New() *sacloud.LoadBalancer {
//	return sacloud.CreateNewLoadBalancer()
//}

func (api *LoadBalancerAPI) Create(value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalancerResponse) error {
		return api.create(api.createRequest(value), res)
	})
}

func (api *LoadBalancerAPI) Read(id string) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalancerResponse) error {
		return api.read(id, nil, res)
	})
}

func (api *LoadBalancerAPI) Update(id string, value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalancerResponse) error {
		return api.update(id, api.createRequest(value), res)
	})
}

func (api *LoadBalancerAPI) Delete(id string) (*sacloud.LoadBalancer, error) {
	return api.request(func(res *loadBalancerResponse) error {
		return api.delete(id, nil, res)
	})
}

func (api *LoadBalancerAPI) Config(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/config", api.getResourceURL(), id)
	)
	return api.modify(method, uri, nil)
}

func (api *LoadBalancerAPI) IsUp(id string) (bool, error) {
	lb, err := api.Read(id)
	if err != nil {
		return false, err
	}
	return lb.Instance.IsUp(), nil
}

func (api *LoadBalancerAPI) IsDown(id string) (bool, error) {
	lb, err := api.Read(id)
	if err != nil {
		return false, err
	}
	return lb.Instance.IsDown(), nil
}

// Boot power on
func (api *LoadBalancerAPI) Boot(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)
	return api.modify(method, uri, nil)
}

// Shutdown power off
func (api *LoadBalancerAPI) Shutdown(id string) (bool, error) {
	var (
		method = "DELETE"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)

	return api.modify(method, uri, nil)
}

// Stop force shutdown
func (api *LoadBalancerAPI) Stop(id string) (bool, error) {
	var (
		method = "DELETE"
		uri    = fmt.Sprintf("%s/%s/power", api.getResourceURL(), id)
	)

	return api.modify(method, uri, map[string]bool{"Force": true})
}

func (api *LoadBalancerAPI) RebootForce(id string) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/reset", api.getResourceURL(), id)
	)

	return api.modify(method, uri, nil)
}

func (api *LoadBalancerAPI) ResetForce(id string, recycleProcess bool) (bool, error) {
	var (
		method = "PUT"
		uri    = fmt.Sprintf("%s/%s/reset", api.getResourceURL(), id)
	)

	return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
}

func (api *LoadBalancerAPI) SleepUntilUp(id string, timeout time.Duration) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	for {

		up, err := api.IsUp(id)
		if err != nil {
			return err
		}

		if up {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: WaitforAvailable")
		}
	}
}

func (api *LoadBalancerAPI) SleepUntilDown(id string, timeout time.Duration) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	for {

		down, err := api.IsDown(id)
		if err != nil {
			return err
		}

		if down {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: WaitforAvailable")
		}
	}
}

// SleepWhileCopying wait until became to available
func (api *LoadBalancerAPI) SleepWhileCopying(id string, timeout time.Duration, maxRetryCount int) error {
	current := 0 * time.Second
	interval := 5 * time.Second
	errCount := 0

	for {
		loadBalancer, err := api.Read(id)
		if err != nil {
			errCount++
			if errCount > maxRetryCount {
				return err
			}
		}

		if loadBalancer != nil && loadBalancer.IsAvailable() {
			return nil
		}
		time.Sleep(interval)
		current += interval

		if timeout > 0 && current > timeout {
			return fmt.Errorf("Timeout: SleepWhileCopying")
		}
	}
}
<|endoftext|>


<commit_before>package egoscale

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
	"strings"
)

func (exo *Client) GetSecurityGroups() (map[string]string, error) {
	var sgs map[string]string
	params := url.Values{}
	resp, err := exo.Request("listSecurityGroups", params)

	if err != nil {
		return nil, err
	}

	var r ListSecurityGroupsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	sgs = make(map[string]string)
	for _, sg := range r.SecurityGroups {
		sgs[sg.Name] = sg.Id
	}
	return sgs, nil
}

func (exo *Client) GetSecurityGroupId(name string) (string, error) {
	params := url.Values{}
	resp, err := exo.Request("listSecurityGroups", params); if err != nil {
		return "", err
	}

	var r ListSecurityGroupsResponse
	err = json.Unmarshal(resp, &r); if err != nil {
		return "", err
	}

	for _, sg := range r.SecurityGroups {
		if sg.Name == name {
			return sg.Id, nil
		}
	}

	return "", nil
}

func (exo *Client) GetZones() (map[string]string, error) {
	var zones map[string]string
	params := url.Values{}
	resp, err := exo.Request("listZones", params)

	if err != nil {
		return nil, err
	}

	var r ListZonesResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	zones = make(map[string]string)
	for _, zone := range r.Zones {
		zones[zone.Name] = zone.Id
	}
	return zones, nil
}

func (exo *Client) GetProfiles() (map[string]string, error) {

	var profiles map[string]string
	params := url.Values{}
	resp, err := exo.Request("listServiceOfferings", params)

	if err != nil {
		return nil, err
	}

	var r ListServiceOfferingsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	profiles = make(map[string]string)
	for _, offering := range r.ServiceOfferings {
		profiles[strings.ToLower(offering.Name)] = offering.Id
	}

	return profiles, nil
}

func (exo *Client) GetKeypairs() ([]SSHKeyPair, error) {
	params := url.Values{}

	resp, err := exo.Request("listSSHKeyPairs", params)

	if err != nil {
		return nil, err
	}

	var r ListSSHKeyPairsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	var keypairs = make([]SSHKeyPair, r.Count, r.Count)
	for i, keypair := range r.SSHKeyPairs {
		keypairs[i] = *keypair
	}
	return keypairs, nil
}

func (exo *Client) GetAffinityGroups() (map[string]string, error) {
	var affinitygroups map[string]string
	params := url.Values{}

	resp, err := exo.Request("listAffinityGroups", params)

	if err != nil {
		return nil, err
	}

	var r ListAffinityGroupsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	affinitygroups = make(map[string]string)
	for _, affinitygroup := range r.AffinityGroups {
		affinitygroups[affinitygroup.Name] = affinitygroup.Id
	}
	return affinitygroups, nil

}

func (exo *Client) GetImages() (map[string]map[int]string, error) {
	var images map[string]map[int]string
	images = make(map[string]map[int]string)

	params := url.Values{}
	params.Set("templatefilter", "executable")

	resp, err := exo.Request("listTemplates", params)

	if err != nil {
		return nil, err
	}

	var r ListTemplatesResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	re := regexp.MustCompile(`^Linux (?P<name>.+?) (?P<version>[0-9.]+).*$`)
	for _, template := range r.Templates {
		size := int(template.Size / (1024 * 1024 * 1024))
		submatch := re.FindStringSubmatch(template.Name)
		if len(submatch) > 0 {
			name := strings.Replace(strings.ToLower(submatch[1]), " ", "-", -1)
			version := submatch[2]
			image := fmt.Sprintf("%s-%s", name, version)

			_, present := images[image]
			if !present {
				images[image] = make(map[int]string)
			}
			images[image][size] = template.Id

			images[fmt.Sprintf("%s-%s", name, version)][size] = template.Id
		}
	}
	return images, nil
}

func (exo *Client) GetTopology() (*Topology, error) {

	zones, err := exo.GetZones()
	if err != nil {
		return nil, err
	}
	images, err := exo.GetImages()
	if err != nil {
		return nil, err
	}
	groups, err := exo.GetSecurityGroups()
	if err != nil {
		return nil, err
	}
	keypairs, err := exo.GetKeypairs()
	if err != nil {
		return nil, err
	}

	/* Convert the ssh keypair to contain just the name */
	keynames := make([]string, len(keypairs))
	for i, k := range keypairs {
		keynames[i] = k.Name
	}

	affinitygroups, err := exo.GetAffinityGroups()
	if err != nil {
		return nil, err
	}
	profiles, err := exo.GetProfiles()
	if err != nil {
		return nil, err
	}

	topo := &Topology{
		Zones:          zones,
		Profiles:       profiles,
		Images:         images,
		Keypairs:       keynames,
		AffinityGroups: affinitygroups,
		SecurityGroups: groups,
	}

	return topo, nil
}
<commit_msg>Added retrieval of full SecurityGroup data<commit_after>package egoscale

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
	"strings"
)

func (exo *Client) GetSecurityGroups() (map[string]SecurityGroup, error) {
	var sgs map[string]SecurityGroup
	params := url.Values{}
	resp, err := exo.Request("listSecurityGroups", params)

	if err != nil {
		return nil, err
	}

	var r ListSecurityGroupsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	sgs = make(map[string]SecurityGroup)
	for _, sg := range r.SecurityGroups {
		sgs[sg.Name] = *sg
	}
	return sgs, nil
}

func (exo *Client) GetSecurityGroupId(name string) (string, error) {
	params := url.Values{}
	resp, err := exo.Request("listSecurityGroups", params); if err != nil {
		return "", err
	}

	var r ListSecurityGroupsResponse
	err = json.Unmarshal(resp, &r); if err != nil {
		return "", err
	}

	for _, sg := range r.SecurityGroups {
		if sg.Name == name {
			return sg.Id, nil
		}
	}

	return "", nil
}

func (exo *Client) GetZones() (map[string]string, error) {
	var zones map[string]string
	params := url.Values{}
	resp, err := exo.Request("listZones", params)

	if err != nil {
		return nil, err
	}

	var r ListZonesResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	zones = make(map[string]string)
	for _, zone := range r.Zones {
		zones[zone.Name] = zone.Id
	}
	return zones, nil
}

func (exo *Client) GetProfiles() (map[string]string, error) {

	var profiles map[string]string
	params := url.Values{}
	resp, err := exo.Request("listServiceOfferings", params)

	if err != nil {
		return nil, err
	}

	var r ListServiceOfferingsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	profiles = make(map[string]string)
	for _, offering := range r.ServiceOfferings {
		profiles[strings.ToLower(offering.Name)] = offering.Id
	}

	return profiles, nil
}

func (exo *Client) GetKeypairs() ([]SSHKeyPair, error) {
	params := url.Values{}

	resp, err := exo.Request("listSSHKeyPairs", params)

	if err != nil {
		return nil, err
	}

	var r ListSSHKeyPairsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	var keypairs = make([]SSHKeyPair, r.Count, r.Count)
	for i, keypair := range r.SSHKeyPairs {
		keypairs[i] = *keypair
	}
	return keypairs, nil
}

func (exo *Client) GetAffinityGroups() (map[string]string, error) {
	var affinitygroups map[string]string
	params := url.Values{}

	resp, err := exo.Request("listAffinityGroups", params)

	if err != nil {
		return nil, err
	}

	var r ListAffinityGroupsResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	affinitygroups = make(map[string]string)
	for _, affinitygroup := range r.AffinityGroups {
		affinitygroups[affinitygroup.Name] = affinitygroup.Id
	}
	return affinitygroups, nil

}

func (exo *Client) GetImages() (map[string]map[int]string, error) {
	var images map[string]map[int]string
	images = make(map[string]map[int]string)

	params := url.Values{}
	params.Set("templatefilter", "executable")

	resp, err := exo.Request("listTemplates", params)

	if err != nil {
		return nil, err
	}

	var r ListTemplatesResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	re := regexp.MustCompile(`^Linux (?P<name>.+?) (?P<version>[0-9.]+).*$`)
	for _, template := range r.Templates {
		size := int(template.Size / (1024 * 1024 * 1024))
		submatch := re.FindStringSubmatch(template.Name)
		if len(submatch) > 0 {
			name := strings.Replace(strings.ToLower(submatch[1]), " ", "-", -1)
			version := submatch[2]
			image := fmt.Sprintf("%s-%s", name, version)

			_, present := images[image]
			if !present {
				images[image] = make(map[int]string)
			}
			images[image][size] = template.Id

			images[fmt.Sprintf("%s-%s", name, version)][size] = template.Id
		}
	}
	return images, nil
}

func (exo *Client) GetTopology() (*Topology, error) {

	zones, err := exo.GetZones()
	if err != nil {
		return nil, err
	}
	images, err := exo.GetImages()
	if err != nil {
		return nil, err
	}
	securityGroups, err := exo.GetSecurityGroups()
	if err != nil {
		return nil, err
	}
	groups := make(map[string]string)
	for k,v := range securityGroups {
		groups[k] = v.Id
	}

	keypairs, err := exo.GetKeypairs()
	if err != nil {
		return nil, err
	}

	/* Convert the ssh keypair to contain just the name */
	keynames := make([]string, len(keypairs))
	for i, k := range keypairs {
		keynames[i] = k.Name
	}

	affinitygroups, err := exo.GetAffinityGroups()
	if err != nil {
		return nil, err
	}
	profiles, err := exo.GetProfiles()
	if err != nil {
		return nil, err
	}

	topo := &Topology{
		Zones:          zones,
		Profiles:       profiles,
		Images:         images,
		Keypairs:       keynames,
		AffinityGroups: affinitygroups,
		SecurityGroups: groups,
	}

	return topo, nil
}
<|endoftext|>


<commit_before>package addrs

import (
	"fmt"

	"github.com/hashicorp/terraform/tfdiags"

	"github.com/hashicorp/hcl2/hcl"
)

// ProviderConfig is the address of a provider configuration.
type ProviderConfig struct {
	Type string

	// If not empty, Alias identifies which non-default (aliased) provider
	// configuration this address refers to.
	Alias string
}

// NewDefaultProviderConfig returns the address of the default (un-aliased)
// configuration for the provider with the given type name.
func NewDefaultProviderConfig(typeName string) ProviderConfig {
	return ProviderConfig{
		Type: typeName,
	}
}

// ParseProviderConfigCompact parses the given absolute traversal as a relative
// provider address in compact form. The following are examples of traversals
// that can be successfully parsed as compact relative provider configuration
// addresses:
//
//     aws
//     aws.foo
//
// This function will panic if given a relative traversal.
//
// If the returned diagnostics contains errors then the result value is invalid
// and must not be used.
func ParseProviderConfigCompact(traversal hcl.Traversal) (ProviderConfig, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := ProviderConfig{
		Type: traversal.RootName(),
	}

	if len(traversal) < 2 {
		// Just a type name, then.
		return ret, diags
	}

	aliasStep := traversal[1]
	switch ts := aliasStep.(type) {
	case hcl.TraverseAttr:
		ret.Alias = ts.Name
		return ret, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The provider type name must either stand alone or be followed by an alias name separated with a dot.",
			Subject:  aliasStep.SourceRange().Ptr(),
		})
	}

	if len(traversal) > 2 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous extra operators after provider configuration address.",
			Subject:  traversal[2:].SourceRange().Ptr(),
		})
	}

	return ret, diags
}

// Absolute returns an AbsProviderConfig from the receiver and the given module
// instance address.
func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig {
	return AbsProviderConfig{
		Module:         module,
		ProviderConfig: pc,
	}
}

func (pc ProviderConfig) String() string {
	if pc.Alias != "" {
		return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias)
	}

	return "provider." + pc.Type
}

// StringCompact is an alternative to String that returns the form that can
// be parsed by ParseProviderConfigCompact, without the "provider." prefix.
func (pc ProviderConfig) StringCompact() string {
	if pc.Alias != "" {
		return fmt.Sprintf("%s.%s", pc.Type, pc.Alias)
	}
	return pc.Type
}

// AbsProviderConfig is the absolute address of a provider configuration
// within a particular module instance.
type AbsProviderConfig struct {
	Module         ModuleInstance
	ProviderConfig ProviderConfig
}

// ParseAbsProviderConfig parses the given traversal as an absolute provider
// address. The following are examples of traversals that can be successfully
// parsed as absolute provider configuration addresses:
//
//     provider.aws
//     provider.aws.foo
//     module.bar.provider.aws
//     module.bar.module.baz.provider.aws.foo
//     module.foo[1].provider.aws.foo
//
// This type of address is used, for example, to record the relationships
// between resources and provider configurations in the state structure.
// This type of address is not generally used in the UI, except in error
// messages that refer to provider configurations.
func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) {
	modInst, remain, diags := parseModuleInstancePrefix(traversal)
	ret := AbsProviderConfig{
		Module: modInst,
	}
	if len(remain) < 2 || remain.RootName() != "provider" {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Provider address must begin with \"provider.\", followed by a provider type name.",
			Subject:  remain.SourceRange().Ptr(),
		})
		return ret, diags
	}
	if len(remain) > 3 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous operators after provider configuration alias.",
			Subject:  hcl.Traversal(remain[3:]).SourceRange().Ptr(),
		})
		return ret, diags
	}

	if tt, ok := remain[1].(hcl.TraverseAttr); ok {
		ret.ProviderConfig.Type = tt.Name
	} else {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The prefix \"provider.\" must be followed by a provider type name.",
			Subject:  remain[1].SourceRange().Ptr(),
		})
		return ret, diags
	}

	if len(remain) == 3 {
		if tt, ok := remain[2].(hcl.TraverseAttr); ok {
			ret.ProviderConfig.Alias = tt.Name
		} else {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid provider configuration address",
				Detail:   "Provider type name must be followed by a configuration alias name.",
				Subject:  remain[2].SourceRange().Ptr(),
			})
			return ret, diags
		}
	}

	return ret, diags
}

// ProviderConfigDefault returns the address of the default provider config
// of the given type inside the recieving module instance.
func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type: name,
		},
	}
}

// ProviderConfigAliased returns the address of an aliased provider config
// of with given type and alias inside the recieving module instance.
func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type:  name,
			Alias: alias,
		},
	}
}

// Inherited returns an address that the receiving configuration address might
// inherit from in a parent module. The second bool return value indicates if
// such inheritance is possible, and thus whether the returned address is valid.
//
// Inheritance is possible only for default (un-aliased) providers in modules
// other than the root module. Even if a valid address is returned, inheritence
// may not be performed for other reasons, such as if the calling module
// provided explicit provider configurations within the call for this module.
// The ProviderTransformer graph transform in the main terraform module has
// the authoritative logic for provider inheritance, and this method is here
// mainly just for its benefit.
func (pc AbsProviderConfig) Inherited() (AbsProviderConfig, bool) {
	// Can't inherit if we're already in the root.
	if len(pc.Module) == 0 {
		return AbsProviderConfig{}, false
	}

	// Can't inherit if we have an alias.
	if pc.ProviderConfig.Alias != "" {
		return AbsProviderConfig{}, false
	}

	// Otherwise, we might inherit from a configuration with the same
	// provider name in the parent module instance.
	parentMod := pc.Module.Parent()
	return pc.ProviderConfig.Absolute(parentMod), true
}

func (pc AbsProviderConfig) String() string {
	if len(pc.Module) == 0 {
		return pc.ProviderConfig.String()
	}
	return fmt.Sprintf("%s.%s", pc.Module.String(), pc.ProviderConfig.String())
}
<commit_msg>addrs: Generate special string for invalid ProviderConfig<commit_after>package addrs

import (
	"fmt"

	"github.com/hashicorp/terraform/tfdiags"

	"github.com/hashicorp/hcl2/hcl"
)

// ProviderConfig is the address of a provider configuration.
type ProviderConfig struct {
	Type string

	// If not empty, Alias identifies which non-default (aliased) provider
	// configuration this address refers to.
	Alias string
}

// NewDefaultProviderConfig returns the address of the default (un-aliased)
// configuration for the provider with the given type name.
func NewDefaultProviderConfig(typeName string) ProviderConfig {
	return ProviderConfig{
		Type: typeName,
	}
}

// ParseProviderConfigCompact parses the given absolute traversal as a relative
// provider address in compact form. The following are examples of traversals
// that can be successfully parsed as compact relative provider configuration
// addresses:
//
//     aws
//     aws.foo
//
// This function will panic if given a relative traversal.
//
// If the returned diagnostics contains errors then the result value is invalid
// and must not be used.
func ParseProviderConfigCompact(traversal hcl.Traversal) (ProviderConfig, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := ProviderConfig{
		Type: traversal.RootName(),
	}

	if len(traversal) < 2 {
		// Just a type name, then.
		return ret, diags
	}

	aliasStep := traversal[1]
	switch ts := aliasStep.(type) {
	case hcl.TraverseAttr:
		ret.Alias = ts.Name
		return ret, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The provider type name must either stand alone or be followed by an alias name separated with a dot.",
			Subject:  aliasStep.SourceRange().Ptr(),
		})
	}

	if len(traversal) > 2 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous extra operators after provider configuration address.",
			Subject:  traversal[2:].SourceRange().Ptr(),
		})
	}

	return ret, diags
}

// Absolute returns an AbsProviderConfig from the receiver and the given module
// instance address.
func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig {
	return AbsProviderConfig{
		Module:         module,
		ProviderConfig: pc,
	}
}

func (pc ProviderConfig) String() string {
	if pc.Type == "" {
		// Should never happen; always indicates a bug
		return "provider.<invalid>"
	}

	if pc.Alias != "" {
		return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias)
	}

	return "provider." + pc.Type
}

// StringCompact is an alternative to String that returns the form that can
// be parsed by ParseProviderConfigCompact, without the "provider." prefix.
func (pc ProviderConfig) StringCompact() string {
	if pc.Alias != "" {
		return fmt.Sprintf("%s.%s", pc.Type, pc.Alias)
	}
	return pc.Type
}

// AbsProviderConfig is the absolute address of a provider configuration
// within a particular module instance.
type AbsProviderConfig struct {
	Module         ModuleInstance
	ProviderConfig ProviderConfig
}

// ParseAbsProviderConfig parses the given traversal as an absolute provider
// address. The following are examples of traversals that can be successfully
// parsed as absolute provider configuration addresses:
//
//     provider.aws
//     provider.aws.foo
//     module.bar.provider.aws
//     module.bar.module.baz.provider.aws.foo
//     module.foo[1].provider.aws.foo
//
// This type of address is used, for example, to record the relationships
// between resources and provider configurations in the state structure.
// This type of address is not generally used in the UI, except in error
// messages that refer to provider configurations.
func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) {
	modInst, remain, diags := parseModuleInstancePrefix(traversal)
	ret := AbsProviderConfig{
		Module: modInst,
	}
	if len(remain) < 2 || remain.RootName() != "provider" {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Provider address must begin with \"provider.\", followed by a provider type name.",
			Subject:  remain.SourceRange().Ptr(),
		})
		return ret, diags
	}
	if len(remain) > 3 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous operators after provider configuration alias.",
			Subject:  hcl.Traversal(remain[3:]).SourceRange().Ptr(),
		})
		return ret, diags
	}

	if tt, ok := remain[1].(hcl.TraverseAttr); ok {
		ret.ProviderConfig.Type = tt.Name
	} else {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The prefix \"provider.\" must be followed by a provider type name.",
			Subject:  remain[1].SourceRange().Ptr(),
		})
		return ret, diags
	}

	if len(remain) == 3 {
		if tt, ok := remain[2].(hcl.TraverseAttr); ok {
			ret.ProviderConfig.Alias = tt.Name
		} else {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid provider configuration address",
				Detail:   "Provider type name must be followed by a configuration alias name.",
				Subject:  remain[2].SourceRange().Ptr(),
			})
			return ret, diags
		}
	}

	return ret, diags
}

// ProviderConfigDefault returns the address of the default provider config
// of the given type inside the recieving module instance.
func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type: name,
		},
	}
}

// ProviderConfigAliased returns the address of an aliased provider config
// of with given type and alias inside the recieving module instance.
func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type:  name,
			Alias: alias,
		},
	}
}

// Inherited returns an address that the receiving configuration address might
// inherit from in a parent module. The second bool return value indicates if
// such inheritance is possible, and thus whether the returned address is valid.
//
// Inheritance is possible only for default (un-aliased) providers in modules
// other than the root module. Even if a valid address is returned, inheritence
// may not be performed for other reasons, such as if the calling module
// provided explicit provider configurations within the call for this module.
// The ProviderTransformer graph transform in the main terraform module has
// the authoritative logic for provider inheritance, and this method is here
// mainly just for its benefit.
func (pc AbsProviderConfig) Inherited() (AbsProviderConfig, bool) {
	// Can't inherit if we're already in the root.
	if len(pc.Module) == 0 {
		return AbsProviderConfig{}, false
	}

	// Can't inherit if we have an alias.
	if pc.ProviderConfig.Alias != "" {
		return AbsProviderConfig{}, false
	}

	// Otherwise, we might inherit from a configuration with the same
	// provider name in the parent module instance.
	parentMod := pc.Module.Parent()
	return pc.ProviderConfig.Absolute(parentMod), true
}

func (pc AbsProviderConfig) String() string {
	if len(pc.Module) == 0 {
		return pc.ProviderConfig.String()
	}
	return fmt.Sprintf("%s.%s", pc.Module.String(), pc.ProviderConfig.String())
}
<|endoftext|>


<commit_before>package dmm

import "fmt"

func ExampleApi() {
    api := New("foobarbazbuzz", "dummy-990")
    api.SetSite(SITE_ALLAGES)
    api.SetService("mono")
    api.SetFloor("dvd")
    api.SetSort("date")
    api.SetLength(1)

    result, err := api.Execute()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(result)
    }
}

func ExampleApiOneLiner() {
    rst, err := New("foobarbazbuzz", "dummy-999").SetSite(SITE_ADULT).SetLength(1).Execute()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(rst)
    }
}<commit_msg>rename tests<commit_after>package dmm

import "fmt"

func ExampleExecute() {
    api := New("foobarbazbuzz", "dummy-990")
    api.SetSite(SITE_ALLAGES)
    api.SetService("mono")
    api.SetFloor("dvd")
    api.SetSort("date")
    api.SetLength(1)

    result, err := api.Execute()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(result)
    }
}

func ExampleExecuteOneLiner() {
    rst, err := New("foobarbazbuzz", "dummy-999").SetSite(SITE_ADULT).SetLength(1).Execute()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(rst)
    }
}<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/brnstz/bus/internal/conf"
	"github.com/brnstz/bus/internal/etc"
	"github.com/brnstz/bus/internal/models"
)

func NewHandler() http.Handler {
	mux := http.NewServeMux()

	mux.HandleFunc("/api/v2/stops", getStops)
	mux.Handle("/", http.FileServer(http.Dir(conf.API.WebDir)))

	return mux
}

func floatOrDie(w http.ResponseWriter, r *http.Request, name string) (f float64, err error) {

	val := r.FormValue(name)
	f, err = strconv.ParseFloat(val, 64)
	if err != nil {
		log.Println("bad float value", val, err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	return
}

// stopResponse is the value returned by getStops
type stopResponse struct {
	UpdatedAt time.Time    `json:"updated_at"`
	Results   []stopResult `json:"results"`
}

type stopResult struct {
	Route      *models.Route `json:"route"`
	Stop       *models.Stop  `json:"stop"`
	Departures struct {
		Live      []*models.Departure `json:"live"`
		Scheduled []*models.Departure `json:"scheduled"`
	} `json:"departures"`
	Dist float64 `json:"dist"`
}

func newStopResponse() stopResponse {
	return stopResponse{
		UpdatedAt: time.Now().UTC(),
	}
}

func getStops(w http.ResponseWriter, r *http.Request) {
	var err error

	lat, err := floatOrDie(w, r, "lat")
	if err != nil {
		return
	}

	lon, err := floatOrDie(w, r, "lon")
	if err != nil {
		return
	}

	miles, err := floatOrDie(w, r, "miles")
	if err != nil {
		return
	}

	filter := r.FormValue("filter")

	meters := etc.MileToMeter(miles)

	stops, err := models.GetStopsByLoc(etc.DBConn, lat, lon, meters, filter)
	if err != nil {
		log.Println("can't get stops", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp := newStopResponse()
	resp.Results = make([]stopResult, len(stops))

	for i, stop := range stops {
		resp.Results[i].Route, err = models.GetRoute(stop.RouteID)
		if err != nil {
			log.Println("can't get route for stop", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		resp.Results[i].Stop = stop
		resp.Results[i].Dist = stop.Dist
		resp.Results[i].Departures.Live = stop.Live
		resp.Results[i].Departures.Scheduled = stop.Scheduled
	}

	b, err := json.Marshal(resp)
	if err != nil {
		log.Println("can't marshal to json", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	w.Write(b)
}
<commit_msg>adding result id<commit_after>package api

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/brnstz/bus/internal/conf"
	"github.com/brnstz/bus/internal/etc"
	"github.com/brnstz/bus/internal/models"
)

func NewHandler() http.Handler {
	mux := http.NewServeMux()

	mux.HandleFunc("/api/v2/stops", getStops)
	mux.Handle("/", http.FileServer(http.Dir(conf.API.WebDir)))

	return mux
}

func floatOrDie(w http.ResponseWriter, r *http.Request, name string) (f float64, err error) {

	val := r.FormValue(name)
	f, err = strconv.ParseFloat(val, 64)
	if err != nil {
		log.Println("bad float value", val, err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	return
}

// stopResponse is the value returned by getStops
type stopResponse struct {
	UpdatedAt time.Time    `json:"updated_at"`
	Results   []stopResult `json:"results"`
}

type stopResult struct {
	// ID is a unique ID for this result. For now it is
	// "{route_id}_{stop_id}"
	ID         string        `json:"id"`
	Route      *models.Route `json:"route"`
	Stop       *models.Stop  `json:"stop"`
	Departures struct {
		Live      []*models.Departure `json:"live"`
		Scheduled []*models.Departure `json:"scheduled"`
	} `json:"departures"`
	Dist float64 `json:"dist"`
}

func newStopResponse() stopResponse {
	return stopResponse{
		UpdatedAt: time.Now().UTC(),
	}
}

func getStops(w http.ResponseWriter, r *http.Request) {
	var err error

	lat, err := floatOrDie(w, r, "lat")
	if err != nil {
		return
	}

	lon, err := floatOrDie(w, r, "lon")
	if err != nil {
		return
	}

	miles, err := floatOrDie(w, r, "miles")
	if err != nil {
		return
	}

	filter := r.FormValue("filter")

	meters := etc.MileToMeter(miles)

	stops, err := models.GetStopsByLoc(etc.DBConn, lat, lon, meters, filter)
	if err != nil {
		log.Println("can't get stops", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	resp := newStopResponse()
	resp.Results = make([]stopResult, len(stops))

	for i, stop := range stops {
		resp.Results[i].Route, err = models.GetRoute(stop.RouteID)
		if err != nil {
			log.Println("can't get route for stop", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		resp.Results[i].Stop = stop
		resp.Results[i].Dist = stop.Dist
		resp.Results[i].Departures.Live = stop.Live
		resp.Results[i].Departures.Scheduled = stop.Scheduled

		resp.Results[i].ID = resp.Results[i].Route.ID + "_" + resp.Results[i].Stop.ID
	}

	b, err := json.Marshal(resp)
	if err != nil {
		log.Println("can't marshal to json", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	w.Write(b)
}
<|endoftext|>