<commit_before>package server

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/justinas/alice"
	"github.com/rs/zerolog/hlog"
	"golang.org/x/oauth2"

	"github.com/gilcrest/go-api-basic/domain/app"
	"github.com/gilcrest/go-api-basic/domain/audit"
	"github.com/gilcrest/go-api-basic/domain/auth"
	"github.com/gilcrest/go-api-basic/domain/errs"
	"github.com/gilcrest/go-api-basic/domain/user"
	"github.com/gilcrest/go-api-basic/service"
)

const (
	// App ID header key
	appIDHeaderKey string = "X-APP-ID"
	// API key header key
	apiKeyHeaderKey string = "X-API-KEY"
	// Authorization provider header key
	authProviderHeaderKey string = "X-AUTH-PROVIDER"
)

// JSONContentTypeResponseHandler middleware is used to add the
// application/json Content-Type Header for responses
func (s *Server) jsonContentTypeResponseHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			w.Header().Add(contentTypeHeaderKey, appJSONContentTypeHeaderVal)
			h.ServeHTTP(w, r) // call original
		})
}

// appHandler middleware is used to parse the request app id and api key
// from the X-APP-ID and X-API-KEY headers, retrieve and validate
// their veracity, retrieve the App details from the datastore and
// finally set the App to the request context.
func (s *Server) appHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve the context from the http.Request
		ctx := r.Context()

		appExtlID, err := xHeader(defaultRealm, r.Header, appIDHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		apiKey, err := xHeader(defaultRealm, r.Header, apiKeyHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		a, err := s.FindAppService.FindAppByAPIKey(ctx, defaultRealm, appExtlID, apiKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// add access token to context
		ctx = app.CtxWithApp(ctx, a)

		// call original, adding access token to request context
		h.ServeHTTP(w, r.WithContext(ctx))
	})
}

// userHandler middleware is used to parse the request authorization
// provider and authorization headers (X-AUTH-PROVIDER + Authorization),
// retrieve and validate their veracity, retrieve the User details from
// the datastore and finally set the User to the request context.
func (s *Server) userHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve the context from the http.Request
		ctx := r.Context()

		var (
			a     app.App
			u     user.User
			token oauth2.Token
			err   error
		)
		a, err = app.FromRequest(r)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		providerVal, err := xHeader(defaultRealm, r.Header, authProviderHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}
		provider := auth.NewProvider(providerVal)

		token, err = authHeader(defaultRealm, r.Header)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		params := service.FindUserParams{
			Realm:    defaultRealm,
			App:      a,
			Provider: provider,
			Token:    token,
		}

		u, err = s.FindUserService.FindUserByOauth2Token(ctx, params)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// add User to context
		ctx = user.CtxWithUser(ctx, u)

		// call original, adding User to request context
		h.ServeHTTP(w, r.WithContext(ctx))
	})
}

// AuthorizeUserHandler middleware is used authorize a User for a request path and http method
func (s *Server) authorizeUserHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve user from request context
		adt, err := audit.FromRequest(r)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// authorize user can access the path/method
		err = s.AuthorizeService.Authorize(lgr, r, adt)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		h.ServeHTTP(w, r) // call original
	})
}

// LoggerChain returns a middleware chain (via alice.Chain)
// initialized with all the standard middleware handlers for logging. The logger
// will be added to the request context for subsequent use with pre-populated
// fields, including the request method, url, status, size, duration, remote IP,
// user agent, referer. A unique Request ID is also added to the logger, context
// and response headers.
func (s *Server) loggerChain() alice.Chain {
	ac := alice.New(hlog.NewHandler(s.Logger),
		hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
			hlog.FromRequest(r).Info().
				Str("method", r.Method).
				Stringer("url", r.URL).
				Int("status", status).
				Int("size", size).
				Dur("duration", duration).
				Msg("request logged")
		}),
		hlog.RemoteAddrHandler("remote_ip"),
		hlog.UserAgentHandler("user_agent"),
		hlog.RefererHandler("referer"),
		hlog.RequestIDHandler("request_id", "Request-Id"),
	)

	return ac
}

// xHeader parses and returns the header value given the key. It is
// used to validate various header values as part of authentication
func xHeader(realm string, header http.Header, key string) (v string, err error) {
	// Pull the header value from the Header map given the key
	headerValue, ok := header[http.CanonicalHeaderKey(key)]
	if !ok {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("unauthenticated: no %s header sent", key))

	}

	// too many values sent - should only be one value
	if len(headerValue) > 1 {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("%s header value > 1", key))
	}

	// retrieve header value from map
	v = headerValue[0]

	// remove all leading/trailing white space
	v = strings.TrimSpace(v)

	// should not be empty
	if v == "" {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("unauthenticated: %s header value not found", key))
	}

	return
}

// authHeader parses/validates the Authorization header and returns an Oauth2 token
func authHeader(realm string, header http.Header) (oauth2.Token, error) {
	// Pull the token from the Authorization header by retrieving the
	// value from the Header map with "Authorization" as the key
	//
	// format: Authorization: Bearer
	headerValue, ok := header["Authorization"]
	if !ok {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: no Authorization header sent")
	}

	// too many values sent - spec allows for only one token
	if len(headerValue) > 1 {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "header value > 1")
	}

	// retrieve token from map
	token := headerValue[0]

	// Oauth2 should have "Bearer " as the prefix as the authentication scheme
	hasBearer := strings.HasPrefix(token, auth.BearerTokenType+" ")
	if !hasBearer {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: Bearer authentication scheme not found")
	}

	// remove "Bearer " authentication scheme from header value
	token = strings.TrimPrefix(token, auth.BearerTokenType+" ")

	// remove all leading/trailing white space
	token = strings.TrimSpace(token)

	// token should not be empty
	if token == "" {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: Authorization header sent with Bearer scheme, but no token found")
	}

	return oauth2.Token{AccessToken: token, TokenType: auth.BearerTokenType}, nil
}
<commit_msg>comment casing updates<commit_after>package server

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/justinas/alice"
	"github.com/rs/zerolog/hlog"
	"golang.org/x/oauth2"

	"github.com/gilcrest/go-api-basic/domain/app"
	"github.com/gilcrest/go-api-basic/domain/audit"
	"github.com/gilcrest/go-api-basic/domain/auth"
	"github.com/gilcrest/go-api-basic/domain/errs"
	"github.com/gilcrest/go-api-basic/domain/user"
	"github.com/gilcrest/go-api-basic/service"
)

const (
	// App ID header key
	appIDHeaderKey string = "X-APP-ID"
	// API key header key
	apiKeyHeaderKey string = "X-API-KEY"
	// Authorization provider header key
	authProviderHeaderKey string = "X-AUTH-PROVIDER"
)

// jsonContentTypeResponseHandler middleware is used to add the
// application/json Content-Type Header for responses
func (s *Server) jsonContentTypeResponseHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			w.Header().Add(contentTypeHeaderKey, appJSONContentTypeHeaderVal)
			h.ServeHTTP(w, r) // call original
		})
}

// appHandler middleware is used to parse the request app id and api key
// from the X-APP-ID and X-API-KEY headers, retrieve and validate
// their veracity, retrieve the App details from the datastore and
// finally set the App to the request context.
func (s *Server) appHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve the context from the http.Request
		ctx := r.Context()

		appExtlID, err := xHeader(defaultRealm, r.Header, appIDHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		apiKey, err := xHeader(defaultRealm, r.Header, apiKeyHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		a, err := s.FindAppService.FindAppByAPIKey(ctx, defaultRealm, appExtlID, apiKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// add access token to context
		ctx = app.CtxWithApp(ctx, a)

		// call original, adding access token to request context
		h.ServeHTTP(w, r.WithContext(ctx))
	})
}

// userHandler middleware is used to parse the request authorization
// provider and authorization headers (X-AUTH-PROVIDER + Authorization),
// retrieve and validate their veracity, retrieve the User details from
// the datastore and finally set the User to the request context.
func (s *Server) userHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve the context from the http.Request
		ctx := r.Context()

		var (
			a     app.App
			u     user.User
			token oauth2.Token
			err   error
		)
		a, err = app.FromRequest(r)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		providerVal, err := xHeader(defaultRealm, r.Header, authProviderHeaderKey)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}
		provider := auth.NewProvider(providerVal)

		token, err = authHeader(defaultRealm, r.Header)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		params := service.FindUserParams{
			Realm:    defaultRealm,
			App:      a,
			Provider: provider,
			Token:    token,
		}

		u, err = s.FindUserService.FindUserByOauth2Token(ctx, params)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// add User to context
		ctx = user.CtxWithUser(ctx, u)

		// call original, adding User to request context
		h.ServeHTTP(w, r.WithContext(ctx))
	})
}

// authorizeUserHandler middleware is used authorize a User for a request path and http method
func (s *Server) authorizeUserHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		lgr := *hlog.FromRequest(r)

		// retrieve user from request context
		adt, err := audit.FromRequest(r)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		// authorize user can access the path/method
		err = s.AuthorizeService.Authorize(lgr, r, adt)
		if err != nil {
			errs.HTTPErrorResponse(w, lgr, err)
			return
		}

		h.ServeHTTP(w, r) // call original
	})
}

// LoggerChain returns a middleware chain (via alice.Chain)
// initialized with all the standard middleware handlers for logging. The logger
// will be added to the request context for subsequent use with pre-populated
// fields, including the request method, url, status, size, duration, remote IP,
// user agent, referer. A unique Request ID is also added to the logger, context
// and response headers.
func (s *Server) loggerChain() alice.Chain {
	ac := alice.New(hlog.NewHandler(s.Logger),
		hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
			hlog.FromRequest(r).Info().
				Str("method", r.Method).
				Stringer("url", r.URL).
				Int("status", status).
				Int("size", size).
				Dur("duration", duration).
				Msg("request logged")
		}),
		hlog.RemoteAddrHandler("remote_ip"),
		hlog.UserAgentHandler("user_agent"),
		hlog.RefererHandler("referer"),
		hlog.RequestIDHandler("request_id", "Request-Id"),
	)

	return ac
}

// xHeader parses and returns the header value given the key. It is
// used to validate various header values as part of authentication
func xHeader(realm string, header http.Header, key string) (v string, err error) {
	// Pull the header value from the Header map given the key
	headerValue, ok := header[http.CanonicalHeaderKey(key)]
	if !ok {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("unauthenticated: no %s header sent", key))

	}

	// too many values sent - should only be one value
	if len(headerValue) > 1 {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("%s header value > 1", key))
	}

	// retrieve header value from map
	v = headerValue[0]

	// remove all leading/trailing white space
	v = strings.TrimSpace(v)

	// should not be empty
	if v == "" {
		return "", errs.E(errs.Unauthenticated, errs.Realm(realm), fmt.Sprintf("unauthenticated: %s header value not found", key))
	}

	return
}

// authHeader parses/validates the Authorization header and returns an Oauth2 token
func authHeader(realm string, header http.Header) (oauth2.Token, error) {
	// Pull the token from the Authorization header by retrieving the
	// value from the Header map with "Authorization" as the key
	//
	// format: Authorization: Bearer
	headerValue, ok := header["Authorization"]
	if !ok {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: no Authorization header sent")
	}

	// too many values sent - spec allows for only one token
	if len(headerValue) > 1 {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "header value > 1")
	}

	// retrieve token from map
	token := headerValue[0]

	// Oauth2 should have "Bearer " as the prefix as the authentication scheme
	hasBearer := strings.HasPrefix(token, auth.BearerTokenType+" ")
	if !hasBearer {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: Bearer authentication scheme not found")
	}

	// remove "Bearer " authentication scheme from header value
	token = strings.TrimPrefix(token, auth.BearerTokenType+" ")

	// remove all leading/trailing white space
	token = strings.TrimSpace(token)

	// token should not be empty
	if token == "" {
		return oauth2.Token{}, errs.E(errs.Unauthenticated, errs.Realm(realm), "unauthenticated: Authorization header sent with Bearer scheme, but no token found")
	}

	return oauth2.Token{AccessToken: token, TokenType: auth.BearerTokenType}, nil
}
<|endoftext|>


<commit_before>package io

import (
	"bufio"
	"io/ioutil"
	"os"
	"path/filepath"
)

//	写文件
func WriteLines(filePath string, lines []string) error {

	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	for _, line := range lines {

		//	将股价写入文件
		_, err = file.WriteString(line)
		if err != nil {
			return err
		}
	}

	return nil
}

//	写入字符串
func WriteString(filePath, content string) error {

	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.WriteString(content)

	return err
}

//	写入缓冲区
func WriteBytes(filePath string, buffer []byte) error {
	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.Write(buffer)

	return err
}

//	打开文件
func openForWrite(filePath string) (*os.File, error) {
	//	检查文件所处目录是否存在
	fileDir := filepath.Dir(filePath)
	_, err := os.Stat(fileDir)
	if os.IsNotExist(err) {
		//	如果不存在就先创建目录
		err = os.Mkdir(fileDir, 0660)
		if err != nil {
			return nil, err
		}
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0660)
}

//	打开文件
func openForRead(filePath string) (*os.File, error) {
	//	检查文件
	_, err := os.Stat(filePath)
	if err != nil {
		return nil, err
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_RDONLY, 0660)
}

//	读取文件
func ReadLines(filePath string) ([]string, error) {
	//	打开文件
	file, err := openForRead(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	//	读取
	scanner := bufio.NewScanner(file)
	lines := make([]string, 0)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}

	return lines, scanner.Err()
}

//	读取所有
func ReadAllBytes(filePath string) ([]byte, error) {
	//	打开文件
	file, err := openForRead(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}

//	读取所有
func ReadAllString(filePath string) (string, error) {
	buffer, err := ReadAllBytes(filePath)
	if err != nil {
		return "", err
	}

	return string(buffer), nil
}
<commit_msg>写入多行时，自动在每行后面加入换行符<commit_after>package io

import (
	"bufio"
	"io/ioutil"
	"os"
	"path/filepath"
)

//	写文件
func WriteLines(filePath string, lines []string) error {

	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	for _, line := range lines {

		//	将字符串写入文件
		_, err = file.WriteString(line + "\n")
		if err != nil {
			return err
		}
	}

	return nil
}

//	写入字符串
func WriteString(filePath, content string) error {

	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.WriteString(content)

	return err
}

//	写入缓冲区
func WriteBytes(filePath string, buffer []byte) error {
	//	打开文件
	file, err := openForWrite(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.Write(buffer)

	return err
}

//	打开文件
func openForWrite(filePath string) (*os.File, error) {
	//	检查文件所处目录是否存在
	fileDir := filepath.Dir(filePath)
	_, err := os.Stat(fileDir)
	if os.IsNotExist(err) {
		//	如果不存在就先创建目录
		err = os.Mkdir(fileDir, 0660)
		if err != nil {
			return nil, err
		}
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0660)
}

//	打开文件
func openForRead(filePath string) (*os.File, error) {
	//	检查文件
	_, err := os.Stat(filePath)
	if err != nil {
		return nil, err
	}

	//	打开文件
	return os.OpenFile(filePath, os.O_RDONLY, 0660)
}

//	读取文件
func ReadLines(filePath string) ([]string, error) {
	//	打开文件
	file, err := openForRead(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	//	读取
	scanner := bufio.NewScanner(file)
	lines := make([]string, 0)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}

	return lines, scanner.Err()
}

//	读取所有
func ReadAllBytes(filePath string) ([]byte, error) {
	//	打开文件
	file, err := openForRead(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}

//	读取所有
func ReadAllString(filePath string) (string, error) {
	buffer, err := ReadAllBytes(filePath)
	if err != nil {
		return "", err
	}

	return string(buffer), nil
}
<|endoftext|>


<commit_before>package finalize

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/kr/text"

	"github.com/cloudfoundry/libbuildpack"
)

type Manifest interface {
	RootDir() string
}

type Stager interface {
	BuildDir() string
	DepDir() string
	DepsIdx() string
	WriteProfileD(string, string) error
}

type Command interface {
	Execute(string, io.Writer, io.Writer, string, ...string) error
	Output(dir string, program string, args ...string) (string, error)
}

type ManagePyFinder interface {
	FindManagePy(dir string) (string, error)
}

type Reqs interface {
	FindAnyPackage(buildDir string, searchedPackages ...string) (bool, error)
	FindStalePackages(oldRequirementsPath, newRequirementsPath string, excludedPackages ...string) ([]string, error)
}

type Finalizer struct {
	Stager         Stager
	Log            *libbuildpack.Logger
	Logfile        *os.File
	Manifest       Manifest
	Command        Command
	ManagePyFinder ManagePyFinder
	Requirements   Reqs
}

func Run(f *Finalizer) error {

	if err := f.HandleCollectstatic(); err != nil {
		f.Log.Error("Error handling collectstatic: %v", err)
		return err
	}

	if err := f.ReplaceDepsDirWithLiteral(); err != nil {
		f.Log.Error("Error replacing depsDir with literal: %v", err)
		return err
	}

	if err := f.ReplaceLiteralWithDepsDirAtRuntime(); err != nil {
		f.Log.Error("Error replacing literal with depsDir: %v", err)
		return err
	}

	return nil
}

func (f *Finalizer) HandleCollectstatic() error {
	if len(os.Getenv("DISABLE_COLLECTSTATIC")) > 0 {
		return nil
	}

	exists, err := f.Requirements.FindAnyPackage(f.Stager.BuildDir(), "django", "Django")
	if err != nil {
		return err
	}

	if !exists {
		return nil
	}

	managePyPath, err := f.ManagePyFinder.FindManagePy(f.Stager.BuildDir())
	if err != nil {
		return err
	}

	f.Log.Info("Running python %s collectstatic --noinput --traceback", managePyPath)
	output := new(bytes.Buffer)
	if err = f.Command.Execute(f.Stager.BuildDir(), output, text.NewIndentWriter(os.Stderr, []byte("       ")), "python", managePyPath, "collectstatic", "--noinput", "--traceback"); err != nil {
		f.Log.Error(fmt.Sprintf(` !     Error while running '$ python %s collectstatic --noinput'.
       See traceback above for details.

       You may need to update application code to resolve this error.
       Or, you can disable collectstatic for this application:

          $ cf set-env <app> DISABLE_COLLECTSTATIC 1

       https://devcenter.heroku.com/articles/django-assets`, managePyPath))
		return err
	}

	writeFilteredCollectstaticOutput(output)

	return nil
}

func writeFilteredCollectstaticOutput(output *bytes.Buffer) {
	buffer := new(bytes.Buffer)
	r := regexp.MustCompile("^(Copying |Post-processed ).*$")
	lines := strings.Split(output.String(), "\n")
	for _, line := range lines {
		if len(line) > 0 && !r.MatchString(line) {
			buffer.WriteString(line)
			buffer.WriteString("\n")
		}
	}
	os.Stdout.Write(buffer.Bytes())
}

func (f *Finalizer) ReplaceDepsDirWithLiteral() error {
	dirs, err := filepath.Glob(filepath.Join(f.Stager.DepDir(), "python", "lib", "python*"))
	if err != nil {
		return err
	}

	for _, dir := range dirs {
		if err := filepath.Walk(dir, func(path string, _ os.FileInfo, _ error) error {
			if strings.HasSuffix(path, ".pth") {
				fileContents, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}

				fileContents = []byte(strings.Replace(string(fileContents), f.Stager.DepDir(), "DOLLAR_DEPS_DIR/"+f.Stager.DepsIdx(), -1))

				if err := ioutil.WriteFile(path, fileContents, 0644); err != nil {
					return err
				}
			}
			return nil
		}); err != nil {
			return err
		}
	}

	return nil
}

func (f *Finalizer) ReplaceLiteralWithDepsDirAtRuntime() error {
	scriptContents := `find $DEPS_DIR/%s/python/lib/python*/  -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#DOLLAR_DEPS_DIR#$DEPS_DIR#" &> /dev/null` + "\n"
	return f.Stager.WriteProfileD("python.fixeggs.sh", fmt.Sprintf(scriptContents, f.Stager.DepsIdx()))
}
<commit_msg>Add Debug logging for collectstatic (#531)<commit_after>package finalize

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/kr/text"

	"github.com/cloudfoundry/libbuildpack"
)

type Manifest interface {
	RootDir() string
}

type Stager interface {
	BuildDir() string
	DepDir() string
	DepsIdx() string
	WriteProfileD(string, string) error
}

type Command interface {
	Execute(string, io.Writer, io.Writer, string, ...string) error
	Output(dir string, program string, args ...string) (string, error)
}

type ManagePyFinder interface {
	FindManagePy(dir string) (string, error)
}

type Reqs interface {
	FindAnyPackage(buildDir string, searchedPackages ...string) (bool, error)
	FindStalePackages(oldRequirementsPath, newRequirementsPath string, excludedPackages ...string) ([]string, error)
}

type Finalizer struct {
	Stager         Stager
	Log            *libbuildpack.Logger
	Logfile        *os.File
	Manifest       Manifest
	Command        Command
	ManagePyFinder ManagePyFinder
	Requirements   Reqs
}

func Run(f *Finalizer) error {

	if err := f.HandleCollectstatic(); err != nil {
		f.Log.Error("Error handling collectstatic: %v", err)
		return err
	}

	if err := f.ReplaceDepsDirWithLiteral(); err != nil {
		f.Log.Error("Error replacing depsDir with literal: %v", err)
		return err
	}

	if err := f.ReplaceLiteralWithDepsDirAtRuntime(); err != nil {
		f.Log.Error("Error replacing literal with depsDir: %v", err)
		return err
	}

	return nil
}

func (f *Finalizer) HandleCollectstatic() error {
	if len(os.Getenv("DISABLE_COLLECTSTATIC")) > 0 {
        f.Log.Debug("DISABLE_COLLECTSTATIC > 0, skipping collectstatic")
		return nil
	}

	exists, err := f.Requirements.FindAnyPackage(f.Stager.BuildDir(), "django", "Django")
	if err != nil {
        f.Log.Debug("Error during FindAnyPackage, skipping collectstatic")
		return err
	}

	if !exists {
        f.Log.Debug("Django not in requirements, skipping collectstatic")
		return nil
	}

	managePyPath, err := f.ManagePyFinder.FindManagePy(f.Stager.BuildDir())
	if err != nil {
        f.Log.Debug("Error finding manage.py, skipping collectstatic")
		return err
	}

	f.Log.Info("Running python %s collectstatic --noinput --traceback", managePyPath)
	output := new(bytes.Buffer)
	if err = f.Command.Execute(f.Stager.BuildDir(), output, text.NewIndentWriter(os.Stderr, []byte("       ")), "python", managePyPath, "collectstatic", "--noinput", "--traceback"); err != nil {
		f.Log.Error(fmt.Sprintf(` !     Error while running '$ python %s collectstatic --noinput'.
       See traceback above for details.

       You may need to update application code to resolve this error.
       Or, you can disable collectstatic for this application:

          $ cf set-env <app> DISABLE_COLLECTSTATIC 1

       https://devcenter.heroku.com/articles/django-assets`, managePyPath))
		return err
	}

	writeFilteredCollectstaticOutput(output)

	return nil
}

func writeFilteredCollectstaticOutput(output *bytes.Buffer) {
	buffer := new(bytes.Buffer)
	r := regexp.MustCompile("^(Copying |Post-processed ).*$")
	lines := strings.Split(output.String(), "\n")
	for _, line := range lines {
		if len(line) > 0 && !r.MatchString(line) {
			buffer.WriteString(line)
			buffer.WriteString("\n")
		}
	}
	os.Stdout.Write(buffer.Bytes())
}

func (f *Finalizer) ReplaceDepsDirWithLiteral() error {
	dirs, err := filepath.Glob(filepath.Join(f.Stager.DepDir(), "python", "lib", "python*"))
	if err != nil {
		return err
	}

	for _, dir := range dirs {
		if err := filepath.Walk(dir, func(path string, _ os.FileInfo, _ error) error {
			if strings.HasSuffix(path, ".pth") {
				fileContents, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}

				fileContents = []byte(strings.Replace(string(fileContents), f.Stager.DepDir(), "DOLLAR_DEPS_DIR/"+f.Stager.DepsIdx(), -1))

				if err := ioutil.WriteFile(path, fileContents, 0644); err != nil {
					return err
				}
			}
			return nil
		}); err != nil {
			return err
		}
	}

	return nil
}

func (f *Finalizer) ReplaceLiteralWithDepsDirAtRuntime() error {
	scriptContents := `find $DEPS_DIR/%s/python/lib/python*/  -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#DOLLAR_DEPS_DIR#$DEPS_DIR#" &> /dev/null` + "\n"
	return f.Stager.WriteProfileD("python.fixeggs.sh", fmt.Sprintf(scriptContents, f.Stager.DepsIdx()))
}
<|endoftext|>


<commit_before>package core

import (
	"errors"
	"fmt"
	"github.com/MG-RAST/AWE/lib/conf"
	"github.com/MG-RAST/AWE/lib/db"
	"github.com/MG-RAST/golib/mgo"
	"github.com/MG-RAST/golib/mgo/bson"
)

func InitJobDB() {
	session := db.Connection.Session.Copy()
	defer session.Close()
	cj := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	cj.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"jid"}, Background: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"updatetime"}, Background: true})
	cp := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
	cp.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
}

func InitClientGroupDB() {
	session := db.Connection.Session.Copy()
	defer session.Close()
	cc := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	cc.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
	cc.EnsureIndex(mgo.Index{Key: []string{"name"}, Unique: true})
	cc.EnsureIndex(mgo.Index{Key: []string{"token"}, Unique: true})
}

func dbDelete(q bson.M, coll string) (err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(coll)
	_, err = c.RemoveAll(q)
	return
}

func dbUpsert(t interface{}) (err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	switch t := t.(type) {
	case *Job:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	case *JobPerf:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	case *ClientGroup:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	default:
		fmt.Printf("invalid database entry type\n")
	}
	return
}

func dbFind(q bson.M, results *Jobs, options map[string]int) (count int, err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}
	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Limit(limit).Skip(offset).All(results)
			return
		} else {
			return 0, errors.New("store.db.Find options limit and offset must be used together")
		}
	}
	err = query.All(results)
	return
}

func dbFindSort(q bson.M, results *Jobs, options map[string]int, sortby string) (count int, err error) {
	if sortby == "" {
		return 0, errors.New("sortby must be an nonempty string")
	}
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}

	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Sort(sortby).Limit(limit).Skip(offset).All(results)
			return
		}
	}
	err = query.Sort(sortby).All(results)
	return
}

func dbFindClientGroups(q bson.M, results *ClientGroups) (count int, err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}
	err = query.All(results)
	return
}

func dbFindSortClientGroups(q bson.M, results *ClientGroups, options map[string]int, sortby string) (count int, err error) {
	if sortby == "" {
		return 0, errors.New("sortby must be an nonempty string")
	}
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}

	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Sort(sortby).Limit(limit).Skip(offset).All(results)
			return
		}
	}
	err = query.Sort(sortby).All(results)
	return
}

func LoadJob(id string) (job *Job, err error) {
	job = new(Job)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	if err = c.Find(bson.M{"id": id}).One(&job); err == nil {
		return job, nil
	}
	return nil, err
}

func LoadJobPerf(id string) (perf *JobPerf, err error) {
	perf = new(JobPerf)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
	if err = c.Find(bson.M{"id": id}).One(&perf); err == nil {
		return perf, nil
	}
	return nil, err
}

func LoadClientGroup(id string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"id": id}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func LoadClientGroupByName(name string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"name": name}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func LoadClientGroupByToken(token string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"token": token}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func DeleteClientGroup(id string) (err error) {
	err = dbDelete(bson.M{"id": id}, conf.DB_COLL_CGS)
	return
}
<commit_msg>Added mongo indexes for commonly queried fields.<commit_after>package core

import (
	"errors"
	"fmt"
	"github.com/MG-RAST/AWE/lib/conf"
	"github.com/MG-RAST/AWE/lib/db"
	"github.com/MG-RAST/golib/mgo"
	"github.com/MG-RAST/golib/mgo/bson"
)

func InitJobDB() {
	session := db.Connection.Session.Copy()
	defer session.Close()
	cj := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	cj.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"jid"}, Background: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"state"}, Background: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"updatetime"}, Background: true})
	cj.EnsureIndex(mgo.Index{Key: []string{"info.submittime"}, Background: true})
	cp := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
	cp.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
}

func InitClientGroupDB() {
	session := db.Connection.Session.Copy()
	defer session.Close()
	cc := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	cc.EnsureIndex(mgo.Index{Key: []string{"id"}, Unique: true})
	cc.EnsureIndex(mgo.Index{Key: []string{"name"}, Unique: true})
	cc.EnsureIndex(mgo.Index{Key: []string{"token"}, Unique: true})
}

func dbDelete(q bson.M, coll string) (err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(coll)
	_, err = c.RemoveAll(q)
	return
}

func dbUpsert(t interface{}) (err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	switch t := t.(type) {
	case *Job:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	case *JobPerf:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	case *ClientGroup:
		c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
		_, err = c.Upsert(bson.M{"id": t.Id}, &t)
	default:
		fmt.Printf("invalid database entry type\n")
	}
	return
}

func dbFind(q bson.M, results *Jobs, options map[string]int) (count int, err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}
	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Limit(limit).Skip(offset).All(results)
			return
		} else {
			return 0, errors.New("store.db.Find options limit and offset must be used together")
		}
	}
	err = query.All(results)
	return
}

func dbFindSort(q bson.M, results *Jobs, options map[string]int, sortby string) (count int, err error) {
	if sortby == "" {
		return 0, errors.New("sortby must be an nonempty string")
	}
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}

	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Sort(sortby).Limit(limit).Skip(offset).All(results)
			return
		}
	}
	err = query.Sort(sortby).All(results)
	return
}

func dbFindClientGroups(q bson.M, results *ClientGroups) (count int, err error) {
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}
	err = query.All(results)
	return
}

func dbFindSortClientGroups(q bson.M, results *ClientGroups, options map[string]int, sortby string) (count int, err error) {
	if sortby == "" {
		return 0, errors.New("sortby must be an nonempty string")
	}
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	query := c.Find(q)
	if count, err = query.Count(); err != nil {
		return 0, err
	}

	if limit, has := options["limit"]; has {
		if offset, has := options["offset"]; has {
			err = query.Sort(sortby).Limit(limit).Skip(offset).All(results)
			return
		}
	}
	err = query.Sort(sortby).All(results)
	return
}

func LoadJob(id string) (job *Job, err error) {
	job = new(Job)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_JOBS)
	if err = c.Find(bson.M{"id": id}).One(&job); err == nil {
		return job, nil
	}
	return nil, err
}

func LoadJobPerf(id string) (perf *JobPerf, err error) {
	perf = new(JobPerf)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_PERF)
	if err = c.Find(bson.M{"id": id}).One(&perf); err == nil {
		return perf, nil
	}
	return nil, err
}

func LoadClientGroup(id string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"id": id}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func LoadClientGroupByName(name string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"name": name}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func LoadClientGroupByToken(token string) (clientgroup *ClientGroup, err error) {
	clientgroup = new(ClientGroup)
	session := db.Connection.Session.Copy()
	defer session.Close()
	c := session.DB(conf.MONGODB_DATABASE).C(conf.DB_COLL_CGS)
	if err = c.Find(bson.M{"token": token}).One(&clientgroup); err == nil {
		return clientgroup, nil
	}
	return nil, err
}

func DeleteClientGroup(id string) (err error) {
	err = dbDelete(bson.M{"id": id}, conf.DB_COLL_CGS)
	return
}
<|endoftext|>


<commit_before>package jas

import (
	"encoding/json"
	"io"
	"log"
	"net/http"

	"github.com/google/go-github/github"
)

// Handler handler is an interface that objects can implement to be registered
// to get called on incoming webhook payloads.
//
// Each handler will have its HandlePayload method called in the order
// registered.
type Handler interface {
	HandlePayload(e []string, p *github.WebHookPayload)
}

// HandlerFunc is an adapter to allow the use of ordinary functions as Jas
// handlers. If f is a function with the appropriate signature, HandlerFunc(f)
// is a Handler object that calls f.
type HandlerFunc func(e []string, p *github.WebHookPayload)

func (h HandlerFunc) HandlePayload(e []string, p *github.WebHookPayload) {
	h(e, p)
}

// Jas is a stack of Handlers that can be invoked as a Handler. Jas
// handlers are evaluated in the order that they are added to the stack using
// the Register and RegisterHandler methods.
type Jas struct {
	handlers []Handler
}

// New returns a new Jas instance with no handlers preconfigured.
func NewJas() *Jas {
	return &Jas{}
}

// RegisteHandlerr adds a Handler onto the handlers stack. Handlers are
// invoked in the order they are added.
func (j *Jas) RegisterHandler(handler Handler) {
	j.handlers = append(j.handlers, handler)
}

// RegisterHandlerFunc adds a HandlerFunc onto the handlers stack. Handlers are
// invoked in the order they are added to a Negroni.
func (j *Jas) RegisterHandlerFunc(handler HandlerFunc) {
	j.RegisterHandler(HandlerFunc(handler))
}

func (j *Jas) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	e := r.Header["X-Github-Event"]
	if e == nil {
		log.Println("Body had no X-Github-Event")
	} else {

		payload, err := githubWebhookDecoder(&r.Body)
		if err != nil {
			log.Println(err)
		}

		for _, handler := range j.handlers {
			handler.HandlePayload(e, payload)
		}
	}
}

// githubWebhookDecoder decodes the payload into a github.WebHookPayload
func githubWebhookDecoder(body *io.ReadCloser) (*github.WebHookPayload, error) {
	var payload github.WebHookPayload
	decoder := json.NewDecoder(*body)
	err := decoder.Decode(&payload)

	if err != nil {
		return nil, err
	}

	return &payload, nil
}
<commit_msg>HandlerFunc comment was incorrect<commit_after>package jas

import (
	"encoding/json"
	"io"
	"log"
	"net/http"

	"github.com/google/go-github/github"
)

// Handler handler is an interface that objects can implement to be registered
// to get called on incoming webhook payloads.
//
// Each handler will have its HandlePayload method called in the order
// registered.
type Handler interface {
	HandlePayload(e []string, p *github.WebHookPayload)
}

// HandlerFunc is an adapter to allow the use of ordinary functions as Jas
// handlers. If f is a function with the appropriate signature, HandlerFunc(f)
// is a Handler object who's HandlePayload method calls f.
type HandlerFunc func(e []string, p *github.WebHookPayload)

func (h HandlerFunc) HandlePayload(e []string, p *github.WebHookPayload) {
	h(e, p)
}

// Jas is a stack of Handlers that can be invoked as a Handler. Jas
// handlers are evaluated in the order that they are added to the stack using
// the Register and RegisterHandler methods.
type Jas struct {
	handlers []Handler
}

// New returns a new Jas instance with no handlers preconfigured.
func NewJas() *Jas {
	return &Jas{}
}

// RegisteHandlerr adds a Handler onto the handlers stack. Handlers are
// invoked in the order they are added.
func (j *Jas) RegisterHandler(handler Handler) {
	j.handlers = append(j.handlers, handler)
}

// RegisterHandlerFunc adds a HandlerFunc onto the handlers stack. Handlers are
// invoked in the order they are added to a Negroni.
func (j *Jas) RegisterHandlerFunc(handler HandlerFunc) {
	j.RegisterHandler(HandlerFunc(handler))
}

func (j *Jas) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	e := r.Header["X-Github-Event"]
	if e == nil {
		log.Println("Body had no X-Github-Event")
	} else {

		payload, err := githubWebhookDecoder(&r.Body)
		if err != nil {
			log.Println(err)
		}

		for _, handler := range j.handlers {
			handler.HandlePayload(e, payload)
		}
	}
}

// githubWebhookDecoder decodes the payload into a github.WebHookPayload
func githubWebhookDecoder(body *io.ReadCloser) (*github.WebHookPayload, error) {
	var payload github.WebHookPayload
	decoder := json.NewDecoder(*body)
	err := decoder.Decode(&payload)

	if err != nil {
		return nil, err
	}

	return &payload, nil
}
<|endoftext|>


<commit_before>package api

type NewRequest struct {
	Uids    []int `json:"uids"`
	Debug   int   `json:"debug"`
	WorldId int   `json:"worldId"`
}

type NewResponse struct {
	Uids  []int `json:"uids"`
	Debug int   `json:"debug"`
}

type ViewWorldRequest struct {
}

type ViewWorldResponse struct {
	TerrainResponse ViewTerrainResponse
	UnitsResponse   ViewUnitsResponse
	PlayersResponse ViewPlayersResponse
}

type ViewTerrainRequest struct {
}

type ViewTerrainResponse struct {
	Terrain [][]int `json:"terrain"`
}

type ViewUnitsRequest struct {
}

type ViewUnitsResponse struct {
	Units []*UnitStruct `json:"units"`
}

type ViewPlayersRequest struct {
}

type ViewPlayersResponse struct {
	Me        *PlayerStruct   `json:"me"`
	TeamMates []*PlayerStruct `json:"teamMates"`
	Enemies   []*PlayerStruct `json:"enemies"`
	TurnOwner int             `json:"turnOwner"`
}

type MoveRequest struct {
	Move []LocationStruct `json:"move"`
}

type MoveResponse struct {
	Move []LocationStruct `json:"move"`
}

type AttackRequest struct {
	Attacker    LocationStruct `json:"attacker"`
	AttackIndex int            `json:"attackIndex"`
	Target      LocationStruct `json:"target"`
}

type AttackResponse struct {
	Attacker    LocationStruct `json:"attacker"`
	AttackIndex int            `json:"attackIndex"`
	Target      LocationStruct `json:"target"`
}

type EndTurnRequest struct {
}

type EndTurnResponse struct {
}

type ExitRequest struct {
	Reason string `json:"reason"`
}

type PlayerStruct struct {
	Nation int `json:"nation"`
	Team   int `json:"team"`
}

type UnitStruct struct {
	Name      string          `json:"name"`
	Health    int             `json:"health"`
	Nation    int             `json:"nation"`
	Movement  *MovementStruct `json:"movement"`
	Position  *LocationStruct `json:"position"`
	CanMove   bool            `json:"canMove"`
	Attacks   []*AttackStruct `json:"attacks"`
	CanAttack bool            `json:"canAttack"`
	Armor     *ArmorStruct    `json:"armor"`
}

type AttackStruct struct {
	Name       string `json:"name"`
	AttackType int    `json:"attackType"`
	Power      int    `json:"power"`
	MinRange   uint   `json:"minRange"`
	MaxRange   uint   `json:"maxRange"`
}

type ArmorStruct struct {
	Name      string `json:"name"`
	ArmorType int    `json:"armorType"`
	Strength  int    `json:"strength"`
}

type MovementStruct struct {
	Type     string             `json:"type"`
	Speeds   map[string]float64 `json:"speeds"`
	Distance int                `json:"distance"`
}

type LocationStruct struct {
	X int `json:"x"`
	Y int `json:"y"`
}
<commit_msg>Include worldId in NewResponse (not used atm)<commit_after>package api

type NewRequest struct {
	Uids    []int `json:"uids"`
	Debug   int   `json:"debug"`
	WorldId int   `json:"worldId"`
}

type NewResponse struct {
	Uids  []int `json:"uids"`
	Debug int   `json:"debug"`
	WorldId int   `json:"worldId"`
}

type ViewWorldRequest struct {
}

type ViewWorldResponse struct {
	TerrainResponse ViewTerrainResponse
	UnitsResponse   ViewUnitsResponse
	PlayersResponse ViewPlayersResponse
}

type ViewTerrainRequest struct {
}

type ViewTerrainResponse struct {
	Terrain [][]int `json:"terrain"`
}

type ViewUnitsRequest struct {
}

type ViewUnitsResponse struct {
	Units []*UnitStruct `json:"units"`
}

type ViewPlayersRequest struct {
}

type ViewPlayersResponse struct {
	Me        *PlayerStruct   `json:"me"`
	TeamMates []*PlayerStruct `json:"teamMates"`
	Enemies   []*PlayerStruct `json:"enemies"`
	TurnOwner int             `json:"turnOwner"`
}

type MoveRequest struct {
	Move []LocationStruct `json:"move"`
}

type MoveResponse struct {
	Move []LocationStruct `json:"move"`
}

type AttackRequest struct {
	Attacker    LocationStruct `json:"attacker"`
	AttackIndex int            `json:"attackIndex"`
	Target      LocationStruct `json:"target"`
}

type AttackResponse struct {
	Attacker    LocationStruct `json:"attacker"`
	AttackIndex int            `json:"attackIndex"`
	Target      LocationStruct `json:"target"`
}

type EndTurnRequest struct {
}

type EndTurnResponse struct {
}

type ExitRequest struct {
	Reason string `json:"reason"`
}

type PlayerStruct struct {
	Nation int `json:"nation"`
	Team   int `json:"team"`
}

type UnitStruct struct {
	Name      string          `json:"name"`
	Health    int             `json:"health"`
	Nation    int             `json:"nation"`
	Movement  *MovementStruct `json:"movement"`
	Position  *LocationStruct `json:"position"`
	CanMove   bool            `json:"canMove"`
	Attacks   []*AttackStruct `json:"attacks"`
	CanAttack bool            `json:"canAttack"`
	Armor     *ArmorStruct    `json:"armor"`
}

type AttackStruct struct {
	Name       string `json:"name"`
	AttackType int    `json:"attackType"`
	Power      int    `json:"power"`
	MinRange   uint   `json:"minRange"`
	MaxRange   uint   `json:"maxRange"`
}

type ArmorStruct struct {
	Name      string `json:"name"`
	ArmorType int    `json:"armorType"`
	Strength  int    `json:"strength"`
}

type MovementStruct struct {
	Type     string             `json:"type"`
	Speeds   map[string]float64 `json:"speeds"`
	Distance int                `json:"distance"`
}

type LocationStruct struct {
	X int `json:"x"`
	Y int `json:"y"`
}
<|endoftext|>


<commit_before>package proxy

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"os"

	"github.com/DimShadoWWW/power-pg/common"
)

var (
	connid = uint64(0)
)

// Start function
func Start(localHost, remoteHost *string, powerCallback common.Callback) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:  *conn,
			laddr:  localAddr,
			raddr:  remoteAddr,
			erred:  false,
			errsig: make(chan bool),
			prefix: fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback)
	}
}

func getResolvedAddresses(localHost, remoteHost *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", *remoteHost)
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) *net.TCPListener {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback) {
	// defer p.lconn.conn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = *rconn
	// p.rconn.alive = true
	// defer p.rconn.conn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, powerCallback)
	go p.pipe(p.rconn, p.lconn, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst net.TCPConn, powerCallback common.Callback) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make(readBuf, 0xffff)
	// newPacket := true
	// var msg string
	// remainingBytes := 0
	if islocal {
		for {
			// var r readBuf
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			fmt.Printf("Readed bytes: %d\n", n)
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}

			// 	r = buff[:n]
			// 	fmt.Printf("%#v\n", buff[:n])
			// 	if remainingBytes > 0 {
			// 		if remainingBytes <= n {
			// 			newPacket = true
			// 			msg = msg + string(r.next(remainingBytes))
			// 			remainingBytes = n - remainingBytes
			// 			fmt.Println(msg)
			// 		} else {
			// 			newPacket = false
			// 			msg = msg + string(r.next(remainingBytes))
			// 			remainingBytes = remainingBytes - n
			// 		}
			// 	}
			// 	fmt.Printf("Remaining bytes: %d\n", remainingBytes)
			// NewP:
			// 	if newPacket {
			// 		remainingBytes = 0
			// 		newPacket = false
			// 		msg = ""
			// 		t := r.byte()
			// 		n = n - 1
			// 		fmt.Println(t)
			// 		switch t {
			// 		case query:
			// 			// c.rxReadyForQuery(r)
			// 			remainingBytes = r.int32()
			// 			remainingBytes = remainingBytes - 4
			// 			if remainingBytes > 0 {
			// 				if remainingBytes <= n {
			// 					newPacket = true
			// 					msg = msg + string(r.next(remainingBytes))
			// 					remainingBytes = n - remainingBytes
			// 					fmt.Println(msg)
			// 					goto NewP
			// 				} else {
			// 					newPacket = false
			// 					msg = msg + string(r.next(remainingBytes))
			// 					remainingBytes = remainingBytes - n
			// 				}
			// 				fmt.Printf("Remaining bytes: %d\n", remainingBytes)
			// 			}
			// 		// case rowDescription:
			// 		// case dataRow:
			// 		// case bindComplete:
			// 		// case commandComplete:
			// 		// 	commandTag = CommandTag(r.readCString())
			// 		default:
			// 			// if e := c.processContextFreeMsg(t, r); e != nil && softErr == nil {
			// 			// 	softErr = e
			// 			// }
			// 		}
			// 	}
			// 	r = append(r, buff[:]...)

			// fmt.Println("a")
			// c := src
			// c.reader = bufio.NewReader(src.conn)
			// c.mr.reader = c.reader
			//
			// var t byte
			// var r *msgReader
			// fmt.Println("b")
			// t, r, err := c.rxMsg()
			// fmt.Println("c")
			// if err != nil {
			// 	fmt.Println(err)
			// 	return
			// }
			// fmt.Println("d")
			//
			// fmt.Printf("t: %#v\n", t)

			// n, err := src.Read(buff)
			// if err != nil {
			// 	p.err("Read failed '%s'\n", err)
			// 	return
			// }
			// b := buff[:n]
			// //show output
			//
			//
			// b = getModifiedBuffer(b, powerCallback)
			// n, err = dst.Write(b)
			// //
			// //write out result
			// n, err = dst.Write(b)
			// if err != nil {
			// 	p.err("Write failed '%s'\n", err)
			// 	return
			// }
		}
	} else {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}
<commit_msg>Update<commit_after>package proxy

import (
	"github.com/DimShadoWWW/power-pg/common"
	"fmt"
	"net"
	"os"
	"io"
	"encoding/binary"
)

var (
	connid = uint64(0)
)

func Start(localHost, remoteHost *string, powerCallback common.Callback) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:    conn,
			laddr:    localAddr,
			raddr:    remoteAddr,
			erred:    false,
			errsig:   make(chan bool),
			prefix:   fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback)
	}
}

func getResolvedAddresses(localHost, remoteHost *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", *remoteHost)
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) (*net.TCPListener) {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  *net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback) {
	defer p.lconn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = rconn
	defer p.rconn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, powerCallback)
	go p.pipe(p.rconn, p.lconn, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst *net.TCPConn, powerCallback common.Callback) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make([]byte, 0xffff)
	for {
		n, err := src.Read(buff)
		if err != nil {
			p.err("Read failed '%s'\n", err)
			return
		}
		b := buff[:n]
		//show output
		if islocal {
			b = getModifiedBuffer(b, powerCallback)
			n, err = dst.Write(b)
		} else {
			//write out result
			n, err = dst.Write(b)
		}
		if err != nil {
			p.err("Write failed '%s'\n", err)
			return
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}

<|endoftext|>


<commit_before>package test

import (
	"io/ioutil"
	"os"
	"testing"
	"time"

	"github.com/coreos/go-etcd/etcd"
)

// This test creates a single node and then set a value to it to trigger snapshot
func TestSimpleSnapshot(t *testing.T) {
	procAttr := new(os.ProcAttr)
	procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
	args := []string{"etcd", "-n=node1", "-d=/tmp/node1", "-snapshot=true", "-snapCount=500"}

	process, err := os.StartProcess(EtcdBinPath, append(args, "-f"), procAttr)
	if err != nil {
		t.Fatal("start process failed:" + err.Error())
	}

	time.Sleep(time.Second)

	c := etcd.NewClient(nil)

	c.SyncCluster()
	// issue first 501 commands
	for i := 0; i < 501; i++ {
		result, err := c.Set("foo", "bar", 100)

		if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL < 95 {
			if err != nil {
				t.Fatal(err)
			}

			t.Fatalf("Set failed with %s %s %v", result.Key, result.Value, result.TTL)
		}
	}

	// wait for a snapshot interval
	time.Sleep(3 * time.Second)

	snapshots, err := ioutil.ReadDir("/tmp/node1/snapshot")

	if err != nil {
		t.Fatal("list snapshot failed:" + err.Error())
	}

	if len(snapshots) != 1 {
		t.Fatal("wrong number of snapshot :[1/", len(snapshots), "]")
	}

	if snapshots[0].Name() != "0_503.ss" {
		t.Fatal("wrong name of snapshot :[0_503.ss/", snapshots[0].Name(), "]")
	}

	// issue second 501 commands
	for i := 0; i < 501; i++ {
		result, err := c.Set("foo", "bar", 100)

		if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL < 95 {
			if err != nil {
				t.Fatal(err)
			}

			t.Fatalf("Set failed with %s %s %v", result.Key, result.Value, result.TTL)
		}
	}

	// wait for a snapshot interval
	time.Sleep(3 * time.Second)

	snapshots, err = ioutil.ReadDir("/tmp/node1/snapshot")

	if err != nil {
		t.Fatal("list snapshot failed:" + err.Error())
	}

	if len(snapshots) != 1 {
		t.Fatal("wrong number of snapshot :[1/", len(snapshots), "]")
	}

	if snapshots[0].Name() != "0_1004.ss" {
		t.Fatal("wrong name of snapshot :[0_1004.ss/", snapshots[0].Name(), "]")
	}

	process.Kill()
}
<commit_msg>refactor use defer<commit_after>package test

import (
	"io/ioutil"
	"os"
	"testing"
	"time"

	"github.com/coreos/go-etcd/etcd"
)

// This test creates a single node and then set a value to it to trigger snapshot
func TestSimpleSnapshot(t *testing.T) {
	procAttr := new(os.ProcAttr)
	procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
	args := []string{"etcd", "-n=node1", "-d=/tmp/node1", "-snapshot=true", "-snapCount=500"}

	process, err := os.StartProcess(EtcdBinPath, append(args, "-f"), procAttr)
	if err != nil {
		t.Fatal("start process failed:" + err.Error())
	}
	defer process.Kill()

	time.Sleep(time.Second)

	c := etcd.NewClient(nil)

	c.SyncCluster()
	// issue first 501 commands
	for i := 0; i < 501; i++ {
		result, err := c.Set("foo", "bar", 100)

		if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL < 95 {
			if err != nil {
				t.Fatal(err)
			}

			t.Fatalf("Set failed with %s %s %v", result.Key, result.Value, result.TTL)
		}
	}

	// wait for a snapshot interval
	time.Sleep(3 * time.Second)

	snapshots, err := ioutil.ReadDir("/tmp/node1/snapshot")

	if err != nil {
		t.Fatal("list snapshot failed:" + err.Error())
	}

	if len(snapshots) != 1 {
		t.Fatal("wrong number of snapshot :[1/", len(snapshots), "]")
	}

	if snapshots[0].Name() != "0_503.ss" {
		t.Fatal("wrong name of snapshot :[0_503.ss/", snapshots[0].Name(), "]")
	}

	// issue second 501 commands
	for i := 0; i < 501; i++ {
		result, err := c.Set("foo", "bar", 100)

		if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL < 95 {
			if err != nil {
				t.Fatal(err)
			}

			t.Fatalf("Set failed with %s %s %v", result.Key, result.Value, result.TTL)
		}
	}

	// wait for a snapshot interval
	time.Sleep(3 * time.Second)

	snapshots, err = ioutil.ReadDir("/tmp/node1/snapshot")

	if err != nil {
		t.Fatal("list snapshot failed:" + err.Error())
	}

	if len(snapshots) != 1 {
		t.Fatal("wrong number of snapshot :[1/", len(snapshots), "]")
	}

	if snapshots[0].Name() != "0_1004.ss" {
		t.Fatal("wrong name of snapshot :[0_1004.ss/", snapshots[0].Name(), "]")
	}
}
<|endoftext|>


<commit_before>package blx

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
)

func cleanup(path, key string) {
	os.Remove(filepath.Join(path, key+dataExt))
	os.Remove(filepath.Join(path, key+metaExt))
}

func TestStoreBlockSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	meta := make(map[string][]byte)
	meta["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: meta,
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	_, err = os.Stat(filepath.Join(path, block.Key+dataExt))
	assert.NoError(t, err)
	_, err = os.Stat(filepath.Join(path, block.Key+metaExt))
	assert.NoError(t, err)

	cleanup(path, block.Key)

}

func TestStoreBlockExists(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	meta := make(map[string][]byte)
	meta["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: meta,
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	err = ds.Store(block.Key, &block)
	assert.Error(t, err)
	assert.EqualError(t, ErrExists, err.Error())

	cleanup(path, block.Key)
}

func TestGetSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	meta := make(map[string][]byte)
	meta["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: meta,
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	b, err := ds.Get(block.Key)
	assert.NoError(t, err)
	assert.Equal(t, block.Key, b.Key)
	assert.Equal(t, block.Data, b.Data)
	assert.Equal(t, block.Meta, b.Meta)

	cleanup(path, block.Key)
}

func TestGetFail(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	key := "TestKey2"

	_, err := ds.Get(key)
	assert.Error(t, err)
	assert.EqualError(t, ErrNotFound, err.Error())
}

func TestListSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	meta := make(map[string][]byte)
	meta["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: meta,
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	list, err := ds.List()
	assert.NoError(t, err)
	assert.Equal(t, block.Key, *list[0])

	cleanup(path, block.Key)
}
<commit_msg>Updates tests  for blx storage<commit_after>package blx

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
)

func cleanup(path, key string) {
	os.Remove(filepath.Join(path, key+dataExt))
	os.Remove(filepath.Join(path, key+metaExt))
}

func TestStoreBlockSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	values := make(map[string][]byte)
	values["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: Meta{Values: values},
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	_, err = os.Stat(filepath.Join(path, block.Key+dataExt))
	assert.NoError(t, err)
	_, err = os.Stat(filepath.Join(path, block.Key+metaExt))
	assert.NoError(t, err)

	cleanup(path, block.Key)

}

func TestStoreBlockExists(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	values := make(map[string][]byte)
	values["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: Meta{Values: values},
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	err = ds.Store(block.Key, &block)
	assert.Error(t, err)
	assert.EqualError(t, ErrExists, err.Error())

	cleanup(path, block.Key)
}

func TestGetSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	values := make(map[string][]byte)
	values["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: Meta{Values: values},
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	b, err := ds.Get(block.Key)
	assert.NoError(t, err)
	assert.Equal(t, block.Key, b.Key)
	assert.Equal(t, block.Data, b.Data)
	assert.Equal(t, block.Meta, b.Meta)

	cleanup(path, block.Key)
}

func TestGetFail(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	key := "TestKey2"

	_, err := ds.Get(key)
	assert.Error(t, err)
	assert.EqualError(t, ErrNotFound, err.Error())
}

func TestListSuccess(t *testing.T) {
	path := os.TempDir()

	ds := NewDiskStorage(path)

	values := make(map[string][]byte)
	values["TestMetaKey"] = []byte("TestMetaValue")

	block := Block{
		Key:  "TestKey1",
		Meta: Meta{Values: values},
		Data: []byte("TestData"),
	}

	err := ds.Store(block.Key, &block)
	assert.NoError(t, err)

	list, err := ds.List()
	assert.NoError(t, err)
	assert.Equal(t, block.Key, list[0])

	cleanup(path, block.Key)
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/terraform-providers/terraform-provider-oci/httpreplay"
)

var (
	InvokeFunctionRequiredOnlyResource = InvokeFunctionResourceDependencies +
		generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Required, Create, invokeFunctionRepresentation)

	InvokeFunctionResourceConfig = InvokeFunctionResourceDependencies +
		generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Update, invokeFunctionRepresentation)

	invokeFunctionSingularDataSourceRepresentation = map[string]interface{}{}

	invokeFunctionRepresentation = map[string]interface{}{
		"function_id":          Representation{repType: Required, create: `${oci_functions_function.test_function.id}`},
		"invoke_function_body": Representation{repType: Optional, create: `{\"name\":\"Bob\"}`},
		"fn_intent":            Representation{repType: Optional, create: `httprequest`},
		"fn_invoke_type":       Representation{repType: Optional, create: `sync`},
	}

	InvokeFunctionResourceDependencies = FunctionRequiredOnlyResource
	sourceFile                         *os.File
)

func createTmpSourceFile() (string, error) {
	sourceFile, err := ioutil.TempFile(os.TempDir(), "source-")
	if err != nil {
		return "", err
	}

	text := []byte("{\"name\":\"Bob\"}")
	if _, err = sourceFile.Write(text); err != nil {
		return "", err
	}

	// Close the file
	if err := sourceFile.Close(); err != nil {
		return "", err
	}

	return sourceFile.Name(), nil
}

func TestFunctionsInvokeFunctionResource_basic(t *testing.T) {
	httpreplay.SetScenario("TestFunctionsInvokeFunctionResource_basic")
	defer httpreplay.SaveScenario()

	provider := testAccProvider
	config := testProviderConfig()

	compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
	compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)

	image := getEnvSettingWithBlankDefault("image")
	imageVariableStr := fmt.Sprintf("variable \"image\" { default = \"%s\" }\n", image)

	imageDigest := getEnvSettingWithBlankDefault("image_digest")
	imageDigestVariableStr := fmt.Sprintf("variable \"image_digest\" { default = \"%s\" }\n", imageDigest)

	resourceName := "oci_functions_invoke_function.test_invoke_function"
	sourceFilePath, err := createTmpSourceFile()
	if err != nil {
		t.Fatalf("Unable to create files for invocation. Error: %q", err)
	}

	resource.Test(t, resource.TestCase{
		PreCheck: func() { testAccPreCheck(t) },
		Providers: map[string]terraform.ResourceProvider{
			"oci": provider,
		},
		CheckDestroy: testAccCheckFunctionsInvokeFunctionDestroy,
		Steps: []resource.TestStep{
			// verify create
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Required, Create, invokeFunctionRepresentation),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 World\"}\n"),
				),
			},

			// delete before next create
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies,
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create, invokeFunctionRepresentation),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_intent", Representation{repType: Optional, create: `cloudevent`}, invokeFunctionRepresentation)),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_invoke_type", Representation{repType: Optional, create: `detached`}, invokeFunctionRepresentation)),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_intent", Representation{repType: Optional, create: `cloudevent`}, getUpdatedRepresentationCopy("fn_invoke_type", Representation{repType: Optional, create: `detached`}, invokeFunctionRepresentation))),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
				),
			},
			// verify create with source path
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(representationCopyWithRemovedProperties(invokeFunctionRepresentation, []string{"invoke_function_body"}), map[string]interface{}{
							"input_body_source_path": Representation{repType: Optional, create: sourceFilePath},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with base64 encoded input
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(representationCopyWithRemovedProperties(invokeFunctionRepresentation, []string{"invoke_function_body"}), map[string]interface{}{
							"invoke_function_body_base64_encoded": Representation{repType: Optional, create: "eyJuYW1lIjoiQm9iIn0="},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify base64 encoded content
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(invokeFunctionRepresentation, map[string]interface{}{
							"base64_encode_content": Representation{repType: Optional, create: `true`},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "eyJtZXNzYWdlIjoiSGVsbG8gdjMgQm9iIn0K"),
				),
			},
		},
	})
}

func testAccCheckFunctionsInvokeFunctionDestroy(s *terraform.State) error {
	if sourceFile != nil {
		if _, err := os.Stat(sourceFile.Name()); err == nil {
			os.Remove(sourceFile.Name())
		}
	}
	return nil
}
<commit_msg>supressing TestFunctionsInvokeFunctionResource_basic from http replay<commit_after>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/terraform-providers/terraform-provider-oci/httpreplay"
)

var (
	InvokeFunctionRequiredOnlyResource = InvokeFunctionResourceDependencies +
		generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Required, Create, invokeFunctionRepresentation)

	InvokeFunctionResourceConfig = InvokeFunctionResourceDependencies +
		generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Update, invokeFunctionRepresentation)

	invokeFunctionSingularDataSourceRepresentation = map[string]interface{}{}

	invokeFunctionRepresentation = map[string]interface{}{
		"function_id":          Representation{repType: Required, create: `${oci_functions_function.test_function.id}`},
		"invoke_function_body": Representation{repType: Optional, create: `{\"name\":\"Bob\"}`},
		"fn_intent":            Representation{repType: Optional, create: `httprequest`},
		"fn_invoke_type":       Representation{repType: Optional, create: `sync`},
	}

	InvokeFunctionResourceDependencies = FunctionRequiredOnlyResource
	sourceFile                         *os.File
)

func createTmpSourceFile() (string, error) {
	sourceFile, err := ioutil.TempFile(os.TempDir(), "source-")
	if err != nil {
		return "", err
	}

	text := []byte("{\"name\":\"Bob\"}")
	if _, err = sourceFile.Write(text); err != nil {
		return "", err
	}

	// Close the file
	if err := sourceFile.Close(); err != nil {
		return "", err
	}

	return sourceFile.Name(), nil
}

func TestFunctionsInvokeFunctionResource_basic(t *testing.T) {
	if httpreplay.ModeRecordReplay() {
		t.Skip("Skipping TestFunctionsInvokeFunctionResource_basic in HttpReplay mode till json encoding is fixed.")
	}

	httpreplay.SetScenario("TestFunctionsInvokeFunctionResource_basic")
	defer httpreplay.SaveScenario()

	provider := testAccProvider
	config := testProviderConfig()

	compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
	compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)

	image := getEnvSettingWithBlankDefault("image")
	imageVariableStr := fmt.Sprintf("variable \"image\" { default = \"%s\" }\n", image)

	imageDigest := getEnvSettingWithBlankDefault("image_digest")
	imageDigestVariableStr := fmt.Sprintf("variable \"image_digest\" { default = \"%s\" }\n", imageDigest)

	resourceName := "oci_functions_invoke_function.test_invoke_function"
	sourceFilePath, err := createTmpSourceFile()
	if err != nil {
		t.Fatalf("Unable to create files for invocation. Error: %q", err)
	}

	resource.Test(t, resource.TestCase{
		PreCheck: func() { testAccPreCheck(t) },
		Providers: map[string]terraform.ResourceProvider{
			"oci": provider,
		},
		CheckDestroy: testAccCheckFunctionsInvokeFunctionDestroy,
		Steps: []resource.TestStep{
			// verify create
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Required, Create, invokeFunctionRepresentation),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 World\"}\n"),
				),
			},

			// delete before next create
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies,
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create, invokeFunctionRepresentation),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_intent", Representation{repType: Optional, create: `cloudevent`}, invokeFunctionRepresentation)),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_invoke_type", Representation{repType: Optional, create: `detached`}, invokeFunctionRepresentation)),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
				),
			},
			// verify create with optionals
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						getUpdatedRepresentationCopy("fn_intent", Representation{repType: Optional, create: `cloudevent`}, getUpdatedRepresentationCopy("fn_invoke_type", Representation{repType: Optional, create: `detached`}, invokeFunctionRepresentation))),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttrSet(resourceName, "function_id"),
				),
			},
			// verify create with source path
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(representationCopyWithRemovedProperties(invokeFunctionRepresentation, []string{"invoke_function_body"}), map[string]interface{}{
							"input_body_source_path": Representation{repType: Optional, create: sourceFilePath},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify create with base64 encoded input
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(representationCopyWithRemovedProperties(invokeFunctionRepresentation, []string{"invoke_function_body"}), map[string]interface{}{
							"invoke_function_body_base64_encoded": Representation{repType: Optional, create: "eyJuYW1lIjoiQm9iIn0="},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "{\"message\":\"Hello v3 Bob\"}\n"),
				),
			},
			// verify base64 encoded content
			{
				Config: config + compartmentIdVariableStr + imageVariableStr + imageDigestVariableStr + InvokeFunctionResourceDependencies +
					generateResourceFromRepresentationMap("oci_functions_invoke_function", "test_invoke_function", Optional, Create,
						representationCopyWithNewProperties(invokeFunctionRepresentation, map[string]interface{}{
							"base64_encode_content": Representation{repType: Optional, create: `true`},
						})),
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(resourceName, "content", "eyJtZXNzYWdlIjoiSGVsbG8gdjMgQm9iIn0K"),
				),
			},
		},
	})
}

func testAccCheckFunctionsInvokeFunctionDestroy(s *terraform.State) error {
	if sourceFile != nil {
		if _, err := os.Stat(sourceFile.Name()); err == nil {
			os.Remove(sourceFile.Name())
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:generate sh generate.sh

// Command genop generates a Go source file with functions for TensorFlow ops.
package main

import (
	"bytes"
	"flag"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/tensorflow/tensorflow/tensorflow/go/genop/internal"
)

func main() {
	filename := flag.String("outfile", "", "File to write generated source code to.")
	flag.Parse()
	if *filename == "" {
		log.Fatal("-outfile must be set")
	}
	os.MkdirAll(filepath.Dir(*filename), 0755)

	var buf bytes.Buffer
	if err := internal.GenerateFunctionsForRegisteredOps(&buf); err != nil {
		log.Fatal(err)
	}
	formatted, err := format.Source(buf.Bytes())
	if err != nil {
		log.Fatalf("Failed to generate valid source? 'go fmt' failed: %v", err)
	}
	if err := ioutil.WriteFile(*filename, formatted, 0644); err != nil {
		log.Fatalf("Failed to write to %q: %v", *filename, err)
	}
}
<commit_msg>Go: Enable custom headers in files generated by genop. Change: 146532572<commit_after>// Copyright 2016 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:generate sh generate.sh

// Command genop generates a Go source file with functions for TensorFlow ops.
package main

import (
	"bytes"
	"flag"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/tensorflow/tensorflow/tensorflow/go/genop/internal"
)

func main() {
	var (
		filename = flag.String("outfile", "", "File to write generated source code to.")
		header   = flag.String("header", "", "Path to a file whose contents will be copied into the generated file. Can be empty")
		buf bytes.Buffer
	)
	flag.Parse()
	if *filename == "" {
		log.Fatal("-outfile must be set")
	}
	if *header != "" {
		hdr, err := ioutil.ReadFile(*header)
		if err != nil {
			log.Fatalf("Unable to read %s: %v", *header, err)
		}
		buf.Write(hdr)
		buf.WriteString("\n\n")
	}
	os.MkdirAll(filepath.Dir(*filename), 0755)

	if err := internal.GenerateFunctionsForRegisteredOps(&buf); err != nil {
		log.Fatal(err)
	}
	formatted, err := format.Source(buf.Bytes())
	if err != nil {
		log.Fatalf("Failed to generate valid source? 'go fmt' failed: %v", err)
	}
	if err := ioutil.WriteFile(*filename, formatted, 0644); err != nil {
		log.Fatalf("Failed to write to %q: %v", *filename, err)
	}
}
<|endoftext|>


<commit_before>package zclwrite

import (
	"bytes"
	"io"
)

type Node interface {
	walkChildNodes(w internalWalkFunc)
	Tokens() *TokenSeq
}

type internalWalkFunc func(Node)

type File struct {
	Name     string
	SrcBytes []byte

	Body      *Body
	AllTokens *TokenSeq
}

// WriteTo writes the tokens underlying the receiving file to the given writer.
func (f *File) WriteTo(wr io.Writer) (int, error) {
	return f.AllTokens.WriteTo(wr)
}

// Bytes returns a buffer containing the source code resulting from the
// tokens underlying the receiving file. If any updates have been made via
// the AST API, these will be reflected in the result.
func (f *File) Bytes() []byte {
	buf := &bytes.Buffer{}
	f.WriteTo(buf)
	return buf.Bytes()
}

// Format makes in-place modifications to the tokens underlying the receiving
// file in order to change the whitespace to be in canonical form.
func (f *File) Format() {
	format(f.Body.AllTokens.Tokens())
}

type Body struct {
	// Items may contain Attribute, Block and Unstructured instances.
	// Items and AllTokens should be updated only by methods of this type,
	// since they must be kept synchronized for correct operation.
	Items     []Node
	AllTokens *TokenSeq

	// IndentLevel is the number of spaces that should appear at the start
	// of lines added within this body.
	IndentLevel int
}

func (n *Body) walkChildNodes(w internalWalkFunc) {
	for _, item := range n.Items {
		w(item)
	}
}

func (n *Body) Tokens() *TokenSeq {
	return n.AllTokens
}

func (n *Body) AppendItem(node Node) {
	if n.AllTokens == nil {
		new := make(TokenSeq, 0, 1)
		n.AllTokens = &new
	}
	n.Items = append(n.Items, node)
	*(n.AllTokens) = append(*(n.AllTokens), node.Tokens())
}

type Attribute struct {
	AllTokens *TokenSeq

	LeadCommentTokens *TokenSeq
	NameToken         *Token
	EqualsToken       *Token
	Value             *Expression
	LineCommentTokens *TokenSeq
	EOLToken          *Token
}

func (a *Attribute) walkChildNodes(w internalWalkFunc) {
	w(a.Value)
}

type Block struct {
	AllTokens *TokenSeq

	LeadCommentTokens *TokenSeq
	TypeToken         *Token
	LabelTokens       []*TokenSeq
	LabelTokensFlat   *TokenSeq
	OBraceToken       *Token
	Body              *Body
	CBraceToken       *Token
	EOLToken          *Token
}

func (n *Block) walkChildNodes(w internalWalkFunc) {
	w(n.Body)
}

// Unstructured represents consecutive sets of tokens within a Body that
// aren't part of any particular construct. This includes blank lines
// and comments that aren't immediately before an attribute or nested block.
type Unstructured struct {
	AllTokens *TokenSeq
}

func (n *Unstructured) Tokens() *TokenSeq {
	return n.AllTokens
}

func (n *Unstructured) walkChildNodes(w internalWalkFunc) {
	// no child nodes
}

type Expression struct {
	AllTokens *TokenSeq
	VarRefs   []*VarRef
}

func (n *Expression) walkChildNodes(w internalWalkFunc) {
	for _, name := range n.VarRefs {
		w(name)
	}
}

func (n *Expression) Tokens() *TokenSeq {
	return n.AllTokens
}

type VarRef struct {
	// Tokens alternate between TokenIdent and TokenDot, with the first
	// and last elements always being TokenIdent.
	AllTokens *TokenSeq
}

func (n *VarRef) walkChildNodes(w internalWalkFunc) {
	// no child nodes of a variable name
}

func (n *VarRef) Tokens() *TokenSeq {
	return n.AllTokens
}
<commit_msg>zclwrite: standardize on TokenSeq for all node parts<commit_after>package zclwrite

import (
	"bytes"
	"io"
)

type Node interface {
	walkChildNodes(w internalWalkFunc)
	Tokens() *TokenSeq
}

type internalWalkFunc func(Node)

type File struct {
	Name     string
	SrcBytes []byte

	Body      *Body
	AllTokens *TokenSeq
}

// WriteTo writes the tokens underlying the receiving file to the given writer.
func (f *File) WriteTo(wr io.Writer) (int, error) {
	return f.AllTokens.WriteTo(wr)
}

// Bytes returns a buffer containing the source code resulting from the
// tokens underlying the receiving file. If any updates have been made via
// the AST API, these will be reflected in the result.
func (f *File) Bytes() []byte {
	buf := &bytes.Buffer{}
	f.WriteTo(buf)
	return buf.Bytes()
}

// Format makes in-place modifications to the tokens underlying the receiving
// file in order to change the whitespace to be in canonical form.
func (f *File) Format() {
	format(f.Body.AllTokens.Tokens())
}

type Body struct {
	// Items may contain Attribute, Block and Unstructured instances.
	// Items and AllTokens should be updated only by methods of this type,
	// since they must be kept synchronized for correct operation.
	Items     []Node
	AllTokens *TokenSeq

	// IndentLevel is the number of spaces that should appear at the start
	// of lines added within this body.
	IndentLevel int
}

func (n *Body) walkChildNodes(w internalWalkFunc) {
	for _, item := range n.Items {
		w(item)
	}
}

func (n *Body) Tokens() *TokenSeq {
	return n.AllTokens
}

func (n *Body) AppendItem(node Node) {
	if n.AllTokens == nil {
		new := make(TokenSeq, 0, 1)
		n.AllTokens = &new
	}
	n.Items = append(n.Items, node)
	*(n.AllTokens) = append(*(n.AllTokens), node.Tokens())
}

type Attribute struct {
	AllTokens *TokenSeq

	LeadCommentTokens *TokenSeq
	NameTokens        *TokenSeq
	EqualsTokens      *TokenSeq
	Value             *Expression
	LineCommentTokens *TokenSeq
	EOLTokens         *TokenSeq
}

func (a *Attribute) walkChildNodes(w internalWalkFunc) {
	w(a.Value)
}

type Block struct {
	AllTokens *TokenSeq

	LeadCommentTokens *TokenSeq
	TypeTokens        *TokenSeq
	LabelTokens       []*TokenSeq
	LabelTokensFlat   *TokenSeq
	OBraceTokens      *TokenSeq
	Body              *Body
	CBraceTokens      *TokenSeq
	EOLTokens         *TokenSeq
}

func (n *Block) walkChildNodes(w internalWalkFunc) {
	w(n.Body)
}

// Unstructured represents consecutive sets of tokens within a Body that
// aren't part of any particular construct. This includes blank lines
// and comments that aren't immediately before an attribute or nested block.
type Unstructured struct {
	AllTokens *TokenSeq
}

func (n *Unstructured) Tokens() *TokenSeq {
	return n.AllTokens
}

func (n *Unstructured) walkChildNodes(w internalWalkFunc) {
	// no child nodes
}

type Expression struct {
	AllTokens *TokenSeq
	VarRefs   []*VarRef
}

func (n *Expression) walkChildNodes(w internalWalkFunc) {
	for _, name := range n.VarRefs {
		w(name)
	}
}

func (n *Expression) Tokens() *TokenSeq {
	return n.AllTokens
}

type VarRef struct {
	// Tokens alternate between TokenIdent and TokenDot, with the first
	// and last elements always being TokenIdent.
	AllTokens *TokenSeq
}

func (n *VarRef) walkChildNodes(w internalWalkFunc) {
	// no child nodes of a variable name
}

func (n *VarRef) Tokens() *TokenSeq {
	return n.AllTokens
}
<|endoftext|>


<commit_before>package integration_test

import (
	"path/filepath"

	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("pushing an app a second time", func() {
	var app *cutlass.App
	AfterEach(func() { app = DestroyApp(app) })

	BeforeEach(func() {
		app = cutlass.New(filepath.Join(bpDir, "fixtures", "sinatra"))
		app.SetEnv("BP_DEBUG", "true")
	})

	RestoringVendorBundle := "Restoring vendor_bundle from cache"
	DownloadRegexp := `Download \[.*/bundler\-.*\.tgz\]`
	CopyRegexp := `Copy \[.*/bundler\-.*\.tgz\]`

	It("uses the cache and runs", func() {
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).ToNot(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(DownloadRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(CopyRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))

		app.Stdout.Reset()
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).To(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(CopyRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(DownloadRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))

		app.Stdout.Reset()
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).To(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(CopyRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(DownloadRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))
	})
})
<commit_msg>Set buildpack when pushing twice<commit_after>package integration_test

import (
	"path/filepath"

	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("pushing an app a second time", func() {
	var app *cutlass.App
	AfterEach(func() { app = DestroyApp(app) })

	BeforeEach(func() {
		app = cutlass.New(filepath.Join(bpDir, "fixtures", "sinatra"))
		app.SetEnv("BP_DEBUG", "true")
		app.Buildpacks = []string{"ruby_buildpack"}
	})

	RestoringVendorBundle := "Restoring vendor_bundle from cache"
	DownloadRegexp := `Download \[.*/bundler\-.*\.tgz\]`
	CopyRegexp := `Copy \[.*/bundler\-.*\.tgz\]`

	It("uses the cache and runs", func() {
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).ToNot(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(DownloadRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(CopyRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))

		app.Stdout.Reset()
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).To(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(CopyRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(DownloadRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))

		app.Stdout.Reset()
		PushAppAndConfirm(app)
		Expect(app.Stdout.String()).To(ContainSubstring(RestoringVendorBundle))
		if !cutlass.Cached {
			Expect(app.Stdout.String()).To(MatchRegexp(CopyRegexp))
			Expect(app.Stdout.String()).ToNot(MatchRegexp(DownloadRegexp))
		}
		Expect(app.GetBody("/")).To(ContainSubstring("Hello world!"))
	})
})
<|endoftext|>