<commit_before>// Copyright 2011 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 sync

import (
	"sync/atomic"
	"unsafe"
)

// A WaitGroup waits for a collection of goroutines to finish.
// The main goroutine calls Add to set the number of
// goroutines to wait for.  Then each of the goroutines
// runs and calls Done when finished.  At the same time,
// Wait can be used to block until all goroutines have finished.
type WaitGroup struct {
	m       Mutex
	counter int32
	waiters int32
	sema    *uint32
}

// WaitGroup creates a new semaphore each time the old semaphore
// is released. This is to avoid the following race:
//
// G1: Add(1)
// G1: go G2()
// G1: Wait() // Context switch after Unlock() and before Semacquire().
// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet.
// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block.
// G3: Add(1) // Makes counter == 1, waiters == 0.
// G3: go G4()
// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.

// Add adds delta, which may be negative, to the WaitGroup counter.
// If the counter becomes zero, all goroutines blocked on Wait() are released.
// If the counter goes negative, Add panics.
func (wg *WaitGroup) Add(delta int) {
	if raceenabled {
		raceReleaseMerge(unsafe.Pointer(wg))
		raceDisable()
		defer raceEnable()
	}
	v := atomic.AddInt32(&wg.counter, int32(delta))
	if v < 0 {
		panic("sync: negative WaitGroup counter")
	}
	if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
		return
	}
	wg.m.Lock()
	for i := int32(0); i < wg.waiters; i++ {
		runtime_Semrelease(wg.sema)
	}
	wg.waiters = 0
	wg.sema = nil
	wg.m.Unlock()
}

// Done decrements the WaitGroup counter.
func (wg *WaitGroup) Done() {
	wg.Add(-1)
}

// Wait blocks until the WaitGroup counter is zero.
func (wg *WaitGroup) Wait() {
	if raceenabled {
		raceDisable()
	}
	if atomic.LoadInt32(&wg.counter) == 0 {
		if raceenabled {
			raceEnable()
			raceAcquire(unsafe.Pointer(wg))
		}
		return
	}
	wg.m.Lock()
	atomic.AddInt32(&wg.waiters, 1)
	// This code is racing with the unlocked path in Add above.
	// The code above modifies counter and then reads waiters.
	// We must modify waiters and then read counter (the opposite order)
	// to avoid missing an Add.
	if atomic.LoadInt32(&wg.counter) == 0 {
		atomic.AddInt32(&wg.waiters, -1)
		if raceenabled {
			raceEnable()
			raceAcquire(unsafe.Pointer(wg))
			raceDisable()
		}
		wg.m.Unlock()
		if raceenabled {
			raceEnable()
		}
		return
	}
	if wg.sema == nil {
		wg.sema = new(uint32)
	}
	s := wg.sema
	wg.m.Unlock()
	runtime_Semacquire(s)
	if raceenabled {
		raceEnable()
		raceAcquire(unsafe.Pointer(wg))
	}
}
<commit_msg>sync: add caution about where to call (*WaitGroup).Add<commit_after>// Copyright 2011 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 sync

import (
	"sync/atomic"
	"unsafe"
)

// A WaitGroup waits for a collection of goroutines to finish.
// The main goroutine calls Add to set the number of
// goroutines to wait for.  Then each of the goroutines
// runs and calls Done when finished.  At the same time,
// Wait can be used to block until all goroutines have finished.
type WaitGroup struct {
	m       Mutex
	counter int32
	waiters int32
	sema    *uint32
}

// WaitGroup creates a new semaphore each time the old semaphore
// is released. This is to avoid the following race:
//
// G1: Add(1)
// G1: go G2()
// G1: Wait() // Context switch after Unlock() and before Semacquire().
// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet.
// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block.
// G3: Add(1) // Makes counter == 1, waiters == 0.
// G3: go G4()
// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.

// Add adds delta, which may be negative, to the WaitGroup counter.
// If the counter becomes zero, all goroutines blocked on Wait are released.
// If the counter goes negative, Add panics.
//
// Note that calls with positive delta must happen before the call to Wait,
// or else Wait may wait for too small a group. Typically this means the calls
// to Add should execute before the statement creating the goroutine or
// other event to be waited for. See the WaitGroup example.
func (wg *WaitGroup) Add(delta int) {
	if raceenabled {
		raceReleaseMerge(unsafe.Pointer(wg))
		raceDisable()
		defer raceEnable()
	}
	v := atomic.AddInt32(&wg.counter, int32(delta))
	if v < 0 {
		panic("sync: negative WaitGroup counter")
	}
	if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
		return
	}
	wg.m.Lock()
	for i := int32(0); i < wg.waiters; i++ {
		runtime_Semrelease(wg.sema)
	}
	wg.waiters = 0
	wg.sema = nil
	wg.m.Unlock()
}

// Done decrements the WaitGroup counter.
func (wg *WaitGroup) Done() {
	wg.Add(-1)
}

// Wait blocks until the WaitGroup counter is zero.
func (wg *WaitGroup) Wait() {
	if raceenabled {
		raceDisable()
	}
	if atomic.LoadInt32(&wg.counter) == 0 {
		if raceenabled {
			raceEnable()
			raceAcquire(unsafe.Pointer(wg))
		}
		return
	}
	wg.m.Lock()
	atomic.AddInt32(&wg.waiters, 1)
	// This code is racing with the unlocked path in Add above.
	// The code above modifies counter and then reads waiters.
	// We must modify waiters and then read counter (the opposite order)
	// to avoid missing an Add.
	if atomic.LoadInt32(&wg.counter) == 0 {
		atomic.AddInt32(&wg.waiters, -1)
		if raceenabled {
			raceEnable()
			raceAcquire(unsafe.Pointer(wg))
			raceDisable()
		}
		wg.m.Unlock()
		if raceenabled {
			raceEnable()
		}
		return
	}
	if wg.sema == nil {
		wg.sema = new(uint32)
	}
	s := wg.sema
	wg.m.Unlock()
	runtime_Semacquire(s)
	if raceenabled {
		raceEnable()
		raceAcquire(unsafe.Pointer(wg))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"strings"

	"github.com/blablacar/dgr/dgr/common"
	"github.com/n0rad/go-erlog/errs"
	"github.com/n0rad/go-erlog/logs"
	"github.com/rkt/rkt/rkt/config"
)

func (aci *Aci) Push() error {
	defer aci.giveBackUserRightsToTarget()
	logs.WithF(aci.fields).Info("Pushing")

	if aci.isUpdated() {
		logs.WithFields(aci.fields).Warn("You cannot push an updated aci, rebuilding")
		if err := aci.CleanAndBuild(); err != nil {
			return err
		}
	}

	if err := aci.EnsureBuilt(); err != nil {
		return err
	}

	if aci.args.Test {
		aci.args.Test = false
		if err := aci.Test(); err != nil {
			return err
		}
	}

	if err := aci.EnsureZipSign(); err != nil {
		return err
	}

	im, err := common.ExtractManifestFromAci(aci.target + pathImageAci)
	if err != nil {
		return errs.WithEF(err, aci.fields.WithField("file", pathImageAci), "Failed to extract manifest from aci file")
	}

	return aci.upload(common.ExtractNameVersionFromManifest(im))
}

func (aci *Aci) upload(name *common.ACFullname) error {
	if Home.Config.Push.Type == "maven" && name.DomainName() == "aci.blbl.cr" { // TODO this definitely need to be removed
		logs.WithF(aci.fields).Info("Uploading aci")
		if err := common.ExecCmd("curl", "-f", "-i", "-L",
			"-F", "r=releases",
			"-F", "hasPom=false",
			"-F", "e=aci",
			"-F", "g=com.blablacar.aci.linux.amd64",
			"-F", "p=aci",
			"-F", "v="+name.Version(),
			"-F", "a="+strings.Split(string(name.Name()), "/")[1],
			"-F", "file=@"+aci.target+pathImageGzAci,
			"-u", Home.Config.Push.Username+":"+Home.Config.Push.Password,
			Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil {
			return errs.WithEF(err, aci.fields, "Failed to push aci")
		}
	} else {
		systemConf := Home.Config.Rkt.SystemConfig
		if systemConf == "" {
			systemConf = "/usr/lib/rkt"
		}
		localConf := Home.Config.Rkt.LocalConfig
		if localConf == "" {
			localConf = "/etc/rkt"
		}

		conf, err := config.GetConfigFrom(systemConf, localConf)
		if err != nil {
			return errs.WithEF(err, aci.fields, "Failed to get rkt configuration")
		}

		upload := Uploader{
			Acipath: aci.target + pathImageGzAci,
			Ascpath: aci.target + pathImageGzAciAsc,
			Uri:     name.String(),
			Debug:   false,
			SetHTTPHeaders: func(r *http.Request) {
				if r.URL == nil {
					return
				}
				headerer, ok := conf.AuthPerHost[r.URL.Host]
				if !ok {
					logs.WithFields(aci.fields).WithField("domain", r.URL.Host).
						Warn("No auth credential found in rkt configuration for this domain")
					return
				}
				header := headerer.GetHeader()
				for k, v := range header {
					r.Header[k] = append(r.Header[k], v...)
				}
			},
		}
		err = upload.Upload()
		if err != nil {
			return errs.WithEF(err, aci.fields, "Failed to upload aci")
		}

	}
	return nil
}
<commit_msg>Check if aci is already in the nexus before push + rewrit of push in pure golang<commit_after>package main

import (
	"net/http"
	"strings"

	"net/url"
	"os"
	"path"

	"bytes"
	"io"
	"mime/multipart"
	"path/filepath"

	"github.com/blablacar/dgr/dgr/common"
	"github.com/n0rad/go-erlog/data"
	"github.com/n0rad/go-erlog/errs"
	"github.com/n0rad/go-erlog/logs"
	"github.com/rkt/rkt/rkt/config"
)

func (aci *Aci) Push() error {
	defer aci.giveBackUserRightsToTarget()
	logs.WithF(aci.fields).Info("Pushing")

	if aci.isUpdated() {
		logs.WithFields(aci.fields).Warn("You cannot push an updated aci, rebuilding")
		if err := aci.CleanAndBuild(); err != nil {
			return err
		}
	}

	if err := aci.EnsureBuilt(); err != nil {
		return err
	}

	if aci.args.Test {
		aci.args.Test = false
		if err := aci.Test(); err != nil {
			return err
		}
	}

	if err := aci.EnsureZipSign(); err != nil {
		return err
	}

	im, err := common.ExtractManifestFromAci(aci.target + pathImageAci)
	if err != nil {
		return errs.WithEF(err, aci.fields.WithField("file", pathImageAci), "Failed to extract manifest from aci file")
	}

	return aci.upload(common.ExtractNameVersionFromManifest(im))
}

func (aci *Aci) nexusRegistryCheck(urlReq url.URL, params map[string]string) (ok bool, err error) {
	logs.WithField("url", urlReq.String()).Debug("Checking remote registry")
	client := &http.Client{}
	queryCheck := urlReq.Query()
	for key, val := range params {
		queryCheck.Set(key, val)
	}
	urlReq.RawQuery = queryCheck.Encode()

	/* Authenticate */
	req, err := http.NewRequest("HEAD", urlReq.String(), nil)
	req.SetBasicAuth(Home.Config.Push.Username, Home.Config.Push.Password)
	resp, err := client.Do(req)
	if err != nil {
		logs.WithE(err).Info("Failed to check version")
		return false, err
	}
	ok = false
	switch {
	case resp.StatusCode >= 200 && resp.StatusCode <= 300:
		logs.WithField("statusCode", resp.StatusCode).
			WithField("status", resp.Status).
			Info("Aci already uploaded.")
	case 404 == resp.StatusCode:
		logs.WithField("statusCode", resp.StatusCode).
			WithField("status", resp.Status).
			Info("Ready to upload")
		ok = true
	case 401 == resp.StatusCode || 403 == resp.StatusCode:
		logs.WithField("statusCode", resp.StatusCode).
			WithField("status", resp.Status).
			Info("Failed to login to the registry")
	case resp.StatusCode >= 500:
		logs.WithField("statusCode", resp.StatusCode).
			WithField("status", resp.Status).
			Info("Registry server error")
	}
	return
}

func (aci *Aci) nexusRegistryPush(urlReq url.URL, aciPath string, params map[string]string) (err error) {
	file, err := os.Open(aciPath)
	if err != nil {
		return err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	for key, val := range params {
		_ = writer.WriteField(key, val)
	}
	part, err := writer.CreateFormFile("file", filepath.Base(aciPath))
	if err != nil {
		return err
	}
	_, err = io.Copy(part, file)

	err = writer.Close()
	if err != nil {
		return err
	}

	client := &http.Client{}

	/* Authenticate */
	req, err := http.NewRequest("POST", urlReq.String(), body)
	req.SetBasicAuth(Home.Config.Push.Username, Home.Config.Push.Password)
	req.Header.Set("Content-Type", writer.FormDataContentType())
	resp, err := client.Do(req)
	if err != nil {
		return errs.WithE(err, "Failed to execute request")
	}
	defer resp.Body.Close()
	logs.WithField("statusCode", resp.StatusCode).
		WithField("status", resp.Status).
		WithField("aciPath", aciPath).
		Debug("Upload logs")
	if resp.StatusCode != 201 {
		return errs.WithE(err, resp.Status)
	}
	return
}

func (aci *Aci) upload(name *common.ACFullname) error {
	if Home.Config.Push.Type == "maven" && name.DomainName() == "aci.blbl.cr" { // TODO this definitely need to be removed
		urlCheck, err := url.Parse(Home.Config.Push.Url)
		if err != nil {
			return errs.WithEF(err, data.Fields{
				"url": Home.Config.Push.Url,
			}, "Failed to parse url in dgr config")
		}
		formArgs := map[string]string{
			"r":         "releases",
			"hasPom":    "false",
			"e":         "aci",
			"p":         "aci",
			"extension": "aci",
			"packaging": "aci",
			"g":         "com.blablacar.aci.linux.amd64",
			"v":         name.Version(),
			"a":         strings.Split(string(name.Name()), "/")[1],
		}
		urlCheck.Path = urlCheck.Path + "/service/local/artifact/maven/content"
		isNotInRegistry, err := aci.nexusRegistryCheck(*urlCheck, formArgs)
		if err != nil {
			return errs.WithEF(err, aci.fields, "Failed to check aci in remote registry")
		}
		aciPath := path.Join(aci.target, pathImageGzAci)
		if isNotInRegistry {
			logs.WithF(aci.fields).Info("Uploading aci")
			if err = aci.nexusRegistryPush(*urlCheck, aciPath, formArgs); err != nil {
				return errs.WithEF(err, aci.fields, "Failed to push aci")
			}
		}
	} else {
		systemConf := Home.Config.Rkt.SystemConfig
		if systemConf == "" {
			systemConf = "/usr/lib/rkt"
		}
		localConf := Home.Config.Rkt.LocalConfig
		if localConf == "" {
			localConf = "/etc/rkt"
		}

		conf, err := config.GetConfigFrom(systemConf, localConf)
		if err != nil {
			return errs.WithEF(err, aci.fields, "Failed to get rkt configuration")
		}

		upload := Uploader{
			Acipath: aci.target + pathImageGzAci,
			Ascpath: aci.target + pathImageGzAciAsc,
			Uri:     name.String(),
			Debug:   false,
			SetHTTPHeaders: func(r *http.Request) {
				if r.URL == nil {
					return
				}
				headerer, ok := conf.AuthPerHost[r.URL.Host]
				if !ok {
					logs.WithFields(aci.fields).WithField("domain", r.URL.Host).
						Warn("No auth credential found in rkt configuration for this domain")
					return
				}
				header := headerer.GetHeader()
				for k, v := range header {
					r.Header[k] = append(r.Header[k], v...)
				}
			},
		}
		err = upload.Upload()
		if err != nil {
			return errs.WithEF(err, aci.fields, "Failed to upload aci")
		}

	}
	return nil
}
<|endoftext|>


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

// Package composeapi provides an idiomatic Go wrapper around the Compose
// API for database platform for deployment, management and monitoring.
package composeapi

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"

	"github.com/parnurzeal/gorequest"
)

const (
	apibase = "https://api.compose.io/2016-07/"
)

// Client is a structure that holds session information for the API
type Client struct {
	apiToken      string
	logger        *log.Logger
	enableLogging bool
}

// NewClient returns a Client for further interaction with the API
func NewClient(apiToken string) (*Client, error) {
	return &Client{
		apiToken: apiToken,
		logger:   log.New(ioutil.Discard, "", 0),
	}, nil
}

// SetLogger can enable or disable http logging to and from the Compose
// API endpoint using the provided io.Writer for the provided client.
func (c *Client) SetLogger(enableLogging bool, logger io.Writer) *Client {
	c.logger = log.New(logger, "[composeapi]", log.LstdFlags)
	c.enableLogging = enableLogging
	return c
}

func (c *Client) newRequest(method, targetURL string) *gorequest.SuperAgent {
	return gorequest.New().
		CustomMethod(method, targetURL).
		Set("Authorization", "Bearer "+c.apiToken).
		Set("Content-type", "application/json; charset=utf-8").
		SetLogger(c.logger).
		SetDebug(c.enableLogging)
}

// Link structure for JSON+HAL links
type Link struct {
	HREF      string `json:"href"`
	Templated bool   `json:"templated"`
}

//Errors struct for parsing error returns
type Errors struct {
	Error map[string][]string `json:"errors,omitempty"`
}

func printJSON(jsontext string) {
	var tempholder map[string]interface{}

	if err := json.Unmarshal([]byte(jsontext), &tempholder); err != nil {
		log.Fatal(err)
	}
	indentedjson, err := json.MarshalIndent(tempholder, "", "  ")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(indentedjson))
}

//SetAPIToken overrides the API token
func (c *Client) SetAPIToken(newtoken string) {
	c.apiToken = newtoken
}

//GetJSON Gets JSON string of content at an endpoint
func (c *Client) getJSON(endpoint string) (string, []error) {
	response, body, errs := c.newRequest("GET", apibase+endpoint).End()

	if response.StatusCode != 200 {
		myerrors := Errors{}
		err := json.Unmarshal([]byte(body), &myerrors)
		if err != nil {
			errs = append(errs, fmt.Errorf("Unable to parse error - status code %d - body %s", response.StatusCode, response.Body))
		} else {
			errs = append(errs, fmt.Errorf("%v", myerrors.Error))
		}
	}
	return body, errs
}
<commit_msg>Retry HTTP Requests when appropriate<commit_after>// Copyright 2016 Compose, an IBM Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// Package composeapi provides an idiomatic Go wrapper around the Compose
// API for database platform for deployment, management and monitoring.
package composeapi

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/parnurzeal/gorequest"
)

const (
	apibase = "https://api.compose.io/2016-07/"
)

// Client is a structure that holds session information for the API
type Client struct {
	// The number of times to retry a failing request if the status code is
	// retryable (e.g. for HTTP 429 or 500)
	Retries int
	// The interval to wait between retries. gorequest does not yet support
	// exponential back-off on retries
	RetryInterval time.Duration
	// RetryStatusCodes is the list of status codes to retry for
	RetryStatusCodes []int

	apiToken      string
	logger        *log.Logger
	enableLogging bool
}

// NewClient returns a Client for further interaction with the API
func NewClient(apiToken string) (*Client, error) {
	return &Client{
		apiToken:      apiToken,
		logger:        log.New(ioutil.Discard, "", 0),
		Retries:       5,
		RetryInterval: 3 * time.Second,
		RetryStatusCodes: []int{
			http.StatusRequestTimeout,
			http.StatusTooManyRequests,
			http.StatusBadGateway,
			http.StatusServiceUnavailable,
			http.StatusGatewayTimeout,
		},
	}, nil
}

// SetLogger can enable or disable http logging to and from the Compose
// API endpoint using the provided io.Writer for the provided client.
func (c *Client) SetLogger(enableLogging bool, logger io.Writer) *Client {
	c.logger = log.New(logger, "[composeapi]", log.LstdFlags)
	c.enableLogging = enableLogging
	return c
}

func (c *Client) newRequest(method, targetURL string) *gorequest.SuperAgent {
	return gorequest.New().
		CustomMethod(method, targetURL).
		Set("Authorization", "Bearer "+c.apiToken).
		Set("Content-type", "application/json; charset=utf-8").
		SetLogger(c.logger).
		SetDebug(c.enableLogging).
		Retry(c.Retries, c.RetryInterval, c.RetryStatusCodes...)
}

// Link structure for JSON+HAL links
type Link struct {
	HREF      string `json:"href"`
	Templated bool   `json:"templated"`
}

//Errors struct for parsing error returns
type Errors struct {
	Error map[string][]string `json:"errors,omitempty"`
}

func printJSON(jsontext string) {
	var tempholder map[string]interface{}

	if err := json.Unmarshal([]byte(jsontext), &tempholder); err != nil {
		log.Fatal(err)
	}
	indentedjson, err := json.MarshalIndent(tempholder, "", "  ")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(indentedjson))
}

//SetAPIToken overrides the API token
func (c *Client) SetAPIToken(newtoken string) {
	c.apiToken = newtoken
}

//GetJSON Gets JSON string of content at an endpoint
func (c *Client) getJSON(endpoint string) (string, []error) {
	response, body, errs := c.newRequest("GET", apibase+endpoint).End()

	if response.StatusCode != 200 {
		myerrors := Errors{}
		err := json.Unmarshal([]byte(body), &myerrors)
		if err != nil {
			errs = append(errs, fmt.Errorf("Unable to parse error - status code %d - body %s", response.StatusCode, response.Body))
		} else {
			errs = append(errs, fmt.Errorf("%v", myerrors.Error))
		}
	}
	return body, errs
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium 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 main

import (
	"fmt"
	"os"
	"path/filepath"

	"v.io/jiri/jiri"
	"v.io/jiri/project"
	"v.io/jiri/runutil"
	"v.io/x/lib/cmdline"
)

// TODO(toddw): Remove the upgrade command after the transition to new-style
// manifests is complete.

var flagUpgradeRevert bool

func init() {
	cmdUpgrade.Flags.BoolVar(&flagUpgradeRevert, "revert", false, `Revert the upgrade by deleting the $JIRI_ROOT/.jiri_manifest file.`)
}

var cmdUpgrade = &cmdline.Command{
	Runner: jiri.RunnerFunc(runUpgrade),
	Name:   "upgrade",
	Short:  "Upgrade jiri to new-style manifests",
	Long: `
Upgrades jiri to use new-style manifests.

The old (deprecated) behavior only allowed a single manifest repository, located
in $JIRI_ROOT/.manifest.  The initial manifest file is located as follows:
  1) Use -manifest flag, if non-empty.  If it's empty...
  2) Use $JIRI_ROOT/.local_manifest file.  If it doesn't exist...
  3) Use $JIRI_ROOT/.manifest/v2/default.

The new behavior allows multiple manifest repositories, by allowing imports to
specify project attributes describing the remote repository.  The -manifest flag
is no longer allowed to be set; the initial manifest file is always located in
$JIRI_ROOT/.jiri_manifest.  The .local_manifest file is ignored.

During the transition phase, both old and new behaviors are supported.  The jiri
tool uses the existence of the $JIRI_ROOT/.jiri_manifest file as the signal; if
it exists we run the new behavior, otherwise we run the old behavior.

The new behavior includes a "jiri import" command, which writes or updates the
.jiri_manifest file.  The new bootstrap procedure runs "jiri import", and it is
intended as a regular command to add imports to your jiri environment.

This upgrade command eases the transition by writing an initial .jiri_manifest
file for you.  If you have an existing .local_manifest file, its contents will
be incorporated into the new .jiri_manifest file, and it will be renamed to
.local_manifest.BACKUP.  The -revert flag deletes the .jiri_manifest file, and
restores the .local_manifest file.
`,
	ArgsName: "<kind>",
	ArgsLong: `
<kind> specifies the kind of upgrade, one of "v23" or "fuchsia".
`,
}

func runUpgrade(jirix *jiri.X, args []string) error {
	localFile := filepath.Join(jirix.Root, ".local_manifest")
	backupFile := localFile + ".BACKUP"
	if flagUpgradeRevert {
		// Restore .local_manifest.BACKUP if it exists.
		switch _, err := jirix.NewSeq().Stat(backupFile); {
		case err != nil && !runutil.IsNotExist(err):
			return err
		case err == nil:
			if err := jirix.NewSeq().Rename(backupFile, localFile).Done(); err != nil {
				return fmt.Errorf("couldn't restore %v to %v: %v", backupFile, localFile, err)
			}
		}
		// Deleting the .jiri_manifest file reverts to the old behavior.
		return jirix.NewSeq().Remove(jirix.JiriManifestFile()).Done()
	}
	if len(args) != 1 {
		return jirix.UsageErrorf("must specify upgrade kind")
	}
	kind := args[0]
	var argRemote, argName, argManifest string
	switch kind {
	case "v23":
		argRemote = "https://vanadium.googlesource.com/manifest"
		argName, argManifest = "manifest", "public"
	case "fuchsia":
		argRemote = "https://github.com/effenel/fnl-start.git"
		argName, argManifest = "fnl-start", "manifest/fuchsia"
	default:
		return jirix.UsageErrorf("unknown upgrade kind %q", kind)
	}
	// Initialize manifest from .local_manifest.
	hasLocalFile := true
	manifest, err := project.ManifestFromFile(jirix, localFile)
	if err != nil {
		if !runutil.IsNotExist(err) {
			return err
		}
		hasLocalFile = false
		manifest = &project.Manifest{}
	}
	oldImports := manifest.Imports
	manifest.Imports = nil
	for _, oldImport := range oldImports {
		if oldImport.Remote != "" {
			// This is a new-style remote import, carry it over directly.
			manifest.Imports = append(manifest.Imports, oldImport)
			continue
		}
		// This is an old-style import, convert it to the new style.
		oldName := oldImport.Name
		switch {
		case kind == "v23" && oldName == "default":
			oldName = "public"
		case kind == "fuchsia" && oldName == "default":
			oldName = "manifest/fuchsia"
		}
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: oldName,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	if len(manifest.Imports) == 0 {
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: argManifest,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	// Write output to .jiri_manifest file.
	outFile := jirix.JiriManifestFile()
	if _, err := os.Stat(outFile); err == nil {
		return fmt.Errorf("%v already exists", outFile)
	}
	if err := manifest.ToFile(jirix, outFile); err != nil {
		return err
	}
	// Backup .local_manifest file, if it exists.
	if hasLocalFile {
		if err := jirix.NewSeq().Rename(localFile, backupFile).Done(); err != nil {
			return fmt.Errorf("couldn't backup %v to %v: %v", localFile, backupFile, err)
		}
	}
	return nil
}
<commit_msg>jiri: Switch fnl-start remote from github to googlesource.<commit_after>// Copyright 2015 The Vanadium 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 main

import (
	"fmt"
	"os"
	"path/filepath"

	"v.io/jiri/jiri"
	"v.io/jiri/project"
	"v.io/jiri/runutil"
	"v.io/x/lib/cmdline"
)

// TODO(toddw): Remove the upgrade command after the transition to new-style
// manifests is complete.

var flagUpgradeRevert bool

func init() {
	cmdUpgrade.Flags.BoolVar(&flagUpgradeRevert, "revert", false, `Revert the upgrade by deleting the $JIRI_ROOT/.jiri_manifest file.`)
}

var cmdUpgrade = &cmdline.Command{
	Runner: jiri.RunnerFunc(runUpgrade),
	Name:   "upgrade",
	Short:  "Upgrade jiri to new-style manifests",
	Long: `
Upgrades jiri to use new-style manifests.

The old (deprecated) behavior only allowed a single manifest repository, located
in $JIRI_ROOT/.manifest.  The initial manifest file is located as follows:
  1) Use -manifest flag, if non-empty.  If it's empty...
  2) Use $JIRI_ROOT/.local_manifest file.  If it doesn't exist...
  3) Use $JIRI_ROOT/.manifest/v2/default.

The new behavior allows multiple manifest repositories, by allowing imports to
specify project attributes describing the remote repository.  The -manifest flag
is no longer allowed to be set; the initial manifest file is always located in
$JIRI_ROOT/.jiri_manifest.  The .local_manifest file is ignored.

During the transition phase, both old and new behaviors are supported.  The jiri
tool uses the existence of the $JIRI_ROOT/.jiri_manifest file as the signal; if
it exists we run the new behavior, otherwise we run the old behavior.

The new behavior includes a "jiri import" command, which writes or updates the
.jiri_manifest file.  The new bootstrap procedure runs "jiri import", and it is
intended as a regular command to add imports to your jiri environment.

This upgrade command eases the transition by writing an initial .jiri_manifest
file for you.  If you have an existing .local_manifest file, its contents will
be incorporated into the new .jiri_manifest file, and it will be renamed to
.local_manifest.BACKUP.  The -revert flag deletes the .jiri_manifest file, and
restores the .local_manifest file.
`,
	ArgsName: "<kind>",
	ArgsLong: `
<kind> specifies the kind of upgrade, one of "v23" or "fuchsia".
`,
}

func runUpgrade(jirix *jiri.X, args []string) error {
	localFile := filepath.Join(jirix.Root, ".local_manifest")
	backupFile := localFile + ".BACKUP"
	if flagUpgradeRevert {
		// Restore .local_manifest.BACKUP if it exists.
		switch _, err := jirix.NewSeq().Stat(backupFile); {
		case err != nil && !runutil.IsNotExist(err):
			return err
		case err == nil:
			if err := jirix.NewSeq().Rename(backupFile, localFile).Done(); err != nil {
				return fmt.Errorf("couldn't restore %v to %v: %v", backupFile, localFile, err)
			}
		}
		// Deleting the .jiri_manifest file reverts to the old behavior.
		return jirix.NewSeq().Remove(jirix.JiriManifestFile()).Done()
	}
	if len(args) != 1 {
		return jirix.UsageErrorf("must specify upgrade kind")
	}
	kind := args[0]
	var argRemote, argName, argManifest string
	switch kind {
	case "v23":
		argRemote = "https://vanadium.googlesource.com/manifest"
		argName, argManifest = "manifest", "public"
	case "fuchsia":
		argRemote = "https://fuchsia.googlesource.com/fnl-start"
		argName, argManifest = "fnl-start", "manifest/fuchsia"
	default:
		return jirix.UsageErrorf("unknown upgrade kind %q", kind)
	}
	// Initialize manifest from .local_manifest.
	hasLocalFile := true
	manifest, err := project.ManifestFromFile(jirix, localFile)
	if err != nil {
		if !runutil.IsNotExist(err) {
			return err
		}
		hasLocalFile = false
		manifest = &project.Manifest{}
	}
	oldImports := manifest.Imports
	manifest.Imports = nil
	for _, oldImport := range oldImports {
		if oldImport.Remote != "" {
			// This is a new-style remote import, carry it over directly.
			manifest.Imports = append(manifest.Imports, oldImport)
			continue
		}
		// This is an old-style import, convert it to the new style.
		oldName := oldImport.Name
		switch {
		case kind == "v23" && oldName == "default":
			oldName = "public"
		case kind == "fuchsia" && oldName == "default":
			oldName = "manifest/fuchsia"
		}
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: oldName,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	if len(manifest.Imports) == 0 {
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: argManifest,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	// Write output to .jiri_manifest file.
	outFile := jirix.JiriManifestFile()
	if _, err := os.Stat(outFile); err == nil {
		return fmt.Errorf("%v already exists", outFile)
	}
	if err := manifest.ToFile(jirix, outFile); err != nil {
		return err
	}
	// Backup .local_manifest file, if it exists.
	if hasLocalFile {
		if err := jirix.NewSeq().Rename(localFile, backupFile).Done(); err != nil {
			return fmt.Errorf("couldn't backup %v to %v: %v", localFile, backupFile, err)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Package display provides information on headers to the views as shown to the user
package display

import (
	"fmt"
	"time"

	"github.com/sjmudd/ps-top/context"
	"github.com/sjmudd/ps-top/lib"
)

// BaseDisplay holds the structure that is common for all types, somewhere
// to put what's needed in the header.  Make the internal members
// visible without functions for now.
type BaseDisplay struct {
	ctx *context.Context
}

// SetContet sets the context from the given pointer
func (d *BaseDisplay) SetContext(ctx *context.Context) {
	d.ctx = ctx
}

// return ctx.Uptime() but protect against nil pointers
func (d BaseDisplay) Uptime() int {
	if d.ctx == nil {
		return 0
	}
	return d.ctx.Uptime()
}

// MyName returns the application name (binary name)
func (d BaseDisplay) MyName() string {
	return lib.MyName()
}

// HeadingLine returns the heading line as a string
func (d *BaseDisplay) HeadingLine(haveRelativeStats, wantRelativeStats bool, initial, last time.Time) string {
	heading := d.MyName() + " " + d.ctx.Version() + " - " + nowHHMMSS() + " " + d.ctx.Hostname() + " / " + d.ctx.MySQLVersion() + ", up " + fmt.Sprintf("%-16s", lib.Uptime(d.Uptime()))

	if haveRelativeStats {
		if wantRelativeStats {
			heading += " [REL] " + fmt.Sprintf("%.0f seconds", time.Since(initial).Seconds())
		} else {
			heading += " [ABS]             "
		}
	}
	return heading
}

// if there's a better way of doing this do it better ...
func nowHHMMSS() string {
	t := time.Now()
	return fmt.Sprintf("%2d:%02d:%02d", t.Hour(), t.Minute(), t.Second())
}
<commit_msg>Fixed typo SetContet<commit_after>// Package display provides information on headers to the views as shown to the user
package display

import (
	"fmt"
	"time"

	"github.com/sjmudd/ps-top/context"
	"github.com/sjmudd/ps-top/lib"
)

// BaseDisplay holds the structure that is common for all types, somewhere
// to put what's needed in the header.  Make the internal members
// visible without functions for now.
type BaseDisplay struct {
	ctx *context.Context
}

// SetContext sets the context from the given pointer
func (d *BaseDisplay) SetContext(ctx *context.Context) {
	d.ctx = ctx
}

// return ctx.Uptime() but protect against nil pointers
func (d BaseDisplay) Uptime() int {
	if d.ctx == nil {
		return 0
	}
	return d.ctx.Uptime()
}

// MyName returns the application name (binary name)
func (d BaseDisplay) MyName() string {
	return lib.MyName()
}

// HeadingLine returns the heading line as a string
func (d *BaseDisplay) HeadingLine(haveRelativeStats, wantRelativeStats bool, initial, last time.Time) string {
	heading := d.MyName() + " " + d.ctx.Version() + " - " + nowHHMMSS() + " " + d.ctx.Hostname() + " / " + d.ctx.MySQLVersion() + ", up " + fmt.Sprintf("%-16s", lib.Uptime(d.Uptime()))

	if haveRelativeStats {
		if wantRelativeStats {
			heading += " [REL] " + fmt.Sprintf("%.0f seconds", time.Since(initial).Seconds())
		} else {
			heading += " [ABS]             "
		}
	}
	return heading
}

// if there's a better way of doing this do it better ...
func nowHHMMSS() string {
	t := time.Now()
	return fmt.Sprintf("%2d:%02d:%02d", t.Hour(), t.Minute(), t.Second())
}
<|endoftext|>


<commit_before>package web

import (
	"html/template"
	"io"
	"path/filepath"
	"runtime"

	"github.com/hectorj/TicTacToe"
)

type templateData struct {
	TicTacToe.Grid
	Coordinates [3][3]TicTacToe.Coordinates
	IsOver      bool
	FirstTurn   bool
	Winner      TicTacToe.Player
}

var (
	templates *template.Template
)

func init() {
	_, basepath, _, _ := runtime.Caller(0)
	basepath = filepath.Dir(basepath)
	templatesPath := filepath.Join(basepath, "/template/*")

	templates = template.Must(template.ParseGlob(templatesPath))
}

func prepareData(ID uint32) templateData {
	data := templateData{
		Grid: TicTacToe.GridFromID(ID),
		Coordinates: [3][3]TicTacToe.Coordinates{
			{
				TicTacToe.Coordinates{0, 0},
				TicTacToe.Coordinates{1, 0},
				TicTacToe.Coordinates{2, 0},
			},
			{
				TicTacToe.Coordinates{0, 1},
				TicTacToe.Coordinates{1, 1},
				TicTacToe.Coordinates{2, 1},
			},
			{
				TicTacToe.Coordinates{0, 2},
				TicTacToe.Coordinates{1, 2},
				TicTacToe.Coordinates{2, 2},
			},
		},
		FirstTurn: ID <= 1,
	}

	if !data.FirstTurn {
		data.IsOver, data.Winner = data.Grid.IsGameOver()

		if !data.IsOver {
			coordinates := TicTacToe.BestNextMove(data.Grid)
			data.Grid.Play(coordinates)
			data.IsOver, data.Winner = data.Grid.IsGameOver()
		}
	}

	return data
}

func Render(wr io.Writer, ID uint32) error {
	return templates.ExecuteTemplate(wr, "main", prepareData(ID))
}
<commit_msg>Fix for go vet<commit_after>package web

import (
	"html/template"
	"io"
	"path/filepath"
	"runtime"

	"github.com/hectorj/TicTacToe"
)

type templateData struct {
	TicTacToe.Grid
	Coordinates [3][3]TicTacToe.Coordinates
	IsOver      bool
	FirstTurn   bool
	Winner      TicTacToe.Player
}

var (
	templates *template.Template
)

func init() {
	_, basepath, _, _ := runtime.Caller(0)
	basepath = filepath.Dir(basepath)
	templatesPath := filepath.Join(basepath, "/template/*")

	templates = template.Must(template.ParseGlob(templatesPath))
}

func prepareData(ID uint32) templateData {
	data := templateData{
		Grid: TicTacToe.GridFromID(ID),
		Coordinates: [3][3]TicTacToe.Coordinates{
			{
				TicTacToe.Coordinates{X: 0, Y: 0},
				TicTacToe.Coordinates{X: 1, Y: 0},
				TicTacToe.Coordinates{X: 2, Y: 0},
			},
			{
				TicTacToe.Coordinates{X: 0, Y: 1},
				TicTacToe.Coordinates{X: 1, Y: 1},
				TicTacToe.Coordinates{X: 2, Y: 1},
			},
			{
				TicTacToe.Coordinates{X: 0, Y: 2},
				TicTacToe.Coordinates{X: 1, Y: 2},
				TicTacToe.Coordinates{X: 2, Y: 2},
			},
		},
		FirstTurn: ID <= 1,
	}

	if !data.FirstTurn {
		data.IsOver, data.Winner = data.Grid.IsGameOver()

		if !data.IsOver {
			coordinates := TicTacToe.BestNextMove(data.Grid)
			data.Grid.Play(coordinates)
			data.IsOver, data.Winner = data.Grid.IsGameOver()
		}
	}

	return data
}

func Render(wr io.Writer, ID uint32) error {
	return templates.ExecuteTemplate(wr, "main", prepareData(ID))
}
<|endoftext|>


<commit_before>package main

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

	"github.com/RangelReale/osin"
	"github.com/davecgh/go-spew/spew"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/stampzilla/stampzilla-go/nodes/stampzilla-google-assistant/googleassistant"
	"github.com/stampzilla/stampzilla-go/nodes/stampzilla-server/models/devices"
	"github.com/stampzilla/stampzilla-go/pkg/node"
)

// SmartHomeHandler contains the logic to answer Google Actions API requests and authorize them usnig oauth2.
type SmartHomeHandler struct {
	node       *node.Node
	deviceList *devices.List
}

// NewSmartHomeHandler returns a new instance of SmartHomeHandler.
func NewSmartHomeHandler(node *node.Node, deviceList *devices.List) *SmartHomeHandler {
	return &SmartHomeHandler{
		node:       node,
		deviceList: deviceList,
	}

}

func (shh *SmartHomeHandler) smartHomeActionHandler(oauth2server *osin.Server) func(c *gin.Context) {
	return func(c *gin.Context) {
		auth := osin.CheckBearerAuth(c.Request)
		if auth == nil {
			logrus.Error("CheckBearerAuth error")
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		accessToken, err := oauth2server.Storage.LoadAccess(auth.Code)
		if err != nil || accessToken == nil {
			logrus.Errorf("LoadAccess error: %#v", err)
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		if accessToken.IsExpired() {
			logrus.Errorf("Accesstoken %s expired at: %s", accessToken.AccessToken, accessToken.ExpireAt())
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		dec := json.NewDecoder(c.Request.Body)
		defer c.Request.Body.Close()

		//body, err := ioutil.ReadAll(c.Request.Body)
		//if err != nil {
		//logrus.Error(err)
		//return
		//}
		//logrus.Info(string(body))

		r := &googleassistant.Request{}

		err = dec.Decode(r)
		if err != nil {
			logrus.Error(err)
			return
		}

		logrus.Info("Intent: ", r.Inputs.Intent())
		logrus.Debug("Request:", spew.Sdump(r))
		switch r.Inputs.Intent() {
		case googleassistant.SyncIntent:
			c.JSON(http.StatusOK, shh.syncHandler(r))
		case googleassistant.ExecuteIntent:
			c.JSON(http.StatusOK, shh.executeHandler(r))

		}
	}
}

func (shh *SmartHomeHandler) executeHandler(req *googleassistant.Request) *googleassistant.Response {
	resp := &googleassistant.Response{}
	resp.RequestID = req.RequestID

	levelCommands := make(map[int]googleassistant.ResponseCommand)

	onCommand := googleassistant.NewResponseCommand()
	onCommand.States.On = true
	onCommand.States.Online = true
	offCommand := googleassistant.NewResponseCommand()
	offCommand.States.Online = true

	deviceNotFound := googleassistant.NewResponseCommand()
	deviceNotFound.Status = "ERROR"
	deviceNotFound.ErrorCode = "deviceNotFound"

	deviceOffline := googleassistant.NewResponseCommand()
	deviceOffline.Status = "OFFLINE"

	affectedDevs := make(devices.DeviceMap)

	for _, command := range req.Inputs.Payload().Commands {

		for _, v := range command.Execution {
			for _, googleDev := range command.Devices {
				devID, err := devices.NewIDFromString(googleDev.ID)
				if err != nil {
					logrus.Error(err)
					continue
				}

				dev := shh.deviceList.Get(devID)
				if dev == nil || dev.Type != "light" {
					deviceNotFound.IDs = append(deviceNotFound.IDs, googleDev.ID)
					continue
				}

				if !dev.Online {
					deviceOffline.IDs = append(deviceOffline.IDs, googleDev.ID)
					continue
				}
				if v.Command == googleassistant.CommandOnOff {
					if v.Params.On {
						logrus.Infof("Turning device %s (%s) on ", dev.Name, dev.ID)
						dev.State["on"] = true
						onCommand.IDs = append(onCommand.IDs, googleDev.ID)
					} else {
						offCommand.IDs = append(onCommand.IDs, googleDev.ID)
						logrus.Infof("Turning device %s (%s) off", dev.Name, dev.ID)
						dev.State["on"] = false
					}
					affectedDevs[devID] = dev
				}
				if v.Command == googleassistant.CommandBrightnessAbsolute {
					bri := v.Params.Brightness
					logrus.Infof("Dimming device %s (%s) to %d", dev.Name, dev.ID, bri)
					dev.State["brightness"] = float64(bri) / 100.0
					affectedDevs[devID] = dev
					if _, ok := levelCommands[v.Params.Brightness]; !ok {
						levelCommands[bri] = googleassistant.ResponseCommand{
							States: googleassistant.ResponseStates{
								Brightness: bri,
							},
							Status: "SUCCESS",
						}
					}
					lvlCmd := levelCommands[bri]
					lvlCmd.IDs = append(lvlCmd.IDs, googleDev.ID)
					levelCommands[bri] = lvlCmd
				}
			}
		}
	}

	shh.node.WriteMessage("state-change", affectedDevs)

	for _, v := range levelCommands {
		resp.Payload.Commands = append(resp.Payload.Commands, v)
	}

	for _, v := range []googleassistant.ResponseCommand{onCommand, offCommand, deviceNotFound, deviceOffline} {
		if v.IDs != nil {
			resp.Payload.Commands = append(resp.Payload.Commands, v)
		}
	}

	if logrus.GetLevel() >= logrus.DebugLevel {
		jResp, err := json.Marshal(resp)
		logrus.Debugf("Execute Error: %s Response: %s", err, string(jResp))
	}
	return resp
}

func (shh *SmartHomeHandler) syncHandler(req *googleassistant.Request) *googleassistant.Response {

	resp := &googleassistant.Response{}
	resp.RequestID = req.RequestID
	resp.Payload.AgentUserID = "agentuserid"

	for _, dev := range shh.deviceList.All() {

		rdev := googleassistant.Device{
			ID:   dev.ID.String(),
			Type: "action.devices.types.LIGHT",
			Name: googleassistant.DeviceName{
				Name: dev.Name,
			},
			WillReportState: false,
			Traits: []string{
				"action.devices.traits.OnOff",
				"action.devices.traits.Brightness",
				//"action.devices.traits.ColorTemperature",
				//"action.devices.traits.ColorSpectrum",
			},
			//Attributes: googleassistant.DeviceAttributes{
			//ColorModel:      "RGB",
			//TemperatureMinK: 2000,
			//TemperatureMaxK: 6500,
			//},
		}
		resp.Payload.Devices = append(resp.Payload.Devices, rdev)

	}

	logrus.Debug("Sync Response: ", resp)
	return resp
}
<commit_msg>Ignore non controllable devs<commit_after>package main

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

	"github.com/RangelReale/osin"
	"github.com/davecgh/go-spew/spew"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/stampzilla/stampzilla-go/nodes/stampzilla-google-assistant/googleassistant"
	"github.com/stampzilla/stampzilla-go/nodes/stampzilla-server/models/devices"
	"github.com/stampzilla/stampzilla-go/pkg/node"
)

// SmartHomeHandler contains the logic to answer Google Actions API requests and authorize them usnig oauth2.
type SmartHomeHandler struct {
	node       *node.Node
	deviceList *devices.List
}

// NewSmartHomeHandler returns a new instance of SmartHomeHandler.
func NewSmartHomeHandler(node *node.Node, deviceList *devices.List) *SmartHomeHandler {
	return &SmartHomeHandler{
		node:       node,
		deviceList: deviceList,
	}

}

func (shh *SmartHomeHandler) smartHomeActionHandler(oauth2server *osin.Server) func(c *gin.Context) {
	return func(c *gin.Context) {
		auth := osin.CheckBearerAuth(c.Request)
		if auth == nil {
			logrus.Error("CheckBearerAuth error")
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		accessToken, err := oauth2server.Storage.LoadAccess(auth.Code)
		if err != nil || accessToken == nil {
			logrus.Errorf("LoadAccess error: %#v", err)
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		if accessToken.IsExpired() {
			logrus.Errorf("Accesstoken %s expired at: %s", accessToken.AccessToken, accessToken.ExpireAt())
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		dec := json.NewDecoder(c.Request.Body)
		defer c.Request.Body.Close()

		//body, err := ioutil.ReadAll(c.Request.Body)
		//if err != nil {
		//logrus.Error(err)
		//return
		//}
		//logrus.Info(string(body))

		r := &googleassistant.Request{}

		err = dec.Decode(r)
		if err != nil {
			logrus.Error(err)
			return
		}

		logrus.Info("Intent: ", r.Inputs.Intent())
		logrus.Debug("Request:", spew.Sdump(r))
		switch r.Inputs.Intent() {
		case googleassistant.SyncIntent:
			c.JSON(http.StatusOK, shh.syncHandler(r))
		case googleassistant.ExecuteIntent:
			c.JSON(http.StatusOK, shh.executeHandler(r))

		}
	}
}

func (shh *SmartHomeHandler) executeHandler(req *googleassistant.Request) *googleassistant.Response {
	resp := &googleassistant.Response{}
	resp.RequestID = req.RequestID

	levelCommands := make(map[int]googleassistant.ResponseCommand)

	onCommand := googleassistant.NewResponseCommand()
	onCommand.States.On = true
	onCommand.States.Online = true
	offCommand := googleassistant.NewResponseCommand()
	offCommand.States.Online = true

	deviceNotFound := googleassistant.NewResponseCommand()
	deviceNotFound.Status = "ERROR"
	deviceNotFound.ErrorCode = "deviceNotFound"

	deviceOffline := googleassistant.NewResponseCommand()
	deviceOffline.Status = "OFFLINE"

	affectedDevs := make(devices.DeviceMap)

	for _, command := range req.Inputs.Payload().Commands {

		for _, v := range command.Execution {
			for _, googleDev := range command.Devices {
				devID, err := devices.NewIDFromString(googleDev.ID)
				if err != nil {
					logrus.Error(err)
					continue
				}

				dev := shh.deviceList.Get(devID)
				if dev == nil || dev.Type != "light" {
					deviceNotFound.IDs = append(deviceNotFound.IDs, googleDev.ID)
					continue
				}

				if !dev.Online {
					deviceOffline.IDs = append(deviceOffline.IDs, googleDev.ID)
					continue
				}
				if v.Command == googleassistant.CommandOnOff {
					if v.Params.On {
						logrus.Infof("Turning device %s (%s) on ", dev.Name, dev.ID)
						dev.State["on"] = true
						onCommand.IDs = append(onCommand.IDs, googleDev.ID)
					} else {
						offCommand.IDs = append(onCommand.IDs, googleDev.ID)
						logrus.Infof("Turning device %s (%s) off", dev.Name, dev.ID)
						dev.State["on"] = false
					}
					affectedDevs[devID] = dev
				}
				if v.Command == googleassistant.CommandBrightnessAbsolute {
					bri := v.Params.Brightness
					logrus.Infof("Dimming device %s (%s) to %d", dev.Name, dev.ID, bri)
					dev.State["brightness"] = float64(bri) / 100.0
					affectedDevs[devID] = dev
					if _, ok := levelCommands[v.Params.Brightness]; !ok {
						levelCommands[bri] = googleassistant.ResponseCommand{
							States: googleassistant.ResponseStates{
								Brightness: bri,
							},
							Status: "SUCCESS",
						}
					}
					lvlCmd := levelCommands[bri]
					lvlCmd.IDs = append(lvlCmd.IDs, googleDev.ID)
					levelCommands[bri] = lvlCmd
				}
			}
		}
	}

	shh.node.WriteMessage("state-change", affectedDevs)

	for _, v := range levelCommands {
		resp.Payload.Commands = append(resp.Payload.Commands, v)
	}

	for _, v := range []googleassistant.ResponseCommand{onCommand, offCommand, deviceNotFound, deviceOffline} {
		if v.IDs != nil {
			resp.Payload.Commands = append(resp.Payload.Commands, v)
		}
	}

	if logrus.GetLevel() >= logrus.DebugLevel {
		jResp, err := json.Marshal(resp)
		logrus.Debugf("Execute Error: %s Response: %s", err, string(jResp))
	}
	return resp
}

func (shh *SmartHomeHandler) syncHandler(req *googleassistant.Request) *googleassistant.Response {

	resp := &googleassistant.Response{}
	resp.RequestID = req.RequestID
	resp.Payload.AgentUserID = "agentuserid"

	for _, dev := range shh.deviceList.All() {

		skip := true
		for _, v := range dev.Traits {
			if v == "OnOff" || v == "Brightness" {
				skip = false
				break
			}
		}

		if skip {
			continue
		}

		rdev := googleassistant.Device{
			ID:   dev.ID.String(),
			Type: "action.devices.types.LIGHT",
			Name: googleassistant.DeviceName{
				Name: dev.Name,
			},
			WillReportState: false,
			Traits: []string{
				"action.devices.traits.OnOff",
				"action.devices.traits.Brightness",
				//"action.devices.traits.ColorTemperature",
				//"action.devices.traits.ColorSpectrum",
			},
			//Attributes: googleassistant.DeviceAttributes{
			//ColorModel:      "RGB",
			//TemperatureMinK: 2000,
			//TemperatureMaxK: 6500,
			//},
		}
		resp.Payload.Devices = append(resp.Payload.Devices, rdev)

	}

	logrus.Debug("Sync Response: ", resp)
	return resp
}
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

// +build gofuzz

package vm

import (
	"bytes"
	"flag"
	"fmt"
)

func Fuzz(data []byte) int {
	// Enable this when debugging with a fuzz crash artifact.
	dumpDebug := false
	// We need to successfully parse flags to initialize the glog logger used
	// by the compiler, but the fuzzer gets called with flags captured by the
	// libfuzzer main, which we don't want to intercept here.
	flag.CommandLine = flag.NewFlagSet("", flag.ContinueOnError)
	if _, err := Compile("fuzz", bytes.NewReader(data), dumpDebug, dumpDebug, false, nil); err != nil {
		if dumpDebug {
			fmt.Print(err)
		}
		return 0
	}
	return 1
}
<commit_msg>Correctly initialize the commandline now.<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

// +build gofuzz

package vm

import (
	"bytes"
	"flag"
	"fmt"
)

func Fuzz(data []byte) int {
	// Enable this when debugging with a fuzz crash artifact.
	dumpDebug := false
	// We need to successfully parse flags to initialize the glog logger used
	// by the compiler, but the fuzzer gets called with flags captured by the
	// libfuzzer main, which we don't want to intercept here.
	flag.CommandLine = flag.NewFlagSet("", flag.ContinueOnError)
	if dumpDebug {
		flag.CommandLine.Parse([]string{})
	} else {
		flag.CommandLine.Parse([]string{"--vmodule=checker=0"})
	}
	if _, err := Compile("fuzz", bytes.NewReader(data), dumpDebug, dumpDebug, false, nil); err != nil {
		if dumpDebug {
			fmt.Print(err)
		}
		return 0
	}
	return 1
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/peterh/liner"
	"github.com/pingcap/tidb"
	"github.com/pingcap/tidb/terror"
	"github.com/pingcap/tidb/util/printer"
)

var (
	logLevel = flag.String("L", "error", "log level")
	store    = flag.String("store", "goleveldb", "the name for the registered storage, e.g. memory, goleveldb, boltdb")
	dbPath   = flag.String("dbpath", "test/test", "db path")
	lease    = flag.Int("lease", 300, "schema lease seconds, very dangerous to change only if you know what you do")

	line        *liner.State
	historyPath = "/tmp/tidb_interpreter"
)

func openHistory() {
	if f, err := os.Open(historyPath); err == nil {
		line.ReadHistory(f)
		f.Close()
	}
}

func saveHistory() {
	if f, err := os.Create(historyPath); err == nil {
		line.WriteHistory(f)
		f.Close()
	}
}

func executeLine(tx *sql.Tx, txnLine string) error {
	start := time.Now()
	if tidb.IsQuery(txnLine) {
		rows, err := tx.Query(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		defer rows.Close()
		cols, err := rows.Columns()
		if err != nil {
			return errors.Trace(err)
		}

		values := make([][]byte, len(cols))
		scanArgs := make([]interface{}, len(values))
		for i := range values {
			scanArgs[i] = &values[i]
		}

		var datas [][]string
		for rows.Next() {
			err := rows.Scan(scanArgs...)
			if err != nil {
				return errors.Trace(err)
			}

			data := make([]string, len(cols))
			for i, value := range values {
				if value == nil {
					data[i] = "NULL"
				} else {
					data[i] = string(value)
				}
			}

			datas = append(datas, data)
		}

		// For `cols` and `datas[i]` always has the same length,
		// no need to check return validity.
		result, _ := printer.GetPrintResult(cols, datas)
		fmt.Printf("%s", result)

		switch len(datas) {
		case 0:
			fmt.Printf("Empty set")
		case 1:
			fmt.Printf("1 row in set")
		default:
			fmt.Printf("%v rows in set", len(datas))
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
		if err := rows.Err(); err != nil {
			return errors.Trace(err)
		}
	} else {
		// TODO: last insert id
		res, err := tx.Exec(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		cnt, err := res.RowsAffected()
		if err != nil {
			return errors.Trace(err)
		}
		switch cnt {
		case 0, 1:
			fmt.Printf("Query OK, %d row affected", cnt)
		default:
			fmt.Printf("Query OK, %d rows affected", cnt)
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
	}
	return nil
}

func mayExit(err error, l string) bool {
	if terror.ErrorEqual(err, liner.ErrPromptAborted) || terror.ErrorEqual(err, io.EOF) {
		fmt.Println("\nBye")
		saveHistory()
		return true
	}
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}
	return false
}

func readStatement(prompt string) (string, error) {
	var ret string
	for {
		l, err := line.Prompt(prompt)
		if err != nil {
			return "", err
		}
		if strings.HasSuffix(l, ";") == false {
			ret += l + "\n"
			prompt = "   -> "
			continue
		}
		return ret + l, nil
	}
}

func main() {
	printer.PrintTiDBInfo()

	flag.Parse()
	log.SetLevelByString(*logLevel)
	// support for signal notify
	runtime.GOMAXPROCS(runtime.NumCPU())

	line = liner.NewLiner()
	defer line.Close()

	line.SetCtrlCAborts(true)
	openHistory()

	tidb.SetSchemaLease(time.Duration(*lease) * time.Second)

	mdb, err := sql.Open(tidb.DriverName, *store+"://"+*dbPath)
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}

	for {
		l, err := readStatement("tidb> ")
		if mayExit(err, l) {
			return
		}
		line.AppendHistory(l)

		// if we're in transaction
		if strings.HasPrefix(l, "BEGIN") || strings.HasPrefix(l, "begin") {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			for {
				txnLine, err := readStatement(">> ")
				if mayExit(err, txnLine) {
					return
				}
				line.AppendHistory(txnLine)

				if !strings.HasSuffix(txnLine, ";") {
					txnLine += ";"
				}

				if strings.HasPrefix(txnLine, "COMMIT") || strings.HasPrefix(txnLine, "commit") {
					err = tx.Commit()
					if err != nil {
						log.Error(errors.ErrorStack(err))
						tx.Rollback()
					}
					break
				}
				// normal sql statement
				err = executeLine(tx, txnLine)
				if err != nil {
					log.Error(errors.ErrorStack(err))
					tx.Rollback()
					break
				}
			}
		} else {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			err = executeLine(tx, l)
			if err != nil {
				log.Error(errors.ErrorStack(err))
				tx.Rollback()
			} else {
				tx.Commit()
			}
		}
	}
}
<commit_msg>interpreter: print error when commit failed<commit_after>// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/peterh/liner"
	"github.com/pingcap/tidb"
	"github.com/pingcap/tidb/terror"
	"github.com/pingcap/tidb/util/printer"
)

var (
	logLevel = flag.String("L", "error", "log level")
	store    = flag.String("store", "goleveldb", "the name for the registered storage, e.g. memory, goleveldb, boltdb")
	dbPath   = flag.String("dbpath", "test/test", "db path")
	lease    = flag.Int("lease", 300, "schema lease seconds, very dangerous to change only if you know what you do")

	line        *liner.State
	historyPath = "/tmp/tidb_interpreter"
)

func openHistory() {
	if f, err := os.Open(historyPath); err == nil {
		line.ReadHistory(f)
		f.Close()
	}
}

func saveHistory() {
	if f, err := os.Create(historyPath); err == nil {
		line.WriteHistory(f)
		f.Close()
	}
}

func executeLine(tx *sql.Tx, txnLine string) error {
	start := time.Now()
	if tidb.IsQuery(txnLine) {
		rows, err := tx.Query(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		defer rows.Close()
		cols, err := rows.Columns()
		if err != nil {
			return errors.Trace(err)
		}

		values := make([][]byte, len(cols))
		scanArgs := make([]interface{}, len(values))
		for i := range values {
			scanArgs[i] = &values[i]
		}

		var datas [][]string
		for rows.Next() {
			err := rows.Scan(scanArgs...)
			if err != nil {
				return errors.Trace(err)
			}

			data := make([]string, len(cols))
			for i, value := range values {
				if value == nil {
					data[i] = "NULL"
				} else {
					data[i] = string(value)
				}
			}

			datas = append(datas, data)
		}

		// For `cols` and `datas[i]` always has the same length,
		// no need to check return validity.
		result, _ := printer.GetPrintResult(cols, datas)
		fmt.Printf("%s", result)

		switch len(datas) {
		case 0:
			fmt.Printf("Empty set")
		case 1:
			fmt.Printf("1 row in set")
		default:
			fmt.Printf("%v rows in set", len(datas))
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
		if err := rows.Err(); err != nil {
			return errors.Trace(err)
		}
	} else {
		// TODO: last insert id
		res, err := tx.Exec(txnLine)
		elapsed := time.Since(start).Seconds()
		if err != nil {
			return errors.Trace(err)
		}
		cnt, err := res.RowsAffected()
		if err != nil {
			return errors.Trace(err)
		}
		switch cnt {
		case 0, 1:
			fmt.Printf("Query OK, %d row affected", cnt)
		default:
			fmt.Printf("Query OK, %d rows affected", cnt)
		}
		fmt.Printf(" (%.2f sec)\n", elapsed)
	}
	return nil
}

func mayExit(err error, l string) bool {
	if terror.ErrorEqual(err, liner.ErrPromptAborted) || terror.ErrorEqual(err, io.EOF) {
		fmt.Println("\nBye")
		saveHistory()
		return true
	}
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}
	return false
}

func readStatement(prompt string) (string, error) {
	var ret string
	for {
		l, err := line.Prompt(prompt)
		if err != nil {
			return "", err
		}
		if strings.HasSuffix(l, ";") == false {
			ret += l + "\n"
			prompt = "   -> "
			continue
		}
		return ret + l, nil
	}
}

func main() {
	printer.PrintTiDBInfo()

	flag.Parse()
	log.SetLevelByString(*logLevel)
	// support for signal notify
	runtime.GOMAXPROCS(runtime.NumCPU())

	line = liner.NewLiner()
	defer line.Close()

	line.SetCtrlCAborts(true)
	openHistory()

	tidb.SetSchemaLease(time.Duration(*lease) * time.Second)

	mdb, err := sql.Open(tidb.DriverName, *store+"://"+*dbPath)
	if err != nil {
		log.Fatal(errors.ErrorStack(err))
	}

	for {
		l, err := readStatement("tidb> ")
		if mayExit(err, l) {
			return
		}
		line.AppendHistory(l)

		// if we're in transaction
		if strings.HasPrefix(l, "BEGIN") || strings.HasPrefix(l, "begin") {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			for {
				txnLine, err := readStatement(">> ")
				if mayExit(err, txnLine) {
					return
				}
				line.AppendHistory(txnLine)

				if !strings.HasSuffix(txnLine, ";") {
					txnLine += ";"
				}

				if strings.HasPrefix(txnLine, "COMMIT") || strings.HasPrefix(txnLine, "commit") {
					err = tx.Commit()
					if err != nil {
						log.Error(errors.ErrorStack(err))
						tx.Rollback()
					}
					break
				}
				// normal sql statement
				err = executeLine(tx, txnLine)
				if err != nil {
					log.Error(errors.ErrorStack(err))
					tx.Rollback()
					break
				}
			}
		} else {
			tx, err := mdb.Begin()
			if err != nil {
				log.Error(errors.ErrorStack(err))
				continue
			}
			err = executeLine(tx, l)
			if err != nil {
				log.Error(errors.ErrorStack(err))
				tx.Rollback()
				continue
			}
			err = tx.Commit()
			if err != nil {
				log.Error(errors.ErrorStack(err))
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"testing"
)

var db *DBInfo

var testDBName string

func TestMain(m *testing.M) {
	var err error
	db, err = getConnectInfo()
	if err != nil {
		log.Fatal(err)
	}
	persistDB := flag.Bool("persist", false, "True, leave the DB container running")
	killDB := flag.Bool("kill", false, "True, kill the DB Container and return.  No tests are run.")
	flag.Parse()
	if *killDB {
		log.Println("Shutting down container...")
		errShutdown := shutdown()
		if errShutdown != nil {
			log.Println(errShutdown)
		}
		log.Println("Shutdown complete.")
		return
	}
	keepDB, errSetup := setup()
	if errSetup != nil {
		log.Println("Setup Error:", errSetup)
	}
	var code int
	if errSetup == nil {
		testDB, errTest := getConnectInfo()
		if errTest != nil {
			log.Println(errTest)
			return
		}
		testDBName = fmt.Sprintf("%s_test", testDB.DBName)
		errCreate := createDB(testDBName)
		if errCreate != nil {
			log.Println(errCreate)
			return
		}
		code = m.Run()
		if !*persistDB && !keepDB {
			errShutdown := shutdown()
			if errShutdown != nil {
				log.Println(errShutdown)
			}
		}
	} else {
		log.Println(errSetup)
	}
	os.Exit(code)
}

func createDB(newdbname string) error {
	killconnstmt := `SELECT pg_terminate_backend(pg_stat_activity.pid)
										FROM pg_stat_activity
										WHERE datname = current_database()
  									AND pid <> pg_backend_pid();`
	dropstmt := fmt.Sprintf("DROP DATABASE IF EXISTS %s;", newdbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, db.DBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	createtemplate := "CREATE DATABASE %s WITH TEMPLATE %s OWNER %s;"
	createstatment := fmt.Sprintf(createtemplate, newdbname, db.DBName, db.UserName)

	//Kill the connections so we can drop/copy the DB
	_, errKillCn := cn.Exec(killconnstmt)
	if errKillCn != nil {
		return errKillCn
	}

	//Drop the test database if it already exists, we don't want it anymore.
	_, errDrop := cn.Exec(dropstmt)
	if errDrop != nil {
		return errDrop
	}
	//Make a copy of the test database from the origin_db`
	_, errExec := cn.Exec(createstatment)
	return errExec
}

func TestInsertMovie(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertMovie := "insert into movie (title) values ('Raiders of the Lost Ark');"
	_, errExec := cn.Exec(insertMovie)
	if errExec != nil {
		t.Error(errExec)
	}

}

func TestInsertActor(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Karen Allen');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestAddActorToMovie(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertMovieActor := `insert into movieactor (movie_id,actor_id) values (4,5);
	insert into movieactor (movie_id,actor_id) values (4,1);
	`
	_, errExec := cn.Exec(insertMovieActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestCheckRaiders(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	queryRaiders := "select a.name from actor a, movieactor ma where ma.movie_id = 4 and ma.actor_id = a.id;"

	rows, err := cn.Query(queryRaiders)
	actornames := []string{}
	for rows.Next() {
		var name string
		if errScan := rows.Scan(&name); err != nil {
			t.Fatal(errScan)
		}
		actornames = append(actornames, name)

	}
	if err := rows.Err(); err != nil {
		t.Fatal(err)
	}
	if actornames[0] != "Harrison Ford" {
		t.Errorf("Harrison Ford should have been the first row. Received: %s\n", actornames[0])
	}
	if actornames[1] != "Karen Allen" {
		t.Errorf("Karen Allen should have been the second row. Received: %s\n", actornames[0])
	}
}

func TestCheckHarrisonFord(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	queryFord := "select m.title from movie m, movieactor ma where ma.movie_id = m.id and ma.actor_id = 1;"

	rows, err := cn.Query(queryFord)
	movies := []string{}
	for rows.Next() {
		var title string
		if errScan := rows.Scan(&title); err != nil {
			t.Fatal(errScan)
		}
		movies = append(movies, title)

	}
	if err := rows.Err(); err != nil {
		t.Fatal(err)
	}
	expected := "[Star Wars Apocalypse Now Raiders of the Lost Ark]"
	result := fmt.Sprintf("%v", movies)
	if string(result) != expected {
		t.Errorf("Expected %s\nReceived: %s\n", expected, result)
	}
}

func TestInsertActorA(t *testing.T) {
	dbname := "testa"
	createDB(dbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, dbname)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Clint Eastwood');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestInsertActorB(t *testing.T) {
	dbname := "testb"
	createDB(dbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, dbname)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Morgan Freeman');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}
<commit_msg>need to kill connections to the created test DB's as well, not just the ones to the origin<commit_after>package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"testing"
)

var db *DBInfo

var testDBName string

func TestMain(m *testing.M) {
	var err error
	db, err = getConnectInfo()
	if err != nil {
		log.Fatal(err)
	}
	persistDB := flag.Bool("persist", false, "True, leave the DB container running")
	killDB := flag.Bool("kill", false, "True, kill the DB Container and return.  No tests are run.")
	flag.Parse()
	if *killDB {
		log.Println("Shutting down container...")
		errShutdown := shutdown()
		if errShutdown != nil {
			log.Println(errShutdown)
		}
		log.Println("Shutdown complete.")
		return
	}
	keepDB, errSetup := setup()
	if errSetup != nil {
		log.Println("Setup Error:", errSetup)
	}
	var code int
	if errSetup == nil {
		testDB, errTest := getConnectInfo()
		if errTest != nil {
			log.Println(errTest)
			return
		}
		testDBName = fmt.Sprintf("%s_test", testDB.DBName)
		errCreate := createDB(testDBName)
		if errCreate != nil {
			log.Println(errCreate)
			return
		}
		code = m.Run()
		if !*persistDB && !keepDB {
			errShutdown := shutdown()
			if errShutdown != nil {
				log.Println(errShutdown)
			}
		}
	} else {
		log.Println(errSetup)
	}
	os.Exit(code)
}

func createDB(newdbname string) error {
	killconnstmt := fmt.Sprintf(`SELECT pg_terminate_backend(pg_stat_activity.pid)
										FROM pg_stat_activity
										WHERE (datname = current_database() or datname = '%s')
  									AND pid <> pg_backend_pid();`, newdbname)
	dropstmt := fmt.Sprintf("DROP DATABASE IF EXISTS %s;", newdbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, db.DBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	createtemplate := "CREATE DATABASE %s WITH TEMPLATE %s OWNER %s;"
	createstatment := fmt.Sprintf(createtemplate, newdbname, db.DBName, db.UserName)

	//Kill the connections so we can drop/copy the DB
	_, errKillCn := cn.Exec(killconnstmt)
	if errKillCn != nil {
		return errKillCn
	}

	//Drop the test database if it already exists, we don't want it anymore.
	_, errDrop := cn.Exec(dropstmt)
	if errDrop != nil {
		return errDrop
	}
	//Make a copy of the test database from the origin_db`
	_, errExec := cn.Exec(createstatment)
	return errExec
}

func TestInsertMovie(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertMovie := "insert into movie (title) values ('Raiders of the Lost Ark');"
	_, errExec := cn.Exec(insertMovie)
	if errExec != nil {
		t.Error(errExec)
	}

}

func TestInsertActor(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Karen Allen');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestAddActorToMovie(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertMovieActor := `insert into movieactor (movie_id,actor_id) values (4,5);
	insert into movieactor (movie_id,actor_id) values (4,1);
	`
	_, errExec := cn.Exec(insertMovieActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestCheckRaiders(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	queryRaiders := "select a.name from actor a, movieactor ma where ma.movie_id = 4 and ma.actor_id = a.id;"

	rows, err := cn.Query(queryRaiders)
	actornames := []string{}
	for rows.Next() {
		var name string
		if errScan := rows.Scan(&name); err != nil {
			t.Fatal(errScan)
		}
		actornames = append(actornames, name)

	}
	if err := rows.Err(); err != nil {
		t.Fatal(err)
	}
	if actornames[0] != "Harrison Ford" {
		t.Errorf("Harrison Ford should have been the first row. Received: %s\n", actornames[0])
	}
	if actornames[1] != "Karen Allen" {
		t.Errorf("Karen Allen should have been the second row. Received: %s\n", actornames[0])
	}
}

func TestCheckHarrisonFord(t *testing.T) {
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, testDBName)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	queryFord := "select m.title from movie m, movieactor ma where ma.movie_id = m.id and ma.actor_id = 1;"

	rows, err := cn.Query(queryFord)
	movies := []string{}
	for rows.Next() {
		var title string
		if errScan := rows.Scan(&title); err != nil {
			t.Fatal(errScan)
		}
		movies = append(movies, title)

	}
	if err := rows.Err(); err != nil {
		t.Fatal(err)
	}
	expected := "[Star Wars Apocalypse Now Raiders of the Lost Ark]"
	result := fmt.Sprintf("%v", movies)
	if string(result) != expected {
		t.Errorf("Expected %s\nReceived: %s\n", expected, result)
	}
}

func TestInsertActorA(t *testing.T) {
	dbname := "testa"
	createDB(dbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, dbname)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Clint Eastwood');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}

func TestInsertActorB(t *testing.T) {
	dbname := "testb"
	createDB(dbname)
	constr := fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", db.Host, db.UserName, db.Password, dbname)
	cn, _ := sql.Open("postgres", constr)
	defer cn.Close()
	insertActor := "insert into actor (name) values ('Morgan Freeman');"
	_, errExec := cn.Exec(insertActor)
	if errExec != nil {
		t.Error(errExec)
	}
}
<|endoftext|>


<commit_before>package app

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	"github.com/magnusbaeck/logstash-filter-verifier/v2/internal/logging"
)

const (
	exitCodeNormal = 0
	exitCodeError  = 1
)

func Execute(version string, stdout, stderr io.Writer) int {
	log := logging.MustGetLogger()
	viper.Set("logger", log)

	// Initialize config
	viper.SetConfigName("logstash-filter-verifier") // name of config file (without extension)
	viper.AddConfigPath(".")
	configDir, err := os.UserConfigDir()
	if err == nil {
		viper.AddConfigPath(filepath.Join(configDir, "logstash-filter-verifier"))
	}
	viper.AddConfigPath("/etc/logstash-filter-verifier/")

	// Setup default values
	viper.SetDefault("loglevel", "WARNING")
	viper.SetDefault("socket", "/tmp/logstash-filter-verifier.sock")
	viper.SetDefault("pipeline", "/etc/logstash/pipelines.yml")
	viper.SetDefault("logstash.path", "")

	// Read config
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
			log.Errorf("Error processing config file: %v", err)
			return exitCodeError
		}
	}

	rootCmd := makeRootCmd(version)
	rootCmd.SetOut(stdout)
	rootCmd.SetErr(stderr)
	rootCmd.SilenceUsage = true

	if err := rootCmd.Execute(); err != nil {
		prefixedUserError(stderr, "error: %v", err)
		return exitCodeError
	}

	return exitCodeNormal
}

func makeRootCmd(version string) *cobra.Command {
	rootCmd := &cobra.Command{
		Use: "logstash-filter-verifier",
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			logging.SetLevel(viper.GetString("loglevel"))
		},
		Run: func(cmd *cobra.Command, args []string) {
			_ = cmd.Help()
		},
		SilenceErrors: true,
		Version:       version,
	}

	rootCmd.InitDefaultVersionFlag()

	rootCmd.PersistentFlags().String("loglevel", "WARNING", "Set the desired level of logging (one of: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG).")
	_ = viper.BindPFlag("loglevel", rootCmd.PersistentFlags().Lookup("loglevel"))

	rootCmd.AddCommand(makeStandaloneCmd())
	rootCmd.AddCommand(makeDaemonCmd())
	rootCmd.AddCommand(makeSetupCmd())

	return rootCmd
}

// prefixedUserError prints an error message to stderr and prefixes it
// with the name of the program file (e.g. "logstash-filter-verifier:
// something bad happened.").
func prefixedUserError(out io.Writer, format string, a ...interface{}) {
	basename := filepath.Base(os.Args[0])
	message := fmt.Sprintf(format, a...)
	if strings.HasSuffix(message, "\n") {
		fmt.Fprintf(out, "%s: %s", basename, message)
	} else {
		fmt.Fprintf(out, "%s: %s\n", basename, message)
	}
}
<commit_msg>Add default values to viper<commit_after>package app

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	"github.com/magnusbaeck/logstash-filter-verifier/v2/internal/logging"
)

const (
	exitCodeNormal = 0
	exitCodeError  = 1
)

func Execute(version string, stdout, stderr io.Writer) int {
	log := logging.MustGetLogger()
	viper.Set("logger", log)

	// Initialize config
	viper.SetConfigName("logstash-filter-verifier") // name of config file (without extension)
	viper.AddConfigPath(".")
	configDir, err := os.UserConfigDir()
	if err == nil {
		viper.AddConfigPath(filepath.Join(configDir, "logstash-filter-verifier"))
	}
	viper.AddConfigPath("/etc/logstash-filter-verifier/")

	// Setup default values
	viper.SetDefault("loglevel", "WARNING")
	viper.SetDefault("socket", "/tmp/logstash-filter-verifier.sock")
	viper.SetDefault("pipeline", "/etc/logstash/pipelines.yml")
	viper.SetDefault("logstash.path", "/usr/share/logstash/bin/logstash")
	viper.SetDefault("inflight-shutdown-timeout", 10*time.Second)
	viper.SetDefault("shutdown-timeout", 3*time.Second)

	// Read config
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
			log.Errorf("Error processing config file: %v", err)
			return exitCodeError
		}
	}

	rootCmd := makeRootCmd(version)
	rootCmd.SetOut(stdout)
	rootCmd.SetErr(stderr)
	rootCmd.SilenceUsage = true

	if err := rootCmd.Execute(); err != nil {
		prefixedUserError(stderr, "error: %v", err)
		return exitCodeError
	}

	return exitCodeNormal
}

func makeRootCmd(version string) *cobra.Command {
	rootCmd := &cobra.Command{
		Use: "logstash-filter-verifier",
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			logging.SetLevel(viper.GetString("loglevel"))
		},
		Run: func(cmd *cobra.Command, args []string) {
			_ = cmd.Help()
		},
		SilenceErrors: true,
		Version:       version,
	}

	rootCmd.InitDefaultVersionFlag()

	rootCmd.PersistentFlags().String("loglevel", "WARNING", "Set the desired level of logging (one of: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG).")
	_ = viper.BindPFlag("loglevel", rootCmd.PersistentFlags().Lookup("loglevel"))

	rootCmd.AddCommand(makeStandaloneCmd())
	rootCmd.AddCommand(makeDaemonCmd())
	rootCmd.AddCommand(makeSetupCmd())

	return rootCmd
}

// prefixedUserError prints an error message to stderr and prefixes it
// with the name of the program file (e.g. "logstash-filter-verifier:
// something bad happened.").
func prefixedUserError(out io.Writer, format string, a ...interface{}) {
	basename := filepath.Base(os.Args[0])
	message := fmt.Sprintf(format, a...)
	if strings.HasSuffix(message, "\n") {
		fmt.Fprintf(out, "%s: %s", basename, message)
	} else {
		fmt.Fprintf(out, "%s: %s\n", basename, message)
	}
}
<|endoftext|>


<commit_before>package internal

import "database/sql"

// ArgType is the type that specifies the command line arguments.
type ArgType struct {
	// Verbose enables verbose output.
	Verbose bool `arg:"-v,help:toggle verbose"`

	// DSN is the database string (ie, pgsql://user@blah:localhost:5432/dbname?args=)
	DSN string `arg:"positional,required,help:data source name"`

	// Schema is the name of the schema to query.
	Schema string `arg:"-s,help:schema name to generate Go types for"`

	// Out is the output path. If Out is a file, then that will be used as the
	// path. If Out is a directory, then the output file will be
	// Out/<$CWD>.xo.go
	Out string `arg:"-o,help:output path or file name"`

	// Append toggles to append to the existing types.
	Append bool `arg:"-a,help:append to existing files"`

	// Suffix is the output suffix for filenames.
	Suffix string `arg:"-f,help:output file suffix"`

	// SingleFile when toggled changes behavior so that output is to one f ile.
	SingleFile bool `arg:"--single-file,help:toggle single file output"`

	// Package is the name used to generate package headers. If not specified,
	// the name of the output directory will be used instead.
	Package string `arg:"-p,help:package name used in generated Go code"`

	// CustomTypePackage is the Go package name to use for unknown types.
	CustomTypePackage string `arg:"--custom-type-package,-C,help:Go package name to use for custom or unknown types"`

	// Int32Type is the type to assign those discovered as int32 (ie, serial, integer, etc).
	Int32Type string `arg:"--int32-type,-i,help:Go type to assign to integers"`

	// Uint32Type is the type to assign those discovered as uint32.
	Uint32Type string `arg:"--uint32-type,-u,help:Go type to assign to unsigned integers"`

	// IgnoreFields allows the user to specify field names which should not be
	// handled by xo in the generated code.
	IgnoreFields []string `arg:"--ignore-fields,help:fields to exclude from the generated Go code types"`

	// ForeignKeyMode is the foreign key mode for generating foreign key names.
	ForeignKeyMode *FkMode `arg:"--fk-mode,-k,help:sets mode for naming foreign key funcs in generated Go code [values: <smart|parent|field|key>]"`

	// UseIndexNames toggles using index names.
	//
	// This is not enabled by default, because index names are often generated
	// using database design software which has the nasty habit of giving
	// non-helpful names to indexes as things like 'authors__b124214__u_idx'
	// instead of 'authors_title_idx'.
	UseIndexNames bool `arg:"--use-index-names,-j,help:use index names as defined in schema for generated Go code"`

	// UseReversedEnumConstNames toggles using reversed enum names.
	UseReversedEnumConstNames bool `arg:"--use-reversed-enum-const-names,-R,help:use reversed enum names for generated consts in Go code"`

	// QueryMode toggles whether or not to parse a query from stdin.
	QueryMode bool `arg:"--query-mode,-N,help:enable query mode"`

	// Query is the passed query. If not specified, then os.Stdin will be used.
	// cli args take precedence over stdin.
	Query string `arg:"-Q,help:query to generate Go type and func from"`

	// QueryType is the name to give to the Go type generated from the query.
	QueryType string `arg:"--query-type,-T,help:query's generated Go type"`

	// QueryFunc is the name to assign to the generated query func.
	QueryFunc string `arg:"--query-func,-F,help:query's generated Go func name"`

	// QueryOnlyOne toggles the generated query code to expect only one result.
	QueryOnlyOne bool `arg:"--query-only-one,-1,help:toggle query's generated Go func to return only one result"`

	// QueryTrim enables triming whitespace on the supplied query.
	QueryTrim bool `arg:"--query-trim,-M,help:toggle trimming of query whitespace in generated Go code"`

	// QueryStrip enables stripping the '::<type> AS <name>' from supplied query.
	QueryStrip bool `arg:"--query-strip,-B,help:toggle stripping type casts from query in generated Go code"`

	// QueryInterpolate enables interpolation in generated query.
	QueryInterpolate bool `arg:"--query-interpolate,-I,help:toggle query interpolation in generated Go code"`

	// TypeComment is the type comment for a query.
	QueryTypeComment string `arg:"--query-type-comment,help:comment for query's generated Go type"`

	// FuncComment is the func comment to provide the named query.
	QueryFuncComment string `arg:"--query-func-comment,help:comment for query's generated Go func"`

	// QueryParamDelimiter is the delimiter for parameterized values for a query.
	QueryParamDelimiter string `arg:"--query-delimiter,-D,help:delimiter for query's embedded Go parameters"`

	// QueryFields are the fields to scan the result to.
	QueryFields string `arg:"--query-fields,-Z,help:comma separated list of field names to scan query's results to the query's associated Go type"`

	// EscapeAll toggles escaping schema, table, and column names in SQL queries.
	EscapeAll bool `arg:"--escape-all,-X,help:escape all names in SQL queries"`

	// EscapeSchemaName toggles escaping schema name in SQL queries.
	EscapeSchemaName bool `arg:"--escape-schema,-z,help:escape schema name in SQL queries"`

	// EscapeTableNames toggles escaping table names in SQL queries.
	EscapeTableNames bool `arg:"--escape-table,-y,help:escape table names in SQL queries"`

	// EscapeColumnNames toggles escaping column names in SQL queries.
	EscapeColumnNames bool `arg:"--escape-column,-x,help:escape column names in SQL queries"`

	// EnablePostgresOIDs toggles postgres oids.
	EnablePostgresOIDs bool `arg:"--enable-postgres-oids,help:enable postgres oids"`

	// NameConflictSuffix is the suffix used when a name conflicts with a scoped Go variable.
	NameConflictSuffix string `arg:"--name-conflict-suffix,-w,help:suffix to append when a name conflicts with a Go variable"`

	// TemplatePath is the path to use the user supplied templates instead of
	// the built in versions.
	TemplatePath string `arg:"--template-path,help:user supplied template path"`

	// Path is the output path, as derived from Out.
	Path string `arg:"-"`

	// Filename is the output filename, as derived from Out.
	Filename string `arg:"-"`

	// LoaderType is the loader type.
	LoaderType string `arg:"-"`

	// Loader is the schema loader.
	Loader Loader `arg:"-"`

	// DB is the opened database handle.
	DB *sql.DB `arg:"-"`

	// templateSet is the set of templates to use for generating data.
	templateSet *TemplateSet `arg:"-"`

	// Generated is the generated templates after a run.
	Generated []TBuf `arg:"-"`

	// KnownTypeMap is the collection of known Go types.
	KnownTypeMap map[string]bool `arg:"-"`

	// ShortNameTypeMap is the collection of Go style short names for types, mainly
	// used for use with declaring a func receiver on a type.
	ShortNameTypeMap map[string]string `arg:"-"`
}

// NewDefaultArgs returns the default arguments.
func NewDefaultArgs() *ArgType {
	fkMode := FkModeSmart

	return &ArgType{
		Suffix:              ".xo.go",
		Int32Type:           "int",
		Uint32Type:          "uint",
		ForeignKeyMode:      &fkMode,
		QueryParamDelimiter: "%%",
		NameConflictSuffix:  "Val",

		// KnownTypeMap is the collection of known Go types.
		KnownTypeMap: map[string]bool{
			"bool":        true,
			"string":      true,
			"byte":        true,
			"rune":        true,
			"int":         true,
			"int16":       true,
			"int32":       true,
			"int64":       true,
			"uint":        true,
			"uint8":       true,
			"uint16":      true,
			"uint32":      true,
			"uint64":      true,
			"float32":     true,
			"float64":     true,
			"Slice":       true,
			"StringSlice": true,
		},

		// ShortNameTypeMap is the collection of Go style short names for types, mainly
		// used for use with declaring a func receiver on a type.
		ShortNameTypeMap: map[string]string{
			"bool":        "b",
			"string":      "s",
			"byte":        "b",
			"rune":        "r",
			"int":         "i",
			"int16":       "i",
			"int32":       "i",
			"int64":       "i",
			"uint":        "u",
			"uint8":       "u",
			"uint16":      "u",
			"uint32":      "u",
			"uint64":      "u",
			"float32":     "f",
			"float64":     "f",
			"Slice":       "s",
			"StringSlice": "ss",
		},
	}
}

// Args are the application arguments.
var Args *ArgType
<commit_msg>Adding Description to internal.ArgType<commit_after>package internal

import "database/sql"

// ArgType is the type that specifies the command line arguments.
type ArgType struct {
	// Verbose enables verbose output.
	Verbose bool `arg:"-v,help:toggle verbose"`

	// DSN is the database string (ie, pgsql://user@blah:localhost:5432/dbname?args=)
	DSN string `arg:"positional,required,help:data source name"`

	// Schema is the name of the schema to query.
	Schema string `arg:"-s,help:schema name to generate Go types for"`

	// Out is the output path. If Out is a file, then that will be used as the
	// path. If Out is a directory, then the output file will be
	// Out/<$CWD>.xo.go
	Out string `arg:"-o,help:output path or file name"`

	// Append toggles to append to the existing types.
	Append bool `arg:"-a,help:append to existing files"`

	// Suffix is the output suffix for filenames.
	Suffix string `arg:"-f,help:output file suffix"`

	// SingleFile when toggled changes behavior so that output is to one f ile.
	SingleFile bool `arg:"--single-file,help:toggle single file output"`

	// Package is the name used to generate package headers. If not specified,
	// the name of the output directory will be used instead.
	Package string `arg:"-p,help:package name used in generated Go code"`

	// CustomTypePackage is the Go package name to use for unknown types.
	CustomTypePackage string `arg:"--custom-type-package,-C,help:Go package name to use for custom or unknown types"`

	// Int32Type is the type to assign those discovered as int32 (ie, serial, integer, etc).
	Int32Type string `arg:"--int32-type,-i,help:Go type to assign to integers"`

	// Uint32Type is the type to assign those discovered as uint32.
	Uint32Type string `arg:"--uint32-type,-u,help:Go type to assign to unsigned integers"`

	// IgnoreFields allows the user to specify field names which should not be
	// handled by xo in the generated code.
	IgnoreFields []string `arg:"--ignore-fields,help:fields to exclude from the generated Go code types"`

	// ForeignKeyMode is the foreign key mode for generating foreign key names.
	ForeignKeyMode *FkMode `arg:"--fk-mode,-k,help:sets mode for naming foreign key funcs in generated Go code [values: <smart|parent|field|key>]"`

	// UseIndexNames toggles using index names.
	//
	// This is not enabled by default, because index names are often generated
	// using database design software which has the nasty habit of giving
	// non-helpful names to indexes as things like 'authors__b124214__u_idx'
	// instead of 'authors_title_idx'.
	UseIndexNames bool `arg:"--use-index-names,-j,help:use index names as defined in schema for generated Go code"`

	// UseReversedEnumConstNames toggles using reversed enum names.
	UseReversedEnumConstNames bool `arg:"--use-reversed-enum-const-names,-R,help:use reversed enum names for generated consts in Go code"`

	// QueryMode toggles whether or not to parse a query from stdin.
	QueryMode bool `arg:"--query-mode,-N,help:enable query mode"`

	// Query is the passed query. If not specified, then os.Stdin will be used.
	// cli args take precedence over stdin.
	Query string `arg:"-Q,help:query to generate Go type and func from"`

	// QueryType is the name to give to the Go type generated from the query.
	QueryType string `arg:"--query-type,-T,help:query's generated Go type"`

	// QueryFunc is the name to assign to the generated query func.
	QueryFunc string `arg:"--query-func,-F,help:query's generated Go func name"`

	// QueryOnlyOne toggles the generated query code to expect only one result.
	QueryOnlyOne bool `arg:"--query-only-one,-1,help:toggle query's generated Go func to return only one result"`

	// QueryTrim enables triming whitespace on the supplied query.
	QueryTrim bool `arg:"--query-trim,-M,help:toggle trimming of query whitespace in generated Go code"`

	// QueryStrip enables stripping the '::<type> AS <name>' from supplied query.
	QueryStrip bool `arg:"--query-strip,-B,help:toggle stripping type casts from query in generated Go code"`

	// QueryInterpolate enables interpolation in generated query.
	QueryInterpolate bool `arg:"--query-interpolate,-I,help:toggle query interpolation in generated Go code"`

	// TypeComment is the type comment for a query.
	QueryTypeComment string `arg:"--query-type-comment,help:comment for query's generated Go type"`

	// FuncComment is the func comment to provide the named query.
	QueryFuncComment string `arg:"--query-func-comment,help:comment for query's generated Go func"`

	// QueryParamDelimiter is the delimiter for parameterized values for a query.
	QueryParamDelimiter string `arg:"--query-delimiter,-D,help:delimiter for query's embedded Go parameters"`

	// QueryFields are the fields to scan the result to.
	QueryFields string `arg:"--query-fields,-Z,help:comma separated list of field names to scan query's results to the query's associated Go type"`

	// EscapeAll toggles escaping schema, table, and column names in SQL queries.
	EscapeAll bool `arg:"--escape-all,-X,help:escape all names in SQL queries"`

	// EscapeSchemaName toggles escaping schema name in SQL queries.
	EscapeSchemaName bool `arg:"--escape-schema,-z,help:escape schema name in SQL queries"`

	// EscapeTableNames toggles escaping table names in SQL queries.
	EscapeTableNames bool `arg:"--escape-table,-y,help:escape table names in SQL queries"`

	// EscapeColumnNames toggles escaping column names in SQL queries.
	EscapeColumnNames bool `arg:"--escape-column,-x,help:escape column names in SQL queries"`

	// EnablePostgresOIDs toggles postgres oids.
	EnablePostgresOIDs bool `arg:"--enable-postgres-oids,help:enable postgres oids"`

	// NameConflictSuffix is the suffix used when a name conflicts with a scoped Go variable.
	NameConflictSuffix string `arg:"--name-conflict-suffix,-w,help:suffix to append when a name conflicts with a Go variable"`

	// TemplatePath is the path to use the user supplied templates instead of
	// the built in versions.
	TemplatePath string `arg:"--template-path,help:user supplied template path"`

	// Path is the output path, as derived from Out.
	Path string `arg:"-"`

	// Filename is the output filename, as derived from Out.
	Filename string `arg:"-"`

	// LoaderType is the loader type.
	LoaderType string `arg:"-"`

	// Loader is the schema loader.
	Loader Loader `arg:"-"`

	// DB is the opened database handle.
	DB *sql.DB `arg:"-"`

	// templateSet is the set of templates to use for generating data.
	templateSet *TemplateSet `arg:"-"`

	// Generated is the generated templates after a run.
	Generated []TBuf `arg:"-"`

	// KnownTypeMap is the collection of known Go types.
	KnownTypeMap map[string]bool `arg:"-"`

	// ShortNameTypeMap is the collection of Go style short names for types, mainly
	// used for use with declaring a func receiver on a type.
	ShortNameTypeMap map[string]string `arg:"-"`
}

// NewDefaultArgs returns the default arguments.
func NewDefaultArgs() *ArgType {
	fkMode := FkModeSmart

	return &ArgType{
		Suffix:              ".xo.go",
		Int32Type:           "int",
		Uint32Type:          "uint",
		ForeignKeyMode:      &fkMode,
		QueryParamDelimiter: "%%",
		NameConflictSuffix:  "Val",

		// KnownTypeMap is the collection of known Go types.
		KnownTypeMap: map[string]bool{
			"bool":        true,
			"string":      true,
			"byte":        true,
			"rune":        true,
			"int":         true,
			"int16":       true,
			"int32":       true,
			"int64":       true,
			"uint":        true,
			"uint8":       true,
			"uint16":      true,
			"uint32":      true,
			"uint64":      true,
			"float32":     true,
			"float64":     true,
			"Slice":       true,
			"StringSlice": true,
		},

		// ShortNameTypeMap is the collection of Go style short names for types, mainly
		// used for use with declaring a func receiver on a type.
		ShortNameTypeMap: map[string]string{
			"bool":        "b",
			"string":      "s",
			"byte":        "b",
			"rune":        "r",
			"int":         "i",
			"int16":       "i",
			"int32":       "i",
			"int64":       "i",
			"uint":        "u",
			"uint8":       "u",
			"uint16":      "u",
			"uint32":      "u",
			"uint64":      "u",
			"float32":     "f",
			"float64":     "f",
			"Slice":       "s",
			"StringSlice": "ss",
		},
	}
}

// Description provides the description for the command output.
func (a *ArgType) Description() string {
	return `xo is a command line utility to generate Go code from a database schema.
`
}

// Args are the application arguments.
var Args *ArgType
<|endoftext|>


<commit_before>// Copyright (c) 2014 TSUYUSATO Kitsune
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

package hotkey_win

const (
	MOD_ALT     = 1
	MOD_CONTROL = 2
	MOD_SHIFT   = 4
	MOD_WIN     = 8
)
<commit_msg>Update consts.go<commit_after>// Copyright (c) 2014 TSUYUSATO Kitsune
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

package hotkey_win

const (
	MOND_NONE   = 0
	MOD_ALT     = 1
	MOD_CONTROL = 2
	MOD_SHIFT   = 4
	MOD_WIN     = 8
)
<|endoftext|>