<commit_before>package main

// This is a basic example to illustrate how to access the Fidor API
// using Go.
//
// To run this example type:
//
//     $ go run example.go
//
// And point your browser to:
//
//     $ http://localhost:8080

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

// The following sections define the settings you require for the
// app to be able to connect to and authorize itself against the api.

// app ID and secret, can be found in this apps "Details" page in the
// AppManager.
var client_id = "<CLIENT_ID>"
var client_secret = "<CLIENT_SECRET>"

// Fidor's OAuth Endpoint (this changes between Sandbox and Production)
var fidor_oauth_url = "<FIDOR_OAUTH_URL>" // e.g https://fidor.com/api_sandbox/oauth
// The OAuth Endpoint this App provides
var oauth_cb_url = "<APP_URL>"

// The URL of the Fidor API (this changes between Sandbox and
// Production)
var fidor_api_url = "<FIDOR_API_URL>" // e.g https://fidor.com/api_sandbox vs /api

func main() {
	// register a handler function (see next function) to service
	// requests ...
	http.HandleFunc("/", indexHandler)
	fmt.Printf("Now open http://localhost:8080")
	// ... and start listening.
	http.ListenAndServe(":8080", nil)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {

	// ignore any favicon requests, etc.
	if r.URL.Path != "/" {
		w.WriteHeader(404)
		return
	}

	// check whether we have a GET parameter named `code`, if so,
	// this is a redirect back from the Fidor OAuth server.
	values := r.URL.Query()
	if values["code"] != nil {
		// retrieve the actual OAuth access token ....
		code := values.Get("code")
		if token, err := retrieveTokenFromCode(code); err != nil {
			fmt.Printf("err: %v\n", err)
			w.WriteHeader(500)
			fmt.Fprintf(w, "Unfortunately, an error occurred retrieving oauth token")
		} else {
			// ... and finally, greet the user and assemble links
			renderWelcome(w, token)
		}
	} else {
		// we don't have an oauth `code` yet, so we need to
		// redirect the user to the OAuth provider to get one ...
		oauth_url := fmt.Sprintf("%s/authorize?client_id=%s&state=123&response_type=code&redirect_uri=%s",
			fidor_oauth_url,
			client_id,
			url.QueryEscape(oauth_cb_url))

		header := w.Header()
		header.Add("location", oauth_url)
		w.WriteHeader(307)
	}
}

// Our TokenResponse representation used to pick it out from the JSON
// returned by the OAuth server.
type TokenResponse struct {
	Token string `json:"access_token"`
}

// Use the OAuth code that the user's browser picked up from the OAuth
// server to request an OAuth access_token to use in API requests.
func retrieveTokenFromCode(code string) (token string, err error) {
	// assemble the API endpoint URL and request payload
	tokenUrl := fmt.Sprintf("%s/token", fidor_oauth_url)
	tokenPayload := url.Values{
		"client_id":     {client_id},
		"client_secret": {client_secret},
		"code":          {code},
		"redirect_uri":  {url.QueryEscape(oauth_cb_url)},
	}
	// Call API
	if resp, err := http.PostForm(tokenUrl, tokenPayload); err != nil {
		return "", err
	} else {
		// if successful, pick the access_token out of the reply.
		var tokenResponse TokenResponse
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&tokenResponse); err != nil {
			return "", err
		} else {
			return tokenResponse.Token, nil
		}
	}
}

// Our server code only makes a single call to the API to retrieve user
// information. This is our internal representation of the returned JSON
// used to pick out the user's email.
type UserResponse struct {
	Email string `json:"email"`
}

// function to retrieve user information from the API
func getUser(token string) (u UserResponse, err error) {
	// Assemble endpoint URL...
	url := fmt.Sprintf("%s/users/current?access_token=%s", fidor_api_url, token)
	if resp, err := http.Get(url); err != nil {
		return u, err
	} else {
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&u); err != nil {
			return u, err
		} else {
			return u, nil
		}
	}
}

// once all the OAuth calls have been taken care of, this function is
// called from the http handler. It retrieves the user's email address
// and inserts links to `transaction` and `accounts` endpoints.

func renderWelcome(w http.ResponseWriter, token string) {
	if user, err := getUser(token); err != nil {
		fmt.Printf("err: %v\n", err)
		w.WriteHeader(500)
	} else {
		txLink := fmt.Sprintf("%s/transactions?access_token=%s", fidor_api_url, token)
		acctsLink := fmt.Sprintf("%s/accounts?access_token=%s", fidor_api_url, token)
		fmt.Fprintf(w, indexTemplate, user.Email, token, txLink, acctsLink)
	}
}

var indexTemplate = `

Welcome %s!

	retrieved <tt>access_token</tt>: %s

Transactions

Accounts

`
<commit_msg>added missing oauth params to go example<commit_after>package main

// This is a basic example to illustrate how to access the Fidor API
// using Go.
//
// To run this example type:
//
//     $ go run example.go
//
// And point your browser to:
//
//     $ http://localhost:8080

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"errors"
)

// The following sections define the settings you require for the
// app to be able to connect to and authorize itself against the api.

// app ID and secret, can be found in this apps "Details" page in the
// AppManager.
var client_id     = "<CLIENT_ID>"
var client_secret = "<CLIENT_SECRET>"

// Fidor's OAuth Endpoint (this changes between Sandbox and Production)
var fidor_oauth_url = "<FIDOR_OAUTH_URL>" // e.g https://fidor.com/api_sandbox/oauth
// The OAuth Endpoint this App provides
var oauth_cb_url    = "<APP_URL>"

// The URL of the Fidor API (this changes between Sandbox and
// Production)
var fidor_api_url   = "<FIDOR_API_URL>" // e.g https://fidor.com/api_sandbox vs /api

func main() {
	// register a handler function (see next function) to service
	// requests ...
	http.HandleFunc("/", indexHandler)
	fmt.Printf("Now open http://localhost:8080")
	// ... and start listening.
	http.ListenAndServe(":8080", nil)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {

	// ignore any favicon requests, etc.
	if r.URL.Path != "/" {
		w.WriteHeader(404)
		return
	}

	// check whether we have a GET parameter named `code`, if so,
	// this is a redirect back from the Fidor OAuth server.
	values := r.URL.Query()
	if values["code"] != nil {
		// retrieve the actual OAuth access token ....
		code := values.Get("code")
		if token, err := retrieveTokenFromCode(code); err != nil {
			fmt.Printf("err: %v\n", err)
			w.WriteHeader(500)
			fmt.Fprintf(w, "Unfortunately, an error occurred retrieving oauth token")
		} else {
			// ... and finally, greet the user and assemble links
			renderWelcome(w, token)
		}
	} else {
		// we don't have an oauth `code` yet, so we need to
		// redirect the user to the OAuth provider to get one ...
		oauth_url := fmt.Sprintf("%s/authorize?client_id=%s&state=123&response_type=code&redirect_uri=%s",
			fidor_oauth_url,
			client_id,
			url.QueryEscape(oauth_cb_url))

		header := w.Header()
		header.Add("location", oauth_url)
		w.WriteHeader(307)
	}
}

// Our TokenResponse representation used to pick it out from the JSON
// returned by the OAuth server.
type TokenResponse struct {
	Token string `json:"access_token"`
}

// Use the OAuth code that the user's browser picked up from the OAuth
// server to request an OAuth access_token to use in API requests.
func retrieveTokenFromCode(code string) (token string, err error) {
	// assemble the API endpoint URL and request payload
	tokenUrl := fmt.Sprintf("%s/token", fidor_oauth_url)
	tokenPayload := url.Values{
		"client_id":     {client_id},
		"client_secret": {client_secret},
		"code":          {code},
		"redirect_uri":  {url.QueryEscape(oauth_cb_url)},
		"grant_type":    {"autorization_code"}
	}
	// Call API
	if resp, err := http.PostForm(tokenUrl, tokenPayload); err != nil {
		println(err)
		return "", err
	} else {
		if resp.StatusCode != 200 {
			return "", errors.New(resp.Status)
		}
		// if successful, pick the access_token out of the reply.
		var tokenResponse TokenResponse
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&tokenResponse); err != nil {
			return "", err
		} else {
			return tokenResponse.Token, nil
		}
	}
}

// Our server code only makes a single call to the API to retrieve user
// information. This is our internal representation of the returned JSON
// used to pick out the user's email.
type UserResponse struct {
	Email string `json:"email"`
}

// function to retrieve user information from the API
func getUser(token string) (u UserResponse, err error) {
	// Assemble endpoint URL...
	url := fmt.Sprintf("%s/users/current?access_token=%s", fidor_api_url, token)
	if resp, err := http.Get(url); err != nil {
		return u, err
	} else {
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&u); err != nil {
			return u, err
		} else {
			return u, nil
		}
	}
}

// once all the OAuth calls have been taken care of, this function is
// called from the http handler. It retrieves the user's email address
// and inserts links to `transaction` and `accounts` endpoints.

func renderWelcome(w http.ResponseWriter, token string) {
	if user, err := getUser(token); err != nil {
		fmt.Printf("err: %v\n", err)
		w.WriteHeader(500)
	} else {
		txLink := fmt.Sprintf("%s/transactions?access_token=%s", fidor_api_url, token)
		acctsLink := fmt.Sprintf("%s/accounts?access_token=%s", fidor_api_url, token)
		fmt.Fprintf(w, indexTemplate, user.Email, token, txLink, acctsLink)
	}
}

var indexTemplate = `

Welcome %s!

	retrieved <tt>access_token</tt>: %s

Transactions

Accounts

`
<|endoftext|>


<commit_before>package libstns

import (
	"os"

	"github.com/shirou/gopsutil/host"
)

func AfterOsBoot() int {
	host, err := host.Info()

	if err != nil {
		return NSS_STATUS_UNAVAIL
	}

	if host.PlatformFamily == "debian" && (os.Args[0] == "/sbin/init" || os.Args[0] == "dbus-daemon") {
		return NSS_STATUS_NOTFOUND
	}

	return NSS_STATUS_SUCCESS
}
<commit_msg>fix pid<commit_after>package libstns

import (
	"os"

	"github.com/shirou/gopsutil/host"
)

func AfterOsBoot() int {
	if _, err := os.FindProcess(1); err != nil {
		return NSS_STATUS_UNAVAIL
	}

	if os.Args[0] == "/sbin/init" || os.Args[0] == "dbus-daemon" {
		host, err := host.Info()

		if err != nil {
			return NSS_STATUS_UNAVAIL
		}

		if host.PlatformFamily == "debian" {
			return NSS_STATUS_NOTFOUND
		}
	}
	return NSS_STATUS_SUCCESS
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/adam000/Go-SDL2/image"
	"github.com/adam000/Go-SDL2/sdl"
)

var fullscreen = flag.Bool("fullscreen", false, "fullscreen window")

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
		sdl.Quit()
		os.Exit(2)
	}
	var err error
	go sdl.Do(func() { err = run() })
	sdl.Main()

	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run() error {
	defer sdl.Quit()
	sdl.Init(sdl.InitVideo)

	surfaces, err := loadImages(flag.Args())
	defer func() {
		for _, s := range surfaces {
			s.Free()
		}
	}()
	if err != nil {
		return err
	}

	_, renderer, err := openWindow(flag.Arg(0), maxSize(surfaces))
	if err != nil {
		return err
	}

	textures, err := convertToTextures(renderer, surfaces)
	defer func() {
		for _, t := range textures {
			t.Destroy()
		}
	}()
	if err != nil {
		return err
	}

	mainLoop(renderer, textures)
	return nil
}

func mainLoop(renderer sdl.Renderer, textures []sdl.Texture) {
	currTex := 0
	for {
		// Poll for events
		for {
			ev := sdl.PollEvent()
			if ev == nil {
				break
			}
			switch ev.Type() {
			case sdl.QuitEventType:
				fmt.Println("QUIT")
				return
			case sdl.KeyDownEventType:
				fmt.Println("KEY")
				// TODO(light): advance texture
			}
		}

		// Display image
		renderer.Clear()
		renderer.CopyTexture(textures[currTex], nil, nil)
		renderer.Present()

		// Wait a bit
		time.Sleep(100 * time.Millisecond)
	}
}

func openWindow(title string, size sdl.Point) (sdl.Window, sdl.Renderer, error) {
	var windowFlags sdl.WindowFlag
	if *fullscreen {
		windowFlags |= sdl.WindowFullscreen
	}
	window, err := sdl.NewWindow(title, 0, 0, size.X, size.Y, windowFlags)
	if err != nil {
		return window, sdl.Renderer{}, err
	}
	renderer, err := sdl.NewRenderer(window, -1, 0)
	return window, renderer, err
}

func loadImages(names []string) ([]sdl.Surface, error) {
	surfaces := make([]sdl.Surface, 0, len(names))
	for _, name := range names {
		s, err := image.Load(name)
		if err != nil {
			return surfaces, &os.PathError{Op: "open", Path: name, Err: err}
		}
		surfaces = append(surfaces, s)
	}
	return surfaces, nil
}

func convertToTextures(renderer sdl.Renderer, surfaces []sdl.Surface) ([]sdl.Texture, error) {
	textures := make([]sdl.Texture, 0, len(surfaces))
	for _, s := range surfaces {
		t, err := s.ToTexture(renderer)
		if err != nil {
			return textures, err
		}
		textures = append(textures, t)
	}
	return textures, nil
}

func maxSize(s []sdl.Surface) sdl.Point {
	var size sdl.Point
	for _, ss := range s {
		z := ss.Size()
		if z.X > size.X {
			size.X = z.X
		}
		if z.Y > size.Y {
			size.Y = z.Y
		}
	}
	return size
}
<commit_msg>Fix double run in showimage demo<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/adam000/Go-SDL2/image"
	"github.com/adam000/Go-SDL2/sdl"
)

var fullscreen = flag.Bool("fullscreen", false, "fullscreen window")

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
		sdl.Quit()
		os.Exit(2)
	}
	var err error
	go sdl.Do(func() { err = run() })
	sdl.Main()

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

func run() error {
	defer sdl.Quit()
	sdl.Init(sdl.InitVideo)

	surfaces, err := loadImages(flag.Args())
	defer func() {
		for _, s := range surfaces {
			s.Free()
		}
	}()
	if err != nil {
		return err
	}

	_, renderer, err := openWindow(flag.Arg(0), maxSize(surfaces))
	if err != nil {
		return err
	}

	textures, err := convertToTextures(renderer, surfaces)
	defer func() {
		for _, t := range textures {
			t.Destroy()
		}
	}()
	if err != nil {
		return err
	}

	mainLoop(renderer, textures)
	return nil
}

func mainLoop(renderer sdl.Renderer, textures []sdl.Texture) {
	currTex := 0
	for {
		// Poll for events
		for {
			ev := sdl.PollEvent()
			if ev == nil {
				break
			}
			switch ev.Type() {
			case sdl.QuitEventType:
				fmt.Println("QUIT")
				return
			case sdl.KeyDownEventType:
				fmt.Println("KEY")
				// TODO(light): advance texture
			}
		}

		// Display image
		renderer.Clear()
		renderer.CopyTexture(textures[currTex], nil, nil)
		renderer.Present()

		// Wait a bit
		time.Sleep(100 * time.Millisecond)
	}
}

func openWindow(title string, size sdl.Point) (sdl.Window, sdl.Renderer, error) {
	var windowFlags sdl.WindowFlag
	if *fullscreen {
		windowFlags |= sdl.WindowFullscreen
	}
	window, err := sdl.NewWindow(title, 0, 0, size.X, size.Y, windowFlags)
	if err != nil {
		return window, sdl.Renderer{}, err
	}
	renderer, err := sdl.NewRenderer(window, -1, 0)
	return window, renderer, err
}

func loadImages(names []string) ([]sdl.Surface, error) {
	surfaces := make([]sdl.Surface, 0, len(names))
	for _, name := range names {
		s, err := image.Load(name)
		if err != nil {
			return surfaces, &os.PathError{Op: "open", Path: name, Err: err}
		}
		surfaces = append(surfaces, s)
	}
	return surfaces, nil
}

func convertToTextures(renderer sdl.Renderer, surfaces []sdl.Surface) ([]sdl.Texture, error) {
	textures := make([]sdl.Texture, 0, len(surfaces))
	for _, s := range surfaces {
		t, err := s.ToTexture(renderer)
		if err != nil {
			return textures, err
		}
		textures = append(textures, t)
	}
	return textures, nil
}

func maxSize(s []sdl.Surface) sdl.Point {
	var size sdl.Point
	for _, ss := range s {
		z := ss.Size()
		if z.X > size.X {
			size.X = z.X
		}
		if z.Y > size.Y {
			size.Y = z.Y
		}
	}
	return size
}
<|endoftext|>


<commit_before>// Support for MCP-23017 I2C port expander.

// Currently only supports basic GPIO (input and output). It does not support interupt features.

package mcp23017

import (
	"fmt"
	"hwio"
)

const (
	// This is the default address if pins A2, A1 and A0 are grounded. So device address is base + (A2, A1, A0)
	DEFAULT_BASE_ADDRESS = 0x20

	REG_IODIRA  = 0x00
	REG_IODIRB  = 0x01
	REG_IPOLA   = 0x02
	REG_IPOLB   = 0x03
	REG_GPINENA = 0x04
	REG_GPINENB = 0x05
	REG_DEFVALA = 0x06
	REG_DEFVALB = 0x07
	REG_INTCONA = 0x08
	REG_INTCONB = 0x09
	REG_IOCON   = 0x0a
	REG_GPPUA   = 0x0c
	REG_GPPUB   = 0x0d
	REG_INTFA   = 0x0e
	REG_INTFB   = 0x0f
	REG_INTCAPA = 0x10
	REG_INTCAPB = 0x11
	REG_GPIOA   = 0x12
	REG_GPIOB   = 0x13
	REG_OLATA   = 0x14
	REG_OLATB   = 0x15
)

type MCP23017 struct {
	device hwio.I2CDevice
}

// Create a new isntance, and set it to use Bank 0. The address can either be what is wired on
// (A2,A1,A0) of the physical device, in which case this is added to the base address for the device
// (0x20). Otherwise, you can use 0x20-0x27. Anything else will return an error.
func NewMCP23017(module hwio.I2CModule, address int) (*MCP23017, error) {
	if address < 8 {
		address += DEFAULT_BASE_ADDRESS
	}

	if address < 0x20 || address > 0x27 {
		return nil, fmt.Errorf("Device address %d is invalid for an MCP23017. It must be in the range 0x20-0x27", address)
	}

	device := module.GetDevice(address)
	result := &MCP23017{device: device}

	// set config reg, force BANK=0, SEQOP=0. Note that this only works if already in BANK0, which is default on power-up
	device.WriteByte(REG_IOCON, 0)

	return result, nil
}

// Set direction bits for port A. A 1 bit indicates corresponding pin will be an input,
// A 0 bit indicates it will be an output.
func (d *MCP23017) SetDirA(value byte) error {
	return d.device.WriteByte(REG_IODIRA, value)
}

// Set direction bits for port A. A 1 bit indicates corresponding pin will be an input,
// A 0 bit indicates it will be an output.
func (d *MCP23017) SetDirB(value byte) error {
	return d.device.WriteByte(REG_IODIRB, value)
}

// Read from port A
func (d *MCP23017) GetPortA() (byte, error) {
	return d.device.ReadByte(REG_GPIOA)
}

// Read from port B
func (d *MCP23017) GetPortB() (byte, error) {
	return d.device.ReadByte(REG_GPIOB)
}

// Write to port A
func (d *MCP23017) SetPortA(value byte) error {
	return d.device.WriteByte(REG_OLATA, value)
}

// Write to port B
func (d *MCP23017) SetPortB(value byte) error {
	return d.device.WriteByte(REG_OLATA, value)
}

// Set pull-up configuration for port A. If a bit is 1 and the corresponding pin is
// an input, a pull-up resistor of about 100K is enabled. A zero bit indicates no pull-up.
func (d *MCP23017) SetPullupA(value byte) error {
	return d.device.WriteByte(REG_GPPUA, value)
}

// Set pull-up configuration for port B. If a bit is 1 and the corresponding pin is
// an input, a pull-up resistor of about 100K is enabled. A zero bit indicates no pull-up.
func (d *MCP23017) SetPullupB(value byte) error {
	return d.device.WriteByte(REG_GPPUB, value)
}
<commit_msg>fix import path<commit_after>// Support for MCP-23017 I2C port expander.

// Currently only supports basic GPIO (input and output). It does not support interupt features.

package mcp23017

import (
	"fmt"
	"github.com/mrmorphic/hwio"
)

const (
	// This is the default address if pins A2, A1 and A0 are grounded. So device address is base + (A2, A1, A0)
	DEFAULT_BASE_ADDRESS = 0x20

	REG_IODIRA  = 0x00
	REG_IODIRB  = 0x01
	REG_IPOLA   = 0x02
	REG_IPOLB   = 0x03
	REG_GPINENA = 0x04
	REG_GPINENB = 0x05
	REG_DEFVALA = 0x06
	REG_DEFVALB = 0x07
	REG_INTCONA = 0x08
	REG_INTCONB = 0x09
	REG_IOCON   = 0x0a
	REG_GPPUA   = 0x0c
	REG_GPPUB   = 0x0d
	REG_INTFA   = 0x0e
	REG_INTFB   = 0x0f
	REG_INTCAPA = 0x10
	REG_INTCAPB = 0x11
	REG_GPIOA   = 0x12
	REG_GPIOB   = 0x13
	REG_OLATA   = 0x14
	REG_OLATB   = 0x15
)

type MCP23017 struct {
	device hwio.I2CDevice
}

// Create a new isntance, and set it to use Bank 0. The address can either be what is wired on
// (A2,A1,A0) of the physical device, in which case this is added to the base address for the device
// (0x20). Otherwise, you can use 0x20-0x27. Anything else will return an error.
func NewMCP23017(module hwio.I2CModule, address int) (*MCP23017, error) {
	if address < 8 {
		address += DEFAULT_BASE_ADDRESS
	}

	if address < 0x20 || address > 0x27 {
		return nil, fmt.Errorf("Device address %d is invalid for an MCP23017. It must be in the range 0x20-0x27", address)
	}

	device := module.GetDevice(address)
	result := &MCP23017{device: device}

	// set config reg, force BANK=0, SEQOP=0. Note that this only works if already in BANK0, which is default on power-up
	device.WriteByte(REG_IOCON, 0)

	return result, nil
}

// Set direction bits for port A. A 1 bit indicates corresponding pin will be an input,
// A 0 bit indicates it will be an output.
func (d *MCP23017) SetDirA(value byte) error {
	return d.device.WriteByte(REG_IODIRA, value)
}

// Set direction bits for port A. A 1 bit indicates corresponding pin will be an input,
// A 0 bit indicates it will be an output.
func (d *MCP23017) SetDirB(value byte) error {
	return d.device.WriteByte(REG_IODIRB, value)
}

// Read from port A
func (d *MCP23017) GetPortA() (byte, error) {
	return d.device.ReadByte(REG_GPIOA)
}

// Read from port B
func (d *MCP23017) GetPortB() (byte, error) {
	return d.device.ReadByte(REG_GPIOB)
}

// Write to port A
func (d *MCP23017) SetPortA(value byte) error {
	return d.device.WriteByte(REG_OLATA, value)
}

// Write to port B
func (d *MCP23017) SetPortB(value byte) error {
	return d.device.WriteByte(REG_OLATA, value)
}

// Set pull-up configuration for port A. If a bit is 1 and the corresponding pin is
// an input, a pull-up resistor of about 100K is enabled. A zero bit indicates no pull-up.
func (d *MCP23017) SetPullupA(value byte) error {
	return d.device.WriteByte(REG_GPPUA, value)
}

// Set pull-up configuration for port B. If a bit is 1 and the corresponding pin is
// an input, a pull-up resistor of about 100K is enabled. A zero bit indicates no pull-up.
func (d *MCP23017) SetPullupB(value byte) error {
	return d.device.WriteByte(REG_GPPUB, value)
}
<|endoftext|>


<commit_before>package influxql

import (
	"reflect"
	"testing"
	"time"

	"github.com/davecgh/go-spew/spew"
)

import "sort"

type point struct {
	seriesID uint64
	time     int64
	value    interface{}
}

type testIterator struct {
	values []point
}

func (t *testIterator) Next() (seriesID uint64, timestamp int64, value interface{}) {
	if len(t.values) > 0 {
		v := t.values[0]
		t.values = t.values[1:]
		return v.seriesID, v.time, v.value
	}

	return 0, 0, nil
}

func TestMapMeanNoValues(t *testing.T) {
	iter := &testIterator{}
	if got := MapMean(iter); got != nil {
		t.Errorf("output mismatch: exp nil got %v", got)
	}
}

func TestMapMean(t *testing.T) {

	tests := []struct {
		input  []point
		output *meanMapOutput
	}{
		{ // Single point
			input:  []point{point{0, 1, 1.0}},
			output: &meanMapOutput{1, 1},
		},
		{ // Two points
			input: []point{
				point{0, 1, 2.0},
				point{0, 2, 8.0},
			},
			output: &meanMapOutput{2, 5.0},
		},
	}

	for _, test := range tests {
		iter := &testIterator{
			values: test.input,
		}

		got := MapMean(iter)
		if got == nil {
			t.Fatalf("MapMean(%v): output mismatch: exp %v got %v", test.input, test.output, got)
		}

		if got.(*meanMapOutput).Count != test.output.Count || got.(*meanMapOutput).Mean != test.output.Mean {
			t.Errorf("output mismatch: exp %v got %v", test.output, got)
		}
	}
}
func TestInitializeMapFuncPercentile(t *testing.T) {
	// No args
	c := &Call{
		Name: "percentile",
		Args: []Expr{},
	}
	_, err := InitializeMapFunc(c)
	if err == nil {
		t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
	}

	if exp := "expected two arguments for percentile()"; err.Error() != exp {
		t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}

	// No percentile arg
	c = &Call{
		Name: "percentile",
		Args: []Expr{
			&VarRef{Val: "field1"},
		},
	}

	_, err = InitializeMapFunc(c)
	if err == nil {
		t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
	}

	if exp := "expected two arguments for percentile()"; err.Error() != exp {
		t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}
}

func TestInitializeMapFuncDerivative(t *testing.T) {

	for _, fn := range []string{"derivative", "non_negative_derivative"} {
		// No args should fail
		c := &Call{
			Name: fn,
			Args: []Expr{},
		}

		_, err := InitializeMapFunc(c)
		if err == nil {
			t.Errorf("InitializeMapFunc(%v) expected error.  got nil", c)
		}

		// Single field arg should return MapEcho
		c = &Call{
			Name: fn,
			Args: []Expr{
				&VarRef{Val: " field1"},
				&DurationLiteral{Val: time.Hour},
			},
		}

		_, err = InitializeMapFunc(c)
		if err != nil {
			t.Errorf("InitializeMapFunc(%v) unexpected error.  got %v", c, err)
		}

		// Nested Aggregate func should return the map func for the nested aggregate
		c = &Call{
			Name: fn,
			Args: []Expr{
				&Call{Name: "mean", Args: []Expr{&VarRef{Val: "field1"}}},
				&DurationLiteral{Val: time.Hour},
			},
		}

		_, err = InitializeMapFunc(c)
		if err != nil {
			t.Errorf("InitializeMapFunc(%v) unexpected error.  got %v", c, err)
		}
	}
}

func TestInitializeReduceFuncPercentile(t *testing.T) {
	// No args
	c := &Call{
		Name: "percentile",
		Args: []Expr{},
	}
	_, err := InitializeReduceFunc(c)
	if err == nil {
		t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c)
	}

	if exp := "expected float argument in percentile()"; err.Error() != exp {
		t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}

	// No percentile arg
	c = &Call{
		Name: "percentile",
		Args: []Expr{
			&VarRef{Val: "field1"},
		},
	}

	_, err = InitializeReduceFunc(c)
	if err == nil {
		t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c)
	}

	if exp := "expected float argument in percentile()"; err.Error() != exp {
		t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}
}

func TestReducePercentileNil(t *testing.T) {

	// ReducePercentile should ignore nil values when calculating the percentile
	fn := ReducePercentile(100)
	input := []interface{}{
		nil,
	}

	got := fn(input)
	if got != nil {
		t.Fatalf("ReducePercentile(100) returned wrong type. exp nil got %v", got)
	}
}

func TestMapDistinct(t *testing.T) {
	const ( // prove that we're ignoring seriesID
		seriesId1 = iota + 1
		seriesId2
	)

	const ( // prove that we're ignoring time
		timeId1 = iota + 1
		timeId2
		timeId3
		timeId4
		timeId5
		timeId6
	)

	iter := &testIterator{
		values: []point{
			{seriesId1, timeId1, uint64(1)},
			{seriesId1, timeId2, uint64(1)},
			{seriesId1, timeId3, "1"},
			{seriesId2, timeId4, uint64(1)},
			{seriesId2, timeId5, float64(1.0)},
			{seriesId2, timeId6, "1"},
		},
	}

	values := MapDistinct(iter).(distinctValues)

	if exp, got := 3, len(values); exp != got {
		t.Errorf("Wrong number of values. exp %v got %v", exp, got)
	}

	sort.Sort(values)

	exp := distinctValues{
		uint64(1),
		float64(1),
		"1",
	}

	if !reflect.DeepEqual(values, exp) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(values))
	}
}

func TestMapDistinctNil(t *testing.T) {
	iter := &testIterator{
		values: []point{},
	}

	values := MapDistinct(iter)

	if values != nil {
		t.Errorf("Wrong values. exp nil got %v", spew.Sdump(values))
	}
}

func TestReduceDistinct(t *testing.T) {
	v1 := distinctValues{
		"2",
		"1",
		float64(2.0),
		float64(1),
		uint64(2),
		uint64(1),
		true,
		false,
	}

	expect := distinctValues{
		uint64(1),
		float64(1),
		uint64(2),
		float64(2),
		false,
		true,
		"1",
		"2",
	}

	got := ReduceDistinct([]interface{}{v1, v1, expect})

	if !reflect.DeepEqual(got, expect) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(got))
	}
}

func TestReduceDistinctNil(t *testing.T) {
	tests := []struct {
		name   string
		values []interface{}
	}{
		{
			name:   "nil values",
			values: nil,
		},
		{
			name:   "nil mapper",
			values: []interface{}{nil},
		},
		{
			name:   "no mappers",
			values: []interface{}{},
		},
		{
			name:   "empty mappper (len 1)",
			values: []interface{}{distinctValues{}},
		},
		{
			name:   "empty mappper (len 2)",
			values: []interface{}{distinctValues{}, distinctValues{}},
		},
	}

	for _, test := range tests {
		t.Log(test.name)
		got := ReduceDistinct(test.values)
		if got != nil {
			t.Errorf("Wrong values. exp nil got %v", spew.Sdump(got))
		}
	}
}

func Test_distinctValues_Sort(t *testing.T) {
	values := distinctValues{
		"2",
		"1",
		float64(2.0),
		float64(1),
		uint64(2),
		uint64(1),
		true,
		false,
	}

	expect := distinctValues{
		uint64(1),
		float64(1),
		uint64(2),
		float64(2),
		false,
		true,
		"1",
		"2",
	}

	sort.Sort(values)

	if !reflect.DeepEqual(values, expect) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(values))
	}
}

var getSortedRangeData = []float64{
	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
}

var getSortedRangeTests = []struct {
	name     string
	data     []float64
	start    int
	count    int
	expected []float64
}{
	{"first 5", getSortedRangeData, 0, 5, []float64{0, 1, 2, 3, 4}},
	{"0 length", getSortedRangeData, 8, 0, []float64{}},
	{"past end of data", getSortedRangeData, len(getSortedRangeData) - 3, 5, []float64{67, 68, 69}},
}

func TestGetSortedRange(t *testing.T) {
	for _, tt := range getSortedRangeTests {
		results := getSortedRange(tt.data, tt.start, tt.count)
		if len(results) != len(tt.expected) {
			t.Errorf("Test %s failed.  Expected getSortedRange to return %v but got %v", tt.name, tt.expected, results)
		}
		for i, point := range tt.expected {
			if point != results[i] {
				t.Errorf("Test %s failed. getSortedRange returned wrong result for index %v.  Expected %v but got %v", tt.name, i, point, results[i])
			}
		}
	}
}

var benchGetSortedRangeResults []float64

func BenchmarkGetSortedRangeByPivot(b *testing.B) {
	data := make([]float64, len(getSortedRangeData))
	var results []float64
	for i := 0; i < b.N; i++ {
		copy(data, getSortedRangeData)
		results = getSortedRange(data, 8, 15)
	}
	benchGetSortedRangeResults = results
}

func BenchmarkGetSortedRangeBySort(b *testing.B) {
	data := make([]float64, len(getSortedRangeData))
	var results []float64
	for i := 0; i < b.N; i++ {
		copy(data, getSortedRangeData)
		sort.Float64s(data)
		results = data[8:23]
	}
	benchGetSortedRangeResults = results
}
<commit_msg>add MapCountDistinct/ReduceCountDistinct function tests<commit_after>package influxql

import (
	"reflect"
	"testing"
	"time"

	"github.com/davecgh/go-spew/spew"
)

import "sort"

type point struct {
	seriesID uint64
	time     int64
	value    interface{}
}

type testIterator struct {
	values []point
}

func (t *testIterator) Next() (seriesID uint64, timestamp int64, value interface{}) {
	if len(t.values) > 0 {
		v := t.values[0]
		t.values = t.values[1:]
		return v.seriesID, v.time, v.value
	}

	return 0, 0, nil
}

func TestMapMeanNoValues(t *testing.T) {
	iter := &testIterator{}
	if got := MapMean(iter); got != nil {
		t.Errorf("output mismatch: exp nil got %v", got)
	}
}

func TestMapMean(t *testing.T) {

	tests := []struct {
		input  []point
		output *meanMapOutput
	}{
		{ // Single point
			input:  []point{point{0, 1, 1.0}},
			output: &meanMapOutput{1, 1},
		},
		{ // Two points
			input: []point{
				point{0, 1, 2.0},
				point{0, 2, 8.0},
			},
			output: &meanMapOutput{2, 5.0},
		},
	}

	for _, test := range tests {
		iter := &testIterator{
			values: test.input,
		}

		got := MapMean(iter)
		if got == nil {
			t.Fatalf("MapMean(%v): output mismatch: exp %v got %v", test.input, test.output, got)
		}

		if got.(*meanMapOutput).Count != test.output.Count || got.(*meanMapOutput).Mean != test.output.Mean {
			t.Errorf("output mismatch: exp %v got %v", test.output, got)
		}
	}
}
func TestInitializeMapFuncPercentile(t *testing.T) {
	// No args
	c := &Call{
		Name: "percentile",
		Args: []Expr{},
	}
	_, err := InitializeMapFunc(c)
	if err == nil {
		t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
	}

	if exp := "expected two arguments for percentile()"; err.Error() != exp {
		t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}

	// No percentile arg
	c = &Call{
		Name: "percentile",
		Args: []Expr{
			&VarRef{Val: "field1"},
		},
	}

	_, err = InitializeMapFunc(c)
	if err == nil {
		t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
	}

	if exp := "expected two arguments for percentile()"; err.Error() != exp {
		t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}
}

func TestInitializeMapFuncDerivative(t *testing.T) {

	for _, fn := range []string{"derivative", "non_negative_derivative"} {
		// No args should fail
		c := &Call{
			Name: fn,
			Args: []Expr{},
		}

		_, err := InitializeMapFunc(c)
		if err == nil {
			t.Errorf("InitializeMapFunc(%v) expected error.  got nil", c)
		}

		// Single field arg should return MapEcho
		c = &Call{
			Name: fn,
			Args: []Expr{
				&VarRef{Val: " field1"},
				&DurationLiteral{Val: time.Hour},
			},
		}

		_, err = InitializeMapFunc(c)
		if err != nil {
			t.Errorf("InitializeMapFunc(%v) unexpected error.  got %v", c, err)
		}

		// Nested Aggregate func should return the map func for the nested aggregate
		c = &Call{
			Name: fn,
			Args: []Expr{
				&Call{Name: "mean", Args: []Expr{&VarRef{Val: "field1"}}},
				&DurationLiteral{Val: time.Hour},
			},
		}

		_, err = InitializeMapFunc(c)
		if err != nil {
			t.Errorf("InitializeMapFunc(%v) unexpected error.  got %v", c, err)
		}
	}
}

func TestInitializeReduceFuncPercentile(t *testing.T) {
	// No args
	c := &Call{
		Name: "percentile",
		Args: []Expr{},
	}
	_, err := InitializeReduceFunc(c)
	if err == nil {
		t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c)
	}

	if exp := "expected float argument in percentile()"; err.Error() != exp {
		t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}

	// No percentile arg
	c = &Call{
		Name: "percentile",
		Args: []Expr{
			&VarRef{Val: "field1"},
		},
	}

	_, err = InitializeReduceFunc(c)
	if err == nil {
		t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c)
	}

	if exp := "expected float argument in percentile()"; err.Error() != exp {
		t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
	}
}

func TestReducePercentileNil(t *testing.T) {

	// ReducePercentile should ignore nil values when calculating the percentile
	fn := ReducePercentile(100)
	input := []interface{}{
		nil,
	}

	got := fn(input)
	if got != nil {
		t.Fatalf("ReducePercentile(100) returned wrong type. exp nil got %v", got)
	}
}

func TestMapDistinct(t *testing.T) {
	const ( // prove that we're ignoring seriesID
		seriesId1 = iota + 1
		seriesId2
	)

	const ( // prove that we're ignoring time
		timeId1 = iota + 1
		timeId2
		timeId3
		timeId4
		timeId5
		timeId6
	)

	iter := &testIterator{
		values: []point{
			{seriesId1, timeId1, uint64(1)},
			{seriesId1, timeId2, uint64(1)},
			{seriesId1, timeId3, "1"},
			{seriesId2, timeId4, uint64(1)},
			{seriesId2, timeId5, float64(1.0)},
			{seriesId2, timeId6, "1"},
		},
	}

	values := MapDistinct(iter).(distinctValues)

	if exp, got := 3, len(values); exp != got {
		t.Errorf("Wrong number of values. exp %v got %v", exp, got)
	}

	sort.Sort(values)

	exp := distinctValues{
		uint64(1),
		float64(1),
		"1",
	}

	if !reflect.DeepEqual(values, exp) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(values))
	}
}

func TestMapDistinctNil(t *testing.T) {
	iter := &testIterator{
		values: []point{},
	}

	values := MapDistinct(iter)

	if values != nil {
		t.Errorf("Wrong values. exp nil got %v", spew.Sdump(values))
	}
}

func TestReduceDistinct(t *testing.T) {
	v1 := distinctValues{
		"2",
		"1",
		float64(2.0),
		float64(1),
		uint64(2),
		uint64(1),
		true,
		false,
	}

	expect := distinctValues{
		uint64(1),
		float64(1),
		uint64(2),
		float64(2),
		false,
		true,
		"1",
		"2",
	}

	got := ReduceDistinct([]interface{}{v1, v1, expect})

	if !reflect.DeepEqual(got, expect) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(got))
	}
}

func TestReduceDistinctNil(t *testing.T) {
	tests := []struct {
		name   string
		values []interface{}
	}{
		{
			name:   "nil values",
			values: nil,
		},
		{
			name:   "nil mapper",
			values: []interface{}{nil},
		},
		{
			name:   "no mappers",
			values: []interface{}{},
		},
		{
			name:   "empty mappper (len 1)",
			values: []interface{}{distinctValues{}},
		},
		{
			name:   "empty mappper (len 2)",
			values: []interface{}{distinctValues{}, distinctValues{}},
		},
	}

	for _, test := range tests {
		t.Log(test.name)
		got := ReduceDistinct(test.values)
		if got != nil {
			t.Errorf("Wrong values. exp nil got %v", spew.Sdump(got))
		}
	}
}

func Test_distinctValues_Sort(t *testing.T) {
	values := distinctValues{
		"2",
		"1",
		float64(2.0),
		float64(1),
		uint64(2),
		uint64(1),
		true,
		false,
	}

	expect := distinctValues{
		uint64(1),
		float64(1),
		uint64(2),
		float64(2),
		false,
		true,
		"1",
		"2",
	}

	sort.Sort(values)

	if !reflect.DeepEqual(values, expect) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(values))
	}
}

func TestMapCountDistinct(t *testing.T) {
	const ( // prove that we're ignoring seriesID
		seriesId1 = iota + 1
		seriesId2
	)

	const ( // prove that we're ignoring time
		timeId1 = iota + 1
		timeId2
		timeId3
		timeId4
		timeId5
		timeId6
		timeId7
	)

	iter := &testIterator{
		values: []point{
			{seriesId1, timeId1, uint64(1)},
			{seriesId1, timeId2, uint64(1)},
			{seriesId1, timeId3, "1"},
			{seriesId2, timeId4, uint64(1)},
			{seriesId2, timeId5, float64(1.0)},
			{seriesId2, timeId6, "1"},
			{seriesId2, timeId7, true},
		},
	}

	values := MapCountDistinct(iter).(map[interface{}]struct{})

	if exp, got := 4, len(values); exp != got {
		t.Errorf("Wrong number of values. exp %v got %v", exp, got)
	}

	exp := map[interface{}]struct{}{
		uint64(1):  struct{}{},
		float64(1): struct{}{},
		"1":        struct{}{},
		true:       struct{}{},
	}

	if !reflect.DeepEqual(values, exp) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(values))
	}
}

func TestMapCountDistinctNil(t *testing.T) {
	iter := &testIterator{
		values: []point{},
	}

	values := MapCountDistinct(iter)

	if values != nil {
		t.Errorf("Wrong values. exp nil got %v", spew.Sdump(values))
	}
}

func TestReduceCountDistinct(t *testing.T) {
	v1 := map[interface{}]struct{}{
		"2":          struct{}{},
		"1":          struct{}{},
		float64(2.0): struct{}{},
		float64(1):   struct{}{},
		uint64(2):    struct{}{},
		uint64(1):    struct{}{},
		true:         struct{}{},
		false:        struct{}{},
	}

	v2 := map[interface{}]struct{}{
		uint64(1):  struct{}{},
		float64(1): struct{}{},
		uint64(2):  struct{}{},
		float64(2): struct{}{},
		false:      struct{}{},
		true:       struct{}{},
		"1":        struct{}{},
		"2":        struct{}{},
	}

	exp := 8
	got := ReduceCountDistinct([]interface{}{v1, v1, v2})

	if !reflect.DeepEqual(got, exp) {
		t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(got))
	}
}

func TestReduceCountDistinctNil(t *testing.T) {
	emptyResults := make(map[interface{}]struct{})
	tests := []struct {
		name   string
		values []interface{}
	}{
		{
			name:   "nil values",
			values: nil,
		},
		{
			name:   "nil mapper",
			values: []interface{}{nil},
		},
		{
			name:   "no mappers",
			values: []interface{}{},
		},
		{
			name:   "empty mappper (len 1)",
			values: []interface{}{emptyResults},
		},
		{
			name:   "empty mappper (len 2)",
			values: []interface{}{emptyResults, emptyResults},
		},
	}

	for _, test := range tests {
		t.Log(test.name)
		got := ReduceCountDistinct(test.values)
		if got != 0 {
			t.Errorf("Wrong values. exp nil got %v", spew.Sdump(got))
		}
	}
}

var getSortedRangeData = []float64{
	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
}

var getSortedRangeTests = []struct {
	name     string
	data     []float64
	start    int
	count    int
	expected []float64
}{
	{"first 5", getSortedRangeData, 0, 5, []float64{0, 1, 2, 3, 4}},
	{"0 length", getSortedRangeData, 8, 0, []float64{}},
	{"past end of data", getSortedRangeData, len(getSortedRangeData) - 3, 5, []float64{67, 68, 69}},
}

func TestGetSortedRange(t *testing.T) {
	for _, tt := range getSortedRangeTests {
		results := getSortedRange(tt.data, tt.start, tt.count)
		if len(results) != len(tt.expected) {
			t.Errorf("Test %s failed.  Expected getSortedRange to return %v but got %v", tt.name, tt.expected, results)
		}
		for i, point := range tt.expected {
			if point != results[i] {
				t.Errorf("Test %s failed. getSortedRange returned wrong result for index %v.  Expected %v but got %v", tt.name, i, point, results[i])
			}
		}
	}
}

var benchGetSortedRangeResults []float64

func BenchmarkGetSortedRangeByPivot(b *testing.B) {
	data := make([]float64, len(getSortedRangeData))
	var results []float64
	for i := 0; i < b.N; i++ {
		copy(data, getSortedRangeData)
		results = getSortedRange(data, 8, 15)
	}
	benchGetSortedRangeResults = results
}

func BenchmarkGetSortedRangeBySort(b *testing.B) {
	data := make([]float64, len(getSortedRangeData))
	var results []float64
	for i := 0; i < b.N; i++ {
		copy(data, getSortedRangeData)
		sort.Float64s(data)
		results = data[8:23]
	}
	benchGetSortedRangeResults = results
}
<|endoftext|>


<commit_before>/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package golang

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sort"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/label"
	"github.com/bazelbuild/bazel-gazelle/language"
	"github.com/bazelbuild/bazel-gazelle/rule"
)

func importReposFromModules(args language.ImportReposArgs) language.ImportReposResult {
	dir := filepath.Dir(args.Path)

	// List all modules except for the main module, including implicit indirect
	// dependencies.
	type module struct {
		Path, Version, Sum string
		Main               bool
		Replace            *struct {
			Path, Version string
		}
	}
	// path@version can be used as a unique identifier for looking up sums
	pathToModule := map[string]*module{}
	data, err := goListModules(dir)
	if err != nil {
		return language.ImportReposResult{Error: err}
	}
	dec := json.NewDecoder(bytes.NewReader(data))
	for dec.More() {
		mod := new(module)
		if err := dec.Decode(mod); err != nil {
			return language.ImportReposResult{Error: err}
		}
		if mod.Main {
			continue
		}
		if mod.Replace != nil {
			if filepath.IsAbs(mod.Replace.Path) || build.IsLocalImport(mod.Replace.Path) {
				log.Printf("go_repository does not support file path replacements for %s -> %s", mod.Path,
					mod.Replace.Path)
				continue
			}
			pathToModule[mod.Replace.Path+"@"+mod.Replace.Version] = mod
		} else {
			pathToModule[mod.Path+"@"+mod.Version] = mod
		}
	}

	// Load sums from go.sum. Ideally, they're all there.
	goSumPath := filepath.Join(filepath.Dir(args.Path), "go.sum")
	data, _ = ioutil.ReadFile(goSumPath)
	lines := bytes.Split(data, []byte("\n"))
	for _, line := range lines {
		line = bytes.TrimSpace(line)
		fields := bytes.Fields(line)
		if len(fields) != 3 {
			continue
		}
		path, version, sum := string(fields[0]), string(fields[1]), string(fields[2])
		if strings.HasSuffix(version, "/go.mod") {
			continue
		}
		if mod, ok := pathToModule[path+"@"+version]; ok {
			mod.Sum = sum
		}
	}

	// If sums are missing, run 'go mod download' to get them.
	// This must be done in a temporary directory because 'go mod download'
	// may modify go.mod and go.sum. It does not support -mod=readonly.
	var missingSumArgs []string
	for pathVer, mod := range pathToModule {
		if mod.Sum == "" {
			missingSumArgs = append(missingSumArgs, pathVer)
		}
	}

	if len(missingSumArgs) > 0 {
		tmpDir, err := ioutil.TempDir("", "")
		if err != nil {
			return language.ImportReposResult{Error: fmt.Errorf("finding module sums: %v", err)}
		}
		defer os.RemoveAll(tmpDir)
		data, err := goModDownload(tmpDir, missingSumArgs)
		if err != nil {
			return language.ImportReposResult{Error: err}
		}
		dec = json.NewDecoder(bytes.NewReader(data))
		for dec.More() {
			var dl module
			if err := dec.Decode(&dl); err != nil {
				return language.ImportReposResult{Error: err}
			}
			if mod, ok := pathToModule[dl.Path+"@"+dl.Version]; ok {
				mod.Sum = dl.Sum
			}
		}
	}

	// Translate to repository rules.
	gen := make([]*rule.Rule, 0, len(pathToModule))
	for pathVer, mod := range pathToModule {
		if mod.Sum == "" {
			log.Printf("could not determine sum for module %s", pathVer)
			continue
		}
		r := rule.NewRule("go_repository", label.ImportPathToBazelRepoName(mod.Path))
		r.SetAttr("importpath", mod.Path)
		r.SetAttr("sum", mod.Sum)
		if mod.Replace == nil {
			r.SetAttr("version", mod.Version)
		} else {
			r.SetAttr("replace", mod.Replace.Path)
			r.SetAttr("version", mod.Replace.Version)
		}
		gen = append(gen, r)
	}
	sort.Slice(gen, func(i, j int) bool {
		return gen[i].Name() < gen[j].Name()
	})
	return language.ImportReposResult{Gen: gen}
}

// goListModules invokes "go list" in a directory containing a go.mod file.
var goListModules = func(dir string) ([]byte, error) {
	return runGoCommandForOutput(dir, "list", "-mod=readonly", "-m", "-json", "all")
}

// goModDownload invokes "go mod download" in a directory containing a
// go.mod file.
var goModDownload = func(dir string, args []string) ([]byte, error) {
	dlArgs := []string{"mod", "download", "-json"}
	dlArgs = append(dlArgs, args...)
	return runGoCommandForOutput(dir, dlArgs...)
}

// findGoTool attempts to locate the go executable. If GOROOT is set, we'll
// prefer the one in there; otherwise, we'll rely on PATH. If the wrapper
// script generated by the gazelle rule is invoked by Bazel, it will set
// GOROOT to the configured SDK. We don't want to rely on the host SDK in
// that situation.
func findGoTool() string {
	path := "go" // rely on PATH by default
	if goroot, ok := os.LookupEnv("GOROOT"); ok {
		path = filepath.Join(goroot, "bin", "go")
	}
	if runtime.GOOS == "windows" {
		path += ".exe"
	}
	return path
}

func runGoCommandForOutput(dir string, args ...string) ([]byte, error) {
	goTool := findGoTool()
	env := os.Environ()
	env = append(env, "GO111MODULE=on")
	if os.Getenv("GOCACHE") == "" && os.Getenv("HOME") == "" {
		gocache, err := ioutil.TempDir("", "")
		if err != nil {
			return nil, err
		}
		env = append(env, "GOCACHE="+gocache)
		defer os.RemoveAll(gocache)
	}
	if os.Getenv("GOPATH") == "" && os.Getenv("HOME") == "" {
		gopath, err := ioutil.TempDir("", "")
		if err != nil {
			return nil, err
		}
		env = append(env, "GOPATH="+gopath)
		defer os.RemoveAll(gopath)
	}
	cmd := exec.Command(goTool, args...)
	stderr := &bytes.Buffer{}
	cmd.Stderr = stderr
	cmd.Dir = dir
	cmd.Env = env
	out, err := cmd.Output()
	if err != nil {
		var errStr string
		var xerr *exec.ExitError
		if errors.As(err, &xerr) {
			errStr = strings.TrimSpace(stderr.String())
		} else {
			errStr = err.Error()
		}
		return nil, fmt.Errorf("running '%s %s': %s", cmd.Path, strings.Join(cmd.Args, " "), errStr)
	}
	return out, nil
}
<commit_msg>gazelle: add -e flag for go list 1.16 (#1019)<commit_after>/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package golang

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sort"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/label"
	"github.com/bazelbuild/bazel-gazelle/language"
	"github.com/bazelbuild/bazel-gazelle/rule"
)

func importReposFromModules(args language.ImportReposArgs) language.ImportReposResult {
	dir := filepath.Dir(args.Path)

	// List all modules except for the main module, including implicit indirect
	// dependencies.
	type module struct {
		Path, Version, Sum string
		Main               bool
		Replace            *struct {
			Path, Version string
		}
	}
	// path@version can be used as a unique identifier for looking up sums
	pathToModule := map[string]*module{}
	data, err := goListModules(dir)
	if err != nil {
		return language.ImportReposResult{Error: err}
	}
	dec := json.NewDecoder(bytes.NewReader(data))
	for dec.More() {
		mod := new(module)
		if err := dec.Decode(mod); err != nil {
			return language.ImportReposResult{Error: err}
		}
		if mod.Main {
			continue
		}
		if mod.Replace != nil {
			if filepath.IsAbs(mod.Replace.Path) || build.IsLocalImport(mod.Replace.Path) {
				log.Printf("go_repository does not support file path replacements for %s -> %s", mod.Path,
					mod.Replace.Path)
				continue
			}
			pathToModule[mod.Replace.Path+"@"+mod.Replace.Version] = mod
		} else {
			pathToModule[mod.Path+"@"+mod.Version] = mod
		}
	}

	// Load sums from go.sum. Ideally, they're all there.
	goSumPath := filepath.Join(filepath.Dir(args.Path), "go.sum")
	data, _ = ioutil.ReadFile(goSumPath)
	lines := bytes.Split(data, []byte("\n"))
	for _, line := range lines {
		line = bytes.TrimSpace(line)
		fields := bytes.Fields(line)
		if len(fields) != 3 {
			continue
		}
		path, version, sum := string(fields[0]), string(fields[1]), string(fields[2])
		if strings.HasSuffix(version, "/go.mod") {
			continue
		}
		if mod, ok := pathToModule[path+"@"+version]; ok {
			mod.Sum = sum
		}
	}

	// If sums are missing, run 'go mod download' to get them.
	// This must be done in a temporary directory because 'go mod download'
	// may modify go.mod and go.sum. It does not support -mod=readonly.
	var missingSumArgs []string
	for pathVer, mod := range pathToModule {
		if mod.Sum == "" {
			missingSumArgs = append(missingSumArgs, pathVer)
		}
	}

	if len(missingSumArgs) > 0 {
		tmpDir, err := ioutil.TempDir("", "")
		if err != nil {
			return language.ImportReposResult{Error: fmt.Errorf("finding module sums: %v", err)}
		}
		defer os.RemoveAll(tmpDir)
		data, err := goModDownload(tmpDir, missingSumArgs)
		if err != nil {
			return language.ImportReposResult{Error: err}
		}
		dec = json.NewDecoder(bytes.NewReader(data))
		for dec.More() {
			var dl module
			if err := dec.Decode(&dl); err != nil {
				return language.ImportReposResult{Error: err}
			}
			if mod, ok := pathToModule[dl.Path+"@"+dl.Version]; ok {
				mod.Sum = dl.Sum
			}
		}
	}

	// Translate to repository rules.
	gen := make([]*rule.Rule, 0, len(pathToModule))
	for pathVer, mod := range pathToModule {
		if mod.Sum == "" {
			log.Printf("could not determine sum for module %s", pathVer)
			continue
		}
		r := rule.NewRule("go_repository", label.ImportPathToBazelRepoName(mod.Path))
		r.SetAttr("importpath", mod.Path)
		r.SetAttr("sum", mod.Sum)
		if mod.Replace == nil {
			r.SetAttr("version", mod.Version)
		} else {
			r.SetAttr("replace", mod.Replace.Path)
			r.SetAttr("version", mod.Replace.Version)
		}
		gen = append(gen, r)
	}
	sort.Slice(gen, func(i, j int) bool {
		return gen[i].Name() < gen[j].Name()
	})
	return language.ImportReposResult{Gen: gen}
}

// goListModules invokes "go list" in a directory containing a go.mod file.
var goListModules = func(dir string) ([]byte, error) {
	return runGoCommandForOutput(dir, "list", "-mod=readonly", "-e", "-m", "-json", "all")
}

// goModDownload invokes "go mod download" in a directory containing a
// go.mod file.
var goModDownload = func(dir string, args []string) ([]byte, error) {
	dlArgs := []string{"mod", "download", "-json"}
	dlArgs = append(dlArgs, args...)
	return runGoCommandForOutput(dir, dlArgs...)
}

// findGoTool attempts to locate the go executable. If GOROOT is set, we'll
// prefer the one in there; otherwise, we'll rely on PATH. If the wrapper
// script generated by the gazelle rule is invoked by Bazel, it will set
// GOROOT to the configured SDK. We don't want to rely on the host SDK in
// that situation.
func findGoTool() string {
	path := "go" // rely on PATH by default
	if goroot, ok := os.LookupEnv("GOROOT"); ok {
		path = filepath.Join(goroot, "bin", "go")
	}
	if runtime.GOOS == "windows" {
		path += ".exe"
	}
	return path
}

func runGoCommandForOutput(dir string, args ...string) ([]byte, error) {
	goTool := findGoTool()
	env := os.Environ()
	env = append(env, "GO111MODULE=on")
	if os.Getenv("GOCACHE") == "" && os.Getenv("HOME") == "" {
		gocache, err := ioutil.TempDir("", "")
		if err != nil {
			return nil, err
		}
		env = append(env, "GOCACHE="+gocache)
		defer os.RemoveAll(gocache)
	}
	if os.Getenv("GOPATH") == "" && os.Getenv("HOME") == "" {
		gopath, err := ioutil.TempDir("", "")
		if err != nil {
			return nil, err
		}
		env = append(env, "GOPATH="+gopath)
		defer os.RemoveAll(gopath)
	}
	cmd := exec.Command(goTool, args...)
	stderr := &bytes.Buffer{}
	cmd.Stderr = stderr
	cmd.Dir = dir
	cmd.Env = env
	out, err := cmd.Output()
	if err != nil {
		var errStr string
		var xerr *exec.ExitError
		if errors.As(err, &xerr) {
			errStr = strings.TrimSpace(stderr.String())
		} else {
			errStr = err.Error()
		}
		return nil, fmt.Errorf("running '%s %s': %s", cmd.Path, strings.Join(cmd.Args, " "), errStr)
	}
	return out, nil
}
<|endoftext|>


<commit_before>package build

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"koding/kite/kd/util"
	"koding/tools/deps"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"text/template"

	"github.com/fatih/file"
)

type Build struct {
	appName    string
	version    string
	output     string
	binaryPath string
	importPath string
	files      string
}

func NewBuild() *Build {
	return &Build{}
}

func (b *Build) Definition() string {
	return "Build deployable install packages"
}

func (b *Build) Exec(args []string) error {
	usage := "Usage: kd build --import <importPath> || --bin <binaryPath> --files <filesPath>"
	if len(args) == 0 {
		return errors.New(usage)
	}

	f := flag.NewFlagSet("build", flag.ContinueOnError)
	f.StringVar(&b.importPath, "import", "", "Go importpath to be packaged")
	f.StringVar(&b.binaryPath, "bin", "", "Binary to be packaged")
	f.StringVar(&b.files, "files", "", "Files to be included with the package")
	f.Parse(args)

	if b.binaryPath != "" {
		b.appName = filepath.Base(b.binaryPath)
	} else if b.importPath != "" {
		b.appName = filepath.Base(b.importPath)
	} else {
		return errors.New("build: --import or --bin should be defined.")
	}

	b.version = "0.0.1"
	b.output = fmt.Sprintf("%s.%s-%s", b.appName, runtime.GOOS, runtime.GOARCH)

	err := b.do()
	if err != nil {
		return err
	}

	return nil
}

func (b *Build) do() error {
	switch runtime.GOOS {
	case "darwin":
		err := b.darwin()
		if err != nil {
			log.Println("darwin:", err)
		}
	case "linux":
		err := b.linux()
		if err != nil {
			log.Println("linux:", err)
		}
	}

	// also create a tar.gz regardless of os
	return b.tarGzFile()
}

func (b *Build) linux() error {
	return nil
}

func (b *Build) tarGzFile() error {
	buildFolder, err := ioutil.TempDir(".", "kd-build")
	if err != nil {
		return err
	}
	defer os.RemoveAll(buildFolder)

	if b.importPath != "" {
		gopath := os.Getenv("GOPATH")
		if gopath == "" {
			return errors.New("GOPATH is not set")
		}

		// or use "go list koding/..." for all packages and commands
		packages := []string{b.importPath}
		d, err := deps.LoadDeps(packages...)
		if err != nil {
			return err
		}

		err = d.InstallDeps()
		if err != nil {
			return err
		}

		buildFolder = filepath.Join(d.BuildGoPath, b.appName)
	} else {
		err := file.Copy(b.binaryPath, buildFolder)
		if err != nil {
			log.Println("copy assets", err)
		}
	}

	// copy package files, such as templates
	if b.files != "" {
		err := file.Copy(b.files, buildFolder)
		if err != nil {
			log.Println("copy assets", err)
		}
	}

	// create tar.gz file from final director
	tarFile := fmt.Sprintf("%s.%s-%s.tar.gz", b.appName, runtime.GOOS, runtime.GOARCH)
	err = util.MakeTar(tarFile, buildFolder)
	if err != nil {
		return err
	}

	fmt.Printf("'%s' is created and ready for deploy\n", tarFile)
	return nil
}

// darwin is building a new .pkg installer for darwin based OS'es.
func (b *Build) darwin() error {
	version := b.version
	if b.output == "" {
		b.output = fmt.Sprintf("koding-%s", b.appName)
	}

	scriptDir := "build/darwin/scripts"
	installRoot := "./root" // TODO REMOVE

	os.RemoveAll(installRoot) // clean up old build before we continue
	installRootUsr := filepath.Join(installRoot, "/usr/local/bin")

	os.MkdirAll(installRootUsr, 0755)
	err := util.CopyFile(b.binaryPath, installRootUsr+"/"+b.appName)
	if err != nil {
		return err
	}

	tempDest, err := ioutil.TempDir("", "tempDest")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempDest)

	b.createScripts(scriptDir)
	b.createLaunchAgent(installRoot)

	cmdPkg := exec.Command("pkgbuild",
		"--identifier", fmt.Sprintf("com.koding.kite.%s.pkg", b.appName),
		"--version", version,
		"--scripts", scriptDir,
		"--root", installRoot,
		"--install-location", "/",
		fmt.Sprintf("%s/com.koding.kite.%s.pkg", tempDest, b.appName),
		// used for next step, also set up for distribution.xml
	)

	_, err = cmdPkg.CombinedOutput()
	if err != nil {
		return err
	}

	distributionFile := "build/darwin/Distribution.xml"
	resources := "build/darwin/Resources"
	targetFile := b.output + ".pkg"

	b.createDistribution(distributionFile)

	cmdBuild := exec.Command("productbuild",
		"--distribution", distributionFile,
		"--resources", resources,
		"--package-path", tempDest,
		targetFile,
	)

	_, err = cmdBuild.CombinedOutput()
	if err != nil {
		return err
	}

	fmt.Printf("'%s' is created and ready for deploy\n", targetFile)
	return nil
}

func (b *Build) createLaunchAgent(rootDir string) {
	launchDir := fmt.Sprintf("%s/Library/LaunchAgents/", rootDir)
	os.MkdirAll(launchDir, 0700)

	launchFile := fmt.Sprintf("%s/com.koding.kite.%s.plist", launchDir, b.appName)

	lFile, err := os.Create(launchFile)
	if err != nil {
		log.Fatalln(err)
	}

	t := template.Must(template.New("launchAgent").Parse(launchAgent))
	t.Execute(lFile, b.appName)

}

func (b *Build) createDistribution(file string) {
	distFile, err := os.Create(file)
	if err != nil {
		log.Fatalln(err)
	}

	t := template.Must(template.New("distribution").Parse(distribution))
	t.Execute(distFile, b.appName)

}

func (b *Build) createScripts(scriptDir string) {
	os.MkdirAll(scriptDir, 0700) // does return nil if exists

	postInstallFile, err := os.Create(scriptDir + "/postInstall")
	if err != nil {
		log.Fatalln(err)
	}
	postInstallFile.Chmod(0755)

	preInstallFile, err := os.Create(scriptDir + "/preInstall")
	if err != nil {
		log.Fatalln(err)
	}
	preInstallFile.Chmod(0755)

	t := template.Must(template.New("postInstall").Parse(postInstall))
	t.Execute(postInstallFile, b.appName)

	t = template.Must(template.New("preInstall").Parse(preInstall))
	t.Execute(preInstallFile, b.appName)
}

func fileExist(dir string) bool {
	var err error
	_, err = os.Stat(dir)
	if err == nil {
		return true // file exist
	}

	if os.IsNotExist(err) {
		return false // file does not exist
	}

	panic(err) // permission errors or something else bad
}
<commit_msg>build: include files seperated with commas<commit_after>package build

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"koding/kite/kd/util"
	"koding/tools/deps"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"text/template"

	"github.com/fatih/file"
)

type Build struct {
	appName    string
	version    string
	output     string
	binaryPath string
	importPath string
	files      string
}

func NewBuild() *Build {
	return &Build{}
}

func (b *Build) Definition() string {
	return "Build deployable install packages"
}

func (b *Build) Exec(args []string) error {
	usage := "Usage: kd build --import <importPath> || --bin <binaryPath> --files <filesPath>"
	if len(args) == 0 {
		return errors.New(usage)
	}

	f := flag.NewFlagSet("build", flag.ContinueOnError)
	f.StringVar(&b.importPath, "import", "", "Go importpath to be packaged")
	f.StringVar(&b.binaryPath, "bin", "", "Binary to be packaged")
	f.StringVar(&b.files, "files", "", "Files to be included with the package")
	f.Parse(args)

	if b.binaryPath != "" {
		b.appName = filepath.Base(b.binaryPath)
	} else if b.importPath != "" {
		b.appName = filepath.Base(b.importPath)
	} else {
		return errors.New("build: --import or --bin should be defined.")
	}

	b.version = "0.0.1"
	b.output = fmt.Sprintf("%s.%s-%s", b.appName, runtime.GOOS, runtime.GOARCH)

	err := b.do()
	if err != nil {
		return err
	}

	return nil
}

func (b *Build) do() error {
	switch runtime.GOOS {
	case "darwin":
		err := b.darwin()
		if err != nil {
			log.Println("darwin:", err)
		}
	case "linux":
		err := b.linux()
		if err != nil {
			log.Println("linux:", err)
		}
	}

	// also create a tar.gz regardless of os
	return b.tarGzFile()
}

func (b *Build) linux() error {
	return nil
}

func (b *Build) tarGzFile() error {
	buildFolder, err := ioutil.TempDir(".", "kd-build")
	if err != nil {
		return err
	}
	defer os.RemoveAll(buildFolder)

	if b.importPath != "" {
		gopath := os.Getenv("GOPATH")
		if gopath == "" {
			return errors.New("GOPATH is not set")
		}

		// or use "go list koding/..." for all packages and commands
		packages := []string{b.importPath}
		d, err := deps.LoadDeps(packages...)
		if err != nil {
			return err
		}

		err = d.InstallDeps()
		if err != nil {
			return err
		}

		buildFolder = filepath.Join(d.BuildGoPath, b.appName)
	} else {
		err := file.Copy(b.binaryPath, buildFolder)
		if err != nil {
			log.Println("copy assets", err)
		}
	}

	// include given files
	if b.files != "" {
		files := strings.Split(b.files, ",")
		for _, path := range files {
			err := file.Copy(path, buildFolder)
			if err != nil {
				log.Println("copy assets", err)
			}
		}
	}

	// create tar.gz file from final director
	tarFile := fmt.Sprintf("%s.%s-%s.tar.gz", b.appName, runtime.GOOS, runtime.GOARCH)
	err = util.MakeTar(tarFile, buildFolder)
	if err != nil {
		return err
	}

	fmt.Printf("'%s' is created and ready for deploy\n", tarFile)
	return nil
}

// darwin is building a new .pkg installer for darwin based OS'es.
func (b *Build) darwin() error {
	version := b.version
	if b.output == "" {
		b.output = fmt.Sprintf("koding-%s", b.appName)
	}

	scriptDir := "build/darwin/scripts"
	installRoot := "./root" // TODO REMOVE

	os.RemoveAll(installRoot) // clean up old build before we continue
	installRootUsr := filepath.Join(installRoot, "/usr/local/bin")

	os.MkdirAll(installRootUsr, 0755)
	err := util.CopyFile(b.binaryPath, installRootUsr+"/"+b.appName)
	if err != nil {
		return err
	}

	tempDest, err := ioutil.TempDir("", "tempDest")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempDest)

	b.createScripts(scriptDir)
	b.createLaunchAgent(installRoot)

	cmdPkg := exec.Command("pkgbuild",
		"--identifier", fmt.Sprintf("com.koding.kite.%s.pkg", b.appName),
		"--version", version,
		"--scripts", scriptDir,
		"--root", installRoot,
		"--install-location", "/",
		fmt.Sprintf("%s/com.koding.kite.%s.pkg", tempDest, b.appName),
		// used for next step, also set up for distribution.xml
	)

	_, err = cmdPkg.CombinedOutput()
	if err != nil {
		return err
	}

	distributionFile := "build/darwin/Distribution.xml"
	resources := "build/darwin/Resources"
	targetFile := b.output + ".pkg"

	b.createDistribution(distributionFile)

	cmdBuild := exec.Command("productbuild",
		"--distribution", distributionFile,
		"--resources", resources,
		"--package-path", tempDest,
		targetFile,
	)

	_, err = cmdBuild.CombinedOutput()
	if err != nil {
		return err
	}

	fmt.Printf("'%s' is created and ready for deploy\n", targetFile)
	return nil
}

func (b *Build) createLaunchAgent(rootDir string) {
	launchDir := fmt.Sprintf("%s/Library/LaunchAgents/", rootDir)
	os.MkdirAll(launchDir, 0700)

	launchFile := fmt.Sprintf("%s/com.koding.kite.%s.plist", launchDir, b.appName)

	lFile, err := os.Create(launchFile)
	if err != nil {
		log.Fatalln(err)
	}

	t := template.Must(template.New("launchAgent").Parse(launchAgent))
	t.Execute(lFile, b.appName)

}

func (b *Build) createDistribution(file string) {
	distFile, err := os.Create(file)
	if err != nil {
		log.Fatalln(err)
	}

	t := template.Must(template.New("distribution").Parse(distribution))
	t.Execute(distFile, b.appName)

}

func (b *Build) createScripts(scriptDir string) {
	os.MkdirAll(scriptDir, 0700) // does return nil if exists

	postInstallFile, err := os.Create(scriptDir + "/postInstall")
	if err != nil {
		log.Fatalln(err)
	}
	postInstallFile.Chmod(0755)

	preInstallFile, err := os.Create(scriptDir + "/preInstall")
	if err != nil {
		log.Fatalln(err)
	}
	preInstallFile.Chmod(0755)

	t := template.Must(template.New("postInstall").Parse(postInstall))
	t.Execute(postInstallFile, b.appName)

	t = template.Must(template.New("preInstall").Parse(preInstall))
	t.Execute(preInstallFile, b.appName)
}

func fileExist(dir string) bool {
	var err error
	_, err = os.Stat(dir)
	if err == nil {
		return true // file exist
	}

	if os.IsNotExist(err) {
		return false // file does not exist
	}

	panic(err) // permission errors or something else bad
}
<|endoftext|>


<commit_before>package buildserver

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

	"github.com/concourse/atc"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/event"
	"github.com/vito/go-sse/sse"
)

const ProtocolVersionHeader = "X-ATC-Stream-Version"
const CurrentProtocolVersion = "2.0"

func NewEventHandler(buildsDB BuildsDB, buildID int, censor bool) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		flusher := w.(http.Flusher)
		closed := w.(http.CloseNotifier).CloseNotify()

		w.Header().Add("Content-Type", "text/event-stream; charset=utf-8")
		w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
		w.Header().Add("Connection", "keep-alive")
		w.Header().Add(ProtocolVersionHeader, CurrentProtocolVersion)

		var start uint = 0
		if r.Header.Get("Last-Event-ID") != "" {
			_, err := fmt.Sscanf(r.Header.Get("Last-Event-ID"), "%d", &start)
			if err != nil {
				w.WriteHeader(http.StatusBadRequest)
				return
			}

			start++
		}

		events, err := buildsDB.GetBuildEvents(buildID, start)
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			return
		}

		defer events.Close()

		es := make(chan atc.Event)
		errs := make(chan error, 1)

		go func() {
			for {
				ev, err := events.Next()
				if err != nil {
					errs <- err
					return
				} else {
					select {
					case es <- ev:
					case <-closed:
						return
					}
				}
			}
		}()

		for {
			select {
			case ev := <-es:
				if censor {
					ev = ev.Censored()
				}

				payload, err := json.Marshal(event.Message{ev})
				if err != nil {
					return
				}

				err = sse.Event{
					ID:   fmt.Sprintf("%d", start),
					Name: "event",
					Data: payload,
				}.Write(w)
				if err != nil {
					return
				}

				start++

				flusher.Flush()
			case err := <-errs:
				if err == db.ErrEndOfBuildEventStream {
					err = sse.Event{Name: "end"}.Write(w)
					if err != nil {
						return
					}
				}

				return
			case <-closed:
				return
			}
		}

		return
	})
}
<commit_msg>gzip encode event stream<commit_after>package buildserver

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"

	"github.com/concourse/atc"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/event"
	"github.com/vito/go-sse/sse"
)

const ProtocolVersionHeader = "X-ATC-Stream-Version"
const CurrentProtocolVersion = "2.0"

func NewEventHandler(buildsDB BuildsDB, buildID int, censor bool) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		flusher := w.(http.Flusher)
		closed := w.(http.CloseNotifier).CloseNotify()

		w.Header().Add("Content-Type", "text/event-stream; charset=utf-8")
		w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
		w.Header().Add("Connection", "keep-alive")
		w.Header().Add(ProtocolVersionHeader, CurrentProtocolVersion)

		var start uint = 0
		if r.Header.Get("Last-Event-ID") != "" {
			_, err := fmt.Sscanf(r.Header.Get("Last-Event-ID"), "%d", &start)
			if err != nil {
				w.WriteHeader(http.StatusBadRequest)
				return
			}

			start++
		}

		var responseWriter io.Writer = w

		w.Header().Add("Vary", "Accept-Encoding")
		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
			w.Header().Set("Content-Encoding", "gzip")

			gz := gzip.NewWriter(w)
			defer gz.Close()

			responseWriter = gz
		}

		events, err := buildsDB.GetBuildEvents(buildID, start)
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			return
		}

		defer events.Close()

		es := make(chan atc.Event)
		errs := make(chan error, 1)

		go func() {
			for {
				ev, err := events.Next()
				if err != nil {
					errs <- err
					return
				} else {
					select {
					case es <- ev:
					case <-closed:
						return
					}
				}
			}
		}()

		for {
			select {
			case ev := <-es:
				if censor {
					ev = ev.Censored()
				}

				payload, err := json.Marshal(event.Message{ev})
				if err != nil {
					return
				}

				err = sse.Event{
					ID:   fmt.Sprintf("%d", start),
					Name: "event",
					Data: payload,
				}.Write(responseWriter)
				if err != nil {
					return
				}

				start++

				flusher.Flush()
			case err := <-errs:
				if err == db.ErrEndOfBuildEventStream {
					err = sse.Event{Name: "end"}.Write(responseWriter)
					if err != nil {
						return
					}
				}

				return
			case <-closed:
				return
			}
		}

		return
	})
}
<|endoftext|>


<commit_before>package integration_test

import (
	"encoding/gob"
	"net/http"
	"os"
	"os/exec"

	"github.com/concourse/atc/api/resources"
	thijack "github.com/concourse/turbine/api/hijack"
	"github.com/kr/pty"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/gomega/ghttp"
)

var _ = FDescribe("Hijacking", func() {
	var atcServer *ghttp.Server
	var hijacked <-chan struct{}

	BeforeEach(func() {
		atcServer = ghttp.NewServer()
		hijacked = nil

		os.Setenv("ATC_URL", atcServer.URL())
	})

	hijackHandler := func(didHijack chan<- struct{}) http.HandlerFunc {
		return ghttp.CombineHandlers(
			ghttp.VerifyRequest("POST", "/api/v1/builds/3/hijack"),
			func(w http.ResponseWriter, r *http.Request) {
				w.WriteHeader(http.StatusOK)

				sconn, sbr, err := w.(http.Hijacker).Hijack()
				Ω(err).ShouldNot(HaveOccurred())

				defer sconn.Close()

				close(didHijack)

				decoder := gob.NewDecoder(sbr)

				var payload thijack.ProcessPayload

				err = decoder.Decode(&payload)
				Ω(err).ShouldNot(HaveOccurred())

				Ω(payload).Should(Equal(thijack.ProcessPayload{
					Stdin: []byte("marco"),
				}))

				_, err = sconn.Write([]byte("polo"))
				Ω(err).ShouldNot(HaveOccurred())
			},
		)
	}

	hijack := func(args ...string) {
		pty, tty, err := pty.Open()
		Ω(err).ShouldNot(HaveOccurred())

		flyCmd := exec.Command(flyPath, append([]string{"hijack"}, args...)...)
		flyCmd.Stdin = tty

		sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(hijacked).Should(BeClosed())

		_, err = pty.WriteString("marco")
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(sess).Should(gbytes.Say("polo"))

		err = pty.Close()
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(sess).Should(gexec.Exit(0))
	}

	Context("with no arguments", func() {
		BeforeEach(func() {
			didHijack := make(chan struct{})
			hijacked = didHijack

			atcServer.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/api/v1/builds"),
					ghttp.RespondWithJSONEncoded(200, []resources.Build{
						{ID: 3, Name: "3", Status: "started"},
						{ID: 2, Name: "2", Status: "started"},
						{ID: 1, Name: "1", Status: "finished"},
					}),
				),
				hijackHandler(didHijack),
			)
		})

		It("hijacks the most recent build", func() {
			hijack()
		})
	})

	Context("with a specific job", func() {
		Context("when the job has a next build", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job"),
						ghttp.RespondWithJSONEncoded(200, resources.Job{
							NextBuild: &resources.Build{
								ID:      3,
								Name:    "3",
								Status:  "started",
								JobName: "some-job",
							},
							FinishedBuild: &resources.Build{
								ID:      2,
								Name:    "2",
								Status:  "failed",
								JobName: "some-job",
							},
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the job's next build", func() {
				hijack("--job", "some-job")
			})
		})

		Context("when the job only has a finished build", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job"),
						ghttp.RespondWithJSONEncoded(200, resources.Job{
							NextBuild: nil,
							FinishedBuild: &resources.Build{
								ID:      3,
								Name:    "3",
								Status:  "failed",
								JobName: "some-job",
							},
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the job's finished build", func() {
				hijack("--job", "some-job")
			})
		})

		Context("with a specific build of the job", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job/builds/3"),
						ghttp.RespondWithJSONEncoded(200, resources.Build{
							ID:      3,
							Name:    "3",
							Status:  "failed",
							JobName: "some-job",
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the given build", func() {
				hijack("--job", "some-job", "--build", "3")
			})
		})
	})
})
<commit_msg>remove accidental focus<commit_after>package integration_test

import (
	"encoding/gob"
	"net/http"
	"os"
	"os/exec"

	"github.com/concourse/atc/api/resources"
	thijack "github.com/concourse/turbine/api/hijack"
	"github.com/kr/pty"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/gomega/ghttp"
)

var _ = Describe("Hijacking", func() {
	var atcServer *ghttp.Server
	var hijacked <-chan struct{}

	BeforeEach(func() {
		atcServer = ghttp.NewServer()
		hijacked = nil

		os.Setenv("ATC_URL", atcServer.URL())
	})

	hijackHandler := func(didHijack chan<- struct{}) http.HandlerFunc {
		return ghttp.CombineHandlers(
			ghttp.VerifyRequest("POST", "/api/v1/builds/3/hijack"),
			func(w http.ResponseWriter, r *http.Request) {
				w.WriteHeader(http.StatusOK)

				sconn, sbr, err := w.(http.Hijacker).Hijack()
				Ω(err).ShouldNot(HaveOccurred())

				defer sconn.Close()

				close(didHijack)

				decoder := gob.NewDecoder(sbr)

				var payload thijack.ProcessPayload

				err = decoder.Decode(&payload)
				Ω(err).ShouldNot(HaveOccurred())

				Ω(payload).Should(Equal(thijack.ProcessPayload{
					Stdin: []byte("marco"),
				}))

				_, err = sconn.Write([]byte("polo"))
				Ω(err).ShouldNot(HaveOccurred())
			},
		)
	}

	hijack := func(args ...string) {
		pty, tty, err := pty.Open()
		Ω(err).ShouldNot(HaveOccurred())

		flyCmd := exec.Command(flyPath, append([]string{"hijack"}, args...)...)
		flyCmd.Stdin = tty

		sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(hijacked).Should(BeClosed())

		_, err = pty.WriteString("marco")
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(sess).Should(gbytes.Say("polo"))

		err = pty.Close()
		Ω(err).ShouldNot(HaveOccurred())

		Eventually(sess).Should(gexec.Exit(0))
	}

	Context("with no arguments", func() {
		BeforeEach(func() {
			didHijack := make(chan struct{})
			hijacked = didHijack

			atcServer.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/api/v1/builds"),
					ghttp.RespondWithJSONEncoded(200, []resources.Build{
						{ID: 3, Name: "3", Status: "started"},
						{ID: 2, Name: "2", Status: "started"},
						{ID: 1, Name: "1", Status: "finished"},
					}),
				),
				hijackHandler(didHijack),
			)
		})

		It("hijacks the most recent build", func() {
			hijack()
		})
	})

	Context("with a specific job", func() {
		Context("when the job has a next build", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job"),
						ghttp.RespondWithJSONEncoded(200, resources.Job{
							NextBuild: &resources.Build{
								ID:      3,
								Name:    "3",
								Status:  "started",
								JobName: "some-job",
							},
							FinishedBuild: &resources.Build{
								ID:      2,
								Name:    "2",
								Status:  "failed",
								JobName: "some-job",
							},
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the job's next build", func() {
				hijack("--job", "some-job")
			})
		})

		Context("when the job only has a finished build", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job"),
						ghttp.RespondWithJSONEncoded(200, resources.Job{
							NextBuild: nil,
							FinishedBuild: &resources.Build{
								ID:      3,
								Name:    "3",
								Status:  "failed",
								JobName: "some-job",
							},
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the job's finished build", func() {
				hijack("--job", "some-job")
			})
		})

		Context("with a specific build of the job", func() {
			BeforeEach(func() {
				didHijack := make(chan struct{})
				hijacked = didHijack

				atcServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/v1/jobs/some-job/builds/3"),
						ghttp.RespondWithJSONEncoded(200, resources.Build{
							ID:      3,
							Name:    "3",
							Status:  "failed",
							JobName: "some-job",
						}),
					),
					hijackHandler(didHijack),
				)
			})

			It("hijacks the given build", func() {
				hijack("--job", "some-job", "--build", "3")
			})
		})
	})
})
<|endoftext|>


<commit_before>package kickbox

import (
	"encoding/json"
)

// KickboxResultBuilder implements our ResultBuilder interface and creates the
// actual Result struct (the response from Kickbox)
type KickboxResultBuilder struct{}

// NewResult creates a new Result object from an JSON API response
func (b KickboxResultBuilder) NewResult(response []byte) (*Result, error) {
	result := Result{}
	if err := json.Unmarshal(response, &result); err != nil {
		return nil, err
	}

	return &result, nil
}

// IsDeliverable returns true if the API returns "result: deliverable"
func (r Result) IsDeliverable() bool {
	return (r.Result == "deliverable")
}

// IsUndeliverable returns true if the API returns "result: undeliverable"
func (r Result) IsUndeliverable() bool {
	return (r.Result == "undeliverable")
}

// IsRisky returns true if the API returns "result: risky"
func (r Result) IsRisky() bool {
	return (r.Result == "risky")
}

// IsUnknown returns true if the API returns "result: unknown"
func (r Result) IsUnknown() bool {
	return (r.Result == "unknown")
}
<commit_msg>Consistent struct creation<commit_after>package kickbox

import (
	"encoding/json"
)

// KickboxResultBuilder implements our ResultBuilder interface and creates the
// actual Result struct (the response from Kickbox)
type KickboxResultBuilder struct{}

// NewResult creates a new Result object from an JSON API response
func (b KickboxResultBuilder) NewResult(response []byte) (*Result, error) {
	result := &Result{}
	if err := json.Unmarshal(response, result); err != nil {
		return nil, err
	}

	return result, nil
}

// IsDeliverable returns true if the API returns "result: deliverable"
func (r Result) IsDeliverable() bool {
	return (r.Result == "deliverable")
}

// IsUndeliverable returns true if the API returns "result: undeliverable"
func (r Result) IsUndeliverable() bool {
	return (r.Result == "undeliverable")
}

// IsRisky returns true if the API returns "result: risky"
func (r Result) IsRisky() bool {
	return (r.Result == "risky")
}

// IsUnknown returns true if the API returns "result: unknown"
func (r Result) IsUnknown() bool {
	return (r.Result == "unknown")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/c-bata/go-prompt-toolkit/prompt"
)

func executor(t string) string {
	r := "Your input: " + t
	return r
}

func completer(t string) []string {
	return []string{
		"users",
		"sites",
		"articles",
		"comments",
	}
}

func main() {
	pt := prompt.NewPrompt(
		executor,
		completer,
		prompt.OptionPrefix(">>> "),
		prompt.OptionTitle("sqlite3-cli"),
		prompt.OptionOutputTextColor(prompt.DarkGray),
	)
	defer fmt.Println("\nGoodbye!")
	pt.Run()
}
<commit_msg>Update example<commit_after>package main

import (
	"fmt"

	"github.com/c-bata/go-prompt-toolkit"
)

func executor(t string) string {
	r := "Your input: " + t
	return r
}

func completer(t string) []string {
	return []string{
		"users",
		"sites",
		"articles",
		"comments",
	}
}

func main() {
	pt := prompt.NewPrompt(
		executor,
		completer,
		prompt.OptionPrefix(">>> "),
		prompt.OptionTitle("sqlite3-cli"),
		prompt.OptionOutputTextColor(prompt.DarkGray),
	)
	defer fmt.Println("\nGoodbye!")
	pt.Run()
}
<|endoftext|>


<commit_before>package logger

import (
	"fmt"
	"os"

	"github.com/bugsnag/bugsnag-go"
	"github.com/juju/loggo"
	"github.com/wolfeidau/loggo-syslog"
)

func init() {

	if os.Getenv("DEBUG") != "" {
		// set the default logger to info
		loggo.GetLogger("").SetLogLevel(loggo.DEBUG)
	} else {
		// set the default logger to info
		loggo.GetLogger("").SetLogLevel(loggo.INFO)
	}
}

// Logger wrapper for the internal logger with some extra helpers
type Logger struct {
	loggo.Logger
}

// GetLogger builds a ninja logger with the given name
func GetLogger(name string) *Logger {
	l := loggo.GetLogger(name)

	// are we in a terminal?
	if !IsTerminal() {

		// we need to use a different writer
		loggo.RemoveWriter("default")

		// setup the syslog writer as the default passing the
		loggo.RegisterWriter("default", lsyslog.NewDefaultSyslogWriter(loggo.TRACE, "ninja"), loggo.TRACE)
	}

	return &Logger{l}
}

// HandleError This notifies bugsnag and logs the error.
func (l *Logger) HandleError(err error, msg string) {
	l.Errorf("%s : %v", msg, err)
	bugsnag.Notify(err)
}

// FatalError This notifies bugsnag and logs the error then quits.
func (l *Logger) FatalError(err error, msg string) {
	l.Errorf("%s : %v", msg, err)
	bugsnag.Notify(err)
	os.Exit(1)
}

// HandleErrorf This notifies bugsnag and logs the error based on the args.
func (l *Logger) HandleErrorf(err error, msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(err)
}

// FatalErrorf This notifies bugsnag and logs the error based on the args then quits
func (l *Logger) FatalErrorf(err error, msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(err)
	os.Exit(1)
}

// FatalErrorf This notifies bugsnag and logs the error based on the args then quits
func (l *Logger) Fatalf(msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(fmt.Errorf(msg, args))
	os.Exit(1)
}
<commit_msg>Kill all output from loggers in underlying libs.<commit_after>package logger

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

	"github.com/bugsnag/bugsnag-go"
	"github.com/juju/loggo"
	"github.com/wolfeidau/loggo-syslog"
)

func init() {

	if os.Getenv("DEBUG") != "" {
		// set the default logger to info
		loggo.GetLogger("").SetLogLevel(loggo.DEBUG)
	} else {
		// set the default logger to info
		loggo.GetLogger("").SetLogLevel(loggo.INFO)
	}
}

// Logger wrapper for the internal logger with some extra helpers
type Logger struct {
	loggo.Logger
}

// GetLogger builds a ninja logger with the given name
func GetLogger(name string) *Logger {
	l := loggo.GetLogger(name)

	// are we in a terminal?
	if !IsTerminal() {

		// kill output from std logger
		log.SetOutput(ioutil.Discard)

		// we need to use a different writer
		loggo.RemoveWriter("default")

		// setup the syslog writer as the default passing the
		loggo.RegisterWriter("default", lsyslog.NewDefaultSyslogWriter(loggo.TRACE, "ninja"), loggo.TRACE)
	}

	return &Logger{l}
}

// HandleError This notifies bugsnag and logs the error.
func (l *Logger) HandleError(err error, msg string) {
	l.Errorf("%s : %v", msg, err)
	bugsnag.Notify(err)
}

// FatalError This notifies bugsnag and logs the error then quits.
func (l *Logger) FatalError(err error, msg string) {
	l.Errorf("%s : %v", msg, err)
	bugsnag.Notify(err)
	os.Exit(1)
}

// HandleErrorf This notifies bugsnag and logs the error based on the args.
func (l *Logger) HandleErrorf(err error, msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(err)
}

// FatalErrorf This notifies bugsnag and logs the error based on the args then quits
func (l *Logger) FatalErrorf(err error, msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(err)
	os.Exit(1)
}

// FatalErrorf This notifies bugsnag and logs the error based on the args then quits
func (l *Logger) Fatalf(msg string, args ...interface{}) {
	l.Errorf(msg, args)
	bugsnag.Notify(fmt.Errorf(msg, args))
	os.Exit(1)
}
<|endoftext|>


<commit_before>// Copyright 2021 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.

// Functions for cleaning the database of unwanted module versions.

package postgres

import (
	"context"
	"database/sql"

	"golang.org/x/pkgsite/internal/derrors"
)

// A ModuleVersion holds a module path and version.
type ModuleVersion struct {
	ModulePath string
	Version    string
}

func (mv ModuleVersion) String() string {
	return mv.ModulePath + "@" + mv.Version
}

// GetModuleVersionsToClean returns module versions that can be removed from the database.
// Only module versions that were updated more than daysOld days ago will be considered.
// At most limit module versions will be returned.
func (db *DB) GetModuleVersionsToClean(ctx context.Context, daysOld, limit int) (modvers []ModuleVersion, err error) {
	defer derrors.WrapStack(&err, "GetModuleVersionsToClean(%d, %d)", daysOld, limit)

	// Get all pseudo-versions that were added before the given number of days.
	// Then remove:
	// - The ones that are the latest versions for their module,
	// - The ones in search_documents (since the latest version of a package might be at an older version),
	// - The ones that the master or main branch resolves to.
	query := `
		SELECT module_path, version
		FROM modules
		WHERE version_type = 'pseudo'
		AND CURRENT_TIMESTAMP - updated_at > make_interval(days => $1)
		EXCEPT (
			SELECT p.path, l.good_version
			FROM latest_module_versions l
			INNER JOIN paths p ON p.id = l.module_path_id
			WHERE good_version != ''
		)
		EXCEPT (
			SELECT module_path, version
			FROM search_documents
		)
		EXCEPT (
			SELECT module_path, resolved_version
			FROM version_map
			WHERE requested_version IN ('master', 'main')
		)
		LIMIT $2
	`

	err = db.db.RunQuery(ctx, query, func(rows *sql.Rows) error {
		var mv ModuleVersion
		if err := rows.Scan(&mv.ModulePath, &mv.Version); err != nil {
			return err
		}
		modvers = append(modvers, mv)
		return nil
	}, daysOld, limit)
	if err != nil {
		return nil, err
	}
	return modvers, nil
}

// CleanModuleVersions deletes each module version from the DB and marks it as cleaned
// in module_version_states.
func (db *DB) CleanModuleVersions(ctx context.Context, mvs []ModuleVersion, reason string) (err error) {
	defer derrors.Wrap(&err, "CleanModuleVersions(%d modules)", len(mvs))

	status := derrors.ToStatus(derrors.Cleaned)
	for _, mv := range mvs {
		if err := db.UpdateModuleVersionStatus(ctx, mv.ModulePath, mv.Version, status, reason); err != nil {
			return err
		}
		if err := db.DeleteModule(ctx, mv.ModulePath, mv.Version); err != nil {
			return err
		}
	}
	return nil
}

// CleanModule deletes all versions of the given module path from the DB and marks them
// as cleaned in module_version_states.
func (db *DB) CleanModule(ctx context.Context, modulePath, reason string) (err error) {
	defer derrors.Wrap(&err, "CleanModule(%q)", modulePath)

	var mvs []ModuleVersion
	err = db.db.RunQuery(ctx, `
		SELECT version
		FROM modules
		WHERE module_path = $1
	`, func(rows *sql.Rows) error {
		var v string
		if err := rows.Scan(&v); err != nil {
			return err
		}
		mvs = append(mvs, ModuleVersion{modulePath, v})
		return nil
	}, modulePath)
	if err != nil {
		return err
	}
	return db.CleanModuleVersions(ctx, mvs, reason)
}
<commit_msg>internal/postgres: do not clean std@dev.fuzz<commit_after>// Copyright 2021 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.

// Functions for cleaning the database of unwanted module versions.

package postgres

import (
	"context"
	"database/sql"

	"golang.org/x/pkgsite/internal/derrors"
)

// A ModuleVersion holds a module path and version.
type ModuleVersion struct {
	ModulePath string
	Version    string
}

func (mv ModuleVersion) String() string {
	return mv.ModulePath + "@" + mv.Version
}

// GetModuleVersionsToClean returns module versions that can be removed from the database.
// Only module versions that were updated more than daysOld days ago will be considered.
// At most limit module versions will be returned.
func (db *DB) GetModuleVersionsToClean(ctx context.Context, daysOld, limit int) (modvers []ModuleVersion, err error) {
	defer derrors.WrapStack(&err, "GetModuleVersionsToClean(%d, %d)", daysOld, limit)

	// Get all pseudo-versions that were added before the given number of days.
	// Then remove:
	// - The ones that are the latest versions for their module,
	// - The ones in search_documents (since the latest version of a package might be at an older version),
	// - The ones that the master or main branch resolves to.
	query := `
		SELECT module_path, version
		FROM modules
		WHERE version_type = 'pseudo'
		AND CURRENT_TIMESTAMP - updated_at > make_interval(days => $1)
		EXCEPT (
			SELECT p.path, l.good_version
			FROM latest_module_versions l
			INNER JOIN paths p ON p.id = l.module_path_id
			WHERE good_version != ''
		)
		EXCEPT (
			SELECT module_path, version
			FROM search_documents
		)
		EXCEPT (
			SELECT module_path, resolved_version
			FROM version_map
			WHERE requested_version IN ('master', 'main', 'dev.fuzz')
		)
		LIMIT $2
	`

	err = db.db.RunQuery(ctx, query, func(rows *sql.Rows) error {
		var mv ModuleVersion
		if err := rows.Scan(&mv.ModulePath, &mv.Version); err != nil {
			return err
		}
		modvers = append(modvers, mv)
		return nil
	}, daysOld, limit)
	if err != nil {
		return nil, err
	}
	return modvers, nil
}

// CleanModuleVersions deletes each module version from the DB and marks it as cleaned
// in module_version_states.
func (db *DB) CleanModuleVersions(ctx context.Context, mvs []ModuleVersion, reason string) (err error) {
	defer derrors.Wrap(&err, "CleanModuleVersions(%d modules)", len(mvs))

	status := derrors.ToStatus(derrors.Cleaned)
	for _, mv := range mvs {
		if err := db.UpdateModuleVersionStatus(ctx, mv.ModulePath, mv.Version, status, reason); err != nil {
			return err
		}
		if err := db.DeleteModule(ctx, mv.ModulePath, mv.Version); err != nil {
			return err
		}
	}
	return nil
}

// CleanModule deletes all versions of the given module path from the DB and marks them
// as cleaned in module_version_states.
func (db *DB) CleanModule(ctx context.Context, modulePath, reason string) (err error) {
	defer derrors.Wrap(&err, "CleanModule(%q)", modulePath)

	var mvs []ModuleVersion
	err = db.db.RunQuery(ctx, `
		SELECT version
		FROM modules
		WHERE module_path = $1
	`, func(rows *sql.Rows) error {
		var v string
		if err := rows.Scan(&v); err != nil {
			return err
		}
		mvs = append(mvs, ModuleVersion{modulePath, v})
		return nil
	}, modulePath)
	if err != nil {
		return err
	}
	return db.CleanModuleVersions(ctx, mvs, reason)
}
<|endoftext|>