<commit_before>// Package httpcache provides a http.RoundTripper implementation that works as a
// mostly RFC-compliant cache for http responses.
//
// It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client
// and not for a shared proxy).
//
// 'max-stale' set on a request is not currently respected. (max-age and min-fresh both are.)
package httpcache

import (
	"bufio"
	"bytes"
	"net/http"
	"net/http/httputil"
	"strings"
	"sync"
	"time"
)

const (
	stale = iota
	fresh
	transparent
	// Header added to responses that are returned from the cache
	XFromCache = "X-From-Cache"
)

// A Cache interface is used by the Transport to store and retrieve responses.
type Cache interface {
	// Get returns the []byte representation of a cached response and a bool
	// set to true if the value isn't empty
	Get(key string) (responseBytes []byte, ok bool)
	// Set stores the []byte representation of a response against a key
	Set(key string, responseBytes []byte)
	// Delete removes the value associated with the key
	Delete(key string)
}

// MemoryCache is an implemtation of Cache that stores responses in an in-memory map.
type MemoryCache struct {
	mu    sync.RWMutex
	items map[string][]byte
}

func (c *MemoryCache) Get(key string) (resp []byte, ok bool) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	resp, ok = c.items[key]
	return resp, ok
}

func (c *MemoryCache) Set(key string, resp []byte) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.items[key] = resp
}

func (c *MemoryCache) Delete(key string) {
	c.mu.Lock()
	defer c.mu.Unlock()
	delete(c.items, key)
}

// NewMemoryCache returns a new Cache that will store items in an in-memory map
func NewMemoryCache() *MemoryCache {
	c := &MemoryCache{items: map[string][]byte{}}
	return c
}

// Transport is an implementation of http.RoundTripper that will return values from a cache
// where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since)
// to repeated requests allowing servers to return 304 / Not Modified
type Transport struct {
	// The RoundTripper interface actually used to make requests
	// If this follows redirects, then only the final response's cache-control will be taken into account
	transport http.RoundTripper
	cache     Cache
	// If true, responses returned from the cache will be given an extra header, X-From-Cache
	MarkCachedResponses bool
}

// NewTransport returns a new Transport using the default HTTP Transport and the
// provided Cache implementation, with MarkCachedResponses set to true
func NewTransport(c Cache) *Transport {
	t := &Transport{transport: http.DefaultTransport, cache: c, MarkCachedResponses: true}
	return t
}

// varyMatches will return false unless all of the cached values for the headers listed in Vary
// match the new request
func varyMatches(cachedResp *http.Response, req *http.Request) bool {
	respVarys := cachedResp.Header.Get("vary")
	for _, header := range strings.Split(respVarys, ",") {
		header = http.CanonicalHeaderKey(strings.Trim(header, " "))
		if header != "" && req.Header.Get(header) != cachedResp.Header.Get("X-Varied-"+header) {
			return false
		}
	}
	return true
}

// RoundTrip takes a Request and returns a Response
//
// If there is a fresh Response already in cache, then it will be returned without connecting to
// the server.
//
// If there is a stale Response, then any validators it contains will be set on the new request
// to give the server a chance to respond with NotModified. If this happens, then the cached Response
// will be returned.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	req = cloneRequest(req)
	cacheKey := req.URL.String()
	cachedVal, ok := t.cache.Get(cacheKey)
	cacheableMethod := req.Method == "GET" || req.Method == "HEAD"
	if !cacheableMethod {
		// Need to invalidate an existing value
		t.cache.Delete(cacheKey)
	}
	if ok && cacheableMethod && req.Header.Get("range") == "" {
		cachedResp, err := responseFromCache(cachedVal, req)
		if err == nil {
			if t.MarkCachedResponses {
				cachedResp.Header.Set(XFromCache, "1")
			}

			if varyMatches(cachedResp, req) {
				// Can only use cached value if the new request doesn't Vary significantly
				freshness := getFreshness(cachedResp.Header, req.Header)
				if freshness == fresh {
					return cachedResp, nil
				}

				if freshness == stale {
					// Add validators if caller hasn't already done so
					etag := cachedResp.Header.Get("etag")
					if etag != "" && req.Header.Get("etag") == "" {
						req.Header.Set("if-none-match", etag)
					}
					lastModified := cachedResp.Header.Get("last-modified")
					if lastModified != "" && req.Header.Get("last-modified") == "" {
						req.Header.Set("if-modified-since", lastModified)
					}
				}
			}

			resp, err = t.transport.RoundTrip(req)
			if err == nil && req.Method == "GET" && resp.StatusCode == http.StatusNotModified {
				// Replace the 304 response with the one from cache, but update with some new headers
				headersToMerge := getHopByHopHeaders(resp)
				for _, headerKey := range headersToMerge {
					cachedResp.Header.Set(headerKey, resp.Header.Get(headerKey))
				}
				cachedResp.Status = http.StatusText(http.StatusOK)
				cachedResp.StatusCode = http.StatusOK

				resp = cachedResp
			} else {
				if err != nil || resp.StatusCode != http.StatusOK {
					t.cache.Delete(cacheKey)
				}
			}
		}
	} else {
		reqCacheControl := parseCacheControl(req.Header)
		if _, ok := reqCacheControl["only-if-cached"]; ok {
			resp = newGatewayTimeoutResponse(req)
		} else {
			resp, err = t.transport.RoundTrip(req)
		}
	}
	reqCacheControl := parseCacheControl(req.Header)
	respCacheControl := parseCacheControl(resp.Header)

	if canStore(reqCacheControl, respCacheControl) {
		vary := resp.Header.Get("Vary")
		for _, varyKey := range strings.Split(vary, ",") {
			varyKey = http.CanonicalHeaderKey(strings.Trim(varyKey, " "))
			fakeHeader := "X-Varied-" + varyKey
			reqValue := req.Header.Get(varyKey)
			if reqValue != "" {
				resp.Header.Set(fakeHeader, reqValue)
			}
		}
		respBytes, err := httputil.DumpResponse(resp, true)
		if err == nil {
			// fmt.Println("Set cache", string(respBytes))
			t.cache.Set(cacheKey, respBytes)
		}
	} else {
		t.cache.Delete(cacheKey)
	}
	return resp, nil
}

// getFreshness will return one of fresh/stale/transparent based on the cache-control
// values of the request and the response
//
// fresh indicates the response can be returned
// stale indicates that the response needs validating before it is returned
// transparent indicates the response should not be used to fulfil the request
//
// Because this is only a private cache, 'public' and 'private' in cache-control aren't
// signficant. Similarly, smax-age isn't used.
//
// Limitation: max-stale is not taken into account. It should be.
func getFreshness(respHeaders, reqHeaders http.Header) (freshness int) {
	respCacheControl := parseCacheControl(respHeaders)
	reqCacheControl := parseCacheControl(reqHeaders)
	if _, ok := reqCacheControl["no-cache"]; ok {
		return transparent
	}
	if _, ok := respCacheControl["no-cache"]; ok {
		return stale
	}
	if _, ok := reqCacheControl["only-if-cached"]; ok {
		return fresh
	}
	dateHeader := respHeaders.Get("date")
	if dateHeader != "" {
		date, err := time.Parse(time.RFC1123, dateHeader)
		if err != nil {
			return stale
		}
		currentAge := time.Since(date)
		var lifetime time.Duration
		zeroDuration, _ := time.ParseDuration("0s")
		// If a response includes both an Expires header and a max-age directive,
		// the max-age directive overrides the Expires header, even if the Expires header is more restrictive.
		if maxAge, ok := respCacheControl["max-age"]; ok {
			lifetime, err = time.ParseDuration(maxAge + "s")
			if err != nil {
				lifetime = zeroDuration
			}
		} else {
			expiresHeader := respHeaders.Get("Expires")
			if expiresHeader != "" {
				expires, err := time.Parse(time.RFC1123, expiresHeader)
				if err != nil {
					lifetime = zeroDuration
				} else {
					lifetime = expires.Sub(date)
				}
			}
		}

		if maxAge, ok := reqCacheControl["max-age"]; ok {
			// the client is willing to accept a response whose age is no greater than the specified time in seconds
			lifetime, err = time.ParseDuration(maxAge + "s")
			if err != nil {
				lifetime = zeroDuration
			}
		}
		if minfresh, ok := reqCacheControl["min-fresh"]; ok {
			//  the client wants a response that will still be fresh for at least the specified number of seconds.
			minfreshDuration, err := time.ParseDuration(minfresh + "s")
			if err == nil {
				currentAge = time.Duration(currentAge + minfreshDuration)
			}
		}

		if lifetime > currentAge {
			return fresh
		}

	}
	return stale
}

func getHopByHopHeaders(resp *http.Response) []string {
	// These headers are always hop-by-hop
	headers := []string{"connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailers", "transfer-encoding", "upgrade"}

	for _, extra := range strings.Split(resp.Header.Get("connection"), ",") {
		// any header listed in connection, if present, is also considered hop-by-hop
		if strings.Trim(extra, " ") != "" {
			headers = append(headers, extra)
		}
	}
	return headers
}

func canStore(reqCacheControl, respCacheControl cacheControl) (canStore bool) {
	if _, ok := respCacheControl["no-store"]; ok {
		return false
	}
	if _, ok := reqCacheControl["no-store"]; ok {
		return false
	}
	return true
}

func responseFromCache(cachedVal []byte, req *http.Request) (*http.Response, error) {
	b := bytes.NewBuffer(cachedVal)
	resp, err := http.ReadResponse(bufio.NewReader(b), req)
	return resp, err
}

func newGatewayTimeoutResponse(req *http.Request) *http.Response {
	var braw bytes.Buffer
	braw.WriteString("HTTP/1.1 504 Gateway Timeout\r\n\r\n")
	resp, err := http.ReadResponse(bufio.NewReader(&braw), req)
	if err != nil {
		panic(err)
	}
	return resp
}

// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
// (This function copyright goauth2 authors: https://code.google.com/p/goauth2)
func cloneRequest(r *http.Request) *http.Request {
	// shallow copy of the struct
	r2 := new(http.Request)
	*r2 = *r
	// deep copy of the Header
	r2.Header = make(http.Header)
	for k, s := range r.Header {
		r2.Header[k] = s
	}
	return r2
}

type cacheControl map[string]string

func parseCacheControl(headers http.Header) cacheControl {
	cc := cacheControl{}
	ccHeader := headers.Get("Cache-Control")
	for _, part := range strings.Split(ccHeader, ",") {
		part = strings.Trim(part, " ")
		if part == "" {
			continue
		}
		if strings.ContainsRune(part, '=') {
			keyval := strings.Split(part, "=")
			cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
		} else {
			cc[part] = "1"
		}
	}
	return cc
}

// NewMemoryCacheTransport returns a new Transport using the in-memory cache implementation
func NewMemoryCacheTransport() *Transport {
	c := NewMemoryCache()
	t := NewTransport(c)
	return t
}
<commit_msg>remove superfluous comments<commit_after>// Package httpcache provides a http.RoundTripper implementation that works as a
// mostly RFC-compliant cache for http responses.
//
// It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client
// and not for a shared proxy).
//
// 'max-stale' set on a request is not currently respected. (max-age and min-fresh both are.)
package httpcache

import (
	"bufio"
	"bytes"
	"net/http"
	"net/http/httputil"
	"strings"
	"sync"
	"time"
)

const (
	stale = iota
	fresh
	transparent
	// Header added to responses that are returned from the cache
	XFromCache = "X-From-Cache"
)

// A Cache interface is used by the Transport to store and retrieve responses.
type Cache interface {
	// Get returns the []byte representation of a cached response and a bool
	// set to true if the value isn't empty
	Get(key string) (responseBytes []byte, ok bool)
	// Set stores the []byte representation of a response against a key
	Set(key string, responseBytes []byte)
	// Delete removes the value associated with the key
	Delete(key string)
}

// MemoryCache is an implemtation of Cache that stores responses in an in-memory map.
type MemoryCache struct {
	mu    sync.RWMutex
	items map[string][]byte
}

func (c *MemoryCache) Get(key string) (resp []byte, ok bool) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	resp, ok = c.items[key]
	return resp, ok
}

func (c *MemoryCache) Set(key string, resp []byte) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.items[key] = resp
}

func (c *MemoryCache) Delete(key string) {
	c.mu.Lock()
	defer c.mu.Unlock()
	delete(c.items, key)
}

// NewMemoryCache returns a new Cache that will store items in an in-memory map
func NewMemoryCache() *MemoryCache {
	c := &MemoryCache{items: map[string][]byte{}}
	return c
}

// Transport is an implementation of http.RoundTripper that will return values from a cache
// where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since)
// to repeated requests allowing servers to return 304 / Not Modified
type Transport struct {
	// The RoundTripper interface actually used to make requests
	transport http.RoundTripper
	cache     Cache
	// If true, responses returned from the cache will be given an extra header, X-From-Cache
	MarkCachedResponses bool
}

// NewTransport returns a new Transport using the default HTTP Transport and the
// provided Cache implementation, with MarkCachedResponses set to true
func NewTransport(c Cache) *Transport {
	t := &Transport{transport: http.DefaultTransport, cache: c, MarkCachedResponses: true}
	return t
}

// varyMatches will return false unless all of the cached values for the headers listed in Vary
// match the new request
func varyMatches(cachedResp *http.Response, req *http.Request) bool {
	respVarys := cachedResp.Header.Get("vary")
	for _, header := range strings.Split(respVarys, ",") {
		header = http.CanonicalHeaderKey(strings.Trim(header, " "))
		if header != "" && req.Header.Get(header) != cachedResp.Header.Get("X-Varied-"+header) {
			return false
		}
	}
	return true
}

// RoundTrip takes a Request and returns a Response
//
// If there is a fresh Response already in cache, then it will be returned without connecting to
// the server.
//
// If there is a stale Response, then any validators it contains will be set on the new request
// to give the server a chance to respond with NotModified. If this happens, then the cached Response
// will be returned.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	req = cloneRequest(req)
	cacheKey := req.URL.String()
	cachedVal, ok := t.cache.Get(cacheKey)
	cacheableMethod := req.Method == "GET" || req.Method == "HEAD"
	if !cacheableMethod {
		// Need to invalidate an existing value
		t.cache.Delete(cacheKey)
	}
	if ok && cacheableMethod && req.Header.Get("range") == "" {
		cachedResp, err := responseFromCache(cachedVal, req)
		if err == nil {
			if t.MarkCachedResponses {
				cachedResp.Header.Set(XFromCache, "1")
			}

			if varyMatches(cachedResp, req) {
				// Can only use cached value if the new request doesn't Vary significantly
				freshness := getFreshness(cachedResp.Header, req.Header)
				if freshness == fresh {
					return cachedResp, nil
				}

				if freshness == stale {
					// Add validators if caller hasn't already done so
					etag := cachedResp.Header.Get("etag")
					if etag != "" && req.Header.Get("etag") == "" {
						req.Header.Set("if-none-match", etag)
					}
					lastModified := cachedResp.Header.Get("last-modified")
					if lastModified != "" && req.Header.Get("last-modified") == "" {
						req.Header.Set("if-modified-since", lastModified)
					}
				}
			}

			resp, err = t.transport.RoundTrip(req)
			if err == nil && req.Method == "GET" && resp.StatusCode == http.StatusNotModified {
				// Replace the 304 response with the one from cache, but update with some new headers
				headersToMerge := getHopByHopHeaders(resp)
				for _, headerKey := range headersToMerge {
					cachedResp.Header.Set(headerKey, resp.Header.Get(headerKey))
				}
				cachedResp.Status = http.StatusText(http.StatusOK)
				cachedResp.StatusCode = http.StatusOK

				resp = cachedResp
			} else {
				if err != nil || resp.StatusCode != http.StatusOK {
					t.cache.Delete(cacheKey)
				}
			}
		}
	} else {
		reqCacheControl := parseCacheControl(req.Header)
		if _, ok := reqCacheControl["only-if-cached"]; ok {
			resp = newGatewayTimeoutResponse(req)
		} else {
			resp, err = t.transport.RoundTrip(req)
		}
	}
	reqCacheControl := parseCacheControl(req.Header)
	respCacheControl := parseCacheControl(resp.Header)

	if canStore(reqCacheControl, respCacheControl) {
		vary := resp.Header.Get("Vary")
		for _, varyKey := range strings.Split(vary, ",") {
			varyKey = http.CanonicalHeaderKey(strings.Trim(varyKey, " "))
			fakeHeader := "X-Varied-" + varyKey
			reqValue := req.Header.Get(varyKey)
			if reqValue != "" {
				resp.Header.Set(fakeHeader, reqValue)
			}
		}
		respBytes, err := httputil.DumpResponse(resp, true)
		if err == nil {
			t.cache.Set(cacheKey, respBytes)
		}
	} else {
		t.cache.Delete(cacheKey)
	}
	return resp, nil
}

// getFreshness will return one of fresh/stale/transparent based on the cache-control
// values of the request and the response
//
// fresh indicates the response can be returned
// stale indicates that the response needs validating before it is returned
// transparent indicates the response should not be used to fulfil the request
//
// Because this is only a private cache, 'public' and 'private' in cache-control aren't
// signficant. Similarly, smax-age isn't used.
//
// Limitation: max-stale is not taken into account. It should be.
func getFreshness(respHeaders, reqHeaders http.Header) (freshness int) {
	respCacheControl := parseCacheControl(respHeaders)
	reqCacheControl := parseCacheControl(reqHeaders)
	if _, ok := reqCacheControl["no-cache"]; ok {
		return transparent
	}
	if _, ok := respCacheControl["no-cache"]; ok {
		return stale
	}
	if _, ok := reqCacheControl["only-if-cached"]; ok {
		return fresh
	}
	dateHeader := respHeaders.Get("date")
	if dateHeader != "" {
		date, err := time.Parse(time.RFC1123, dateHeader)
		if err != nil {
			return stale
		}
		currentAge := time.Since(date)
		var lifetime time.Duration
		zeroDuration, _ := time.ParseDuration("0s")
		// If a response includes both an Expires header and a max-age directive,
		// the max-age directive overrides the Expires header, even if the Expires header is more restrictive.
		if maxAge, ok := respCacheControl["max-age"]; ok {
			lifetime, err = time.ParseDuration(maxAge + "s")
			if err != nil {
				lifetime = zeroDuration
			}
		} else {
			expiresHeader := respHeaders.Get("Expires")
			if expiresHeader != "" {
				expires, err := time.Parse(time.RFC1123, expiresHeader)
				if err != nil {
					lifetime = zeroDuration
				} else {
					lifetime = expires.Sub(date)
				}
			}
		}

		if maxAge, ok := reqCacheControl["max-age"]; ok {
			// the client is willing to accept a response whose age is no greater than the specified time in seconds
			lifetime, err = time.ParseDuration(maxAge + "s")
			if err != nil {
				lifetime = zeroDuration
			}
		}
		if minfresh, ok := reqCacheControl["min-fresh"]; ok {
			//  the client wants a response that will still be fresh for at least the specified number of seconds.
			minfreshDuration, err := time.ParseDuration(minfresh + "s")
			if err == nil {
				currentAge = time.Duration(currentAge + minfreshDuration)
			}
		}

		if lifetime > currentAge {
			return fresh
		}

	}
	return stale
}

func getHopByHopHeaders(resp *http.Response) []string {
	// These headers are always hop-by-hop
	headers := []string{"connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailers", "transfer-encoding", "upgrade"}

	for _, extra := range strings.Split(resp.Header.Get("connection"), ",") {
		// any header listed in connection, if present, is also considered hop-by-hop
		if strings.Trim(extra, " ") != "" {
			headers = append(headers, extra)
		}
	}
	return headers
}

func canStore(reqCacheControl, respCacheControl cacheControl) (canStore bool) {
	if _, ok := respCacheControl["no-store"]; ok {
		return false
	}
	if _, ok := reqCacheControl["no-store"]; ok {
		return false
	}
	return true
}

func responseFromCache(cachedVal []byte, req *http.Request) (*http.Response, error) {
	b := bytes.NewBuffer(cachedVal)
	resp, err := http.ReadResponse(bufio.NewReader(b), req)
	return resp, err
}

func newGatewayTimeoutResponse(req *http.Request) *http.Response {
	var braw bytes.Buffer
	braw.WriteString("HTTP/1.1 504 Gateway Timeout\r\n\r\n")
	resp, err := http.ReadResponse(bufio.NewReader(&braw), req)
	if err != nil {
		panic(err)
	}
	return resp
}

// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
// (This function copyright goauth2 authors: https://code.google.com/p/goauth2)
func cloneRequest(r *http.Request) *http.Request {
	// shallow copy of the struct
	r2 := new(http.Request)
	*r2 = *r
	// deep copy of the Header
	r2.Header = make(http.Header)
	for k, s := range r.Header {
		r2.Header[k] = s
	}
	return r2
}

type cacheControl map[string]string

func parseCacheControl(headers http.Header) cacheControl {
	cc := cacheControl{}
	ccHeader := headers.Get("Cache-Control")
	for _, part := range strings.Split(ccHeader, ",") {
		part = strings.Trim(part, " ")
		if part == "" {
			continue
		}
		if strings.ContainsRune(part, '=') {
			keyval := strings.Split(part, "=")
			cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
		} else {
			cc[part] = "1"
		}
	}
	return cc
}

// NewMemoryCacheTransport returns a new Transport using the in-memory cache implementation
func NewMemoryCacheTransport() *Transport {
	c := NewMemoryCache()
	t := NewTransport(c)
	return t
}
<|endoftext|>


<commit_before>// Copyright 2011 The Snappy-Go Authors. All rights reserved.
// Modified for deflate by Klaus Post (c) 2015.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flate

type tokens struct {
	tokens []token
}

// We limit how far copy back-references can go, the same as the C++ code.
const maxOffset = 1 << 15

// emitLiteral writes a literal chunk and returns the number of bytes written.
func emitLiteral(dst *tokens, lit []byte) {
	for _, v := range lit {
		dst.tokens = append(dst.tokens, literalToken(uint32(v)))
	}
}

// emitCopy writes a copy chunk and returns the number of bytes written.
func emitCopy(dst *tokens, offset, length int) {
	dst.tokens = append(dst.tokens, matchToken(uint32(length-3), uint32(offset-minOffsetSize)))
}

// snappyEncode uses Snappy-like compression, but stores as Huffman
// blocks.
func snappyEncode(dst *tokens, src []byte) {
	// Return early if src is short.
	if len(src) <= 4 {
		if len(src) != 0 {
			emitLiteral(dst, src)
		}
		return
	}

	// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
	const maxTableSize = 1 << 14
	shift, tableSize := uint(32-8), 1<<8
	for tableSize < maxTableSize && tableSize < len(src) {
		shift--
		tableSize *= 2
	}
	var table [maxTableSize]int

	// Iterate over the source bytes.
	var (
		s   int // The iterator position.
		t   int // The last position with the same hash as s.
		lit int // The start position of any pending literal bytes.
	)
	for s+3 < len(src) {
		// Update the hash table.
		b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3]
		h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24
		p := &table[(h*0x1e35a7bd)>>shift]
		// We need to to store values in [-1, inf) in table. To save
		// some initialization time, (re)use the table's zero value
		// and shift the values against this zero: add 1 on writes,
		// subtract 1 on reads.
		t, *p = *p-1, s+1
		// If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte.
		if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] {
			s++
			continue
		}
		// Otherwise, we have a match. First, emit any pending literal bytes.
		if lit != s {
			emitLiteral(dst, src[lit:s])
		}
		// Extend the match to be as long as possible.
		s0 := s
		s1 := s+maxMatchLength
		if s1 > len(src) {
			s1 = len(src)
		}
		s, t = s+4, t+4
		for s < s1 && src[s] == src[t]  {
			s++
			t++
		}
		// Emit the copied bytes.
		//emitCopy(dst, s-t, s-s0)
		dst.tokens = append(dst.tokens, matchToken(uint32(s-s0-3), uint32(s-t-minOffsetSize)))

		lit = s
	}

	// Emit any final pending literal bytes and return.
	if lit != len(src) {
		emitLiteral(dst, src[lit:])
	}
}
<commit_msg>Comment<commit_after>// Copyright 2011 The Snappy-Go Authors. All rights reserved.
// Modified for deflate by Klaus Post (c) 2015.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flate

type tokens struct {
	tokens []token
}

// We limit how far copy back-references can go, the same as the C++ code.
const maxOffset = 1 << 15

// emitLiteral writes a literal chunk and returns the number of bytes written.
func emitLiteral(dst *tokens, lit []byte) {
	for _, v := range lit {
		dst.tokens = append(dst.tokens, literalToken(uint32(v)))
	}
}

// emitCopy writes a copy chunk and returns the number of bytes written.
func emitCopy(dst *tokens, offset, length int) {
	dst.tokens = append(dst.tokens, matchToken(uint32(length-3), uint32(offset-minOffsetSize)))
}

// snappyEncode uses Snappy-like compression, but stores as Huffman
// blocks.
func snappyEncode(dst *tokens, src []byte) {
	// Return early if src is short.
	if len(src) <= 4 {
		if len(src) != 0 {
			emitLiteral(dst, src)
		}
		return
	}

	// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
	const maxTableSize = 1 << 14
	shift, tableSize := uint(32-8), 1<<8
	for tableSize < maxTableSize && tableSize < len(src) {
		shift--
		tableSize *= 2
	}
	var table [maxTableSize]int

	// Iterate over the source bytes.
	var (
		s   int // The iterator position.
		t   int // The last position with the same hash as s.
		lit int // The start position of any pending literal bytes.
	)
	for s+3 < len(src) {
		// Update the hash table.
		b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3]
		h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24
		p := &table[(h*0x1e35a7bd)>>shift]
		// We need to to store values in [-1, inf) in table. To save
		// some initialization time, (re)use the table's zero value
		// and shift the values against this zero: add 1 on writes,
		// subtract 1 on reads.
		t, *p = *p-1, s+1
		// If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte.
		if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] {
			s++
			continue
		}
		// Otherwise, we have a match. First, emit any pending literal bytes.
		if lit != s {
			emitLiteral(dst, src[lit:s])
		}
		// Extend the match to be as long as possible.
		s0 := s
		s1 := s+maxMatchLength
		if s1 > len(src) {
			s1 = len(src)
		}
		s, t = s+4, t+4
		for s < s1 && src[s] == src[t]  {
			s++
			t++
		}
		// Emit the copied bytes.
		// inlined: emitCopy(dst, s-t, s-s0)
		dst.tokens = append(dst.tokens, matchToken(uint32(s-s0-3), uint32(s-t-minOffsetSize)))

		lit = s
	}

	// Emit any final pending literal bytes and return.
	if lit != len(src) {
		emitLiteral(dst, src[lit:])
	}
}
<|endoftext|>


<commit_before>package vsphere

import (
	"bytes"
	"fmt"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/packer"
	"os/exec"
	"strings"
)

var builtins = map[string]string{
	"mitchellh.vmware": "vmware",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	Insecure           bool   `mapstructure:"insecure"`
	Cluster            string `mapstructure:"cluster"`
	Datacenter         string `mapstructure:"datacenter"`
	Datastore          string `mapstructure:"datastore"`
	Debug              bool   `mapstructure:"debug"`
	Host               string `mapstructure:"host"`
	Password           string `mapstructure:"password"`
	ResourcePool       string `mapstructure:"resource_pool"`
	Username           string `mapstructure:"username"`
	VMFolder           string `mapstructure:"vm_folder"`
	VMName             string `mapstructure:"vm_name"`
	VMNetwork          string `mapstructure:"vm_network"`

	tpl *packer.ConfigTemplate
}

type PostProcessor struct {
	config Config
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	_, err := common.DecodeConfig(&p.config, raws...)
	if err != nil {
		return err
	}

	p.config.tpl, err = packer.NewConfigTemplate()
	if err != nil {
		return err
	}
	p.config.tpl.UserVars = p.config.PackerUserVars

	// Accumulate any errors
	errs := new(packer.MultiError)

	if _, err := exec.LookPath("ovftool"); err != nil {
		errs = packer.MultiErrorAppend(
			errs, fmt.Errorf("ovftool not found: %s", err))
	}

	validates := map[string]*string{
		"cluster":      &p.config.Cluster,
		"datacenter":   &p.config.Datacenter,
		"datastore":    &p.config.Datastore,
		"host":         &p.config.Host,
		"vm_network":   &p.config.VMNetwork,
		"password":     &p.config.Password,
		"resource_pool": &p.config.ResourcePool,
		"username":     &p.config.Username,
		"vm_folder":    &p.config.VMFolder,
		"vm_name":      &p.config.VMName,
	}

	for n := range validates {
		if *validates[n] == "" {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("%s must be set", n))
		}
	}

	if len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	if _, ok := builtins[artifact.BuilderId()]; !ok {
		return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	vmx := ""
	for _, path := range artifact.Files() {
		if strings.HasSuffix(path, ".vmx") {
			vmx = path
			break
		}
	}

	if vmx == "" {
		return nil, false, fmt.Errorf("VMX file not found")
	}

	vm_name, err := p.config.tpl.Process(p.config.VMName, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	username, err := p.config.tpl.Process(p.config.Username, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	password, err := p.config.tpl.Process(p.config.Password, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	ui.Message(fmt.Sprintf("Uploading %s to vSphere", vmx))

	args := []string{
		fmt.Sprintf("--noSSLVerify=%t", p.config.Insecure),
		"--acceptAllEulas",
		fmt.Sprintf("--name=%s", vm_name),
		fmt.Sprintf("--datastore=%s", p.config.Datastore),
		fmt.Sprintf("--network=%s", p.config.VMNetwork),
		fmt.Sprintf("--vmFolder=%s", p.config.VMFolder),
		fmt.Sprintf("%s", vmx),
		fmt.Sprintf("vi://%s:%s@%s/%s/host/%s/Resources/%s",
			username,
			password,
			p.config.Host,
			p.config.Datacenter,
			p.config.Cluster,
			p.config.ResourcePool),
	}

	if p.config.Debug {
		ui.Message(fmt.Sprintf("DEBUG: %s", args))
	}

	var out bytes.Buffer
	cmd := exec.Command("ovftool", args...)
	cmd.Stdout = &out
	if err := cmd.Run(); err != nil {
		return nil, false, fmt.Errorf("Failed: %s\nStdout: %s", err, out.String())
	}

	ui.Message(fmt.Sprintf("%s", out.String()))

	return artifact, false, nil
}
<commit_msg>post-processor-vsphere: user variables for datastore<commit_after>package vsphere

import (
	"bytes"
	"fmt"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/packer"
	"os/exec"
	"strings"
)

var builtins = map[string]string{
	"mitchellh.vmware": "vmware",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	Insecure           bool   `mapstructure:"insecure"`
	Cluster            string `mapstructure:"cluster"`
	Datacenter         string `mapstructure:"datacenter"`
	Datastore          string `mapstructure:"datastore"`
	Debug              bool   `mapstructure:"debug"`
	Host               string `mapstructure:"host"`
	Password           string `mapstructure:"password"`
	ResourcePool       string `mapstructure:"resource_pool"`
	Username           string `mapstructure:"username"`
	VMFolder           string `mapstructure:"vm_folder"`
	VMName             string `mapstructure:"vm_name"`
	VMNetwork          string `mapstructure:"vm_network"`

	tpl *packer.ConfigTemplate
}

type PostProcessor struct {
	config Config
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	_, err := common.DecodeConfig(&p.config, raws...)
	if err != nil {
		return err
	}

	p.config.tpl, err = packer.NewConfigTemplate()
	if err != nil {
		return err
	}
	p.config.tpl.UserVars = p.config.PackerUserVars

	// Accumulate any errors
	errs := new(packer.MultiError)

	if _, err := exec.LookPath("ovftool"); err != nil {
		errs = packer.MultiErrorAppend(
			errs, fmt.Errorf("ovftool not found: %s", err))
	}

	validates := map[string]*string{
		"cluster":      &p.config.Cluster,
		"datacenter":   &p.config.Datacenter,
		"datastore":    &p.config.Datastore,
		"host":         &p.config.Host,
		"vm_network":   &p.config.VMNetwork,
		"password":     &p.config.Password,
		"resource_pool": &p.config.ResourcePool,
		"username":     &p.config.Username,
		"vm_folder":    &p.config.VMFolder,
		"vm_name":      &p.config.VMName,
	}

	for n := range validates {
		if *validates[n] == "" {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("%s must be set", n))
		}
	}

	if len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	if _, ok := builtins[artifact.BuilderId()]; !ok {
		return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	vmx := ""
	for _, path := range artifact.Files() {
		if strings.HasSuffix(path, ".vmx") {
			vmx = path
			break
		}
	}

	if vmx == "" {
		return nil, false, fmt.Errorf("VMX file not found")
	}

	// Get user variables from template
	vm_name, err := p.config.tpl.Process(p.config.VMName, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	username, err := p.config.tpl.Process(p.config.Username, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	password, err := p.config.tpl.Process(p.config.Password, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	datastore, err := p.config.tpl.Process(p.config.Datastore, p.config.PackerUserVars)
	if err != nil {
		return nil, false, fmt.Errorf("Failed: %s", err)
	}

	ui.Message(fmt.Sprintf("Uploading %s to vSphere", vmx))

	args := []string{
		fmt.Sprintf("--noSSLVerify=%t", p.config.Insecure),
		"--acceptAllEulas",
		fmt.Sprintf("--name=%s", vm_name),
		fmt.Sprintf("--datastore=%s", datastore),
		fmt.Sprintf("--network=%s", p.config.VMNetwork),
		fmt.Sprintf("--vmFolder=%s", p.config.VMFolder),
		fmt.Sprintf("%s", vmx),
		fmt.Sprintf("vi://%s:%s@%s/%s/host/%s/Resources/%s",
			username,
			password,
			p.config.Host,
			p.config.Datacenter,
			p.config.Cluster,
			p.config.ResourcePool),
	}

	if p.config.Debug {
		ui.Message(fmt.Sprintf("DEBUG: %s", args))
	}

	var out bytes.Buffer
	cmd := exec.Command("ovftool", args...)
	cmd.Stdout = &out
	if err := cmd.Run(); err != nil {
		return nil, false, fmt.Errorf("Failed: %s\nStdout: %s", err, out.String())
	}

	ui.Message(fmt.Sprintf("%s", out.String()))

	return artifact, false, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/types"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/loader"

	"github.com/gojuno/generator"
)

type (
	options struct {
		InputFile       string
		OutputFile      string
		InterfaceName   string
		StructName      string
		Package         string
		TestingType     string
		ImportWithTests bool
	}

	visitor struct {
		gen             *generator.Generator
		methods         map[string]*types.Signature
		sourceInterface string
	}
)

func main() {
	opts := processFlags()
	packagePath := opts.InputFile

	if _, err := os.Stat(packagePath); err == nil {
		if packagePath, err = generator.PackageOf(packagePath); err != nil {
			die(err)
		}
	}

	destPackagePath, err := generator.PackageOf(filepath.Dir(opts.OutputFile))
	if err != nil {
		die(err)
	}

	cfg := loader.Config{
		AllowErrors:         true,
		TypeCheckFuncBodies: func(string) bool { return false },
		TypeChecker: types.Config{
			IgnoreFuncBodies:         true,
			FakeImportC:              true,
			DisableUnusedImportCheck: true,
			Error: func(err error) {},
		},
	}

	if opts.ImportWithTests {
		cfg.ImportWithTests(packagePath)
	} else {
		cfg.Import(packagePath)
	}

	if err := os.Remove(opts.OutputFile); err != nil && !os.IsNotExist(err) {
		die(err)
	}

	if destPackagePath != packagePath {
		cfg.Import(destPackagePath)
	}

	prog, err := cfg.Load()
	if err != nil {
		die(err)
	}

	gen := generator.New(prog)
	gen.ImportWithAlias(destPackagePath, "")
	gen.SetPackageName(opts.Package)
	gen.SetVar("structName", opts.StructName)
	gen.SetVar("interfaceName", opts.InterfaceName)
	gen.SetVar("testingType", opts.TestingType)
	gen.SetVar("packagePath", packagePath)
	gen.SetHeader(fmt.Sprintf(`DO NOT EDIT!
This code was generated automatically using github.com/gojuno/minimock v1.3
The original interface %q can be found in %s`, opts.InterfaceName, packagePath))
	gen.SetDefaultParamsPrefix("p")
	gen.SetDefaultResultsPrefix("r")

	v := &visitor{
		gen:             gen,
		methods:         map[string]*types.Signature{},
		sourceInterface: opts.InterfaceName,
	}

	for _, file := range prog.Package(packagePath).Files {
		ast.Walk(v, file)
	}

	if len(v.methods) == 0 {
		die(fmt.Errorf("interface %s was not found in %s or it's an empty interface", opts.InterfaceName, packagePath))
	}

	if err := gen.ProcessTemplate("interface", template, v.methods); err != nil {
		die(err)
	}

	if err := gen.WriteToFilename(opts.OutputFile); err != nil {
		die(err)
	}
}

func (v *visitor) Visit(node ast.Node) ast.Visitor {
	switch ts := node.(type) {
	case *ast.FuncDecl:
		return nil
	case *ast.TypeSpec:
		exprType, err := v.gen.ExpressionType(ts.Type)
		if err != nil {
			die(fmt.Errorf("failed to get expression for %T %s: %v", ts.Type, ts.Name.Name, err))
		}

		var i *types.Interface

		switch t := exprType.(type) {
		case *types.Named:
			underlying, ok := t.Underlying().(*types.Interface)
			if !ok {
				return nil
			}
			i = underlying
		case *types.Interface:
			i = t
		}

		if ts.Name.Name == v.sourceInterface {
			v.processInterface(i)
		}

		return nil
	}

	return v
}

func (v *visitor) processInterface(t *types.Interface) {
	for i := 0; i < t.NumMethods(); i++ {
		v.methods[t.Method(i).Name()] = t.Method(i).Type().(*types.Signature)
	}
}

const template = `
	import minimock "github.com/gojuno/minimock"

	//{{$structName}} implements {{$packagePath}}.{{$interfaceName}}
	type {{$structName}} struct {
		t {{$testingType}}

		{{ range $methodName, $method := . }}
			{{$methodName}}Func func{{ signature $method }}
			{{$methodName}}Counter uint64
			{{$methodName}}Mock m{{$structName}}{{$methodName}}
		{{ end }}
	}

	//New{{$structName}} returns a mock for {{$packagePath}}.{{$interfaceName}}
	func New{{$structName}}(t {{$testingType}}) *{{$structName}} {
		m := &{{$structName}}{t: t}
		{{ range $methodName, $method := . }}m.{{$methodName}}Mock = m{{$structName}}{{$methodName}}{mock: m}
		{{ end }}

		return m
	}

	{{ range $methodName, $method := . }}
		type m{{$structName}}{{$methodName}} struct {
			mock *{{$structName}}
		}

		//Return sets up a mock for {{$interfaceName}}.{{$methodName}} to return Return's arguments
		func (m m{{$structName}}{{$methodName}}) Return({{results $method}}) *{{$structName}} {
			m.mock.{{$methodName}}Func = func({{params $method}}) ({{(results $method).Types}}) {
				return {{ (results $method).Names }}
			}
			return m.mock
		}

		//Set uses given function f as a mock of {{$interfaceName}}.{{$methodName}} method
		func (m m{{$structName}}{{$methodName}}) Set(f func({{params $method}}) ({{results $method}})) *{{$structName}}{
			m.mock.{{$methodName}}Func = f
			return m.mock
		}

		//{{$methodName}} implements {{$packagePath}}.{{$interfaceName}} interface
		func (m *{{$structName}}) {{$methodName}}{{signature $method}} {
			defer atomic.AddUint64(&m.{{$methodName}}Counter, 1)

			if m.{{$methodName}}Func == nil {
				m.t.Fatal("Unexpected call to {{$structName}}.{{$methodName}}")
				return
			}

			{{if gt (len (results $method)) 0 }}
			return {{ end }} m.{{$methodName}}Func({{(params $method).Pass}})
		}
	{{ end }}

	//ValidateCallCounters checks that all mocked methods of the iterface have been called at least once
	//Deprecated: please use Finish method
	func (m *{{$structName}}) ValidateCallCounters() {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				m.t.Fatal("Expected call to {{$structName}}.{{$methodName}}")
			}
		{{ end }}
	}

	//CheckMocksCalled checks that all mocked methods of the iterface have been called at least once
	//Deprecated: please use Finish method
	func (m *{{$structName}}) CheckMocksCalled() {
		m.Finish()
	}

	//Finish checks that all mocked methods of the iterface have been called at least once
	func (m *{{$structName}}) Finish() {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				m.t.Fatal("Expected call to {{$structName}}.{{$methodName}}")
			}
		{{ end }}
	}

	//Wait waits for all mocked methods to be called at least once
	func (m *{{$structName}}) Wait(timeout time.Duration) {
		timeoutCh := time.After(timeout)
		for {
			ok := true
			{{ range $methodName, $method := . }}ok = ok && (m.{{$methodName}}Func == nil || m.{{$methodName}}Counter > 0)
			{{ end }}

			if ok {
				return
			}

			select {
			case <-timeoutCh:
				{{ range $methodName, $method := . }}
					if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
						m.t.Error("Expected call to {{$structName}}.{{$methodName}}")
					}
				{{ end }}
				m.t.Fatalf("Some mocks were not called on time: %s", timeout)
				return
			default:
				time.Sleep(time.Millisecond)
			}
		}
	}

	//AllMocksCalled returns true if all mocked methods were called before the execution of AllMocksCalled,
	//it can be used with assert/require, i.e. assert.True(mock.AllMocksCalled())
	func (m *{{$structName}}) AllMocksCalled() bool {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				return false
			}
		{{ end }}

		return true
	}`

func processFlags() *options {
	var (
		input       = flag.String("f", "", "input file or import path of the package that contains interface declaration")
		name        = flag.String("i", "", "name of the interface to mock")
		output      = flag.String("o", "", "destination file name to place the generated mock")
		pkg         = flag.String("p", "", "destination package name")
		sname       = flag.String("t", "", "mock struct name, default is: <interface name>Mock")
		withTests   = flag.Bool("withTests", false, "parse *_test.go files in the source package")
		testingType = flag.String("testingType", "*testing.T", "type of the argument that is passed to mock constructor")
	)

	flag.Parse()

	if *pkg == "" || *input == "" || *output == "" || *name == "" || *testingType == "" || !strings.HasSuffix(*output, ".go") {
		flag.Usage()
		os.Exit(1)
	}

	if *sname == "" {
		*sname = *name + "Mock"
	}

	return &options{
		InputFile:       *input,
		OutputFile:      *output,
		InterfaceName:   *name,
		Package:         *pkg,
		StructName:      *sname,
		ImportWithTests: *withTests,
		TestingType:     *testingType,
	}
}

func die(err error) {
	fmt.Fprintf(os.Stderr, "%v\n", err)
	os.Exit(1)
}
<commit_msg>removed unused import<commit_after>package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/types"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/loader"

	"github.com/gojuno/generator"
)

type (
	options struct {
		InputFile       string
		OutputFile      string
		InterfaceName   string
		StructName      string
		Package         string
		TestingType     string
		ImportWithTests bool
	}

	visitor struct {
		gen             *generator.Generator
		methods         map[string]*types.Signature
		sourceInterface string
	}
)

func main() {
	opts := processFlags()
	packagePath := opts.InputFile

	if _, err := os.Stat(packagePath); err == nil {
		if packagePath, err = generator.PackageOf(packagePath); err != nil {
			die(err)
		}
	}

	destPackagePath, err := generator.PackageOf(filepath.Dir(opts.OutputFile))
	if err != nil {
		die(err)
	}

	cfg := loader.Config{
		AllowErrors:         true,
		TypeCheckFuncBodies: func(string) bool { return false },
		TypeChecker: types.Config{
			IgnoreFuncBodies:         true,
			FakeImportC:              true,
			DisableUnusedImportCheck: true,
			Error: func(err error) {},
		},
	}

	if opts.ImportWithTests {
		cfg.ImportWithTests(packagePath)
	} else {
		cfg.Import(packagePath)
	}

	if err := os.Remove(opts.OutputFile); err != nil && !os.IsNotExist(err) {
		die(err)
	}

	if destPackagePath != packagePath {
		cfg.Import(destPackagePath)
	}

	prog, err := cfg.Load()
	if err != nil {
		die(err)
	}

	gen := generator.New(prog)
	gen.ImportWithAlias(destPackagePath, "")
	gen.SetPackageName(opts.Package)
	gen.SetVar("structName", opts.StructName)
	gen.SetVar("interfaceName", opts.InterfaceName)
	gen.SetVar("testingType", opts.TestingType)
	gen.SetVar("packagePath", packagePath)
	gen.SetHeader(fmt.Sprintf(`DO NOT EDIT!
This code was generated automatically using github.com/gojuno/minimock v1.3
The original interface %q can be found in %s`, opts.InterfaceName, packagePath))
	gen.SetDefaultParamsPrefix("p")
	gen.SetDefaultResultsPrefix("r")

	v := &visitor{
		gen:             gen,
		methods:         map[string]*types.Signature{},
		sourceInterface: opts.InterfaceName,
	}

	for _, file := range prog.Package(packagePath).Files {
		ast.Walk(v, file)
	}

	if len(v.methods) == 0 {
		die(fmt.Errorf("interface %s was not found in %s or it's an empty interface", opts.InterfaceName, packagePath))
	}

	if err := gen.ProcessTemplate("interface", template, v.methods); err != nil {
		die(err)
	}

	if err := gen.WriteToFilename(opts.OutputFile); err != nil {
		die(err)
	}
}

func (v *visitor) Visit(node ast.Node) ast.Visitor {
	switch ts := node.(type) {
	case *ast.FuncDecl:
		return nil
	case *ast.TypeSpec:
		exprType, err := v.gen.ExpressionType(ts.Type)
		if err != nil {
			die(fmt.Errorf("failed to get expression for %T %s: %v", ts.Type, ts.Name.Name, err))
		}

		var i *types.Interface

		switch t := exprType.(type) {
		case *types.Named:
			underlying, ok := t.Underlying().(*types.Interface)
			if !ok {
				return nil
			}
			i = underlying
		case *types.Interface:
			i = t
		}

		if ts.Name.Name == v.sourceInterface {
			v.processInterface(i)
		}

		return nil
	}

	return v
}

func (v *visitor) processInterface(t *types.Interface) {
	for i := 0; i < t.NumMethods(); i++ {
		v.methods[t.Method(i).Name()] = t.Method(i).Type().(*types.Signature)
	}
}

const template = `
	//{{$structName}} implements {{$packagePath}}.{{$interfaceName}}
	type {{$structName}} struct {
		t {{$testingType}}

		{{ range $methodName, $method := . }}
			{{$methodName}}Func func{{ signature $method }}
			{{$methodName}}Counter uint64
			{{$methodName}}Mock m{{$structName}}{{$methodName}}
		{{ end }}
	}

	//New{{$structName}} returns a mock for {{$packagePath}}.{{$interfaceName}}
	func New{{$structName}}(t {{$testingType}}) *{{$structName}} {
		m := &{{$structName}}{t: t}
		{{ range $methodName, $method := . }}m.{{$methodName}}Mock = m{{$structName}}{{$methodName}}{mock: m}
		{{ end }}

		return m
	}

	{{ range $methodName, $method := . }}
		type m{{$structName}}{{$methodName}} struct {
			mock *{{$structName}}
		}

		//Return sets up a mock for {{$interfaceName}}.{{$methodName}} to return Return's arguments
		func (m m{{$structName}}{{$methodName}}) Return({{results $method}}) *{{$structName}} {
			m.mock.{{$methodName}}Func = func({{params $method}}) ({{(results $method).Types}}) {
				return {{ (results $method).Names }}
			}
			return m.mock
		}

		//Set uses given function f as a mock of {{$interfaceName}}.{{$methodName}} method
		func (m m{{$structName}}{{$methodName}}) Set(f func({{params $method}}) ({{results $method}})) *{{$structName}}{
			m.mock.{{$methodName}}Func = f
			return m.mock
		}

		//{{$methodName}} implements {{$packagePath}}.{{$interfaceName}} interface
		func (m *{{$structName}}) {{$methodName}}{{signature $method}} {
			defer atomic.AddUint64(&m.{{$methodName}}Counter, 1)

			if m.{{$methodName}}Func == nil {
				m.t.Fatal("Unexpected call to {{$structName}}.{{$methodName}}")
				return
			}

			{{if gt (len (results $method)) 0 }}
			return {{ end }} m.{{$methodName}}Func({{(params $method).Pass}})
		}
	{{ end }}

	//ValidateCallCounters checks that all mocked methods of the iterface have been called at least once
	//Deprecated: please use Finish method
	func (m *{{$structName}}) ValidateCallCounters() {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				m.t.Fatal("Expected call to {{$structName}}.{{$methodName}}")
			}
		{{ end }}
	}

	//CheckMocksCalled checks that all mocked methods of the iterface have been called at least once
	//Deprecated: please use Finish method
	func (m *{{$structName}}) CheckMocksCalled() {
		m.Finish()
	}

	//Finish checks that all mocked methods of the iterface have been called at least once
	func (m *{{$structName}}) Finish() {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				m.t.Fatal("Expected call to {{$structName}}.{{$methodName}}")
			}
		{{ end }}
	}

	//Wait waits for all mocked methods to be called at least once
	func (m *{{$structName}}) Wait(timeout time.Duration) {
		timeoutCh := time.After(timeout)
		for {
			ok := true
			{{ range $methodName, $method := . }}ok = ok && (m.{{$methodName}}Func == nil || m.{{$methodName}}Counter > 0)
			{{ end }}

			if ok {
				return
			}

			select {
			case <-timeoutCh:
				{{ range $methodName, $method := . }}
					if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
						m.t.Error("Expected call to {{$structName}}.{{$methodName}}")
					}
				{{ end }}
				m.t.Fatalf("Some mocks were not called on time: %s", timeout)
				return
			default:
				time.Sleep(time.Millisecond)
			}
		}
	}

	//AllMocksCalled returns true if all mocked methods were called before the execution of AllMocksCalled,
	//it can be used with assert/require, i.e. assert.True(mock.AllMocksCalled())
	func (m *{{$structName}}) AllMocksCalled() bool {
		{{ range $methodName, $method := . }}
			if m.{{$methodName}}Func != nil && m.{{$methodName}}Counter == 0 {
				return false
			}
		{{ end }}

		return true
	}`

func processFlags() *options {
	var (
		input       = flag.String("f", "", "input file or import path of the package that contains interface declaration")
		name        = flag.String("i", "", "name of the interface to mock")
		output      = flag.String("o", "", "destination file name to place the generated mock")
		pkg         = flag.String("p", "", "destination package name")
		sname       = flag.String("t", "", "mock struct name, default is: <interface name>Mock")
		withTests   = flag.Bool("withTests", false, "parse *_test.go files in the source package")
		testingType = flag.String("testingType", "*testing.T", "type of the argument that is passed to mock constructor")
	)

	flag.Parse()

	if *pkg == "" || *input == "" || *output == "" || *name == "" || *testingType == "" || !strings.HasSuffix(*output, ".go") {
		flag.Usage()
		os.Exit(1)
	}

	if *sname == "" {
		*sname = *name + "Mock"
	}

	return &options{
		InputFile:       *input,
		OutputFile:      *output,
		InterfaceName:   *name,
		Package:         *pkg,
		StructName:      *sname,
		ImportWithTests: *withTests,
		TestingType:     *testingType,
	}
}

func die(err error) {
	fmt.Fprintf(os.Stderr, "%v\n", err)
	os.Exit(1)
}
<|endoftext|>


<commit_before>/*--------------------------------------------------------*\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: https://hprose.com                     |
|                                                          |
| encoding/ptr_encoder.go                                  |
|                                                          |
| LastModified: Apr 12, 2020                               |
| Author: Ma Bingyao <andot@hprose.com>                    |
|                                                          |
\*________________________________________________________*/

package encoding

import (
	"math/big"
	"reflect"

	"github.com/modern-go/reflect2"
)

// ptrEncoder is the implementation of ValueEncoder for ptr.
type ptrEncoder struct{}

var ptrenc ptrEncoder

func (ptrEncoder) Encode(enc *Encoder, v interface{}) {
	writePtr(enc, v, func(valenc ValueEncoder, enc *Encoder, v interface{}) {
		valenc.Encode(enc, v)
	})
}

func (ptrEncoder) Write(enc *Encoder, v interface{}) {
	writePtr(enc, v, func(valenc ValueEncoder, enc *Encoder, v interface{}) {
		valenc.Write(enc, v)
	})
}

func fastWritePtr(enc *Encoder, v interface{}) (ok bool) {
	ok = true
	switch v := v.(type) {
	case *int:
		enc.WriteInt(*v)
	case *int8:
		enc.WriteInt8(*v)
	case *int16:
		enc.WriteInt16(*v)
	case *int32:
		enc.WriteInt32(*v)
	case *int64:
		enc.WriteInt64(*v)
	case *uint:
		enc.WriteUint(*v)
	case *uint8:
		enc.WriteUint8(*v)
	case *uint16:
		enc.WriteUint16(*v)
	case *uint32:
		enc.WriteUint32(*v)
	case *uint64:
		enc.WriteUint64(*v)
	case *uintptr:
		enc.WriteUint64(uint64(*v))
	case *bool:
		enc.WriteBool(*v)
	case *float32:
		enc.WriteFloat32(*v)
	case *float64:
		enc.WriteFloat64(*v)
	case *complex64:
		enc.WriteComplex64(*v)
	case *complex128:
		enc.WriteComplex128(*v)
	case *big.Int:
		enc.WriteBigInt(v)
	case *big.Float:
		enc.WriteBigFloat(v)
	case *big.Rat:
		enc.WriteBigRat(v)
	case *error:
		enc.WriteError(*v)
	default:
		ok = false
	}
	return
}
func writePtr(enc *Encoder, v interface{}, encode func(m ValueEncoder, enc *Encoder, v interface{})) {
	if fastWritePtr(enc, v) {
		return
	}
	e := reflect.ValueOf(v).Elem()
	kind := e.Kind()
	switch kind {
	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface:
		if e.IsNil() {
			enc.WriteNil()
			return
		}
	}
	et := e.Type()
	if valenc := getOtherEncoder(et); valenc != nil {
		encode(valenc, enc, v)
		return
	}
	switch kind {
	case reflect.Int:
		enc.WriteInt(*(*int)(reflect2.PtrOf(v)))
	case reflect.Int8:
		enc.WriteInt8(*(*int8)(reflect2.PtrOf(v)))
	case reflect.Int16:
		enc.WriteInt16(*(*int16)(reflect2.PtrOf(v)))
	case reflect.Int32:
		enc.WriteInt32(*(*int32)(reflect2.PtrOf(v)))
	case reflect.Int64:
		enc.WriteInt64(*(*int64)(reflect2.PtrOf(v)))
	case reflect.Uint:
		enc.WriteUint(*(*uint)(reflect2.PtrOf(v)))
	case reflect.Uint8:
		enc.WriteUint8(*(*uint8)(reflect2.PtrOf(v)))
	case reflect.Uint16:
		enc.WriteUint16(*(*uint16)(reflect2.PtrOf(v)))
	case reflect.Uint32:
		enc.WriteUint32(*(*uint32)(reflect2.PtrOf(v)))
	case reflect.Uint64, reflect.Uintptr:
		enc.WriteUint64(*(*uint64)(reflect2.PtrOf(v)))
	case reflect.Bool:
		enc.WriteBool(*(*bool)(reflect2.PtrOf(v)))
	case reflect.Float32:
		enc.WriteFloat32(*(*float32)(reflect2.PtrOf(v)))
	case reflect.Float64:
		enc.WriteFloat64(*(*float64)(reflect2.PtrOf(v)))
	case reflect.Complex64:
		enc.WriteComplex64(*(*complex64)(reflect2.PtrOf(v)))
	case reflect.Complex128:
		enc.WriteComplex128(*(*complex128)(reflect2.PtrOf(v)))
	case reflect.String:
		encode(strenc, enc, e.String())
	case reflect.Array:
		encode(arrayenc, enc, v)
	case reflect.Struct:
		encode(getStructEncoder(et), enc, v)
	case reflect.Slice:
		encode(slcenc, enc, v)
	case reflect.Map:
		encode(mapenc, enc, v)
	case reflect.Ptr:
		encode(ptrenc, enc, e.Interface())
	case reflect.Interface:
		encode(intfenc, enc, e.Interface())
	default:
		enc.WriteNil()
		enc.Error = &UnsupportedTypeError{Type: reflect.TypeOf(v)}
	}
}
<commit_msg>Update ptr_encoder.go<commit_after>/*--------------------------------------------------------*\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: https://hprose.com                     |
|                                                          |
| encoding/ptr_encoder.go                                  |
|                                                          |
| LastModified: Apr 12, 2020                               |
| Author: Ma Bingyao <andot@hprose.com>                    |
|                                                          |
\*________________________________________________________*/

package encoding

import (
	"math/big"
	"reflect"

	"github.com/modern-go/reflect2"
)

// ptrEncoder is the implementation of ValueEncoder for ptr.
type ptrEncoder struct{}

var ptrenc ptrEncoder

func (ptrEncoder) Encode(enc *Encoder, v interface{}) {
	enc.writePtr(v, func(valenc ValueEncoder, v interface{}) {
		valenc.Encode(enc, v)
	})
}

func (ptrEncoder) Write(enc *Encoder, v interface{}) {
	enc.writePtr(v, func(valenc ValueEncoder, v interface{}) {
		valenc.Write(enc, v)
	})
}

func (enc *Encoder) fastWritePtr(v interface{}) (ok bool) {
	ok = true
	switch v := v.(type) {
	case *int:
		enc.WriteInt(*v)
	case *int8:
		enc.WriteInt8(*v)
	case *int16:
		enc.WriteInt16(*v)
	case *int32:
		enc.WriteInt32(*v)
	case *int64:
		enc.WriteInt64(*v)
	case *uint:
		enc.WriteUint(*v)
	case *uint8:
		enc.WriteUint8(*v)
	case *uint16:
		enc.WriteUint16(*v)
	case *uint32:
		enc.WriteUint32(*v)
	case *uint64:
		enc.WriteUint64(*v)
	case *uintptr:
		enc.WriteUint64(uint64(*v))
	case *bool:
		enc.WriteBool(*v)
	case *float32:
		enc.WriteFloat32(*v)
	case *float64:
		enc.WriteFloat64(*v)
	case *complex64:
		enc.WriteComplex64(*v)
	case *complex128:
		enc.WriteComplex128(*v)
	case *big.Int:
		enc.WriteBigInt(v)
	case *big.Float:
		enc.WriteBigFloat(v)
	case *big.Rat:
		enc.WriteBigRat(v)
	case *error:
		enc.WriteError(*v)
	default:
		ok = false
	}
	return
}
func (enc *Encoder) writePtr(v interface{}, encode func(m ValueEncoder, v interface{})) {
	if enc.fastWritePtr(v) {
		return
	}
	e := reflect.ValueOf(v).Elem()
	kind := e.Kind()
	switch kind {
	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface:
		if e.IsNil() {
			enc.WriteNil()
			return
		}
	}
	et := e.Type()
	if valenc := getOtherEncoder(et); valenc != nil {
		encode(valenc, v)
		return
	}
	switch kind {
	case reflect.Int:
		enc.WriteInt(*(*int)(reflect2.PtrOf(v)))
	case reflect.Int8:
		enc.WriteInt8(*(*int8)(reflect2.PtrOf(v)))
	case reflect.Int16:
		enc.WriteInt16(*(*int16)(reflect2.PtrOf(v)))
	case reflect.Int32:
		enc.WriteInt32(*(*int32)(reflect2.PtrOf(v)))
	case reflect.Int64:
		enc.WriteInt64(*(*int64)(reflect2.PtrOf(v)))
	case reflect.Uint:
		enc.WriteUint(*(*uint)(reflect2.PtrOf(v)))
	case reflect.Uint8:
		enc.WriteUint8(*(*uint8)(reflect2.PtrOf(v)))
	case reflect.Uint16:
		enc.WriteUint16(*(*uint16)(reflect2.PtrOf(v)))
	case reflect.Uint32:
		enc.WriteUint32(*(*uint32)(reflect2.PtrOf(v)))
	case reflect.Uint64, reflect.Uintptr:
		enc.WriteUint64(*(*uint64)(reflect2.PtrOf(v)))
	case reflect.Bool:
		enc.WriteBool(*(*bool)(reflect2.PtrOf(v)))
	case reflect.Float32:
		enc.WriteFloat32(*(*float32)(reflect2.PtrOf(v)))
	case reflect.Float64:
		enc.WriteFloat64(*(*float64)(reflect2.PtrOf(v)))
	case reflect.Complex64:
		enc.WriteComplex64(*(*complex64)(reflect2.PtrOf(v)))
	case reflect.Complex128:
		enc.WriteComplex128(*(*complex128)(reflect2.PtrOf(v)))
	case reflect.String:
		encode(strenc, e.String())
	case reflect.Array:
		encode(arrayenc, v)
	case reflect.Struct:
		encode(getStructEncoder(et), v)
	case reflect.Slice:
		encode(slcenc, v)
	case reflect.Map:
		encode(mapenc, v)
	case reflect.Ptr:
		encode(ptrenc, e.Interface())
	case reflect.Interface:
		encode(intfenc, e.Interface())
	default:
		enc.WriteNil()
		enc.Error = &UnsupportedTypeError{Type: reflect.TypeOf(v)}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"golang.org/x/net/html"
	"net/http"
)

//sequence:
// Type: ElementNode
// Data: h2
// Attr.Key: id
// Attr.Val: pkg-overview

var requiredNodePath []*html.Node

func init() {
	//TODO: these additions are not reflecting
	n := html.Node{}
	n.Type = html.ElementNode
	n.Data = "div"
	a := html.Attribute{}
	a.Key = "class"
	a.Val = "post-footer-line post-footer-line-1"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, &n)

	n = html.Node{}
	n.Type = html.ElementNode
	n.Data = "div"
	a = html.Attribute{}
	a.Key = "class"
	a.Val = "post-author vcard"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, &n)

	n = html.Node{}
	n.Type = html.ElementNode
	n.Data = "span"
	a = html.Attribute{}
	a.Key = "itemprop"
	a.Val = "name"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, &n)

	n = html.Node{}
	n.Type = html.TextNode
	requiredNodePath = append(requiredNodePath, &n)
}

func main() {
	//url := `https://godoc.org/golang.org/x/oauth2`
	//url := `https://socketloop.com/tutorials/golang-read-file`
	url := `http://goblog.qwest.io/2017/09/protobuf-for-go-quick-reference.html`

	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	n, err := html.Parse(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	FindMatchingNode(n, requiredNodePath, isMatchingNode)

}

func isMatchingNode(n *html.Node, matchWith *html.Node) bool {
	if n.Type == matchWith.Type && n.Data == matchWith.Data { // TODO: check only on non blank fields
		matchCnt := 0
		for _, a := range matchWith.Attr {
			for _, w := range n.Attr {
				if a.Key == w.Key && a.Val == w.Val {
					matchCnt++
				}
			}
		}
		if matchCnt != len(matchWith.Attr) {
			return false
		}
		return true
	}
	return false
}

type WalkFunc func(*html.Node, *html.Node) bool

func FindMatchingNode(root *html.Node, match []*html.Node, walkF WalkFunc) {
	for _, m:= range match {
		fmt.Println(nodeTypeText(m.Type), m.Data, m.Attr)
		var f func(*html.Node)*html.Node
		f = func(n *html.Node) *html.Node {
			//fmt.Println(nodeTypeText(n.Type), n.Data, n.Attr)
			if walkF(n, m) {
				//fmt.Println(nodeTypeText(n.Type), n.Data, n.Attr)
				return n
			}

			for c := n.FirstChild; c != nil; c = c.NextSibling {
				f(c)
			}
			return nil
		}
		f(root)
	}
}

func nodeTypeText(nodeType html.NodeType) string {
	switch nodeType {
	case html.ErrorNode:
		return "ErrorNode"
	case html.TextNode:
		return "TextNode"
	case html.DocumentNode:
		return "DocumentNode"
	case html.ElementNode:
		return "ElementNode"
	case html.CommentNode:
		return "CommentNode"
	case html.DoctypeNode:
		return "DoctypeNode"
	}
	return ""

}
<commit_msg>html parsing: get-only-desired-section wip code<commit_after>package main

import (
	"fmt"
	"golang.org/x/net/html"
	"net/http"
)

//sequence:
// Type: ElementNode
// Data: h2
// Attr.Key: id
// Attr.Val: pkg-overview

var requiredNodePath []html.Node

func init() {
	n := html.Node{}
	n.Type = html.ElementNode
	n.Data = "div"
	a := html.Attribute{}
	a.Key = "class"
	a.Val = "post-footer-line post-footer-line-1"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, n)

	n = html.Node{}
	n.Type = html.ElementNode
	n.Data = "div"
	a = html.Attribute{}
	a.Key = "class"
	a.Val = "post-author vcard"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, n)

	n = html.Node{}
	n.Type = html.ElementNode
	n.Data = "span"
	a = html.Attribute{}
	a.Key = "itemprop"
	a.Val = "name"
	n.Attr = append(n.Attr, a)
	requiredNodePath = append(requiredNodePath, n)

	n = html.Node{}
	n.Type = html.TextNode
	requiredNodePath = append(requiredNodePath, n)

	//for _, m := range requiredNodePath { // for debug purpose
	////for m := requiredNodePath.FirstChild; m != nil; m = m.NextSibling {
	//	fmt.Println(nodeTypeText(m.Type), m.Data, m.Attr)
	//}

}

func main() {
	//url := `https://godoc.org/golang.org/x/oauth2`
	//url := `https://socketloop.com/tutorials/golang-read-file`
	url := `http://goblog.qwest.io/2017/09/protobuf-for-go-quick-reference.html`

	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	n, err := html.Parse(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	FindMatchingNode(n, requiredNodePath, isMatchingNode)

}

func isMatchingNode(n *html.Node, matchWith html.Node) bool {
	if n.Type == matchWith.Type && n.Data == matchWith.Data { // TODO: check only on non blank fields
		matchCnt := 0
		for _, a := range matchWith.Attr {
			for _, w := range n.Attr {
				if a.Key == w.Key && a.Val == w.Val {
					matchCnt++
				}
			}
		}
		if matchCnt != len(matchWith.Attr) {
			return false
		}
		return true
	}
	return false
}

type WalkFunc func(*html.Node, html.Node) bool

func FindMatchingNode(root *html.Node, match []html.Node, walkF WalkFunc) {
	for i, m := range match {
		//for m := match.FirstChild; m != nil; m = m.NextSibling {
		//fmt.Println(nodeTypeText(m.Type), m.Data, m.Attr)
		var f func(*html.Node) *html.Node
		f = func(n *html.Node) *html.Node {
			//fmt.Println(nodeTypeText(n.Type), n.Data, n.Attr)
			if walkF(n, m) {
				fmt.Println(i, nodeTypeText(n.Type), n.Data, n.Attr)
				return n
			}

			for c := n.FirstChild; c != nil; c = c.NextSibling {
				f(c)
			}
			return nil
		}
		root = f(root)
	}
}

func nodeTypeText(nodeType html.NodeType) string {
	switch nodeType {
	case html.ErrorNode:
		return "ErrorNode"
	case html.TextNode:
		return "TextNode"
	case html.DocumentNode:
		return "DocumentNode"
	case html.ElementNode:
		return "ElementNode"
	case html.CommentNode:
		return "CommentNode"
	case html.DoctypeNode:
		return "DoctypeNode"
	}
	return ""

}
<|endoftext|>


<commit_before>package model

import (
	"github.com/Sirupsen/logrus"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var (
	db  gorm.DB
	log *logrus.Logger
)

func InitDB(driver, database string) {
	var err error

	db, err = gorm.Open(driver, database)
	if err != nil {
		panic(err)
	}

	// enable SQL logging
	db.LogMode(true)
	db.SetLogger(&debugLogger{})

	db.AutoMigrate(&Job{}, &LeaveAllowance{}, &LeaveRequest{}, &User{})

	db.Model(&Job{}).AddIndex("id", "id")
	db.Model(&Job{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveRequest{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveRequest{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveAllowance{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveAllowance{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&User{}).AddIndex("id", "id")
	db.Model(&User{}).AddIndex("email", "email")
	db.Model(&User{}).AddIndex("deleted_at", "deleted_at")
}

func SetLogger(l *logrus.Logger) {
	log = l
}

// debugLogger satisfies Gorm's logger interface
// so that we can log SQL queries at Logrus' debug level
type debugLogger struct{}

func (*debugLogger) Print(msg ...interface{}) {
	log.Debug(msg)
}
<commit_msg>Sort models alphabetically when adding indices<commit_after>package model

import (
	"github.com/Sirupsen/logrus"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var (
	db  gorm.DB
	log *logrus.Logger
)

func InitDB(driver, database string) {
	var err error

	db, err = gorm.Open(driver, database)
	if err != nil {
		panic(err)
	}

	// enable SQL logging
	db.LogMode(true)
	db.SetLogger(&debugLogger{})

	db.AutoMigrate(&Job{}, &LeaveAllowance{}, &LeaveRequest{}, &User{})

	db.Model(&Job{}).AddIndex("id", "id")
	db.Model(&Job{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveAllowance{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveAllowance{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&LeaveRequest{}).AddIndex("start_date", "start_date")
	db.Model(&LeaveRequest{}).AddIndex("deleted_at", "deleted_at")

	db.Model(&User{}).AddIndex("id", "id")
	db.Model(&User{}).AddIndex("email", "email")
	db.Model(&User{}).AddIndex("deleted_at", "deleted_at")
}

func SetLogger(l *logrus.Logger) {
	log = l
}

// debugLogger satisfies Gorm's logger interface
// so that we can log SQL queries at Logrus' debug level
type debugLogger struct{}

func (*debugLogger) Print(msg ...interface{}) {
	log.Debug(msg)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"log"
	"net/http"
	"time"

	"github.com/bmizerany/lpx"
	"github.com/heroku/slog"
	"github.com/kr/logfmt"
)

var (
	TokenPrefix = []byte("t.")
	Heroku      = []byte("heroku")
)

// "Parse tree" from hell
func serveDrain(w http.ResponseWriter, r *http.Request) {
	ctx := slog.Context{}
	defer func() { LogWithContext(ctx) }()

	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
		ctx.Count("errors.drain.wrong.method", 1)
		return
	}

	id := r.Header.Get("Logplex-Drain-Token")

	if id == "" {
		w.WriteHeader(http.StatusBadRequest)
		ctx.Count("errors.drain.missing.token", 1)
		return
	}

	ctx.Count("batch", 1)

	parseStart := time.Now()
	lp := lpx.NewReader(bufio.NewReader(r.Body))
	defer r.Body.Close()

	for lp.Next() {
		ctx.Count("lines.total", 1)
		header := lp.Header()

		// If the syslog App Name Header field containts what looks like a log token,
		// let's assume it's an override of the id and we're getting the data from the magic
		// channel
		if bytes.HasPrefix(header.Name, TokenPrefix) {
			id = string(header.Name)
		}

		msg := lp.Bytes()
		switch {
		case bytes.Equal(header.Name, Heroku), bytes.HasPrefix(header.Name, TokenPrefix):
			t, e := time.Parse("2006-01-02T15:04:05.000000+00:00", string(lp.Header().Time))
			if e != nil {
				log.Printf("Error Parsing Time(%s): %q\n", string(lp.Header().Time), e)
				continue
			}
			timestamp := t.UnixNano() / int64(time.Microsecond)

			pid := string(header.Procid)
			switch pid {
			case "router":

				switch {
				// router logs with a H error code in them
				case bytes.Contains(msg, keyCodeH):
					ctx.Count("lines.router.error", 1)
					re := routerError{}
					err := logfmt.Unmarshal(msg, &re)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					routerEventPoints <- []interface{}{timestamp, id, re.At, re.Code, re.Desc, re.Method, re.Host, re.Path, re.RequestId, re.Fwd, re.Dyno, re.Connect, re.Service, re.Status, re.Bytes, re.Sock}

				// likely a standard router log
				default:
					ctx.Count("lines.router", 1)
					rm := routerMsg{}
					err := logfmt.Unmarshal(msg, &rm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					routerPoints <- []interface{}{timestamp, id, rm.Bytes, rm.Status, rm.Service, rm.Connect, rm.Dyno, rm.Method, rm.Path, rm.Host, rm.RequestId, rm.Fwd}
				}

				// Non router logs, so either dynos, runtime, etc
			default:
				switch {
				case bytes.HasPrefix(msg, dynoErrorSentinel):
					ctx.Count("lines.dyno.error", 1)
					de, err := parseBytesToDynoError(msg)
					if err != nil {
						log.Printf("Unable to parse dyno error message: %q\n", err)
					}
					dynoEventsPoints <- []interface{}{timestamp, id, string(lp.Header().Procid), "R", de.Code, string(msg)}

				case bytes.Contains(msg, dynoMemMsgSentinel):
					ctx.Count("lines.dyno.mem", 1)
					dm := dynoMemMsg{}
					err := logfmt.Unmarshal(msg, &dm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					if dm.Source != "" {
						dynoMemPoints <- []interface{}{timestamp, id, dm.Source, dm.MemoryCache, dm.MemoryPgpgin, dm.MemoryPgpgout, dm.MemoryRSS, dm.MemorySwap, dm.MemoryTotal}
					}
				case bytes.Contains(msg, dynoLoadMsgSentinel):
					ctx.Count("lines.dyno.load", 1)
					dm := dynoLoadMsg{}
					err := logfmt.Unmarshal(msg, &dm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					if dm.Source != "" {
						dynoLoadPoints <- []interface{}{timestamp, id, dm.Source, dm.LoadAvg1Min, dm.LoadAvg5Min, dm.LoadAvg15Min}
					}
				default: // unknown
					ctx.Count("lines.unknown.heroku", 1)
				}
			}
		default: // non heroku lines
			ctx.Count("lines.unknown.user", 1)
			log.Printf("Unknown User Line - Header: PRI: %s, Time: %s, Hostname: %s, Name: %s, ProcId: %s, MsgId: %s - Body: %s",
				header.PrivalVersion,
				header.Time,
				header.Hostname,
				header.Name,
				header.Procid,
				header.Msgid,
				string(msg),
			)
		}
	}
	ctx.MeasureSince("lines.parse.time", parseStart)

	w.WriteHeader(http.StatusOK)
}
<commit_msg>debug<commit_after>package main

import (
	"bufio"
	"bytes"
	"log"
	"net/http"
	"time"

	"github.com/bmizerany/lpx"
	"github.com/heroku/slog"
	"github.com/kr/logfmt"
)

var (
	TokenPrefix = []byte("t.")
	Heroku      = []byte("heroku")
)

// "Parse tree" from hell
func serveDrain(w http.ResponseWriter, r *http.Request) {
	ctx := slog.Context{}
	defer func() { LogWithContext(ctx) }()

	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
		ctx.Count("errors.drain.wrong.method", 1)
		return
	}

	id := r.Header.Get("Logplex-Drain-Token")

	if id == "" {
		w.WriteHeader(http.StatusBadRequest)
		ctx.Count("errors.drain.missing.token", 1)
		return
	}

	ctx.Count("batch", 1)

	parseStart := time.Now()
	lp := lpx.NewReader(bufio.NewReader(r.Body))
	defer r.Body.Close()

	for lp.Next() {
		ctx.Count("lines.total", 1)
		header := lp.Header()

		// If the syslog App Name Header field containts what looks like a log token,
		// let's assume it's an override of the id and we're getting the data from the magic
		// channel
		if bytes.HasPrefix(header.Name, TokenPrefix) {
			id = string(header.Name)
		}

		msg := lp.Bytes()
		switch {
		case bytes.Equal(header.Name, Heroku), bytes.HasPrefix(header.Name, TokenPrefix):
			t, e := time.Parse("2006-01-02T15:04:05.000000+00:00", string(lp.Header().Time))
			if e != nil {
				log.Printf("Error Parsing Time(%s): %q\n", string(lp.Header().Time), e)
				continue
			}
			timestamp := t.UnixNano() / int64(time.Microsecond)

			pid := string(header.Procid)
			switch pid {
			case "router":

				switch {
				// router logs with a H error code in them
				case bytes.Contains(msg, keyCodeH):
					ctx.Count("lines.router.error", 1)
					re := routerError{}
					err := logfmt.Unmarshal(msg, &re)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					log.Printf("Id: %s\n", id)
					routerEventPoints <- []interface{}{timestamp, id, re.At, re.Code, re.Desc, re.Method, re.Host, re.Path, re.RequestId, re.Fwd, re.Dyno, re.Connect, re.Service, re.Status, re.Bytes, re.Sock}

				// likely a standard router log
				default:
					ctx.Count("lines.router", 1)
					rm := routerMsg{}
					err := logfmt.Unmarshal(msg, &rm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					routerPoints <- []interface{}{timestamp, id, rm.Bytes, rm.Status, rm.Service, rm.Connect, rm.Dyno, rm.Method, rm.Path, rm.Host, rm.RequestId, rm.Fwd}
				}

				// Non router logs, so either dynos, runtime, etc
			default:
				switch {
				case bytes.HasPrefix(msg, dynoErrorSentinel):
					ctx.Count("lines.dyno.error", 1)
					de, err := parseBytesToDynoError(msg)
					if err != nil {
						log.Printf("Unable to parse dyno error message: %q\n", err)
					}
					dynoEventsPoints <- []interface{}{timestamp, id, string(lp.Header().Procid), "R", de.Code, string(msg)}

				case bytes.Contains(msg, dynoMemMsgSentinel):
					ctx.Count("lines.dyno.mem", 1)
					dm := dynoMemMsg{}
					err := logfmt.Unmarshal(msg, &dm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					if dm.Source != "" {
						dynoMemPoints <- []interface{}{timestamp, id, dm.Source, dm.MemoryCache, dm.MemoryPgpgin, dm.MemoryPgpgout, dm.MemoryRSS, dm.MemorySwap, dm.MemoryTotal}
					}
				case bytes.Contains(msg, dynoLoadMsgSentinel):
					ctx.Count("lines.dyno.load", 1)
					dm := dynoLoadMsg{}
					err := logfmt.Unmarshal(msg, &dm)
					if err != nil {
						log.Printf("logfmt unmarshal error: %s\n", err)
						continue
					}
					if dm.Source != "" {
						dynoLoadPoints <- []interface{}{timestamp, id, dm.Source, dm.LoadAvg1Min, dm.LoadAvg5Min, dm.LoadAvg15Min}
					}
				default: // unknown
					ctx.Count("lines.unknown.heroku", 1)
				}
			}
		default: // non heroku lines
			ctx.Count("lines.unknown.user", 1)
			log.Printf("Unknown User Line - Header: PRI: %s, Time: %s, Hostname: %s, Name: %s, ProcId: %s, MsgId: %s - Body: %s",
				header.PrivalVersion,
				header.Time,
				header.Hostname,
				header.Name,
				header.Procid,
				header.Msgid,
				string(msg),
			)
		}
	}
	ctx.MeasureSince("lines.parse.time", parseStart)

	w.WriteHeader(http.StatusOK)
}
<|endoftext|>


<commit_before>package flags

import (
	"reflect"
	"unicode/utf8"
	"unsafe"
)

type scanHandler func(reflect.Value, *reflect.StructField) (bool, error)

func newGroup(shortDescription string, longDescription string, data interface{}) *Group {
	return &Group{
		ShortDescription: shortDescription,
		LongDescription:  longDescription,

		data: data,
	}
}

func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option {
	prio := 0
	var retopt *Option

	for _, opt := range g.options {
		if namematch != nil && namematch(opt, name) && prio < 4 {
			retopt = opt
			prio = 4
		}

		if name == opt.field.Name && prio < 3 {
			retopt = opt
			prio = 3
		}

		if name == opt.LongName && prio < 2 {
			retopt = opt
			prio = 2
		}

		if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 {
			retopt = opt
			prio = 1
		}
	}

	return retopt
}

func (g *Group) storeDefaults() {
	for _, option := range g.options {
		// First. empty out the value
		if len(option.Default) > 0 {
			option.clear()
		}

		for _, d := range option.Default {
			option.set(&d)
		}

		if !option.value.CanSet() {
			continue
		}

		option.defaultValue = reflect.ValueOf(option.value.Interface())
	}
}

func (g *Group) eachGroup(f func(*Group)) {
	f(g)

	for _, gg := range g.groups {
		gg.eachGroup(f)
	}
}

func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error {
	stype := realval.Type()

	if sfield != nil {
		if ok, err := handler(realval, sfield); err != nil {
			return err
		} else if ok {
			return nil
		}
	}

	for i := 0; i < stype.NumField(); i++ {
		field := stype.Field(i)

		// PkgName is set only for non-exported fields, which we ignore
		if field.PkgPath != "" {
			continue
		}

		mtag := newMultiTag(string(field.Tag))

		// Skip fields with the no-flag tag
		if mtag.Get("no-flag") != "" {
			continue
		}

		// Dive deep into structs or pointers to structs
		kind := field.Type.Kind()

		if kind == reflect.Struct {
			return g.scanStruct(realval.Field(i), &field, handler)
		} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct && !realval.Field(i).IsNil() {
			return g.scanStruct(reflect.Indirect(realval.Field(i)), &field, handler)
		}

		longname := mtag.Get("long")
		shortname := mtag.Get("short")

		// Need at least either a short or long name
		if longname == "" && shortname == "" {
			continue
		}

		short := rune(0)
		rc := utf8.RuneCountInString(shortname)

		if rc > 1 {
			return newErrorf(ErrShortNameTooLong,
				"short names can only be 1 character long, not `%s'",
				shortname)

		} else if rc == 1 {
			short, _ = utf8.DecodeRuneInString(shortname)
		}

		description := mtag.Get("description")
		def := mtag.GetMany("default")
		optionalValue := mtag.GetMany("optional-value")
		valueName := mtag.Get("value-name")
		defaultMask := mtag.Get("default-mask")
		ininame := mtag.Get("ini-name")

		optional := (mtag.Get("optional") != "")
		required := (mtag.Get("required") != "")

		option := &Option{
			Description:      description,
			ShortName:        short,
			LongName:         longname,
			Default:          def,
			OptionalArgument: optional,
			OptionalValue:    optionalValue,
			Required:         required,
			ValueName:        valueName,
			DefaultMask:      defaultMask,
			IniName:          ininame,

			field: field,
			value: realval.Field(i),
			tag:   mtag,
		}

		g.options = append(g.options, option)
	}

	return nil
}

func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
	mtag := newMultiTag(string(sfield.Tag))

	subgroup := mtag.Get("group")

	if len(subgroup) != 0 {
		ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr()))
		description := mtag.Get("description")

		if _, err := g.AddGroup(subgroup, description, ptrval.Interface()); err != nil {
			return true, err
		}

		return true, nil
	}

	return false, nil
}

func (g *Group) scanType(handler scanHandler) error {
	// Get all the public fields in the data struct
	ptrval := reflect.ValueOf(g.data)

	if ptrval.Type().Kind() != reflect.Ptr {
		panic(ErrNotPointerToStruct)
	}

	stype := ptrval.Type().Elem()

	if stype.Kind() != reflect.Struct {
		panic(ErrNotPointerToStruct)
	}

	realval := reflect.Indirect(ptrval)

	return g.scanStruct(realval, nil, handler)
}

func (g *Group) scan() error {
	return g.scanType(g.scanSubGroupHandler)
}

func (g *Group) groupByName(name string) *Group {
	if len(name) == 0 {
		return g
	}

	return g.Find(name)
}
<commit_msg>Do not stop scanning after first embedded struct<commit_after>package flags

import (
	"reflect"
	"unicode/utf8"
	"unsafe"
)

type scanHandler func(reflect.Value, *reflect.StructField) (bool, error)

func newGroup(shortDescription string, longDescription string, data interface{}) *Group {
	return &Group{
		ShortDescription: shortDescription,
		LongDescription:  longDescription,

		data: data,
	}
}

func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option {
	prio := 0
	var retopt *Option

	for _, opt := range g.options {
		if namematch != nil && namematch(opt, name) && prio < 4 {
			retopt = opt
			prio = 4
		}

		if name == opt.field.Name && prio < 3 {
			retopt = opt
			prio = 3
		}

		if name == opt.LongName && prio < 2 {
			retopt = opt
			prio = 2
		}

		if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 {
			retopt = opt
			prio = 1
		}
	}

	return retopt
}

func (g *Group) storeDefaults() {
	for _, option := range g.options {
		// First. empty out the value
		if len(option.Default) > 0 {
			option.clear()
		}

		for _, d := range option.Default {
			option.set(&d)
		}

		if !option.value.CanSet() {
			continue
		}

		option.defaultValue = reflect.ValueOf(option.value.Interface())
	}
}

func (g *Group) eachGroup(f func(*Group)) {
	f(g)

	for _, gg := range g.groups {
		gg.eachGroup(f)
	}
}

func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error {
	stype := realval.Type()

	if sfield != nil {
		if ok, err := handler(realval, sfield); err != nil {
			return err
		} else if ok {
			return nil
		}
	}

	for i := 0; i < stype.NumField(); i++ {
		field := stype.Field(i)

		// PkgName is set only for non-exported fields, which we ignore
		if field.PkgPath != "" {
			continue
		}

		mtag := newMultiTag(string(field.Tag))

		// Skip fields with the no-flag tag
		if mtag.Get("no-flag") != "" {
			continue
		}

		// Dive deep into structs or pointers to structs
		kind := field.Type.Kind()
		fld := realval.Field(i)

		if kind == reflect.Struct {
			if err := g.scanStruct(fld, &field, handler); err != nil {
				return err
			}
		} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct && !fld.IsNil() {
			if err := g.scanStruct(reflect.Indirect(fld), &field, handler); err != nil {
				return err
			}
		}

		longname := mtag.Get("long")
		shortname := mtag.Get("short")

		// Need at least either a short or long name
		if longname == "" && shortname == "" {
			continue
		}

		short := rune(0)
		rc := utf8.RuneCountInString(shortname)

		if rc > 1 {
			return newErrorf(ErrShortNameTooLong,
				"short names can only be 1 character long, not `%s'",
				shortname)

		} else if rc == 1 {
			short, _ = utf8.DecodeRuneInString(shortname)
		}

		description := mtag.Get("description")
		def := mtag.GetMany("default")
		optionalValue := mtag.GetMany("optional-value")
		valueName := mtag.Get("value-name")
		defaultMask := mtag.Get("default-mask")
		ininame := mtag.Get("ini-name")

		optional := (mtag.Get("optional") != "")
		required := (mtag.Get("required") != "")

		option := &Option{
			Description:      description,
			ShortName:        short,
			LongName:         longname,
			Default:          def,
			OptionalArgument: optional,
			OptionalValue:    optionalValue,
			Required:         required,
			ValueName:        valueName,
			DefaultMask:      defaultMask,
			IniName:          ininame,

			field: field,
			value: realval.Field(i),
			tag:   mtag,
		}

		g.options = append(g.options, option)
	}

	return nil
}

func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
	mtag := newMultiTag(string(sfield.Tag))

	subgroup := mtag.Get("group")

	if len(subgroup) != 0 {
		ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr()))
		description := mtag.Get("description")

		if _, err := g.AddGroup(subgroup, description, ptrval.Interface()); err != nil {
			return true, err
		}

		return true, nil
	}

	return false, nil
}

func (g *Group) scanType(handler scanHandler) error {
	// Get all the public fields in the data struct
	ptrval := reflect.ValueOf(g.data)

	if ptrval.Type().Kind() != reflect.Ptr {
		panic(ErrNotPointerToStruct)
	}

	stype := ptrval.Type().Elem()

	if stype.Kind() != reflect.Struct {
		panic(ErrNotPointerToStruct)
	}

	realval := reflect.Indirect(ptrval)

	return g.scanStruct(realval, nil, handler)
}

func (g *Group) scan() error {
	return g.scanType(g.scanSubGroupHandler)
}

func (g *Group) groupByName(name string) *Group {
	if len(name) == 0 {
		return g
	}

	return g.Find(name)
}
<|endoftext|>


<commit_before>package rel

type GroupingNode struct {
	Expr []Visitable
	BaseVisitable
}
<commit_msg>Added predications to GroupingNodes<commit_after>package rel

type GroupingNode struct {
	Expr []Visitable
	BaseVisitable
}

func (node GroupingNode) Eq(visitable Visitable) *EqualityNode {
	return predicationEq(node, visitable)
}

func (node GroupingNode) EqAny(visitables ...Visitable) *GroupingNode {
	return predicationEqAny(node, visitables...)
}

func (node GroupingNode) EqAll(visitables ...Visitable) *GroupingNode {
	return predicationEqAll(node, visitables...)
}

func (node GroupingNode) Lt(visitable Visitable) *LessThanNode {
	return predicationLt(node, visitable)
}

func (node GroupingNode) LtAny(visitables ...Visitable) *GroupingNode {
	return predicationLtAny(node, visitables...)
}

func (node GroupingNode) LtAll(visitables ...Visitable) *GroupingNode {
	return predicationLtAll(node, visitables...)
}

func (node GroupingNode) LtEq(v Visitable) *LessThanOrEqualNode {
	return &LessThanOrEqualNode{Left: node, Right: v}
}

func (node GroupingNode) LtEqAny(visitables ...Visitable) *GroupingNode {
	return predicationLtEqAny(node, visitables...)
}

func (node GroupingNode) LtEqAll(visitables ...Visitable) *GroupingNode {
	return predicationLtEqAll(node, visitables...)
}

func (node GroupingNode) Gt(visitable Visitable) *GreaterThanNode {
	return predicationGt(node, visitable)
}

func (node GroupingNode) GtAny(visitables ...Visitable) *GroupingNode {
	return predicationGtAny(node, visitables...)
}

func (node GroupingNode) GtAll(visitables ...Visitable) *GroupingNode {
	return predicationGtAll(node, visitables...)
}

func (node GroupingNode) GtEq(visitable Visitable) *GreaterThanOrEqualNode {
	return predicationGtEq(node, visitable)
}

func (node GroupingNode) GtEqAny(visitables ...Visitable) *GroupingNode {
	return predicationGtEqAny(node, visitables...)
}

func (node GroupingNode) GtEqAll(visitables ...Visitable) *GroupingNode {
	return predicationGtEqAll(node, visitables...)
}

func (node GroupingNode) Desc() *DescendingNode {
	return predicationDesc(node)
}

func (node GroupingNode) Asc() *AscendingNode {
	return predicationAsc(node)
}

func (node GroupingNode) Count() *CountNode {
	return predicationCount(node)
}

func (node GroupingNode) Extract(literal SqlLiteralNode) *ExtractNode {
	return predicationExtract(node, literal)
}

func (node GroupingNode) As(visitable Visitable) *AsNode {
	return predicationAs(node, visitable)
}

func (node GroupingNode) In(visitables []Visitable) Visitable {
	return predicationIn(node, visitables)
}

func (node GroupingNode) InAny(visitableslices ...[]Visitable) Visitable {
	return predicationInAny(node, visitableslices...)
}

func (node GroupingNode) InAll(visitableslices ...[]Visitable) Visitable {
	return predicationInAll(node, visitableslices...)
}

func (node GroupingNode) NotIn(visitables []Visitable) Visitable {
	return predicationNotIn(node, visitables)
}

func (node GroupingNode) NotInAny(visitableslices ...[]Visitable) Visitable {
	return predicationNotInAny(node, visitableslices...)
}

func (node GroupingNode) NotInAll(visitableslices ...[]Visitable) Visitable {
	return predicationNotInAll(node, visitableslices...)
}

func (node GroupingNode) NotEq(visitable Visitable) *NotEqualNode {
	return predicationNotEq(node, visitable)
}

func (node GroupingNode) NotEqAny(visitables ...Visitable) *GroupingNode {
	return predicationNotEqAny(node, visitables...)
}

func (node GroupingNode) NotEqAll(visitables ...Visitable) *GroupingNode {
	return predicationNotEqAll(node, visitables...)
}

func (node GroupingNode) DoesNotMatch(literal SqlLiteralNode) *DoesNotMatchNode {
	return predicationDoesNotMatch(node, literal)
}

func (node GroupingNode) DoesNotMatchAny(literals ...SqlLiteralNode) *GroupingNode {
	return predicationDoesNotMatchAny(node, literals...)
}

func (node GroupingNode) DoesNotMatchAll(literals ...SqlLiteralNode) *GroupingNode {
	return predicationDoesNotMatchAll(node, literals...)
}

func (node GroupingNode) Matches(literal SqlLiteralNode) *MatchesNode {
	return predicationMatches(node, literal)
}

func (node GroupingNode) MatchesAny(literals ...SqlLiteralNode) *GroupingNode {
	return predicationMatchesAny(node, literals...)
}

func (node GroupingNode) MatchesAll(literals ...SqlLiteralNode) *GroupingNode {
	return predicationMatchesAll(node, literals...)
}

func (node GroupingNode) GroupAny(visitables ...Visitable) *GroupingNode {
	return predicationGroupAny(node, visitables...)
}

func (node GroupingNode) GroupAll(visitables ...Visitable) *GroupingNode {
	return predicationGroupAll(node, visitables...)
}
<|endoftext|>


<commit_before>package main

//go:generate go generate github.com/containous/dyngo/stdlib

import (
	"bufio"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/containous/dyngo/interp"
	"github.com/containous/dyngo/stdlib"
)

func main() {
	opt := interp.Opt{Entry: "main"}
	var interactive bool
	flag.BoolVar(&opt.AstDot, "a", false, "display AST graph")
	flag.BoolVar(&opt.CfgDot, "c", false, "display CFG graph")
	flag.BoolVar(&interactive, "i", false, "start an interactive REPL")
	flag.BoolVar(&opt.NoRun, "n", false, "do not run")
	flag.Usage = func() {
		fmt.Println("Usage:", os.Args[0], "[options] [script] [args]")
		fmt.Println("Options:")
		flag.PrintDefaults()
	}
	flag.Parse()
	args := flag.Args()
	log.SetFlags(log.Lshortfile)
	if len(args) > 0 {
		b, err := ioutil.ReadFile(args[0])
		if err != nil {
			log.Fatal("Could not read file: ", args[0])
		}
		s := string(b)
		if s[:2] == "#!" {
			// Allow executable go scripts, but fix them prior to parse
			s = strings.Replace(s, "#!", "//", 1)
		}
		i := interp.New(opt)
		i.Use(stdlib.Value, stdlib.Type)
		i.Use(interp.ExportValue, interp.ExportType)
		if _, err := i.Eval(string(s)); err != nil {
			fmt.Println(err)
		}
		if interactive {
			repl(i)
		}
	} else {
		i := interp.New(opt)
		i.Use(stdlib.Value, stdlib.Type)
		i.Use(interp.ExportValue, interp.ExportType)
		repl(i)
	}
}

func repl(i *interp.Interpreter) {
	s := bufio.NewScanner(os.Stdin)
	prompt := getPrompt()
	prompt()
	for s.Scan() {
		if v, err := i.Eval(s.Text()); err != nil {
			fmt.Println(err)
		} else if v.IsValid() {
			fmt.Println(v)
		}
		prompt()
	}
}

// getPrompt returns a function which prints a prompt only if stdin is a terminal
func getPrompt() func() {
	if stat, err := os.Stdin.Stat(); err == nil && stat.Mode()&os.ModeCharDevice != 0 {
		return func() { fmt.Print("> ") }
	}
	return func() {}
}
<commit_msg>repl: parse multiple line expressions<commit_after>package main

//go:generate go generate github.com/containous/dyngo/stdlib

import (
	"bufio"
	"flag"
	"fmt"
	"go/scanner"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/containous/dyngo/interp"
	"github.com/containous/dyngo/stdlib"
)

func main() {
	opt := interp.Opt{Entry: "main"}
	var interactive bool
	flag.BoolVar(&opt.AstDot, "a", false, "display AST graph")
	flag.BoolVar(&opt.CfgDot, "c", false, "display CFG graph")
	flag.BoolVar(&interactive, "i", false, "start an interactive REPL")
	flag.BoolVar(&opt.NoRun, "n", false, "do not run")
	flag.Usage = func() {
		fmt.Println("Usage:", os.Args[0], "[options] [script] [args]")
		fmt.Println("Options:")
		flag.PrintDefaults()
	}
	flag.Parse()
	args := flag.Args()
	log.SetFlags(log.Lshortfile)
	if len(args) > 0 {
		b, err := ioutil.ReadFile(args[0])
		if err != nil {
			log.Fatal("Could not read file: ", args[0])
		}
		s := string(b)
		if s[:2] == "#!" {
			// Allow executable go scripts, but fix them prior to parse
			s = strings.Replace(s, "#!", "//", 1)
		}
		i := interp.New(opt)
		i.Use(stdlib.Value, stdlib.Type)
		i.Use(interp.ExportValue, interp.ExportType)
		if _, err := i.Eval(string(s)); err != nil {
			fmt.Println(err)
		}
		if interactive {
			repl(i)
		}
	} else {
		i := interp.New(opt)
		i.Use(stdlib.Value, stdlib.Type)
		i.Use(interp.ExportValue, interp.ExportType)
		repl(i)
	}
}

func repl(i *interp.Interpreter) {
	s := bufio.NewScanner(os.Stdin)
	prompt := getPrompt()
	prompt()
	src := ""
	for s.Scan() {
		src += s.Text() + "\n"
		if v, err := i.Eval(src); err != nil {
			switch err.(type) {
			case scanner.ErrorList:
				continue
			}
			fmt.Println(err)
		} else if v.IsValid() {
			fmt.Println(v)
		}
		src = ""
		prompt()
	}
}

// getPrompt returns a function which prints a prompt only if stdin is a terminal
func getPrompt() func() {
	if stat, err := os.Stdin.Stat(); err == nil && stat.Mode()&os.ModeCharDevice != 0 {
		return func() { fmt.Print("> ") }
	}
	return func() {}
}
<|endoftext|>