<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"testing"

	"github.com/hyperledger/fabric/common/util"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

func ccSetup(t *testing.T, stub *shim.MockStub) {
	// a successfull init should not return any errors
	response := stub.MockInit(uuid, util.ToChaincodeArgs("init", "999"))
	if response.Payload != nil {
		t.Error(response.Payload)
	}

	// init should write a test on the ledger
	testAsBytes, err := stub.GetState("abc")
	if err != nil {
		t.Error("Failed to read test var from ledger")
	}

	var aval int
	json.Unmarshal(testAsBytes, &aval)

	if aval != 999 {
		t.Error("Aval for testing should be '999', but is '%d'", aval)
	}

	// check out the empty car index
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Empty car index:\t%v\n", carIndex)
	fmt.Printf("Car index length:\t%v\n", len(carIndex))

	if len(carIndex) != 0 {
		t.Error("Car index should be empty")
	}
}

func TestInit(t *testing.T) {
	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)
}

func TestSellCar(t *testing.T) {
	var username string = "amag"
	var receiver string = "bobby"
	var vin string = "WVW ZZZ 6RZ HY26 0780"

	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)

	// create a new car
	carData := `{ "vin": "` + vin + `" }`
	response := stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData))

	// payload should contain the car
	car := Car{}
	err := json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Successfully created car with ts '%d'\n", car.CreatedTs)

	// register the car as DOT user
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("register", username, "dot", vin))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error("Error registering the car")
	}

	if !IsRegistered(&car) {
		t.Error("Car should now be registered!")
	}

	// create receiver
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("createUser", username, "garage", receiver))
	buyer := User{}
	err = json.Unmarshal(response.Payload, &buyer)
	if err != nil {
		t.Error("Error creating buyer")
		return
	}

	// sell the car without sales offer should be forbidden
	// price will not be defined anyway..
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("sell", username, "garage", vin, receiver))
	err = json.Unmarshal(response.Payload, &car)
	if err == nil {
		t.Error("Selling without a sales offer is not possible. No agreement on price!")
		return
	}

	// create sales offer
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("createSellingOffer", username, "garage", "99", vin, receiver))
	offer := Offer{}
	err = json.Unmarshal(response.Payload, &offer)
	if err != nil {
		t.Error("Error creating sales offer")
		return
	}

	// sell the car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("sell", username, "garage", vin, receiver))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error(err.Error())
		return
	}

	// check that the old owner has no longer access to the car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", username, "TESTING", car.Vin))
	err = json.Unmarshal(response.Payload, &car)
	if err == nil {
		fmt.Println(response.Message)
		t.Error("The old car owner should no longer have access to the car")
		return
	}

	// check that bobby has access to the car now
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", receiver, "TESTING", car.Vin))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error("Error transferring car ownership in the cars certificate")
		return
	}

	// checkout bobbys user record
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readUser", receiver, "user", receiver))
	receiverAsUser := User {}
	err = json.Unmarshal(response.Payload, &receiverAsUser)
	if err != nil {
		t.Error("Error fetching receiver")
		return
	}

	fmt.Printf("New owner/receiver with cars: %v\n", receiverAsUser)

	if receiverAsUser.Cars[0] != vin {
		t.Error("Car transfer unsuccessfull")
		return
	}

	// checkout the old owners user record
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readUser", username, "garage", username))
	oldOwnerAsUser := User {}
	err = json.Unmarshal(response.Payload, &oldOwnerAsUser)
	if err != nil {
		t.Error("Error fetching seller")
		return
	}

	fmt.Printf("Old owner with cars: %v\n", oldOwnerAsUser)

	// the old owner should be left with 0 cars
	if len(oldOwnerAsUser.Cars) != 0 {
		t.Error("Car transfer unsuccessfull")
		return
	}

	// check out the new car index and see
	// that ownership righs are registered properly
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	fmt.Printf("Car index after transfer: %v\n", carIndex)

	if carIndex[vin] != receiver {
		t.Error("Car transfer unsuccessfull")
	}

	// check new balances of seller (old owner)
	if oldOwnerAsUser.Balance != 99 {
		t.Error("Sellers balance not updated")
	}

	// check new balances of buyer
	if receiverAsUser.Balance != -99 {
		t.Error("Buyers balance not updated")
	}
}

func TestCreateAndReadCar(t *testing.T) {
	username := "amag"
	vin := "WVW ZZZ 6RZ HY26 0780"

	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)

	// create a new car
	// and provide additional registration data for the DOT
	carData := `{ "vin": "` + vin + `" }`
	registrationData := `{ "number_of_doors":     "4+1",
                           "number_of_cylinders":  4,
                           "number_of_axis":       2,
                           "max_speed":            200 }`
	response := stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData, registrationData))

	// payload should contain the car
	carCreated := Car{}
	err := json.Unmarshal(response.Payload, &carCreated)
	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Successfully created car with ts '%d'\n", carCreated.CreatedTs)

	// check out the car index, should contain one car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	if err != nil {
		t.Error("Failed to fetch car index")
	} else if len(carIndex) > 1 {
		t.Error("The car index should only contain one car by now")
	} else if carIndex[carCreated.Vin] != username {
		t.Error("This is not the car '" + username + "' created")
	}

	// check out the new car entry
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", username, "TESTING", carCreated.Vin))
	carFetched := Car{}
	err = json.Unmarshal(response.Payload, &carFetched)
	if err != nil {
		t.Error("Failed to fetch car")
	} else if carFetched.Vin != carCreated.Vin {
		t.Error("Car VIN does not match")
	} else if carFetched.CreatedTs != carCreated.CreatedTs {
		t.Error("This is not the car you created before")
	}

	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", "usr_" + username))
	user := User {}
	err = json.Unmarshal(response.Payload, &user)
	if err != nil {
		t.Error("Failed to fetch user")
	}

	fmt.Printf("Car owner: %v\n+", user)

	// the user should only have one car by now
	if user.Cars[0] != vin {
		t.Error(fmt.Sprintf("Car was not handed over to user '%s'", username))
	}

	// create a car with the same vin
	// should get rejected with an error msg
	// also tests to create cars without the additional registration data
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData))
	err = json.Unmarshal(response.Payload, &carCreated)
	if err == nil {
		t.Error(fmt.Sprintf("Only one car with vin '%s' can exist", vin))
	}

	fmt.Println(carFetched)
}
<commit_msg>test clear pending insureProposals<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"testing"

	"github.com/hyperledger/fabric/common/util"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

func ccSetup(t *testing.T, stub *shim.MockStub) {
	// a successfull init should not return any errors
	response := stub.MockInit(uuid, util.ToChaincodeArgs("init", "999"))
	if response.Payload != nil {
		t.Error(response.Payload)
	}

	// init should write a test on the ledger
	testAsBytes, err := stub.GetState("abc")
	if err != nil {
		t.Error("Failed to read test var from ledger")
	}

	var aval int
	json.Unmarshal(testAsBytes, &aval)

	if aval != 999 {
		t.Error("Aval for testing should be '999', but is '%d'", aval)
	}

	// check out the empty car index
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Empty car index:\t%v\n", carIndex)
	fmt.Printf("Car index length:\t%v\n", len(carIndex))

	if len(carIndex) != 0 {
		t.Error("Car index should be empty")
	}
}

func TestInit(t *testing.T) {
	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)
}

func TestSellCar(t *testing.T) {
	var username string = "amag"
	var receiver string = "bobby"
	var vin string = "WVW ZZZ 6RZ HY26 0780"
	var insuranceCompany string = "axa"
	var insuranceCompany2 string = "mobiliar"

	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)

	// create a new car
	carData := `{ "vin": "` + vin + `" }`
	response := stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData))

	// payload should contain the car
	car := Car{}
	err := json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Successfully created car with ts '%d'\n", car.CreatedTs)

	// register the car as DOT user
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("register", username, "dot", vin))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error("Error registering the car")
	}

	if !IsRegistered(&car) {
		t.Error("Car should now be registered!")
	}

	// create insurance proposals for the car
	stub.MockInvoke(uuid, util.ToChaincodeArgs("insureProposal", username, "user", vin, insuranceCompany))
	stub.MockInvoke(uuid, util.ToChaincodeArgs("insureProposal", username, "user", vin, insuranceCompany2))

	// ensure it got created
    response = stub.MockInvoke(uuid, util.ToChaincodeArgs("getInsurer", username, "insurer", insuranceCompany))
    insurer := Insurer {}
    err = json.Unmarshal(response.Payload, &insurer)
    if (err != nil) {
        t.Error("Error fetching insurance records")
        return
    }

    if insurer.Proposals[0].Car != vin {
		t.Error("Insurance proposal for company 1 not saved")
        return
    }

    response = stub.MockInvoke(uuid, util.ToChaincodeArgs("getInsurer", username, "insurer", insuranceCompany2))
    insurer2 := Insurer {}
    err = json.Unmarshal(response.Payload, &insurer2)
    if (err != nil) {
		t.Error("Error fetching insurance records")
        return
    }

    if insurer2.Proposals[0].Car != vin {
		t.Error("Insurance proposal for company 2 not saved")
        return
    }

	// create receiver
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("createUser", username, "garage", receiver))
	buyer := User{}
	err = json.Unmarshal(response.Payload, &buyer)
	if err != nil {
		t.Error("Error creating buyer")
		return
	}

	// sell the car without sales offer should be forbidden
	// price will not be defined anyway..
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("sell", username, "garage", vin, receiver))
	err = json.Unmarshal(response.Payload, &car)
	if err == nil {
		t.Error("Selling without a sales offer is not possible. No agreement on price!")
		return
	}

	// create sales offer
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("createSellingOffer", username, "garage", "99", vin, receiver))
	offer := Offer{}
	err = json.Unmarshal(response.Payload, &offer)
	if err != nil {
		t.Error("Error creating sales offer")
		return
	}

	// sell the car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("sell", username, "garage", vin, receiver))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error(err.Error())
		return
	}

	// check that all insurance proposals for this car are removed
    response = stub.MockInvoke(uuid, util.ToChaincodeArgs("getInsurer", username, "insurer", insuranceCompany))
    err = json.Unmarshal(response.Payload, &insurer)

    if len(insurer.Proposals) != 0 {
		t.Error("Insurance proposal for company 1 not removed")
        return
    }

    response = stub.MockInvoke(uuid, util.ToChaincodeArgs("getInsurer", username, "insurer", insuranceCompany2))
    err = json.Unmarshal(response.Payload, &insurer2)

    if len(insurer2.Proposals) != 0 {
		t.Error("Insurance proposal for company 2 not removed")
        return
    }

	// check that the old owner has no longer access to the car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", username, "TESTING", car.Vin))
	err = json.Unmarshal(response.Payload, &car)
	if err == nil {
		fmt.Println(response.Message)
		t.Error("The old car owner should no longer have access to the car")
		return
	}

	// check that bobby has access to the car now
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", receiver, "TESTING", car.Vin))
	err = json.Unmarshal(response.Payload, &car)
	if err != nil {
		t.Error("Error transferring car ownership in the cars certificate")
		return
	}

	// checkout bobbys user record
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readUser", receiver, "user", receiver))
	receiverAsUser := User {}
	err = json.Unmarshal(response.Payload, &receiverAsUser)
	if err != nil {
		t.Error("Error fetching receiver")
		return
	}

	fmt.Printf("New owner/receiver with cars: %v\n", receiverAsUser)

	if receiverAsUser.Cars[0] != vin {
		t.Error("Car transfer unsuccessfull")
		return
	}

	// checkout the old owners user record
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readUser", username, "garage", username))
	oldOwnerAsUser := User {}
	err = json.Unmarshal(response.Payload, &oldOwnerAsUser)
	if err != nil {
		t.Error("Error fetching seller")
		return
	}

	fmt.Printf("Old owner with cars: %v\n", oldOwnerAsUser)

	// the old owner should be left with 0 cars
	if len(oldOwnerAsUser.Cars) != 0 {
		t.Error("Car transfer unsuccessfull")
		return
	}

	// check out the new car index and see
	// that ownership righs are registered properly
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	fmt.Printf("Car index after transfer: %v\n", carIndex)

	if carIndex[vin] != receiver {
		t.Error("Car transfer unsuccessfull")
	}

	// check new balances of seller (old owner)
	if oldOwnerAsUser.Balance != 99 {
		t.Error("Sellers balance not updated")
	}

	// check new balances of buyer
	if receiverAsUser.Balance != -99 {
		t.Error("Buyers balance not updated")
	}
}

func TestCreateAndReadCar(t *testing.T) {
	username := "amag"
	vin := "WVW ZZZ 6RZ HY26 0780"

	// create and name a new chaincode mock
	carChaincode := &CarChaincode{}
	stub := shim.NewMockStub("car", carChaincode)

	ccSetup(t, stub)

	// create a new car
	// and provide additional registration data for the DOT
	carData := `{ "vin": "` + vin + `" }`
	registrationData := `{ "number_of_doors":     "4+1",
                           "number_of_cylinders":  4,
                           "number_of_axis":       2,
                           "max_speed":            200 }`
	response := stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData, registrationData))

	// payload should contain the car
	carCreated := Car{}
	err := json.Unmarshal(response.Payload, &carCreated)
	if err != nil {
		t.Error(err.Error())
	}

	fmt.Printf("Successfully created car with ts '%d'\n", carCreated.CreatedTs)

	// check out the car index, should contain one car
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", carIndexStr))
	carIndex := make(map[string]string)
	err = json.Unmarshal(response.Payload, &carIndex)

	if err != nil {
		t.Error("Failed to fetch car index")
	} else if len(carIndex) > 1 {
		t.Error("The car index should only contain one car by now")
	} else if carIndex[carCreated.Vin] != username {
		t.Error("This is not the car '" + username + "' created")
	}

	// check out the new car entry
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("readCar", username, "TESTING", carCreated.Vin))
	carFetched := Car{}
	err = json.Unmarshal(response.Payload, &carFetched)
	if err != nil {
		t.Error("Failed to fetch car")
	} else if carFetched.Vin != carCreated.Vin {
		t.Error("Car VIN does not match")
	} else if carFetched.CreatedTs != carCreated.CreatedTs {
		t.Error("This is not the car you created before")
	}

	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("read", "TESTING", "TESTING", "usr_" + username))
	user := User {}
	err = json.Unmarshal(response.Payload, &user)
	if err != nil {
		t.Error("Failed to fetch user")
	}

	fmt.Printf("Car owner: %v\n+", user)

	// the user should only have one car by now
	if user.Cars[0] != vin {
		t.Error(fmt.Sprintf("Car was not handed over to user '%s'", username))
	}

	// create a car with the same vin
	// should get rejected with an error msg
	// also tests to create cars without the additional registration data
	response = stub.MockInvoke(uuid, util.ToChaincodeArgs("create", username, "garage", carData))
	err = json.Unmarshal(response.Payload, &carCreated)
	if err == nil {
		t.Error(fmt.Sprintf("Only one car with vin '%s' can exist", vin))
	}

	fmt.Println(carFetched)
}
<|endoftext|>


<commit_before>package dfa

import (
	"bytes"
	"fmt"
)

type State string

func (s State) String() string {
	return string(s)
}

type Letter string

func (l Letter) String() string {
	return string(l)
}

type DFA struct {
	q        map[State]bool                     // States
	e        map[Letter]bool                    // Alphabet
	d        map[domainelement]*codomainelement // Transition
	q0       State                              // Start State
	f        map[State]bool                     // Terminal States
	synccall bool                               // Call callbacks synchronously
	done     chan laststate                     // Termination channel
	input    *Letter                            // Inputs to the DFA
	stop     chan struct{}
	logger   func(State) // Logger for transitions
}

type domainelement struct {
	l Letter
	s State
}

type codomainelement struct {
	s    State
	exec interface{}
}

type laststate struct {
	s   State
	err error
}

func New() *DFA {
	return &DFA{
		q:      make(map[State]bool),
		e:      make(map[Letter]bool),
		f:      make(map[State]bool),
		d:      make(map[domainelement]*codomainelement),
		done:   make(chan laststate, 1),
		stop:   make(chan struct{}),
		logger: func(State) {},
	}
}

func (m *DFA) SetTransition(from State, input Letter, to State, exec interface{}) {
	if exec == nil {
		panic("stateful computation cannot be nil")
	}
	if from == State("") || to == State("") {
		panic("state cannot be defined as the empty string")
	}
	switch exec.(type) {
	case func():
		if !m.f[to] {
			panic(fmt.Sprintf("stateful computation must be of type func() Letter for non-terminal '%v' state", to))
		}
	case func() Letter:
		if m.f[to] {
			panic(fmt.Sprintf("stateful computation must be of type func() for terminal '%v' state", to))
		}
	default:
		panic("stateful computation must be of type func() or func() Letter")
	}
	m.q[to] = true
	m.q[from] = true
	m.e[input] = true
	de := domainelement{l: input, s: from}
	if _, ok := m.d[de]; !ok {
		m.d[de] = &codomainelement{s: to, exec: exec}
	}
}

func (m *DFA) SetStartState(q0 State) {
	m.q0 = q0
}

func (m *DFA) SetTerminalStates(f ...State) {
	for _, q := range f {
		m.f[q] = true
	}
}

func (m *DFA) SetTransitionLogger(logger func(State)) {
	m.logger = logger
}

func (m *DFA) States() []State {
	q := make([]State, 0, len(m.q))
	for s, _ := range m.q {
		q = append(q, s)
	}
	return q
}

func (m *DFA) Alphabet() []Letter {
	e := make([]Letter, 0, len(m.e))
	for l, _ := range m.e {
		e = append(e, l)
	}
	return e
}

func (m *DFA) Run(init interface{}) (State, error) {
	// Check some pre-conditions.
	if init == nil {
		panic("initial stateful computation is nil")
	}
	if m.q0 == State("") {
		panic("no start state definied")
	}
	if len(m.f) == 0 {
		panic("no terminal states definied")
	}
	if _, ok := m.q[m.q0]; !ok {
		panic(fmt.Sprintf("start state '%v' is not in the set of states", m.q0))
	}
	for s, _ := range m.f {
		if _, ok := m.q[s]; !ok {
			panic(fmt.Sprintf("terminal state '%v' is not in the set of states", s))
		}
	}
	// Run the DFA.
	go func() {
		defer close(m.done)
		// The current state, starts at q0.
		s := m.q0
		// Run the initial stateful computation.
		if m.f[s] {
			// If the state is a terminal state then the DFA has
			// accepted the input sequence and it can stop.
			m.done <- accepted(s)
			return
		} else {
			// Otherwise continue reading generated input
			// by starting the next stateful computation.
			switch init := init.(type) {
			case func():
				m.logger(s)
				init()
			case func() Letter:
				m.logger(s)
				l := init()
				m.input = &l
			}
		}
		for {
			var stopnow bool
			select {
			case <-m.stop:
				stopnow = true
			default:
			}
			if stopnow {
				break
			}
			if m.input != nil {
				l := *m.input
				// Reject upfront if letter is not in alphabet.
				if !m.e[l] {
					m.done <- rejected(s, "letter '%v' is not in alphabet", l)
					return
				}
				// Compose the domain element, so that the co-domain
				// element can be found via the transition function.
				de := domainelement{l: l, s: s}
				// Check the transition function.
				if coe := m.d[de]; coe != nil {
					s = coe.s
					switch exec := coe.exec.(type) {
					case func():
						m.logger(s)
						exec()
					case func() Letter:
						m.logger(s)
						l := exec()
						m.input = &l
					}
					if m.f[s] {
						// If the new state is a terminal state then
						// the DFA has accepted the input sequence
						// and it can stop.
						m.done <- accepted(s)
						return
					}
				} else {
					// Otherwise stop the DFA with a rejected state,
					// the DFA has rejected the input sequence.
					m.done <- rejected(s, "no state transition for input '%v' from '%v'", l, s)
					return
				}
			}
		}
		// The caller has closed the input channel, check if the
		// current state is accepted or rejected by the DFA.
		if m.f[s] {
			m.done <- accepted(s)
		} else {
			m.done <- rejected(s, "state '%v' is not terminal", s)
		}
	}()
	return m.result()
}

func (m *DFA) Stop() {
	close(m.stop)
}

func (m *DFA) result() (State, error) {
	t := <-m.done
	return t.s, t.err
}

func (m *DFA) GraphViz() string {
	var buf bytes.Buffer
	buf.WriteString("digraph {\n")
	for do, cdo := range m.d {
		if do.s == m.q0 {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		} else if m.f[cdo.s] {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		} else {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		}
	}
	buf.WriteString("}")
	return buf.String()
}

func accepted(s State) laststate {
	return laststate{s: s}
}

func rejected(s State, format string, a ...interface{}) laststate {
	return laststate{s: s, err: fmt.Errorf(format, a...)}
}
<commit_msg>Allow errors to be returned from functions.<commit_after>package dfa

import (
	"bytes"
	"fmt"
)

type State string

func (s State) String() string {
	return string(s)
}

type Letter string

func (l Letter) String() string {
	return string(l)
}

type DFA struct {
	q        map[State]bool                     // States
	e        map[Letter]bool                    // Alphabet
	d        map[domainelement]*codomainelement // Transition
	q0       State                              // Start State
	f        map[State]bool                     // Terminal States
	synccall bool                               // Call callbacks synchronously
	done     chan laststate                     // Termination channel
	input    *Letter                            // Inputs to the DFA
	stop     chan struct{}
	logger   func(State) // Logger for transitions
}

type domainelement struct {
	l Letter
	s State
}

type codomainelement struct {
	s    State
	exec interface{}
}

type laststate struct {
	s   State
	err error
}

func New() *DFA {
	return &DFA{
		q:      make(map[State]bool),
		e:      make(map[Letter]bool),
		f:      make(map[State]bool),
		d:      make(map[domainelement]*codomainelement),
		done:   make(chan laststate, 1),
		stop:   make(chan struct{}),
		logger: func(State) {},
	}
}

func (m *DFA) SetTransition(from State, input Letter, to State, exec interface{}) {
	if exec == nil {
		panic("stateful computation cannot be nil")
	}
	if from == State("") || to == State("") {
		panic("state cannot be defined as the empty string")
	}
	switch exec.(type) {
	case func() error:
		if !m.f[to] {
			panic(fmt.Sprintf("stateful computation must be of type 'func() (Letter, error)' for non-terminal '%v' state", to))
		}
	case func() (Letter, error):
		if m.f[to] {
			panic(fmt.Sprintf("stateful computation must be of type 'func() error' for terminal '%v' state", to))
		}
	default:
		panic("stateful computation must be of type 'func() error' or 'func() (Letter, error)")
	}
	m.q[to] = true
	m.q[from] = true
	m.e[input] = true
	de := domainelement{l: input, s: from}
	if _, ok := m.d[de]; !ok {
		m.d[de] = &codomainelement{s: to, exec: exec}
	}
}

func (m *DFA) SetStartState(q0 State) {
	m.q0 = q0
}

func (m *DFA) SetTerminalStates(f ...State) {
	for _, q := range f {
		m.f[q] = true
	}
}

func (m *DFA) SetTransitionLogger(logger func(State)) {
	m.logger = logger
}

func (m *DFA) States() []State {
	q := make([]State, 0, len(m.q))
	for s, _ := range m.q {
		q = append(q, s)
	}
	return q
}

func (m *DFA) Alphabet() []Letter {
	e := make([]Letter, 0, len(m.e))
	for l, _ := range m.e {
		e = append(e, l)
	}
	return e
}

func (m *DFA) Run(init interface{}) (State, error) {
	// Check some pre-conditions.
	if init == nil {
		panic("initial stateful computation is nil")
	}
	if m.q0 == State("") {
		panic("no start state definied")
	}
	if len(m.f) == 0 {
		panic("no terminal states definied")
	}
	if _, ok := m.q[m.q0]; !ok {
		panic(fmt.Sprintf("start state '%v' is not in the set of states", m.q0))
	}
	for s, _ := range m.f {
		if _, ok := m.q[s]; !ok {
			panic(fmt.Sprintf("terminal state '%v' is not in the set of states", s))
		}
	}
	// Run the DFA.
	go func() {
		defer close(m.done)
		// The current state, starts at q0.
		s := m.q0
		// Run the initial stateful computation.
		if m.f[s] {
			// If the state is a terminal state then the DFA has
			// accepted the input sequence and it can stop.
			m.done <- accepted(s)
			return
		} else {
			// Otherwise continue reading generated input
			// by starting the next stateful computation.
			switch init := init.(type) {
			case func() error:
				m.logger(s)
				err := init()
			case func() (Letter, error):
				m.logger(s)
				l, err := init()
				m.input = &l
			}
		}
		for {
			var stopnow bool
			select {
			case <-m.stop:
				stopnow = true
			default:
			}
			if stopnow {
				break
			}
			if m.input != nil {
				l := *m.input
				// Reject upfront if letter is not in alphabet.
				if !m.e[l] {
					m.done <- rejected(s, "letter '%v' is not in alphabet", l)
					return
				}
				// Compose the domain element, so that the co-domain
				// element can be found via the transition function.
				de := domainelement{l: l, s: s}
				// Check the transition function.
				if coe := m.d[de]; coe != nil {
					s = coe.s
					switch exec := coe.exec.(type) {
					case func():
						m.logger(s)
						exec()
					case func() Letter:
						m.logger(s)
						l := exec()
						m.input = &l
					}
					if m.f[s] {
						// If the new state is a terminal state then
						// the DFA has accepted the input sequence
						// and it can stop.
						m.done <- accepted(s)
						return
					}
				} else {
					// Otherwise stop the DFA with a rejected state,
					// the DFA has rejected the input sequence.
					m.done <- rejected(s, "no state transition for input '%v' from '%v'", l, s)
					return
				}
			}
		}
		// The caller has closed the input channel, check if the
		// current state is accepted or rejected by the DFA.
		if m.f[s] {
			m.done <- accepted(s)
		} else {
			m.done <- rejected(s, "state '%v' is not terminal", s)
		}
	}()
	return m.result()
}

func (m *DFA) Stop() {
	close(m.stop)
}

func (m *DFA) result() (State, error) {
	t := <-m.done
	return t.s, t.err
}

func (m *DFA) GraphViz() string {
	var buf bytes.Buffer
	buf.WriteString("digraph {\n")
	for do, cdo := range m.d {
		if do.s == m.q0 {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		} else if m.f[cdo.s] {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		} else {
			buf.WriteString(fmt.Sprintf("    \"%s\" -> \"%s\"[label=\"%s\"];\n", do.s, cdo.s, do.l))
		}
	}
	buf.WriteString("}")
	return buf.String()
}

func accepted(s State) laststate {
	return laststate{s: s}
}

func rejected(s State, format string, a ...interface{}) laststate {
	return laststate{s: s, err: fmt.Errorf(format, a...)}
}
<|endoftext|>


<commit_before>// go:generate go-bindata -o bindata.go template mapconfig
package main

import (
	"bytes"
	"database/sql"
	"fmt"
	"go/format"
	"log"
	"sort"
	"text/template"

	"github.com/BurntSushi/toml"
	"github.com/achiku/varfmt"
	"github.com/pkg/errors"
)

const pgLoadColumnDef = `
SELECT
    a.attnum AS field_ordinal,
    a.attname AS column_name,
    format_type(a.atttypid, a.atttypmod) AS data_type,
    a.attnotnull AS not_null,
    COALESCE(pg_get_expr(ad.adbin, ad.adrelid), '') AS default_value,
    COALESCE(ct.contype = 'p', false) AS  is_primary_key,
    CASE WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
      AND EXISTS (
         SELECT 1 FROM pg_attrdef ad
         WHERE  ad.adrelid = a.attrelid
         AND    ad.adnum   = a.attnum
         AND    ad.adsrc = 'nextval('''
            || (pg_get_serial_sequence (a.attrelid::regclass::text
                                      , a.attname))::regclass
            || '''::regclass)'
         )
    THEN CASE a.atttypid
            WHEN 'int'::regtype  THEN 'serial'
            WHEN 'int8'::regtype THEN 'bigserial'
            WHEN 'int2'::regtype THEN 'smallserial'
         END
    ELSE format_type(a.atttypid, a.atttypmod)
    END AS data_type
FROM pg_attribute a
JOIN ONLY pg_class c ON c.oid = a.attrelid
JOIN ONLY pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_constraint ct ON ct.conrelid = c.oid
AND a.attnum = ANY(ct.conkey) AND ct.contype IN ('p', 'u')
LEFT JOIN pg_attrdef ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
WHERE a.attisdropped = false
AND n.nspname = $1
AND c.relname = $2
AND a.attnum > 0
ORDER BY a.attnum
`

const pgLoadTableDef = `
SELECT
c.relkind AS type,
c.relname AS table_name
FROM pg_class c
JOIN ONLY pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = $1
AND c.relkind = 'r'
ORDER BY c.relname
`

// TypeMap go/db type map struct
type TypeMap struct {
	DBTypes        []string `toml:"db_types"`
	NotNullGoType  string   `toml:"notnull_go_type"`
	NullableGoType string   `toml:"nullable_go_type"`
}

// AutoKeyMap auto generating key config
type AutoKeyMap struct {
	Types []string `toml:"db_types"`
}

// PgTypeMapConfig go/db type map struct toml config
type PgTypeMapConfig map[string]TypeMap

// PgTable postgres table
type PgTable struct {
	Schema      string
	Name        string
	DataType    string
	AutoGenPk   bool
	PrimaryKeys []*PgColumn
	Columns     []*PgColumn
}

var autoGenKeyCfg = &AutoKeyMap{
	Types: []string{"serial", "bigserial", "UUID"},
}

func (t *PgTable) setPrimaryKeyInfo(cfg *AutoKeyMap) {
	t.AutoGenPk = false
	for _, c := range t.Columns {
		if c.IsPrimaryKey {
			t.PrimaryKeys = append(t.PrimaryKeys, c)
			for _, typ := range cfg.Types {
				if c.DDLType == typ {
					t.AutoGenPk = true
				}
			}
		}
	}
	return
}

// PgColumn postgres columns
type PgColumn struct {
	FieldOrdinal int
	Name         string
	DataType     string
	DDLType      string
	NotNull      bool
	DefaultValue sql.NullString
	IsPrimaryKey bool
}

// Struct go struct
type Struct struct {
	Name    string
	Table   *PgTable
	Comment string
	Fields  []*StructField
}

// StructTmpl go struct passed to template
type StructTmpl struct {
	Struct *Struct
}

// StructField go struct field
type StructField struct {
	Name   string
	Type   string
	Tag    string
	Column *PgColumn
}

// PgLoadTypeMapFromFile load type map from toml file
func PgLoadTypeMapFromFile(filePath string) (*PgTypeMapConfig, error) {
	var conf PgTypeMapConfig
	if _, err := toml.DecodeFile(filePath, &conf); err != nil {
		return nil, errors.Wrap(err, "faild to parse config file")
	}
	return &conf, nil
}

// PgLoadColumnDef load Postgres column definition
func PgLoadColumnDef(db Queryer, schema string, table string) ([]*PgColumn, error) {
	colDefs, err := db.Query(pgLoadColumnDef, schema, table)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load table def")
	}

	cols := []*PgColumn{}
	for colDefs.Next() {
		c := &PgColumn{}
		err := colDefs.Scan(
			&c.FieldOrdinal,
			&c.Name,
			&c.DataType,
			&c.NotNull,
			&c.DefaultValue,
			&c.IsPrimaryKey,
			&c.DDLType,
		)
		if err != nil {
			return nil, errors.Wrap(err, "failed to scan")
		}
		cols = append(cols, c)
	}
	return cols, nil
}

// PgLoadTableDef load Postgres table definition
func PgLoadTableDef(db Queryer, schema string) ([]*PgTable, error) {
	tbDefs, err := db.Query(pgLoadTableDef, schema)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load table def")
	}
	tbs := []*PgTable{}
	for tbDefs.Next() {
		t := &PgTable{Schema: schema}
		err := tbDefs.Scan(
			&t.DataType,
			&t.Name,
		)
		if err != nil {
			return nil, errors.Wrap(err, "failed to scan")
		}
		cols, err := PgLoadColumnDef(db, schema, t.Name)
		if err != nil {
			return nil, errors.Wrap(err, fmt.Sprintf("failed to get columns of %s", t.Name))
		}
		t.Columns = cols
		tbs = append(tbs, t)
	}
	return tbs, nil
}

func contains(v string, l []string) bool {
	sort.Strings(l)
	i := sort.SearchStrings(l, v)
	if i < len(l) && l[i] == v {
		return true
	}
	return false
}

// PgConvertType converts type
func PgConvertType(col *PgColumn, typeCfg *PgTypeMapConfig) string {
	cfg := map[string]TypeMap(*typeCfg)
	typ := cfg["default"].NotNullGoType
	for _, v := range cfg {
		if contains(col.DataType, v.DBTypes) {
			if col.NotNull {
				return v.NotNullGoType
			}
			return v.NullableGoType
		}
	}
	return typ
}

// PgColToField converts pg column to go struct field
func PgColToField(col *PgColumn, typeCfg *PgTypeMapConfig) (*StructField, error) {
	stfType := PgConvertType(col, typeCfg)
	stf := &StructField{
		Name:   varfmt.PublicVarName(col.Name),
		Type:   stfType,
		Column: col,
	}
	return stf, nil
}

// PgTableToStruct converts table def to go struct
func PgTableToStruct(t *PgTable, typeCfg *PgTypeMapConfig, keyConfig *AutoKeyMap) (*Struct, error) {
	t.setPrimaryKeyInfo(keyConfig)
	s := &Struct{
		Name:  varfmt.PublicVarName(t.Name),
		Table: t,
	}
	var fs []*StructField
	for _, c := range t.Columns {
		f, err := PgColToField(c, typeCfg)
		if err != nil {
			return nil, errors.Wrap(err, "faield to convert col to field")
		}
		fs = append(fs, f)
	}
	s.Fields = fs
	return s, nil
}

// PgExecuteStructTmpl execute struct template with *Struct
func PgExecuteStructTmpl(st *StructTmpl, path string) ([]byte, error) {
	var src []byte
	d, err := Asset(path)
	if err != nil {
		return src, errors.Wrap(err, "failed to load asset")
	}
	tpl, err := template.New("struct").Funcs(tmplFuncMap).Parse(string(d))
	if err != nil {
		return src, errors.Wrap(err, "failed to parse template")
	}
	buf := new(bytes.Buffer)
	if err := tpl.Execute(buf, st); err != nil {
		return src, errors.Wrap(err, fmt.Sprintf("failed to execute template:\n%s", src))
	}
	src, err = format.Source(buf.Bytes())
	if err != nil {
		log.Printf("%s", buf)
		return src, errors.Wrap(err, fmt.Sprintf("failed to format code:\n%s", src))
	}
	return src, nil
}

// PgCreateStruct creates struct from given schema
func PgCreateStruct(db Queryer, schema, typeMapPath, pkgName string, excludeTableName []string) ([]byte, error) {
	var src []byte
	pkgDef := []byte(fmt.Sprintf("package %s\n\n", pkgName))
	src = append(src, pkgDef...)

	tbls, err := PgLoadTableDef(db, schema)
	if err != nil {
		return src, errors.Wrap(err, "faield to load table definitions")
	}
	cfg := &PgTypeMapConfig{}
	if typeMapPath == "" {
		if _, err := toml.Decode(typeMap, cfg); err != nil {
			return src, errors.Wrap(err, "faield to read type map")
		}
	} else {
		if _, err := toml.DecodeFile(typeMapPath, cfg); err != nil {
			return src, errors.Wrap(err, fmt.Sprintf("failed to decode type map file %s", typeMapPath))
		}
	}
	for _, tbl := range tbls {
		if contains(tbl.Name, excludeTableName) {
			continue
		}
		st, err := PgTableToStruct(tbl, cfg, autoGenKeyCfg)
		if err != nil {
			return src, errors.Wrap(err, "faield to convert table definition to struct")
		}
		s, err := PgExecuteStructTmpl(&StructTmpl{Struct: st}, "template/struct.tmpl")
		if err != nil {
			return src, errors.Wrap(err, "faield to execute template")
		}
		m, err := PgExecuteStructTmpl(&StructTmpl{Struct: st}, "template/method.tmpl")
		if err != nil {
			return src, errors.Wrap(err, "faield to execute template")
		}
		src = append(src, s...)
		src = append(src, m...)
	}
	return src, nil
}
<commit_msg>Fix uuid col type name<commit_after>// go:generate go-bindata -o bindata.go template mapconfig
package main

import (
	"bytes"
	"database/sql"
	"fmt"
	"go/format"
	"log"
	"sort"
	"text/template"

	"github.com/BurntSushi/toml"
	"github.com/achiku/varfmt"
	"github.com/pkg/errors"
)

const pgLoadColumnDef = `
SELECT
    a.attnum AS field_ordinal,
    a.attname AS column_name,
    format_type(a.atttypid, a.atttypmod) AS data_type,
    a.attnotnull AS not_null,
    COALESCE(pg_get_expr(ad.adbin, ad.adrelid), '') AS default_value,
    COALESCE(ct.contype = 'p', false) AS  is_primary_key,
    CASE WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
      AND EXISTS (
         SELECT 1 FROM pg_attrdef ad
         WHERE  ad.adrelid = a.attrelid
         AND    ad.adnum   = a.attnum
         AND    ad.adsrc = 'nextval('''
            || (pg_get_serial_sequence (a.attrelid::regclass::text
                                      , a.attname))::regclass
            || '''::regclass)'
         )
    THEN CASE a.atttypid
            WHEN 'int'::regtype  THEN 'serial'
            WHEN 'int8'::regtype THEN 'bigserial'
            WHEN 'int2'::regtype THEN 'smallserial'
         END
    ELSE format_type(a.atttypid, a.atttypmod)
    END AS data_type
FROM pg_attribute a
JOIN ONLY pg_class c ON c.oid = a.attrelid
JOIN ONLY pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_constraint ct ON ct.conrelid = c.oid
AND a.attnum = ANY(ct.conkey) AND ct.contype IN ('p', 'u')
LEFT JOIN pg_attrdef ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
WHERE a.attisdropped = false
AND n.nspname = $1
AND c.relname = $2
AND a.attnum > 0
ORDER BY a.attnum
`

const pgLoadTableDef = `
SELECT
c.relkind AS type,
c.relname AS table_name
FROM pg_class c
JOIN ONLY pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = $1
AND c.relkind = 'r'
ORDER BY c.relname
`

// TypeMap go/db type map struct
type TypeMap struct {
	DBTypes        []string `toml:"db_types"`
	NotNullGoType  string   `toml:"notnull_go_type"`
	NullableGoType string   `toml:"nullable_go_type"`
}

// AutoKeyMap auto generating key config
type AutoKeyMap struct {
	Types []string `toml:"db_types"`
}

// PgTypeMapConfig go/db type map struct toml config
type PgTypeMapConfig map[string]TypeMap

// PgTable postgres table
type PgTable struct {
	Schema      string
	Name        string
	DataType    string
	AutoGenPk   bool
	PrimaryKeys []*PgColumn
	Columns     []*PgColumn
}

var autoGenKeyCfg = &AutoKeyMap{
	Types: []string{"serial", "bigserial", "uuid"},
}

func (t *PgTable) setPrimaryKeyInfo(cfg *AutoKeyMap) {
	t.AutoGenPk = false
	for _, c := range t.Columns {
		if c.IsPrimaryKey {
			t.PrimaryKeys = append(t.PrimaryKeys, c)
			for _, typ := range cfg.Types {
				if c.DDLType == typ {
					t.AutoGenPk = true
				}
			}
		}
	}
	return
}

// PgColumn postgres columns
type PgColumn struct {
	FieldOrdinal int
	Name         string
	DataType     string
	DDLType      string
	NotNull      bool
	DefaultValue sql.NullString
	IsPrimaryKey bool
}

// Struct go struct
type Struct struct {
	Name    string
	Table   *PgTable
	Comment string
	Fields  []*StructField
}

// StructTmpl go struct passed to template
type StructTmpl struct {
	Struct *Struct
}

// StructField go struct field
type StructField struct {
	Name   string
	Type   string
	Tag    string
	Column *PgColumn
}

// PgLoadTypeMapFromFile load type map from toml file
func PgLoadTypeMapFromFile(filePath string) (*PgTypeMapConfig, error) {
	var conf PgTypeMapConfig
	if _, err := toml.DecodeFile(filePath, &conf); err != nil {
		return nil, errors.Wrap(err, "faild to parse config file")
	}
	return &conf, nil
}

// PgLoadColumnDef load Postgres column definition
func PgLoadColumnDef(db Queryer, schema string, table string) ([]*PgColumn, error) {
	colDefs, err := db.Query(pgLoadColumnDef, schema, table)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load table def")
	}

	cols := []*PgColumn{}
	for colDefs.Next() {
		c := &PgColumn{}
		err := colDefs.Scan(
			&c.FieldOrdinal,
			&c.Name,
			&c.DataType,
			&c.NotNull,
			&c.DefaultValue,
			&c.IsPrimaryKey,
			&c.DDLType,
		)
		if err != nil {
			return nil, errors.Wrap(err, "failed to scan")
		}
		cols = append(cols, c)
	}
	return cols, nil
}

// PgLoadTableDef load Postgres table definition
func PgLoadTableDef(db Queryer, schema string) ([]*PgTable, error) {
	tbDefs, err := db.Query(pgLoadTableDef, schema)
	if err != nil {
		return nil, errors.Wrap(err, "failed to load table def")
	}
	tbs := []*PgTable{}
	for tbDefs.Next() {
		t := &PgTable{Schema: schema}
		err := tbDefs.Scan(
			&t.DataType,
			&t.Name,
		)
		if err != nil {
			return nil, errors.Wrap(err, "failed to scan")
		}
		cols, err := PgLoadColumnDef(db, schema, t.Name)
		if err != nil {
			return nil, errors.Wrap(err, fmt.Sprintf("failed to get columns of %s", t.Name))
		}
		t.Columns = cols
		tbs = append(tbs, t)
	}
	return tbs, nil
}

func contains(v string, l []string) bool {
	sort.Strings(l)
	i := sort.SearchStrings(l, v)
	if i < len(l) && l[i] == v {
		return true
	}
	return false
}

// PgConvertType converts type
func PgConvertType(col *PgColumn, typeCfg *PgTypeMapConfig) string {
	cfg := map[string]TypeMap(*typeCfg)
	typ := cfg["default"].NotNullGoType
	for _, v := range cfg {
		if contains(col.DataType, v.DBTypes) {
			if col.NotNull {
				return v.NotNullGoType
			}
			return v.NullableGoType
		}
	}
	return typ
}

// PgColToField converts pg column to go struct field
func PgColToField(col *PgColumn, typeCfg *PgTypeMapConfig) (*StructField, error) {
	stfType := PgConvertType(col, typeCfg)
	stf := &StructField{
		Name:   varfmt.PublicVarName(col.Name),
		Type:   stfType,
		Column: col,
	}
	return stf, nil
}

// PgTableToStruct converts table def to go struct
func PgTableToStruct(t *PgTable, typeCfg *PgTypeMapConfig, keyConfig *AutoKeyMap) (*Struct, error) {
	t.setPrimaryKeyInfo(keyConfig)
	s := &Struct{
		Name:  varfmt.PublicVarName(t.Name),
		Table: t,
	}
	var fs []*StructField
	for _, c := range t.Columns {
		f, err := PgColToField(c, typeCfg)
		if err != nil {
			return nil, errors.Wrap(err, "faield to convert col to field")
		}
		fs = append(fs, f)
	}
	s.Fields = fs
	return s, nil
}

// PgExecuteStructTmpl execute struct template with *Struct
func PgExecuteStructTmpl(st *StructTmpl, path string) ([]byte, error) {
	var src []byte
	d, err := Asset(path)
	if err != nil {
		return src, errors.Wrap(err, "failed to load asset")
	}
	tpl, err := template.New("struct").Funcs(tmplFuncMap).Parse(string(d))
	if err != nil {
		return src, errors.Wrap(err, "failed to parse template")
	}
	buf := new(bytes.Buffer)
	if err := tpl.Execute(buf, st); err != nil {
		return src, errors.Wrap(err, fmt.Sprintf("failed to execute template:\n%s", src))
	}
	src, err = format.Source(buf.Bytes())
	if err != nil {
		log.Printf("%s", buf)
		return src, errors.Wrap(err, fmt.Sprintf("failed to format code:\n%s", src))
	}
	return src, nil
}

// PgCreateStruct creates struct from given schema
func PgCreateStruct(db Queryer, schema, typeMapPath, pkgName string, excludeTableName []string) ([]byte, error) {
	var src []byte
	pkgDef := []byte(fmt.Sprintf("package %s\n\n", pkgName))
	src = append(src, pkgDef...)

	tbls, err := PgLoadTableDef(db, schema)
	if err != nil {
		return src, errors.Wrap(err, "faield to load table definitions")
	}
	cfg := &PgTypeMapConfig{}
	if typeMapPath == "" {
		if _, err := toml.Decode(typeMap, cfg); err != nil {
			return src, errors.Wrap(err, "faield to read type map")
		}
	} else {
		if _, err := toml.DecodeFile(typeMapPath, cfg); err != nil {
			return src, errors.Wrap(err, fmt.Sprintf("failed to decode type map file %s", typeMapPath))
		}
	}
	for _, tbl := range tbls {
		if contains(tbl.Name, excludeTableName) {
			continue
		}
		st, err := PgTableToStruct(tbl, cfg, autoGenKeyCfg)
		if err != nil {
			return src, errors.Wrap(err, "faield to convert table definition to struct")
		}
		s, err := PgExecuteStructTmpl(&StructTmpl{Struct: st}, "template/struct.tmpl")
		if err != nil {
			return src, errors.Wrap(err, "faield to execute template")
		}
		m, err := PgExecuteStructTmpl(&StructTmpl{Struct: st}, "template/method.tmpl")
		if err != nil {
			return src, errors.Wrap(err, "faield to execute template")
		}
		src = append(src, s...)
		src = append(src, m...)
	}
	return src, nil
}
<|endoftext|>


<commit_before>package handler

import (
	"errors"
	"os"
	"sync"

	"github.com/cloudfoundry-incubator/app-manager/start_message_builder"
	"github.com/cloudfoundry-incubator/delta_force/delta_force"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	steno "github.com/cloudfoundry/gosteno"
)

var ErrNoHealthCheckDefined = errors.New("no health check defined for stack")

type Handler struct {
	bbs                 Bbs.AppManagerBBS
	startMessageBuilder *start_message_builder.StartMessageBuilder
	logger              *steno.Logger
}

func NewHandler(
	bbs Bbs.AppManagerBBS,
	startMessageBuilder *start_message_builder.StartMessageBuilder,
	logger *steno.Logger,
) Handler {
	return Handler{
		bbs:                 bbs,
		startMessageBuilder: startMessageBuilder,
		logger:              logger,
	}
}

func (h Handler) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	wg := new(sync.WaitGroup)
	desiredChangeChan, stopChan, errChan := h.bbs.WatchForDesiredLRPChanges()

	close(ready)

	for {
		if desiredChangeChan == nil {
			desiredChangeChan, stopChan, errChan = h.bbs.WatchForDesiredLRPChanges()
		}
		select {
		case desiredChange, ok := <-desiredChangeChan:
			if ok {
				wg.Add(1)
				go func() {
					defer wg.Done()
					h.processDesiredChange(desiredChange)
				}()
			} else {
				h.logger.Error("app-manager.handler.watch-closed")
				desiredChangeChan = nil
			}

		case err, ok := <-errChan:
			if ok {
				h.logger.Errord(map[string]interface{}{
					"error": err.Error(),
				}, "app-manager.handler.received-watch-error")
			}
			desiredChangeChan = nil

		case <-signals:
			h.logger.Info("app-manager.handler.shutting-down")
			close(stopChan)
			wg.Wait()
			h.logger.Info("app-manager.handler.shut-down")
			return nil
		}
	}

	return nil
}

func (h Handler) processDesiredChange(desiredChange models.DesiredLRPChange) {
	var desiredLRP models.DesiredLRP
	var desiredInstances int

	if desiredChange.After == nil {
		desiredLRP = *desiredChange.Before
		desiredInstances = 0
	} else {
		desiredLRP = *desiredChange.After
		desiredInstances = desiredLRP.Instances
	}

	fileServerURL, err := h.bbs.GetAvailableFileServer()
	if err != nil {
		h.logger.Warnd(
			map[string]interface{}{
				"desired-app-message": desiredLRP,
				"error":               err.Error(),
			},
			"handler.get-available-file-server.failed",
		)

		return
	}

	actualInstances, instanceGuidToActual, err := h.actualsForProcessGuid(desiredLRP.ProcessGuid)
	if err != nil {
		h.logger.Errord(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"error":               err,
		}, "handler.fetch-actuals.failed")
		return
	}

	delta := delta_force.Reconcile(desiredInstances, actualInstances)

	for _, lrpIndex := range delta.IndicesToStart {
		h.logger.Infod(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"index":               lrpIndex,
		}, "handler.request-start")

		startMessage, err := h.startMessageBuilder.Build(desiredLRP, lrpIndex, fileServerURL)

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"index":               lrpIndex,
				"error":               err,
			}, "handler.build-start-message.failed")
			continue
		}

		err = h.bbs.RequestLRPStartAuction(startMessage)

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"index":               lrpIndex,
				"error":               err,
			}, "handler.request-start-auction.failed")
		}
	}

	for _, guidToStop := range delta.GuidsToStop {
		h.logger.Infod(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"stop-instance-guid":  guidToStop,
		}, "handler.request-stop")

		actualToStop := instanceGuidToActual[guidToStop]

		err = h.bbs.RequestStopLRPInstance(models.StopLRPInstance{
			ProcessGuid:  actualToStop.ProcessGuid,
			InstanceGuid: actualToStop.InstanceGuid,
			Index:        actualToStop.Index,
		})

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"stop-instance-guid":  guidToStop,
				"error":               err,
			}, "handler.request-stop-instance.failed")
		}
	}
}

func (h Handler) actualsForProcessGuid(lrpGuid string) (delta_force.ActualInstances, map[string]models.ActualLRP, error) {
	actualInstances := delta_force.ActualInstances{}
	actualLRPs, err := h.bbs.GetActualLRPsByProcessGuid(lrpGuid)
	instanceGuidToActual := map[string]models.ActualLRP{}

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

	for _, actualLRP := range actualLRPs {
		actualInstances = append(actualInstances, delta_force.ActualInstance{actualLRP.Index, actualLRP.InstanceGuid})
		instanceGuidToActual[actualLRP.InstanceGuid] = actualLRP
	}

	return actualInstances, instanceGuidToActual, err
}
<commit_msg>err -> err.Error() in logging<commit_after>package handler

import (
	"errors"
	"os"
	"sync"

	"github.com/cloudfoundry-incubator/app-manager/start_message_builder"
	"github.com/cloudfoundry-incubator/delta_force/delta_force"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	steno "github.com/cloudfoundry/gosteno"
)

var ErrNoHealthCheckDefined = errors.New("no health check defined for stack")

type Handler struct {
	bbs                 Bbs.AppManagerBBS
	startMessageBuilder *start_message_builder.StartMessageBuilder
	logger              *steno.Logger
}

func NewHandler(
	bbs Bbs.AppManagerBBS,
	startMessageBuilder *start_message_builder.StartMessageBuilder,
	logger *steno.Logger,
) Handler {
	return Handler{
		bbs:                 bbs,
		startMessageBuilder: startMessageBuilder,
		logger:              logger,
	}
}

func (h Handler) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	wg := new(sync.WaitGroup)
	desiredChangeChan, stopChan, errChan := h.bbs.WatchForDesiredLRPChanges()

	close(ready)

	for {
		if desiredChangeChan == nil {
			desiredChangeChan, stopChan, errChan = h.bbs.WatchForDesiredLRPChanges()
		}
		select {
		case desiredChange, ok := <-desiredChangeChan:
			if ok {
				wg.Add(1)
				go func() {
					defer wg.Done()
					h.processDesiredChange(desiredChange)
				}()
			} else {
				h.logger.Error("app-manager.handler.watch-closed")
				desiredChangeChan = nil
			}

		case err, ok := <-errChan:
			if ok {
				h.logger.Errord(map[string]interface{}{
					"error": err.Error(),
				}, "app-manager.handler.received-watch-error")
			}
			desiredChangeChan = nil

		case <-signals:
			h.logger.Info("app-manager.handler.shutting-down")
			close(stopChan)
			wg.Wait()
			h.logger.Info("app-manager.handler.shut-down")
			return nil
		}
	}

	return nil
}

func (h Handler) processDesiredChange(desiredChange models.DesiredLRPChange) {
	var desiredLRP models.DesiredLRP
	var desiredInstances int

	if desiredChange.After == nil {
		desiredLRP = *desiredChange.Before
		desiredInstances = 0
	} else {
		desiredLRP = *desiredChange.After
		desiredInstances = desiredLRP.Instances
	}

	fileServerURL, err := h.bbs.GetAvailableFileServer()
	if err != nil {
		h.logger.Warnd(
			map[string]interface{}{
				"desired-app-message": desiredLRP,
				"error":               err.Error(),
			},
			"handler.get-available-file-server.failed",
		)

		return
	}

	actualInstances, instanceGuidToActual, err := h.actualsForProcessGuid(desiredLRP.ProcessGuid)
	if err != nil {
		h.logger.Errord(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"error":               err.Error(),
		}, "handler.fetch-actuals.failed")
		return
	}

	delta := delta_force.Reconcile(desiredInstances, actualInstances)

	for _, lrpIndex := range delta.IndicesToStart {
		h.logger.Infod(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"index":               lrpIndex,
		}, "handler.request-start")

		startMessage, err := h.startMessageBuilder.Build(desiredLRP, lrpIndex, fileServerURL)

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"index":               lrpIndex,
				"error":               err.Error(),
			}, "handler.build-start-message.failed")
			continue
		}

		err = h.bbs.RequestLRPStartAuction(startMessage)

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"index":               lrpIndex,
				"error":               err.Error(),
			}, "handler.request-start-auction.failed")
		}
	}

	for _, guidToStop := range delta.GuidsToStop {
		h.logger.Infod(map[string]interface{}{
			"desired-app-message": desiredLRP,
			"stop-instance-guid":  guidToStop,
		}, "handler.request-stop")

		actualToStop := instanceGuidToActual[guidToStop]

		err = h.bbs.RequestStopLRPInstance(models.StopLRPInstance{
			ProcessGuid:  actualToStop.ProcessGuid,
			InstanceGuid: actualToStop.InstanceGuid,
			Index:        actualToStop.Index,
		})

		if err != nil {
			h.logger.Errord(map[string]interface{}{
				"desired-app-message": desiredLRP,
				"stop-instance-guid":  guidToStop,
				"error":               err.Error(),
			}, "handler.request-stop-instance.failed")
		}
	}
}

func (h Handler) actualsForProcessGuid(lrpGuid string) (delta_force.ActualInstances, map[string]models.ActualLRP, error) {
	actualInstances := delta_force.ActualInstances{}
	actualLRPs, err := h.bbs.GetActualLRPsByProcessGuid(lrpGuid)
	instanceGuidToActual := map[string]models.ActualLRP{}

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

	for _, actualLRP := range actualLRPs {
		actualInstances = append(actualInstances, delta_force.ActualInstance{actualLRP.Index, actualLRP.InstanceGuid})
		instanceGuidToActual[actualLRP.InstanceGuid] = actualLRP
	}

	return actualInstances, instanceGuidToActual, err
}
<|endoftext|>


<commit_before>package handler

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"sort"
	"unicode/utf8"

	"golang.org/x/net/context"

	log "github.com/Sirupsen/logrus"
	"github.com/camptocamp/conplicity/config"
	"github.com/camptocamp/conplicity/util"
	"github.com/camptocamp/conplicity/volume"
	docker "github.com/docker/engine-api/client"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
)

// Conplicity is the main handler struct
type Conplicity struct {
	*docker.Client
	Config   *config.Config
	Hostname string
	Metrics  []string
}

// NewConplicity returns a new Conplicity handler
func NewConplicity(version string) (*Conplicity, error) {
	c := &Conplicity{}
	err := c.Setup(version)
	return c, err
}

// Setup sets up a Conplicity struct
func (c *Conplicity) Setup(version string) (err error) {
	c.Config = config.LoadConfig(version)

	err = c.setupLoglevel()
	util.CheckErr(err, "Failed to setup log level: %v", "fatal")

	err = c.GetHostname()
	util.CheckErr(err, "Failed to get hostname: %v", "fatal")

	err = c.SetupDocker()
	util.CheckErr(err, "Failed to setup docker: %v", "fatal")

	return
}

// GetHostname gets the host name
func (c *Conplicity) GetHostname() (err error) {
	if c.Config.HostnameFromRancher {
		resp, err := http.Get("http://rancher-metadata/latest/self/host/name")
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		c.Hostname = string(body)
	} else {
		c.Hostname, err = os.Hostname()
	}
	return
}

// SetupDocker for the  client
func (c *Conplicity) SetupDocker() (err error) {
	c.Client, err = docker.NewClient(c.Config.Docker.Endpoint, "", nil, nil)
	util.CheckErr(err, "Failed to create Docker client: %v", "fatal")
	return
}

// GetVolumes returns the Docker volumes, inspected and filtered
func (c *Conplicity) GetVolumes() (volumes []*volume.Volume, err error) {
	vols, err := c.VolumeList(context.Background(), filters.NewArgs())
	if err != nil {
		err = fmt.Errorf("Failed to list Docker volumes: %v", err)
		return
	}
	for _, vol := range vols.Volumes {
		var voll types.Volume
		voll, err = c.VolumeInspect(context.Background(), vol.Name)
		if err != nil {
			err = fmt.Errorf("Failed to inspect volume %s: %v", vol.Name, err)
			return
		}
		if b, r, s := c.blacklistedVolume(&voll); b {
			log.WithFields(log.Fields{
				"volume": vol.Name,
				"reason": r,
				"source": s,
			}).Info("Ignoring volume")
			continue
		}
		v := volume.NewVolume(vol)
		volumes = append(volumes, v)
	}
	return
}

func (c *Conplicity) blacklistedVolume(vol *types.Volume) (bool, string, string) {
	if utf8.RuneCountInString(vol.Name) == 64 || vol.Name == "duplicity_cache" || vol.Name == "lost+found" {
		return true, "unnamed", ""
	}

	list := c.Config.VolumesBlacklist
	i := sort.SearchStrings(list, vol.Name)
	if i < len(list) && list[i] == vol.Name {
		return true, "blacklisted", "blacklist config"
	}

	if ignoreLbl, _ := util.GetVolumeLabel(vol, ".ignore"); ignoreLbl == "true" {
		return true, "blacklisted", "volume label"
	}

	return false, "", ""
}

func (c *Conplicity) setupLoglevel() (err error) {
	switch c.Config.Loglevel {
	case "debug":
		log.SetLevel(log.DebugLevel)
	case "info":
		log.SetLevel(log.InfoLevel)
	case "warn":
		log.SetLevel(log.WarnLevel)
	case "error":
		log.SetLevel(log.ErrorLevel)
	case "fatal":
		log.SetLevel(log.FatalLevel)
	case "panic":
		log.SetLevel(log.PanicLevel)
	default:
		errMsg := fmt.Sprintf("Wrong log level '%v'", c.Config.Loglevel)
		err = errors.New(errMsg)
	}

	if c.Config.JSON {
		log.SetFormatter(&log.JSONFormatter{})
	}

	return
}
<commit_msg>Fix volume labels fetch (fixes #83)<commit_after>package handler

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"sort"
	"unicode/utf8"

	"golang.org/x/net/context"

	log "github.com/Sirupsen/logrus"
	"github.com/camptocamp/conplicity/config"
	"github.com/camptocamp/conplicity/util"
	"github.com/camptocamp/conplicity/volume"
	docker "github.com/docker/engine-api/client"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
)

// Conplicity is the main handler struct
type Conplicity struct {
	*docker.Client
	Config   *config.Config
	Hostname string
	Metrics  []string
}

// NewConplicity returns a new Conplicity handler
func NewConplicity(version string) (*Conplicity, error) {
	c := &Conplicity{}
	err := c.Setup(version)
	return c, err
}

// Setup sets up a Conplicity struct
func (c *Conplicity) Setup(version string) (err error) {
	c.Config = config.LoadConfig(version)

	err = c.setupLoglevel()
	util.CheckErr(err, "Failed to setup log level: %v", "fatal")

	err = c.GetHostname()
	util.CheckErr(err, "Failed to get hostname: %v", "fatal")

	err = c.SetupDocker()
	util.CheckErr(err, "Failed to setup docker: %v", "fatal")

	return
}

// GetHostname gets the host name
func (c *Conplicity) GetHostname() (err error) {
	if c.Config.HostnameFromRancher {
		resp, err := http.Get("http://rancher-metadata/latest/self/host/name")
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		c.Hostname = string(body)
	} else {
		c.Hostname, err = os.Hostname()
	}
	return
}

// SetupDocker for the  client
func (c *Conplicity) SetupDocker() (err error) {
	c.Client, err = docker.NewClient(c.Config.Docker.Endpoint, "", nil, nil)
	util.CheckErr(err, "Failed to create Docker client: %v", "fatal")
	return
}

// GetVolumes returns the Docker volumes, inspected and filtered
func (c *Conplicity) GetVolumes() (volumes []*volume.Volume, err error) {
	vols, err := c.VolumeList(context.Background(), filters.NewArgs())
	if err != nil {
		err = fmt.Errorf("Failed to list Docker volumes: %v", err)
		return
	}
	for _, vol := range vols.Volumes {
		var voll types.Volume
		voll, err = c.VolumeInspect(context.Background(), vol.Name)
		if err != nil {
			err = fmt.Errorf("Failed to inspect volume %s: %v", vol.Name, err)
			return
		}
		if b, r, s := c.blacklistedVolume(&voll); b {
			log.WithFields(log.Fields{
				"volume": vol.Name,
				"reason": r,
				"source": s,
			}).Info("Ignoring volume")
			continue
		}
		v := volume.NewVolume(&voll)
		volumes = append(volumes, v)
	}
	return
}

func (c *Conplicity) blacklistedVolume(vol *types.Volume) (bool, string, string) {
	if utf8.RuneCountInString(vol.Name) == 64 || vol.Name == "duplicity_cache" || vol.Name == "lost+found" {
		return true, "unnamed", ""
	}

	list := c.Config.VolumesBlacklist
	i := sort.SearchStrings(list, vol.Name)
	if i < len(list) && list[i] == vol.Name {
		return true, "blacklisted", "blacklist config"
	}

	if ignoreLbl, _ := util.GetVolumeLabel(vol, ".ignore"); ignoreLbl == "true" {
		return true, "blacklisted", "volume label"
	}

	return false, "", ""
}

func (c *Conplicity) setupLoglevel() (err error) {
	switch c.Config.Loglevel {
	case "debug":
		log.SetLevel(log.DebugLevel)
	case "info":
		log.SetLevel(log.InfoLevel)
	case "warn":
		log.SetLevel(log.WarnLevel)
	case "error":
		log.SetLevel(log.ErrorLevel)
	case "fatal":
		log.SetLevel(log.FatalLevel)
	case "panic":
		log.SetLevel(log.PanicLevel)
	default:
		errMsg := fmt.Sprintf("Wrong log level '%v'", c.Config.Loglevel)
		err = errors.New(errMsg)
	}

	if c.Config.JSON {
		log.SetFormatter(&log.JSONFormatter{})
	}

	return
}
<|endoftext|>


<commit_before>// Copyright © 2015-2017 Hilko Bengen <bengen@hilluzination.de>
// All rights reserved.
//
// Use of this source code is governed by the license that can be
// found in the LICENSE file.

package yara

/*
#include <yara.h>

// rule_identifier is a union accessor function.
static const char* rule_identifier(YR_RULE* r) {
	return r->identifier;
}

// rule_namespace is a union accessor function.
static const char* rule_namespace(YR_RULE* r) {
	return r->ns->name;
}

// rule_tags returns pointers to the tag names associated with a rule,
// using YARA's own implementation
static void rule_tags(YR_RULE* r, const char *tags[], int *n) {
	const char *tag;
	int i = 0;
	yr_rule_tags_foreach(r, tag) {
		if (i < *n)
			tags[i] = tag;
		i++;
	};
	*n = i;
	return;
}

// rule_tags returns pointers to the meta variables associated with a
// rule, using YARA's own implementation
static void rule_metas(YR_RULE* r, const YR_META *metas[], int *n) {
	const YR_META *meta;
	int i = 0;
	yr_rule_metas_foreach(r, meta) {
		if (i < *n)
			metas[i] = meta;
		i++;
	};
	*n = i;
	return;
}

// meta_get is an accessor function for unions that are not directly
// accessible from Go because CGO does not understand them.
static void meta_get(YR_META *m, const char** identifier, char** string) {
	*identifier = m->identifier;
	*string = m->string;
	return;
}
*/
import "C"

// Rule represents a single rule as part of a ruleset
type Rule struct{ cptr *C.YR_RULE }

// Identifier returns the rule's name.
func (r *Rule) Identifier() string {
	return C.GoString(C.rule_identifier(r.cptr))
}

// Namespace returns the rule's namespace.
func (r *Rule) Namespace() string {
	return C.GoString(C.rule_namespace(r.cptr))
}

// Tags returns the rule's tags.
func (r *Rule) Tags() (tags []string) {
	var size C.int
	C.rule_tags(r.cptr, nil, &size)
	if size == 0 {
		return
	}
	tagptrs := make([]*C.char, int(size))
	C.rule_tags(r.cptr, &tagptrs[0], &size)
	for _, t := range tagptrs {
		tags = append(tags, C.GoString(t))
	}
	return
}

// Metas returns a map containing the rule's meta variables. Values
// can be of type string, int, bool, or nil.
func (r *Rule) Metas() (metas map[string]interface{}) {
	metas = make(map[string]interface{})
	var size C.int
	C.rule_metas(r.cptr, nil, &size)
	if size == 0 {
		return
	}
	mptrs := make([]*C.YR_META, int(size))
	C.rule_metas(r.cptr, &mptrs[0], &size)
	for _, m := range mptrs {
		var id, str *C.char
		C.meta_get(m, &id, &str)
		switch m._type {
		case C.META_TYPE_NULL:
			metas[C.GoString(id)] = nil
		case C.META_TYPE_STRING:
			metas[C.GoString(id)] = C.GoString(str)
		case C.META_TYPE_INTEGER:
			metas[C.GoString(id)] = int(m.integer)
		case C.META_TYPE_BOOLEAN:
			metas[C.GoString(id)] = m.integer != 0
		}
	}
	return
}
<commit_msg>Implement containers for YR_STRING, YR_MATCH<commit_after>// Copyright © 2015-2017 Hilko Bengen <bengen@hilluzination.de>
// All rights reserved.
//
// Use of this source code is governed by the license that can be
// found in the LICENSE file.

package yara

/*
#include <yara.h>

// rule_identifier is a union accessor function.
static const char* rule_identifier(YR_RULE* r) {
	return r->identifier;
}

// rule_namespace is a union accessor function.
static const char* rule_namespace(YR_RULE* r) {
	return r->ns->name;
}

// rule_tags returns pointers to the tag names associated with a rule,
// using YARA's own implementation
static void rule_tags(YR_RULE* r, const char *tags[], int *n) {
	const char *tag;
	int i = 0;
	yr_rule_tags_foreach(r, tag) {
		if (i < *n)
			tags[i] = tag;
		i++;
	};
	*n = i;
	return;
}

// rule_tags returns pointers to the meta variables associated with a
// rule, using YARA's own implementation
static void rule_metas(YR_RULE* r, const YR_META *metas[], int *n) {
	const YR_META *meta;
	int i = 0;
	yr_rule_metas_foreach(r, meta) {
		if (i < *n)
			metas[i] = meta;
		i++;
	};
	*n = i;
	return;
}

// meta_get is an accessor function for unions that are not directly
// accessible from Go because CGO does not understand them.
static void meta_get(YR_META *m, const char** identifier, char** string) {
	*identifier = m->identifier;
	*string = m->string;
	return;
}

// rule_strings returns pointers to the matching strings associated
// with a rule, using YARA's own implementation.
static void rule_strings(YR_RULE* r, const YR_STRING *strings[], int *n) {
	const YR_STRING *string;
	int i = 0;
	yr_rule_strings_foreach(r, string) {
		if (i < *n)
			strings[i] = string;
		i++;
	}
	*n = i;
	return;
}

// string_identifier is a union accessor function.
static const char* string_identifier(YR_STRING* s) {
	return s->identifier;
}

// string_matches
static void string_matches(YR_STRING* s, const YR_MATCH *matches[], int *n) {
	const YR_MATCH *match;
	int i = 0;
	yr_string_matches_foreach(s, match) {
		if (i < *n)
			matches[i] = match;
		i++;
	};
	*n = i;
	return;
}

*/
import "C"
import "unsafe"

// Rule represents a single rule as part of a ruleset
type Rule struct{ cptr *C.YR_RULE }

// Identifier returns the rule's name.
func (r *Rule) Identifier() string {
	return C.GoString(C.rule_identifier(r.cptr))
}

// Namespace returns the rule's namespace.
func (r *Rule) Namespace() string {
	return C.GoString(C.rule_namespace(r.cptr))
}

// Tags returns the rule's tags.
func (r *Rule) Tags() (tags []string) {
	var size C.int
	C.rule_tags(r.cptr, nil, &size)
	if size == 0 {
		return
	}
	tagptrs := make([]*C.char, int(size))
	C.rule_tags(r.cptr, &tagptrs[0], &size)
	for _, t := range tagptrs {
		tags = append(tags, C.GoString(t))
	}
	return
}

// Metas returns a map containing the rule's meta variables. Values
// can be of type string, int, bool, or nil.
func (r *Rule) Metas() (metas map[string]interface{}) {
	metas = make(map[string]interface{})
	var size C.int
	C.rule_metas(r.cptr, nil, &size)
	if size == 0 {
		return
	}
	mptrs := make([]*C.YR_META, int(size))
	C.rule_metas(r.cptr, &mptrs[0], &size)
	for _, m := range mptrs {
		var id, str *C.char
		C.meta_get(m, &id, &str)
		switch m._type {
		case C.META_TYPE_NULL:
			metas[C.GoString(id)] = nil
		case C.META_TYPE_STRING:
			metas[C.GoString(id)] = C.GoString(str)
		case C.META_TYPE_INTEGER:
			metas[C.GoString(id)] = int(m.integer)
		case C.META_TYPE_BOOLEAN:
			metas[C.GoString(id)] = m.integer != 0
		}
	}
	return
}

// String represents a string as part of a rule
type String struct{ cptr *C.YR_STRING }

// Strings returns the rule's strings
func (r *Rule) Strings() (strs []String) {
	var size C.int
	C.rule_strings(r.cptr, nil, &size)
	if size == 0 {
		return
	}
	ptrs := make([]*C.YR_STRING, int(size))
	C.rule_strings(r.cptr, &ptrs[0], &size)
	for _, ptr := range ptrs {
		strs = append(strs, String{ptr})
	}
	return
}

// Identifier returns the string's name
func (s *String) Identifier() string {
	return C.GoString(C.string_identifier(s.cptr))
}

// Match represents a string match
type Match struct{ cptr *C.YR_MATCH }

// Matches returns all matches that have been recorded for the string.
func (s *String) Matches() (matches []Match) {
	var size C.int
	C.string_matches(s.cptr, nil, &size)
	ptrs := make([]*C.YR_MATCH, int(size))
	if size == 0 {
		return
	}
	C.string_matches(s.cptr, &ptrs[0], &size)
	for _, ptr := range ptrs {
		matches = append(matches, Match{ptr})
	}
	return
}

// Data returns the blob of data associated with the string match
func (m *Match) Data() []byte {
	return C.GoBytes(unsafe.Pointer(m.cptr.data), C.int(m.cptr.data_length))
}

// Offset returns the offset at which the string match occurred
func (m *Match) Offset() int64 {
	return int64(m.cptr.offset)
}
<|endoftext|>


<commit_before>package golang

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"path/filepath"

	"strings"

	"github.com/golang/gddo/gosrc"
	"github.com/peterbourgon/diskv"
	"github.com/sourcegraph/httpcache"
	"github.com/sourcegraph/httpcache/diskcache"
	"sourcegraph.com/sourcegraph/srcgraph/config"
	"sourcegraph.com/sourcegraph/srcgraph/container"
	"sourcegraph.com/sourcegraph/srcgraph/dep2"
	"sourcegraph.com/sourcegraph/srcgraph/task2"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	dep2.RegisterLister(&Package{}, dep2.DockerLister{defaultGoVersion})
	dep2.RegisterResolver(goImportPathTargetType, defaultGoVersion)
}

func (v *goVersion) BuildLister(dir string, unit unit.SourceUnit, c *config.Repository, x *task2.Context) (*container.Command, error) {
	goConfig := v.goConfig(c)
	pkg := unit.(*Package)

	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}

	containerDir := filepath.Join(containerGOPATH, "src", goConfig.BaseImportPath)
	cmd := container.Command{
		Container: container.Container{
			Dockerfile: dockerfile,
			RunOptions: []string{"-v", dir + ":" + containerDir},
			// TODO(sqs): include TestImports and XTestImports
			Cmd: []string{"go", "list", "-e", "-f", `[{{if .Imports}}"{{join .Imports "\",\""}}"{{end}}]`, pkg.ImportPath},
		},
		Transform: func(orig []byte) ([]byte, error) {
			var importPaths []string
			err := json.Unmarshal(orig, &importPaths)
			if err != nil {
				return nil, err
			}

			deps := make([]*dep2.RawDependency, len(importPaths))
			for i, importPath := range importPaths {
				deps[i] = &dep2.RawDependency{
					TargetType: goImportPathTargetType,
					Target:     goImportPath(importPath),
				}
			}

			return json.Marshal(deps)
		},
	}
	return &cmd, nil
}

// goImportPath represents a Go import path, such as "github.com/user/repo" or
// "net/http".
type goImportPath string

const goImportPathTargetType = "go-import-path"

func (v *goVersion) Resolve(dep *dep2.RawDependency, c *config.Repository, x *task2.Context) (*dep2.ResolvedTarget, error) {
	importPath := dep.Target.(string)
	return v.resolveGoImportDep(importPath, c, x)
}

func (v *goVersion) resolveGoImportDep(importPath string, c *config.Repository, x *task2.Context) (*dep2.ResolvedTarget, error) {
	// Look up in cache.
	resolvedTarget := func() *dep2.ResolvedTarget {
		v.resolveCacheMu.Lock()
		defer v.resolveCacheMu.Unlock()
		return v.resolveCache[importPath]
	}()
	if resolvedTarget != nil {
		return resolvedTarget, nil
	}

	// Check if this importPath is in this repository.
	goConfig := v.goConfig(c)
	if strings.HasPrefix(importPath, goConfig.BaseImportPath) {
		dir, err := filepath.Rel(goConfig.BaseImportPath, importPath)
		if err != nil {
			return nil, err
		}
		toUnit := &Package{Dir: dir, ImportPath: importPath}
		return &dep2.ResolvedTarget{
			// TODO(sqs): this is a URI not a clone URL
			ToRepoCloneURL: string(c.URI),
			ToUnit:         toUnit.Name(),
			ToUnitType:     unit.Type(toUnit),
		}, nil
	}

	// Special-case the cgo package "C".
	if importPath == "C" {
		return nil, nil
	}

	if gosrc.IsGoRepoPath(importPath) {
		toUnit := &Package{ImportPath: importPath, Dir: "src/pkg/" + importPath}
		return &dep2.ResolvedTarget{
			ToRepoCloneURL:  v.RepositoryCloneURL,
			ToVersionString: v.VersionString,
			ToRevSpec:       v.VCSRevision,
			ToUnit:          toUnit.Name(),
			ToUnitType:      unit.Type(toUnit),
		}, nil
	}

	x.Log.Printf("Resolving Go dep: %s", importPath)

	dir, err := gosrc.Get(cachingHTTPClient, string(importPath), "")
	if err != nil {
		return nil, fmt.Errorf("unable to fetch information about Go package %q", importPath)
	}

	// gosrc returns code.google.com URLs ending in a slash. Remove it.
	dir.ProjectURL = strings.TrimSuffix(dir.ProjectURL, "/")

	toUnit := &Package{ImportPath: dir.ImportPath}
	toUnit.Dir, err = filepath.Rel(dir.ProjectRoot, dir.ImportPath)
	if err != nil {
		return nil, err
	}

	resolvedTarget = &dep2.ResolvedTarget{
		ToRepoCloneURL: dir.ProjectURL,
		ToUnit:         toUnit.Name(),
		ToUnitType:     unit.Type(toUnit),
	}

	if gosrc.IsGoRepoPath(dir.ImportPath) {
		resolvedTarget.ToVersionString = v.VersionString
		resolvedTarget.ToRevSpec = v.VCSRevision
		resolvedTarget.ToUnit = "src/pkg/" + resolvedTarget.ToUnit
	}

	// Save in cache.
	v.resolveCacheMu.Lock()
	defer v.resolveCacheMu.Unlock()
	if v.resolveCache == nil {
		v.resolveCache = make(map[string]*dep2.ResolvedTarget)
	}
	v.resolveCache[importPath] = resolvedTarget

	return resolvedTarget, nil
}

var cachingHTTPClient = &http.Client{
	Transport: &httpcache.Transport{
		Cache: diskcache.NewWithDiskv(diskv.New(diskv.Options{
			BasePath:     filepath.Join(os.TempDir(), "sg-golang-toolchain-cache"),
			CacheSizeMax: 5000 * 1024 * 100, // 500 MB
		})),
	},
}
<commit_msg>get TestImports and XTestImports<commit_after>package golang

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"path/filepath"

	"strings"

	"github.com/golang/gddo/gosrc"
	"github.com/peterbourgon/diskv"
	"github.com/sourcegraph/httpcache"
	"github.com/sourcegraph/httpcache/diskcache"
	"sourcegraph.com/sourcegraph/srcgraph/config"
	"sourcegraph.com/sourcegraph/srcgraph/container"
	"sourcegraph.com/sourcegraph/srcgraph/dep2"
	"sourcegraph.com/sourcegraph/srcgraph/task2"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	dep2.RegisterLister(&Package{}, dep2.DockerLister{defaultGoVersion})
	dep2.RegisterResolver(goImportPathTargetType, defaultGoVersion)
}

func (v *goVersion) BuildLister(dir string, unit unit.SourceUnit, c *config.Repository, x *task2.Context) (*container.Command, error) {
	goConfig := v.goConfig(c)
	pkg := unit.(*Package)

	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}

	containerDir := filepath.Join(containerGOPATH, "src", goConfig.BaseImportPath)
	cmd := container.Command{
		Container: container.Container{
			Dockerfile: dockerfile,
			RunOptions: []string{"-v", dir + ":" + containerDir},
			// TODO(sqs): include TestImports and XTestImports
			Cmd: []string{"go", "list", "-e", "-f", `{{join .Imports "\n"}}{{join .TestImports "\n"}}{{join .XTestImports "\n"}}`, pkg.ImportPath},
		},
		Transform: func(orig []byte) ([]byte, error) {
			importPaths := strings.Split(string(orig), "\n")
			var deps []*dep2.RawDependency
			for _, importPath := range importPaths {
				if importPath == "" {
					continue
				}
				deps = append(deps, &dep2.RawDependency{
					TargetType: goImportPathTargetType,
					Target:     goImportPath(importPath),
				})
			}

			return json.Marshal(deps)
		},
	}
	return &cmd, nil
}

// goImportPath represents a Go import path, such as "github.com/user/repo" or
// "net/http".
type goImportPath string

const goImportPathTargetType = "go-import-path"

func (v *goVersion) Resolve(dep *dep2.RawDependency, c *config.Repository, x *task2.Context) (*dep2.ResolvedTarget, error) {
	importPath := dep.Target.(string)
	return v.resolveGoImportDep(importPath, c, x)
}

func (v *goVersion) resolveGoImportDep(importPath string, c *config.Repository, x *task2.Context) (*dep2.ResolvedTarget, error) {
	// Look up in cache.
	resolvedTarget := func() *dep2.ResolvedTarget {
		v.resolveCacheMu.Lock()
		defer v.resolveCacheMu.Unlock()
		return v.resolveCache[importPath]
	}()
	if resolvedTarget != nil {
		return resolvedTarget, nil
	}

	// Check if this importPath is in this repository.
	goConfig := v.goConfig(c)
	if strings.HasPrefix(importPath, goConfig.BaseImportPath) {
		dir, err := filepath.Rel(goConfig.BaseImportPath, importPath)
		if err != nil {
			return nil, err
		}
		toUnit := &Package{Dir: dir, ImportPath: importPath}
		return &dep2.ResolvedTarget{
			// TODO(sqs): this is a URI not a clone URL
			ToRepoCloneURL: string(c.URI),
			ToUnit:         toUnit.Name(),
			ToUnitType:     unit.Type(toUnit),
		}, nil
	}

	// Special-case the cgo package "C".
	if importPath == "C" {
		return nil, nil
	}

	if gosrc.IsGoRepoPath(importPath) {
		toUnit := &Package{ImportPath: importPath, Dir: "src/pkg/" + importPath}
		return &dep2.ResolvedTarget{
			ToRepoCloneURL:  v.RepositoryCloneURL,
			ToVersionString: v.VersionString,
			ToRevSpec:       v.VCSRevision,
			ToUnit:          toUnit.Name(),
			ToUnitType:      unit.Type(toUnit),
		}, nil
	}

	x.Log.Printf("Resolving Go dep: %s", importPath)

	dir, err := gosrc.Get(cachingHTTPClient, string(importPath), "")
	if err != nil {
		return nil, fmt.Errorf("unable to fetch information about Go package %q", importPath)
	}

	// gosrc returns code.google.com URLs ending in a slash. Remove it.
	dir.ProjectURL = strings.TrimSuffix(dir.ProjectURL, "/")

	toUnit := &Package{ImportPath: dir.ImportPath}
	toUnit.Dir, err = filepath.Rel(dir.ProjectRoot, dir.ImportPath)
	if err != nil {
		return nil, err
	}

	resolvedTarget = &dep2.ResolvedTarget{
		ToRepoCloneURL: dir.ProjectURL,
		ToUnit:         toUnit.Name(),
		ToUnitType:     unit.Type(toUnit),
	}

	if gosrc.IsGoRepoPath(dir.ImportPath) {
		resolvedTarget.ToVersionString = v.VersionString
		resolvedTarget.ToRevSpec = v.VCSRevision
		resolvedTarget.ToUnit = "src/pkg/" + resolvedTarget.ToUnit
	}

	// Save in cache.
	v.resolveCacheMu.Lock()
	defer v.resolveCacheMu.Unlock()
	if v.resolveCache == nil {
		v.resolveCache = make(map[string]*dep2.ResolvedTarget)
	}
	v.resolveCache[importPath] = resolvedTarget

	return resolvedTarget, nil
}

var cachingHTTPClient = &http.Client{
	Transport: &httpcache.Transport{
		Cache: diskcache.NewWithDiskv(diskv.New(diskv.Options{
			BasePath:     filepath.Join(os.TempDir(), "sg-golang-toolchain-cache"),
			CacheSizeMax: 5000 * 1024 * 100, // 500 MB
		})),
	},
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/ec2"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()
	_, err = ec2.Conn()
	if err != nil {
		log.Print("Got error while connecting with ec2:")
		log.Print(err.Error())
	}

	repository.RunAgent()
	m := pat.New()

	m.Post("/services/instances", AuthorizationRequiredHandler(service.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(service.BindHandler))

	m.Post("/services", AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", AuthorizationRequiredHandler(service.ServicesHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(service.DeleteHandler))
	// m.Post("/services/unbind", AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<commit_msg>api/webserver: registered UnbindHandler for DELETE requests<commit_after>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/ec2"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()
	_, err = ec2.Conn()
	if err != nil {
		log.Print("Got error while connecting with ec2:")
		log.Print(err.Error())
	}

	repository.RunAgent()
	m := pat.New()

	m.Post("/services/instances", AuthorizationRequiredHandler(service.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(service.BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(service.UnbindHandler))

	m.Post("/services", AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", AuthorizationRequiredHandler(service.ServicesHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(service.DeleteHandler))
	// m.Post("/services/unbind", AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"

	// https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/examples/storage/appengine/app.go
	"cloud.google.com/go/storage"
	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
)

// var out *logging.Logger

func init() {
	http.HandleFunc("/_ah/warmup", warmupHandler)
	http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	log.Infof(ctx, "Unders Request: %s", r.RequestURI)
	fmt.Fprint(w, "Hello, world 10! (Standard Environment)")

	client, err := storage.NewClient(ctx)
	if err != nil {
		log.Errorf(ctx, "failed to create client: %v", err)
		return
	}

	if err := client.Close(); err != nil {
		log.Errorf(ctx, "failed to create client: %v", err)
		return
	}

}

func warmupHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	// Perform warmup tasks, including ones that require a context,
	// such as retrieving data from Datastore.

	log.Infof(ctx, "Warmup: %s", r.RequestURI)
}
<commit_msg>bump to 11.<commit_after>package main

import (
	"fmt"
	"net/http"

	// https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/examples/storage/appengine/app.go
	"cloud.google.com/go/storage"
	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
)

// var out *logging.Logger

func init() {
	http.HandleFunc("/_ah/warmup", warmupHandler)
	http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	log.Infof(ctx, "Unders Request: %s", r.RequestURI)
	fmt.Fprint(w, "Hello, world 11! (Standard Environment)")

	client, err := storage.NewClient(ctx)
	if err != nil {
		log.Errorf(ctx, "failed to create client: %v", err)
		return
	}

	if err := client.Close(); err != nil {
		log.Errorf(ctx, "failed to create client: %v", err)
		return
	}

}

func warmupHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	// Perform warmup tasks, including ones that require a context,
	// such as retrieving data from Datastore.

	log.Infof(ctx, "Warmup: %s", r.RequestURI)
}
<|endoftext|>