<commit_before>// Copyright 2018 The ACH Authors
// Use of this source code is governed by an Apache License
// license that can be found in the LICENSE file.

package ach

import (
	"testing"
)

func mockAddenda02() *Addenda02 {
	addenda02 := NewAddenda02()
	addenda02.ReferenceInformationOne = "REFONEA"
	addenda02.ReferenceInformationTwo = "REF"
	addenda02.TerminalIdentificationCode = "TERM02"
	addenda02.TransactionSerialNumber = "100049"
	addenda02.TransactionDate = "0612"
	addenda02.AuthorizationCodeOrExpireDate = "123456"
	addenda02.TerminalLocation = "Target Store 0049"
	addenda02.TerminalCity = "PHILADELPHIA"
	addenda02.TerminalState = "PA"
	addenda02.TraceNumber = 91012980000088
	return addenda02
}

func TestMockAddenda02(t *testing.T) {
	addenda02 := mockAddenda02()
	if err := addenda02.Validate(); err != nil {
		t.Error("mockAddenda02 does not validate and will break other tests")
	}
}

func testAddenda02ValidRecordType(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.recordType = "63"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "recordType" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02ValidRecordType(t *testing.T) {
	testAddenda02ValidRecordType(t)
}

func BenchmarkAddenda02ValidRecordType(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02ValidRecordType(b)
	}
}

func testAddenda02ValidTypeCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = "65"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "TypeCode" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02ValidTypeCode(t *testing.T) {
	testAddenda02ValidTypeCode(t)
}

func BenchmarkAddenda02ValidTypeCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02ValidTypeCode(b)
	}
}

func testAddenda02TypeCode02(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = "05"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "TypeCode" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02TypeCode02(t *testing.T) {
	testAddenda02TypeCode02(t)
}

func BenchmarkAddenda02TypeCode02(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TypeCode02(b)
	}
}

func testAddenda02RecordType(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.recordType = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02RecordType(t *testing.T) {
	testAddenda02RecordType(t)
}

func BenchmarkAddenda02FieldInclusionRecordType(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02RecordType(b)
	}
}

func testAddenda02TypeCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TypeCode(t *testing.T) {
	testAddenda02TypeCode(t)
}

func BenchmarkAddenda02TypeCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TypeCode(b)
	}
}

func testAddenda02TerminalIdentificationCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalIdentificationCode = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalIdentificationCode(t *testing.T) {
	testAddenda02TerminalIdentificationCode(t)
}

func BenchmarkAddenda02TerminalIdentificationCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalIdentificationCode(b)
	}
}

func testAddenda02TransactionSerialNumber(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TransactionSerialNumber = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TransactionSerialNumber(t *testing.T) {
	testAddenda02TransactionSerialNumber(t)
}

func BenchmarkAddenda02TransactionSerialNumber(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TransactionSerialNumber(b)
	}
}

func testAddenda02TransactionDate(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TransactionDate = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TransactionDate(t *testing.T) {
	testAddenda02TransactionDate(t)
}

func BenchmarkAddenda02TransactionDate(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TransactionDate(b)
	}
}

func testAddenda02TerminalLocation(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalLocation = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalLocation(t *testing.T) {
	testAddenda02TerminalLocation(t)
}

func BenchmarkAddenda02TerminalLocation(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalLocation(b)
	}
}

func testAddenda02TerminalCity(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalCity = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalCity(t *testing.T) {
	testAddenda02TerminalCity(t)
}

func BenchmarkAddenda02TerminalCity(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalCity(b)
	}
}

func testAddenda02TerminalState(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalState = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalState(t *testing.T) {
	testAddenda02TerminalState(t)
}

func BenchmarkAddenda02TerminalState(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalState(b)
	}
}

// TestAddenda02 String validates that a known parsed file can be return to a string of the same value
func testAddenda02String(t testing.TB) {
	addenda02 := NewAddenda02()
	var line = "702REFONEAREFTERM021000490612123456Target Store 0049          PHILADELPHIA   PA091012980000088"
	addenda02.Parse(line)
	if addenda02.String() != line {
		t.Errorf("Strings do not match")
	}
}

func TestAddenda02String(t *testing.T) {
	testAddenda02String(t)
}

func BenchmarkAddenda02String(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02String(b)
	}
}
<commit_msg>ParseAddenda02<commit_after>// Copyright 2018 The ACH Authors
// Use of this source code is governed by an Apache License
// license that can be found in the LICENSE file.

package ach

import (
	"testing"
)

func mockAddenda02() *Addenda02 {
	addenda02 := NewAddenda02()
	addenda02.ReferenceInformationOne = "REFONEA"
	addenda02.ReferenceInformationTwo = "REF"
	addenda02.TerminalIdentificationCode = "TERM02"
	addenda02.TransactionSerialNumber = "100049"
	addenda02.TransactionDate = "0612"
	addenda02.AuthorizationCodeOrExpireDate = "123456"
	addenda02.TerminalLocation = "Target Store 0049"
	addenda02.TerminalCity = "PHILADELPHIA"
	addenda02.TerminalState = "PA"
	addenda02.TraceNumber = 91012980000088
	return addenda02
}

func TestMockAddenda02(t *testing.T) {
	addenda02 := mockAddenda02()
	if err := addenda02.Validate(); err != nil {
		t.Error("mockAddenda02 does not validate and will break other tests")
	}
}

func testAddenda02ValidRecordType(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.recordType = "63"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "recordType" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02ValidRecordType(t *testing.T) {
	testAddenda02ValidRecordType(t)
}

func BenchmarkAddenda02ValidRecordType(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02ValidRecordType(b)
	}
}

func testAddenda02ValidTypeCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = "65"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "TypeCode" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02ValidTypeCode(t *testing.T) {
	testAddenda02ValidTypeCode(t)
}

func BenchmarkAddenda02ValidTypeCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02ValidTypeCode(b)
	}
}

func testAddenda02TypeCode02(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = "05"
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.FieldName != "TypeCode" {
				t.Errorf("%T: %s", err, err)
			}
		} else {
			t.Errorf("%T: %s", err, err)
		}
	}
}
func TestAddenda02TypeCode02(t *testing.T) {
	testAddenda02TypeCode02(t)
}

func BenchmarkAddenda02TypeCode02(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TypeCode02(b)
	}
}

func testAddenda02RecordType(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.recordType = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02RecordType(t *testing.T) {
	testAddenda02RecordType(t)
}

func BenchmarkAddenda02FieldInclusionRecordType(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02RecordType(b)
	}
}

func testAddenda02TypeCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.typeCode = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TypeCode(t *testing.T) {
	testAddenda02TypeCode(t)
}

func BenchmarkAddenda02TypeCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TypeCode(b)
	}
}

func testAddenda02TerminalIdentificationCode(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalIdentificationCode = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalIdentificationCode(t *testing.T) {
	testAddenda02TerminalIdentificationCode(t)
}

func BenchmarkAddenda02TerminalIdentificationCode(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalIdentificationCode(b)
	}
}

func testAddenda02TransactionSerialNumber(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TransactionSerialNumber = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TransactionSerialNumber(t *testing.T) {
	testAddenda02TransactionSerialNumber(t)
}

func BenchmarkAddenda02TransactionSerialNumber(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TransactionSerialNumber(b)
	}
}

func testAddenda02TransactionDate(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TransactionDate = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TransactionDate(t *testing.T) {
	testAddenda02TransactionDate(t)
}

func BenchmarkAddenda02TransactionDate(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TransactionDate(b)
	}
}

func testAddenda02TerminalLocation(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalLocation = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalLocation(t *testing.T) {
	testAddenda02TerminalLocation(t)
}

func BenchmarkAddenda02TerminalLocation(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalLocation(b)
	}
}

func testAddenda02TerminalCity(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalCity = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalCity(t *testing.T) {
	testAddenda02TerminalCity(t)
}

func BenchmarkAddenda02TerminalCity(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalCity(b)
	}
}

func testAddenda02TerminalState(t testing.TB) {
	addenda02 := mockAddenda02()
	addenda02.TerminalState = ""
	if err := addenda02.Validate(); err != nil {
		if e, ok := err.(*FieldError); ok {
			if e.Msg != msgFieldInclusion {
				t.Errorf("%T: %s", err, err)
			}
		}
	}
}

func TestAddenda02TerminalState(t *testing.T) {
	testAddenda02TerminalState(t)
}

func BenchmarkAddenda02TerminalState(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02TerminalState(b)
	}
}

// TestAddenda02 String validates that a known parsed file can be return to a string of the same value
func testAddenda02String(t testing.TB) {
	addenda02 := NewAddenda02()
	var line = "702REFONEAREFTERM021000490612123456Target Store 0049          PHILADELPHIA   PA091012980000088"
	addenda02.Parse(line)
	if addenda02.String() != line {
		t.Errorf("Strings do not match")
	}
}

func TestAddenda02String(t *testing.T) {
	testAddenda02String(t)
}

func BenchmarkAddenda02String(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testAddenda02String(b)
	}
}

func testParseAddenda02(t testing.TB) {
	addendaPOS := NewAddenda02()
	var line = "702REFONEAREFTERM021000490612123456Target Store 0049          PHILADELPHIA   PA091012980000088"
	addendaPOS.Parse(line)

	if addendaPOS.recordType != "7" {
		t.Errorf("RecordType Expected '7' got: %v", addendaPOS.recordType)
	}
	if addendaPOS.TypeCode() != "02" {
		t.Errorf("TypeCode Expected 02 got: %v", addendaPOS.TypeCode())
	}
	if addendaPOS.ReferenceInformationOne != "REFONEA" {
		t.Errorf("ReferenceInformationOne Expected 'REFONEA' got: %v", addendaPOS.ReferenceInformationOneField())
	}
	if addendaPOS.ReferenceInformationTwo != "REF" {
		t.Errorf("ReferenceInformationTwo Expected 'REF' got: %v", addendaPOS.ReferenceInformationTwoField())
	}
	if addendaPOS.TerminalIdentificationCode != "TERM02" {
		t.Errorf("TerminalIdentificationCode Expected 'TERM02' got: %v", addendaPOS.TerminalIdentificationCodeField())
	}
	if addendaPOS.TransactionSerialNumber != "100049" {
		t.Errorf("TransactionSerialNumber Expected '100049' got: %v", addendaPOS.TransactionSerialNumberField())
	}
	if addendaPOS.TransactionDate != "0612" {
		t.Errorf("TransactionDate Expected '0612' got: %v", addendaPOS.TransactionDateField())
	}
	if addendaPOS.AuthorizationCodeOrExpireDate != "123456" {
		t.Errorf("AuthorizationCodeOrExpireDate Expected '123456' got: %v", addendaPOS.AuthorizationCodeOrExpireDateField())
	}
	if addendaPOS.TerminalLocation != "Target Store 0049" {
		t.Errorf("TerminalLocation Expected 'Target Store 0049' got: %v", addendaPOS.TerminalLocationField())
	}
	if addendaPOS.TerminalCity != "PHILADELPHIA" {
		t.Errorf("TerminalCity Expected '123456' got: %v", addendaPOS.TerminalCityField())
	}
	if addendaPOS.TerminalState != "PA" {
		t.Errorf("TerminalState Expected '123456' got: %v", addendaPOS.TerminalStateField())
	}
	if addendaPOS.TraceNumber != 91012980000088 {
		t.Errorf("TraceNumber Expected '91012980000088' got: %v", addendaPOS.TraceNumberField())
	}
}

func TestParseAddenda02(t *testing.T) {
	testParseAddenda02(t)
}

func BenchmarkParseAddenda02(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		testParseAddenda02(b)
	}
}<|endoftext|>


<commit_before>package gogl

import "sync"

// VertexSet uses maps to express a value-less (empty struct), indexed
// unordered list. See
// https://groups.google.com/forum/#!searchin/golang-nuts/map/golang-nuts/H2cXpwisEUE/1X2FV-rODfIJ
type VertexSet map[Vertex]struct{}
type adjacencyList map[Vertex]VertexSet

// Helper to not have to write struct{} everywhere.
var keyExists = struct{}{}

type AdjacencyList struct {
	adjacencyList
	size uint
	mu   sync.RWMutex
}

// Composite literal to create a new AdjacencyList.
func NewAdjacencyList() *AdjacencyList {
	return &AdjacencyList{
		adjacencyList: make(map[Vertex]VertexSet)}
}

func (g *AdjacencyList) EachVertex(f func(vertex Vertex)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	for v := range g.adjacencyList {
		f(v)
	}
}

func (g *AdjacencyList) EachEdge(f func(edge Edge)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	for source, adjacent := range g.adjacencyList {
		for _, target := range adjacent {
			f(BaseEdge{u: source, v: target})
		}
	}
}

func (g *AdjacencyList) EachAdjacent(vertex Vertex, f func(target Vertex)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	if _, exists := g.adjacencyList[vertex]; exists {
		for adjacent, _ := range g.adjacencyList[vertex] {
			f(adjacent)
		}
	}
}

func (g *AdjacencyList) HasVertex(vertex Vertex) (exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	exists = g.hasVertex(vertex)
	return
}

func (g *AdjacencyList) OutDegree(vertex Vertex) (degree uint, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	if exists = g.hasVertex(vertex); exists {
		degree = uint(len(g.adjacencyList[vertex]))
	}
	return
}

// Getting InDegree is highly inefficient for directed adjacency lists
func (g *AdjacencyList) InDegree(vertex Vertex) (degree uint, exists bool) {
	// locking done by the called methods
	if exists = g.HasVertex(vertex); exists {

		f := func(v Vertex) {
			if v == vertex {
				degree++
			}
		}
		g.EachVertex(f)
	}

	return
}

func (g *AdjacencyList) hasVertex(vertex Vertex) (exists bool) {
	_, exists = g.adjacencyList[vertex]
	return
}

func (g *AdjacencyList) Order() (length uint) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	length = uint(len(g.adjacencyList))

	g.mu.RUnlock()
	return
}

func (g *AdjacencyList) Size() uint {
	return g.size
}

func (g *AdjacencyList) Density() float64 {
	g.mu.RLock()
	defer g.mu.RUnlock()

	order := float64(g.Order())
	return (2 * float64(g.Size())) / (order * (order - 1))
}

func (g *AdjacencyList) AddVertex(vertex Vertex) (success bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	success = g.addVertex(vertex)
	return
}

func (g *AdjacencyList) addVertex(vertex Vertex) (success bool) {
	if exists := g.hasVertex(vertex); !exists {
		// TODO experiment with different lengths...possibly by analyzing existing density?
		g.adjacencyList[vertex] = make(VertexSet, 10)
		success = true
	}

	return
}

func (g *AdjacencyList) RemoveVertex(vertex Vertex) (success bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	if g.hasVertex(vertex) {
		// TODO Is the expensive search good to do here and now...
		// while read-locked?
		delete(g.adjacencyList, vertex)

		// TODO consider chunking the list and parallelizing into goroutines
		for _, adjacent := range g.adjacencyList {
			if _, has := adjacent[vertex]; has {
				delete(adjacent, vertex)
				g.size--
			}
		}

		success = true
	}
	return
}

func (g *AdjacencyList) AddEdge(edge Edge) (exists bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	g.addVertex(edge.Source())
	g.addVertex(edge.Target())

	if _, exists = g.adjacencyList[edge.Source()][edge.Target]; !exists {
		g.adjacencyList[edge.Source()][edge.Target()] = keyExists
	}
	return !exists
}

func (g *AdjacencyList) RemoveEdge(edge Edge) {
	g.mu.Lock()
	defer g.mu.Unlock()

	delete(g.adjacencyList, edge.Source())
}
<commit_msg>Fix a few typoish mistakes<commit_after>package gogl

import "sync"

// VertexSet uses maps to express a value-less (empty struct), indexed
// unordered list. See
// https://groups.google.com/forum/#!searchin/golang-nuts/map/golang-nuts/H2cXpwisEUE/1X2FV-rODfIJ
type VertexSet map[Vertex]struct{}
type adjacencyList map[Vertex]VertexSet

// Helper to not have to write struct{} everywhere.
var keyExists = struct{}{}

type AdjacencyList struct {
	adjacencyList
	size uint
	mu   sync.RWMutex
}

// Composite literal to create a new AdjacencyList.
func NewAdjacencyList() *AdjacencyList {
	return &AdjacencyList{
		adjacencyList: make(map[Vertex]VertexSet)}
}

func (g *AdjacencyList) EachVertex(f func(vertex Vertex)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	for v := range g.adjacencyList {
		f(v)
	}
}

func (g *AdjacencyList) EachEdge(f func(edge Edge)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	for source, adjacent := range g.adjacencyList {
		for _, target := range adjacent {
			f(BaseEdge{u: source, v: target})
		}
	}
}

func (g *AdjacencyList) EachAdjacent(vertex Vertex, f func(target Vertex)) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	if _, exists := g.adjacencyList[vertex]; exists {
		for adjacent, _ := range g.adjacencyList[vertex] {
			f(adjacent)
		}
	}
}

func (g *AdjacencyList) HasVertex(vertex Vertex) (exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	exists = g.hasVertex(vertex)
	return
}

func (g *AdjacencyList) OutDegree(vertex Vertex) (degree uint, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	if exists = g.hasVertex(vertex); exists {
		degree = uint(len(g.adjacencyList[vertex]))
	}
	return
}

// Getting InDegree is highly inefficient for directed adjacency lists
func (g *AdjacencyList) InDegree(vertex Vertex) (degree uint, exists bool) {
	// locking done by the called methods
	if exists = g.HasVertex(vertex); exists {

		f := func(v Vertex) {
			if v == vertex {
				degree++
			}
		}
		g.EachVertex(f)
	}

	return
}

func (g *AdjacencyList) hasVertex(vertex Vertex) (exists bool) {
	_, exists = g.adjacencyList[vertex]
	return
}

func (g *AdjacencyList) Order() (length uint) {
	g.mu.RLock()
	defer g.mu.RUnlock()

	length = uint(len(g.adjacencyList))

	g.mu.RUnlock()
	return
}

func (g *AdjacencyList) Size() uint {
	return g.size
}

func (g *AdjacencyList) Density() float64 {
	g.mu.RLock()
	defer g.mu.RUnlock()

	order := float64(g.Order())
	return (2 * float64(g.Size())) / (order * (order - 1))
}

func (g *AdjacencyList) AddVertex(vertex Vertex) (success bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	success = g.addVertex(vertex)
	return
}

func (g *AdjacencyList) addVertex(vertex Vertex) (success bool) {
	if exists := g.hasVertex(vertex); !exists {
		// TODO experiment with different lengths...possibly by analyzing existing density?
		g.adjacencyList[vertex] = make(VertexSet, 10)
		success = true
	}

	return
}

func (g *AdjacencyList) RemoveVertex(vertex Vertex) (success bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	if g.hasVertex(vertex) {
		// TODO Is the expensive search good to do here and now...
		// while read-locked?
		delete(g.adjacencyList, vertex)

		// TODO consider chunking the list and parallelizing into goroutines
		for _, adjacent := range g.adjacencyList {
			if _, has := adjacent[vertex]; has {
				delete(adjacent, vertex)
				g.size--
			}
		}

		success = true
	}
	return
}

func (g *AdjacencyList) AddEdge(edge Edge) (exists bool) {
	g.mu.Lock()
	defer g.mu.Unlock()

	g.addVertex(edge.Source())
	g.addVertex(edge.Target())

	if _, exists = g.adjacencyList[edge.Source()][edge.Target()]; !exists {
		g.adjacencyList[edge.Source()][edge.Target()] = keyExists
	}
	return !exists
}

func (g *AdjacencyList) RemoveEdge(edge Edge) {
	g.mu.Lock()
	defer g.mu.Unlock()

	delete(g.adjacencyList[edge.Source()], edge.Target())
}
<|endoftext|>


<commit_before>package admin

import (
	"regexp"
	"strconv"
	"strings"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor"
)

type scopeFunc func(db *gorm.DB, context *qor.Context) *gorm.DB

type Pagination struct {
	Total       int
	Pages       int
	CurrentPage int
	PrePage     int
}

type Searcher struct {
	*Context
	scopes         []*Scope
	filters        map[string]string
	withPagination bool
	Pagination     Pagination
}

func (s *Searcher) WithPagination() *Searcher {
	s.withPagination = true
	return s
}

func (s *Searcher) Page(num int) *Searcher {
	s.Pagination.CurrentPage = num
	return s
}

func (s *Searcher) PrePage(num int) *Searcher {
	s.Pagination.PrePage = num
	return s
}

func (s *Searcher) clone() *Searcher {
	return &Searcher{Context: s.Context, scopes: s.scopes, filters: s.filters}
}

func (s *Searcher) Scope(names ...string) *Searcher {
	newSearcher := s.clone()
	for _, name := range names {
		if s.Resource.scopes != nil {
			if scope := s.Resource.scopes[name]; scope != nil && !scope.Default {
				newSearcher.scopes = append(newSearcher.scopes, scope)
			}
		}
	}
	return newSearcher
}

func (s *Searcher) Filter(name, query string) *Searcher {
	newSearcher := s.clone()
	if newSearcher.filters == nil {
		newSearcher.filters = map[string]string{}
	}
	newSearcher.filters[name] = query
	return newSearcher
}

var filterRegexp = regexp.MustCompile(`^filters\[(.*?)\]$`)

func (s *Searcher) callScopes(context *qor.Context) *qor.Context {
	db := context.GetDB()

	// call default scopes
	for _, scope := range s.Resource.scopes {
		if scope.Default {
			db = scope.Handle(db, context)
		}
	}

	// call scopes
	for _, scope := range s.scopes {
		db = scope.Handle(db, context)
	}

	// call filters
	if s.filters != nil {
		for key, value := range s.filters {
			filter := s.Resource.filters[key]
			if filter != nil && filter.Handler != nil {
				db = filter.Handler(key, value, db, context)
			} else {
				db = DefaultHandler(key, value, db, context)
			}
		}
	}

	context.SetDB(db)
	return context
}

func (s *Searcher) getContext() *qor.Context {
	return s.Context.Context.New()
}

func (s *Searcher) parseContext() *qor.Context {
	var context = s.getContext()
	var searcher = s.clone()

	if context != nil && context.Request != nil {
		// parse scopes
		scopes := strings.Split(context.Request.Form.Get("scopes"), "|")
		searcher = searcher.Scope(scopes...)

		// parse filters
		for key, value := range context.Request.Form {
			if matches := filterRegexp.FindStringSubmatch(key); len(matches) > 0 {
				searcher = searcher.Filter(matches[1], value[0])
			}
		}
	}

	searcher.callScopes(context)

	// pagination
	db := context.GetDB()
	paginationDB := db.Select("count(*) total").Model(s.Resource.Value).InstantSet("gorm:query_destination", &s.Pagination)
	context.SetDB(paginationDB)
	s.Resource.CallSearcher(s.Resource.Value, context)

	if s.Pagination.CurrentPage == 0 {
		if s.Context.Request != nil {
			if page, err := strconv.Atoi(s.Context.Request.Form.Get("page")); err == nil {
				s.Pagination.CurrentPage = page
			}
		}

		if s.Pagination.CurrentPage == 0 {
			s.Pagination.CurrentPage = 1
		}
	}

	if s.Pagination.PrePage == 0 {
		s.Pagination.PrePage = s.Resource.Config.PageCount
	}

	s.Pagination.Pages = (s.Pagination.Total-1)/s.Pagination.PrePage + 1

	db = db.Limit(s.Pagination.PrePage).Offset((s.Pagination.CurrentPage - 1) * s.Pagination.PrePage)
	context.SetDB(db)

	return context
}

func (s *Searcher) FindAll() (interface{}, error) {
	context := s.parseContext()
	result := s.Resource.NewSlice()
	err := s.Resource.CallSearcher(result, context)
	return result, err
}

func (s *Searcher) FindOne() (interface{}, error) {
	context := s.parseContext()
	result := s.Resource.NewStruct()
	err := s.Resource.CallFinder(result, nil, context)
	return result, err
}
<commit_msg>New scopes style<commit_after>package admin

import (
	"regexp"
	"strconv"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor"
)

type scopeFunc func(db *gorm.DB, context *qor.Context) *gorm.DB

type Pagination struct {
	Total       int
	Pages       int
	CurrentPage int
	PrePage     int
}

type Searcher struct {
	*Context
	scopes         []*Scope
	filters        map[string]string
	withPagination bool
	Pagination     Pagination
}

func (s *Searcher) WithPagination() *Searcher {
	s.withPagination = true
	return s
}

func (s *Searcher) Page(num int) *Searcher {
	s.Pagination.CurrentPage = num
	return s
}

func (s *Searcher) PrePage(num int) *Searcher {
	s.Pagination.PrePage = num
	return s
}

func (s *Searcher) clone() *Searcher {
	return &Searcher{Context: s.Context, scopes: s.scopes, filters: s.filters}
}

func (s *Searcher) Scope(names ...string) *Searcher {
	newSearcher := s.clone()
	for _, name := range names {
		if s.Resource.scopes != nil {
			if scope := s.Resource.scopes[name]; scope != nil && !scope.Default {
				newSearcher.scopes = append(newSearcher.scopes, scope)
			}
		}
	}
	return newSearcher
}

func (s *Searcher) Filter(name, query string) *Searcher {
	newSearcher := s.clone()
	if newSearcher.filters == nil {
		newSearcher.filters = map[string]string{}
	}
	newSearcher.filters[name] = query
	return newSearcher
}

var filterRegexp = regexp.MustCompile(`^filters\[(.*?)\]$`)

func (s *Searcher) callScopes(context *qor.Context) *qor.Context {
	db := context.GetDB()

	// call default scopes
	for _, scope := range s.Resource.scopes {
		if scope.Default {
			db = scope.Handle(db, context)
		}
	}

	// call scopes
	for _, scope := range s.scopes {
		db = scope.Handle(db, context)
	}

	// call filters
	if s.filters != nil {
		for key, value := range s.filters {
			filter := s.Resource.filters[key]
			if filter != nil && filter.Handler != nil {
				db = filter.Handler(key, value, db, context)
			} else {
				db = DefaultHandler(key, value, db, context)
			}
		}
	}

	context.SetDB(db)
	return context
}

func (s *Searcher) getContext() *qor.Context {
	return s.Context.Context.New()
}

func (s *Searcher) parseContext() *qor.Context {
	var context = s.getContext()
	var searcher = s.clone()

	if context != nil && context.Request != nil {
		// parse scopes
		scopes := context.Request.Form["scopes"]
		searcher = searcher.Scope(scopes...)

		// parse filters
		for key, value := range context.Request.Form {
			if matches := filterRegexp.FindStringSubmatch(key); len(matches) > 0 {
				searcher = searcher.Filter(matches[1], value[0])
			}
		}
	}

	searcher.callScopes(context)

	// pagination
	db := context.GetDB()
	paginationDB := db.Select("count(*) total").Model(s.Resource.Value).InstantSet("gorm:query_destination", &s.Pagination)
	context.SetDB(paginationDB)
	s.Resource.CallSearcher(s.Resource.Value, context)

	if s.Pagination.CurrentPage == 0 {
		if s.Context.Request != nil {
			if page, err := strconv.Atoi(s.Context.Request.Form.Get("page")); err == nil {
				s.Pagination.CurrentPage = page
			}
		}

		if s.Pagination.CurrentPage == 0 {
			s.Pagination.CurrentPage = 1
		}
	}

	if s.Pagination.PrePage == 0 {
		s.Pagination.PrePage = s.Resource.Config.PageCount
	}

	s.Pagination.Pages = (s.Pagination.Total-1)/s.Pagination.PrePage + 1

	db = db.Limit(s.Pagination.PrePage).Offset((s.Pagination.CurrentPage - 1) * s.Pagination.PrePage)
	context.SetDB(db)

	return context
}

func (s *Searcher) FindAll() (interface{}, error) {
	context := s.parseContext()
	result := s.Resource.NewSlice()
	err := s.Resource.CallSearcher(result, context)
	return result, err
}

func (s *Searcher) FindOne() (interface{}, error) {
	context := s.parseContext()
	result := s.Resource.NewStruct()
	err := s.Resource.CallFinder(result, nil, context)
	return result, err
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The AUTHORS
//
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

package main

import (
	// Stdlib
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"

	// Salsa
	"github.com/tchap/salsa/utils/flagutil"
	"github.com/tchap/salsa/utils/httputil"

	// Others
	"github.com/tchap/gocli"
)

const crxURLTemplate = "https://clients2.google.com/service/update2/crx?response=redirect&x=id%3D~~~~%26uc"

// Subcommand initialisation and registration.
func init() {
	chromeExt := &gocli.Command{
		UsageLine: `
  chrome_ext SUBCMD`,
		Short: "manipulate Chrome Web Store extensions",
	}

	getName := &gocli.Command{
		UsageLine: `
  get_name MANIFEST_FILE`,
		Short:  "get name string from a manifest file",
		Action: getNameFromManifest,
	}
	chromeExt.MustRegisterSubcommand(getName)

	getVersion := &gocli.Command{
		UsageLine: `
  get_version MANIFEST_FILE`,
		Short:  "get version string from a manifest file",
		Action: getVersionFromManifest,
	}
	chromeExt.MustRegisterSubcommand(getVersion)

	getCrx := &gocli.Command{
		UsageLine: `
  get_crx [-zip] EXTENSION_ID FILENAME`,
		Short: "download Chrome extensions from Chrome Web Store",
		Long: `
  Download the extensions identified by EXTENSION_ID and save it in FILENAME.
  In case EXTENSION_ID is actually a URL, the address is used to retrieve the
  package directly.
		`,
		Action: runGetCrx,
	}
	getCrx.Flags.BoolVar(&convertCrxToZip, "zip", convertCrxToZip, "convert crx to zip")
	chromeExt.MustRegisterSubcommand(getCrx)

	genPackageJson := &gocli.Command{
		UsageLine: `
  gen_package_json [-dep NAME:VERSION ...] MANIFEST_FILE`,
		Short: "generate package.json from manifest.json",
		Long: `
  Generate package.json in the current working directory from manifest.json
  living at MANIFEST_FILE.

  Project name and version from manifest.json is reused, dependencies can be
  added to package.json using -dep option, which can be used multiple times.
  NAME is used as the dependency map key, version as the value
		`,
		Action: runGenPackageJson,
	}
	genPackageJson.Flags.Var(packageJsonDeps, "dep", "add a dependency into package.json")
	chromeExt.MustRegisterSubcommand(genPackageJson)

	getApp().MustRegisterSubcommand(chromeExt)
}

var convertCrxToZip bool

// Subcommand handler.
func runGetCrx(cmd *gocli.Command, args []string) {
	if len(args) != 2 {
		cmd.Usage()
		os.Exit(2)
	}

	var (
		id       = args[0]
		filename = args[1]
	)

	var packageURL string
	if regexp.MustCompile("^https?://").MatchString(id) {
		packageURL = id
	} else {
		packageURL = strings.Replace(crxURLTemplate, "~~~~", id, 1)
	}

	if config.Verbose() {
		fmt.Println("GET", packageURL)
	}
	if config.Dry() {
		return
	}

	// Download CRX.
	resp, err := httputil.Get(packageURL, nil)
	if err != nil {
		log.Fatalf("Error: failed to download crx: %v\n", err)
	}
	if resp.StatusCode >= 300 {
		log.Fatalf("Error: failed to download crx: %v\n", resp.Status)
	}
	defer resp.Body.Close()

	// Convert CRX to ZIP if requested.
	if convertCrxToZip {
		var (
			publicKeyLen uint32
			signatureLen uint32
		)

		// Drop magic number.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Drop version.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Read public key length.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Read signature length.
		if err := binary.Read(resp.Body, binary.LittleEndian, &signatureLen); err != nil {
			log.Fatal(err)
		}

		var p []byte
		if publicKeyLen > signatureLen {
			p = make([]byte, publicKeyLen)
		} else {
			p = make([]byte, signatureLen)
		}

		// Drop the public key.
		b := p[:publicKeyLen]
		for i := uint32(0); i != publicKeyLen; {
			n, err := resp.Body.Read(b[i:])
			if err != nil {
				log.Fatal(err)
			}
			i += uint32(n)
		}
		// Drop the signature.
		b = p[:signatureLen]
		for i := uint32(0); i != signatureLen; {
			n, err := resp.Body.Read(b[i:])
			if err != nil {
				log.Fatal(err)
			}
			i += uint32(n)
		}
	}

	// Write it to the file.
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}
	defer file.Close()

	n, err := io.Copy(file, resp.Body)
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Printf("Wrote %v bytes\n", n)
}

var packageJsonDeps = flagutil.NewMapValue()

// Subcommand handler.
func runGenPackageJson(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	var manifestFilename = args[0]

	content, err := ioutil.ReadFile(manifestFilename)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	var packageJson struct {
		Name         string            `json:"name"`
		Version      string            `json:"version"`
		Dependencies map[string]string `json:"dependencies"`
	}

	if err := json.Unmarshal(content, &packageJson); err != nil {
		log.Fatalf("Error: failed to unmarshal manifest.json: %v", err)
	}

	packageJson.Name = strings.ToLower(packageJson.Name)
	packageJson.Name = strings.Replace(packageJson.Name, " ", "-", -1)
	packageJson.Dependencies = packageJsonDeps.M

	content, err = json.MarshalIndent(packageJson, "", "  ")
	if err != nil {
		log.Fatalf("Error: failed to marshal package.json: %v", err)
	}

	file, err := os.OpenFile("package.json", os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}
	defer file.Close()

	if _, err := file.Write(content); err != nil {
		log.Fatalf("Error: %v", err)
	}

	fmt.Println("package.json created")
}

func getNameFromManifest(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	manifest, err := loadManifest(args[0])
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Print(manifest.Name)
}

func getVersionFromManifest(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	manifest, err := loadManifest(args[0])
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Print(manifest.Version)
}

type manifest struct {
	Name    string
	Version string
}

func loadManifest(filename string) (*manifest, error) {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	var m manifest
	if err := json.Unmarshal(content, &m); err != nil {
		return nil, err
	}

	return &m, nil
}
<commit_msg>chrome_ext: Use YAML parser instead of JSON<commit_after>// Copyright (c) 2013 The AUTHORS
//
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

package main

import (
	// Stdlib
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"

	// Salsa
	"github.com/tchap/salsa/utils/flagutil"
	"github.com/tchap/salsa/utils/httputil"

	// Others
	"github.com/tchap/gocli"
	"gopkg.in/yaml.v1"
)

const crxURLTemplate = "https://clients2.google.com/service/update2/crx?response=redirect&x=id%3D~~~~%26uc"

// Subcommand initialisation and registration.
func init() {
	chromeExt := &gocli.Command{
		UsageLine: `
  chrome_ext SUBCMD`,
		Short: "manipulate Chrome Web Store extensions",
	}

	getName := &gocli.Command{
		UsageLine: `
  get_name MANIFEST_FILE`,
		Short:  "get name string from a manifest file",
		Action: getNameFromManifest,
	}
	chromeExt.MustRegisterSubcommand(getName)

	getVersion := &gocli.Command{
		UsageLine: `
  get_version MANIFEST_FILE`,
		Short:  "get version string from a manifest file",
		Action: getVersionFromManifest,
	}
	chromeExt.MustRegisterSubcommand(getVersion)

	getCrx := &gocli.Command{
		UsageLine: `
  get_crx [-zip] EXTENSION_ID FILENAME`,
		Short: "download Chrome extensions from Chrome Web Store",
		Long: `
  Download the extensions identified by EXTENSION_ID and save it in FILENAME.
  In case EXTENSION_ID is actually a URL, the address is used to retrieve the
  package directly.
		`,
		Action: runGetCrx,
	}
	getCrx.Flags.BoolVar(&convertCrxToZip, "zip", convertCrxToZip, "convert crx to zip")
	chromeExt.MustRegisterSubcommand(getCrx)

	genPackageJson := &gocli.Command{
		UsageLine: `
  gen_package_json [-dep NAME:VERSION ...] MANIFEST_FILE`,
		Short: "generate package.json from manifest.json",
		Long: `
  Generate package.json in the current working directory from manifest.json
  living at MANIFEST_FILE.

  Project name and version from manifest.json is reused, dependencies can be
  added to package.json using -dep option, which can be used multiple times.
  NAME is used as the dependency map key, version as the value
		`,
		Action: runGenPackageJson,
	}
	genPackageJson.Flags.Var(packageJsonDeps, "dep", "add a dependency into package.json")
	chromeExt.MustRegisterSubcommand(genPackageJson)

	getApp().MustRegisterSubcommand(chromeExt)
}

var convertCrxToZip bool

// Subcommand handler.
func runGetCrx(cmd *gocli.Command, args []string) {
	if len(args) != 2 {
		cmd.Usage()
		os.Exit(2)
	}

	var (
		id       = args[0]
		filename = args[1]
	)

	var packageURL string
	if regexp.MustCompile("^https?://").MatchString(id) {
		packageURL = id
	} else {
		packageURL = strings.Replace(crxURLTemplate, "~~~~", id, 1)
	}

	if config.Verbose() {
		fmt.Println("GET", packageURL)
	}
	if config.Dry() {
		return
	}

	// Download CRX.
	resp, err := httputil.Get(packageURL, nil)
	if err != nil {
		log.Fatalf("Error: failed to download crx: %v\n", err)
	}
	if resp.StatusCode >= 300 {
		log.Fatalf("Error: failed to download crx: %v\n", resp.Status)
	}
	defer resp.Body.Close()

	// Convert CRX to ZIP if requested.
	if convertCrxToZip {
		var (
			publicKeyLen uint32
			signatureLen uint32
		)

		// Drop magic number.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Drop version.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Read public key length.
		if err := binary.Read(resp.Body, binary.LittleEndian, &publicKeyLen); err != nil {
			log.Fatal(err)
		}
		// Read signature length.
		if err := binary.Read(resp.Body, binary.LittleEndian, &signatureLen); err != nil {
			log.Fatal(err)
		}

		var p []byte
		if publicKeyLen > signatureLen {
			p = make([]byte, publicKeyLen)
		} else {
			p = make([]byte, signatureLen)
		}

		// Drop the public key.
		b := p[:publicKeyLen]
		for i := uint32(0); i != publicKeyLen; {
			n, err := resp.Body.Read(b[i:])
			if err != nil {
				log.Fatal(err)
			}
			i += uint32(n)
		}
		// Drop the signature.
		b = p[:signatureLen]
		for i := uint32(0); i != signatureLen; {
			n, err := resp.Body.Read(b[i:])
			if err != nil {
				log.Fatal(err)
			}
			i += uint32(n)
		}
	}

	// Write it to the file.
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}
	defer file.Close()

	n, err := io.Copy(file, resp.Body)
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Printf("Wrote %v bytes\n", n)
}

var packageJsonDeps = flagutil.NewMapValue()

// Subcommand handler.
func runGenPackageJson(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	var manifestFilename = args[0]

	content, err := ioutil.ReadFile(manifestFilename)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	var packageJson struct {
		Name         string            `json:"name"`
		Version      string            `json:"version"`
		Dependencies map[string]string `json:"dependencies`
	}

	if err := yaml.Unmarshal(content, &packageJson); err != nil {
		log.Fatalf("Error: failed to unmarshal manifest.json: %v", err)
	}

	packageJson.Name = strings.ToLower(packageJson.Name)
	packageJson.Name = strings.Replace(packageJson.Name, " ", "-", -1)
	packageJson.Dependencies = packageJsonDeps.M

	content, err = json.MarshalIndent(packageJson, "", "  ")
	if err != nil {
		log.Fatalf("Error: failed to marshal package.json: %v", err)
	}

	file, err := os.OpenFile("package.json", os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}
	defer file.Close()

	if _, err := file.Write(content); err != nil {
		log.Fatalf("Error: %v", err)
	}

	fmt.Println("package.json created")
}

func getNameFromManifest(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	manifest, err := loadManifest(args[0])
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Print(manifest.Name)
}

func getVersionFromManifest(cmd *gocli.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(2)
	}

	manifest, err := loadManifest(args[0])
	if err != nil {
		log.Fatalf("Error: %v\n", err)
	}

	fmt.Print(manifest.Version)
}

type manifest struct {
	Name    string
	Version string
}

func loadManifest(filename string) (*manifest, error) {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	var m manifest
	if err := yaml.Unmarshal(content, &m); err != nil {
		return nil, err
	}

	return &m, nil
}
<|endoftext|>


<commit_before>package minecraft

import (
	"github.com/MJKWoolnough/minecraft/nbt"
	"testing"
)

func TestNew(t *testing.T) {
	biomes := make([]int8, 256)
	biome := int8(-1)
	blocks := make([]int8, 4096)
	add := make([]int8, 2048)
	data := make([]int8, 2048)
	for i := 0; i < 256; i++ {
		biomes[i] = biome
		if biome++; biome >= 23 {
			biome = -1
		}
	}
	dataTag := nbt.NewTag("", nbt.NewCompound([]nbt.Tag{
		nbt.NewTag("Level", nbt.NewCompound([]nbt.Tag{
			nbt.NewTag("Biomes", nbt.NewByteArray(biomes)),
			nbt.NewTag("HeightMap", nbt.NewIntArray(make([]int32, 256))),
			nbt.NewTag("InhabitedTime", nbt.NewLong(0)),
			nbt.NewTag("LastUpdate", nbt.NewLong(0)),
			nbt.NewTag("Sections", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(0)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(1)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(3)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(10)),
				}),
			})),
			nbt.NewTag("TileEntities", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("test1")),
					nbt.NewTag("x", nbt.NewInt(-191)),
					nbt.NewTag("y", nbt.NewInt(13)),
					nbt.NewTag("z", nbt.NewInt(379)),
					nbt.NewTag("testTag", nbt.NewByte(1)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("test2")),
					nbt.NewTag("x", nbt.NewInt(-191)),
					nbt.NewTag("y", nbt.NewInt(17)),
					nbt.NewTag("z", nbt.NewInt(372)),
					nbt.NewTag("testTag", nbt.NewLong(8)),
				}),
			})),
			nbt.NewTag("Entities", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("testEntity1")),
					nbt.NewTag("Pos", nbt.NewList([]nbt.Data{
						nbt.NewDouble(-190),
						nbt.NewDouble(13),
						nbt.NewDouble(375),
					})),
					nbt.NewTag("Motion", nbt.NewList([]nbt.Data{
						nbt.NewDouble(1),
						nbt.NewDouble(13),
						nbt.NewDouble(11),
					})),
					nbt.NewTag("Rotation", nbt.NewList([]nbt.Data{
						nbt.NewFloat(13),
						nbt.NewFloat(11),
					})),
					nbt.NewTag("FallDistance", nbt.NewFloat(0)),
					nbt.NewTag("Fire", nbt.NewShort(-1)),
					nbt.NewTag("Air", nbt.NewShort(300)),
					nbt.NewTag("OnGround", nbt.NewByte(1)),
					nbt.NewTag("Dimension", nbt.NewInt(0)),
					nbt.NewTag("Invulnerable", nbt.NewByte(0)),
					nbt.NewTag("PortalCooldown", nbt.NewInt(0)),
					nbt.NewTag("UUIDMost", nbt.NewLong(0)),
					nbt.NewTag("UUIDLease", nbt.NewLong(0)),
					nbt.NewTag("Riding", nbt.NewCompound([]nbt.Tag{})),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("testEntity2")),
					nbt.NewTag("Pos", nbt.NewList([]nbt.Data{
						nbt.NewDouble(-186),
						nbt.NewDouble(2),
						nbt.NewDouble(378),
					})),
					nbt.NewTag("Motion", nbt.NewList([]nbt.Data{
						nbt.NewDouble(17.5),
						nbt.NewDouble(1000),
						nbt.NewDouble(54),
					})),
					nbt.NewTag("Rotation", nbt.NewList([]nbt.Data{
						nbt.NewFloat(11),
						nbt.NewFloat(13),
					})),
					nbt.NewTag("FallDistance", nbt.NewFloat(30)),
					nbt.NewTag("Fire", nbt.NewShort(4)),
					nbt.NewTag("Air", nbt.NewShort(30)),
					nbt.NewTag("OnGround", nbt.NewByte(0)),
					nbt.NewTag("Dimension", nbt.NewInt(0)),
					nbt.NewTag("Invulnerable", nbt.NewByte(1)),
					nbt.NewTag("PortalCooldown", nbt.NewInt(10)),
					nbt.NewTag("UUIDMost", nbt.NewLong(1450)),
					nbt.NewTag("UUIDLease", nbt.NewLong(6435)),
					nbt.NewTag("Riding", nbt.NewCompound([]nbt.Tag{})),
				}),
			})),
			nbt.NewTag("TileTicks", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("i", nbt.NewInt(0)),
					nbt.NewTag("t", nbt.NewInt(0)),
					nbt.NewTag("p", nbt.NewInt(0)),
					nbt.NewTag("x", nbt.NewInt(-192)),
					nbt.NewTag("y", nbt.NewInt(0)),
					nbt.NewTag("z", nbt.NewInt(368)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("i", nbt.NewInt(1)),
					nbt.NewTag("t", nbt.NewInt(34)),
					nbt.NewTag("p", nbt.NewInt(12)),
					nbt.NewTag("x", nbt.NewInt(-186)),
					nbt.NewTag("y", nbt.NewInt(11)),
					nbt.NewTag("z", nbt.NewInt(381)),
				}),
			})),
			nbt.NewTag("TerrainPopulated", nbt.NewByte(1)),
			nbt.NewTag("xPos", nbt.NewInt(-12)),
			nbt.NewTag("zPos", nbt.NewInt(23)),
		})),
	}))
	if _, err := newChunk(-12, 23, dataTag); err != nil {
		t.Fatalf("reveived unexpected error during testing, %q", err.Error())
	}
}

func TestBiomes(t *testing.T) {
	chunk, _ := newChunk(0, 0, nil)
	for b := Biome(-1); b < 23; b++ {
		biome := b
		for x := int32(0); x < 16; x++ {
			for z := int32(0); z < 16; z++ {
				chunk.SetBiome(x, z, biome)
				if newB := chunk.GetBiome(x, z); newB != biome {
					t.Errorf("error setting biome at co-ordinates, expecting %q, got %q", biome.String(), newB.String())
				} else if biome++; biome >= 23 {
					biome = -1
				}
			}
		}
	}
}

func TestBlock(t *testing.T) {
	chunk, _ := newChunk(0, 0, nil)
	testBlocks := []struct {
		Block
		x, y, z int32
		recheck bool
	}{
		//Test simple set
		{
			Block{
				BlockId: 12,
			},
			0, 0, 0,
			true,
		},
		//Test higher ids
		{
			Block{
				BlockId: 853,
			},
			1, 0, 0,
			true,
		},
		{
			Block{
				BlockId: 463,
			},
			2, 0, 0,
			true,
		},
		{
			Block{
				BlockId: 1001,
			},
			3, 0, 0,
			true,
		},
		//Test data set
		{
			Block{
				BlockId: 143,
				Data:    12,
			},
			0, 1, 0,
			true,
		},
		{
			Block{
				BlockId: 153,
				Data:    4,
			},
			1, 1, 0,
			true,
		},
		{
			Block{
				BlockId: 163,
				Data:    5,
			},
			2, 1, 0,
			true,
		},
		//Test metadata [un]set
		{
			Block{
				metadata: []nbt.Tag{
					nbt.NewTag("testInt2", nbt.NewInt(1743)),
					nbt.NewTag("testString2", nbt.NewString("world")),
				},
			},
			0, 0, 1,
			true,
		},
		{
			Block{
				metadata: []nbt.Tag{
					nbt.NewTag("testInt", nbt.NewInt(15)),
					nbt.NewTag("testString", nbt.NewString("hello")),
				},
			},
			1, 0, 1,
			false,
		},
		{
			Block{},
			1, 0, 1,
			true,
		},
		//Test tick [un]set
		{
			Block{
				ticks: []Tick{{123, 1, 4}, {123, 7, -1}},
			},
			0, 1, 1,
			true,
		},
		{
			Block{
				ticks: []Tick{{654, 4, 6}, {4, 63, 5}, {4, 5, 9}},
			},
			1, 1, 1,
			false,
		},
		{
			Block{},
			1, 1, 1,
			true,
		},
	}
	for _, tB := range testBlocks {
		chunk.SetBlock(tB.x, tB.y, tB.z, &tB.Block)
		if block := chunk.GetBlock(tB.x, tB.y, tB.z); !tB.Block.Equal(block) {
			t.Errorf("blocks do not match, expecting %s, got %s", tB.Block.String(), block.String())
		}
	}
	for _, tB := range testBlocks {
		if tB.recheck {
			if block := chunk.GetBlock(tB.x, tB.y, tB.z); !tB.Block.Equal(block) {
				t.Errorf("blocks do not match, expecting:-\n%s\ngot:-\n%s", tB.Block.String(), block.String())
			}
		}
	}
}
<commit_msg>Added heightmap tests<commit_after>package minecraft

import (
	"github.com/MJKWoolnough/minecraft/nbt"
	"testing"
)

func TestNew(t *testing.T) {
	biomes := make([]int8, 256)
	biome := int8(-1)
	blocks := make([]int8, 4096)
	add := make([]int8, 2048)
	data := make([]int8, 2048)
	for i := 0; i < 256; i++ {
		biomes[i] = biome
		if biome++; biome >= 23 {
			biome = -1
		}
	}
	dataTag := nbt.NewTag("", nbt.NewCompound([]nbt.Tag{
		nbt.NewTag("Level", nbt.NewCompound([]nbt.Tag{
			nbt.NewTag("Biomes", nbt.NewByteArray(biomes)),
			nbt.NewTag("HeightMap", nbt.NewIntArray(make([]int32, 256))),
			nbt.NewTag("InhabitedTime", nbt.NewLong(0)),
			nbt.NewTag("LastUpdate", nbt.NewLong(0)),
			nbt.NewTag("Sections", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(0)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(1)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(3)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("Blocks", nbt.NewByteArray(blocks)),
					nbt.NewTag("Add", nbt.NewByteArray(add)),
					nbt.NewTag("Data", nbt.NewByteArray(data)),
					nbt.NewTag("BlockLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("SkyLight", nbt.NewByteArray(make([]int8, 2048))),
					nbt.NewTag("Y", nbt.NewByte(10)),
				}),
			})),
			nbt.NewTag("TileEntities", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("test1")),
					nbt.NewTag("x", nbt.NewInt(-191)),
					nbt.NewTag("y", nbt.NewInt(13)),
					nbt.NewTag("z", nbt.NewInt(379)),
					nbt.NewTag("testTag", nbt.NewByte(1)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("test2")),
					nbt.NewTag("x", nbt.NewInt(-191)),
					nbt.NewTag("y", nbt.NewInt(17)),
					nbt.NewTag("z", nbt.NewInt(372)),
					nbt.NewTag("testTag", nbt.NewLong(8)),
				}),
			})),
			nbt.NewTag("Entities", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("testEntity1")),
					nbt.NewTag("Pos", nbt.NewList([]nbt.Data{
						nbt.NewDouble(-190),
						nbt.NewDouble(13),
						nbt.NewDouble(375),
					})),
					nbt.NewTag("Motion", nbt.NewList([]nbt.Data{
						nbt.NewDouble(1),
						nbt.NewDouble(13),
						nbt.NewDouble(11),
					})),
					nbt.NewTag("Rotation", nbt.NewList([]nbt.Data{
						nbt.NewFloat(13),
						nbt.NewFloat(11),
					})),
					nbt.NewTag("FallDistance", nbt.NewFloat(0)),
					nbt.NewTag("Fire", nbt.NewShort(-1)),
					nbt.NewTag("Air", nbt.NewShort(300)),
					nbt.NewTag("OnGround", nbt.NewByte(1)),
					nbt.NewTag("Dimension", nbt.NewInt(0)),
					nbt.NewTag("Invulnerable", nbt.NewByte(0)),
					nbt.NewTag("PortalCooldown", nbt.NewInt(0)),
					nbt.NewTag("UUIDMost", nbt.NewLong(0)),
					nbt.NewTag("UUIDLease", nbt.NewLong(0)),
					nbt.NewTag("Riding", nbt.NewCompound([]nbt.Tag{})),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("id", nbt.NewString("testEntity2")),
					nbt.NewTag("Pos", nbt.NewList([]nbt.Data{
						nbt.NewDouble(-186),
						nbt.NewDouble(2),
						nbt.NewDouble(378),
					})),
					nbt.NewTag("Motion", nbt.NewList([]nbt.Data{
						nbt.NewDouble(17.5),
						nbt.NewDouble(1000),
						nbt.NewDouble(54),
					})),
					nbt.NewTag("Rotation", nbt.NewList([]nbt.Data{
						nbt.NewFloat(11),
						nbt.NewFloat(13),
					})),
					nbt.NewTag("FallDistance", nbt.NewFloat(30)),
					nbt.NewTag("Fire", nbt.NewShort(4)),
					nbt.NewTag("Air", nbt.NewShort(30)),
					nbt.NewTag("OnGround", nbt.NewByte(0)),
					nbt.NewTag("Dimension", nbt.NewInt(0)),
					nbt.NewTag("Invulnerable", nbt.NewByte(1)),
					nbt.NewTag("PortalCooldown", nbt.NewInt(10)),
					nbt.NewTag("UUIDMost", nbt.NewLong(1450)),
					nbt.NewTag("UUIDLease", nbt.NewLong(6435)),
					nbt.NewTag("Riding", nbt.NewCompound([]nbt.Tag{})),
				}),
			})),
			nbt.NewTag("TileTicks", nbt.NewList([]nbt.Data{
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("i", nbt.NewInt(0)),
					nbt.NewTag("t", nbt.NewInt(0)),
					nbt.NewTag("p", nbt.NewInt(0)),
					nbt.NewTag("x", nbt.NewInt(-192)),
					nbt.NewTag("y", nbt.NewInt(0)),
					nbt.NewTag("z", nbt.NewInt(368)),
				}),
				nbt.NewCompound([]nbt.Tag{
					nbt.NewTag("i", nbt.NewInt(1)),
					nbt.NewTag("t", nbt.NewInt(34)),
					nbt.NewTag("p", nbt.NewInt(12)),
					nbt.NewTag("x", nbt.NewInt(-186)),
					nbt.NewTag("y", nbt.NewInt(11)),
					nbt.NewTag("z", nbt.NewInt(381)),
				}),
			})),
			nbt.NewTag("TerrainPopulated", nbt.NewByte(1)),
			nbt.NewTag("xPos", nbt.NewInt(-12)),
			nbt.NewTag("zPos", nbt.NewInt(23)),
		})),
	}))
	if _, err := newChunk(-12, 23, dataTag); err != nil {
		t.Fatalf("reveived unexpected error during testing, %q", err.Error())
	}
}

func TestBiomes(t *testing.T) {
	chunk, _ := newChunk(0, 0, nil)
	for b := Biome(-1); b < 23; b++ {
		biome := b
		for x := int32(0); x < 16; x++ {
			for z := int32(0); z < 16; z++ {
				chunk.SetBiome(x, z, biome)
				if newB := chunk.GetBiome(x, z); newB != biome {
					t.Errorf("error setting biome at co-ordinates, expecting %q, got %q", biome.String(), newB.String())
				} else if biome++; biome >= 23 {
					biome = -1
				}
			}
		}
	}
}

func TestBlock(t *testing.T) {
	chunk, _ := newChunk(0, 0, nil)
	testBlocks := []struct {
		Block
		x, y, z int32
		recheck bool
	}{
		//Test simple set
		{
			Block{
				BlockId: 12,
			},
			0, 0, 0,
			true,
		},
		//Test higher ids
		{
			Block{
				BlockId: 853,
			},
			1, 0, 0,
			true,
		},
		{
			Block{
				BlockId: 463,
			},
			2, 0, 0,
			true,
		},
		{
			Block{
				BlockId: 1001,
			},
			3, 0, 0,
			true,
		},
		//Test data set
		{
			Block{
				BlockId: 143,
				Data:    12,
			},
			0, 1, 0,
			true,
		},
		{
			Block{
				BlockId: 153,
				Data:    4,
			},
			1, 1, 0,
			true,
		},
		{
			Block{
				BlockId: 163,
				Data:    5,
			},
			2, 1, 0,
			true,
		},
		//Test metadata [un]set
		{
			Block{
				metadata: []nbt.Tag{
					nbt.NewTag("testInt2", nbt.NewInt(1743)),
					nbt.NewTag("testString2", nbt.NewString("world")),
				},
			},
			0, 0, 1,
			true,
		},
		{
			Block{
				metadata: []nbt.Tag{
					nbt.NewTag("testInt", nbt.NewInt(15)),
					nbt.NewTag("testString", nbt.NewString("hello")),
				},
			},
			1, 0, 1,
			false,
		},
		{
			Block{},
			1, 0, 1,
			true,
		},
		//Test tick [un]set
		{
			Block{
				ticks: []Tick{{123, 1, 4}, {123, 7, -1}},
			},
			0, 1, 1,
			true,
		},
		{
			Block{
				ticks: []Tick{{654, 4, 6}, {4, 63, 5}, {4, 5, 9}},
			},
			1, 1, 1,
			false,
		},
		{
			Block{},
			1, 1, 1,
			true,
		},
	}
	for _, tB := range testBlocks {
		chunk.SetBlock(tB.x, tB.y, tB.z, &tB.Block)
		if block := chunk.GetBlock(tB.x, tB.y, tB.z); !tB.Block.Equal(block) {
			t.Errorf("blocks do not match, expecting %s, got %s", tB.Block.String(), block.String())
		}
	}
	for _, tB := range testBlocks {
		if tB.recheck {
			if block := chunk.GetBlock(tB.x, tB.y, tB.z); !tB.Block.Equal(block) {
				t.Errorf("blocks do not match, expecting:-\n%s\ngot:-\n%s", tB.Block.String(), block.String())
			}
		}
	}
}

func TestHeightMap(t *testing.T) {
	tests := []struct {
		x, y, z int32
		*Block
		height int32
	}{
		{0, 0, 0, &Block{}, 0},
		{1, 0, 0, &Block{BlockId: 1}, 1},
		{1, 1, 0, &Block{BlockId: 1}, 2},
		{1, 0, 0, &Block{}, 2},
		{1, 1, 0, &Block{}, 0},
		{2, 10, 0, &Block{BlockId: 1}, 11},
		{2, 12, 0, &Block{BlockId: 1}, 13},
		{2, 12, 0, &Block{}, 11},
		{2, 10, 0, &Block{}, 0},
		{3, 15, 0, &Block{BlockId: 1}, 16},
		{3, 16, 0, &Block{BlockId: 1}, 17},
		{3, 16, 0, &Block{}, 16},
		{3, 15, 0, &Block{}, 0},
		{4, 31, 0, &Block{BlockId: 1}, 32},
		{4, 32, 0, &Block{BlockId: 1}, 33},
		{4, 32, 0, &Block{}, 32},
		{4, 31, 0, &Block{}, 0},
		{5, 16, 0, &Block{BlockId: 1}, 17},
		{5, 32, 0, &Block{BlockId: 1}, 33},
		{5, 32, 0, &Block{}, 17},
		{5, 16, 0, &Block{}, 0},
	}
	chunk, _ := newChunk(0, 0, nil)
	for n, test := range tests {
		chunk.SetBlock(test.x, test.y, test.z, test.Block)
		if h := chunk.GetHeight(test.x, test.z); h != test.height {
			t.Errorf("test %d: expecting height %d, got %d", n+1, test.height, h)
		}
	}
}
<|endoftext|>


<commit_before>package cli

import (
	"bytes"
	"fmt"
	"html/template"
	"runtime"
	"strings"
	"sync"
	"time"

	"github.com/exercism/cli/user"
)

// Status represents the results of a CLI self test.
type Status struct {
	Censor          bool
	Version         versionStatus
	System          systemStatus
	Configuration   configurationStatus
	APIReachability apiReachabilityStatus
	cli             *CLI
	cfg             user.Config
}

type versionStatus struct {
	Current  string
	Latest   string
	Status   string
	Error    error
	UpToDate bool
}

type systemStatus struct {
	OS           string
	Architecture string
	Build        string
}

type configurationStatus struct {
	Home      string
	Workspace string
	File      string
	Token     string
	TokenURL  string
}

type apiReachabilityStatus struct {
	Services []*apiPing
}

type apiPing struct {
	Service string
	URL     string
	Status  string
	Latency time.Duration
}

func NewStatus(c *CLI, uc user.Config) Status {
	status := Status{
		cli: c,
		cfg: uc,
	}
	return status
}

func (status *Status) Check() (string, error) {
	status.Version = newVersionStatus(status.cli)
	status.System = newSystemStatus()
	status.Configuration = newConfigurationStatus(status)
	status.APIReachability = newAPIReachabilityStatus()

	return status.compile()
}
func (status *Status) compile() (string, error) {
	t, err := template.New("self-test").Parse(tmplSelfTest)
	if err != nil {
		return "", err
	}

	var bb bytes.Buffer
	t.Execute(&bb, status)
	return bb.String(), nil
}

func newAPIReachabilityStatus() apiReachabilityStatus {
	ar := apiReachabilityStatus{
		Services: []*apiPing{
			{Service: "GitHub", URL: "https://api.github.com"},
			{Service: "Exercism", URL: "http://exercism.io/api/v1"},
			{Service: "X-API", URL: "http://x.exercism.io"},
		},
	}
	var wg sync.WaitGroup
	wg.Add(len(ar.Services))
	for _, service := range ar.Services {
		go service.Call(&wg)
	}
	wg.Wait()
	return ar
}

func newVersionStatus(cli *CLI) versionStatus {
	vs := versionStatus{
		Current: cli.Version,
	}
	ok, err := cli.IsUpToDate()
	if err == nil {
		vs.Latest = cli.LatestRelease.Version()
	} else {
		vs.Error = fmt.Errorf("Error: %s", err)
	}
	vs.UpToDate = ok
	return vs
}

func newSystemStatus() systemStatus {
	ss := systemStatus{
		OS:           runtime.GOOS,
		Architecture: runtime.GOARCH,
	}
	if BuildOS != "" && BuildARCH != "" {
		ss.Build = fmt.Sprintf("%s/%s", BuildOS, BuildARCH)
	}
	if BuildARM != "" {
		ss.Build = fmt.Sprintf("%s ARMv%s", ss.Build, BuildARM)
	}
	return ss
}

func newConfigurationStatus(status *Status) configurationStatus {
	cs := configurationStatus{
		Home:      status.cfg.Home,
		Workspace: status.cfg.Workspace,
		File:      status.cfg.Path,
		Token:     status.cfg.Token,
		TokenURL:  "http://exercism.io/account/key",
	}
	if status.Censor {
		cs.Token = redactToken(status.cfg.Token)
	}
	return cs
}

func (ping *apiPing) Call(wg *sync.WaitGroup) {
	defer wg.Done()

	now := time.Now()
	res, err := HTTPClient.Get(ping.URL)
	delta := time.Since(now)
	ping.Latency = delta
	if err != nil {
		ping.Status = err.Error()
		return
	}
	res.Body.Close()
	ping.Status = "connected"
}

func redactToken(token string) string {
	str := token[4 : len(token)-3]
	redaction := strings.Repeat("*", len(str))
	return string(token[:4]) + redaction + string(token[len(token)-3:])
}

const tmplSelfTest = `

Debug Information
=================

Version
----------------
Current: {{ .Version.Current }}
Latest:  {{ with .Version.Latest }}{{ . }}{{ else }}<unknown>{{ end }}
{{ with .Version.Error }}
{{ . }}
{{ end -}}
{{ if not .Version.UpToDate }}
Call 'exercism upgrade' to get the latest version.
See the release notes at https://github.com/exercism/cli/releases/tag/{{ .Version.Latest }} for details.
{{ end }}

Operating System
----------------
OS:           {{ .System.OS }}
Architecture: {{ .System.Architecture }}
{{ with .System.Build }}
Build: {{ . }}
{{ end }}

Configuration
----------------
Home:      {{ .Configuration.Home }}
Workspace: {{ .Configuration.Workspace }}
Config:    {{ .Configuration.File }}
API key:   {{ with .Configuration.Token }}{{ . }}{{ else }}<not configured>
Find your API key at {{ .Configuration.TokenURL }}{{ end }}

API Reachability
----------------
{{ range .APIReachability.Services }}
{{ .Service }}:
          {{ .URL }}
          [{{ .Status }}]
          {{ .Latency }}
{{ end }}

If you are having trouble please file a GitHub issue at
https://github.com/exercism/exercism.io/issues and include
this information.
{{ if not .Censor }}
Don't share your API key. Keep that private.
{{ end }}
`
<commit_msg>Display ping results as a markdown list in debug output<commit_after>package cli

import (
	"bytes"
	"fmt"
	"html/template"
	"runtime"
	"strings"
	"sync"
	"time"

	"github.com/exercism/cli/user"
)

// Status represents the results of a CLI self test.
type Status struct {
	Censor          bool
	Version         versionStatus
	System          systemStatus
	Configuration   configurationStatus
	APIReachability apiReachabilityStatus
	cli             *CLI
	cfg             user.Config
}

type versionStatus struct {
	Current  string
	Latest   string
	Status   string
	Error    error
	UpToDate bool
}

type systemStatus struct {
	OS           string
	Architecture string
	Build        string
}

type configurationStatus struct {
	Home      string
	Workspace string
	File      string
	Token     string
	TokenURL  string
}

type apiReachabilityStatus struct {
	Services []*apiPing
}

type apiPing struct {
	Service string
	URL     string
	Status  string
	Latency time.Duration
}

func NewStatus(c *CLI, uc user.Config) Status {
	status := Status{
		cli: c,
		cfg: uc,
	}
	return status
}

func (status *Status) Check() (string, error) {
	status.Version = newVersionStatus(status.cli)
	status.System = newSystemStatus()
	status.Configuration = newConfigurationStatus(status)
	status.APIReachability = newAPIReachabilityStatus()

	return status.compile()
}
func (status *Status) compile() (string, error) {
	t, err := template.New("self-test").Parse(tmplSelfTest)
	if err != nil {
		return "", err
	}

	var bb bytes.Buffer
	t.Execute(&bb, status)
	return bb.String(), nil
}

func newAPIReachabilityStatus() apiReachabilityStatus {
	ar := apiReachabilityStatus{
		Services: []*apiPing{
			{Service: "GitHub", URL: "https://api.github.com"},
			{Service: "Exercism", URL: "http://exercism.io/api/v1"},
			{Service: "X-API", URL: "http://x.exercism.io"},
		},
	}
	var wg sync.WaitGroup
	wg.Add(len(ar.Services))
	for _, service := range ar.Services {
		go service.Call(&wg)
	}
	wg.Wait()
	return ar
}

func newVersionStatus(cli *CLI) versionStatus {
	vs := versionStatus{
		Current: cli.Version,
	}
	ok, err := cli.IsUpToDate()
	if err == nil {
		vs.Latest = cli.LatestRelease.Version()
	} else {
		vs.Error = fmt.Errorf("Error: %s", err)
	}
	vs.UpToDate = ok
	return vs
}

func newSystemStatus() systemStatus {
	ss := systemStatus{
		OS:           runtime.GOOS,
		Architecture: runtime.GOARCH,
	}
	if BuildOS != "" && BuildARCH != "" {
		ss.Build = fmt.Sprintf("%s/%s", BuildOS, BuildARCH)
	}
	if BuildARM != "" {
		ss.Build = fmt.Sprintf("%s ARMv%s", ss.Build, BuildARM)
	}
	return ss
}

func newConfigurationStatus(status *Status) configurationStatus {
	cs := configurationStatus{
		Home:      status.cfg.Home,
		Workspace: status.cfg.Workspace,
		File:      status.cfg.Path,
		Token:     status.cfg.Token,
		TokenURL:  "http://exercism.io/account/key",
	}
	if status.Censor {
		cs.Token = redactToken(status.cfg.Token)
	}
	return cs
}

func (ping *apiPing) Call(wg *sync.WaitGroup) {
	defer wg.Done()

	now := time.Now()
	res, err := HTTPClient.Get(ping.URL)
	delta := time.Since(now)
	ping.Latency = delta
	if err != nil {
		ping.Status = err.Error()
		return
	}
	res.Body.Close()
	ping.Status = "connected"
}

func redactToken(token string) string {
	str := token[4 : len(token)-3]
	redaction := strings.Repeat("*", len(str))
	return string(token[:4]) + redaction + string(token[len(token)-3:])
}

const tmplSelfTest = `

Debug Information
=================

Version
----------------
Current: {{ .Version.Current }}
Latest:  {{ with .Version.Latest }}{{ . }}{{ else }}<unknown>{{ end }}
{{ with .Version.Error }}
{{ . }}
{{ end -}}
{{ if not .Version.UpToDate }}
Call 'exercism upgrade' to get the latest version.
See the release notes at https://github.com/exercism/cli/releases/tag/{{ .Version.Latest }} for details.
{{ end }}

Operating System
----------------
OS:           {{ .System.OS }}
Architecture: {{ .System.Architecture }}
{{ with .System.Build }}
Build: {{ . }}
{{ end }}

Configuration
----------------
Home:      {{ .Configuration.Home }}
Workspace: {{ .Configuration.Workspace }}
Config:    {{ .Configuration.File }}
API key:   {{ with .Configuration.Token }}{{ . }}{{ else }}<not configured>
Find your API key at {{ .Configuration.TokenURL }}{{ end }}

API Reachability
----------------
{{ range .APIReachability.Services }}
{{ .Service }}:
    * {{ .URL }}
    * [{{ .Status }}]
    * {{ .Latency }}
{{ end }}

If you are having trouble please file a GitHub issue at
https://github.com/exercism/exercism.io/issues and include
this information.
{{ if not .Censor }}
Don't share your API key. Keep that private.
{{ end }}
`
<|endoftext|>


<commit_before>package cli

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-pathutil/pathutil"
	"github.com/bitrise-io/stepman/stepman"
	"github.com/codegangsta/cli"
)

func update(c *cli.Context) {
	log.Info("[STEPMAN] - Update")

	collectionURIs := []string{}

	// StepSpec collection path
	collectionURI := c.String(CollectionKey)
	if collectionURI == "" {
		collectionURI = os.Getenv(CollectionPathEnvKey)
	}

	if collectionURI == "" {
		log.Info("[STEPMAN] - No step collection specified, update all")
		collectionURIs = stepman.GetAllSetpCollectionPath()
	} else {
		collectionURIs = append(collectionURIs, collectionURI)
	}

	for _, URI := range collectionURIs {
		pth := stepman.GetStepCollectionPath(URI)
		if exists, err := pathutil.IsPathExists(pth); err != nil {
			log.Fatal("[STEPMAN] - Failed to check path:", err)
		} else if !exists {
			log.Fatal("[STEPMAN] - Not initialized")
		}

		if err := stepman.DoGitPull(pth); err != nil {
			log.Fatal("[STEPMAN] - Failed to do git update:", err)
		}

		specPth := pth + "steplib.yml"
		collection, err := stepman.ParseStepCollection(specPth)
		if err != nil {
			log.Fatal("[STEPMAN] - Failed to read step spec:", err)
		}

		if err := stepman.WriteStepSpecToFile(URI, collection); err != nil {
			log.Fatal("[STEPMAN] - Failed to save step spec:", err)
		}
	}

	log.Info("[STEPMAN] - Updated")
}
<commit_msg>fixed update cmd<commit_after>package cli

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-pathutil/pathutil"
	"github.com/bitrise-io/stepman/stepman"
	"github.com/codegangsta/cli"
)

func update(c *cli.Context) {
	log.Info("[STEPMAN] - Update")

	collectionURIs := []string{}

	// StepSpec collection path
	collectionURI := c.String(CollectionKey)
	if collectionURI == "" {
		collectionURI = os.Getenv(CollectionPathEnvKey)
	}

	if collectionURI == "" {
		log.Info("[STEPMAN] - No step collection specified, update all")
		collectionURIs = stepman.GetAllSetpCollectionPath()
	} else {
		collectionURIs = []string{collectionURI}
	}

	for _, URI := range collectionURIs {
		pth := stepman.GetStepCollectionPath(URI)
		if exists, err := pathutil.IsPathExists(pth); err != nil {
			log.Fatal("[STEPMAN] - Failed to check path:", err)
		} else if !exists {
			log.Fatal("[STEPMAN] - Not initialized")
		}

		if err := stepman.DoGitPull(pth); err != nil {
			log.Fatal("[STEPMAN] - Failed to do git update:", err)
		}

		specPth := pth + "steplib.yml"
		collection, err := stepman.ParseStepCollection(specPth)
		if err != nil {
			log.Fatal("[STEPMAN] - Failed to read step spec:", err)
		}

		if err := stepman.WriteStepSpecToFile(URI, collection); err != nil {
			log.Fatal("[STEPMAN] - Failed to save step spec:", err)
		}
	}

	log.Info("[STEPMAN] - Updated")
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kedge Authors All rights reserved.

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

    http://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 cmd

import (
	"fmt"
	"os"

	pkgcmd "github.com/kedgeproject/kedge/pkg/cmd"
	"github.com/spf13/cobra"
)

// Represents the "create" command
var createCmd = &cobra.Command{
	Use:   "create",
	Short: "Create the resource on the Kubernetes cluster",
	Run: func(cmd *cobra.Command, args []string) {
		if err := ifFilesPassed(InputFiles); err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}

		kubectlCommand := []string{"create"}

		// Only setting the namespace flag to kubectl when --namespace is passed
		// explicitly by the user
		if cmd.Flags().Lookup("namespace").Changed {
			kubectlCommand = append(kubectlCommand, "--namespace", Namespace)
		}

		if err := pkgcmd.CreateKubernetesArtifacts(InputFiles, false, kubectlCommand...); err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}
	},
}

func init() {
	createCmd.Flags().StringArrayVarP(&InputFiles, "files", "f", []string{}, "Specify files")
	createCmd.MarkFlagRequired("files")
	createCmd.Flags().StringVarP(&Namespace, "namespace", "n", "", "Kubernetes namespace to deploy your application to")

	RootCmd.AddCommand(createCmd)
}
<commit_msg>fix(kedge create): add flag `--save-config`<commit_after>/*
Copyright 2017 The Kedge Authors All rights reserved.

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

    http://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 cmd

import (
	"fmt"
	"os"

	pkgcmd "github.com/kedgeproject/kedge/pkg/cmd"
	"github.com/spf13/cobra"
)

// Represents the "create" command
var createCmd = &cobra.Command{
	Use:   "create",
	Short: "Create the resource on the Kubernetes cluster",
	Run: func(cmd *cobra.Command, args []string) {
		if err := ifFilesPassed(InputFiles); err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}

		kubectlCommand := []string{"create", "--save-config"}

		// Only setting the namespace flag to kubectl when --namespace is passed
		// explicitly by the user
		if cmd.Flags().Lookup("namespace").Changed {
			kubectlCommand = append(kubectlCommand, "--namespace", Namespace)
		}

		if err := pkgcmd.CreateKubernetesArtifacts(InputFiles, false, kubectlCommand...); err != nil {
			fmt.Println(err)
			os.Exit(-1)
		}
	},
}

func init() {
	createCmd.Flags().StringArrayVarP(&InputFiles, "files", "f", []string{}, "Specify files")
	createCmd.MarkFlagRequired("files")
	createCmd.Flags().StringVarP(&Namespace, "namespace", "n", "", "Kubernetes namespace to deploy your application to")

	RootCmd.AddCommand(createCmd)
}
<|endoftext|>


<commit_before>// Copyright © 2016 Kevin Kirsche <kev.kirsche@gmail.com>
//
// 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
//
//     http://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 cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// ingestCmd represents the ingest command
var ingestCmd = &cobra.Command{
	Use:   "ingest",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		fmt.Println("ingest called")
	},
}

func init() {
	RootCmd.AddCommand(ingestCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// ingestCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// ingestCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<commit_msg>Get ingest pipeline working<commit_after>// Copyright © 2016 Kevin Kirsche <kev.kirsche@gmail.com>
//
// 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
//
//     http://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 cmd

import (
	"crypto/tls"
	"github.com/kkirsche/nessusControl/api"
	"github.com/kkirsche/nessusControl/creator"
	"github.com/kkirsche/nessusControl/database"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"log"
	"net/http"
	"os/user"
)

// ingestCmd represents the ingest command
var ingestCmd = &cobra.Command{
	Use:   "ingest",
	Short: "Begin the ingest pipeline for Nessus",
	Long:  `Begins running the ingest pipeline within .`,
	Run: func(cmd *cobra.Command, args []string) {
		transport := &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
		httpClient := &http.Client{Transport: transport}
		debugEnabled := false
		moveFilesDuringPipeline := false
		apiClient := nessusAPI.NewAccessTokenClient(viper.GetString("nessusLocation.hostname"),
			viper.GetString("nessusLocation.port"), viper.GetString("auth.username"),
			viper.GetString("auth.password"), viper.GetBool("debug"))

		nessusDB, err := nessusDatabase.ConnectToSQLite(viper.GetString("sqlitePath"))
		if err != nil {
			log.Fatal(err.Error())
		}

		creator := nessusCreator.NewCreator(viper.GetString("incomingFilesPath"), apiClient, httpClient, nessusDB, debugEnabled)
		err = creator.IngestPipeline(moveFilesDuringPipeline)
		if err != nil {
			log.Fatal(err.Error())
		}
	},
}

func init() {
	RootCmd.AddCommand(ingestCmd)
	usr, _ := user.Current()

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	ingestCmd.PersistentFlags().StringP("sqlitePath", "s", usr.HomeDir+"/nessusIncoming", "The path to the Nessus SQLite database.")
	viper.BindPFlag("sqlitePath", ingestCmd.PersistentFlags().Lookup("sqlitePath"))
	viper.SetDefault("sqlitePath", usr.HomeDir+"/nessusControl.db")

	ingestCmd.PersistentFlags().StringP("requestedScansPath", "i", usr.HomeDir+"/nessusRequestedScans", "The path to the Nessus request scan files.")
	viper.BindPFlag("requestedScansPath", ingestCmd.PersistentFlags().Lookup("requestedScansPath"))
	viper.SetDefault("requestedScansPath", usr.HomeDir+"/nessusRequestedScans")
	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// ingestCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

// CMEP MEPMD01 extended record format
// Metering Data Type 1 – Interval Data, Pulse Data, Reference Register Reads
type MEPMD01x struct {
	RecordType          string
	RecordVersion       string // Fixed value-Release date to production. YYYYMMDD
	SenderID            string // Fixed value
	SenderCustomerID    string // Sensus code - customer:Key for flexible fields
	ReceiverID          string // Flexible field – see Table 9 for options
	ReceiverCustomerID  string // Flexible field – see Table 9 for options
	TimeStamp           string // Date&time this record was created YYYYMMDDHHMM
	MeterID             string // Flexible field – see table 9 for options
	Purpose             string // Table 2
	Commodity           string // Table 3
	Units               string // Table 4
	CalculationConstant string // float32 Multiplier to convert data values to
	// engineering units.
	Interval string // Time interval between readings. 00000015
	Count    string // int32 Number of triples to follow.
	// Maximum of 48 allowed per record.
	Triples []Interval // Stores the Interval Data
}

// Interval Block of Data, can up Register and Interval Data
// TODO(cn): Parse out the Bit for the Data Quality Flag, this value
// holds a text value and a bit value, for two values with seperate meanings
type Interval struct {
	EndTime         string // End time of the interval
	DataQualityFlag string // Data Quality Flag: see Table 6.
	MeasuredValue   string // The measured value
}

// Main Function Entry Point
func main() {

	// Open the file
	file, err := os.Open("cmep.dat")

	// On Error Close
	if err != nil {
		log.Fatal(err)
	}

	// defer the close so we don't leave a locked file open during an error
	defer file.Close()

	// Create a map to hold the counts of the record locators
	recordformats := make(map[string]int)

	// Quick output of found types
	fmt.Printf("map := %v\n", recordformats)

	//TODO we need to process by RecordType so we need a series of If statements

	//Create the slice of the struct
	mepmd01x := make([]MEPMD01x, 0)

	//Start processing the file line by line
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		text := scanner.Text()

		// Example Line by Line Processing
		ProcessLine(text, recordformats)

		// Batching the Results into on RecordType
		mepmd01x = ProcessBatchLine(text, mepmd01x)
	}

	// Printing the results for these first commits and then
	// I will write some tests
	json, err := json.Marshal(mepmd01x)
	if err != nil {
		fmt.Println(err)
		return
	}
	//Quick and Dirty Print Here
	fmt.Println("\n")
	fmt.Println(string(json))
	fmt.Println("\n")

	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

//A CMEP file is comma delimited file where each line contains
//a specific set of values based on the record locator.
//The record locator is the first value of every line in the file.
func ProcessLine(line string, recordformats map[string]int) MEPMD01x {

	recordformats = RecordLocatorCount(line, recordformats)
	// We only want the record format which is the first value in this slice
	// We are only working with one line at a time
	// this will be many thousands of hits to the database
	// another method would be to batch the results and then push
	data := RecordFormatTransform(line)

	// Printing of the results until I have a test setup
	//json, err := json.Marshal(data)
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//Quick and Dirty Print Here
	//fmt.Println(string(json))
	//fmt.Println("\n")

	return data
	// POST Data to Database, here or in another function
}

// We are only working with one line at a time
// this will be many thousands of hits to the database
// another method would be to batch the results and then push
// Here we are assuming process the entire file and then
// allow another function to post the data to the database
func ProcessBatchLine(line string, records []MEPMD01x) []MEPMD01x {

	data := RecordFormatTransform(line)

	// Expand the slice, expansion does decrease performance
	records = append(records, data)

	return records
}

// Transform the CMEP csv values to the MEPMD01x struct
// and return this struct back the to calling function
func RecordFormatTransform(line string) MEPMD01x {

	//split the csv data
	values := strings.Split(line, ",")

	//values[13] contains the count for intervals at the
	//end of the cmep csv, we can have a max of 48
	count, err := strconv.Atoi(values[13])
	if err != nil {
		// handle error
		fmt.Fprintln(os.Stderr, "convert string to int:", err)
	}

	// After the 14th position, is where the interval data is found
	intervalstartposition := 14

	// Create a slice of all the intervals we need to store
	// We can use a slice because CMEP returns the number of intervals
	// expected, if this is wrong we will to err out and recover and
	// keep processing the data.  We could have more intervals than
	// what the data suggests
	intervals := make([]Interval, count)

	for i := 0; i < count; i++ {
		intervals[i].EndTime = values[intervalstartposition+i]
		intervals[i].DataQualityFlag = values[intervalstartposition+i+1]
		intervals[i].MeasuredValue = values[intervalstartposition+i+2]
	}

	// Populate the data
	// TODO: I should rework this to use .Notation for the values[x]
	// is easier to read
	data := MEPMD01x{values[0],
		values[1],
		values[2],
		values[3],
		values[4],
		values[5],
		values[6],
		values[7],
		values[8],
		values[9],
		values[10],
		values[11],
		values[12],
		values[13], intervals}

	return data

}

// Create map containing the RecordLocator and the number
// of instances the RecordLocator has occured.  This is for
// reporting purposes only.
func RecordLocatorCount(rl string, counts map[string]int) map[string]int {
	counts[rl]++
	return counts
}
<commit_msg>fixed RecordFormat count, it needed to be moved down below thescanner loop<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

// CMEP MEPMD01 extended record format
// Metering Data Type 1 – Interval Data, Pulse Data, Reference Register Reads
type MEPMD01x struct {
	RecordType          string
	RecordVersion       string // Fixed value-Release date to production. YYYYMMDD
	SenderID            string // Fixed value
	SenderCustomerID    string // Sensus code - customer:Key for flexible fields
	ReceiverID          string // Flexible field – see Table 9 for options
	ReceiverCustomerID  string // Flexible field – see Table 9 for options
	TimeStamp           string // Date&time this record was created YYYYMMDDHHMM
	MeterID             string // Flexible field – see table 9 for options
	Purpose             string // Table 2
	Commodity           string // Table 3
	Units               string // Table 4
	CalculationConstant string // float32 Multiplier to convert data values to
	// engineering units.
	Interval string // Time interval between readings. 00000015
	Count    string // int32 Number of triples to follow.
	// Maximum of 48 allowed per record.
	Triples []Interval // Stores the Interval Data
}

// Interval Block of Data, can up Register and Interval Data
// TODO(cn): Parse out the Bit for the Data Quality Flag, this value
// holds a text value and a bit value, for two values with seperate meanings
type Interval struct {
	EndTime         string // End time of the interval
	DataQualityFlag string // Data Quality Flag: see Table 6.
	MeasuredValue   string // The measured value
}

// Main Function Entry Point
func main() {

	// Open the file
	file, err := os.Open("cmep.dat")

	// On Error Close
	if err != nil {
		log.Fatal(err)
	}

	// defer the close so we don't leave a locked file open during an error
	defer file.Close()

	// Create a map to hold the counts of the record locators
	recordformats := make(map[string]int)

	//TODO we need to process by RecordType so we need a series of If statements

	//Create the slice of the struct
	mepmd01x := make([]MEPMD01x, 0)

	//Start processing the file line by line
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		text := scanner.Text()

		// Example Line by Line Processing
		ProcessLine(text, recordformats)

		// Batching the Results into on RecordType
		mepmd01x = ProcessBatchLine(text, mepmd01x)
	}

	// Quick output of found types
	fmt.Printf("RecordTypes : %v\n", recordformats)

	// Printing the results for these first commits and then
	// I will write some tests
	json, err := json.Marshal(mepmd01x)
	if err != nil {
		fmt.Println(err)
		return
	}
	//Quick and Dirty Print Here
	fmt.Println("\n")
	fmt.Println(string(json))
	fmt.Println("\n")

	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

//A CMEP file is comma delimited file where each line contains
//a specific set of values based on the record locator.
//The record locator is the first value of every line in the file.
func ProcessLine(line string, recordformats map[string]int) MEPMD01x {

	// We only want the record format which is the first value in this slice
	// We are only working with one line at a time
	// this will be many thousands of hits to the database
	// another method would be to batch the results and then push

	// split the csv data
	// need to rework and pass the values around since have
	// to split it for both functions, this way it's done once
	values := strings.Split(line, ",")
	recordformats = RecordLocatorCount(values[0], recordformats)

	data := RecordFormatTransform(line)

	// Printing of the results until I have a test setup
	//json, err := json.Marshal(data)
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//Quick and Dirty Print Here
	//fmt.Println(string(json))
	//fmt.Println("\n")

	return data
	// POST Data to Database, here or in another function
}

// We are only working with one line at a time
// this will be many thousands of hits to the database
// another method would be to batch the results and then push
// Here we are assuming process the entire file and then
// allow another function to post the data to the database
func ProcessBatchLine(line string, records []MEPMD01x) []MEPMD01x {

	data := RecordFormatTransform(line)
	// Expand the slice, expansion does decrease performance
	records = append(records, data)

	return records
}

// Transform the CMEP csv values to the MEPMD01x struct
// and return this struct back the to calling function
func RecordFormatTransform(line string) MEPMD01x {

	//split the csv data
	values := strings.Split(line, ",")

	//values[13] contains the count for intervals at the
	//end of the cmep csv, we can have a max of 48
	count, err := strconv.Atoi(values[13])
	if err != nil {
		// handle error
		fmt.Fprintln(os.Stderr, "convert string to int:", err)
	}

	// After the 14th position, is where the interval data is found
	intervalstartposition := 14

	// Create a slice of all the intervals we need to store
	// We can use a slice because CMEP returns the number of intervals
	// expected, if this is wrong we will to err out and recover and
	// keep processing the data.  We could have more intervals than
	// what the data suggests
	intervals := make([]Interval, count)

	for i := 0; i < count; i++ {
		intervals[i].EndTime = values[intervalstartposition+i]
		intervals[i].DataQualityFlag = values[intervalstartposition+i+1]
		intervals[i].MeasuredValue = values[intervalstartposition+i+2]
	}

	// Populate the data
	// TODO: I should rework this to use .Notation for the values[x]
	// is easier to read
	data := MEPMD01x{values[0],
		values[1],values[2],values[3],values[4],values[5],
		values[6],values[7],values[8],values[9],values[10],
		values[11],values[12],values[13], intervals}

	return data

}

// Create map containing the RecordLocator and the number
// of instances the RecordLocator has occured.  This is for
// reporting purposes only.
func RecordLocatorCount(rl string, counts map[string]int) map[string]int {
	counts[rl]++
	return counts
}
<|endoftext|>