<commit_before>// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package repos contains information about Go source repositories.
package repos

import "fmt"

type Repo struct {
	// GoGerritProject, if non-empty, is the repo's Gerrit project
	// name, such as "go", "net", or "sys".
	GoGerritProject string

	// ImportPath is the repo's import path.
	// It is empty for the main Go repo and other repos that do not
	// contain Go code.
	ImportPath string

	// MirrorToGitHub controls whether this repo is mirrored
	// from Gerrit to GitHub. If true, GoGerritProject and
	// gitHubRepo must both be defined.
	MirrorToGitHub bool

	// showOnDashboard is whether to show the repo on the bottom
	// of build.golang.org in the repo overview section.
	showOnDashboard bool

	// CoordinatorCanBuild reports whether this a repo that the
	// build coordinator knows how to build.
	CoordinatorCanBuild bool

	// gitHubRepo is the "org/repo" of where this repo exists on
	// GitHub. If MirrorToGitHub is true, this is the
	// destination.
	gitHubRepo string

	// WebsiteDesc is the description of the repo for showing on
	// https://golang.org/pkg/#subrepo.
	// It should be plain text. Hostnames may be auto-linkified.
	WebsiteDesc string

	// usePkgGoDev controls whether the repo has opted-in to use
	// pkg.go.dev for displaying documentation for Go packages.
	usePkgGoDev bool
}

// ByGerritProject maps from a Gerrit project name ("go", "net", etc)
// to the Repo's information.
var ByGerritProject = map[string]*Repo{ /* initialized below */ }

// ByImportPath maps from an import path ("golang.org/x/net") to the
// Repo's information.
var ByImportPath = map[string]*Repo{ /* initialized below */ }

func init() {
	addMirrored("go", coordinatorCanBuild, noDash)
	addMirrored("dl", importPath("golang.org/dl"), coordinatorCanBuild)
	addMirrored("gddo", importPath("github.com/golang/gddo"), archivedOnGitHub)
	addMirrored("gofrontend")
	addMirrored("proposal")
	addMirrored("sublime-build")
	addMirrored("sublime-config")

	x("arch")
	x("benchmarks", desc("benchmarks to measure Go as it is developed"))
	x("blog", desc("blog.golang.org's implementation"))
	x("build", desc("build.golang.org's implementation"))
	x("crypto", desc("additional cryptography packages"))
	x("debug", desc("an experimental debugger for Go"))
	x("example", noDash)
	x("exp", desc("experimental and deprecated packages (handle with care; may change without warning)"))
	x("image", desc("additional imaging packages"))
	x("lint", noDash)
	x("mobile", desc("experimental support for Go on mobile platforms"))
	x("mod")
	x("net", desc("additional networking packages"))
	x("oauth2")
	x("perf", desc("packages and tools for performance measurement, storage, and analysis"))
	x("pkgsite", desc("home of the pkg.go.dev website"), usePkgGoDev(), noBuildAndNoDash)
	x("playground", noDash)
	x("review", desc("a tool for working with Gerrit code reviews"))
	x("scratch", noDash)
	x("sync", desc("additional concurrency primitives"))
	x("sys", desc("packages for making system calls"))
	x("talks")
	x("term")
	x("text", desc("packages for working with text"))
	x("time", desc("additional time packages"))
	x("tools", desc("godoc, goimports, gorename, and other tools"))
	x("tour", noDash, desc("tour.golang.org's implementation"))
	x("vgo", noDash)
	x("website")
	x("xerrors", noDash)

	add(&Repo{GoGerritProject: "gollvm"})
	add(&Repo{GoGerritProject: "grpc-review"})

	add(&Repo{
		GoGerritProject: "protobuf",
		MirrorToGitHub:  true,
		ImportPath:      "google.golang.org/protobuf",
		gitHubRepo:      "protocolbuffers/protobuf-go",
	})

	add(&Repo{
		GoGerritProject: "vscode-go",
		MirrorToGitHub:  true,
		gitHubRepo:      "golang/vscode-go",
	})
}

type modifyRepo func(*Repo)

// noDash is an option to the x func that marks the repo as hidden on
// the https://build.golang.org/ dashboard.
func noDash(r *Repo) { r.showOnDashboard = false }

func noBuildAndNoDash(r *Repo) { r.CoordinatorCanBuild, r.showOnDashboard = false, false }

func coordinatorCanBuild(r *Repo) { r.CoordinatorCanBuild = true }

func archivedOnGitHub(r *Repo) {
	// When a repository is archived on GitHub, trying to push
	// to it will fail. So don't mirror.
	r.MirrorToGitHub = false
}

func importPath(v string) modifyRepo { return func(r *Repo) { r.ImportPath = v } }

func desc(v string) modifyRepo { return func(r *Repo) { r.WebsiteDesc = v } }
func usePkgGoDev() modifyRepo  { return func(r *Repo) { r.usePkgGoDev = true } }

// addMirrored adds a repo that's on Gerrit and mirrored to GitHub.
func addMirrored(proj string, opts ...modifyRepo) {
	repo := &Repo{
		GoGerritProject: proj,
		MirrorToGitHub:  true,
		gitHubRepo:      "golang/" + proj,
	}
	for _, o := range opts {
		o(repo)
	}
	add(repo)
}

// x adds a golang.org/x repo.
func x(proj string, opts ...modifyRepo) {
	repo := &Repo{
		GoGerritProject:     proj,
		MirrorToGitHub:      true,
		CoordinatorCanBuild: true,
		ImportPath:          "golang.org/x/" + proj,
		gitHubRepo:          "golang/" + proj,
		showOnDashboard:     true,
	}
	for _, o := range opts {
		o(repo)
	}
	add(repo)
}

func add(r *Repo) {
	if r.MirrorToGitHub {
		if r.gitHubRepo == "" {
			panic(fmt.Sprintf("project %+v has MirrorToGitHub but no gitHubRepo", r))
		}
		if r.GoGerritProject == "" {
			panic(fmt.Sprintf("project %+v has MirrorToGitHub but no GoGerritProject", r))
		}
	}
	if r.showOnDashboard {
		if !r.CoordinatorCanBuild {
			panic(fmt.Sprintf("project %+v is showOnDashboard but not marked buildable by coordinator", r))
		}
		if r.GoGerritProject == "" {
			panic(fmt.Sprintf("project %+v is showOnDashboard but has no Gerrit project", r))
		}
	}

	if p := r.GoGerritProject; p != "" {
		if _, dup := ByGerritProject[p]; dup {
			panic(fmt.Sprintf("duplicate Gerrit project %q in %+v", p, r))
		}
		ByGerritProject[p] = r
	}
	if p := r.ImportPath; p != "" {
		if _, dup := ByImportPath[p]; dup {
			panic(fmt.Sprintf("duplicate import path %q in %+v", p, r))
		}
		ByImportPath[p] = r
	}
}

// ShowOnDashboard reports whether this repo should show up on build.golang.org
// in the list of repos at bottom.
//
// When this returns true, r.GoGerritProject is guaranteed to be non-empty.
func (r *Repo) ShowOnDashboard() bool { return r.showOnDashboard }

// GitHubRepo returns the "<org>/<repo>" that this repo either lives
// at or is mirrored to. It returns the empty string if this repo has no
// GitHub presence.
func (r *Repo) GitHubRepo() string { return r.gitHubRepo }

// UsePkgGoDev reports whether the repo has opted-in to use
// pkg.go.dev for displaying documentation for Go packages.
func (r *Repo) UsePkgGoDev() bool { return r.usePkgGoDev }
<commit_msg>repos: remove unused Repo.UsePkgGoDev<commit_after>// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package repos contains information about Go source repositories.
package repos

import "fmt"

type Repo struct {
	// GoGerritProject, if non-empty, is the repo's Gerrit project
	// name, such as "go", "net", or "sys".
	GoGerritProject string

	// ImportPath is the repo's import path.
	// It is empty for the main Go repo and other repos that do not
	// contain Go code.
	ImportPath string

	// MirrorToGitHub controls whether this repo is mirrored
	// from Gerrit to GitHub. If true, GoGerritProject and
	// gitHubRepo must both be defined.
	MirrorToGitHub bool

	// showOnDashboard is whether to show the repo on the bottom
	// of build.golang.org in the repo overview section.
	showOnDashboard bool

	// CoordinatorCanBuild reports whether this a repo that the
	// build coordinator knows how to build.
	CoordinatorCanBuild bool

	// gitHubRepo is the "org/repo" of where this repo exists on
	// GitHub. If MirrorToGitHub is true, this is the
	// destination.
	gitHubRepo string

	// WebsiteDesc is the description of the repo for showing on
	// https://golang.org/pkg/#subrepo.
	// It should be plain text. Hostnames may be auto-linkified.
	WebsiteDesc string
}

// ByGerritProject maps from a Gerrit project name ("go", "net", etc)
// to the Repo's information.
var ByGerritProject = map[string]*Repo{ /* initialized below */ }

// ByImportPath maps from an import path ("golang.org/x/net") to the
// Repo's information.
var ByImportPath = map[string]*Repo{ /* initialized below */ }

func init() {
	addMirrored("go", coordinatorCanBuild, noDash)
	addMirrored("dl", importPath("golang.org/dl"), coordinatorCanBuild)
	addMirrored("gddo", importPath("github.com/golang/gddo"), archivedOnGitHub)
	addMirrored("gofrontend")
	addMirrored("proposal")
	addMirrored("sublime-build")
	addMirrored("sublime-config")

	x("arch")
	x("benchmarks", desc("benchmarks to measure Go as it is developed"))
	x("blog", desc("blog.golang.org's implementation"))
	x("build", desc("build.golang.org's implementation"))
	x("crypto", desc("additional cryptography packages"))
	x("debug", desc("an experimental debugger for Go"))
	x("example", noDash)
	x("exp", desc("experimental and deprecated packages (handle with care; may change without warning)"))
	x("image", desc("additional imaging packages"))
	x("lint", noDash)
	x("mobile", desc("experimental support for Go on mobile platforms"))
	x("mod")
	x("net", desc("additional networking packages"))
	x("oauth2")
	x("perf", desc("packages and tools for performance measurement, storage, and analysis"))
	x("pkgsite", desc("home of the pkg.go.dev website"), noBuildAndNoDash)
	x("playground", noDash)
	x("review", desc("a tool for working with Gerrit code reviews"))
	x("scratch", noDash)
	x("sync", desc("additional concurrency primitives"))
	x("sys", desc("packages for making system calls"))
	x("talks")
	x("term")
	x("text", desc("packages for working with text"))
	x("time", desc("additional time packages"))
	x("tools", desc("godoc, goimports, gorename, and other tools"))
	x("tour", noDash, desc("tour.golang.org's implementation"))
	x("vgo", noDash)
	x("website")
	x("xerrors", noDash)

	add(&Repo{GoGerritProject: "gollvm"})
	add(&Repo{GoGerritProject: "grpc-review"})

	add(&Repo{
		GoGerritProject: "protobuf",
		MirrorToGitHub:  true,
		ImportPath:      "google.golang.org/protobuf",
		gitHubRepo:      "protocolbuffers/protobuf-go",
	})

	add(&Repo{
		GoGerritProject: "vscode-go",
		MirrorToGitHub:  true,
		gitHubRepo:      "golang/vscode-go",
	})
}

type modifyRepo func(*Repo)

// noDash is an option to the x func that marks the repo as hidden on
// the https://build.golang.org/ dashboard.
func noDash(r *Repo) { r.showOnDashboard = false }

func noBuildAndNoDash(r *Repo) { r.CoordinatorCanBuild, r.showOnDashboard = false, false }

func coordinatorCanBuild(r *Repo) { r.CoordinatorCanBuild = true }

func archivedOnGitHub(r *Repo) {
	// When a repository is archived on GitHub, trying to push
	// to it will fail. So don't mirror.
	r.MirrorToGitHub = false
}

func importPath(v string) modifyRepo { return func(r *Repo) { r.ImportPath = v } }

func desc(v string) modifyRepo { return func(r *Repo) { r.WebsiteDesc = v } }

// addMirrored adds a repo that's on Gerrit and mirrored to GitHub.
func addMirrored(proj string, opts ...modifyRepo) {
	repo := &Repo{
		GoGerritProject: proj,
		MirrorToGitHub:  true,
		gitHubRepo:      "golang/" + proj,
	}
	for _, o := range opts {
		o(repo)
	}
	add(repo)
}

// x adds a golang.org/x repo.
func x(proj string, opts ...modifyRepo) {
	repo := &Repo{
		GoGerritProject:     proj,
		MirrorToGitHub:      true,
		CoordinatorCanBuild: true,
		ImportPath:          "golang.org/x/" + proj,
		gitHubRepo:          "golang/" + proj,
		showOnDashboard:     true,
	}
	for _, o := range opts {
		o(repo)
	}
	add(repo)
}

func add(r *Repo) {
	if r.MirrorToGitHub {
		if r.gitHubRepo == "" {
			panic(fmt.Sprintf("project %+v has MirrorToGitHub but no gitHubRepo", r))
		}
		if r.GoGerritProject == "" {
			panic(fmt.Sprintf("project %+v has MirrorToGitHub but no GoGerritProject", r))
		}
	}
	if r.showOnDashboard {
		if !r.CoordinatorCanBuild {
			panic(fmt.Sprintf("project %+v is showOnDashboard but not marked buildable by coordinator", r))
		}
		if r.GoGerritProject == "" {
			panic(fmt.Sprintf("project %+v is showOnDashboard but has no Gerrit project", r))
		}
	}

	if p := r.GoGerritProject; p != "" {
		if _, dup := ByGerritProject[p]; dup {
			panic(fmt.Sprintf("duplicate Gerrit project %q in %+v", p, r))
		}
		ByGerritProject[p] = r
	}
	if p := r.ImportPath; p != "" {
		if _, dup := ByImportPath[p]; dup {
			panic(fmt.Sprintf("duplicate import path %q in %+v", p, r))
		}
		ByImportPath[p] = r
	}
}

// ShowOnDashboard reports whether this repo should show up on build.golang.org
// in the list of repos at bottom.
//
// When this returns true, r.GoGerritProject is guaranteed to be non-empty.
func (r *Repo) ShowOnDashboard() bool { return r.showOnDashboard }

// GitHubRepo returns the "<org>/<repo>" that this repo either lives
// at or is mirrored to. It returns the empty string if this repo has no
// GitHub presence.
func (r *Repo) GitHubRepo() string { return r.gitHubRepo }
<|endoftext|>


<commit_before>// Copyright (c) 2014 Datacratic. All rights reserved.

package rest

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// Client is a convenience REST client which simplifies the creation of REST
// requests.
type Client struct {
	*http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Header is a list of HTTP requests that will be added to every requests
	// originating from this client.
	Header http.Header

	// Limit sets a hard limit on the number of concurrent requests. If not set
	// then no limits are imposed.
	Limit uint

	initialize sync.Once

	limit chan struct{}
}

// NewRequest creates a new Request object for the given HTTP method.
func (client *Client) NewRequest(method string) *Request {
	client.initialize.Do(func() {
		if client.Client == nil {
			client.Client = http.DefaultClient
		}

		if client.Limit > 0 {
			client.limit = make(chan struct{}, client.Limit)

			for i := uint(0); i < client.Limit; i++ {
				client.end()
			}
		}

	})

	headers := make(http.Header)
	if client.Header != nil {
		for key, val := range client.Header {
			headers[key] = val
		}
	}

	return &Request{
		REST:   client,
		Client: client.Client,
		Host:   client.Host,
		Method: method,
		Root:   client.Root,
		Header: headers,
	}
}

func (client *Client) begin() {
	if client.limit != nil {
		<-client.limit
	}
}

func (client *Client) end() {
	if client.limit != nil {
		client.limit <- struct{}{}
	}
}

// Request is used to gradually construct REST requests and send them to a
// remote endpoint. Request object should be created via the NewRequest function
// or the Client.NewRequest function and filled in via the SetXxx and AddXxx
// functions. Finally the request is sent via the Send function which returns a
// Response object.
type Request struct {

	// REST is the client that originated the request. Can be nil.
	REST *Client

	// Client is the http.Client used to send the request. Defaults to
	// http.DefaultClient and can changed via the SetClient method.
	Client *http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Path is the absolute path where the Request should be routed to on the
	// remote endpoint. Can be changed via the SetPath method.
	Path string

	// Method is the HTTP verb used for the HTTP request.
	Method string

	// Header contains all the headers to be added to the HTTP request. Can be
	// changed via the AddHeader method.
	Header http.Header

	// Body is the JSON serialized body of the HTTP request. Can be set via the
	// SetBody method.
	Body []byte

	HTTP *http.Request

	err *Error
}

// NewRequest creates a new Request object to be sent to the given host using
// the given HTTP verb.
func NewRequest(host, method string) *Request {
	return &Request{
		Host:   host,
		Method: method,
		Client: http.DefaultClient,
	}
}

// SetHost selects the host where the request will be sent.
func (req *Request) SetHost(host string) *Request {
	req.Host = host
	return req
}

// SetClient selects the http.Client to be used to execute the requests.
func (req *Request) SetClient(client *http.Client) *Request {
	req.Client = client
	return req
}

// SetPath formats and sets the path where the request will be routed to. Note
// that the root is prefixed to the path before formatting the string.
func (req *Request) SetPath(path string, args ...interface{}) *Request {
	req.Path = fmt.Sprintf(JoinPath(req.Root, path), args...)
	return req
}

// AddHeader adds the given header to the request.
func (req *Request) AddHeader(key, value string) *Request {
	if req.Header == nil {
		req.Header = make(http.Header)
	}

	req.Header.Add(key, value)
	return req
}

// SetBody marshals the given objects and sets it as the body of the
// request. The Content-Length header will be automatically set.
func (req *Request) SetBody(obj interface{}) *Request {
	var err error
	if req.Body, err = json.Marshal(obj); err == nil {
		req.AddHeader("Content-Length", strconv.Itoa(len(req.Body)))

	} else {
		req.err = &Error{MarshalError, err}
	}

	return req
}

// Send attempts to send the request to the remote endpoint and returns a
// Response which contains the result.
func (req *Request) Send() *Response {
	t0 := time.Now()

	if len(req.Path) == 0 {
		req.Path = req.Root
	}

	resp := &Response{Request: req, Error: req.err}

	if resp.Error == nil {
		if req.REST != nil {
			req.REST.begin()
		}

		req.send(resp)

		if req.REST != nil {
			req.REST.end()
		}
	}

	resp.Latency = time.Since(t0)
	return resp
}

func (req *Request) send(resp *Response) {
	var reader io.Reader
	if len(req.Body) > 0 {
		reader = bytes.NewReader(req.Body)
	}

	url := strings.TrimRight(req.Host, "/") + req.Path

	var err error

	if req.HTTP, err = http.NewRequest(req.Method, url, reader); err != nil {
		resp.Error = &Error{NewRequestError, err}
		return
	}

	req.AddHeader("Content-Type", "application/json")
	req.HTTP.Header = req.Header

	httpResp, err := req.Client.Do(req.HTTP)
	if err != nil {
		resp.Error = &Error{SendRequestError, err}
		return
	}

	resp.Code = httpResp.StatusCode
	resp.Header = httpResp.Header

	if resp.Body, err = ioutil.ReadAll(httpResp.Body); err != nil {
		resp.Error = &Error{ReadBodyError, err}
	}

	httpResp.Body.Close()
	return
}

// Response holds the result of a sent REST request. The response should be read
// via the GetBody method which checks the various fields to detect errors.
type Response struct {

	// Request is the request that originated the response.
	Request *Request

	// Code is the http status code returned by the endpoint.
	Code int

	// Header holds the headers of the HTTP response.
	Header http.Header

	// Body holds the raw unmarshalled body of the HTTP response. GetBody can be
	// used to unmarshal the body.
	Body []byte

	// Error is set if an error occured while sending the request.
	Error *Error

	// Latency indicates how long the request round-trip took.
	Latency time.Duration
}

// GetBody checks the various fields of the response for errors and unmarshals
// the response body if the given object is not nil. If an error is detected,
// the error type and error will be returned instead.
func (resp *Response) GetBody(obj interface{}) (err *Error) {
	if resp.Error != nil {
		err = resp.Error

	} else if resp.Code == http.StatusNotFound {
		err = &Error{UnknownRoute, errors.New(string(resp.Body))}

	} else if resp.Code >= 400 {
		err = &Error{EndpointError, errors.New(string(resp.Body))}

	} else if resp.Code < 200 && resp.Code >= 300 {
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: %d", resp.Code)

	} else if resp.Code == http.StatusNoContent {
		if obj == nil {
			return
		}
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: 204")

	} else if contentType := resp.Header.Get("Content-Type"); len(resp.Body) > 0 && contentType != "application/json" {
		err = ErrorFmt(UnsupportedContentType, "unsupported content-type: '%s' != 'application/json'", contentType)

	} else if jsonErr := json.Unmarshal(resp.Body, obj); err != nil {
		err = &Error{UnmarshalError, jsonErr}
	}

	return
}
<commit_msg>Added the Request.SetRawBody()<commit_after>// Copyright (c) 2014 Datacratic. All rights reserved.

package rest

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// Client is a convenience REST client which simplifies the creation of REST
// requests.
type Client struct {
	*http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Header is a list of HTTP requests that will be added to every requests
	// originating from this client.
	Header http.Header

	// Limit sets a hard limit on the number of concurrent requests. If not set
	// then no limits are imposed.
	Limit uint

	initialize sync.Once

	limit chan struct{}
}

// NewRequest creates a new Request object for the given HTTP method.
func (client *Client) NewRequest(method string) *Request {
	client.initialize.Do(func() {
		if client.Client == nil {
			client.Client = http.DefaultClient
		}

		if client.Limit > 0 {
			client.limit = make(chan struct{}, client.Limit)

			for i := uint(0); i < client.Limit; i++ {
				client.end()
			}
		}

	})

	headers := make(http.Header)
	if client.Header != nil {
		for key, val := range client.Header {
			headers[key] = val
		}
	}

	return &Request{
		REST:   client,
		Client: client.Client,
		Host:   client.Host,
		Method: method,
		Root:   client.Root,
		Header: headers,
	}
}

func (client *Client) begin() {
	if client.limit != nil {
		<-client.limit
	}
}

func (client *Client) end() {
	if client.limit != nil {
		client.limit <- struct{}{}
	}
}

// Request is used to gradually construct REST requests and send them to a
// remote endpoint. Request object should be created via the NewRequest function
// or the Client.NewRequest function and filled in via the SetXxx and AddXxx
// functions. Finally the request is sent via the Send function which returns a
// Response object.
type Request struct {

	// REST is the client that originated the request. Can be nil.
	REST *Client

	// Client is the http.Client used to send the request. Defaults to
	// http.DefaultClient and can changed via the SetClient method.
	Client *http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Path is the absolute path where the Request should be routed to on the
	// remote endpoint. Can be changed via the SetPath method.
	Path string

	// Method is the HTTP verb used for the HTTP request.
	Method string

	// Header contains all the headers to be added to the HTTP request. Can be
	// changed via the AddHeader method.
	Header http.Header

	// Body is the JSON serialized body of the HTTP request. Can be set via the
	// SetBody method.
	Body []byte

	HTTP *http.Request

	err *Error
}

// NewRequest creates a new Request object to be sent to the given host using
// the given HTTP verb.
func NewRequest(host, method string) *Request {
	return &Request{
		Host:   host,
		Method: method,
		Client: http.DefaultClient,
	}
}

// SetHost selects the host where the request will be sent.
func (req *Request) SetHost(host string) *Request {
	req.Host = host
	return req
}

// SetClient selects the http.Client to be used to execute the requests.
func (req *Request) SetClient(client *http.Client) *Request {
	req.Client = client
	return req
}

// SetPath formats and sets the path where the request will be routed to. Note
// that the root is prefixed to the path before formatting the string.
func (req *Request) SetPath(path string, args ...interface{}) *Request {
	req.Path = fmt.Sprintf(JoinPath(req.Root, path), args...)
	return req
}

// AddHeader adds the given header to the request.
func (req *Request) AddHeader(key, value string) *Request {
	if req.Header == nil {
		req.Header = make(http.Header)
	}

	req.Header.Add(key, value)
	return req
}

// SetRawBody sets the body of the request to the given set of bytes. The
// Content-Length header will be automatically set.
func (req *Request) SetRawBody(bytes []byte) *Request {
	req.Body = bytes
	req.AddHeader("Content-Length", strconv.Itoa(len(bytes)))
	return req
}

// SetBody marshals the given objects and sets it as the body of the
// request. The Content-Length header will be automatically set.
func (req *Request) SetBody(obj interface{}) *Request {
	var err error
	if req.Body, err = json.Marshal(obj); err == nil {
		req.AddHeader("Content-Length", strconv.Itoa(len(req.Body)))

	} else {
		req.err = &Error{MarshalError, err}
	}

	return req
}

// Send attempts to send the request to the remote endpoint and returns a
// Response which contains the result.
func (req *Request) Send() *Response {
	t0 := time.Now()

	if len(req.Path) == 0 {
		req.Path = req.Root
	}

	resp := &Response{Request: req, Error: req.err}

	if resp.Error == nil {
		if req.REST != nil {
			req.REST.begin()
		}

		req.send(resp)

		if req.REST != nil {
			req.REST.end()
		}
	}

	resp.Latency = time.Since(t0)
	return resp
}

func (req *Request) send(resp *Response) {
	var reader io.Reader
	if len(req.Body) > 0 {
		reader = bytes.NewReader(req.Body)
	}

	url := strings.TrimRight(req.Host, "/") + req.Path

	var err error

	if req.HTTP, err = http.NewRequest(req.Method, url, reader); err != nil {
		resp.Error = &Error{NewRequestError, err}
		return
	}

	req.AddHeader("Content-Type", "application/json")
	req.HTTP.Header = req.Header

	httpResp, err := req.Client.Do(req.HTTP)
	if err != nil {
		resp.Error = &Error{SendRequestError, err}
		return
	}

	resp.Code = httpResp.StatusCode
	resp.Header = httpResp.Header

	if resp.Body, err = ioutil.ReadAll(httpResp.Body); err != nil {
		resp.Error = &Error{ReadBodyError, err}
	}

	httpResp.Body.Close()
	return
}

// Response holds the result of a sent REST request. The response should be read
// via the GetBody method which checks the various fields to detect errors.
type Response struct {

	// Request is the request that originated the response.
	Request *Request

	// Code is the http status code returned by the endpoint.
	Code int

	// Header holds the headers of the HTTP response.
	Header http.Header

	// Body holds the raw unmarshalled body of the HTTP response. GetBody can be
	// used to unmarshal the body.
	Body []byte

	// Error is set if an error occured while sending the request.
	Error *Error

	// Latency indicates how long the request round-trip took.
	Latency time.Duration
}

// GetBody checks the various fields of the response for errors and unmarshals
// the response body if the given object is not nil. If an error is detected,
// the error type and error will be returned instead.
func (resp *Response) GetBody(obj interface{}) (err *Error) {
	if resp.Error != nil {
		err = resp.Error

	} else if resp.Code == http.StatusNotFound {
		err = &Error{UnknownRoute, errors.New(string(resp.Body))}

	} else if resp.Code >= 400 {
		err = &Error{EndpointError, errors.New(string(resp.Body))}

	} else if resp.Code < 200 && resp.Code >= 300 {
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: %d", resp.Code)

	} else if resp.Code == http.StatusNoContent {
		if obj == nil {
			return
		}
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: 204")

	} else if contentType := resp.Header.Get("Content-Type"); len(resp.Body) > 0 && contentType != "application/json" {
		err = ErrorFmt(UnsupportedContentType, "unsupported content-type: '%s' != 'application/json'", contentType)

	} else if jsonErr := json.Unmarshal(resp.Body, obj); err != nil {
		err = &Error{UnmarshalError, jsonErr}
	}

	return
}
<|endoftext|>


<commit_before>package main_test

import (
	"fmt"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"os"
	"os/exec"
	"testing"
)

func TestUtils(t *testing.T) {
	RegisterFailHandler(Fail)
	doSetup()
	RunSpecs(t, "main test suite")
	doTeardown()
}

var (
	cfHome              string
	err                 error
	orgName             = "chaos-galago-smoke"
	spaceName           = orgName
	output              []byte
	serviceInstanceName = "galago_smoke_test"
	appName             = "galago_smoke_test"
)

func doSetup() {
	cfHome = os.Getenv("CF_HOME")
	isEnvSet("CF_HOME", cfHome)
	if _, homeErr := os.Stat(fmt.Sprintf("%s/.cf", cfHome)); homeErr == nil {
		fmt.Println("CF_HOME must be a temp directory")
		os.Exit(1)
	}

	cfPassword := os.Getenv("CF_PASSWORD")
	cfUsername := os.Getenv("CF_USERNAME")
	cfDomain := os.Getenv("CF_DOMAIN")
	isEnvSet("CF_PASSWORD", cfPassword)
	isEnvSet("CF_USERNAME", cfUsername)
	isEnvSet("CF_DOMAIN", cfDomain)

	output, err = exec.Command("cf", "login", "-a", fmt.Sprintf("https://api.%s", cfDomain), "-u", cfUsername, "-p", cfPassword, "--skip-ssl-validation").Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "create-org", orgName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "target", "-o", orgName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "create-space", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "target", "-s", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "push", "-f", "fixtures/galago_smoke_test/manifest.yml").Output()
	freakOutDebug(output, err)
}

func doTeardown() {
	output, err = exec.Command("cf", "delete", "-f", appName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "delete-space", "-f", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "delete-org", "-f", orgName).Output()
	freakOutDebug(output, err)
	os.RemoveAll(fmt.Sprintf("%s/.cf", cfHome))
}

func isEnvSet(envName string, env string) {
	if env == "" {
		fmt.Printf("\n\nEnvironment Variable \"%s\" was not set\n", envName)
		os.Exit(1)
	}
}

func freakOutDebug(output []byte, err error) {
	if err != nil {
		fmt.Printf("\nAn unexpected error occurred: \n%s\n", output)
	}
}
<commit_msg>name by UUID to allow parallel tests<commit_after>package main_test

import (
	"fmt"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/satori/go.uuid"
	"os"
	"os/exec"
	"testing"
)

func TestUtils(t *testing.T) {
	RegisterFailHandler(Fail)
	doSetup()
	RunSpecs(t, "main test suite")
	doTeardown()
}

var (
	cfHome              string
	err                 error
	guid                = uuid.NewV4()
	orgName             = fmt.Sprintf("chaos-galago-smoke-%s", guid)
	spaceName           = orgName
	output              []byte
	serviceInstanceName = fmt.Sprintf("galago_smoke_test_%s", guid)
	appName             = fmt.Sprintf("galago_smoke_test_%s", guid)
)

func doSetup() {
	cfHome = os.Getenv("CF_HOME")
	isEnvSet("CF_HOME", cfHome)
	if _, homeErr := os.Stat(fmt.Sprintf("%s/.cf", cfHome)); homeErr == nil {
		fmt.Println("CF_HOME must be a temp directory")
		os.Exit(1)
	}

	cfPassword := os.Getenv("CF_PASSWORD")
	cfUsername := os.Getenv("CF_USERNAME")
	cfDomain := os.Getenv("CF_DOMAIN")
	isEnvSet("CF_PASSWORD", cfPassword)
	isEnvSet("CF_USERNAME", cfUsername)
	isEnvSet("CF_DOMAIN", cfDomain)

	output, err = exec.Command("cf", "login", "-a", fmt.Sprintf("https://api.%s", cfDomain), "-u", cfUsername, "-p", cfPassword, "--skip-ssl-validation").Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "create-org", orgName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "target", "-o", orgName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "create-space", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "target", "-s", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "push", "-f", "fixtures/galago_smoke_test/manifest.yml").Output()
	freakOutDebug(output, err)
}

func doTeardown() {
	output, err = exec.Command("cf", "delete", "-f", appName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "delete-space", "-f", spaceName).Output()
	freakOutDebug(output, err)
	output, err = exec.Command("cf", "delete-org", "-f", orgName).Output()
	freakOutDebug(output, err)
	os.RemoveAll(fmt.Sprintf("%s/.cf", cfHome))
}

func isEnvSet(envName string, env string) {
	if env == "" {
		fmt.Printf("\n\nEnvironment Variable \"%s\" was not set\n", envName)
		os.Exit(1)
	}
}

func freakOutDebug(output []byte, err error) {
	if err != nil {
		fmt.Printf("\nAn unexpected error occurred: \n%s\n", output)
	}
}
<|endoftext|>


<commit_before>package swarm

import "os"

// Secret represents a secret.
type Secret struct {
	ID string
	Meta
	Spec       SecretSpec
	Digest     string
	SecretSize int64
}

type SecretSpec struct {
	Annotations
	Data []byte
}

type SecretReferenceFileTarget struct {
	Name string
	UID  string
	GID  string
	Mode os.FileMode
}

type SecretReference struct {
	SecretID   string
	SecretName string
	Target     SecretReferenceFileTarget
}

// SecretRequestSpec is a type for requesting secrets
type SecretRequestSpec struct {
	Source string
	Target string
	UID    string
	GID    string
	Mode   os.FileMode
}
<commit_msg>remove SecretRequestSpec<commit_after>package swarm

import "os"

// Secret represents a secret.
type Secret struct {
	ID string
	Meta
	Spec       SecretSpec
	Digest     string
	SecretSize int64
}

type SecretSpec struct {
	Annotations
	Data []byte
}

type SecretReferenceFileTarget struct {
	Name string
	UID  string
	GID  string
	Mode os.FileMode
}

type SecretReference struct {
	SecretID   string
	SecretName string
	Target     SecretReferenceFileTarget
}
<|endoftext|>


<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state

import (
	"fmt"

	"github.com/juju/errors"
	"github.com/juju/names"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"gopkg.in/mgo.v2/txn"

	"github.com/juju/juju/network"
)

// Space represents the state of a juju network space.
type Space struct {
	st  *State
	doc spaceDoc
}

type spaceDoc struct {
	DocID      string `bson:"_id"`
	ModelUUID  string `bson:"model-uuid"`
	Life       Life   `bson:"life"`
	Name       string `bson:"name"`
	IsPublic   bool   `bson:"is-public"`
	ProviderId string `bson:"providerid,omitempty"`
}

type providerIdDoc struct {
}

// Life returns whether the space is Alive, Dying or Dead.
func (s *Space) Life() Life {
	return s.doc.Life
}

// ID returns the unique id for the space, for other entities to reference it
func (s *Space) ID() string {
	return s.doc.DocID
}

// String implements fmt.Stringer.
func (s *Space) String() string {
	return s.doc.Name
}

// Name returns the name of the Space.
func (s *Space) Name() string {
	return s.doc.Name
}

// ProviderId returns the provider id of the space. This will be the empty
// string except on substrates that directly support spaces.
func (s *Space) ProviderId() network.Id {
	return network.Id(s.st.localID(s.doc.ProviderId))
}

// Subnets returns all the subnets associated with the Space.
func (s *Space) Subnets() (results []*Subnet, err error) {
	defer errors.DeferredAnnotatef(&err, "cannot fetch subnets")
	name := s.Name()

	subnetsCollection, closer := s.st.getCollection(subnetsC)
	defer closer()

	var doc subnetDoc
	iter := subnetsCollection.Find(bson.D{{"space-name", name}}).Iter()
	defer iter.Close()
	for iter.Next(&doc) {
		subnet := &Subnet{s.st, doc}
		results = append(results, subnet)
	}
	if err := iter.Err(); err != nil {
		return nil, err
	}
	return results, nil
}

// AddSpace creates and returns a new space.
func (st *State) AddSpace(name string, providerId network.Id, subnets []string, isPublic bool) (newSpace *Space, err error) {
	defer errors.DeferredAnnotatef(&err, "adding space %q", name)
	if !names.IsValidSpace(name) {
		return nil, errors.NewNotValid(nil, "invalid space name")
	}

	spaceID := st.docID(name)
	spaceDoc := spaceDoc{
		DocID:      spaceID,
		ModelUUID:  st.ModelUUID(),
		Life:       Alive,
		Name:       name,
		IsPublic:   isPublic,
		ProviderId: string(providerId),
	}
	newSpace = &Space{doc: spaceDoc, st: st}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     spaceID,
		Assert: txn.DocMissing,
		Insert: spaceDoc,
	}}

	// XXX should this be first?
	if providerId != "" {
		key := fmt.Sprintf("%v:space#%v", st.ModelUUID(), providerId)
		ops = append(ops, txn.Op{
			C:      providerIDsC,
			Id:     key,
			Assert: txn.DocMissing,
		})
	}

	for _, subnetId := range subnets {
		// TODO:(mfoord) once we have refcounting for subnets we should
		// also assert that the refcount is zero as moving the space of a
		// subnet in use is not permitted.
		ops = append(ops, txn.Op{
			C:      subnetsC,
			Id:     st.docID(subnetId),
			Assert: txn.DocExists,
			Update: bson.D{{"$set", bson.D{{"space-name", name}}}},
		})
	}

	if err := st.runTransaction(ops); err == txn.ErrAborted {
		if _, err := st.Space(name); err == nil {
			return nil, errors.AlreadyExistsf("space %q", name)
		}
		for _, subnetId := range subnets {
			if _, err := st.Subnet(subnetId); errors.IsNotFound(err) {
				return nil, err
			}
		}
	} else if err != nil {
		return nil, err
	}

	// If the ProviderId was not unique adding the space can fail without an
	// error. Refreshing catches this by returning NotFoundError.
	err = newSpace.Refresh()
	if err != nil {
		if errors.IsNotFound(err) {
			return nil, errors.Errorf("ProviderId %q not unique", providerId)
		}
		return nil, errors.Trace(err)
	}

	return newSpace, nil
}

// Space returns a space from state that matches the provided name. An error
// is returned if the space doesn't exist or if there was a problem accessing
// its information.
func (st *State) Space(name string) (*Space, error) {
	spaces, closer := st.getCollection(spacesC)
	defer closer()

	var doc spaceDoc
	err := spaces.FindId(name).One(&doc)
	if err == mgo.ErrNotFound {
		return nil, errors.NotFoundf("space %q", name)
	}
	if err != nil {
		return nil, errors.Annotatef(err, "cannot get space %q", name)
	}
	return &Space{st, doc}, nil
}

// AllSpaces returns all spaces for the model.
func (st *State) AllSpaces() ([]*Space, error) {
	spacesCollection, closer := st.getCollection(spacesC)
	defer closer()

	docs := []spaceDoc{}
	err := spacesCollection.Find(nil).All(&docs)
	if err != nil {
		return nil, errors.Annotatef(err, "cannot get all spaces")
	}
	spaces := make([]*Space, len(docs))
	for i, doc := range docs {
		spaces[i] = &Space{st: st, doc: doc}
	}
	return spaces, nil
}

// EnsureDead sets the Life of the space to Dead, if it's Alive. If the space is
// already Dead, no error is returned. When the space is no longer Alive or
// already removed, errNotAlive is returned.
func (s *Space) EnsureDead() (err error) {
	defer errors.DeferredAnnotatef(&err, "cannot set space %q to dead", s)

	if s.doc.Life == Dead {
		return nil
	}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     s.doc.DocID,
		Update: bson.D{{"$set", bson.D{{"life", Dead}}}},
		Assert: isAliveDoc,
	}}

	txnErr := s.st.runTransaction(ops)
	if txnErr == nil {
		s.doc.Life = Dead
		return nil
	}
	return onAbort(txnErr, errNotAlive)
}

// Remove removes a Dead space. If the space is not Dead or it is already
// removed, an error is returned.
func (s *Space) Remove() (err error) {
	defer errors.DeferredAnnotatef(&err, "cannot remove space %q", s)

	if s.doc.Life != Dead {
		return errors.New("space is not dead")
	}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     s.doc.DocID,
		Remove: true,
		Assert: isDeadDoc,
	}}

	txnErr := s.st.runTransaction(ops)
	if txnErr == nil {
		return nil
	}
	return onAbort(txnErr, errors.New("not found or not dead"))
}

// Refresh: refreshes the contents of the Space from the underlying state. It
// returns an error that satisfies errors.IsNotFound if the Space has been
// removed.
func (s *Space) Refresh() error {
	spaces, closer := s.st.getCollection(spacesC)
	defer closer()

	var doc spaceDoc
	err := spaces.FindId(s.doc.DocID).One(&doc)
	if err == mgo.ErrNotFound {
		return errors.NotFoundf("space %q", s)
	} else if err != nil {
		return errors.Errorf("cannot refresh space %q: %v", s, err)
	}
	s.doc = doc
	return nil
}
<commit_msg>Minor tweaks<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state

import (
	"fmt"

	"github.com/juju/errors"
	"github.com/juju/names"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"gopkg.in/mgo.v2/txn"

	"github.com/juju/juju/network"
)

// Space represents the state of a juju network space.
type Space struct {
	st  *State
	doc spaceDoc
}

type spaceDoc struct {
	DocID      string `bson:"_id"`
	ModelUUID  string `bson:"model-uuid"`
	Life       Life   `bson:"life"`
	Name       string `bson:"name"`
	IsPublic   bool   `bson:"is-public"`
	ProviderId string `bson:"providerid,omitempty"`
}

type providerIdDoc struct {
}

// Life returns whether the space is Alive, Dying or Dead.
func (s *Space) Life() Life {
	return s.doc.Life
}

// ID returns the unique id for the space, for other entities to reference it
func (s *Space) ID() string {
	return s.doc.DocID
}

// String implements fmt.Stringer.
func (s *Space) String() string {
	return s.doc.Name
}

// Name returns the name of the Space.
func (s *Space) Name() string {
	return s.doc.Name
}

// ProviderId returns the provider id of the space. This will be the empty
// string except on substrates that directly support spaces.
func (s *Space) ProviderId() network.Id {
	return network.Id(s.doc.ProviderId)
}

// Subnets returns all the subnets associated with the Space.
func (s *Space) Subnets() (results []*Subnet, err error) {
	defer errors.DeferredAnnotatef(&err, "cannot fetch subnets")
	name := s.Name()

	subnetsCollection, closer := s.st.getCollection(subnetsC)
	defer closer()

	var doc subnetDoc
	iter := subnetsCollection.Find(bson.D{{"space-name", name}}).Iter()
	defer iter.Close()
	for iter.Next(&doc) {
		subnet := &Subnet{s.st, doc}
		results = append(results, subnet)
	}
	if err := iter.Err(); err != nil {
		return nil, err
	}
	return results, nil
}

// AddSpace creates and returns a new space.
func (st *State) AddSpace(name string, providerId network.Id, subnets []string, isPublic bool) (newSpace *Space, err error) {
	defer errors.DeferredAnnotatef(&err, "adding space %q", name)
	if !names.IsValidSpace(name) {
		return nil, errors.NewNotValid(nil, "invalid space name")
	}

	spaceID := st.docID(name)
	spaceDoc := spaceDoc{
		DocID:      spaceID,
		ModelUUID:  st.ModelUUID(),
		Life:       Alive,
		Name:       name,
		IsPublic:   isPublic,
		ProviderId: string(providerId),
	}
	newSpace = &Space{doc: spaceDoc, st: st}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     spaceID,
		Assert: txn.DocMissing,
		Insert: spaceDoc,
	}}

	if providerId != "" {
		key := fmt.Sprintf("%v:space#%v", st.ModelUUID(), providerId)
		ops = append(ops, txn.Op{
			C:      providerIDsC,
			Id:     key,
			Assert: txn.DocMissing,
		})
	}

	for _, subnetId := range subnets {
		// TODO:(mfoord) once we have refcounting for subnets we should
		// also assert that the refcount is zero as moving the space of a
		// subnet in use is not permitted.
		ops = append(ops, txn.Op{
			C:      subnetsC,
			Id:     st.docID(subnetId),
			Assert: txn.DocExists,
			Update: bson.D{{"$set", bson.D{{"space-name", name}}}},
		})
	}

	if err := st.runTransaction(ops); err == txn.ErrAborted {
		if _, err := st.Space(name); err == nil {
			return nil, errors.AlreadyExistsf("space %q", name)
		}
		for _, subnetId := range subnets {
			if _, err := st.Subnet(subnetId); errors.IsNotFound(err) {
				return nil, err
			}
		}
	} else if err != nil {
		return nil, err
	}

	// If the ProviderId was not unique adding the space can fail without an
	// error. Refreshing catches this by returning NotFoundError.
	err = newSpace.Refresh()
	if err != nil {
		if errors.IsNotFound(err) {
			return nil, errors.Errorf("ProviderId %q not unique", providerId)
		}
		return nil, errors.Trace(err)
	}

	return newSpace, nil
}

// Space returns a space from state that matches the provided name. An error
// is returned if the space doesn't exist or if there was a problem accessing
// its information.
func (st *State) Space(name string) (*Space, error) {
	spaces, closer := st.getCollection(spacesC)
	defer closer()

	var doc spaceDoc
	err := spaces.FindId(name).One(&doc)
	if err == mgo.ErrNotFound {
		return nil, errors.NotFoundf("space %q", name)
	}
	if err != nil {
		return nil, errors.Annotatef(err, "cannot get space %q", name)
	}
	return &Space{st, doc}, nil
}

// AllSpaces returns all spaces for the model.
func (st *State) AllSpaces() ([]*Space, error) {
	spacesCollection, closer := st.getCollection(spacesC)
	defer closer()

	docs := []spaceDoc{}
	err := spacesCollection.Find(nil).All(&docs)
	if err != nil {
		return nil, errors.Annotatef(err, "cannot get all spaces")
	}
	spaces := make([]*Space, len(docs))
	for i, doc := range docs {
		spaces[i] = &Space{st: st, doc: doc}
	}
	return spaces, nil
}

// EnsureDead sets the Life of the space to Dead, if it's Alive. If the space is
// already Dead, no error is returned. When the space is no longer Alive or
// already removed, errNotAlive is returned.
func (s *Space) EnsureDead() (err error) {
	defer errors.DeferredAnnotatef(&err, "cannot set space %q to dead", s)

	if s.doc.Life == Dead {
		return nil
	}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     s.doc.DocID,
		Update: bson.D{{"$set", bson.D{{"life", Dead}}}},
		Assert: isAliveDoc,
	}}

	txnErr := s.st.runTransaction(ops)
	if txnErr == nil {
		s.doc.Life = Dead
		return nil
	}
	return onAbort(txnErr, errNotAlive)
}

// Remove removes a Dead space. If the space is not Dead or it is already
// removed, an error is returned.
func (s *Space) Remove() (err error) {
	defer errors.DeferredAnnotatef(&err, "cannot remove space %q", s)

	if s.doc.Life != Dead {
		return errors.New("space is not dead")
	}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     s.doc.DocID,
		Remove: true,
		Assert: isDeadDoc,
	}}

	txnErr := s.st.runTransaction(ops)
	if txnErr == nil {
		return nil
	}
	return onAbort(txnErr, errors.New("not found or not dead"))
}

// Refresh: refreshes the contents of the Space from the underlying state. It
// returns an error that satisfies errors.IsNotFound if the Space has been
// removed.
func (s *Space) Refresh() error {
	spaces, closer := s.st.getCollection(spacesC)
	defer closer()

	var doc spaceDoc
	err := spaces.FindId(s.doc.DocID).One(&doc)
	if err == mgo.ErrNotFound {
		return errors.NotFoundf("space %q", s)
	} else if err != nil {
		return errors.Errorf("cannot refresh space %q: %v", s, err)
	}
	s.doc = doc
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"go/importer"
	"go/parser"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"go/types"

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

var (
	buildContext = build.Default

	loaderConfig = loader.Config{
		ParserMode: parser.ParseComments,
		TypeChecker: types.Config{
			Importer:    importer.Default(),
			FakeImportC: true,
		},
		Build:       &buildContext,
		AllowErrors: true,
	}

	config *srcfileConfig

	goBinaryName string

	validVersions = []string{"", "1.3", "1.2", "1.1", "1"}

	// effectiveConfigGOPATHs is a list of GOPATH dirs that were
	// created as a result of the GOPATH config property. These are
	// the dirs that are appended to the actual build context GOPATH.
	effectiveConfigGOPATHs []string
)

// isInEffectiveConfigGOPATH is true if dir is underneath any of the
// dirs in effectiveConfigGOPATHs.
func isInEffectiveConfigGOPATH(dir string) bool {
	for _, gopath := range effectiveConfigGOPATHs {
		if pathHasPrefix(dir, gopath) {
			return true
		}
	}
	return false
}

type srcfileConfig struct {
	// GOROOT, if specified, is made absolute (prefixed with the
	// directory that the repository being built is checked out to)
	// and is set as the GOROOT environment variable.
	GOROOT string

	// GOROOTForCmd, if set, is used as the GOROOT env var when
	// invoking the "go" tool.
	GOROOTForCmd string

	// GOPATH's colon-separated dirs, if specified, are made absolute
	// (prefixed with the directory that the repository being built is
	// checked out to) and the resulting value is appended to the
	// GOPATH environment variable during the build.
	GOPATH string

	// GOVERSION is the version of the go tool that srclib-go
	// should shell out to. If GOVERSION is empty, the system's
	// default go binary is used. The only valid values for
	// GOVERSION are the empty string, "1.3", "1.2", "1.1", and
	// "1", which are transformed into "go", "go1.3", ..., "go1",
	// respectively, when the binary is called.
	GOVERSION string

	// SkipGodeps makes srclib-go skip the Godeps/_workspace directory when
	// scanning for packages. This causes references to those packages to point
	// to the files in their respective repositories instead of the local copies
	// inside of Godeps/_workspace.
	SkipGodeps bool

	// ImportPathRoot is a prefix which is used when converting from repository
	// URI to Go import path.
	ImportPathRoot string
}

// unmarshalTypedConfig parses config from the Config field of the source unit.
// It stores it in the config global variable.
//
// Callers should typically call config.apply() after calling
// unmarshalTypedConfig to actually apply the config.
func unmarshalTypedConfig(cfg map[string]string) error {
	data, err := json.Marshal(cfg)
	if err != nil {
		return err
	}

	if err := json.Unmarshal(data, &config); err != nil {
		return err
	}

	if config == nil {
		config = &srcfileConfig{}
	}

	return config.apply()
}

// apply applies the configuration.
func (c *srcfileConfig) apply() error {
	// KLUDGE: determine whether we're in the stdlib and if so, set GOROOT to "." before applying config.
	// This is necessary for the stdlib unit names to be correct.
	cloneURL, err := exec.Command("git", "config", "--get", "remote.origin.url").Output()
	if err == nil && strings.HasSuffix(strings.TrimSpace(string(cloneURL)), "github.com/golang/go") && c.GOROOT == "" {
		c.GOROOT = "."
	}

	var versionValid bool
	for _, v := range validVersions {
		if config.GOVERSION == v {
			versionValid = true
			goBinaryName = fmt.Sprintf("go%s", config.GOVERSION)
			if config.GOVERSION != "" && config.GOROOT == "" {
				// If GOROOT is empty, assign $GOROOT<version_num> to it.
				newGOROOT := os.Getenv(fmt.Sprintf("GOROOT%s", strings.Replace(config.GOVERSION, ".", "", -1)))
				if newGOROOT != "" {
					config.GOROOTForCmd = newGOROOT
				}
			}
			break
		}
	}
	if !versionValid {
		return fmt.Errorf("The version %s is not valid. Use one of the following: %v", config.GOVERSION, validVersions)
	}

	if config.GOROOT != "" {
		// clean/absolutize all paths
		config.GOROOT = filepath.Clean(config.GOROOT)
		if !filepath.IsAbs(config.GOROOT) {
			config.GOROOT = filepath.Join(cwd, config.GOROOT)
		}

		buildContext.GOROOT = c.GOROOT
		loaderConfig.Build = &buildContext
	}

	if config.GOPATH != "" {
		// clean/absolutize all paths
		dirs := cleanDirs(filepath.SplitList(config.GOPATH))
		config.GOPATH = strings.Join(dirs, string(filepath.ListSeparator))

		dirs = append(dirs, filepath.SplitList(buildContext.GOPATH)...)
		buildContext.GOPATH = strings.Join(uniq(dirs), string(filepath.ListSeparator))
		loaderConfig.Build = &buildContext
	}

	if config.GOROOTForCmd == "" {
		config.GOROOTForCmd = buildContext.GOROOT
	}

	return nil
}

func (c *srcfileConfig) env() []string {
	return []string{
		"PATH=" + os.Getenv("PATH"),
		"GOARCH=" + buildContext.GOARCH,
		"GOOS=" + buildContext.GOOS,
		"GOROOT=" + config.GOROOTForCmd,
		"GOPATH=" + buildContext.GOPATH,
		"GO15VENDOREXPERIMENT=1",
	}
}

func pathHasPrefix(path, prefix string) bool {
	return prefix == "." || path == prefix || strings.HasPrefix(path, prefix+string(filepath.Separator))
}

// cleanDirs takes a list of paths cleans/abs them + removes duplicates
func cleanDirs(dirs []string) []string {
	dirs = uniq(dirs)
	for i, dir := range dirs {
		dir = filepath.Clean(dir)
		if !filepath.IsAbs(dir) {
			dir = filepath.Join(cwd, dir)
		}
		dirs[i] = dir
	}
	return dirs
}

// uniq maintains the order of s.
func uniq(s []string) []string {
	seen := make(map[string]struct{}, len(s))
	var uniq []string
	for _, s := range s {
		if _, seen := seen[s]; seen {
			continue
		}
		seen[s] = struct{}{}
		uniq = append(uniq, s)
	}
	return uniq
}
<commit_msg>removed unused srcfileConfig.env<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"go/importer"
	"go/parser"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"go/types"

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

var (
	buildContext = build.Default

	loaderConfig = loader.Config{
		ParserMode: parser.ParseComments,
		TypeChecker: types.Config{
			Importer:    importer.Default(),
			FakeImportC: true,
		},
		Build:       &buildContext,
		AllowErrors: true,
	}

	config *srcfileConfig

	goBinaryName string

	validVersions = []string{"", "1.3", "1.2", "1.1", "1"}

	// effectiveConfigGOPATHs is a list of GOPATH dirs that were
	// created as a result of the GOPATH config property. These are
	// the dirs that are appended to the actual build context GOPATH.
	effectiveConfigGOPATHs []string
)

// isInEffectiveConfigGOPATH is true if dir is underneath any of the
// dirs in effectiveConfigGOPATHs.
func isInEffectiveConfigGOPATH(dir string) bool {
	for _, gopath := range effectiveConfigGOPATHs {
		if pathHasPrefix(dir, gopath) {
			return true
		}
	}
	return false
}

type srcfileConfig struct {
	// GOROOT, if specified, is made absolute (prefixed with the
	// directory that the repository being built is checked out to)
	// and is set as the GOROOT environment variable.
	GOROOT string

	// GOROOTForCmd, if set, is used as the GOROOT env var when
	// invoking the "go" tool.
	GOROOTForCmd string

	// GOPATH's colon-separated dirs, if specified, are made absolute
	// (prefixed with the directory that the repository being built is
	// checked out to) and the resulting value is appended to the
	// GOPATH environment variable during the build.
	GOPATH string

	// GOVERSION is the version of the go tool that srclib-go
	// should shell out to. If GOVERSION is empty, the system's
	// default go binary is used. The only valid values for
	// GOVERSION are the empty string, "1.3", "1.2", "1.1", and
	// "1", which are transformed into "go", "go1.3", ..., "go1",
	// respectively, when the binary is called.
	GOVERSION string

	// SkipGodeps makes srclib-go skip the Godeps/_workspace directory when
	// scanning for packages. This causes references to those packages to point
	// to the files in their respective repositories instead of the local copies
	// inside of Godeps/_workspace.
	SkipGodeps bool

	// ImportPathRoot is a prefix which is used when converting from repository
	// URI to Go import path.
	ImportPathRoot string
}

// unmarshalTypedConfig parses config from the Config field of the source unit.
// It stores it in the config global variable.
//
// Callers should typically call config.apply() after calling
// unmarshalTypedConfig to actually apply the config.
func unmarshalTypedConfig(cfg map[string]string) error {
	data, err := json.Marshal(cfg)
	if err != nil {
		return err
	}

	if err := json.Unmarshal(data, &config); err != nil {
		return err
	}

	if config == nil {
		config = &srcfileConfig{}
	}

	return config.apply()
}

// apply applies the configuration.
func (c *srcfileConfig) apply() error {
	// KLUDGE: determine whether we're in the stdlib and if so, set GOROOT to "." before applying config.
	// This is necessary for the stdlib unit names to be correct.
	cloneURL, err := exec.Command("git", "config", "--get", "remote.origin.url").Output()
	if err == nil && strings.HasSuffix(strings.TrimSpace(string(cloneURL)), "github.com/golang/go") && c.GOROOT == "" {
		c.GOROOT = "."
	}

	var versionValid bool
	for _, v := range validVersions {
		if config.GOVERSION == v {
			versionValid = true
			goBinaryName = fmt.Sprintf("go%s", config.GOVERSION)
			if config.GOVERSION != "" && config.GOROOT == "" {
				// If GOROOT is empty, assign $GOROOT<version_num> to it.
				newGOROOT := os.Getenv(fmt.Sprintf("GOROOT%s", strings.Replace(config.GOVERSION, ".", "", -1)))
				if newGOROOT != "" {
					config.GOROOTForCmd = newGOROOT
				}
			}
			break
		}
	}
	if !versionValid {
		return fmt.Errorf("The version %s is not valid. Use one of the following: %v", config.GOVERSION, validVersions)
	}

	if config.GOROOT != "" {
		// clean/absolutize all paths
		config.GOROOT = filepath.Clean(config.GOROOT)
		if !filepath.IsAbs(config.GOROOT) {
			config.GOROOT = filepath.Join(cwd, config.GOROOT)
		}

		buildContext.GOROOT = c.GOROOT
		loaderConfig.Build = &buildContext
	}

	if config.GOPATH != "" {
		// clean/absolutize all paths
		dirs := cleanDirs(filepath.SplitList(config.GOPATH))
		config.GOPATH = strings.Join(dirs, string(filepath.ListSeparator))

		dirs = append(dirs, filepath.SplitList(buildContext.GOPATH)...)
		buildContext.GOPATH = strings.Join(uniq(dirs), string(filepath.ListSeparator))
		loaderConfig.Build = &buildContext
	}

	if config.GOROOTForCmd == "" {
		config.GOROOTForCmd = buildContext.GOROOT
	}

	return nil
}

func pathHasPrefix(path, prefix string) bool {
	return prefix == "." || path == prefix || strings.HasPrefix(path, prefix+string(filepath.Separator))
}

// cleanDirs takes a list of paths cleans/abs them + removes duplicates
func cleanDirs(dirs []string) []string {
	dirs = uniq(dirs)
	for i, dir := range dirs {
		dir = filepath.Clean(dir)
		if !filepath.IsAbs(dir) {
			dir = filepath.Join(cwd, dir)
		}
		dirs[i] = dir
	}
	return dirs
}

// uniq maintains the order of s.
func uniq(s []string) []string {
	seen := make(map[string]struct{}, len(s))
	var uniq []string
	for _, s := range s {
		if _, seen := seen[s]; seen {
			continue
		}
		seen[s] = struct{}{}
		uniq = append(uniq, s)
	}
	return uniq
}
<|endoftext|>


<commit_before>package main

import (
  "encoding/json"
  "os"
  "log"
  "time"
)

type Config struct {
  Network NetworkConfig `json:network`
  Files []FileConfig `json:files`
}

type NetworkConfig struct {
  Servers []string `json:servers`
  SSLCertificate string `json:"ssl certificate"`
  SSLKey string `json:"ssl key"`
  SSLCA string `json:"ssl ca"`
  Timeout time.Duration `json:timeout`
}

type FileConfig struct {
  Paths []string `json:paths`
  Fields map[string]string `json:fields`
}

func LoadConfig(path string) (config Config, err error) {
  config_file, err := os.Open(path)
  if err != nil {
    log.Printf("Failed to open config file '%s': %s\n", path, err)
    return
  }

  fi, _ := config_file.Stat()
  if fi.Size() > (10 << 20) {
    log.Printf("Config file too large? Aborting, just in case. '%s' is %d bytes\n",
               path, fi)
    return
  }

  buffer := make([]byte, fi.Size())
  _, err = config_file.Read(buffer)
  log.Printf("%s\n", buffer)

  err = json.Unmarshal(buffer, &config)
  if err != nil {
    log.Printf("Failed unmarshalling json: %s\n", err)
    return
  }

  if config.Network.Timeout == 0 {
    config.Network.Timeout = 5 * time.Second
  }

  return
}
<commit_msg>- disable DeadTime for now<commit_after>package main

import (
  "encoding/json"
  "os"
  "log"
  "time"
)

type Config struct {
  Network NetworkConfig `json:network`
  Files []FileConfig `json:files`
}

type NetworkConfig struct {
  Servers []string `json:servers`
  SSLCertificate string `json:"ssl certificate"`
  SSLKey string `json:"ssl key"`
  SSLCA string `json:"ssl ca"`
  Timeout time.Duration `json:timeout`
}

type FileConfig struct {
  Paths []string `json:paths`
  Fields map[string]string `json:fields`
  //DeadTime time.Duration `json:"dead time"`
}

func LoadConfig(path string) (config Config, err error) {
  config_file, err := os.Open(path)
  if err != nil {
    log.Printf("Failed to open config file '%s': %s\n", path, err)
    return
  }

  fi, _ := config_file.Stat()
  if fi.Size() > (10 << 20) {
    log.Printf("Config file too large? Aborting, just in case. '%s' is %d bytes\n",
               path, fi)
    return
  }

  buffer := make([]byte, fi.Size())
  _, err = config_file.Read(buffer)
  log.Printf("%s\n", buffer)

  err = json.Unmarshal(buffer, &config)
  if err != nil {
    log.Printf("Failed unmarshalling json: %s\n", err)
    return
  }

  if config.Network.Timeout == 0 {
    config.Network.Timeout = 5 * time.Second
  }

  //for _, fileconfig := range config.Files {
    //if fileconfig.DeadTime == 0 {
      //fileconfig.DeadTime = 24 * time.Hour
    //}
  //}

  return
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/michaelsauter/crane/print"
	"gopkg.in/v1/yaml"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var targetsSpecifiedManually = false

func getContainers(options Options) Containers {

	if len(options.config) > 0 {
		return unmarshalJSON([]byte(options.config))
	}

	targets := NewTargets(options.targets)
	for _, f := range manifestFiles() {
		if _, err := os.Stat(f); err == nil {
			return getContainersFromManifestFile(f, targets)
		}
	}
	panic(fmt.Sprintf("No configuration found %v", manifestFiles()))
}

func getContainersFromManifestFile(filename string, targets Targets) Containers {
	result := Containers{}
	all_containers := readCraneData(filename)

	for _, c := range all_containers {
		if targets.Includes(c.Name) {
			result = append(result, c)
		}
	}
	if len(result) == 0 {
		panic(fmt.Sprintf("No matching targets found."))
	}

	return result
}

func readCraneData(filename string) Containers {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}

	if filename == "Cranefile" {
		print.Notice("Using a Cranefile is deprecated. Please use crane.json/crane.yaml instead.\n")
	}

	ext := filepath.Ext(filename)
	if ext == ".json" {
		return unmarshalJSON(data)
	} else if ext == ".yml" || ext == ".yaml" {
		return unmarshalYAML(data)
	} else if ext == "" {
		return unmarshalJSON(data)
	} else {
		panic("Unrecognized file extension")
	}
}

// Thanks to https://github.com/markpeek/packer/commit/5bf33a0e91b2318a40c42e9bf855dcc8dd4cdec5
func displaySyntaxError(data []byte, syntaxError error) (err error) {
	syntax, ok := syntaxError.(*json.SyntaxError)
	if !ok {
		err = syntaxError
		return
	}
	newline := []byte{'\x0a'}
	space := []byte{' '}

	start, end := bytes.LastIndex(data[:syntax.Offset], newline)+1, len(data)
	if idx := bytes.Index(data[start:], newline); idx >= 0 {
		end = start + idx
	}

	line, pos := bytes.Count(data[:start], newline)+1, int(syntax.Offset)-start-1

	err = fmt.Errorf("\nError in line %d: %s \n%s\n%s^", line, syntaxError, data[start:end], bytes.Repeat(space, pos))
	return
}

func unmarshalJSON(data []byte) Containers {
	var containers Containers
	err := json.Unmarshal(data, &containers)
	if err != nil {
		err = displaySyntaxError(data, err)
		panic(err)
	}
	return containers
}

func unmarshalYAML(data []byte) Containers {
	var containers Containers
	err := yaml.Unmarshal(data, &containers)
	if err != nil {
		err = displaySyntaxError(data, err)
		panic(err)
	}
	return containers
}

type Targets interface {
	Includes(name string) bool
}

type AllTargets string
func (AllTargets) Includes(name string) bool {
	return true
}

type TargetSet map[string]bool
func (t TargetSet) Includes(name string) bool {
	return t[name]
}

func NewTargets(target_spec string) Targets {
	if len(target_spec) == 0 {
		return AllTargets("")
	}

	targetsSpecifiedManually = true
	result := make(TargetSet)
	for _, t := range strings.Split(target_spec, ",") {
		t = strings.TrimSpace(t)
		result[t] = true
	}
	return result
}

func isManualTargetting() bool {
	return targetsSpecifiedManually
}
<commit_msg>expand environment in entire manifest file<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/michaelsauter/crane/print"
	"gopkg.in/v1/yaml"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var targetsSpecifiedManually = false

func getContainers(options Options) Containers {

	if len(options.config) > 0 {
		return unmarshalJSON([]byte(options.config))
	}

	targets := NewTargets(options.targets)
	for _, f := range manifestFiles() {
		if _, err := os.Stat(f); err == nil {
			return getContainersFromManifestFile(f, targets)
		}
	}
	panic(fmt.Sprintf("No configuration found %v", manifestFiles()))
}

func getContainersFromManifestFile(filename string, targets Targets) Containers {
	result := Containers{}
	all_containers := readCraneData(filename)

	for _, c := range all_containers {
		if targets.Includes(c.Name) {
			result = append(result, c)
		}
	}
	if len(result) == 0 {
		panic(fmt.Sprintf("No matching targets found."))
	}

	return result
}

func readCraneData(filename string) Containers {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}

	if filename == "Cranefile" {
		print.Notice("Using a Cranefile is deprecated. Please use crane.json/crane.yaml instead.\n")
	}

	environ_data := []byte(os.ExpandEnv(string(data)))
	ext := filepath.Ext(filename)
	if ext == ".json" {
		return unmarshalJSON(environ_data)
	} else if ext == ".yml" || ext == ".yaml" {
		return unmarshalYAML(environ_data)
	} else if ext == "" {
		return unmarshalJSON(environ_data)
	} else {
		panic("Unrecognized file extension")
	}
}

// Thanks to https://github.com/markpeek/packer/commit/5bf33a0e91b2318a40c42e9bf855dcc8dd4cdec5
func displaySyntaxError(data []byte, syntaxError error) (err error) {
	syntax, ok := syntaxError.(*json.SyntaxError)
	if !ok {
		err = syntaxError
		return
	}
	newline := []byte{'\x0a'}
	space := []byte{' '}

	start, end := bytes.LastIndex(data[:syntax.Offset], newline)+1, len(data)
	if idx := bytes.Index(data[start:], newline); idx >= 0 {
		end = start + idx
	}

	line, pos := bytes.Count(data[:start], newline)+1, int(syntax.Offset)-start-1

	err = fmt.Errorf("\nError in line %d: %s \n%s\n%s^", line, syntaxError, data[start:end], bytes.Repeat(space, pos))
	return
}

func unmarshalJSON(data []byte) Containers {
	var containers Containers
	err := json.Unmarshal(data, &containers)
	if err != nil {
		err = displaySyntaxError(data, err)
		panic(err)
	}
	return containers
}

func unmarshalYAML(data []byte) Containers {
	var containers Containers
	err := yaml.Unmarshal(data, &containers)
	if err != nil {
		err = displaySyntaxError(data, err)
		panic(err)
	}
	return containers
}

type Targets interface {
	Includes(name string) bool
}

type AllTargets string

func (AllTargets) Includes(name string) bool {
	return true
}

type TargetSet map[string]bool

func (t TargetSet) Includes(name string) bool {
	return t[name]
}

func NewTargets(target_spec string) Targets {
	if len(target_spec) == 0 {
		return AllTargets("")
	}

	targetsSpecifiedManually = true
	result := make(TargetSet)
	for _, t := range strings.Split(target_spec, ",") {
		t = strings.TrimSpace(t)
		result[t] = true
	}
	return result
}

func isManualTargetting() bool {
	return targetsSpecifiedManually
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"os"

	"code.google.com/p/gcfg"
)

// Configuration is Ourd's configuration
type Configuration struct {
	HTTP struct {
		Host string
	}
	App struct {
		Name   string
		APIKey string `gcfg:"api-key"`
	}
	DB struct {
		ImplName string `gcfg:"implementation"`
		Option   string
	}
	TokenStore struct {
		Path string `gcfg:"path"`
	} `gcfg:"token-store"`
	AssetStore struct {
		ImplName string `gcfg:"implementation"`

		// followings only used when ImplName = fs
		Path string

		// followings only used when ImplName = s3
		AccessToken string `gcfg:"access-key"`
		SecretToken string `gcfg:"secret-key"`
		Reigon      string
		Bucket      string
	} `gcfg:"asset-store"`
	AssetURLSigner struct {
		URLPrefix string `gcfg:"url-prefix"`
		Secret    string
	} `gcfg:"asset-url-signer"`
	APNS struct {
		Enable   bool
		Env      string
		Cert     string
		Key      string
		CertPath string `gcfg:"cert-path"`
		KeyPath  string `gcfg:"key-path"`
	}
	LOG struct {
		Level string
	}
	LogHook struct {
		SentryDSN   string `gcfg:"sentry-dsn"`
		SentryLevel string `gcfg:"sentry-level"`
	} `gcfg:"log-hook"`
	Plugin map[string]*struct {
		Transport string
		Path      string
		Args      []string
	}
}

// ReadFileInto reads a configuration from file specified by path
func ReadFileInto(config *Configuration, path string) error {
	if err := gcfg.ReadFileInto(config, path); err != nil {
		return err
	}
	if config.HTTP.Host == "" {
		port := os.Getenv("PORT")
		if port == "" {
			port = "3000"
		}
		config.HTTP.Host = ":" + port
	}

	appAPIKey := os.Getenv("API_KEY")
	if appAPIKey != "" {
		config.App.APIKey = appAPIKey
	}

	dbImplName := os.Getenv("DB_IMPL_NAME")
	if dbImplName != "" {
		config.DB.ImplName = dbImplName
	}

	if config.DB.ImplName == "pq" && os.Getenv("DATABASE_URL") != "" {
		config.DB.Option = os.Getenv("DATABASE_URL")
	}

	shouldEnableAPNS := os.Getenv("APNS_ENABLE")
	if shouldEnableAPNS != "" {
		config.APNS.Enable = shouldEnableAPNS == "1"
	}

	env := os.Getenv("APNS_ENV")
	if env != "" {
		config.APNS.Env = env
	}

	cert, key := os.Getenv("APNS_CERTIFICATE"), os.Getenv("APNS_PRIVATE_KEY")
	if cert != "" {
		config.APNS.Cert = cert
	}
	if key != "" {
		config.APNS.Key = key
	}

	if config.APNS.Cert == "" && config.APNS.CertPath != "" {
		certPEMBlock, err := ioutil.ReadFile(config.APNS.CertPath)
		if err != nil {
			return err
		}
		config.APNS.Cert = string(certPEMBlock)
	}

	if config.APNS.Key == "" && config.APNS.KeyPath != "" {
		keyPEMBlock, err := ioutil.ReadFile(config.APNS.KeyPath)
		if err != nil {
			return err
		}
		config.APNS.Key = string(keyPEMBlock)
	}

	return nil
}
<commit_msg>config: please config parser by adding a section for alembic<commit_after>package main

import (
	"io/ioutil"
	"os"

	"code.google.com/p/gcfg"
)

// Configuration is Ourd's configuration
type Configuration struct {
	HTTP struct {
		Host string
	}
	App struct {
		Name   string
		APIKey string `gcfg:"api-key"`
	}
	DB struct {
		ImplName string `gcfg:"implementation"`
		Option   string
	}
	TokenStore struct {
		Path string `gcfg:"path"`
	} `gcfg:"token-store"`
	AssetStore struct {
		ImplName string `gcfg:"implementation"`

		// followings only used when ImplName = fs
		Path string

		// followings only used when ImplName = s3
		AccessToken string `gcfg:"access-key"`
		SecretToken string `gcfg:"secret-key"`
		Reigon      string
		Bucket      string
	} `gcfg:"asset-store"`
	AssetURLSigner struct {
		URLPrefix string `gcfg:"url-prefix"`
		Secret    string
	} `gcfg:"asset-url-signer"`
	APNS struct {
		Enable   bool
		Env      string
		Cert     string
		Key      string
		CertPath string `gcfg:"cert-path"`
		KeyPath  string `gcfg:"key-path"`
	}
	LOG struct {
		Level string
	}
	LogHook struct {
		SentryDSN   string `gcfg:"sentry-dsn"`
		SentryLevel string `gcfg:"sentry-level"`
	} `gcfg:"log-hook"`
	Plugin map[string]*struct {
		Transport string
		Path      string
		Args      []string
	}
	// the alembic section here is to make the config be parsed correctly
	// the values should not be used
	UselessAlembic struct {
		ScriptLocation string `gcfg:"script_location"`
	} `gcfg:"alembic"`
}

// ReadFileInto reads a configuration from file specified by path
func ReadFileInto(config *Configuration, path string) error {
	if err := gcfg.ReadFileInto(config, path); err != nil {
		return err
	}
	if config.HTTP.Host == "" {
		port := os.Getenv("PORT")
		if port == "" {
			port = "3000"
		}
		config.HTTP.Host = ":" + port
	}

	appAPIKey := os.Getenv("API_KEY")
	if appAPIKey != "" {
		config.App.APIKey = appAPIKey
	}

	dbImplName := os.Getenv("DB_IMPL_NAME")
	if dbImplName != "" {
		config.DB.ImplName = dbImplName
	}

	if config.DB.ImplName == "pq" && os.Getenv("DATABASE_URL") != "" {
		config.DB.Option = os.Getenv("DATABASE_URL")
	}

	shouldEnableAPNS := os.Getenv("APNS_ENABLE")
	if shouldEnableAPNS != "" {
		config.APNS.Enable = shouldEnableAPNS == "1"
	}

	env := os.Getenv("APNS_ENV")
	if env != "" {
		config.APNS.Env = env
	}

	cert, key := os.Getenv("APNS_CERTIFICATE"), os.Getenv("APNS_PRIVATE_KEY")
	if cert != "" {
		config.APNS.Cert = cert
	}
	if key != "" {
		config.APNS.Key = key
	}

	if config.APNS.Cert == "" && config.APNS.CertPath != "" {
		certPEMBlock, err := ioutil.ReadFile(config.APNS.CertPath)
		if err != nil {
			return err
		}
		config.APNS.Cert = string(certPEMBlock)
	}

	if config.APNS.Key == "" && config.APNS.KeyPath != "" {
		keyPEMBlock, err := ioutil.ReadFile(config.APNS.KeyPath)
		if err != nil {
			return err
		}
		config.APNS.Key = string(keyPEMBlock)
	}

	return nil
}
<|endoftext|>


<commit_before>package webgo

import (
	"encoding/json"
	"io/ioutil"
	"strconv"
	"time"
)

// Config is used for reading app's configuration from json file
type Config struct {
	// Host is the host on which the server is listening
	Host string `json:"host,omitempty"`
	// Port is the port number where the server has to listen for the HTTP requests
	Port string `json:"port,omitempty"`

	// CertFile is the TLS/SSL certificate file path, required for HTTPS
	CertFile string `json:"certFile,omitempty"`
	// KeyFile is the filepath of private key of the certificate
	KeyFile string `json:"keyFile,omitempty"`
	// HTTPSPort is the port number where the server has to listen for the HTTP requests
	HTTPSPort string `json:"httpsPort,omitempty"`

	// readTimeout is the maximum duration for which the server would read a request
	ReadTimeout time.Duration `json:"readTimeout,omitempty"`
	// writeTimeout is the maximum duration for which the server would try to respond
	WriteTimeout time.Duration `json:"writeTimeout,omitempty"`

	// InsecureSkipVerify is the HTTP certificate verification
	InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}

// Load config file from the provided filepath and validate
func (cfg *Config) Load(filepath string) {
	file, err := ioutil.ReadFile(filepath)
	if err != nil {
		errLogger.Fatal(err)
	}

	err = json.Unmarshal(file, cfg)
	if err != nil {
		errLogger.Fatal(err)
	}

	cfg.Validate()
}

// Validate the config parsed into the Config struct
func (cfg *Config) Validate() {
	i, err := strconv.Atoi(cfg.Port)
	if err != nil {
		errLogger.Fatal(ErrInvalidPort)
	}
	if i <= 0 || i > 65535 {
		errLogger.Fatal(ErrInvalidPort)
	}
}
<commit_msg>fix typo<commit_after>package webgo

import (
	"encoding/json"
	"io/ioutil"
	"strconv"
	"time"
)

// Config is used for reading app's configuration from json file
type Config struct {
	// Host is the host on which the server is listening
	Host string `json:"host,omitempty"`
	// Port is the port number where the server has to listen for the HTTP requests
	Port string `json:"port,omitempty"`

	// CertFile is the TLS/SSL certificate file path, required for HTTPS
	CertFile string `json:"certFile,omitempty"`
	// KeyFile is the filepath of private key of the certificate
	KeyFile string `json:"keyFile,omitempty"`
	// HTTPSPort is the port number where the server has to listen for the HTTP requests
	HTTPSPort string `json:"httpsPort,omitempty"`

	// ReadTimeout is the maximum duration for which the server would read a request
	ReadTimeout time.Duration `json:"readTimeout,omitempty"`
	// WriteTimeout is the maximum duration for which the server would try to respond
	WriteTimeout time.Duration `json:"writeTimeout,omitempty"`

	// InsecureSkipVerify is the HTTP certificate verification
	InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}

// Load config file from the provided filepath and validate
func (cfg *Config) Load(filepath string) {
	file, err := ioutil.ReadFile(filepath)
	if err != nil {
		errLogger.Fatal(err)
	}

	err = json.Unmarshal(file, cfg)
	if err != nil {
		errLogger.Fatal(err)
	}

	cfg.Validate()
}

// Validate the config parsed into the Config struct
func (cfg *Config) Validate() {
	i, err := strconv.Atoi(cfg.Port)
	if err != nil {
		errLogger.Fatal(ErrInvalidPort)
	}
	if i <= 0 || i > 65535 {
		errLogger.Fatal(ErrInvalidPort)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"runtime"
)

const (
	// Name is the user facing name for this binary. Internally we call it
	// klientctl to avoid confusion.
	Name = "kd"

	// KlientName is the user facing name for klient.
	KlientName = "KD Daemon"

	// KlientAddress is url of locally running klient to connect to send
	// user commands.
	KlientAddress = "http://127.0.0.1:56789/kite"

	// KiteHome is full path to the kite key that we will use to authenticate
	// to the given klient.
	KiteHome = "/etc/kite"

	// KlientDirectory is full path to directory that holds klient.
	KlientDirectory = "/opt/kite/klient"

	// KlientctlDirectory is full path to directory that holds klientctl.
	KlientctlDirectory = "/usr/local/bin"

	// KlientctlBinName is the bin named that will be stored in the KlientctlDirectory.
	KlientctlBinName = "kd"

	// KontrolURL is the url to connect to authenticate local klient and get
	// list of machines.
	KontrolURL = "https://koding.com/kontrol/kite"

	// Version is the current version of klientctl. This number is used
	// by CheckUpdate to determine if current version is behind or equal to latest
	// version on S3 bucket.
	Version = 19

	osName = runtime.GOOS

	// S3UpdateLocation is publically accessible url to check for new updates.
	S3UpdateLocation = "https://koding-kd.s3.amazonaws.com/latest-version.txt"

	// S3KlientPath is publically accessible url for latest version of klient.
	// Each OS has its own version of binary, identifiable by OS suffix.
	S3KlientPath = "https://koding-kd.s3.amazonaws.com/klient-" + osName

	// S3KlientctlPath is publically accessible url for latest version of
	// klientctl. Each OS has its own version of binary, identifiable by suffix.
	S3KlientctlPath = "https://koding-kd.s3.amazonaws.com/klientctl-" + osName

	// SSHDefaultKeyDir is the default directory that stores users ssh key pairs.
	SSHDefaultKeyDir = ".ssh"

	// SSHDefaultKeyName is the default name of the ssh key pair.
	SSHDefaultKeyName = "kd-ssh-key"
)

var (
	// KiteVersion is the version identifier used to connect to Kontrol.
	KiteVersion = fmt.Sprintf("0.0.%d", Version)

	// ConfigFolder is folder where config and other related info are stored.
	ConfigFolder string
)

func init() {
	var err error
	if ConfigFolder, err = createFolderAtHome(".config", "koding"); err != nil {
		panic(err)
	}
}

func createFolderAtHome(cf ...string) (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}

	args := []string{usr.HomeDir}
	args = append(args, cf...)

	folderName := filepath.Join(args...)
	if err := os.MkdirAll(folderName, 0755); err != nil {
		return "", err
	}

	return folderName, nil
}
<commit_msg>Bump version to 20<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"runtime"
)

const (
	// Name is the user facing name for this binary. Internally we call it
	// klientctl to avoid confusion.
	Name = "kd"

	// KlientName is the user facing name for klient.
	KlientName = "KD Daemon"

	// KlientAddress is url of locally running klient to connect to send
	// user commands.
	KlientAddress = "http://127.0.0.1:56789/kite"

	// KiteHome is full path to the kite key that we will use to authenticate
	// to the given klient.
	KiteHome = "/etc/kite"

	// KlientDirectory is full path to directory that holds klient.
	KlientDirectory = "/opt/kite/klient"

	// KlientctlDirectory is full path to directory that holds klientctl.
	KlientctlDirectory = "/usr/local/bin"

	// KlientctlBinName is the bin named that will be stored in the KlientctlDirectory.
	KlientctlBinName = "kd"

	// KontrolURL is the url to connect to authenticate local klient and get
	// list of machines.
	KontrolURL = "https://koding.com/kontrol/kite"

	// Version is the current version of klientctl. This number is used
	// by CheckUpdate to determine if current version is behind or equal to latest
	// version on S3 bucket.
	Version = 20

	osName = runtime.GOOS

	// S3UpdateLocation is publically accessible url to check for new updates.
	S3UpdateLocation = "https://koding-kd.s3.amazonaws.com/latest-version.txt"

	// S3KlientPath is publically accessible url for latest version of klient.
	// Each OS has its own version of binary, identifiable by OS suffix.
	S3KlientPath = "https://koding-kd.s3.amazonaws.com/klient-" + osName

	// S3KlientctlPath is publically accessible url for latest version of
	// klientctl. Each OS has its own version of binary, identifiable by suffix.
	S3KlientctlPath = "https://koding-kd.s3.amazonaws.com/klientctl-" + osName

	// SSHDefaultKeyDir is the default directory that stores users ssh key pairs.
	SSHDefaultKeyDir = ".ssh"

	// SSHDefaultKeyName is the default name of the ssh key pair.
	SSHDefaultKeyName = "kd-ssh-key"
)

var (
	// KiteVersion is the version identifier used to connect to Kontrol.
	KiteVersion = fmt.Sprintf("0.0.%d", Version)

	// ConfigFolder is folder where config and other related info are stored.
	ConfigFolder string
)

func init() {
	var err error
	if ConfigFolder, err = createFolderAtHome(".config", "koding"); err != nil {
		panic(err)
	}
}

func createFolderAtHome(cf ...string) (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}

	args := []string{usr.HomeDir}
	args = append(args, cf...)

	folderName := filepath.Join(args...)
	if err := os.MkdirAll(folderName, 0755); err != nil {
		return "", err
	}

	return folderName, nil
}
<|endoftext|>


<commit_before>package main

import (
	"time"

	"github.com/BurntSushi/toml"
)

type ListenerUrlsConfig struct {
	Urls []string `toml:"urls"`
}

type HAproxyConfig struct {
	ReloadCmd    string `toml:"reload_command"`
	VerifyCmd    string `toml:"verify_command"`
	BindIP       string `toml:"bind_ip"`
	TemplateFile string `toml:"template_file"`
	ConfigFile   string `toml:"config_file"`
	PidFile      string `toml:"pid_file"`
	Disable      bool   `toml:"disable"`
	User         string `toml:"user"`
	Group        string `toml:"group"`
}

type ServicesConfig struct {
	NameMatch    string `toml:"name_match"`
	ServiceNamer string `toml:"service_namer"`
	NameLabel    string `toml:"name_label"`
}

type SidecarConfig struct {
	ExcludeIPs           []string `toml:"exclude_ips"`
	Discovery            []string `toml:"discovery"`
	StatsAddr            string   `toml:"stats_addr"`
	PushPullInterval     duration `toml:"push_pull_interval"`
	GossipMessages       int      `toml:"gossip_messages"`
	LoggingFormat        string   `toml:"logging_format"`
	LoggingLevel         string   `toml:"logging_level"`
	DefaultCheckEndpoint string   `toml:"default_check_endpoint"`
}

type DockerConfig struct {
	DockerURL string `toml:"docker_url"`
}

type StaticConfig struct {
	ConfigFile string `toml:"config_file"`
}

type Config struct {
	Sidecar         SidecarConfig      `toml:"sidecar"`
	DockerDiscovery DockerConfig       `toml:"docker_discovery"`
	StaticDiscovery StaticConfig       `toml:"static_discovery"`
	Services        ServicesConfig     `toml:"services"`
	HAproxy         HAproxyConfig      `toml:"haproxy"`
	Listeners       ListenerUrlsConfig `toml:"listeners"`
}

func setDefaults(config *Config) {
	config.DockerDiscovery.DockerURL = "tcp://localhost:2375"
	config.StaticDiscovery.ConfigFile = "static.json"
}

type duration struct {
	time.Duration
}

func (d *duration) UnmarshalText(text []byte) error {
	var err error
	d.Duration, err = time.ParseDuration(string(text))
	return err
}

func parseConfig(path string) Config {
	var config Config

	setDefaults(&config)

	_, err := toml.DecodeFile(path, &config)
	if err != nil {
		exitWithError(err, "Failed to parse config file")
	}

	return config
}
<commit_msg>Call this 'namer'.<commit_after>package main

import (
	"time"

	"github.com/BurntSushi/toml"
)

type ListenerUrlsConfig struct {
	Urls []string `toml:"urls"`
}

type HAproxyConfig struct {
	ReloadCmd    string `toml:"reload_command"`
	VerifyCmd    string `toml:"verify_command"`
	BindIP       string `toml:"bind_ip"`
	TemplateFile string `toml:"template_file"`
	ConfigFile   string `toml:"config_file"`
	PidFile      string `toml:"pid_file"`
	Disable      bool   `toml:"disable"`
	User         string `toml:"user"`
	Group        string `toml:"group"`
}

type ServicesConfig struct {
	NameMatch    string `toml:"name_match"`
	ServiceNamer string `toml:"namer"`
	NameLabel    string `toml:"name_label"`
}

type SidecarConfig struct {
	ExcludeIPs           []string `toml:"exclude_ips"`
	Discovery            []string `toml:"discovery"`
	StatsAddr            string   `toml:"stats_addr"`
	PushPullInterval     duration `toml:"push_pull_interval"`
	GossipMessages       int      `toml:"gossip_messages"`
	LoggingFormat        string   `toml:"logging_format"`
	LoggingLevel         string   `toml:"logging_level"`
	DefaultCheckEndpoint string   `toml:"default_check_endpoint"`
}

type DockerConfig struct {
	DockerURL string `toml:"docker_url"`
}

type StaticConfig struct {
	ConfigFile string `toml:"config_file"`
}

type Config struct {
	Sidecar         SidecarConfig      `toml:"sidecar"`
	DockerDiscovery DockerConfig       `toml:"docker_discovery"`
	StaticDiscovery StaticConfig       `toml:"static_discovery"`
	Services        ServicesConfig     `toml:"services"`
	HAproxy         HAproxyConfig      `toml:"haproxy"`
	Listeners       ListenerUrlsConfig `toml:"listeners"`
}

func setDefaults(config *Config) {
	config.DockerDiscovery.DockerURL = "tcp://localhost:2375"
	config.StaticDiscovery.ConfigFile = "static.json"
}

type duration struct {
	time.Duration
}

func (d *duration) UnmarshalText(text []byte) error {
	var err error
	d.Duration, err = time.ParseDuration(string(text))
	return err
}

func parseConfig(path string) Config {
	var config Config

	setDefaults(&config)

	_, err := toml.DecodeFile(path, &config)
	if err != nil {
		exitWithError(err, "Failed to parse config file")
	}

	return config
}
<|endoftext|>


<commit_before>package datadog

import (
	"fmt"
	"strconv"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/zorkian/go-datadog-api"
)

func TestAccDatadogDashboard_Basic(t *testing.T) {
	var resp datadog.Dashboard

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDatadogDashboardDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccCheckDatadogDashboardConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDatadogDashboardExists("datadog_dashboard.foo", &resp),
					resource.TestCheckResourceAttr(
						"datadog_dashboard.foo", "title", "title for dashboard foo"),
					resource.TestCheckResourceAttr(
						"datadog_dashboard.foo", "description", "description for dashboard foo"),
				),
			},
		},
	})
}

func testAccCheckDatadogDashboardDestroy(s *terraform.State) error {
	client := testAccProvider.Meta().(*datadog.Client)

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "datadog_dashboard" {
			continue
		}

		IdInt, int_err := strconv.Atoi(rs.Primary.ID)
		if int_err == nil {
			return int_err
		}

		_, err := client.GetDashboard(IdInt)

		if err == nil {
			return fmt.Errorf("Dashboard still exists")
		}
	}

	return nil
}

func testAccCheckDatadogDashboardExists(n string, DashboardResp *datadog.Dashboard) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]

		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Dashboard ID is set")
		}

		client := testAccProvider.Meta().(*datadog.Client)

		IntId, int_err := strconv.Atoi(rs.Primary.ID)

		if int_err != nil {
			return int_err
		}

		resp, err := client.GetDashboard(IntId)

		if err != nil {
			return err
		}

		// TODO: fix this one.
		//if resp.Dashboard.name != rs.Primary.ID {
		//return fmt.Errorf("Domain not found")
		//}

		DashboardResp = resp

		return nil
	}
}

const testAccCheckDatadogDashboardConfig_basic = `
resource "datadog_dashboard" "foo" {
       description = "description for dashboard foo"
       title = "title for dashboard foo"
   }
`
<commit_msg>Add basic test.<commit_after>package datadog

import (
	"fmt"
	"strconv"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/zorkian/go-datadog-api"
)

func TestAccDatadogDashboard_Basic(t *testing.T) {
	var resp datadog.Dashboard

	testTemplateVariables := func(*terraform.State) error {
		var resp datadog.Dashboard

		if len(resp.TemplateVariables) != 2 {
			return fmt.Errorf("bad template variables: %#v", resp.TemplateVariables)
		}

		variables := make(map[string]datadog.TemplateVariable)
		for _, r := range resp.TemplateVariables {
			variables[r.Name] = r
		}

		if _, ok := variables["host1"]; !ok {
			return fmt.Errorf("bad template variables: %#v", resp.TemplateVariables)
		}
		if _, ok := variables["host2"]; !ok {
			return fmt.Errorf("bad template variables: %#v", resp.TemplateVariables)
		}

		return nil
	}

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDatadogDashboardDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccCheckDatadogDashboardConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDatadogDashboardExists("datadog_dashboard.foo", &resp),
					resource.TestCheckResourceAttr(
						"datadog_dashboard.foo", "title", "title for dashboard foo"),
					resource.TestCheckResourceAttr(
						"datadog_dashboard.foo", "description", "description for dashboard foo"),
					testTemplateVariables,
					// TODO: Add tests to verify change
				),
			},
		},
	})

}

func testAccCheckDatadogDashboardDestroy(s *terraform.State) error {
	client := testAccProvider.Meta().(*datadog.Client)

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "datadog_dashboard" {
			continue
		}

		IdInt, int_err := strconv.Atoi(rs.Primary.ID)
		if int_err == nil {
			return int_err
		}

		_, err := client.GetDashboard(IdInt)

		if err == nil {
			return fmt.Errorf("Dashboard still exists")
		}
	}

	return nil
}

func testAccCheckDatadogDashboardExists(n string, DashboardResp *datadog.Dashboard) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]

		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Dashboard ID is set")
		}

		client := testAccProvider.Meta().(*datadog.Client)

		IntId, int_err := strconv.Atoi(rs.Primary.ID)

		if int_err != nil {
			return int_err
		}

		resp, err := client.GetDashboard(IntId)

		if err != nil {
			return err
		}

		// TODO: fix this one.
		//if resp.Dashboard.name != rs.Primary.ID {
		//return fmt.Errorf("Domain not found")
		//}

		DashboardResp = resp

		return nil
	}
}

const testAccCheckDatadogDashboardConfig_basic = `
resource "datadog_dashboard" "foo" {
       description = "description for dashboard foo"
       title = "title for dashboard foo"
       template_variable {
		name = "host1"
		prefix = "host"
		default = "host:foo.example.com"
       }
       template_variable {
		name = "host2"
		prefix = "host"
		default = "host:bar.example.com"
       }
   }
`
<|endoftext|>


<commit_before>package dess

import (
	"math/big"
)

type Decimal struct {
	coefficient *big.Int
	exponent int64
}

// pow returns an int64 of base raised to power. The math package
// returns floats, which could lead to accuracy issues here.
func pow(base, power int64) int64 {
	if power == 0 {
		return 1
	} else if power == 1 {
		return base
	} else {
		return base * pow(base, power - 1)
	}
}

// NewDecimal allocates and returns a new Decimal set to x, with
// places indicating the number of places after the decimal point.
func NewDecimal(x int64, places int64) *Decimal {
	decimal := new(Decimal)

	if x == 0 {
		decimal.coefficient = big.NewInt(0)
		decimal.exponent = 1
	} else {
		decimal.coefficient = big.NewInt(x)
		decimal.exponent = places
	}
	return decimal
}

func (d1 *Decimal) Add(d2 *Decimal) *Decimal {
	decimal := new(Decimal)
	if d1.exponent > d2.exponent {
		diff := d1.exponent - d2.exponent
		alignedExponent := pow(10, diff)
		alignedCoefficient := &big.Int{}
		alignedCoefficient.Mul(d2.coefficient, big.NewInt(alignedExponent))

		coef := &big.Int{}
		decimal.coefficient = coef.Add(alignedCoefficient, d1.coefficient)
		decimal.exponent = d2.exponent
	} else if d1.exponent < d2.exponent {
		diff := d2.exponent - d1.exponent
		alignedExponent := pow(10, diff)
		alignedCoefficient := &big.Int{}
		alignedCoefficient.Mul(d1.coefficient, big.NewInt(alignedExponent))

		coef := &big.Int{}
		decimal.coefficient = coef.Add(alignedCoefficient, d2.coefficient)
		decimal.exponent = d1.exponent
	} else {
		coef := &big.Int{}
		decimal.coefficient = coef.Add(d1.coefficient, d2.coefficient)
		decimal.exponent = d1.exponent
	}
	return decimal
}

func (d1 *Decimal) Equals(d2 *Decimal) bool {
	if d1.coefficient.Cmp(d2.coefficient) != 0 {
		return false
	}
	if d1.exponent != d2.exponent {
		return false
	}
	return true
}

func (d1 *Decimal) Sub(d2 *Decimal) *Decimal {
	inverted := &Decimal{&big.Int{}, d2.exponent}
	inverted.coefficient.Neg(d2.coefficient)
	return d1.Add(inverted)
}

func (d *Decimal) String() string {
	coef := d.coefficient.String()
	if coef == "0" {
		return "0.0"
	}

	neg := false
	if coef[0] == '-' {
		neg = true
		coef = coef[1:]
	}

	var i int64
	for i = 0; i < d.exponent; i += 1 {
		if i >= int64(len(coef)) {
			coef = "0" + coef
		}
	}

	var before string
	var after string
	if coef[0] == '0' {
		before = "0"
		after = coef[:i]
	} else {
		before = coef[:i]
		after = coef[i:]
	}

	if neg {
		before = "-" + before
	}
	return before + "." + after
}
<commit_msg>gofmt<commit_after>package dess

import (
	"math/big"
)

type Decimal struct {
	coefficient *big.Int
	exponent    int64
}

// pow returns an int64 of base raised to power. The math package
// returns floats, which could lead to accuracy issues here.
func pow(base, power int64) int64 {
	if power == 0 {
		return 1
	} else if power == 1 {
		return base
	} else {
		return base * pow(base, power-1)
	}
}

// NewDecimal allocates and returns a new Decimal set to x, with
// places indicating the number of places after the decimal point.
func NewDecimal(x int64, places int64) *Decimal {
	decimal := new(Decimal)

	if x == 0 {
		decimal.coefficient = big.NewInt(0)
		decimal.exponent = 1
	} else {
		decimal.coefficient = big.NewInt(x)
		decimal.exponent = places
	}
	return decimal
}

func (d1 *Decimal) Add(d2 *Decimal) *Decimal {
	decimal := new(Decimal)
	if d1.exponent > d2.exponent {
		diff := d1.exponent - d2.exponent
		alignedExponent := pow(10, diff)
		alignedCoefficient := &big.Int{}
		alignedCoefficient.Mul(d2.coefficient, big.NewInt(alignedExponent))

		coef := &big.Int{}
		decimal.coefficient = coef.Add(alignedCoefficient, d1.coefficient)
		decimal.exponent = d2.exponent
	} else if d1.exponent < d2.exponent {
		diff := d2.exponent - d1.exponent
		alignedExponent := pow(10, diff)
		alignedCoefficient := &big.Int{}
		alignedCoefficient.Mul(d1.coefficient, big.NewInt(alignedExponent))

		coef := &big.Int{}
		decimal.coefficient = coef.Add(alignedCoefficient, d2.coefficient)
		decimal.exponent = d1.exponent
	} else {
		coef := &big.Int{}
		decimal.coefficient = coef.Add(d1.coefficient, d2.coefficient)
		decimal.exponent = d1.exponent
	}
	return decimal
}

func (d1 *Decimal) Equals(d2 *Decimal) bool {
	if d1.coefficient.Cmp(d2.coefficient) != 0 {
		return false
	}
	if d1.exponent != d2.exponent {
		return false
	}
	return true
}

func (d1 *Decimal) Sub(d2 *Decimal) *Decimal {
	inverted := &Decimal{&big.Int{}, d2.exponent}
	inverted.coefficient.Neg(d2.coefficient)
	return d1.Add(inverted)
}

func (d *Decimal) String() string {
	coef := d.coefficient.String()
	if coef == "0" {
		return "0.0"
	}

	neg := false
	if coef[0] == '-' {
		neg = true
		coef = coef[1:]
	}

	var i int64
	for i = 0; i < d.exponent; i += 1 {
		if i >= int64(len(coef)) {
			coef = "0" + coef
		}
	}

	var before string
	var after string
	if coef[0] == '0' {
		before = "0"
		after = coef[:i]
	} else {
		before = coef[:i]
		after = coef[i:]
	}

	if neg {
		before = "-" + before
	}
	return before + "." + after
}
<|endoftext|>