<commit_before>package channeldb

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"time"

	"github.com/boltdb/bolt"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/wire"
)

var (
	// nodeInfoBucket stores meta-data pertaining to nodes that we've had
	// direct channel-based correspondence with. This bucket allows one to
	// query for all open channels pertaining to the node by exploring each
	// node's sub-bucket within the openChanBucket.
	nodeInfoBucket = []byte("nib")
)

// LinkNode stores meta-data related to node's that we have/had a direct
// channel open with. Information such as the Bitcoin network the node
// advertised, and its identity public key are also stored. Additionally, this
// struct and the bucket its stored within have store data similar to that of
// Bitcion's addrmanager. The TCP address information stored within the struct
// can be used to establish persistent connections will all channel
// counter-parties on daemon startup.
//
// TODO(roasbeef): also add current OnionKey plus rotation schedule?
// TODO(roasbeef): add bitfield for supported services
//  * possibly add a wire.NetAddress type, type
type LinkNode struct {
	// Network indicates the Bitcoin network that the LinkNode advertises
	// for incoming channel creation.
	Network wire.BitcoinNet

	// IdentityPub is the node's current identity public key. Any
	// channel/topology related information received by this node MUST be
	// signed by this public key.
	IdentityPub *btcec.PublicKey

	// LastSeen tracks the last time this node was seen within the network.
	// A node should be marked as seen if the daemon either is able to
	// establish an outgoing connection to the node or receives a new
	// incoming connection from the node. This timestamp (stored in unix
	// epoch) may be used within a heuristic which aims to determine when a
	// channel should be unilaterally closed due to inactivity.
	//
	// TODO(roasbeef): replace with block hash/height?
	LastSeen time.Time

	// Addresses is a list of IP address in which either we were able to
	// reach the node over in the past, OR we received an incoming
	// authenticated connection for the stored identity public key.
	//
	// TODO(roasbeef): also need to support hidden service addrs
	Addresses []*net.TCPAddr

	db *DB
}

// NewLinkNode creates a new LinkNode from the provided parameters, which is
// backed by an instance of channeldb.
func (db *DB) NewLinkNode(bitNet wire.BitcoinNet, pub *btcec.PublicKey,
	addr *net.TCPAddr) *LinkNode {

	return &LinkNode{
		Network:     bitNet,
		IdentityPub: pub,
		LastSeen:    time.Now(),
		Addresses:   []*net.TCPAddr{addr},
		db:          db,
	}
}

// UpdateLastSeen updates the last time this node was directly encountered on
// the Lightning Network.
func (l *LinkNode) UpdateLastSeen(lastSeen time.Time) error {
	l.LastSeen = lastSeen

	return l.Sync()
}

// AddAddress appends the specified TCP address to the list of known addresses
// this node is/was known to be reachable at.
func (l *LinkNode) AddAddress(addr *net.TCPAddr) error {
	for _, a := range l.Addresses {
		if a.String() == addr.String() {
			return nil
		}
	}

	l.Addresses = append(l.Addresses, addr)

	return l.Sync()
}

// Sync performs a full database sync which writes the current up-to-date data
// within the struct to the database.
func (l *LinkNode) Sync() error {
	// First serialize the LinkNode into its raw-bytes encoding. This is
	// done outside of the transaction in order to minimize the length of
	// the DB transaction.
	var b bytes.Buffer
	if err := serializeLinkNode(&b, l); err != nil {
		return err
	}

	nodePub := l.IdentityPub.SerializeCompressed()

	// Finally update the database by storing the link node and updating
	// any relevant indexes.
	return l.db.store.Update(func(tx *bolt.Tx) error {
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		return nodeMetaBucket.Put(nodePub, b.Bytes())
	})
}

// FetchLinkNode attempts to lookup the data for a LinkNode based on a target
// identity public key. If a particular LinkNode for the passed identity public
// key cannot be found, then ErrNodeNotFound if returned.
func (db *DB) FetchLinkNode(identity *btcec.PublicKey) (*LinkNode, error) {
	var (
		node *LinkNode
		err  error
	)

	err = db.store.View(func(tx *bolt.Tx) error {
		// First fetch the bucket for storing node meta-data, bailing
		// out early if it hasn't been created yet.
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		// If a link node for that particular public key cannot be
		// located, then exit early with a ErrNodeNotFound.
		pubKey := identity.SerializeCompressed()
		nodeBytes := nodeMetaBucket.Get(pubKey)
		if nodeBytes == nil {
			return ErrNodeNotFound
		}

		// Finally, decode an allocate a fresh LinkNode object to be
		// returned to the caller.
		nodeReader := bytes.NewReader(nodeBytes)
		node, err = deserializeLinkNode(nodeReader)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return node, nil
}

// FetchAllLinkNodes attempts to fetch all active LinkNodes from the database.
func (db *DB) FetchAllLinkNodes() ([]*LinkNode, error) {
	var linkNodes []*LinkNode

	err := db.store.View(func(tx *bolt.Tx) error {
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		return nodeMetaBucket.ForEach(func(k, v []byte) error {
			nodeReader := bytes.NewReader(v)
			linkNode, err := deserializeLinkNode(nodeReader)
			if err != nil {
				return err
			}

			linkNodes = append(linkNodes, linkNode)
			return nil
		})

		return nil
	})
	if err != nil {
		return nil, err
	}

	return linkNodes, nil
}

func serializeLinkNode(w io.Writer, l *LinkNode) error {
	var buf [8]byte

	byteOrder.PutUint32(buf[:4], uint32(l.Network))
	if _, err := w.Write(buf[:4]); err != nil {
		return err
	}

	serializedID := l.IdentityPub.SerializeCompressed()
	if _, err := w.Write(serializedID); err != nil {
		return err
	}

	seenUnix := uint64(l.LastSeen.Unix())
	byteOrder.PutUint64(buf[:], seenUnix)
	if _, err := w.Write(buf[:]); err != nil {
		return err
	}

	numAddrs := uint32(len(l.Addresses))
	byteOrder.PutUint32(buf[:4], numAddrs)
	if _, err := w.Write(buf[:4]); err != nil {
		return err
	}

	for _, addr := range l.Addresses {
		addrString := addr.String()
		if err := wire.WriteVarString(w, 0, addrString); err != nil {
			return err
		}
	}

	return nil
}

func deserializeLinkNode(r io.Reader) (*LinkNode, error) {
	var (
		err error
		buf [8]byte
	)

	node := &LinkNode{}

	if _, err := io.ReadFull(r, buf[:4]); err != nil {
		return nil, err
	}
	node.Network = wire.BitcoinNet(byteOrder.Uint32(buf[:4]))

	var pub [33]byte
	if _, err := io.ReadFull(r, pub[:]); err != nil {
		return nil, err
	}
	node.IdentityPub, err = btcec.ParsePubKey(pub[:], btcec.S256())
	if err != nil {
		return nil, err
	}

	if _, err := io.ReadFull(r, buf[:]); err != nil {
		return nil, err
	}
	node.LastSeen = time.Unix(int64(byteOrder.Uint64(buf[:])), 0)

	if _, err := io.ReadFull(r, buf[:4]); err != nil {
		return nil, err
	}
	numAddrs := byteOrder.Uint32(buf[:4])

	node.Addresses = make([]*net.TCPAddr, numAddrs)
	for i := uint32(0); i < numAddrs; i++ {
		addrString, err := wire.ReadVarString(r, 0)
		if err != nil {
			return nil, err
		}

		addr, err := net.ResolveTCPAddr("tcp", addrString)
		if err != nil {
			return nil, err
		}
		node.Addresses[i] = addr
	}

	return node, nil
}
<commit_msg>channeldb: factor out LinkNode serialization+db write into new func<commit_after>package channeldb

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"time"

	"github.com/boltdb/bolt"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/wire"
)

var (
	// nodeInfoBucket stores meta-data pertaining to nodes that we've had
	// direct channel-based correspondence with. This bucket allows one to
	// query for all open channels pertaining to the node by exploring each
	// node's sub-bucket within the openChanBucket.
	nodeInfoBucket = []byte("nib")
)

// LinkNode stores meta-data related to node's that we have/had a direct
// channel open with. Information such as the Bitcoin network the node
// advertised, and its identity public key are also stored. Additionally, this
// struct and the bucket its stored within have store data similar to that of
// Bitcion's addrmanager. The TCP address information stored within the struct
// can be used to establish persistent connections will all channel
// counter-parties on daemon startup.
//
// TODO(roasbeef): also add current OnionKey plus rotation schedule?
// TODO(roasbeef): add bitfield for supported services
//  * possibly add a wire.NetAddress type, type
type LinkNode struct {
	// Network indicates the Bitcoin network that the LinkNode advertises
	// for incoming channel creation.
	Network wire.BitcoinNet

	// IdentityPub is the node's current identity public key. Any
	// channel/topology related information received by this node MUST be
	// signed by this public key.
	IdentityPub *btcec.PublicKey

	// LastSeen tracks the last time this node was seen within the network.
	// A node should be marked as seen if the daemon either is able to
	// establish an outgoing connection to the node or receives a new
	// incoming connection from the node. This timestamp (stored in unix
	// epoch) may be used within a heuristic which aims to determine when a
	// channel should be unilaterally closed due to inactivity.
	//
	// TODO(roasbeef): replace with block hash/height?
	LastSeen time.Time

	// Addresses is a list of IP address in which either we were able to
	// reach the node over in the past, OR we received an incoming
	// authenticated connection for the stored identity public key.
	//
	// TODO(roasbeef): also need to support hidden service addrs
	Addresses []*net.TCPAddr

	db *DB
}

// NewLinkNode creates a new LinkNode from the provided parameters, which is
// backed by an instance of channeldb.
func (db *DB) NewLinkNode(bitNet wire.BitcoinNet, pub *btcec.PublicKey,
	addr *net.TCPAddr) *LinkNode {

	return &LinkNode{
		Network:     bitNet,
		IdentityPub: pub,
		LastSeen:    time.Now(),
		Addresses:   []*net.TCPAddr{addr},
		db:          db,
	}
}

// UpdateLastSeen updates the last time this node was directly encountered on
// the Lightning Network.
func (l *LinkNode) UpdateLastSeen(lastSeen time.Time) error {
	l.LastSeen = lastSeen

	return l.Sync()
}

// AddAddress appends the specified TCP address to the list of known addresses
// this node is/was known to be reachable at.
func (l *LinkNode) AddAddress(addr *net.TCPAddr) error {
	for _, a := range l.Addresses {
		if a.String() == addr.String() {
			return nil
		}
	}

	l.Addresses = append(l.Addresses, addr)

	return l.Sync()
}

// Sync performs a full database sync which writes the current up-to-date data
// within the struct to the database.
func (l *LinkNode) Sync() error {

	// Finally update the database by storing the link node and updating
	// any relevant indexes.
	return l.db.store.Update(func(tx *bolt.Tx) error {
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		return putLinkNode(nodeMetaBucket, l)
	})
}

// putLinkNode serializes then writes the encoded version of the passed link
// node into the nodeMetaBucket. This function is provided in order to allow
// the ability to re-use a database transaction across many operations.
func putLinkNode(nodeMetaBucket *bolt.Bucket, l *LinkNode) error {
	// First serialize the LinkNode into its raw-bytes encoding.
	var b bytes.Buffer
	if err := serializeLinkNode(&b, l); err != nil {
		return err
	}

	// Finally insert the link-node into the node meta-data bucket keyed
	// according to the its pubkey serialized in compressed form.
	nodePub := l.IdentityPub.SerializeCompressed()
	return nodeMetaBucket.Put(nodePub, b.Bytes())
}

// FetchLinkNode attempts to lookup the data for a LinkNode based on a target
// identity public key. If a particular LinkNode for the passed identity public
// key cannot be found, then ErrNodeNotFound if returned.
func (db *DB) FetchLinkNode(identity *btcec.PublicKey) (*LinkNode, error) {
	var (
		node *LinkNode
		err  error
	)

	err = db.store.View(func(tx *bolt.Tx) error {
		// First fetch the bucket for storing node meta-data, bailing
		// out early if it hasn't been created yet.
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		// If a link node for that particular public key cannot be
		// located, then exit early with a ErrNodeNotFound.
		pubKey := identity.SerializeCompressed()
		nodeBytes := nodeMetaBucket.Get(pubKey)
		if nodeBytes == nil {
			return ErrNodeNotFound
		}

		// Finally, decode an allocate a fresh LinkNode object to be
		// returned to the caller.
		nodeReader := bytes.NewReader(nodeBytes)
		node, err = deserializeLinkNode(nodeReader)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return node, nil
}

// FetchAllLinkNodes attempts to fetch all active LinkNodes from the database.
// If there haven't been any channels explicitly linked to LinkNodes written to
// the database, then this function will return an empty slice.
func (db *DB) FetchAllLinkNodes() ([]*LinkNode, error) {
	var linkNodes []*LinkNode

	err := db.store.View(func(tx *bolt.Tx) error {
		nodeMetaBucket := tx.Bucket(nodeInfoBucket)
		if nodeInfoBucket == nil {
			return fmt.Errorf("node bucket not created")
		}

		return nodeMetaBucket.ForEach(func(k, v []byte) error {
			nodeReader := bytes.NewReader(v)
			linkNode, err := deserializeLinkNode(nodeReader)
			if err != nil {
				return err
			}

			linkNodes = append(linkNodes, linkNode)
			return nil
		})

		return nil
	})
	if err != nil {
		return nil, err
	}

	return linkNodes, nil
}

func serializeLinkNode(w io.Writer, l *LinkNode) error {
	var buf [8]byte

	byteOrder.PutUint32(buf[:4], uint32(l.Network))
	if _, err := w.Write(buf[:4]); err != nil {
		return err
	}

	serializedID := l.IdentityPub.SerializeCompressed()
	if _, err := w.Write(serializedID); err != nil {
		return err
	}

	seenUnix := uint64(l.LastSeen.Unix())
	byteOrder.PutUint64(buf[:], seenUnix)
	if _, err := w.Write(buf[:]); err != nil {
		return err
	}

	numAddrs := uint32(len(l.Addresses))
	byteOrder.PutUint32(buf[:4], numAddrs)
	if _, err := w.Write(buf[:4]); err != nil {
		return err
	}

	for _, addr := range l.Addresses {
		addrString := addr.String()
		if err := wire.WriteVarString(w, 0, addrString); err != nil {
			return err
		}
	}

	return nil
}

func deserializeLinkNode(r io.Reader) (*LinkNode, error) {
	var (
		err error
		buf [8]byte
	)

	node := &LinkNode{}

	if _, err := io.ReadFull(r, buf[:4]); err != nil {
		return nil, err
	}
	node.Network = wire.BitcoinNet(byteOrder.Uint32(buf[:4]))

	var pub [33]byte
	if _, err := io.ReadFull(r, pub[:]); err != nil {
		return nil, err
	}
	node.IdentityPub, err = btcec.ParsePubKey(pub[:], btcec.S256())
	if err != nil {
		return nil, err
	}

	if _, err := io.ReadFull(r, buf[:]); err != nil {
		return nil, err
	}
	node.LastSeen = time.Unix(int64(byteOrder.Uint64(buf[:])), 0)

	if _, err := io.ReadFull(r, buf[:4]); err != nil {
		return nil, err
	}
	numAddrs := byteOrder.Uint32(buf[:4])

	node.Addresses = make([]*net.TCPAddr, numAddrs)
	for i := uint32(0); i < numAddrs; i++ {
		addrString, err := wire.ReadVarString(r, 0)
		if err != nil {
			return nil, err
		}

		addr, err := net.ResolveTCPAddr("tcp", addrString)
		if err != nil {
			return nil, err
		}
		node.Addresses[i] = addr
	}

	return node, nil
}
<|endoftext|>


<commit_before>package manifest

import (
	"bufio"
	"fmt"
	"io"
	"regexp"
	"strings"

	"github.com/docker-library/go-dockerlibrary/pkg/stripper"

	"pault.ag/go/debian/control"
)

type Manifest2822 struct {
	Global  Manifest2822Entry
	Entries []Manifest2822Entry
}

type Manifest2822Entry struct {
	control.Paragraph

	Maintainers []string `delim:"," strip:"\n\r\t "`
	Tags        []string `delim:"," strip:"\n\r\t "`
	GitRepo     string
	GitFetch    string
	GitCommit   string
	Directory   string
	Constraints []string `delim:"," strip:"\n\r\t "`
}

var DefaultManifestEntry = Manifest2822Entry{
	GitFetch:  "refs/heads/master",
	Directory: ".",
}

func (entry Manifest2822Entry) Clone() Manifest2822Entry {
	// SLICES! grr
	entry.Maintainers = append([]string{}, entry.Maintainers...)
	entry.Tags = append([]string{}, entry.Tags...)
	entry.Constraints = append([]string{}, entry.Constraints...)
	return entry
}

const StringSeparator2822 = ", "

func (entry Manifest2822Entry) MaintainersString() string {
	return strings.Join(entry.Maintainers, StringSeparator2822)
}

func (entry Manifest2822Entry) TagsString() string {
	return strings.Join(entry.Tags, StringSeparator2822)
}

func (entry Manifest2822Entry) ConstraintsString() string {
	return strings.Join(entry.Constraints, StringSeparator2822)
}

// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
func (a Manifest2822Entry) SameBuildArtifacts(b Manifest2822Entry) bool {
	return a.GitRepo == b.GitRepo && a.GitFetch == b.GitFetch && a.GitCommit == b.GitCommit && a.Directory == b.Directory && a.ConstraintsString() == b.ConstraintsString()
}

// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifest2822Entry {
	if entry.MaintainersString() == defaults.MaintainersString() {
		entry.Maintainers = nil
	}
	if entry.TagsString() == defaults.TagsString() {
		entry.Tags = nil
	}
	if entry.GitRepo == defaults.GitRepo {
		entry.GitRepo = ""
	}
	if entry.GitFetch == defaults.GitFetch {
		entry.GitFetch = ""
	}
	if entry.GitCommit == defaults.GitCommit {
		entry.GitCommit = ""
	}
	if entry.Directory == defaults.Directory {
		entry.Directory = ""
	}
	if entry.ConstraintsString() == defaults.ConstraintsString() {
		entry.Constraints = nil
	}
	return entry
}

func (entry Manifest2822Entry) String() string {
	ret := []string{}
	if str := entry.MaintainersString(); str != "" {
		ret = append(ret, "Maintainers: "+str)
	}
	if str := entry.TagsString(); str != "" {
		ret = append(ret, "Tags: "+str)
	}
	if str := entry.GitRepo; str != "" {
		ret = append(ret, "GitRepo: "+str)
	}
	if str := entry.GitFetch; str != "" {
		ret = append(ret, "GitFetch: "+str)
	}
	if str := entry.GitCommit; str != "" {
		ret = append(ret, "GitCommit: "+str)
	}
	if str := entry.Directory; str != "" {
		ret = append(ret, "Directory: "+str)
	}
	if str := entry.ConstraintsString(); str != "" {
		ret = append(ret, "Constraints: "+str)
	}
	return strings.Join(ret, "\n")
}

func (manifest Manifest2822) String() string {
	entries := []Manifest2822Entry{manifest.Global.ClearDefaults(DefaultManifestEntry)}
	entries = append(entries, manifest.Entries...)

	ret := []string{}
	for i, entry := range entries {
		if i > 0 {
			entry = entry.ClearDefaults(manifest.Global)
		}
		ret = append(ret, entry.String())
	}

	return strings.Join(ret, "\n\n")
}

func (manifest Manifest2822) GetTag(tag string) *Manifest2822Entry {
	for _, entry := range manifest.Entries {
		for _, existingTag := range entry.Tags {
			if tag == existingTag {
				return &entry
			}
		}
	}
	return nil
}

func (manifest *Manifest2822) AddEntry(entry Manifest2822Entry) error {
	for _, tag := range entry.Tags {
		if manifest.GetTag(tag) != nil {
			return fmt.Errorf("Tags %q includes duplicate tag: %s", entry.TagsString(), tag)
		}
	}

	for i, existingEntry := range manifest.Entries {
		if existingEntry.SameBuildArtifacts(entry) {
			manifest.Entries[i].Tags = append(existingEntry.Tags, entry.Tags...)
			return nil
		}
	}

	manifest.Entries = append(manifest.Entries, entry)

	return nil
}

const (
	MaintainersNameRegex   = `[^\s<>()][^<>()]*`
	MaintainersEmailRegex  = `[^\s<>()]+`
	MaintainersGitHubRegex = `[^\s<>()]+`

	MaintainersFormat = `Full Name <contact-email-or-url> (@github-handle) OR Full Name (@github-handle)`
)

var (
	MaintainersRegex = regexp.MustCompile(`^(` + MaintainersNameRegex + `)(?:\s+<(` + MaintainersEmailRegex + `)>)?\s+[(]@(` + MaintainersGitHubRegex + `)[)]$`)
)

func (entry Manifest2822Entry) InvalidMaintainers() []string {
	invalid := []string{}
	for _, maintainer := range entry.Maintainers {
		if !MaintainersRegex.MatchString(maintainer) {
			invalid = append(invalid, maintainer)
		}
	}
	return invalid
}

type decoderWrapper struct {
	*control.Decoder
}

func (decoder *decoderWrapper) Decode(entry *Manifest2822Entry) error {
	for {
		err := decoder.Decoder.Decode(entry)
		if err != nil {
			return err
		}
		// ignore empty paragraphs (blank lines at the start, excess blank lines between paragraphs, excess blank lines at EOF)
		if len(entry.Paragraph.Order) > 0 {
			return nil
		}
	}
}

func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
	reader := stripper.NewCommentStripper(readerIn)

	realDecoder, err := control.NewDecoder(bufio.NewReader(reader), nil)
	if err != nil {
		return nil, err
	}
	decoder := decoderWrapper{realDecoder}

	manifest := Manifest2822{
		Global: DefaultManifestEntry.Clone(),
	}

	if err := decoder.Decode(&manifest.Global); err != nil {
		return nil, err
	}
	if len(manifest.Global.Maintainers) < 1 {
		return nil, fmt.Errorf("missing Maintainers")
	}
	if invalidMaintainers := manifest.Global.InvalidMaintainers(); len(invalidMaintainers) > 0 {
		return nil, fmt.Errorf("invalid Maintainers: %q (expected format %q)", strings.Join(invalidMaintainers, ", "), MaintainersFormat)
	}
	if len(manifest.Global.Tags) > 0 {
		return nil, fmt.Errorf("global Tags not permitted")
	}

	for {
		entry := manifest.Global.Clone()

		err := decoder.Decode(&entry)
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}

		if len(entry.Tags) < 1 {
			return nil, fmt.Errorf("missing Tags")
		}
		if entry.GitRepo == "" || entry.GitFetch == "" || entry.GitCommit == "" {
			return nil, fmt.Errorf("Tags %q missing one of GitRepo, GitFetch, or GitCommit", entry.TagsString())
		}

		err = manifest.AddEntry(entry)
		if err != nil {
			return nil, err
		}
	}

	return &manifest, nil
}
<commit_msg>Add simple "HasTag" function for a Manifest2822Entry<commit_after>package manifest

import (
	"bufio"
	"fmt"
	"io"
	"regexp"
	"strings"

	"github.com/docker-library/go-dockerlibrary/pkg/stripper"

	"pault.ag/go/debian/control"
)

type Manifest2822 struct {
	Global  Manifest2822Entry
	Entries []Manifest2822Entry
}

type Manifest2822Entry struct {
	control.Paragraph

	Maintainers []string `delim:"," strip:"\n\r\t "`
	Tags        []string `delim:"," strip:"\n\r\t "`
	GitRepo     string
	GitFetch    string
	GitCommit   string
	Directory   string
	Constraints []string `delim:"," strip:"\n\r\t "`
}

var DefaultManifestEntry = Manifest2822Entry{
	GitFetch:  "refs/heads/master",
	Directory: ".",
}

func (entry Manifest2822Entry) Clone() Manifest2822Entry {
	// SLICES! grr
	entry.Maintainers = append([]string{}, entry.Maintainers...)
	entry.Tags = append([]string{}, entry.Tags...)
	entry.Constraints = append([]string{}, entry.Constraints...)
	return entry
}

const StringSeparator2822 = ", "

func (entry Manifest2822Entry) MaintainersString() string {
	return strings.Join(entry.Maintainers, StringSeparator2822)
}

func (entry Manifest2822Entry) TagsString() string {
	return strings.Join(entry.Tags, StringSeparator2822)
}

func (entry Manifest2822Entry) ConstraintsString() string {
	return strings.Join(entry.Constraints, StringSeparator2822)
}

// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
func (a Manifest2822Entry) SameBuildArtifacts(b Manifest2822Entry) bool {
	return a.GitRepo == b.GitRepo && a.GitFetch == b.GitFetch && a.GitCommit == b.GitCommit && a.Directory == b.Directory && a.ConstraintsString() == b.ConstraintsString()
}

// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifest2822Entry {
	if entry.MaintainersString() == defaults.MaintainersString() {
		entry.Maintainers = nil
	}
	if entry.TagsString() == defaults.TagsString() {
		entry.Tags = nil
	}
	if entry.GitRepo == defaults.GitRepo {
		entry.GitRepo = ""
	}
	if entry.GitFetch == defaults.GitFetch {
		entry.GitFetch = ""
	}
	if entry.GitCommit == defaults.GitCommit {
		entry.GitCommit = ""
	}
	if entry.Directory == defaults.Directory {
		entry.Directory = ""
	}
	if entry.ConstraintsString() == defaults.ConstraintsString() {
		entry.Constraints = nil
	}
	return entry
}

func (entry Manifest2822Entry) String() string {
	ret := []string{}
	if str := entry.MaintainersString(); str != "" {
		ret = append(ret, "Maintainers: "+str)
	}
	if str := entry.TagsString(); str != "" {
		ret = append(ret, "Tags: "+str)
	}
	if str := entry.GitRepo; str != "" {
		ret = append(ret, "GitRepo: "+str)
	}
	if str := entry.GitFetch; str != "" {
		ret = append(ret, "GitFetch: "+str)
	}
	if str := entry.GitCommit; str != "" {
		ret = append(ret, "GitCommit: "+str)
	}
	if str := entry.Directory; str != "" {
		ret = append(ret, "Directory: "+str)
	}
	if str := entry.ConstraintsString(); str != "" {
		ret = append(ret, "Constraints: "+str)
	}
	return strings.Join(ret, "\n")
}

func (manifest Manifest2822) String() string {
	entries := []Manifest2822Entry{manifest.Global.ClearDefaults(DefaultManifestEntry)}
	entries = append(entries, manifest.Entries...)

	ret := []string{}
	for i, entry := range entries {
		if i > 0 {
			entry = entry.ClearDefaults(manifest.Global)
		}
		ret = append(ret, entry.String())
	}

	return strings.Join(ret, "\n\n")
}

func (entry Manifest2822Entry) HasTag(tag string) bool {
	for _, existingTag := range entry.Tags {
		if tag == existingTag {
			return true
		}
	}
	return false
}

func (manifest Manifest2822) GetTag(tag string) *Manifest2822Entry {
	for _, entry := range manifest.Entries {
		if entry.HasTag(tag) {
			return &entry
		}
	}
	return nil
}

func (manifest *Manifest2822) AddEntry(entry Manifest2822Entry) error {
	for _, tag := range entry.Tags {
		if manifest.GetTag(tag) != nil {
			return fmt.Errorf("Tags %q includes duplicate tag: %s", entry.TagsString(), tag)
		}
	}

	for i, existingEntry := range manifest.Entries {
		if existingEntry.SameBuildArtifacts(entry) {
			manifest.Entries[i].Tags = append(existingEntry.Tags, entry.Tags...)
			return nil
		}
	}

	manifest.Entries = append(manifest.Entries, entry)

	return nil
}

const (
	MaintainersNameRegex   = `[^\s<>()][^<>()]*`
	MaintainersEmailRegex  = `[^\s<>()]+`
	MaintainersGitHubRegex = `[^\s<>()]+`

	MaintainersFormat = `Full Name <contact-email-or-url> (@github-handle) OR Full Name (@github-handle)`
)

var (
	MaintainersRegex = regexp.MustCompile(`^(` + MaintainersNameRegex + `)(?:\s+<(` + MaintainersEmailRegex + `)>)?\s+[(]@(` + MaintainersGitHubRegex + `)[)]$`)
)

func (entry Manifest2822Entry) InvalidMaintainers() []string {
	invalid := []string{}
	for _, maintainer := range entry.Maintainers {
		if !MaintainersRegex.MatchString(maintainer) {
			invalid = append(invalid, maintainer)
		}
	}
	return invalid
}

type decoderWrapper struct {
	*control.Decoder
}

func (decoder *decoderWrapper) Decode(entry *Manifest2822Entry) error {
	for {
		err := decoder.Decoder.Decode(entry)
		if err != nil {
			return err
		}
		// ignore empty paragraphs (blank lines at the start, excess blank lines between paragraphs, excess blank lines at EOF)
		if len(entry.Paragraph.Order) > 0 {
			return nil
		}
	}
}

func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
	reader := stripper.NewCommentStripper(readerIn)

	realDecoder, err := control.NewDecoder(bufio.NewReader(reader), nil)
	if err != nil {
		return nil, err
	}
	decoder := decoderWrapper{realDecoder}

	manifest := Manifest2822{
		Global: DefaultManifestEntry.Clone(),
	}

	if err := decoder.Decode(&manifest.Global); err != nil {
		return nil, err
	}
	if len(manifest.Global.Maintainers) < 1 {
		return nil, fmt.Errorf("missing Maintainers")
	}
	if invalidMaintainers := manifest.Global.InvalidMaintainers(); len(invalidMaintainers) > 0 {
		return nil, fmt.Errorf("invalid Maintainers: %q (expected format %q)", strings.Join(invalidMaintainers, ", "), MaintainersFormat)
	}
	if len(manifest.Global.Tags) > 0 {
		return nil, fmt.Errorf("global Tags not permitted")
	}

	for {
		entry := manifest.Global.Clone()

		err := decoder.Decode(&entry)
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}

		if len(entry.Tags) < 1 {
			return nil, fmt.Errorf("missing Tags")
		}
		if entry.GitRepo == "" || entry.GitFetch == "" || entry.GitCommit == "" {
			return nil, fmt.Errorf("Tags %q missing one of GitRepo, GitFetch, or GitCommit", entry.TagsString())
		}

		err = manifest.AddEntry(entry)
		if err != nil {
			return nil, err
		}
	}

	return &manifest, nil
}
<|endoftext|>


<commit_before>// test before and after hooks

package hooks

import (
	"fmt"
	pb "github.com/tcncloud/protoc-gen-persist/examples/test"
)

var cache map[int64]*pb.ExampleTable

func init() {
	cache = make(map[int64]*pb.ExampleTable)
}

func UniaryInsertBeforeHook(req *pb.ExampleTable) (*pb.ExampleTable, error) {
	fmt.Printf("UniaryInsertBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryInsertAfterHook(req *pb.ExampleTable, res *pb.ExampleTable) error {
	fmt.Printf("UniaryInsertAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func UniaryUpdateBeforeHook(req *pb.ExampleTable) (*pb.PartialTable, error) {
	fmt.Printf("UniaryUpdateBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryUpdateAfterHook(req *pb.ExampleTable, res *pb.PartialTable) error {
	fmt.Printf("UniaryUpdateAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func UniaryDeleteBeforeHook(req *pb.ExampleTableRange) (*pb.ExampleTable, error) {
	fmt.Printf("UniaryDeleteBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryDeleteAfterHook(req *pb.ExampleTableRange, res *pb.ExampleTable) error {
	fmt.Printf("UniaryDeleteAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func ServerStreamBeforeHook(req *pb.Name) (*pb.ExampleTable, error) {
	fmt.Printf("ServerStreamBeforeHook: %+v\n", *req)
	return nil, nil
}

func ServerStreamAfterHook(req *pb.Name, res *pb.ExampleTable) error {
	fmt.Printf("ServerStreamAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func ClientStreamUpdateBeforeHook(req *pb.ExampleTable) (*pb.NumRows, error) {
	fmt.Printf("ClientStreamUpdateBeforeHook: %+v\n", *req)
	return nil, nil
}

func ClientStreamUpdateAfterHook(req *pb.ExampleTable, res *pb.NumRows) error {
	fmt.Printf("ClientStreamAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}
<commit_msg>update server stream before hook<commit_after>// test before and after hooks

package hooks

import (
	"fmt"
	pb "github.com/tcncloud/protoc-gen-persist/examples/test"
)

var cache map[int64]*pb.ExampleTable

func init() {
	cache = make(map[int64]*pb.ExampleTable)
}

func UniaryInsertBeforeHook(req *pb.ExampleTable) (*pb.ExampleTable, error) {
	fmt.Printf("UniaryInsertBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryInsertAfterHook(req *pb.ExampleTable, res *pb.ExampleTable) error {
	fmt.Printf("UniaryInsertAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func UniaryUpdateBeforeHook(req *pb.ExampleTable) (*pb.PartialTable, error) {
	fmt.Printf("UniaryUpdateBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryUpdateAfterHook(req *pb.ExampleTable, res *pb.PartialTable) error {
	fmt.Printf("UniaryUpdateAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func UniaryDeleteBeforeHook(req *pb.ExampleTableRange) (*pb.ExampleTable, error) {
	fmt.Printf("UniaryDeleteBeforeHook: %+v\n", *req)
	return nil, nil
}

func UniaryDeleteAfterHook(req *pb.ExampleTableRange, res *pb.ExampleTable) error {
	fmt.Printf("UniaryDeleteAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func ServerStreamBeforeHook(req *pb.Name) ([]*pb.ExampleTable, error) {
	fmt.Printf("ServerStreamBeforeHook: %+v\n", *req)
	return nil, nil
}

func ServerStreamAfterHook(req *pb.Name, res *pb.ExampleTable) error {
	fmt.Printf("ServerStreamAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}

func ClientStreamUpdateBeforeHook(req *pb.ExampleTable) (*pb.NumRows, error) {
	fmt.Printf("ClientStreamUpdateBeforeHook: %+v\n", *req)
	return nil, nil
}

func ClientStreamUpdateAfterHook(req *pb.ExampleTable, res *pb.NumRows) error {
	fmt.Printf("ClientStreamAfterHook req:%+v res:%+v\n", *req, *res)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/graphql-go/graphql"
	"github.com/graphql-go/graphql/language/ast"
	"log"
)

// NullString to be used in place of sql.NullString
type NullString struct {
	sql.NullString
}

// MarshalJSON from the json.Marshaler interface
func (v NullString) MarshalJSON() ([]byte, error) {
	if v.Valid {
		return json.Marshal(v.String)
	}
	return json.Marshal(nil)
}

// UnmarshalJSON from the json.Unmarshaler interface
func (v *NullString) UnmarshalJSON(data []byte) error {
	var x *string
	if err := json.Unmarshal(data, &x); err != nil {
		return err
	}
	if x != nil {
		v.String = *x
		v.Valid = true
	} else {
		v.Valid = false
	}
	return nil
}

// NewNullString create a new null string. Empty string evaluates to an
// "invalid" NullString
func NewNullString(value string) *NullString {
	var null NullString
	if value != "" {
		null.String = value
		null.Valid = true
		return &null
	}
	null.Valid = false
	return &null
}

// SerializeNullString serializes `NullString` to a string
func SerializeNullString(value interface{}) interface{} {
	switch value := value.(type) {
	case NullString:
		return value.String
	case *NullString:
		v := *value
		return v.String
	default:
		return nil
	}
}

// ParseNullString parses GraphQL variables from `string` to `CustomID`
func ParseNullString(value interface{}) interface{} {
	switch value := value.(type) {
	case string:
		return NewNullString(value)
	case *string:
		return NewNullString(*value)
	default:
		return nil
	}
}

// ParseLiteralNullString parses GraphQL AST value to `NullString`.
func ParseLiteralNullString(valueAST ast.Value) interface{} {
	switch valueAST := valueAST.(type) {
	case *ast.StringValue:
		return NewNullString(valueAST.Value)
	default:
		return nil
	}
}

// NullableString graphql *Scalar type based of NullString
var NullableString = graphql.NewScalar(graphql.ScalarConfig{
	Name:         "NullableString",
	Description:  "The `NullableString` type repesents a nullable SQL string.",
	Serialize:    SerializeNullString,
	ParseValue:   ParseNullString,
	ParseLiteral: ParseLiteralNullString,
})

/*
CREATE TABLE persons (
	favorite_dog TEXT -- is a nullable field
	);

*/

// Person noqa
type Person struct {
	Name        string      `json:"name"`
	FavoriteDog *NullString `json:"favorite_dog"` // Some people don't like dogs ¯\_(ツ)_/¯
}

// PersonType noqa
var PersonType = graphql.NewObject(graphql.ObjectConfig{
	Name: "Person",
	Fields: graphql.Fields{
		"name": &graphql.Field{
			Type: graphql.String,
		},
		"favorite_dog": &graphql.Field{
			Type: NullableString,
		},
	},
})

func main() {
	schema, err := graphql.NewSchema(graphql.SchemaConfig{
		Query: graphql.NewObject(graphql.ObjectConfig{
			Name: "Query",
			Fields: graphql.Fields{
				"people": &graphql.Field{
					Type: graphql.NewList(PersonType),
					Args: graphql.FieldConfigArgument{
						"favorite_dog": &graphql.ArgumentConfig{
							Type: NullableString,
						},
					},
					Resolve: func(p graphql.ResolveParams) (interface{}, error) {
						dog, dogOk := p.Args["favorite_dog"].(*NullString)
						people := []Person{
							Person{Name: "Alice", FavoriteDog: NewNullString("Yorkshire Terrier")},
							// `Bob`'s favorite dog will be saved as null in the database
							Person{Name: "Bob", FavoriteDog: NewNullString("")},
							Person{Name: "Chris", FavoriteDog: NewNullString("French Bulldog")},
						}
						switch {
						case dogOk:
							log.Printf("favorite_dog from arguments: %+v", dog)
							dogPeople := make([]Person, 0)
							for _, p := range people {
								if p.FavoriteDog.Valid {
									if p.FavoriteDog.String == dog.String {
										dogPeople = append(dogPeople, p)
									}
								}
							}
							return dogPeople, nil
						default:
							return people, nil
						}
					},
				},
			},
		}),
	})
	if err != nil {
		log.Fatal(err)
	}
	query := `
query {
  people {
    name
    favorite_dog
    }
}`
	queryWithArgument := `
query {
  people(favorite_dog: "Yorkshire Terrier") {
    name
    favorite_dog
  }
}`
	r1 := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: query,
	})
	r2 := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: queryWithArgument,
	})
	if len(r1.Errors) > 0 {
		log.Fatal(r1)
	}
	if len(r2.Errors) > 0 {
		log.Fatal(r1)
	}
	b1, err := json.MarshalIndent(r1, "", "  ")
	b2, err := json.MarshalIndent(r2, "", "  ")
	if err != nil {
		log.Fatal(err)

	}
	fmt.Printf("\nQuery: %+v\n", string(query))
	fmt.Printf("\nResult: %+v\n", string(b1))
	fmt.Printf("\nQuery (with arguments): %+v\n", string(queryWithArgument))
	fmt.Printf("\nResult (with arguments): %+v\n", string(b2))
}

/* Output:
Query:
query {
  people {
    name
    favorite_dog
    }
}

Result: {
  "data": {
    "people": [
      {
        "favorite_dog": "Yorkshire Terrier",
        "name": "Alice"
      },
      {
        "favorite_dog": "",
        "name": "Bob"
      },
      {
        "favorite_dog": "French Bulldog",
        "name": "Chris"
      }
    ]
  }
}

Query (with arguments):
query {
  people(favorite_dog: "Yorkshire Terrier") {
    name
    favorite_dog
  }
}

Result (with arguments): {
  "data": {
    "people": [
      {
        "favorite_dog": "Yorkshire Terrier",
        "name": "Alice"
      }
    ]
  }
}
*/
<commit_msg>examples/sql-nullstring: fix dropped error<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/graphql-go/graphql"
	"github.com/graphql-go/graphql/language/ast"
	"log"
)

// NullString to be used in place of sql.NullString
type NullString struct {
	sql.NullString
}

// MarshalJSON from the json.Marshaler interface
func (v NullString) MarshalJSON() ([]byte, error) {
	if v.Valid {
		return json.Marshal(v.String)
	}
	return json.Marshal(nil)
}

// UnmarshalJSON from the json.Unmarshaler interface
func (v *NullString) UnmarshalJSON(data []byte) error {
	var x *string
	if err := json.Unmarshal(data, &x); err != nil {
		return err
	}
	if x != nil {
		v.String = *x
		v.Valid = true
	} else {
		v.Valid = false
	}
	return nil
}

// NewNullString create a new null string. Empty string evaluates to an
// "invalid" NullString
func NewNullString(value string) *NullString {
	var null NullString
	if value != "" {
		null.String = value
		null.Valid = true
		return &null
	}
	null.Valid = false
	return &null
}

// SerializeNullString serializes `NullString` to a string
func SerializeNullString(value interface{}) interface{} {
	switch value := value.(type) {
	case NullString:
		return value.String
	case *NullString:
		v := *value
		return v.String
	default:
		return nil
	}
}

// ParseNullString parses GraphQL variables from `string` to `CustomID`
func ParseNullString(value interface{}) interface{} {
	switch value := value.(type) {
	case string:
		return NewNullString(value)
	case *string:
		return NewNullString(*value)
	default:
		return nil
	}
}

// ParseLiteralNullString parses GraphQL AST value to `NullString`.
func ParseLiteralNullString(valueAST ast.Value) interface{} {
	switch valueAST := valueAST.(type) {
	case *ast.StringValue:
		return NewNullString(valueAST.Value)
	default:
		return nil
	}
}

// NullableString graphql *Scalar type based of NullString
var NullableString = graphql.NewScalar(graphql.ScalarConfig{
	Name:         "NullableString",
	Description:  "The `NullableString` type repesents a nullable SQL string.",
	Serialize:    SerializeNullString,
	ParseValue:   ParseNullString,
	ParseLiteral: ParseLiteralNullString,
})

/*
CREATE TABLE persons (
	favorite_dog TEXT -- is a nullable field
	);

*/

// Person noqa
type Person struct {
	Name        string      `json:"name"`
	FavoriteDog *NullString `json:"favorite_dog"` // Some people don't like dogs ¯\_(ツ)_/¯
}

// PersonType noqa
var PersonType = graphql.NewObject(graphql.ObjectConfig{
	Name: "Person",
	Fields: graphql.Fields{
		"name": &graphql.Field{
			Type: graphql.String,
		},
		"favorite_dog": &graphql.Field{
			Type: NullableString,
		},
	},
})

func main() {
	schema, err := graphql.NewSchema(graphql.SchemaConfig{
		Query: graphql.NewObject(graphql.ObjectConfig{
			Name: "Query",
			Fields: graphql.Fields{
				"people": &graphql.Field{
					Type: graphql.NewList(PersonType),
					Args: graphql.FieldConfigArgument{
						"favorite_dog": &graphql.ArgumentConfig{
							Type: NullableString,
						},
					},
					Resolve: func(p graphql.ResolveParams) (interface{}, error) {
						dog, dogOk := p.Args["favorite_dog"].(*NullString)
						people := []Person{
							Person{Name: "Alice", FavoriteDog: NewNullString("Yorkshire Terrier")},
							// `Bob`'s favorite dog will be saved as null in the database
							Person{Name: "Bob", FavoriteDog: NewNullString("")},
							Person{Name: "Chris", FavoriteDog: NewNullString("French Bulldog")},
						}
						switch {
						case dogOk:
							log.Printf("favorite_dog from arguments: %+v", dog)
							dogPeople := make([]Person, 0)
							for _, p := range people {
								if p.FavoriteDog.Valid {
									if p.FavoriteDog.String == dog.String {
										dogPeople = append(dogPeople, p)
									}
								}
							}
							return dogPeople, nil
						default:
							return people, nil
						}
					},
				},
			},
		}),
	})
	if err != nil {
		log.Fatal(err)
	}
	query := `
query {
  people {
    name
    favorite_dog
    }
}`
	queryWithArgument := `
query {
  people(favorite_dog: "Yorkshire Terrier") {
    name
    favorite_dog
  }
}`
	r1 := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: query,
	})
	r2 := graphql.Do(graphql.Params{
		Schema:        schema,
		RequestString: queryWithArgument,
	})
	if len(r1.Errors) > 0 {
		log.Fatal(r1)
	}
	if len(r2.Errors) > 0 {
		log.Fatal(r1)
	}
	b1, err := json.MarshalIndent(r1, "", "  ")
	if err != nil {
		log.Fatal(err)
	}
	b2, err := json.MarshalIndent(r2, "", "  ")
	if err != nil {
		log.Fatal(err)

	}
	fmt.Printf("\nQuery: %+v\n", string(query))
	fmt.Printf("\nResult: %+v\n", string(b1))
	fmt.Printf("\nQuery (with arguments): %+v\n", string(queryWithArgument))
	fmt.Printf("\nResult (with arguments): %+v\n", string(b2))
}

/* Output:
Query:
query {
  people {
    name
    favorite_dog
    }
}

Result: {
  "data": {
    "people": [
      {
        "favorite_dog": "Yorkshire Terrier",
        "name": "Alice"
      },
      {
        "favorite_dog": "",
        "name": "Bob"
      },
      {
        "favorite_dog": "French Bulldog",
        "name": "Chris"
      }
    ]
  }
}

Query (with arguments):
query {
  people(favorite_dog: "Yorkshire Terrier") {
    name
    favorite_dog
  }
}

Result (with arguments): {
  "data": {
    "people": [
      {
        "favorite_dog": "Yorkshire Terrier",
        "name": "Alice"
      }
    ]
  }
}
*/
<|endoftext|>


<commit_before><commit_msg>Let the client know the server is up and running<commit_after><|endoftext|>


<commit_before>package irmago

import (
	"crypto/sha256"
	"encoding/base64"
	"encoding/xml"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"github.com/mhe/gabi"
)

// MetaStore is the global instance of ConfigurationStore
var MetaStore = newConfigurationStore()

// ConfigurationStore keeps track of scheme managers, issuers, credential types and public keys.
// Use the global MetaStore instance.
type ConfigurationStore struct {
	SchemeManagers map[SchemeManagerIdentifier]*SchemeManager
	Issuers        map[IssuerIdentifier]*Issuer
	Credentials    map[CredentialTypeIdentifier]*CredentialType
	PublicKeys     map[IssuerIdentifier][]*gabi.PublicKey

	reverseHashes map[string]CredentialTypeIdentifier
	initialized   bool
}

func newConfigurationStore() (store *ConfigurationStore) {
	store = &ConfigurationStore{
		SchemeManagers: make(map[SchemeManagerIdentifier]*SchemeManager),
		Issuers:        make(map[IssuerIdentifier]*Issuer),
		Credentials:    make(map[CredentialTypeIdentifier]*CredentialType),
		PublicKeys:     make(map[IssuerIdentifier][]*gabi.PublicKey),
		reverseHashes:  make(map[string]CredentialTypeIdentifier),
	}
	return
}

// PublicKey returns the specified public key, or nil if not present in the ConfigurationStore.
func (store *ConfigurationStore) PublicKey(id IssuerIdentifier, counter int) *gabi.PublicKey {
	if list, ok := MetaStore.PublicKeys[id]; ok {
		if len(list) > counter {
			return list[counter]
		}
	}
	return nil
}

func (store *ConfigurationStore) addReverseHash(credid CredentialTypeIdentifier) {
	hash := sha256.Sum256([]byte(credid.String()))
	store.reverseHashes[base64.StdEncoding.EncodeToString(hash[:16])] = credid
}

func (store *ConfigurationStore) hashToCredentialType(hash []byte) *CredentialType {
	if str, exists := store.reverseHashes[base64.StdEncoding.EncodeToString(hash)]; exists {
		return store.Credentials[str]
	}
	return nil
}

// IsInitialized indicates whether this instance has successfully been initialized.
func (store *ConfigurationStore) IsInitialized() bool {
	return store.initialized
}

// ParseFolder populates the current store by parsing the specified irma_configuration folder,
// listing the containing scheme managers, issuers, credential types and public keys.
func (store *ConfigurationStore) ParseFolder(path string) error {
	err := iterateSubfolders(path, func(dir string) error {
		manager := &SchemeManager{}
		exists, err := pathToDescription(dir+"/description.xml", manager)
		if err != nil {
			return err
		}
		if exists {
			MetaStore.SchemeManagers[manager.Identifier()] = manager
			return store.parseIssuerFolders(dir)
		}
		return nil
	})
	if err != nil {
		return err
	}
	store.initialized = true
	return nil
}

func (store *ConfigurationStore) parseIssuerFolders(path string) error {
	return iterateSubfolders(path, func(dir string) error {
		issuer := &Issuer{}
		exists, err := pathToDescription(dir+"/description.xml", issuer)
		if err != nil {
			return err
		}
		if exists {
			store.Issuers[issuer.Identifier()] = issuer
			if err = store.parseCredentialsFolder(dir + "/Issues/"); err != nil {
				return err
			}
			return store.parseKeysFolder(issuer, dir+"/PublicKeys/")
		}
		return nil
	})
}

func (store *ConfigurationStore) parseKeysFolder(issuer *Issuer, path string) error {
	for i := 0; ; i++ {
		file := path + strconv.Itoa(i) + ".xml"
		if _, err := os.Stat(file); err != nil {
			break
		}
		pk, err := gabi.NewPublicKeyFromFile(file)
		if err != nil {
			return err
		}
		pk.Issuer = issuer.Identifier().String()
		MetaStore.PublicKeys[issuer.Identifier()] = append(MetaStore.PublicKeys[issuer.Identifier()], pk)
	}
	return nil
}

func (store *ConfigurationStore) parseCredentialsFolder(path string) error {
	return iterateSubfolders(path, func(dir string) error {
		cred := &CredentialType{}
		exists, err := pathToDescription(dir+"/description.xml", cred)
		if err != nil {
			return err
		}
		if exists {
			credid := cred.Identifier()
			store.Credentials[credid] = cred
			store.addReverseHash(credid)
		}
		return nil
	})
}

// iterateSubfolders iterates over the subfolders of the specified path,
// calling the specified handler each time. If anything goes wrong, or
// if the caller returns a non-nil error, an error is immediately returned.
func iterateSubfolders(path string, handler func(string) error) error {
	dirs, err := filepath.Glob(path + "/*")
	if err != nil {
		return err
	}

	for _, dir := range dirs {
		stat, err := os.Stat(dir)
		if err != nil {
			return err
		}
		if !stat.IsDir() {
			continue
		}
		err = handler(dir)
		if err != nil {
			return err
		}
	}

	return nil
}

func pathToDescription(path string, description interface{}) (bool, error) {
	if _, err := os.Stat(path); err != nil {
		return false, nil
	}

	file, err := os.Open(path)
	if err != nil {
		return true, err
	}
	defer file.Close()

	bytes, err := ioutil.ReadAll(file)
	if err != nil {
		return true, err
	}

	err = xml.Unmarshal(bytes, description)
	if err != nil {
		return true, err
	}

	return true, nil
}

// Contains checks if the store contains the specified credential type.
func (store *ConfigurationStore) Contains(cred CredentialTypeIdentifier) bool {
	return store.SchemeManagers[cred.IssuerIdentifier().SchemeManagerIdentifier()] != nil &&
		store.Issuers[cred.IssuerIdentifier()] != nil &&
		store.Credentials[cred] != nil
}
<commit_msg>Small fix<commit_after>package irmago

import (
	"crypto/sha256"
	"encoding/base64"
	"encoding/xml"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"github.com/mhe/gabi"
)

// MetaStore is the global instance of ConfigurationStore
var MetaStore = newConfigurationStore()

// ConfigurationStore keeps track of scheme managers, issuers, credential types and public keys.
// Use the global MetaStore instance.
type ConfigurationStore struct {
	SchemeManagers map[SchemeManagerIdentifier]*SchemeManager
	Issuers        map[IssuerIdentifier]*Issuer
	Credentials    map[CredentialTypeIdentifier]*CredentialType
	PublicKeys     map[IssuerIdentifier][]*gabi.PublicKey

	reverseHashes map[string]CredentialTypeIdentifier
	initialized   bool
}

func newConfigurationStore() (store *ConfigurationStore) {
	store = &ConfigurationStore{
		SchemeManagers: make(map[SchemeManagerIdentifier]*SchemeManager),
		Issuers:        make(map[IssuerIdentifier]*Issuer),
		Credentials:    make(map[CredentialTypeIdentifier]*CredentialType),
		PublicKeys:     make(map[IssuerIdentifier][]*gabi.PublicKey),
		reverseHashes:  make(map[string]CredentialTypeIdentifier),
	}
	return
}

// PublicKey returns the specified public key, or nil if not present in the ConfigurationStore.
func (store *ConfigurationStore) PublicKey(id IssuerIdentifier, counter int) *gabi.PublicKey {
	if list, ok := store.PublicKeys[id]; ok {
		if len(list) > counter {
			return list[counter]
		}
	}
	return nil
}

func (store *ConfigurationStore) addReverseHash(credid CredentialTypeIdentifier) {
	hash := sha256.Sum256([]byte(credid.String()))
	store.reverseHashes[base64.StdEncoding.EncodeToString(hash[:16])] = credid
}

func (store *ConfigurationStore) hashToCredentialType(hash []byte) *CredentialType {
	if str, exists := store.reverseHashes[base64.StdEncoding.EncodeToString(hash)]; exists {
		return store.Credentials[str]
	}
	return nil
}

// IsInitialized indicates whether this instance has successfully been initialized.
func (store *ConfigurationStore) IsInitialized() bool {
	return store.initialized
}

// ParseFolder populates the current store by parsing the specified irma_configuration folder,
// listing the containing scheme managers, issuers, credential types and public keys.
func (store *ConfigurationStore) ParseFolder(path string) error {
	err := iterateSubfolders(path, func(dir string) error {
		manager := &SchemeManager{}
		exists, err := pathToDescription(dir+"/description.xml", manager)
		if err != nil {
			return err
		}
		if exists {
			store.SchemeManagers[manager.Identifier()] = manager
			return store.parseIssuerFolders(dir)
		}
		return nil
	})
	if err != nil {
		return err
	}
	store.initialized = true
	return nil
}

func (store *ConfigurationStore) parseIssuerFolders(path string) error {
	return iterateSubfolders(path, func(dir string) error {
		issuer := &Issuer{}
		exists, err := pathToDescription(dir+"/description.xml", issuer)
		if err != nil {
			return err
		}
		if exists {
			store.Issuers[issuer.Identifier()] = issuer
			if err = store.parseCredentialsFolder(dir + "/Issues/"); err != nil {
				return err
			}
			return store.parseKeysFolder(issuer, dir+"/PublicKeys/")
		}
		return nil
	})
}

func (store *ConfigurationStore) parseKeysFolder(issuer *Issuer, path string) error {
	for i := 0; ; i++ {
		file := path + strconv.Itoa(i) + ".xml"
		if _, err := os.Stat(file); err != nil {
			break
		}
		pk, err := gabi.NewPublicKeyFromFile(file)
		if err != nil {
			return err
		}
		pk.Issuer = issuer.Identifier().String()
		store.PublicKeys[issuer.Identifier()] = append(store.PublicKeys[issuer.Identifier()], pk)
	}
	return nil
}

func (store *ConfigurationStore) parseCredentialsFolder(path string) error {
	return iterateSubfolders(path, func(dir string) error {
		cred := &CredentialType{}
		exists, err := pathToDescription(dir+"/description.xml", cred)
		if err != nil {
			return err
		}
		if exists {
			credid := cred.Identifier()
			store.Credentials[credid] = cred
			store.addReverseHash(credid)
		}
		return nil
	})
}

// iterateSubfolders iterates over the subfolders of the specified path,
// calling the specified handler each time. If anything goes wrong, or
// if the caller returns a non-nil error, an error is immediately returned.
func iterateSubfolders(path string, handler func(string) error) error {
	dirs, err := filepath.Glob(path + "/*")
	if err != nil {
		return err
	}

	for _, dir := range dirs {
		stat, err := os.Stat(dir)
		if err != nil {
			return err
		}
		if !stat.IsDir() {
			continue
		}
		err = handler(dir)
		if err != nil {
			return err
		}
	}

	return nil
}

func pathToDescription(path string, description interface{}) (bool, error) {
	if _, err := os.Stat(path); err != nil {
		return false, nil
	}

	file, err := os.Open(path)
	if err != nil {
		return true, err
	}
	defer file.Close()

	bytes, err := ioutil.ReadAll(file)
	if err != nil {
		return true, err
	}

	err = xml.Unmarshal(bytes, description)
	if err != nil {
		return true, err
	}

	return true, nil
}

// Contains checks if the store contains the specified credential type.
func (store *ConfigurationStore) Contains(cred CredentialTypeIdentifier) bool {
	return store.SchemeManagers[cred.IssuerIdentifier().SchemeManagerIdentifier()] != nil &&
		store.Issuers[cred.IssuerIdentifier()] != nil &&
		store.Credentials[cred] != nil
}
<|endoftext|>


<commit_before>package xlsx

import "strconv"

// Style is a high level structure intended to provide user access to
// the contents of Style within an XLSX file.
type Style struct {
	Border          Border
	Fill            Fill
	Font            Font
	ApplyBorder     bool
	ApplyFill       bool
	ApplyFont       bool
	ApplyAlignment  bool
	Alignment       Alignment
	NamedStyleIndex *int
}

// Return a new Style structure initialised with the default values.
func NewStyle() *Style {
	return &Style{
		Alignment: *DefaultAlignment(),
		Border:    *DefaultBorder(),
		Fill:      *DefaultFill(),
		Font:      *DefaultFont(),
	}
}

// Generate the underlying XLSX style elements that correspond to the Style.
func (style *Style) makeXLSXStyleElements() (xFont xlsxFont, xFill xlsxFill, xBorder xlsxBorder, xCellXf xlsxXf) {
	xFont = xlsxFont{}
	xFill = xlsxFill{}
	xBorder = xlsxBorder{}
	xCellXf = xlsxXf{}
	xFont.Sz.Val = strconv.Itoa(style.Font.Size)
	xFont.Name.Val = style.Font.Name
	xFont.Family.Val = strconv.Itoa(style.Font.Family)
	xFont.Charset.Val = strconv.Itoa(style.Font.Charset)
	xFont.Color.RGB = style.Font.Color
	if style.Font.Bold {
		xFont.B = &xlsxVal{}
	} else {
		xFont.B = nil
	}
	if style.Font.Italic {
		xFont.I = &xlsxVal{}
	} else {
		xFont.I = nil
	}
	if style.Font.Underline {
		xFont.U = &xlsxVal{}
	} else {
		xFont.U = nil
	}
	xPatternFill := xlsxPatternFill{}
	xPatternFill.PatternType = style.Fill.PatternType
	xPatternFill.FgColor.RGB = style.Fill.FgColor
	xPatternFill.BgColor.RGB = style.Fill.BgColor
	xFill.PatternFill = xPatternFill
	xBorder.Left = xlsxLine{
		Style: style.Border.Left,
		Color: xlsxColor{RGB: style.Border.LeftColor},
	}
	xBorder.Right = xlsxLine{
		Style: style.Border.Right,
		Color: xlsxColor{RGB: style.Border.RightColor},
	}
	xBorder.Top = xlsxLine{
		Style: style.Border.Top,
		Color: xlsxColor{RGB: style.Border.TopColor},
	}
	xBorder.Bottom = xlsxLine{
		Style: style.Border.Bottom,
		Color: xlsxColor{RGB: style.Border.BottomColor},
	}
	xCellXf = makeXLSXCellElement()
	xCellXf.ApplyBorder = style.ApplyBorder
	xCellXf.ApplyFill = style.ApplyFill
	xCellXf.ApplyFont = style.ApplyFont
	xCellXf.ApplyAlignment = style.ApplyAlignment
	if style.NamedStyleIndex != nil {
		xCellXf.XfId = style.NamedStyleIndex
	}
	return
}

func makeXLSXCellElement() (xCellXf xlsxXf) {
	xCellXf.NumFmtId = 0
	return
}

// Border is a high level structure intended to provide user access to
// the contents of Border Style within an Sheet.
type Border struct {
	Left        string
	LeftColor   string
	Right       string
	RightColor  string
	Top         string
	TopColor    string
	Bottom      string
	BottomColor string
}

func NewBorder(left, right, top, bottom string) *Border {
	return &Border{
		Left:   left,
		Right:  right,
		Top:    top,
		Bottom: bottom,
	}
}

// Fill is a high level structure intended to provide user access to
// the contents of background and foreground color index within an Sheet.
type Fill struct {
	PatternType string
	BgColor     string
	FgColor     string
}

func NewFill(patternType, fgColor, bgColor string) *Fill {
	return &Fill{
		PatternType: patternType,
		FgColor:     fgColor,
		BgColor:     bgColor,
	}
}

type Font struct {
	Size      int
	Name      string
	Family    int
	Charset   int
	Color     string
	Bold      bool
	Italic    bool
	Underline bool
}

func NewFont(size int, name string) *Font {
	return &Font{Size: size, Name: name}
}

type Alignment struct {
	Horizontal   string
	Indent       int
	ShrinkToFit  bool
	TextRotation int
	Vertical     string
	WrapText     bool
}

var defaultFontSize = 12
var defaultFontName = "Verdana"

func SetDefaultFont(size int, name string) {
	defaultFontSize = size
	defaultFontName = name
}

func DefaultFont() *Font {
	return NewFont(defaultFontSize, defaultFontName)
}

func DefaultFill() *Fill {
	return NewFill("none", "FFFFFFFF", "00000000")

}

func DefaultBorder() *Border {
	return NewBorder("none", "none", "none", "none")
}

func DefaultAlignment() *Alignment {
	return &Alignment{
		Horizontal: "general",
		Vertical:   "bottom",
	}
}
<commit_msg>fix:unset col default style backgroud color  issue #432<commit_after>package xlsx

import "strconv"

// Style is a high level structure intended to provide user access to
// the contents of Style within an XLSX file.
type Style struct {
	Border          Border
	Fill            Fill
	Font            Font
	ApplyBorder     bool
	ApplyFill       bool
	ApplyFont       bool
	ApplyAlignment  bool
	Alignment       Alignment
	NamedStyleIndex *int
}

// Return a new Style structure initialised with the default values.
func NewStyle() *Style {
	return &Style{
		Alignment: *DefaultAlignment(),
		Border:    *DefaultBorder(),
		Fill:      *DefaultFill(),
		Font:      *DefaultFont(),
	}
}

// Generate the underlying XLSX style elements that correspond to the Style.
func (style *Style) makeXLSXStyleElements() (xFont xlsxFont, xFill xlsxFill, xBorder xlsxBorder, xCellXf xlsxXf) {
	xFont = xlsxFont{}
	xFill = xlsxFill{}
	xBorder = xlsxBorder{}
	xCellXf = xlsxXf{}
	xFont.Sz.Val = strconv.Itoa(style.Font.Size)
	xFont.Name.Val = style.Font.Name
	xFont.Family.Val = strconv.Itoa(style.Font.Family)
	xFont.Charset.Val = strconv.Itoa(style.Font.Charset)
	xFont.Color.RGB = style.Font.Color
	if style.Font.Bold {
		xFont.B = &xlsxVal{}
	} else {
		xFont.B = nil
	}
	if style.Font.Italic {
		xFont.I = &xlsxVal{}
	} else {
		xFont.I = nil
	}
	if style.Font.Underline {
		xFont.U = &xlsxVal{}
	} else {
		xFont.U = nil
	}
	xPatternFill := xlsxPatternFill{}
	xPatternFill.PatternType = style.Fill.PatternType
	xPatternFill.FgColor.RGB = style.Fill.FgColor
	xPatternFill.BgColor.RGB = style.Fill.BgColor
	xFill.PatternFill = xPatternFill
	xBorder.Left = xlsxLine{
		Style: style.Border.Left,
		Color: xlsxColor{RGB: style.Border.LeftColor},
	}
	xBorder.Right = xlsxLine{
		Style: style.Border.Right,
		Color: xlsxColor{RGB: style.Border.RightColor},
	}
	xBorder.Top = xlsxLine{
		Style: style.Border.Top,
		Color: xlsxColor{RGB: style.Border.TopColor},
	}
	xBorder.Bottom = xlsxLine{
		Style: style.Border.Bottom,
		Color: xlsxColor{RGB: style.Border.BottomColor},
	}
	xCellXf = makeXLSXCellElement()
	xCellXf.ApplyBorder = style.ApplyBorder
	xCellXf.ApplyFill = style.ApplyFill
	xCellXf.ApplyFont = style.ApplyFont
	xCellXf.ApplyAlignment = style.ApplyAlignment
	if style.NamedStyleIndex != nil {
		xCellXf.XfId = style.NamedStyleIndex
	}
	return
}

func makeXLSXCellElement() (xCellXf xlsxXf) {
	xCellXf.NumFmtId = 0
	return
}

// Border is a high level structure intended to provide user access to
// the contents of Border Style within an Sheet.
type Border struct {
	Left        string
	LeftColor   string
	Right       string
	RightColor  string
	Top         string
	TopColor    string
	Bottom      string
	BottomColor string
}

func NewBorder(left, right, top, bottom string) *Border {
	return &Border{
		Left:   left,
		Right:  right,
		Top:    top,
		Bottom: bottom,
	}
}

// Fill is a high level structure intended to provide user access to
// the contents of background and foreground color index within an Sheet.
type Fill struct {
	PatternType string
	BgColor     string
	FgColor     string
}

func NewFill(patternType, fgColor, bgColor string) *Fill {
	return &Fill{
		PatternType: patternType,
		FgColor:     fgColor,
		BgColor:     bgColor,
	}
}

type Font struct {
	Size      int
	Name      string
	Family    int
	Charset   int
	Color     string
	Bold      bool
	Italic    bool
	Underline bool
}

func NewFont(size int, name string) *Font {
	return &Font{Size: size, Name: name}
}

type Alignment struct {
	Horizontal   string
	Indent       int
	ShrinkToFit  bool
	TextRotation int
	Vertical     string
	WrapText     bool
}

var defaultFontSize = 12
var defaultFontName = "Verdana"

func SetDefaultFont(size int, name string) {
	defaultFontSize = size
	defaultFontName = name
}

func DefaultFont() *Font {
	return NewFont(defaultFontSize, defaultFontName)
}

func DefaultFill() *Fill {
	return NewFill("none", "", "")

}

func DefaultBorder() *Border {
	return NewBorder("none", "none", "none", "none")
}

func DefaultAlignment() *Alignment {
	return &Alignment{
		Horizontal: "general",
		Vertical:   "bottom",
	}
}
<|endoftext|>


<commit_before>package ethutil

import (
	"io/ioutil"
	"os"
	"os/user"
	"strings"
)

func ExpandHomePath(p string) (path string) {
	path = p

	// Check in case of paths like "/something/~/something/"
	if path[:2] == "~/" {
		usr, _ := user.Current()
		dir := usr.HomeDir

		path = strings.Replace(p, "~", dir, 1)
	}

	return
}

func FileExist(filePath string) bool {
	_, err := os.Stat(filePath)
	if err != nil && os.IsNotExist(err) {
		return false
	}

	return true
}

func ReadAllFile(filePath string) (string, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return "", err
	}

	data, err := ioutil.ReadAll(file)
	if err != nil {
		return "", err
	}

	return string(data), nil
}

func WriteFile(filePath string, content []byte) error {
	fh, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return err
	}
	defer fh.Close()

	_, err = fh.Write(content)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Truncate when writing<commit_after>package ethutil

import (
	"io/ioutil"
	"os"
	"os/user"
	"strings"
)

func ExpandHomePath(p string) (path string) {
	path = p

	// Check in case of paths like "/something/~/something/"
	if path[:2] == "~/" {
		usr, _ := user.Current()
		dir := usr.HomeDir

		path = strings.Replace(p, "~", dir, 1)
	}

	return
}

func FileExist(filePath string) bool {
	_, err := os.Stat(filePath)
	if err != nil && os.IsNotExist(err) {
		return false
	}

	return true
}

func ReadAllFile(filePath string) (string, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return "", err
	}

	data, err := ioutil.ReadAll(file)
	if err != nil {
		return "", err
	}

	return string(data), nil
}

func WriteFile(filePath string, content []byte) error {
	fh, err := os.OpenFile(filePath, os.O_TRUNC|os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return err
	}
	defer fh.Close()

	_, err = fh.Write(content)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package events

import (
	"github.com/Shopify/sarama"
	"github.com/ohsu-comp-bio/funnel/config"
)

// KafkaWriter writes events to a Kafka topic.
type KafkaWriter struct {
	conf     config.Kafka
	producer sarama.SyncProducer
}

// NewKafkaWriter creates a new event writer for writing events to a Kafka topic.
func NewKafkaWriter(conf config.Kafka) (*KafkaWriter, error) {
	producer, err := sarama.NewSyncProducer(conf.Servers, nil)
	if err != nil {
		return nil, err
	}
	return &KafkaWriter{conf, producer}, nil
}

// Close closes the Kafka producer, cleaning up resources.
func (k *KafkaWriter) Close() error {
	return k.producer.Close()
}

// Write writes the event. Events may be sent in batches in the background by the
// Kafka client library. Currently stdout, stderr, and system log events are dropped.
func (k *KafkaWriter) Write(ev *Event) error {

	switch ev.Type {
	case Type_EXECUTOR_STDOUT, Type_EXECUTOR_STDERR, Type_SYSTEM_LOG:
		return nil
	}

	s, err := Marshal(ev)
	if err != nil {
		return err
	}

	msg := &sarama.ProducerMessage{
		Topic: k.conf.Topic,
		Key:   nil,
		Value: sarama.StringEncoder(s),
	}
	_, _, err = k.producer.SendMessage(msg)
	return err
}

// KafkaReader reads events to a Kafka topic and writes them
// to a Writer.
type KafkaReader struct {
	conf config.Kafka
	con  sarama.Consumer
	pcon sarama.PartitionConsumer
}

// NewKafkaReader creates a new event reader for reading events from a Kafka topic and writing them to the given Writer.
func NewKafkaReader(conf config.Kafka, w Writer) (*KafkaReader, error) {
	con, err := sarama.NewConsumer(conf.Servers, nil)
	if err != nil {
		return nil, err
	}

	// TODO better handling of partition and offset.
	p, err := con.ConsumePartition(conf.Topic, 0, sarama.OffsetNewest)
	if err != nil {
		return nil, err
	}

	go func() {
		for msg := range p.Messages() {
			ev := &Event{}
			err := Unmarshal(msg.Value, ev)
			if err != nil {
				// TODO
				continue
			}
			w.Write(ev)
		}
	}()
	return &KafkaReader{conf, con, p}, nil
}

// Close closes the Kafka reader, cleaning up resources.
func (k *KafkaReader) Close() error {
	err := k.con.Close()
	perr := k.pcon.Close()
	if err != nil {
		return err
	}
	if perr != nil {
		return perr
	}
	return nil
}
<commit_msg>kafka: avoid nil panic on Close()<commit_after>package events

import (
	"github.com/Shopify/sarama"
	"github.com/ohsu-comp-bio/funnel/config"
)

// KafkaWriter writes events to a Kafka topic.
type KafkaWriter struct {
	conf     config.Kafka
	producer sarama.SyncProducer
}

// NewKafkaWriter creates a new event writer for writing events to a Kafka topic.
func NewKafkaWriter(conf config.Kafka) (*KafkaWriter, error) {
	producer, err := sarama.NewSyncProducer(conf.Servers, nil)
	if err != nil {
		return nil, err
	}
	return &KafkaWriter{conf, producer}, nil
}

// Close closes the Kafka producer, cleaning up resources.
func (k *KafkaWriter) Close() error {
	if k.producer != nil {
		return k.producer.Close()
	}
	return nil
}

// Write writes the event. Events may be sent in batches in the background by the
// Kafka client library. Currently stdout, stderr, and system log events are dropped.
func (k *KafkaWriter) Write(ev *Event) error {

	switch ev.Type {
	case Type_EXECUTOR_STDOUT, Type_EXECUTOR_STDERR, Type_SYSTEM_LOG:
		return nil
	}

	s, err := Marshal(ev)
	if err != nil {
		return err
	}

	msg := &sarama.ProducerMessage{
		Topic: k.conf.Topic,
		Key:   nil,
		Value: sarama.StringEncoder(s),
	}
	_, _, err = k.producer.SendMessage(msg)
	return err
}

// KafkaReader reads events to a Kafka topic and writes them
// to a Writer.
type KafkaReader struct {
	conf config.Kafka
	con  sarama.Consumer
	pcon sarama.PartitionConsumer
}

// NewKafkaReader creates a new event reader for reading events from a Kafka topic and writing them to the given Writer.
func NewKafkaReader(conf config.Kafka, w Writer) (*KafkaReader, error) {
	con, err := sarama.NewConsumer(conf.Servers, nil)
	if err != nil {
		return nil, err
	}

	// TODO better handling of partition and offset.
	p, err := con.ConsumePartition(conf.Topic, 0, sarama.OffsetNewest)
	if err != nil {
		return nil, err
	}

	go func() {
		for msg := range p.Messages() {
			ev := &Event{}
			err := Unmarshal(msg.Value, ev)
			if err != nil {
				// TODO
				continue
			}
			w.Write(ev)
		}
	}()
	return &KafkaReader{conf, con, p}, nil
}

// Close closes the Kafka reader, cleaning up resources.
func (k *KafkaReader) Close() error {
	var err, perr error
	if k.con != nil {
		err = k.con.Close()
	}
	if k.pcon != nil {
		perr = k.pcon.Close()
	}
	if err != nil {
		return err
	}
	if perr != nil {
		return perr
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import(
  "fmt"
  "io"
  "io/ioutil"
  "crypto/sha1"
  "os"
  "os/exec"
  "path/filepath"
  "bytes"
  "runtime"
  "strings"
  "github.com/kr/s3/s3util"
)

const VERSION = "0.1.1"

func fileExists(path string) bool {
  _, err := os.Stat(path)
  return err == nil
}

func open(s string) (io.ReadCloser, error) {
  if isURL(s) {
    return s3util.Open(s, nil)
  }
  return os.Open(s)
}

func create(s string) (io.WriteCloser, error) {
  if isURL(s) {
    return s3util.Create(s, nil, nil)
  }
  return os.Create(s)
}

func isURL(s string) bool {
  return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}

func s3url(filename string) string {
  format := "https://s3.amazonaws.com/%s/%s"
  url := fmt.Sprintf(format, os.Getenv("S3_BUCKET"), filename)

  return url
}

func sh(command string) (string, error) {
  var output bytes.Buffer

  cmd := exec.Command("bash", "-c", command)

  cmd.Stdout = &output
  cmd.Stderr = &output

  err := cmd.Run()
  return output.String(), err
}

func calculateChecksum(buffer string) string {
  h := sha1.New()
  io.WriteString(h, buffer)
  return fmt.Sprintf("%x", h.Sum(nil))
}

func transferArchive(file string, url string) {
  s3util.DefaultConfig.AccessKey = os.Getenv("S3_ACCESS_KEY")
  s3util.DefaultConfig.SecretKey = os.Getenv("S3_SECRET_KEY")

  r, err := open(file)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  w, err := create(url)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  _, err = io.Copy(w, r)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  err = w.Close()
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }
}

func extractArchive(filename string, path string) bool {
  cmd_mkdir   := fmt.Sprintf("cd %s && mkdir .bundle", path)
  cmd_move    := fmt.Sprintf("mv %s %s/.bundle/bundle_cache.tar.gz", filename, path)
  cmd_extract := fmt.Sprintf("cd %s/.bundle && tar -xzf ./bundle_cache.tar.gz", path)
  cmd_remove  := fmt.Sprintf("rm %s/.bundle/bundle_cache.tar.gz", path)

  if _, err := sh(cmd_mkdir) ; err != nil {
    fmt.Println("Bundle directory '.bundle' already exists")
    return false
  }

  if _, err := sh(cmd_move) ; err != nil {
    fmt.Println("Unable to move file")
    return false
  }

  if out, err := sh(cmd_extract) ; err != nil {
    fmt.Println("Unable to extract:", out)
    return false
  }

  if _, err := sh(cmd_remove) ; err != nil {
    fmt.Println("Unable to remove archive")
    return false
  }

  return true
}

func envDefined(name string) bool {
  result := os.Getenv(name)
  return len(result) > 0
}

func checkS3Credentials() {
  required := [3]string { "S3_ACCESS_KEY", "S3_SECRET_KEY", "S3_BUCKET" }

  for _, v := range required {
    if !envDefined(v) {
      fmt.Printf("Please define %s environment variable\n", v)
      os.Exit(2)
    }
  }
}

func printUsage() {
  fmt.Println("Usage: bundle_cache [download|upload]")
  os.Exit(2)
}

func upload(bundle_path string, archive_path string, archive_url string) {
  if !fileExists(bundle_path) {
    fmt.Println("Bundle path does not exist")
    os.Exit(1)
  }

  cmd := fmt.Sprintf("cd %s && tar -czf %s .", bundle_path, archive_path)

  fmt.Println("Archiving...")
  if out, err := sh(cmd); err != nil {
    fmt.Println("Failed to make archive:", out)
    os.Exit(1)
  }

  fmt.Println("Archived bundle at", archive_path)
  transferArchive(archive_path, archive_url)

  os.Exit(0)
}

func download(path string, bundle_path string, archive_path string, archive_url string) {
  if fileExists(bundle_path) {
    fmt.Println("Bundle path already exists")
    os.Exit(1)
  }

  fmt.Println("Downloading", archive_url)
  transferArchive(archive_url, archive_path)

  fmt.Println("Extracting...")
  extractArchive(archive_path, path)

  os.Exit(0)
}

func main() {
  args := os.Args[1:]

  if len(args) != 1 {
    printUsage()
  }

  action := args[0]

  checkS3Credentials()

  path, _       := os.Getwd()
  name          := filepath.Base(path)
  bundle_path   := fmt.Sprintf("%s/.bundle", path)
  lockfile_path := fmt.Sprintf("%s/Gemfile.lock", path)

  if !fileExists(lockfile_path) {
    fmt.Println("Gemfile.lock does not exist")
    os.Exit(1)
  }

  lockfile, err := ioutil.ReadFile(lockfile_path)
  if err != nil {
    fmt.Println("Unable to read Gemfile.lock")
    os.Exit(1)
  }

  checksum     := calculateChecksum(string(lockfile))
  archive_name := fmt.Sprintf("%s_%s_%s.tar.gz", name, checksum, runtime.GOARCH)
  archive_path := fmt.Sprintf("/tmp/%s", archive_name)
  archive_url  := s3url(archive_name)

  if fileExists(archive_path) {
    if os.Remove(archive_path) != nil {
      fmt.Println("Failed to remove existing archive")
      os.Exit(1)
    }
  }

  if action == "upload" || action == "up" {
    upload(bundle_path, archive_path, archive_url)
  }

  if action == "download" || action == "down" {
    download(path, bundle_path, archive_path, archive_url)
  }

  fmt.Println("Invalid command:", action)
  printUsage()
}
<commit_msg>Refactor errors<commit_after>package main

import(
  "fmt"
  "io"
  "io/ioutil"
  "crypto/sha1"
  "os"
  "os/exec"
  "path/filepath"
  "bytes"
  "runtime"
  "strings"
  "github.com/kr/s3/s3util"
)

const VERSION = "0.1.1"

const(
  ERR_WRONG_USAGE    = 2
  ERR_NO_CREDENTIALS = 3
  ERR_NO_BUNDLE      = 4
  ERR_BUNDLE_EXISTS  = 5
  ERR_NO_GEMLOCK     = 6
)

func terminate(message string, exit_code int) {
  fmt.Fprintln(os.Stderr, message)
  os.Exit(exit_code)
}

func fileExists(path string) bool {
  _, err := os.Stat(path)
  return err == nil
}

func open(s string) (io.ReadCloser, error) {
  if isURL(s) {
    return s3util.Open(s, nil)
  }
  return os.Open(s)
}

func create(s string) (io.WriteCloser, error) {
  if isURL(s) {
    return s3util.Create(s, nil, nil)
  }
  return os.Create(s)
}

func isURL(s string) bool {
  return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}

func s3url(filename string) string {
  format := "https://s3.amazonaws.com/%s/%s"
  url := fmt.Sprintf(format, os.Getenv("S3_BUCKET"), filename)

  return url
}

func sh(command string) (string, error) {
  var output bytes.Buffer

  cmd := exec.Command("bash", "-c", command)

  cmd.Stdout = &output
  cmd.Stderr = &output

  err := cmd.Run()
  return output.String(), err
}

func calculateChecksum(buffer string) string {
  h := sha1.New()
  io.WriteString(h, buffer)
  return fmt.Sprintf("%x", h.Sum(nil))
}

func transferArchive(file string, url string) {
  s3util.DefaultConfig.AccessKey = os.Getenv("S3_ACCESS_KEY")
  s3util.DefaultConfig.SecretKey = os.Getenv("S3_SECRET_KEY")

  r, err := open(file)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  w, err := create(url)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  _, err = io.Copy(w, r)
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }

  err = w.Close()
  if err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
  }
}

func extractArchive(filename string, path string) bool {
  cmd_mkdir   := fmt.Sprintf("cd %s && mkdir .bundle", path)
  cmd_move    := fmt.Sprintf("mv %s %s/.bundle/bundle_cache.tar.gz", filename, path)
  cmd_extract := fmt.Sprintf("cd %s/.bundle && tar -xzf ./bundle_cache.tar.gz", path)
  cmd_remove  := fmt.Sprintf("rm %s/.bundle/bundle_cache.tar.gz", path)

  if _, err := sh(cmd_mkdir) ; err != nil {
    fmt.Println("Bundle directory '.bundle' already exists")
    return false
  }

  if _, err := sh(cmd_move) ; err != nil {
    fmt.Println("Unable to move file")
    return false
  }

  if out, err := sh(cmd_extract) ; err != nil {
    fmt.Println("Unable to extract:", out)
    return false
  }

  if _, err := sh(cmd_remove) ; err != nil {
    fmt.Println("Unable to remove archive")
    return false
  }

  return true
}

func envDefined(name string) bool {
  result := os.Getenv(name)
  return len(result) > 0
}

func checkS3Credentials() {
  required := [3]string { "S3_ACCESS_KEY", "S3_SECRET_KEY", "S3_BUCKET" }

  for _, v := range required {
    if !envDefined(v) {
      message = fmt.Sprintf("Please define %s environment variable", v)
      terminate(message, ERR_NO_CREDENTIALS)
    }
  }
}

func printUsage() {
  terminate("Usage: bundle_cache [download|upload]", ERR_WRONG_USAGE)
}

func upload(bundle_path string, archive_path string, archive_url string) {
  if !fileExists(bundle_path) {
    terminate("Bundle path does not exist", ERR_NO_BUNDLE)
  }

  fmt.Println("Archiving...")
  cmd := fmt.Sprintf("cd %s && tar -czf %s .", bundle_path, archive_path)
  if out, err := sh(cmd); err != nil {
    terminate("Failed to make archive.", 1)
  }

  fmt.Println("Transferring...")
  transferArchive(archive_path, archive_url)

  os.Exit(0)
}

func download(path string, bundle_path string, archive_path string, archive_url string) {
  if fileExists(bundle_path) {
    terminate("Bundle path already exists", ERR_BUNDLE_EXISTS)
  }

  fmt.Println("Downloading...", archive_url)
  transferArchive(archive_url, archive_path)

  fmt.Println("Extracting...")
  extractArchive(archive_path, path)

  os.Exit(0)
}

func main() {
  args := os.Args[1:]

  if len(args) != 1 {
    printUsage()
  }

  action := args[0]

  checkS3Credentials()

  path, _       := os.Getwd()
  name          := filepath.Base(path)
  bundle_path   := fmt.Sprintf("%s/.bundle", path)
  lockfile_path := fmt.Sprintf("%s/Gemfile.lock", path)

  if !fileExists(lockfile_path) {
    terminate("Gemfile.lock does not exist", ERR_NO_GEMLOCK)
  }

  lockfile, err := ioutil.ReadFile(lockfile_path)
  if err != nil {
    terminate("Unable to read Gemfile.lock", 1)
  }

  checksum     := calculateChecksum(string(lockfile))
  archive_name := fmt.Sprintf("%s_%s_%s.tar.gz", name, checksum, runtime.GOARCH)
  archive_path := fmt.Sprintf("/tmp/%s", archive_name)
  archive_url  := s3url(archive_name)

  if fileExists(archive_path) {
    if os.Remove(archive_path) != nil {
      terminate("Failed to remove existing archive", 1)
    }
  }

  if action == "upload" || action == "up" {
    upload(bundle_path, archive_path, archive_url)
  }

  if action == "download" || action == "down" {
    download(path, bundle_path, archive_path, archive_url)
  }

  fmt.Println("Invalid command:", action)
  printUsage()
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	_ "net/http/pprof"

	"github.com/kavehmz/short"
)

func main() {
	site := short.Site{Host: "https://short.kaveh.me/"}
	http.HandleFunc("/", site.Redirect)
	http.HandleFunc("/post", site.Post)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
<commit_msg>addnig limit for number of serving clients<commit_after>package main

import (
	"log"
	"net/http"

	_ "net/http/pprof"

	"github.com/kavehmz/short"
)

func main() {
	site := short.Site{Host: "https://short.kaveh.me/"}
	http.HandleFunc("/", site.Redirect)
	http.HandleFunc("/post", site.Post)

	// If pool is full, connections will wait.
	// This is not a good pattern for high scale sites.
	// This only helps if http connection as a resource is cheaper
	// than underlying resources like db connetion,...
	maxServingClients := 2
	maxClientsPool := make(chan bool, maxServingClients)

	server := &http.Server{
		Addr:    ":8080"
		Handler: nil,
		ConnState: func(conn net.Conn, state http.ConnState) {
			switch state {
			case http.StateNew:
				maxClientsPool <- true
			case http.StateClosed, http.StateHijacked:
				<-maxClientsPool

			}
		},
	}
	log.Fatal(server.ListenAndServe())
}
<|endoftext|>


<commit_before>// Copyright 2017 The Grafeas 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 main

import (
	"github.com/grafeas/client-go"
	"log"
	"github.com/grafeas/grafeas/samples/server/go-server/api/server/name"
	"fmt"
)

func main() {
	client := swagger.NewGrafeasApi()
	nPID := "best-vuln-scanner"
	nID := "CVE-2014-9911"
	n := note(nPID, nID)
	createdN, _, err := client.CreateNote(nPID, nID, *n)
	if err != nil {
		log.Printf("Error creating note %v", err)
	} else {
		log.Printf("Succesfully created note: %v", createdN)
	}

	if got, _, err := client.GetNote(nPID, nID); err != nil {
		log.Printf("Error getting note %v", err)
	} else {
		log.Printf("Succesfully got note: %v", got)
	}

	oPID := "scanning-customer"
	o := Occurrence(createdN.Name)
	createdO, _, err := client.CreateOccurrence(oPID, *o)
	if err != nil {
		log.Printf("Error creating occurrence %v", err)
	} else {
		log.Printf("Succesfully created occurrence: %v", createdO)
	}

	 _, oID, pErr := name.ParseOccurrence(createdO.Name);
	 if pErr != nil {
		log.Fatalf("Unable to get occurenceId from occurrence name %v: %v", createdO.Name, err)
	}
	if got, _, err := client.GetOccurrence(oPID, oID); err != nil {
		log.Printf("Error getting occurrence %v", err)
	} else {
		log.Printf("Succesfully got occurrence: %v", got)
	}

}

func note(pID, nID string) *swagger.Note {
	return &swagger.Note{
		Name: fmt.Sprintf("projects/%v/notes/%v", pID, nID),
		ShortDescription: "CVE-2014-9911",
		LongDescription:  "NIST vectors: AV:N/AC:L/Au:N/C:P/I:P",
		Kind:             "PACKAGE_VULNERABILITY",
		VulnerabilityType: swagger.VulnerabilityType{
			CvssScore: 7.5,
			Severity:  "HIGH",
			Details: []swagger.Detail{
				{
					CpeUri:  "cpe:/o:debian:debian_linux:7",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:7",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "4.8.1.1",
							Revision: "12+deb7u6",
						},
					},
				},
				{
					CpeUri:  "cpe:/o:debian:debian_linux:8",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u4",
						},
					},
				},
				{
					CpeUri:  "cpe:/o:debian:debian_linux:9",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:9",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "55.1",
							Revision: "3",
						},
					},
				},
				{
					CpeUri:  "cpe:/o:canonical:ubuntu_linux:14.04",
					Package_: "andriod",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "MEDIUM",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:canonical:ubuntu_linux:14.04",
						Package_: "andriod",
						Version: swagger.Version{
							Kind: "MAXIMUM",
						},
					},
				},
			},
		},
		RelatedUrl: []swagger.RelatedUrl{
			{
				Url:   "https://security-tracker.debian.org/tracker/CVE-2014-9911",
				Label: "More Info",
			},
			{
				Url:   "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2014-9911",
				Label: "More Info",
			},
		},
	}
}

func Occurrence(noteName string) *swagger.Occurrence {
	return &swagger.Occurrence{
		ResourceUrl: "gcr.io/foo/bar",
		NoteName:    noteName,
		Kind:        "PACKAGE_VULNERABILITY",
		VulnerabilityDetails: swagger.VulnerabilityDetails{
			Severity:  "HIGH",
			CvssScore: 7.5,
			PackageIssue: []swagger.PackageIssue{
				swagger.PackageIssue{
					SeverityName: "HIGH",
					AffectedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u3",
						},
					},
					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u4",
						},
					},
				},
			},
		},
	}
}<commit_msg>Log fatal if creates fail<commit_after>// Copyright 2017 The Grafeas 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 main

import (
	"fmt"
	"github.com/grafeas/client-go"
	"github.com/grafeas/grafeas/samples/server/go-server/api/server/name"
	"log"
)

func main() {
	client := swagger.NewGrafeasApi()
	nPID := "best-vuln-scanner"
	nID := "CVE-2014-9911"
	n := note(nPID, nID)
	createdN, _, err := client.CreateNote(nPID, nID, *n)
	if err != nil {
		log.Fatalf("Error creating note %v", err)
	} else {
		log.Printf("Succesfully created note: %v", createdN)
	}

	if got, _, err := client.GetNote(nPID, nID); err != nil {
		log.Fatalf("Error getting note %v", err)

	} else {
		log.Printf("Succesfully got note: %v", got)
	}

	oPID := "scanning-customer"
	o := Occurrence(createdN.Name)
	createdO, _, err := client.CreateOccurrence(oPID, *o)
	if err != nil {
		log.Fatalf("Error creating occurrence %v", err)
	} else {
		log.Printf("Succesfully created occurrence: %v", createdO)
	}

	_, oID, pErr := name.ParseOccurrence(createdO.Name)
	if pErr != nil {
		log.Fatalf("Unable to get occurenceId from occurrence name %v: %v", createdO.Name, err)
	}
	if got, _, err := client.GetOccurrence(oPID, oID); err != nil {
		log.Printf("Error getting occurrence %v", err)
	} else {
		log.Printf("Succesfully got occurrence: %v", got)
	}

}

func note(pID, nID string) *swagger.Note {
	return &swagger.Note{
		Name:             fmt.Sprintf("projects/%v/notes/%v", pID, nID),
		ShortDescription: "CVE-2014-9911",
		LongDescription:  "NIST vectors: AV:N/AC:L/Au:N/C:P/I:P",
		Kind:             "PACKAGE_VULNERABILITY",
		VulnerabilityType: swagger.VulnerabilityType{
			CvssScore: 7.5,
			Severity:  "HIGH",
			Details: []swagger.Detail{
				{
					CpeUri:   "cpe:/o:debian:debian_linux:7",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:7",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "4.8.1.1",
							Revision: "12+deb7u6",
						},
					},
				},
				{
					CpeUri:   "cpe:/o:debian:debian_linux:8",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u4",
						},
					},
				},
				{
					CpeUri:   "cpe:/o:debian:debian_linux:9",
					Package_: "icu",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "HIGH",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:9",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "55.1",
							Revision: "3",
						},
					},
				},
				{
					CpeUri:   "cpe:/o:canonical:ubuntu_linux:14.04",
					Package_: "andriod",
					Description: "Stack-based buffer overflow in the ures_getByKeyWithFallback function in " +
						"common/uresbund.cpp in International Components for Unicode (ICU) before 54.1 for C/C++ allows " +
						"remote attackers to cause a denial of service or possibly have unspecified other impact via a crafted uloc_getDisplayName call.",
					MinAffectedVersion: swagger.Version{
						Kind: "MINIMUM",
					},
					SeverityName: "MEDIUM",

					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:canonical:ubuntu_linux:14.04",
						Package_: "andriod",
						Version: swagger.Version{
							Kind: "MAXIMUM",
						},
					},
				},
			},
		},
		RelatedUrl: []swagger.RelatedUrl{
			{
				Url:   "https://security-tracker.debian.org/tracker/CVE-2014-9911",
				Label: "More Info",
			},
			{
				Url:   "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2014-9911",
				Label: "More Info",
			},
		},
	}
}

func Occurrence(noteName string) *swagger.Occurrence {
	return &swagger.Occurrence{
		ResourceUrl: "gcr.io/foo/bar",
		NoteName:    noteName,
		Kind:        "PACKAGE_VULNERABILITY",
		VulnerabilityDetails: swagger.VulnerabilityDetails{
			Severity:  "HIGH",
			CvssScore: 7.5,
			PackageIssue: []swagger.PackageIssue{
				swagger.PackageIssue{
					SeverityName: "HIGH",
					AffectedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u3",
						},
					},
					FixedLocation: swagger.VulnerabilityLocation{
						CpeUri:   "cpe:/o:debian:debian_linux:8",
						Package_: "icu",
						Version: swagger.Version{
							Name:     "52.1",
							Revision: "8+deb8u4",
						},
					},
				},
			},
		},
	}
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    rbt "github.com/erriapo/redblacktree"
)

type Key struct {
    Path, Country string
}

func KeyComparator(o1, o2 interface{}) int {
    k1 := o1.(Key)
    k2 := o2.(Key)
    return rbt.StringComparator(k1.Path+k1.Country, k2.Path+k2.Country)
}

func main() {
    t := rbt.NewTree()

    fmt.Printf("Starting with empty tree\n")
    fmt.Printf("t.Has(7) = %t\n", t.Has(7)) // false

    fmt.Printf("Add 3 nodes with keys 7, 3 and 1 in succession\n")
    t.Put(7, "payload7")
    t.Put(3, "payload3")
    t.Put(1, "payload1")

    fmt.Printf("size = %d\n", t.Size()) // 3

    inorder := &rbt.InorderVisitor{}
    t.Walk(inorder)
    fmt.Printf("tree = %s\n", inorder) // tree = ((.1.)3(.7.))

    if ok, payload := t.Get(3); ok {
        fmt.Printf("%d is mapped to %s\n", 3, payload.(string))
    }
    fmt.Printf("t.Has(7) = %t\n", t.Has(7)) // true

    t.Delete(1)
    fmt.Printf("\nt.Delete(1)\n")
    inorder2 := &rbt.InorderVisitor{}
    t.Walk(inorder2)
    fmt.Printf("tree = %s\n", inorder2) // tree = (.3(.7.))
    fmt.Printf("t.Has(1) = %t\n\n", t.Has(1)) // false

    tr := rbt.NewTreeWith(KeyComparator)
    kAU, kNZ := Key{"/", "au"}, Key{"/tmp", "nz"}
    tr.Put(kAU, 999)
    if ok, payload := tr.Get(kAU); ok {
        fmt.Printf("%#v is mapped to %#v\n", kAU, payload)
    }
    tr.Put(kNZ, 666)
    fmt.Printf("tr.Put(kNZ, 666)\n")
    fmt.Printf("size = %d\n", tr.Size())
}
<commit_msg>better formatting<commit_after>package main

import (
    "fmt"
    rbt "github.com/erriapo/redblacktree"
)

type Key struct {
    Path, Country string
}

func KeyComparator(o1, o2 interface{}) int {
    k1 := o1.(Key)
    k2 := o2.(Key)
    return rbt.StringComparator(k1.Path+k1.Country, k2.Path+k2.Country)
}

func main() {
    t := rbt.NewTree()

    fmt.Printf("Starting with an empty tree\n")
    fmt.Printf("\tt.Has(7) = %t\n", t.Has(7)) // false

    fmt.Printf("Add 3 nodes with keys 7, 3 and 1 in succession\n")
    t.Put(7, "payload7")
    t.Put(3, "payload3")
    t.Put(1, "payload1")

    fmt.Printf("\tsize = %d\n", t.Size()) // 3

    inorder := &rbt.InorderVisitor{}
    t.Walk(inorder)
    fmt.Printf("\ttree = %s\n", inorder) // tree = ((.1.)3(.7.))

    if ok, payload := t.Get(3); ok {
        fmt.Printf("\t%d is mapped to %s\n", 3, payload.(string))
    }
    fmt.Printf("\tt.Has(7) = %t\n", t.Has(7)) // true

    t.Delete(1)
    fmt.Printf("\nt.Delete(1)\n")
    inorder2 := &rbt.InorderVisitor{}
    t.Walk(inorder2)
    fmt.Printf("\ttree = %s\n", inorder2) // tree = (.3(.7.))
    fmt.Printf("\tt.Has(1) = %t\n\n", t.Has(1)) // false

    tr := rbt.NewTreeWith(KeyComparator)
    kAU, kNZ := Key{"/", "au"}, Key{"/tmp", "nz"}
    tr.Put(kAU, 999)
    fmt.Printf("tr.Put(kAU, 999)\n")
    if ok, payload := tr.Get(kAU); ok {
        fmt.Printf("\t%#v is mapped to %#v\n", kAU, payload)
    }
    tr.Put(kNZ, 666)
    fmt.Printf("tr.Put(kNZ, 666)\n")
    fmt.Printf("\tsize = %d\n", tr.Size())
}
<|endoftext|>


<commit_before>// Package main is an entry point of the application.
package main

import (
	"net/http"
	"runtime"

	"github.com/anonx/sunplate/log"

	"github.com/julienschmidt/httprouter"
)

// Comments below are used by `go generate`.
// Please, DO NOT EDIT if you do not know what you are doing.
//
//go:generate sunplate generate handlers --path ./controllers/ --output ./assets/ --package handlers

func main() {
	// Set max procs for multi-thread executing.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Include handlers and run the app.
	router := httprouter.New()
	log.Error.Fatal(http.ListenAndServe(":8080", router))
}
<commit_msg>Updated example app's router<commit_after>// Package main is an entry point of the application.
package main

import (
	"net/http"
	"runtime"

	"github.com/anonx/sunplate/log"
	"github.com/anonx/sunplate/routing"
)

// Comments below are used by `go generate`.
// Please, DO NOT EDIT if you do not know what you are doing.
//
//go:generate sunplate generate handlers --path ./controllers/ --output ./assets/ --package handlers

func main() {
	// Set max procs for multi-thread executing.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Include handlers and run the app.
	r := routing.NewRouter()
	err := r.Handle(routing.Routes{
		nil,
	}).Build()
	if err != nil {
		log.Error.Fatal(err)
	}
	log.Error.Fatal(http.ListenAndServe(":8080", r))
}
<|endoftext|>