<commit_before>package httputilmore

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"strings"

	"github.com/grokify/gotilla/strconv/strconvutil"
)

const (
	HeaderAuthorization           = "Authorization"
	HeaderContentDisposition      = "Content-Disposition"
	HeaderContentLength           = "Content-Length"
	HeaderContentTransferEncoding = "Content-Transfer-Encoding"
	HeaderContentType             = "Content-Type"
	// ContentTypeValueJSONUTF8 represents the HTTP Content-Type header
	// value for UTF-8 encoded JSON.
	HeaderContentTypeValueJSONUTF8      = "application/json; charset=utf-8"
	HeaderContenTypeValueFormURLEncoded = "application/x-www-form-urlencoded"
	// HTTPS Scheme
	SchemeHTTPS = "https"
)

// GetWriteFile performs a HTTP GET request and saves the response body
// to the file path specified
func GetWriteFile(url string, filename string, perm os.FileMode) ([]byte, error) {
	_, bytes, err := GetResponseAndBytes(url)
	if err != nil {
		return bytes, err
	}
	err = ioutil.WriteFile(filename, bytes, perm)
	return bytes, err
}

// ResponseBody returns the body as a byte array
func ResponseBody(res *http.Response) ([]byte, error) {
	defer res.Body.Close()
	contents, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return []byte{}, err
	}
	return contents, nil
}

// ResponseBodyJSONMapIndent returns the body as a generic JSON dictionary
func ResponseBodyJSONMapIndent(res *http.Response, prefix string, indent string) ([]byte, error) {
	body, err := ResponseBody(res)
	if err != nil {
		return body, err
	}
	any := map[string]interface{}{}
	json.Unmarshal(body, &any)
	return json.MarshalIndent(any, prefix, indent)
}

// GetResponseAndBytes retreives a URL and returns the response body
// as a byte array in addition to the *http.Response.
func GetResponseAndBytes(url string) (*http.Response, []byte, error) {
	resp, err := http.Get(url)
	if err != nil {
		return resp, []byte{}, err
	}
	bytes, err := ResponseBody(resp)
	return resp, bytes, err
}

// UnmarshalResponseJSON unmarshal a `*http.Response` JSON body into
// a data pointer.
func UnmarshalResponseJSON(resp *http.Response, data interface{}) error {
	//bytes, err := ResponseBody(resp)
	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, data)
}

// PrintRequestOut prints a http.Request using `httputil.DumpRequestOut`.
func PrintRequestOut(req *http.Request, includeBody bool) error {
	reqBytes, err := httputil.DumpRequestOut(req, includeBody)
	if err != nil {
		return err
	}
	fmt.Println(string(reqBytes))
	return nil
}

// PrintResponse prints a http.Response using `httputil.DumpResponse`.
func PrintResponse(resp *http.Response, includeBody bool) error {
	respBytes, err := httputil.DumpResponse(resp, includeBody)
	if err != nil {
		return err
	}
	fmt.Println(string(respBytes))
	return nil
}

// MergeHeader merges two http.Header adding the values of the second
// to the first.
func MergeHeader(base, extra http.Header, overwrite bool) http.Header {
	for k, vals := range extra {
		if overwrite {
			base.Del(k)
		}

		for _, v := range vals {
			v = strings.TrimSpace(v)
			if len(v) > 0 {
				base.Add(k, v)
			}
		}
	}
	return base
}

// RateLimitInfo is a structure for holding parsed rate limit info.
// It uses headers from the GitHub, RingCentral and Twitter APIs.
type RateLimitInfo struct {
	StatusCode          int
	RetryAfter          int
	XRateLimitLimit     int
	XRateLimitRemaining int
	XRateLimitReset     int
	XRateLimitWindow    int
}

// NewResponseRateLimitInfo returns a RateLimitInfo from a http.Response.
func NewResponseRateLimitInfo(resp *http.Response, useXrlHyphen bool) RateLimitInfo {
	rlstat := RateLimitInfo{
		StatusCode: resp.StatusCode,
		RetryAfter: strconvutil.AtoiWithDefault(resp.Header.Get("Retry-After"), 0)}

	if useXrlHyphen {
		rlstat.XRateLimitLimit = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Limit"), 0)
		rlstat.XRateLimitRemaining = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Remaining"), 0)
		rlstat.XRateLimitReset = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Reset"), 0)
		rlstat.XRateLimitWindow = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Window"), 0)
	} else {
		rlstat.XRateLimitLimit = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Limit"), 0)
		rlstat.XRateLimitRemaining = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Remaining"), 0)
		rlstat.XRateLimitReset = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Reset"), 0)
		rlstat.XRateLimitWindow = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Window"), 0)
	}
	return rlstat
}

type FnLogRateLimitInfo func(RateLimitInfo)
<commit_msg>add httputilmore.HeaderContentTypeValueTextPlainUsAscii<commit_after>package httputilmore

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"strings"

	"github.com/grokify/gotilla/strconv/strconvutil"
)

const (
	HeaderAuthorization           = "Authorization"
	HeaderContentDisposition      = "Content-Disposition"
	HeaderContentLength           = "Content-Length"
	HeaderContentTransferEncoding = "Content-Transfer-Encoding"
	HeaderContentType             = "Content-Type"
	// ContentTypeValueJSONUTF8 represents the HTTP Content-Type header
	// value for UTF-8 encoded JSON.
	HeaderContentTypeValueJSONUTF8         = "application/json; charset=utf-8"
	HeaderContentTypeValueFormURLEncoded   = "application/x-www-form-urlencoded"
	HeaderContentTypeValueTextPlainUsAscii = "text/plain; charset=us-ascii"
	// HTTPS Scheme
	SchemeHTTPS = "https"
)

// GetWriteFile performs a HTTP GET request and saves the response body
// to the file path specified
func GetWriteFile(url string, filename string, perm os.FileMode) ([]byte, error) {
	_, bytes, err := GetResponseAndBytes(url)
	if err != nil {
		return bytes, err
	}
	err = ioutil.WriteFile(filename, bytes, perm)
	return bytes, err
}

// ResponseBody returns the body as a byte array
func ResponseBody(res *http.Response) ([]byte, error) {
	defer res.Body.Close()
	contents, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return []byte{}, err
	}
	return contents, nil
}

// ResponseBodyJSONMapIndent returns the body as a generic JSON dictionary
func ResponseBodyJSONMapIndent(res *http.Response, prefix string, indent string) ([]byte, error) {
	body, err := ResponseBody(res)
	if err != nil {
		return body, err
	}
	any := map[string]interface{}{}
	json.Unmarshal(body, &any)
	return json.MarshalIndent(any, prefix, indent)
}

// GetResponseAndBytes retreives a URL and returns the response body
// as a byte array in addition to the *http.Response.
func GetResponseAndBytes(url string) (*http.Response, []byte, error) {
	resp, err := http.Get(url)
	if err != nil {
		return resp, []byte{}, err
	}
	bytes, err := ResponseBody(resp)
	return resp, bytes, err
}

// UnmarshalResponseJSON unmarshal a `*http.Response` JSON body into
// a data pointer.
func UnmarshalResponseJSON(resp *http.Response, data interface{}) error {
	//bytes, err := ResponseBody(resp)
	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, data)
}

// PrintRequestOut prints a http.Request using `httputil.DumpRequestOut`.
func PrintRequestOut(req *http.Request, includeBody bool) error {
	reqBytes, err := httputil.DumpRequestOut(req, includeBody)
	if err != nil {
		return err
	}
	fmt.Println(string(reqBytes))
	return nil
}

// PrintResponse prints a http.Response using `httputil.DumpResponse`.
func PrintResponse(resp *http.Response, includeBody bool) error {
	respBytes, err := httputil.DumpResponse(resp, includeBody)
	if err != nil {
		return err
	}
	fmt.Println(string(respBytes))
	return nil
}

// MergeHeader merges two http.Header adding the values of the second
// to the first.
func MergeHeader(base, extra http.Header, overwrite bool) http.Header {
	for k, vals := range extra {
		if overwrite {
			base.Del(k)
		}

		for _, v := range vals {
			v = strings.TrimSpace(v)
			if len(v) > 0 {
				base.Add(k, v)
			}
		}
	}
	return base
}

// RateLimitInfo is a structure for holding parsed rate limit info.
// It uses headers from the GitHub, RingCentral and Twitter APIs.
type RateLimitInfo struct {
	StatusCode          int
	RetryAfter          int
	XRateLimitLimit     int
	XRateLimitRemaining int
	XRateLimitReset     int
	XRateLimitWindow    int
}

// NewResponseRateLimitInfo returns a RateLimitInfo from a http.Response.
func NewResponseRateLimitInfo(resp *http.Response, useXrlHyphen bool) RateLimitInfo {
	rlstat := RateLimitInfo{
		StatusCode: resp.StatusCode,
		RetryAfter: strconvutil.AtoiWithDefault(resp.Header.Get("Retry-After"), 0)}

	if useXrlHyphen {
		rlstat.XRateLimitLimit = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Limit"), 0)
		rlstat.XRateLimitRemaining = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Remaining"), 0)
		rlstat.XRateLimitReset = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Reset"), 0)
		rlstat.XRateLimitWindow = strconvutil.AtoiWithDefault(resp.Header.Get("X-Rate-Limit-Window"), 0)
	} else {
		rlstat.XRateLimitLimit = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Limit"), 0)
		rlstat.XRateLimitRemaining = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Remaining"), 0)
		rlstat.XRateLimitReset = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Reset"), 0)
		rlstat.XRateLimitWindow = strconvutil.AtoiWithDefault(resp.Header.Get("X-RateLimit-Window"), 0)
	}
	return rlstat
}

type FnLogRateLimitInfo func(RateLimitInfo)
<|endoftext|>


<commit_before>package core

import (
	"testing"

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

func TestDumpFail(t *testing.T) {
	for _, th := range []*Thunk{
		OutOfRangeError(),
	} {
		v := PApp(Dump, th).Eval()
		t.Log(v)

		if _, ok := v.(ErrorType); !ok {
			t.Fail()
		}
	}
}

func TestInternalStrictDumpPanic(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		}
	}()

	strictDump(nil)
}

func TestInternalStrictDumpFail(t *testing.T) {
	for _, th := range []*Thunk{
		NewList(OutOfRangeError()),
		NewDictionary([]Value{Nil.Eval()}, []*Thunk{OutOfRangeError()})} {
		if _, err := strictDump(th.Eval()); err == nil {
			t.Fail()
		}
	}
}

func TestStrictDump(t *testing.T) {
	for _, th := range []*Thunk{
		Nil,
		True,
		False,
		EmptyList,
		EmptyDictionary,
		NewNumber(42),
		NewString("foo"),
		NewOutput(Nil),
	} {
		s, err := StrictDump(th.Eval())
		assert.NotEqual(t, "", s)
		assert.Equal(t, (*Thunk)(nil), err)
	}
}

func TestTypeOf(t *testing.T) {
	for _, test := range []struct {
		typ   string
		thunk *Thunk
	}{
		{"nil", Nil},
		{"list", NewList()},
		{"list", EmptyList},
		{"bool", True},
		{"number", NewNumber(123)},
		{"string", NewString("foo")},
		{"dict", NewDictionary(nil, nil)},
		{"error", NewError("MyError", "This is error.")},
		{"function", identity},
		{"function", PApp(Partial, identity)},
	} {
		v := PApp(TypeOf, test.thunk).Eval()
		t.Log(v)
		assert.Equal(t, test.typ, string(v.(StringType)))
	}
}

func TestTypeOfFail(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		} else if _, ok := r.(error); !ok {
			t.Fail()
		}
	}()

	PApp(TypeOf, Normal("foo")).Eval()
}
<commit_msg>Test identity function<commit_after>package core

import (
	"testing"

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

func TestDumpFail(t *testing.T) {
	for _, th := range []*Thunk{
		OutOfRangeError(),
	} {
		v := PApp(Dump, th).Eval()
		t.Log(v)

		if _, ok := v.(ErrorType); !ok {
			t.Fail()
		}
	}
}

func TestInternalStrictDumpPanic(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		}
	}()

	strictDump(nil)
}

func TestInternalStrictDumpFail(t *testing.T) {
	for _, th := range []*Thunk{
		NewList(OutOfRangeError()),
		NewDictionary([]Value{Nil.Eval()}, []*Thunk{OutOfRangeError()})} {
		if _, err := strictDump(th.Eval()); err == nil {
			t.Fail()
		}
	}
}

func TestStrictDump(t *testing.T) {
	for _, th := range []*Thunk{
		Nil,
		True,
		False,
		EmptyList,
		EmptyDictionary,
		NewNumber(42),
		NewString("foo"),
		NewOutput(Nil),
	} {
		s, err := StrictDump(th.Eval())
		assert.NotEqual(t, "", s)
		assert.Equal(t, (*Thunk)(nil), err)
	}
}

func TestIdentity(t *testing.T) {
	for _, th := range []*Thunk{Nil, NewNumber(42), True, False, NewString("foo")} {
		assert.True(t, testEqual(PApp(identity, th), th))
	}
}

func TestTypeOf(t *testing.T) {
	for _, test := range []struct {
		typ   string
		thunk *Thunk
	}{
		{"nil", Nil},
		{"list", NewList()},
		{"list", EmptyList},
		{"bool", True},
		{"number", NewNumber(123)},
		{"string", NewString("foo")},
		{"dict", NewDictionary(nil, nil)},
		{"error", NewError("MyError", "This is error.")},
		{"function", identity},
		{"function", PApp(Partial, identity)},
	} {
		v := PApp(TypeOf, test.thunk).Eval()
		t.Log(v)
		assert.Equal(t, test.typ, string(v.(StringType)))
	}
}

func TestTypeOfFail(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		} else if _, ok := r.(error); !ok {
			t.Fail()
		}
	}()

	PApp(TypeOf, Normal("foo")).Eval()
}
<|endoftext|>


<commit_before>package actors

import (
	"github.com/cloudfoundry/cli/cf/i18n"
	goi18n "github.com/nicksnyder/go-i18n/i18n"
)

var T goi18n.TranslateFunc

func init() {
	T = i18n.Init("actors", i18n.GetResourcesPath())
}<commit_msg>Add newline at end of some random file<commit_after>package actors

import (
	"github.com/cloudfoundry/cli/cf/i18n"
	goi18n "github.com/nicksnyder/go-i18n/i18n"
)

var T goi18n.TranslateFunc

func init() {
	T = i18n.Init("actors", i18n.GetResourcesPath())
}
<|endoftext|>


<commit_before>package terminal_test

import (
	"io"
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/i18n/detection"
	"github.com/cloudfoundry/cli/cf/models"
	testassert "github.com/cloudfoundry/cli/testhelpers/assert"
	"github.com/cloudfoundry/cli/testhelpers/configuration"
	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
	io_helpers "github.com/cloudfoundry/cli/testhelpers/io"

	. "github.com/cloudfoundry/cli/cf/terminal"
	. "github.com/cloudfoundry/cli/testhelpers/matchers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("UI", func() {

	Describe("Printing message to stdout with PrintCapturingNoOutput", func() {
		It("prints strings without using the TeePrinter", func() {
			bucket := &[]string{}

			printer := NewTeePrinter()
			printer.SetOutputBucket(bucket)

			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, printer)
					ui.PrintCapturingNoOutput("Hello")
				})

				Expect("Hello").To(Equal(strings.Join(output, "")))
				Expect(len(*bucket)).To(Equal(0))
			})
		})
	})

	Describe("Printing message to stdout with Say", func() {
		It("prints strings", func() {
			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					ui.Say("Hello")
				})

				Expect("Hello").To(Equal(strings.Join(output, "")))
			})
		})

		It("prints formatted strings", func() {
			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					ui.Say("Hello %s", "World!")
				})

				Expect("Hello World!").To(Equal(strings.Join(output, "")))
			})
		})

		It("does not format strings when provided no args", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.Say("Hello %s World!") // whoops
			})

			Expect(strings.Join(output, "")).To(Equal("Hello %s World!"))
		})
	})

	Describe("Asking user for input", func() {
		It("allows string with whitespaces", func() {
			io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("foo bar\n", func(reader io.Reader) {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Ask("?")).To(Equal("foo bar"))
				})
			})
		})

		It("returns empty string if an error occured while reading string", func() {
			io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("string without expected delimiter", func(reader io.Reader) {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Ask("?")).To(Equal(""))
				})
			})
		})

		It("always outputs the prompt, even when output is disabled", func() {
			output := io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("things are great\n", func(reader io.Reader) {
					printer := NewTeePrinter()
					printer.DisableTerminalOutput(true)
					ui := NewUI(reader, printer)
					ui.Ask("You like things?")
				})
			})
			Expect(strings.Join(output, "")).To(ContainSubstring("You like things?"))
		})
	})

	Describe("Confirming user input", func() {
		It("treats 'y' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats 'yes' as an affirmative confirmation when default language is not en_US", func() {
			oldLang := os.Getenv("LC_ALL")
			defer os.Setenv("LC_ALL", oldLang)

			oldT := i18n.T
			defer func() {
				i18n.T = oldT
			}()

			os.Setenv("LC_ALL", "fr_FR")

			config := configuration.NewRepositoryWithDefaults()
			i18n.T = i18n.Init(config, &detection.JibberJabberDetector{})

			io_helpers.SimulateStdin("oui\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})
				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})

			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})
				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats 'yes' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats other input as a negative confirmation", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})
	})

	Describe("Confirming deletion", func() {
		It("formats a nice output string with exactly one prompt", func() {
			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("fizzbuzz", "bizzbump")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{
					"Really delete the fizzbuzz",
					"bizzbump",
					"?> ",
				}))
			})
		})

		It("treats 'yes' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"modelType modelName"}))
			})
		})

		It("treats other input as a negative confirmation and warns the user", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
			})
		})
	})

	Describe("Confirming deletion with associations", func() {
		It("warns the user that associated objects will also be deleted", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDeleteWithAssociations("modelType", "modelName")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
			})
		})
	})

	Context("when user is not logged in", func() {
		var config core_config.Reader

		BeforeEach(func() {
			config = testconfig.NewRepository()
		})

		It("prompts the user to login", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).ToNot(ContainSubstrings([]string{"API endpoint:"}))
			Expect(output).To(ContainSubstrings([]string{"Not logged in", "Use", "log in"}))
		})
	})

	Context("when an api endpoint is set and the user logged in", func() {
		var config core_config.ReadWriter

		BeforeEach(func() {
			accessToken := core_config.TokenInfo{
				UserGuid: "my-user-guid",
				Username: "my-user",
				Email:    "my-user-email",
			}
			config = testconfig.NewRepositoryWithAccessToken(accessToken)
			config.SetApiEndpoint("https://test.example.org")
			config.SetApiVersion("☃☃☃")
		})

		Describe("tells the user what is set in the config", func() {
			var output []string

			JustBeforeEach(func() {
				output = io_helpers.CaptureOutput(func() {
					ui := NewUI(os.Stdin, NewTeePrinter())
					ui.ShowConfiguration(config)
				})
			})

			It("tells the user which api endpoint is set", func() {
				Expect(output).To(ContainSubstrings([]string{"API endpoint:", "https://test.example.org"}))
			})

			It("tells the user the api version", func() {
				Expect(output).To(ContainSubstrings([]string{"API version:", "☃☃☃"}))
			})

			It("tells the user which user is logged in", func() {
				Expect(output).To(ContainSubstrings([]string{"User:", "my-user-email"}))
			})

			Context("when an org is targeted", func() {
				BeforeEach(func() {
					config.SetOrganizationFields(models.OrganizationFields{
						Name: "org-name",
						Guid: "org-guid",
					})
				})

				It("tells the user which org is targeted", func() {
					Expect(output).To(ContainSubstrings([]string{"Org:", "org-name"}))
				})
			})

			Context("when a space is targeted", func() {
				BeforeEach(func() {
					config.SetSpaceFields(models.SpaceFields{
						Name: "my-space",
						Guid: "space-guid",
					})
				})

				It("tells the user which space is targeted", func() {
					Expect(output).To(ContainSubstrings([]string{"Space:", "my-space"}))
				})
			})
		})

		It("prompts the user to target an org and space when no org or space is targeted", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "org", "space", "targeted", "-o ORG", "-s SPACE"}))
		})

		It("prompts the user to target an org when no org is targeted", func() {
			sf := models.SpaceFields{}
			sf.Guid = "guid"
			sf.Name = "name"

			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "org", "targeted", "-o ORG"}))
		})

		It("prompts the user to target a space when no space is targeted", func() {
			of := models.OrganizationFields{}
			of.Guid = "of-guid"
			of.Name = "of-name"

			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "space", "targeted", "-s SPACE"}))
		})
	})

	Describe("failing", func() {
		It("panics with a specific string", func() {
			io_helpers.CaptureOutput(func() {
				testassert.AssertPanic(QuietPanic, func() {
					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
				})
			})
		})

		It("does not use 'T' func to translate when it is not initialized", func() {
			t := i18n.T
			i18n.T = nil

			io_helpers.CaptureOutput(func() {
				testassert.AssertPanic(QuietPanic, func() {
					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
				})
			})

			i18n.T = t
		})
	})
})
<commit_msg>remove windows incompatible language test<commit_after>package terminal_test

import (
	"io"
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/i18n/detection"
	"github.com/cloudfoundry/cli/cf/models"
	testassert "github.com/cloudfoundry/cli/testhelpers/assert"
	"github.com/cloudfoundry/cli/testhelpers/configuration"
	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
	io_helpers "github.com/cloudfoundry/cli/testhelpers/io"

	. "github.com/cloudfoundry/cli/cf/terminal"
	. "github.com/cloudfoundry/cli/testhelpers/matchers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("UI", func() {

	Describe("Printing message to stdout with PrintCapturingNoOutput", func() {
		It("prints strings without using the TeePrinter", func() {
			bucket := &[]string{}

			printer := NewTeePrinter()
			printer.SetOutputBucket(bucket)

			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, printer)
					ui.PrintCapturingNoOutput("Hello")
				})

				Expect("Hello").To(Equal(strings.Join(output, "")))
				Expect(len(*bucket)).To(Equal(0))
			})
		})
	})

	Describe("Printing message to stdout with Say", func() {
		It("prints strings", func() {
			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					ui.Say("Hello")
				})

				Expect("Hello").To(Equal(strings.Join(output, "")))
			})
		})

		It("prints formatted strings", func() {
			io_helpers.SimulateStdin("", func(reader io.Reader) {
				output := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					ui.Say("Hello %s", "World!")
				})

				Expect("Hello World!").To(Equal(strings.Join(output, "")))
			})
		})

		It("does not format strings when provided no args", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.Say("Hello %s World!") // whoops
			})

			Expect(strings.Join(output, "")).To(Equal("Hello %s World!"))
		})
	})

	Describe("Asking user for input", func() {
		It("allows string with whitespaces", func() {
			io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("foo bar\n", func(reader io.Reader) {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Ask("?")).To(Equal("foo bar"))
				})
			})
		})

		It("returns empty string if an error occured while reading string", func() {
			io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("string without expected delimiter", func(reader io.Reader) {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Ask("?")).To(Equal(""))
				})
			})
		})

		It("always outputs the prompt, even when output is disabled", func() {
			output := io_helpers.CaptureOutput(func() {
				io_helpers.SimulateStdin("things are great\n", func(reader io.Reader) {
					printer := NewTeePrinter()
					printer.DisableTerminalOutput(true)
					ui := NewUI(reader, printer)
					ui.Ask("You like things?")
				})
			})
			Expect(strings.Join(output, "")).To(ContainSubstring("You like things?"))
		})
	})

	Describe("Confirming user input", func() {
		It("treats 'y' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats 'yes' as an affirmative confirmation when default language is not en_US", func() {
			oldLang := os.Getenv("LC_ALL")
			defer os.Setenv("LC_ALL", oldLang)

			oldT := i18n.T
			defer func() {
				i18n.T = oldT
			}()

			os.Setenv("LC_ALL", "fr_FR")

			config := configuration.NewRepositoryWithDefaults()
			i18n.T = i18n.Init(config, &detection.JibberJabberDetector{})

			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})
				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats 'yes' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})

		It("treats other input as a negative confirmation", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.Confirm("Hello %s", "World?")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
			})
		})
	})

	Describe("Confirming deletion", func() {
		It("formats a nice output string with exactly one prompt", func() {
			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("fizzbuzz", "bizzbump")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{
					"Really delete the fizzbuzz",
					"bizzbump",
					"?> ",
				}))
			})
		})

		It("treats 'yes' as an affirmative confirmation", func() {
			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeTrue())
				})

				Expect(out).To(ContainSubstrings([]string{"modelType modelName"}))
			})
		})

		It("treats other input as a negative confirmation and warns the user", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
			})
		})
	})

	Describe("Confirming deletion with associations", func() {
		It("warns the user that associated objects will also be deleted", func() {
			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
				out := io_helpers.CaptureOutput(func() {
					ui := NewUI(reader, NewTeePrinter())
					Expect(ui.ConfirmDeleteWithAssociations("modelType", "modelName")).To(BeFalse())
				})

				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
			})
		})
	})

	Context("when user is not logged in", func() {
		var config core_config.Reader

		BeforeEach(func() {
			config = testconfig.NewRepository()
		})

		It("prompts the user to login", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).ToNot(ContainSubstrings([]string{"API endpoint:"}))
			Expect(output).To(ContainSubstrings([]string{"Not logged in", "Use", "log in"}))
		})
	})

	Context("when an api endpoint is set and the user logged in", func() {
		var config core_config.ReadWriter

		BeforeEach(func() {
			accessToken := core_config.TokenInfo{
				UserGuid: "my-user-guid",
				Username: "my-user",
				Email:    "my-user-email",
			}
			config = testconfig.NewRepositoryWithAccessToken(accessToken)
			config.SetApiEndpoint("https://test.example.org")
			config.SetApiVersion("☃☃☃")
		})

		Describe("tells the user what is set in the config", func() {
			var output []string

			JustBeforeEach(func() {
				output = io_helpers.CaptureOutput(func() {
					ui := NewUI(os.Stdin, NewTeePrinter())
					ui.ShowConfiguration(config)
				})
			})

			It("tells the user which api endpoint is set", func() {
				Expect(output).To(ContainSubstrings([]string{"API endpoint:", "https://test.example.org"}))
			})

			It("tells the user the api version", func() {
				Expect(output).To(ContainSubstrings([]string{"API version:", "☃☃☃"}))
			})

			It("tells the user which user is logged in", func() {
				Expect(output).To(ContainSubstrings([]string{"User:", "my-user-email"}))
			})

			Context("when an org is targeted", func() {
				BeforeEach(func() {
					config.SetOrganizationFields(models.OrganizationFields{
						Name: "org-name",
						Guid: "org-guid",
					})
				})

				It("tells the user which org is targeted", func() {
					Expect(output).To(ContainSubstrings([]string{"Org:", "org-name"}))
				})
			})

			Context("when a space is targeted", func() {
				BeforeEach(func() {
					config.SetSpaceFields(models.SpaceFields{
						Name: "my-space",
						Guid: "space-guid",
					})
				})

				It("tells the user which space is targeted", func() {
					Expect(output).To(ContainSubstrings([]string{"Space:", "my-space"}))
				})
			})
		})

		It("prompts the user to target an org and space when no org or space is targeted", func() {
			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "org", "space", "targeted", "-o ORG", "-s SPACE"}))
		})

		It("prompts the user to target an org when no org is targeted", func() {
			sf := models.SpaceFields{}
			sf.Guid = "guid"
			sf.Name = "name"

			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "org", "targeted", "-o ORG"}))
		})

		It("prompts the user to target a space when no space is targeted", func() {
			of := models.OrganizationFields{}
			of.Guid = "of-guid"
			of.Name = "of-name"

			output := io_helpers.CaptureOutput(func() {
				ui := NewUI(os.Stdin, NewTeePrinter())
				ui.ShowConfiguration(config)
			})

			Expect(output).To(ContainSubstrings([]string{"No", "space", "targeted", "-s SPACE"}))
		})
	})

	Describe("failing", func() {
		It("panics with a specific string", func() {
			io_helpers.CaptureOutput(func() {
				testassert.AssertPanic(QuietPanic, func() {
					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
				})
			})
		})

		It("does not use 'T' func to translate when it is not initialized", func() {
			t := i18n.T
			i18n.T = nil

			io_helpers.CaptureOutput(func() {
				testassert.AssertPanic(QuietPanic, func() {
					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
				})
			})

			i18n.T = t
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"

	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	weed_server "github.com/chrislusf/seaweedfs/weed/server"
	"github.com/chrislusf/seaweedfs/weed/storage"
	"github.com/spf13/viper"
	"golang.org/x/tools/godoc/util"

	"io"
	"log"
)

var (
	master         = flag.String("master", "localhost:9333", "master server host and port")
	volumeId       = flag.Int("volumeId", -1, "a volume id")
	timeoutSeconds = flag.Int("timeoutSeconds", 0, "disconnect if no activity after these seconds")
	showTextFile   = flag.Bool("showTextFile", false, "display textual file content")
)

func main() {
	flag.Parse()

	weed_server.LoadConfiguration("security", false)
	grpcDialOption := security.LoadClientTLS(viper.Sub("grpc"), "client")

	vid := storage.VolumeId(*volumeId)

	// find volume location, replication, ttl info
	lookup, err := operation.Lookup(*master, vid.String())
	if err != nil {
		log.Printf("Error looking up volume %d: %v", vid, err)
		return
	}
	volumeServer := lookup.Locations[0].Url
	log.Printf("volume %d is on volume server %s", vid, volumeServer)

	err = operation.WithVolumeServerClient(volumeServer, grpcDialOption, func(client volume_server_pb.VolumeServerClient) error {

		stream, err := client.VolumeTail(context.Background(), &volume_server_pb.VolumeTailRequest{
			VolumeId:        uint32(vid),
			SinceNs:         0,
			DrainingSeconds: uint32(*timeoutSeconds),
		})
		if err != nil {
			return err
		}

		for {
			resp, recvErr := stream.Recv()
			if recvErr != nil {
				if recvErr == io.EOF {
					break
				} else {
					return recvErr
				}
			}

			needleHeader := resp.NeedleHeader
			needleBody := resp.NeedleBody

			if len(needleHeader) == 0 {
				continue
			}

			for !resp.IsLastChunk {
				resp, recvErr = stream.Recv()
				if recvErr != nil {
					if recvErr == io.EOF {
						break
					} else {
						return recvErr
					}
				}
				needleBody = append(needleBody, resp.NeedleBody...)
			}

			n := new(storage.Needle)
			n.ParseNeedleHeader(needleHeader)
			n.ReadNeedleBodyBytes(needleBody, storage.CurrentVersion)

			if n.Size == 0 {
				println("-", n.String())
				continue
			} else {
				println("+", n.String())
			}

			if *showTextFile {

				data := n.Data
				if n.IsGzipped() {
					if data, err = operation.UnGzipData(data); err != nil {
						continue
					}
				}
				if util.IsText(data) {
					println(string(data))
				}

				println("-", n.String(), "compressed", n.IsGzipped(), "original size", len(data))
			}

		}

		return nil

	})

	if err != nil {
		log.Printf("Error VolumeTail volume %d: %v", vid, err)
	}

}
<commit_msg>refactoring<commit_after>package main

import (
	"context"
	"flag"
	"fmt"

	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	weed_server "github.com/chrislusf/seaweedfs/weed/server"
	"github.com/chrislusf/seaweedfs/weed/storage"
	"github.com/spf13/viper"
	"golang.org/x/tools/godoc/util"
	"google.golang.org/grpc"

	"io"
	"log"
)

var (
	master         = flag.String("master", "localhost:9333", "master server host and port")
	volumeId       = flag.Int("volumeId", -1, "a volume id")
	timeoutSeconds = flag.Int("timeoutSeconds", 0, "disconnect if no activity after these seconds")
	showTextFile   = flag.Bool("showTextFile", false, "display textual file content")
)

func main() {
	flag.Parse()

	weed_server.LoadConfiguration("security", false)
	grpcDialOption := security.LoadClientTLS(viper.Sub("grpc"), "client")

	vid := storage.VolumeId(*volumeId)

	err := TailVolume(*master, grpcDialOption, vid, func(n *storage.Needle) (err error) {
		if n.Size == 0 {
			println("-", n.String())
			return nil
		} else {
			println("+", n.String())
		}

		if *showTextFile {

			data := n.Data
			if n.IsGzipped() {
				if data, err = operation.UnGzipData(data); err != nil {
					return err
				}
			}
			if util.IsText(data) {
				println(string(data))
			}

			println("-", n.String(), "compressed", n.IsGzipped(), "original size", len(data))
		}
		return nil
	})

	if err != nil {
		log.Printf("Error VolumeTail volume %d: %v", vid, err)
	}

}

func TailVolume(master string, grpcDialOption grpc.DialOption, vid storage.VolumeId, fn func(n *storage.Needle) error) error {
	// find volume location, replication, ttl info
	lookup, err := operation.Lookup(master, vid.String())
	if err != nil {
		return fmt.Errorf("Error looking up volume %d: %v", vid, err)
	}
	if len(lookup.Locations) == 0 {
		return fmt.Errorf("unable to locate volume %d", vid)
	}

	volumeServer := lookup.Locations[0].Url

	return operation.WithVolumeServerClient(volumeServer, grpcDialOption, func(client volume_server_pb.VolumeServerClient) error {

		stream, err := client.VolumeTail(context.Background(), &volume_server_pb.VolumeTailRequest{
			VolumeId:        uint32(vid),
			SinceNs:         0,
			DrainingSeconds: uint32(*timeoutSeconds),
		})
		if err != nil {
			return err
		}

		for {
			resp, recvErr := stream.Recv()
			if recvErr != nil {
				if recvErr == io.EOF {
					break
				} else {
					return recvErr
				}
			}

			needleHeader := resp.NeedleHeader
			needleBody := resp.NeedleBody

			if len(needleHeader) == 0 {
				continue
			}

			for !resp.IsLastChunk {
				resp, recvErr = stream.Recv()
				if recvErr != nil {
					if recvErr == io.EOF {
						break
					} else {
						return recvErr
					}
				}
				needleBody = append(needleBody, resp.NeedleBody...)
			}

			n := new(storage.Needle)
			n.ParseNeedleHeader(needleHeader)
			n.ReadNeedleBodyBytes(needleBody, storage.CurrentVersion)

			err = fn(n)

			if err != nil {
				return err
			}

		}
		return nil
	})
}
<|endoftext|>


<commit_before>// vcfanno is a command-line application and an api for annotating intervals (bed or vcf).
package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	//_ "net/http/pprof"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/biogo/hts/bgzf"
	"github.com/brentp/irelate"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	. "github.com/brentp/vcfanno/api"
	. "github.com/brentp/vcfanno/shared"
	"github.com/brentp/vcfgo"
	"github.com/brentp/xopen"
)

var VERSION = "0.2.7-beta"

func envGet(name string, vdefault int) int {
	sval := os.Getenv(name)
	var err error
	if sval != "" {
		vdefault, err = strconv.Atoi(sval)
		if err != nil {
			log.Printf("couldn't parse %s using %d\n", name, vdefault)
		} else {
			log.Printf("using %s of %d\n", name, vdefault)
		}
	}
	return vdefault
}

func init() {
	log.SetFlags(log.Lshortfile)
}

func main() {
	fmt.Fprintf(os.Stderr, `
=============================================
vcfanno version %s [built with %s]

see: https://github.com/brentp/vcfanno
=============================================
`, VERSION, runtime.Version())

	ends := flag.Bool("ends", false, "annotate the start and end as well as the interval itself.")
	notstrict := flag.Bool("permissive-overlap", false, "annotate with an overlapping variant even it doesn't"+
		" share the same ref and alt alleles. Default is to require exact match between variants.")
	lua := flag.String("lua", "", "optional path to a file containing custom javascript functions to be used as ops")
	base := flag.String("base-path", "", "optional base-path to prepend to annotation files in the config")
	procs := flag.Int("p", 2, "number of processes to use.")
	flag.Parse()
	inFiles := flag.Args()
	if len(inFiles) != 2 {
		fmt.Printf(`Usage:
%s config.toml input.vcf > annotated.vcf

`, os.Args[0])
		flag.PrintDefaults()
		return
	}
	queryFile := inFiles[1]
	if !(xopen.Exists(queryFile) || queryFile == "") {
		fmt.Fprintf(os.Stderr, "\nERROR: can't find query file: %s\n", queryFile)
		os.Exit(2)
	}
	runtime.GOMAXPROCS(*procs)

	var config Config
	if _, err := toml.DecodeFile(inFiles[0], &config); err != nil {
		if strings.Contains(err.Error(), "Expected value but found") {
			fmt.Fprintln(os.Stderr, "\nNOTE: you must quote values in the conf file, e.g. fields=['AC', 'AN'] instead of fields=[AC, AN]")
		}
		panic(err)
	}
	config.Base = *base
	for _, a := range config.Annotation {
		err := CheckAnno(&a)
		if err != nil {
			log.Fatal("CheckAnno err:", err)
		}
		for _, op := range a.Ops {
			if len(op) > 4 && op[:4] == "lua:" && *lua == "" {
				log.Fatal("ERROR: requested lua op without specifying -lua flag")
			}
		}
	}
	for i := range config.PostAnnotation {
		r := config.PostAnnotation[i]
		err := CheckPostAnno(&r)
		if err != nil {
			log.Fatal(fmt.Sprintf("error in postannotation section %s err: %s", r.Name, err))
		}
		if len(r.Op) > 4 && r.Op[:4] == "lua:" && *lua == "" {
			log.Fatal("ERROR: requested lua op without specifying -lua flag")
		}
	}

	sources, e := config.Sources()
	if e != nil {
		log.Fatal(e)
	}

	log.Printf("found %d sources from %d files\n", len(sources), len(config.Annotation))
	/*
		go func() {
			log.Println(http.ListenAndServe("localhost:6060", nil))
		}()
	*/

	luaString := ReadLua(*lua)
	strict := !*notstrict
	var a = NewAnnotator(sources, luaString, *ends, strict, config.PostAnnotation)

	var out io.Writer = os.Stdout
	defer os.Stdout.Close()

	var err error
	var qrdr io.Reader
	// try to parallelizing reading if we have plenty of CPUs and it's (possibly)
	// a bgzf file.
	if len(config.Annotation) < runtime.GOMAXPROCS(0) && strings.HasSuffix(queryFile, ".gz") {
		if rdr, err := os.Open(queryFile); err == nil {
			if st, err := rdr.Stat(); err == nil && st.Size() > 2320303098 {
				qrdr, err = bgzf.NewReader(rdr, 4)
				if err == nil {
					log.Printf("using 4 worker threads to decompress query file")
				}
			} else {
				qrdr, err = bgzf.NewReader(rdr, 2)
				if err == nil {
					log.Printf("using 2 worker threads to decompress query file")
				}
			}
		}
	}
	if qrdr == nil {
		qrdr, err = xopen.Ropen(queryFile)
	}
	if err != nil {
		log.Fatal(fmt.Errorf("error opening query file %s: %s", queryFile, err))
	}
	qstream, query, err := parsers.VCFIterator(qrdr)
	if err != nil {
		log.Fatal(fmt.Errorf("error parsing VCF query file %s: %s", queryFile, err))
	}

	queryables, err := a.Setup(query)
	if err != nil {
		log.Fatal(err)
	}
	aends := INTERVAL
	if *ends {
		aends = BOTH
	}

	lastMsg := struct {
		sync.RWMutex
		s [10]string
		i int
	}{}

	fn := func(v interfaces.Relatable) {
		e := a.AnnotateEnds(v, aends)
		if e != nil {
			lastMsg.RLock()
			em := e.Error()
			found := false
			for i := len(lastMsg.s) - 1; i >= 0; i-- {
				if em == lastMsg.s[i] {
					found = true
					break
				}
			}
			if !found {
				log.Println(e, ">> this error/warning may occur many times. reporting once here...")
				lastMsg.RUnlock()
				lastMsg.Lock()
				lastMsg.s[lastMsg.i] = em
				if lastMsg.i == len(lastMsg.s)-1 {
					lastMsg.i = -1
				}
				lastMsg.i++

				lastMsg.Unlock()
			} else {
				lastMsg.RUnlock()
			}
		}
	}

	maxGap := envGet("IRELATE_MAX_GAP", 20000)
	maxChunk := envGet("IRELATE_MAX_CHUNK", 8000)

	// make a new writer from the string header.
	out, err = vcfgo.NewWriter(out, query.Header)

	stream := irelate.PIRelate(maxChunk, maxGap, qstream, *ends, fn, queryables...)

	if err != nil {
		log.Fatal(err)
	}

	start := time.Now()
	n := 0

	/*
		if os.Getenv("IRELATE_PROFILE") == "TRUE" {
			log.Println("profiling to: irelate.pprof")
			f, err := os.Create("irelate.pprof")
			if err != nil {
				panic(err)
			}
			pprof.StartCPUProfile(f)
			defer pprof.StopCPUProfile()
		}
	*/

	for interval := range stream {
		//log.Printf("%v\n", interval)
		fmt.Fprintln(out, interval)
		n++
	}
	printTime(start, n)
}

func printTime(start time.Time, n int) {
	dur := time.Since(start)
	duri, duru := dur.Seconds(), "second"
	log.Printf("annotated %d variants in %.2f %ss (%.1f / %s)", n, duri, duru, float64(n)/duri, duru)
}
<commit_msg>bump version<commit_after>// vcfanno is a command-line application and an api for annotating intervals (bed or vcf).
package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	//_ "net/http/pprof"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/biogo/hts/bgzf"
	"github.com/brentp/irelate"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	. "github.com/brentp/vcfanno/api"
	. "github.com/brentp/vcfanno/shared"
	"github.com/brentp/vcfgo"
	"github.com/brentp/xopen"
)

var VERSION = "0.2.7-beta2"

func envGet(name string, vdefault int) int {
	sval := os.Getenv(name)
	var err error
	if sval != "" {
		vdefault, err = strconv.Atoi(sval)
		if err != nil {
			log.Printf("couldn't parse %s using %d\n", name, vdefault)
		} else {
			log.Printf("using %s of %d\n", name, vdefault)
		}
	}
	return vdefault
}

func init() {
	log.SetFlags(log.Lshortfile)
}

func main() {
	fmt.Fprintf(os.Stderr, `
=============================================
vcfanno version %s [built with %s]

see: https://github.com/brentp/vcfanno
=============================================
`, VERSION, runtime.Version())

	ends := flag.Bool("ends", false, "annotate the start and end as well as the interval itself.")
	notstrict := flag.Bool("permissive-overlap", false, "annotate with an overlapping variant even it doesn't"+
		" share the same ref and alt alleles. Default is to require exact match between variants.")
	lua := flag.String("lua", "", "optional path to a file containing custom javascript functions to be used as ops")
	base := flag.String("base-path", "", "optional base-path to prepend to annotation files in the config")
	procs := flag.Int("p", 2, "number of processes to use.")
	flag.Parse()
	inFiles := flag.Args()
	if len(inFiles) != 2 {
		fmt.Printf(`Usage:
%s config.toml input.vcf > annotated.vcf

`, os.Args[0])
		flag.PrintDefaults()
		return
	}
	queryFile := inFiles[1]
	if !(xopen.Exists(queryFile) || queryFile == "") {
		fmt.Fprintf(os.Stderr, "\nERROR: can't find query file: %s\n", queryFile)
		os.Exit(2)
	}
	runtime.GOMAXPROCS(*procs)

	var config Config
	if _, err := toml.DecodeFile(inFiles[0], &config); err != nil {
		if strings.Contains(err.Error(), "Expected value but found") {
			fmt.Fprintln(os.Stderr, "\nNOTE: you must quote values in the conf file, e.g. fields=['AC', 'AN'] instead of fields=[AC, AN]")
		}
		panic(err)
	}
	config.Base = *base
	for _, a := range config.Annotation {
		err := CheckAnno(&a)
		if err != nil {
			log.Fatal("CheckAnno err:", err)
		}
		for _, op := range a.Ops {
			if len(op) > 4 && op[:4] == "lua:" && *lua == "" {
				log.Fatal("ERROR: requested lua op without specifying -lua flag")
			}
		}
	}
	for i := range config.PostAnnotation {
		r := config.PostAnnotation[i]
		err := CheckPostAnno(&r)
		if err != nil {
			log.Fatal(fmt.Sprintf("error in postannotation section %s err: %s", r.Name, err))
		}
		if len(r.Op) > 4 && r.Op[:4] == "lua:" && *lua == "" {
			log.Fatal("ERROR: requested lua op without specifying -lua flag")
		}
	}

	sources, e := config.Sources()
	if e != nil {
		log.Fatal(e)
	}

	log.Printf("found %d sources from %d files\n", len(sources), len(config.Annotation))
	/*
		go func() {
			log.Println(http.ListenAndServe("localhost:6060", nil))
		}()
	*/

	luaString := ReadLua(*lua)
	strict := !*notstrict
	var a = NewAnnotator(sources, luaString, *ends, strict, config.PostAnnotation)

	var out io.Writer = os.Stdout
	defer os.Stdout.Close()

	var err error
	var qrdr io.Reader
	// try to parallelizing reading if we have plenty of CPUs and it's (possibly)
	// a bgzf file.
	if len(config.Annotation) < runtime.GOMAXPROCS(0) && strings.HasSuffix(queryFile, ".gz") {
		if rdr, err := os.Open(queryFile); err == nil {
			if st, err := rdr.Stat(); err == nil && st.Size() > 2320303098 {
				qrdr, err = bgzf.NewReader(rdr, 4)
				if err == nil {
					log.Printf("using 4 worker threads to decompress query file")
				}
			} else {
				qrdr, err = bgzf.NewReader(rdr, 2)
				if err == nil {
					log.Printf("using 2 worker threads to decompress query file")
				}
			}
		}
	}
	if qrdr == nil {
		qrdr, err = xopen.Ropen(queryFile)
	}
	if err != nil {
		log.Fatal(fmt.Errorf("error opening query file %s: %s", queryFile, err))
	}
	qstream, query, err := parsers.VCFIterator(qrdr)
	if err != nil {
		log.Fatal(fmt.Errorf("error parsing VCF query file %s: %s", queryFile, err))
	}

	queryables, err := a.Setup(query)
	if err != nil {
		log.Fatal(err)
	}
	aends := INTERVAL
	if *ends {
		aends = BOTH
	}

	lastMsg := struct {
		sync.RWMutex
		s [10]string
		i int
	}{}

	fn := func(v interfaces.Relatable) {
		e := a.AnnotateEnds(v, aends)
		if e != nil {
			lastMsg.RLock()
			em := e.Error()
			found := false
			for i := len(lastMsg.s) - 1; i >= 0; i-- {
				if em == lastMsg.s[i] {
					found = true
					break
				}
			}
			if !found {
				log.Println(e, ">> this error/warning may occur many times. reporting once here...")
				lastMsg.RUnlock()
				lastMsg.Lock()
				lastMsg.s[lastMsg.i] = em
				if lastMsg.i == len(lastMsg.s)-1 {
					lastMsg.i = -1
				}
				lastMsg.i++

				lastMsg.Unlock()
			} else {
				lastMsg.RUnlock()
			}
		}
	}

	maxGap := envGet("IRELATE_MAX_GAP", 20000)
	maxChunk := envGet("IRELATE_MAX_CHUNK", 8000)

	// make a new writer from the string header.
	out, err = vcfgo.NewWriter(out, query.Header)

	stream := irelate.PIRelate(maxChunk, maxGap, qstream, *ends, fn, queryables...)

	if err != nil {
		log.Fatal(err)
	}

	start := time.Now()
	n := 0

	/*
		if os.Getenv("IRELATE_PROFILE") == "TRUE" {
			log.Println("profiling to: irelate.pprof")
			f, err := os.Create("irelate.pprof")
			if err != nil {
				panic(err)
			}
			pprof.StartCPUProfile(f)
			defer pprof.StopCPUProfile()
		}
	*/

	for interval := range stream {
		//log.Printf("%v\n", interval)
		fmt.Fprintln(out, interval)
		n++
	}
	printTime(start, n)
}

func printTime(start time.Time, n int) {
	dur := time.Since(start)
	duri, duru := dur.Seconds(), "second"
	log.Printf("annotated %d variants in %.2f %ss (%.1f / %s)", n, duri, duru, float64(n)/duri, duru)
}
<|endoftext|>


<commit_before>package wbrules

import (
	"github.com/contactless/wbgo"
	"io/ioutil"
	"os"
	"path"
	"regexp"
	"strings"
)

var editorPathRx = regexp.MustCompile(`^[\w /-]{0,256}[\w -]{1,253}\.js$`)

type Editor struct {
	locFileManager LocFileManager
}

type EditorError struct {
	code    int32
	message string
}

func (err *EditorError) Error() string {
	return err.message
}

func (err *EditorError) ErrorCode() int32 {
	return err.code
}

const (
	// no iota here because these values may be used
	// by external software
	EDITOR_ERROR_INVALID_PATH   = 1000
	EDITOR_ERROR_LISTDIR        = 1001
	EDITOR_ERROR_WRITE          = 1002
	EDITOR_ERROR_FILE_NOT_FOUND = 1003
	EDITOR_ERROR_REMOVE         = 1004
	EDITOR_ERROR_READ           = 1005
	EDITOR_ERROR_RENAME         = 1006
	EDITOR_ERROR_OVERWRITE      = 1007
)

var invalidPathError = &EditorError{EDITOR_ERROR_INVALID_PATH, "Invalid path"}
var listDirError = &EditorError{EDITOR_ERROR_LISTDIR, "Error listing the directory"}
var writeError = &EditorError{EDITOR_ERROR_WRITE, "Error writing the file"}
var fileNotFoundError = &EditorError{EDITOR_ERROR_FILE_NOT_FOUND, "File not found"}
var rmError = &EditorError{EDITOR_ERROR_REMOVE, "Error removing the file"}
var renameError = &EditorError{EDITOR_ERROR_RENAME, "Error renaming the file"}
var readError = &EditorError{EDITOR_ERROR_READ, "Error reading the file"}
var overwriteError = &EditorError{EDITOR_ERROR_OVERWRITE, "New-state file already exists"}

func NewEditor(locFileManager LocFileManager) *Editor {
	return &Editor{locFileManager}
}

func (editor *Editor) List(args *struct{}, reply *[]LocFileEntry) (err error) {
	*reply, err = editor.locFileManager.ListSourceFiles()
	return
}

type EditorSaveArgs struct {
	Path    string `json:"path"`
	Content string `json:"content"`
}

type EditorSaveResponse struct {
	Error     interface{} `json:"error,omitempty",`
	Path      string      `json:"path"`
	Traceback []LocItem   `json:"traceback,omitempty"`
}

func (editor *Editor) Save(args *EditorSaveArgs, reply *EditorSaveResponse) error {
	pth := path.Clean(args.Path)

	for strings.HasPrefix(pth, "/") {
		pth = pth[1:]
	}

	if !editorPathRx.MatchString(pth) {
		return invalidPathError
	}

	*reply = EditorSaveResponse{nil, pth, nil}

	// check if this file already exists and disabled, so update path
	if entry, err := editor.locateFile(pth); err == nil && !entry.Enabled {
		pth = pth + FILE_DISABLED_SUFFIX
	}

	err := editor.locFileManager.LiveWriteScript(pth, args.Content)
	switch err.(type) {
	case nil:
		return nil
	case ScriptError:
		reply.Error = err.Error()
		reply.Traceback = err.(ScriptError).Traceback
	default:
		wbgo.Error.Printf("error writing %s: %s", pth, err)
		return writeError
	}

	return nil
}

type EditorPathArgs struct {
	Path string `json:"path"`
}

func (editor *Editor) locateFile(virtualPath string) (*LocFileEntry, error) {
	entries, err := editor.locFileManager.ListSourceFiles()
	if err != nil {
		return nil, listDirError
	}

	for _, entry := range entries {
		if entry.VirtualPath != virtualPath {
			continue
		}
		return &entry, nil
	}

	return nil, fileNotFoundError
}

func (editor *Editor) Remove(args *EditorPathArgs, reply *bool) error {
	entry, err := editor.locateFile(args.Path)
	if err != nil {
		return err
	}
	if err = os.Remove(entry.PhysicalPath); err != nil {
		wbgo.Error.Printf("error removing %s: %s", entry.PhysicalPath, err)
		return rmError
	}
	*reply = true
	return nil
}

type EditorContentResponse struct {
	Content string       `json:"content"`
	Error   *ScriptError `json:"error,omitempty"`
}

func (editor *Editor) Load(args *EditorPathArgs, reply *EditorContentResponse) error {
	entry, err := editor.locateFile(args.Path)
	if err != nil {
		return err
	}
	content, err := ioutil.ReadFile(entry.PhysicalPath)
	if err != nil {
		wbgo.Error.Printf("error reading %s: %s", entry.PhysicalPath, err)
		return writeError
	}
	*reply = EditorContentResponse{
		string(content),
		entry.Error,
	}
	return nil
}

type EditorChangeStateArgs struct {
	Path  string `json:"path"`
	State bool   `json:"state"`
}

func (editor *Editor) ChangeState(args *EditorChangeStateArgs, reply *bool) error {
	entry, err := editor.locateFile(args.Path)

	if err != nil {
		return err
	}

	*reply = false

	// is state is not changed - just say about it
	if args.State == entry.Enabled {
		return nil
	}

	var newPath string
	// if we need to enable file, remove suffix
	// else add suffix
	if args.State {
		newPath = entry.PhysicalPath[:len(entry.PhysicalPath)-len(FILE_DISABLED_SUFFIX)]
	} else {
		newPath = entry.PhysicalPath + FILE_DISABLED_SUFFIX
	}

	// check overwrite
	if _, err = os.Stat(newPath); !os.IsNotExist(err) {
		wbgo.Error.Printf("can't rename %s to %s: looks like second file exists already, deal with this by yourself!",
			entry.PhysicalPath, newPath)
		return overwriteError
	}

	if err = os.Rename(entry.PhysicalPath, newPath); err != nil {
		wbgo.Error.Printf("error renaming %s to %s: %s", entry.PhysicalPath, newPath, err)
		return renameError
	}

	*reply = true
	return nil
}
<commit_msg>Small go fmt fix<commit_after>package wbrules

import (
	"io/ioutil"
	"os"
	"path"
	"regexp"
	"strings"

	"github.com/contactless/wbgo"
)

var editorPathRx = regexp.MustCompile(`^[\w /-]{0,256}[\w -]{1,253}\.js$`)

type Editor struct {
	locFileManager LocFileManager
}

type EditorError struct {
	code    int32
	message string
}

func (err *EditorError) Error() string {
	return err.message
}

func (err *EditorError) ErrorCode() int32 {
	return err.code
}

const (
	// no iota here because these values may be used
	// by external software
	EDITOR_ERROR_INVALID_PATH   = 1000
	EDITOR_ERROR_LISTDIR        = 1001
	EDITOR_ERROR_WRITE          = 1002
	EDITOR_ERROR_FILE_NOT_FOUND = 1003
	EDITOR_ERROR_REMOVE         = 1004
	EDITOR_ERROR_READ           = 1005
	EDITOR_ERROR_RENAME         = 1006
	EDITOR_ERROR_OVERWRITE      = 1007
)

var invalidPathError = &EditorError{EDITOR_ERROR_INVALID_PATH, "Invalid path"}
var listDirError = &EditorError{EDITOR_ERROR_LISTDIR, "Error listing the directory"}
var writeError = &EditorError{EDITOR_ERROR_WRITE, "Error writing the file"}
var fileNotFoundError = &EditorError{EDITOR_ERROR_FILE_NOT_FOUND, "File not found"}
var rmError = &EditorError{EDITOR_ERROR_REMOVE, "Error removing the file"}
var renameError = &EditorError{EDITOR_ERROR_RENAME, "Error renaming the file"}
var readError = &EditorError{EDITOR_ERROR_READ, "Error reading the file"}
var overwriteError = &EditorError{EDITOR_ERROR_OVERWRITE, "New-state file already exists"}

func NewEditor(locFileManager LocFileManager) *Editor {
	return &Editor{locFileManager}
}

func (editor *Editor) List(args *struct{}, reply *[]LocFileEntry) (err error) {
	*reply, err = editor.locFileManager.ListSourceFiles()
	return
}

type EditorSaveArgs struct {
	Path    string `json:"path"`
	Content string `json:"content"`
}

type EditorSaveResponse struct {
	Error     interface{} `json:"error,omitempty",`
	Path      string      `json:"path"`
	Traceback []LocItem   `json:"traceback,omitempty"`
}

func (editor *Editor) Save(args *EditorSaveArgs, reply *EditorSaveResponse) error {
	pth := path.Clean(args.Path)

	for strings.HasPrefix(pth, "/") {
		pth = pth[1:]
	}

	if !editorPathRx.MatchString(pth) {
		return invalidPathError
	}

	*reply = EditorSaveResponse{nil, pth, nil}

	// check if this file already exists and disabled, so update path
	if entry, err := editor.locateFile(pth); err == nil && !entry.Enabled {
		pth = pth + FILE_DISABLED_SUFFIX
	}

	err := editor.locFileManager.LiveWriteScript(pth, args.Content)
	switch err.(type) {
	case nil:
		return nil
	case ScriptError:
		reply.Error = err.Error()
		reply.Traceback = err.(ScriptError).Traceback
	default:
		wbgo.Error.Printf("error writing %s: %s", pth, err)
		return writeError
	}

	return nil
}

type EditorPathArgs struct {
	Path string `json:"path"`
}

func (editor *Editor) locateFile(virtualPath string) (*LocFileEntry, error) {
	entries, err := editor.locFileManager.ListSourceFiles()
	if err != nil {
		return nil, listDirError
	}

	for _, entry := range entries {
		if entry.VirtualPath != virtualPath {
			continue
		}
		return &entry, nil
	}

	return nil, fileNotFoundError
}

func (editor *Editor) Remove(args *EditorPathArgs, reply *bool) error {
	entry, err := editor.locateFile(args.Path)
	if err != nil {
		return err
	}
	if err = os.Remove(entry.PhysicalPath); err != nil {
		wbgo.Error.Printf("error removing %s: %s", entry.PhysicalPath, err)
		return rmError
	}
	*reply = true
	return nil
}

type EditorContentResponse struct {
	Content string       `json:"content"`
	Error   *ScriptError `json:"error,omitempty"`
}

func (editor *Editor) Load(args *EditorPathArgs, reply *EditorContentResponse) error {
	entry, err := editor.locateFile(args.Path)
	if err != nil {
		return err
	}
	content, err := ioutil.ReadFile(entry.PhysicalPath)
	if err != nil {
		wbgo.Error.Printf("error reading %s: %s", entry.PhysicalPath, err)
		return writeError
	}
	*reply = EditorContentResponse{
		string(content),
		entry.Error,
	}
	return nil
}

type EditorChangeStateArgs struct {
	Path  string `json:"path"`
	State bool   `json:"state"`
}

func (editor *Editor) ChangeState(args *EditorChangeStateArgs, reply *bool) error {
	entry, err := editor.locateFile(args.Path)

	if err != nil {
		return err
	}

	*reply = false

	// is state is not changed - just say about it
	if args.State == entry.Enabled {
		return nil
	}

	var newPath string
	// if we need to enable file, remove suffix
	// else add suffix
	if args.State {
		newPath = entry.PhysicalPath[:len(entry.PhysicalPath)-len(FILE_DISABLED_SUFFIX)]
	} else {
		newPath = entry.PhysicalPath + FILE_DISABLED_SUFFIX
	}

	// check overwrite
	if _, err = os.Stat(newPath); !os.IsNotExist(err) {
		wbgo.Error.Printf("can't rename %s to %s: looks like second file exists already, deal with this by yourself!",
			entry.PhysicalPath, newPath)
		return overwriteError
	}

	if err = os.Rename(entry.PhysicalPath, newPath); err != nil {
		wbgo.Error.Printf("error renaming %s to %s: %s", entry.PhysicalPath, newPath, err)
		return renameError
	}

	*reply = true
	return nil
}
<|endoftext|>


<commit_before>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "48"
)
<commit_msg>Bump asset version<commit_after>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "49"
)
<|endoftext|>


<commit_before>package amino

// Version
const Version = "0.9.11"
<commit_msg>bump version<commit_after>package amino

// Version
const Version = "0.10.0-rc2"
<|endoftext|>


<commit_before>package main

const VERSION = "0.5.0-alpha1"
<commit_msg>:+1: Bump up the version<commit_after>package main

const VERSION = "0.5.0-alpha2"
<|endoftext|>


<commit_before>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string

// The main version number that is being run at the moment.
const Version = "0.3.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = ""
<commit_msg>agent: update version until we release<commit_after>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string

// The main version number that is being run at the moment.
const Version = "0.4.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "pre"
<|endoftext|>


<commit_before>package main

func versionString() string {
	return "get 0.0.1"
}
<commit_msg>Version 0.0.2<commit_after>package main

func versionString() string {
	return "get 0.0.2"
}
<|endoftext|>


<commit_before>package main

import "github.com/tsaikd/KDGoLib/version"

func init() {
	version.VERSION = "0.0.12"
}
<commit_msg>0.0.13<commit_after>package main

import "github.com/tsaikd/KDGoLib/version"

func init() {
	version.VERSION = "0.0.13"
}
<|endoftext|>


<commit_before>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2021

package instana

// Version is the version of Instana sensor
const Version = "1.30.0"
<commit_msg>Bump version to v1.30.1<commit_after>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2021

package instana

// Version is the version of Instana sensor
const Version = "1.30.1"
<|endoftext|>


<commit_before>package main

import "runtime"

// The current version of chef-runner. A ".dev" suffix denotes that the version
// is currently being developed.
const Version = "v0.7.0"

// GitVersion is the Git version that is being compiled. This string contains
// tag and commit information. It will be filled in by the compiler.
var GitVersion string

// VersionString returns the current program version, which is either the Git
// version if available or the static version defined above.
func VersionString() string {
	if GitVersion != "" {
		return GitVersion
	}
	return Version
}

// TargetString returns the target operating system and architecture.
func TargetString() string {
	return runtime.GOOS + "/" + runtime.GOARCH
}
<commit_msg>Start development of v0.8.0<commit_after>package main

import "runtime"

// The current version of chef-runner. A ".dev" suffix denotes that the version
// is currently being developed.
const Version = "v0.8.0.dev"

// GitVersion is the Git version that is being compiled. This string contains
// tag and commit information. It will be filled in by the compiler.
var GitVersion string

// VersionString returns the current program version, which is either the Git
// version if available or the static version defined above.
func VersionString() string {
	if GitVersion != "" {
		return GitVersion
	}
	return Version
}

// TargetString returns the target operating system and architecture.
func TargetString() string {
	return runtime.GOOS + "/" + runtime.GOARCH
}
<|endoftext|>


<commit_before>package superast

import (
	"go/ast"
	"go/token"
	"log"
	"strconv"
	"strings"
)

const (
	Default = iota
	IfBody
	IfElse
	FuncBody
)

type AST struct {
	curID      int
	RootBlock  *block
	nodeStack  []ast.Node
	stmtsStack []*[]stmt
	fset       *token.FileSet
	pos        token.Pos
	status     int
}

func NewAST(fset *token.FileSet) *AST {
	a := &AST{
		fset: fset,
	}
	a.RootBlock = &block{
		id:    a.newID(),
		Stmts: make([]stmt, 0),
	}
	a.pushStmts(&a.RootBlock.Stmts)
	return a
}

func (a *AST) newID() id {
	i := a.curID
	a.curID++
	return id{ID: i}
}

func (a *AST) newPos(p token.Pos) pos {
	position := a.fset.Position(p)
	return pos{Line: position.Line, Col: position.Column}
}

func (a *AST) nodePos(n ast.Node) pos {
	return a.newPos(n.Pos())
}

func (a *AST) curPos() pos {
	return a.newPos(a.pos)
}

func (a *AST) pushNode(node ast.Node) {
	a.nodeStack = append(a.nodeStack, node)
}

func (a *AST) curNode() ast.Node {
	return a.nodeStack[len(a.nodeStack)-1]
}

func (a *AST) popNode() {
	a.nodeStack = a.nodeStack[:len(a.nodeStack)-1]
}

func (a *AST) pushStmts(stmts *[]stmt) {
	a.stmtsStack = append(a.stmtsStack, stmts)
}

func (a *AST) curStmts() *[]stmt {
	return a.stmtsStack[len(a.stmtsStack)-1]
}

func (a *AST) addStmt(s stmt) {
	curStmts := a.curStmts()
	*curStmts = append(*curStmts, s)
}

func (a *AST) popStmts() {
	a.stmtsStack = a.stmtsStack[:len(a.stmtsStack)-1]
}

func exprString(x ast.Expr) string {
	switch t := x.(type) {
	case *ast.Ident:
		return t.Name
	case *ast.BasicLit:
		return t.Value
	case *ast.SelectorExpr:
		return exprString(t.X) + "." + t.Sel.Name
	case *ast.StarExpr:
		return exprString(t.X)
	}
	return ""
}

func exprValue(x ast.Expr) value {
	switch t := x.(type) {
	case *ast.BasicLit:
		switch t.Kind {
		case token.INT:
			i, _ := strconv.ParseInt(t.Value, 10, 0)
			return i
		case token.FLOAT:
			f, _ := strconv.ParseFloat(t.Value, 64)
			return f
		case token.CHAR:
			r, _, _, _ := strconv.UnquoteChar(t.Value, '\'')
			return r
		case token.STRING:
			s, _ := strconv.Unquote(t.Value)
			return s
		}
		return t.Value
	}
	return nil
}

func exprType(x ast.Expr) *dataType {
	if s := exprString(x); s != "" {
		return &dataType{
			Name: s,
		}
	}
	switch t := x.(type) {
	case *ast.ArrayType:
		return &dataType{
			Name:    "vector",
			SubType: exprType(t.Elt),
		}
	}
	return nil
}

type namedType struct {
	vName string
	dType *dataType
	node  ast.Node
}

func flattenNames(baseType ast.Expr, names []*ast.Ident) []namedType {
	t := exprType(baseType)
	if len(names) == 0 {
		return []namedType{
			{vName: "", dType: t},
		}
	}
	var types []namedType
	for _, n := range names {
		types = append(types, namedType{
			vName: n.Name,
			dType: t,
			node:  n,
		})
	}
	return types
}

func flattenFieldList(fieldList *ast.FieldList) []namedType {
	if fieldList == nil {
		return nil
	}
	var types []namedType
	for _, f := range fieldList.List {
		for _, t := range flattenNames(f.Type, f.Names) {
			types = append(types, t)
		}
	}
	return types
}

var basicLitName = map[token.Token]string{
	token.INT:    "int",
	token.FLOAT:  "double",
	token.CHAR:   "char",
	token.STRING: "string",
}

var zeroValues = map[string]value{
	"int":    0,
	"double": 0.0,
	"char":   '\x00',
	"string": "",
}

func (a *AST) parseExpr(expr ast.Expr) expr {
	switch x := expr.(type) {
	case *ast.Ident:
		return &identifier{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  "identifier",
			Value: x.Name,
		}
	case *ast.BasicLit:
		lType, _ := basicLitName[x.Kind]
		return &identifier{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  lType,
			Value: exprValue(x),
		}
	case *ast.UnaryExpr:
		return &unary{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: x.Op.String(),
			Expr: a.parseExpr(x.X),
		}
	case *ast.CallExpr:
		call := &funcCall{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: "function-call",
			Name: exprString(x.Fun),
		}
		for _, e := range x.Args {
			call.Args = append(call.Args, a.parseExpr(e))
		}
		return call
	case *ast.BinaryExpr:
		return &binary{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  x.Op.String(),
			Left:  a.parseExpr(x.X),
			Right: a.parseExpr(x.Y),
		}
	case *ast.ParenExpr:
		return a.parseExpr(x.X)
	}
	return nil
}

func (a *AST) assignIdToDataType(dType *dataType) *dataType {
	if dType == nil {
		return nil
	}
	dTypeCopy := *dType
	dTypeCopy.id = a.newID()
	if dTypeCopy.SubType != nil {
		dTypeCopy.SubType = a.assignIdToDataType(dTypeCopy.SubType)
	}
	return &dTypeCopy
}

func (a *AST) Visit(node ast.Node) ast.Visitor {
	if node == nil {
		switch a.curNode().(type) {
		case *ast.BlockStmt:
			a.popStmts()
		}
		a.popNode()
		return nil
	}
	a.pos = node.Pos()
	log.Printf("%s%#v", strings.Repeat("  ", len(a.nodeStack)), node)
	switch x := node.(type) {
	case *ast.TypeSpec:
		n := ""
		if x.Name != nil {
			n = exprString(x.Name)
		}
		switch t := x.Type.(type) {
		case *ast.StructType:
			decl := &structDecl{
				id:   a.newID(),
				pos:  a.curPos(),
				Type: "struct-declaration",
				Name: n,
			}
			for _, f := range flattenFieldList(t.Fields) {
				attr := varDecl{
					id:       a.newID(),
					pos:      a.curPos(),
					Type:     "variable-declaration",
					Name:     f.vName,
					DataType: a.assignIdToDataType(f.dType),
				}
				decl.Attrs = append(decl.Attrs, attr)
			}
			a.addStmt(decl)
		}
	case *ast.BasicLit:
		lit := a.parseExpr(x)
		a.addStmt(lit)
	case *ast.UnaryExpr:
		unary := a.parseExpr(x)
		a.addStmt(unary)
		return nil
	case *ast.CallExpr:
		call := a.parseExpr(x)
		a.addStmt(call)
		return nil
	case *ast.FuncDecl:
		name := x.Name.Name
		var retType *dataType
		results := flattenFieldList(x.Type.Results)
		switch len(results) {
		case 1:
			retType = results[0].dType
		}
		fn := &funcDecl{
			id:      a.newID(),
			pos:     a.nodePos(x),
			Type:    "function-declaration",
			Name:    name,
			RetType: a.assignIdToDataType(retType),
			Block: &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			},
		}
		for _, f := range flattenFieldList(x.Type.Params) {
			param := varDecl{
				id:       a.newID(),
				pos:      a.nodePos(f.node),
				Type:     "variable-declaration",
				Name:     f.vName,
				DataType: a.assignIdToDataType(f.dType),
			}
			fn.Params = append(fn.Params, param)
		}
		a.addStmt(fn)
		a.pushStmts(&fn.Block.Stmts)
	case *ast.DeclStmt:
		gd, _ := x.Decl.(*ast.GenDecl)
		for _, spec := range gd.Specs {
			s, ok := spec.(*ast.ValueSpec)
			if !ok {
				continue
			}
			for i, t := range flattenNames(s.Type, s.Names) {
				vType := t.dType.Name
				v, _ := zeroValues[vType]
				if s.Values != nil {
					v = exprValue(s.Values[i])
				}
				decl := &varDecl{
					id:       a.newID(),
					pos:      a.curPos(),
					Type:     "variable-declaration",
					Name:     t.vName,
					DataType: a.assignIdToDataType(t.dType),
					Init: &identifier{
						id:    a.newID(),
						pos:   a.curPos(),
						Type:  vType,
						Value: v,
					},
				}
				a.addStmt(decl)
			}
		}
	case *ast.AssignStmt:
		for i, l := range x.Lhs {
			r := x.Rhs[i]
			var t string
			switch rx := r.(type) {
			case *ast.BasicLit:
				t, _ = basicLitName[rx.Kind]
			case *ast.CompositeLit:
				t = exprString(rx.Type)
			}
			var s stmt
			if x.Tok == token.DEFINE {
				s = &varDecl{
					id:   a.newID(),
					pos:  a.curPos(),
					Type: "variable-declaration",
					Name: exprString(l),
					DataType: &dataType{
						id:   a.newID(),
						Name: t,
					},
					Init: a.parseExpr(r),
				}
			} else {
				s = &binary{
					id:    a.newID(),
					pos:   a.curPos(),
					Type:  x.Tok.String(),
					Left:  a.parseExpr(l),
					Right: a.parseExpr(r),
				}
			}
			a.addStmt(s)
		}
		return nil
	case *ast.IfStmt:
		cond := &conditional{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: "conditional",
			Cond: a.parseExpr(x.Cond),
			Then: &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			},
		}
		a.addStmt(cond)
		if x.Else != nil {
			cond.Else = &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			}
			a.pushStmts(&cond.Else.Stmts)
			a.pushNode(node)
		}
		a.pushStmts(&cond.Then.Stmts)
	case *ast.File:
	case *ast.BlockStmt:
	case *ast.ExprStmt:
	case *ast.GenDecl:
	default:
		return nil
	}
	a.pushNode(node)
	return a
}
<commit_msg>Warn about untreated expressions<commit_after>package superast

import (
	"go/ast"
	"go/token"
	"log"
	"strconv"
	"strings"
)

const (
	Default = iota
	IfBody
	IfElse
	FuncBody
)

type AST struct {
	curID      int
	RootBlock  *block
	nodeStack  []ast.Node
	stmtsStack []*[]stmt
	fset       *token.FileSet
	pos        token.Pos
	status     int
}

func NewAST(fset *token.FileSet) *AST {
	a := &AST{
		fset: fset,
	}
	a.RootBlock = &block{
		id:    a.newID(),
		Stmts: make([]stmt, 0),
	}
	a.pushStmts(&a.RootBlock.Stmts)
	return a
}

func (a *AST) newID() id {
	i := a.curID
	a.curID++
	return id{ID: i}
}

func (a *AST) newPos(p token.Pos) pos {
	position := a.fset.Position(p)
	return pos{Line: position.Line, Col: position.Column}
}

func (a *AST) nodePos(n ast.Node) pos {
	return a.newPos(n.Pos())
}

func (a *AST) curPos() pos {
	return a.newPos(a.pos)
}

func (a *AST) pushNode(node ast.Node) {
	a.nodeStack = append(a.nodeStack, node)
}

func (a *AST) curNode() ast.Node {
	return a.nodeStack[len(a.nodeStack)-1]
}

func (a *AST) popNode() {
	a.nodeStack = a.nodeStack[:len(a.nodeStack)-1]
}

func (a *AST) pushStmts(stmts *[]stmt) {
	a.stmtsStack = append(a.stmtsStack, stmts)
}

func (a *AST) curStmts() *[]stmt {
	return a.stmtsStack[len(a.stmtsStack)-1]
}

func (a *AST) addStmt(s stmt) {
	curStmts := a.curStmts()
	*curStmts = append(*curStmts, s)
}

func (a *AST) popStmts() {
	a.stmtsStack = a.stmtsStack[:len(a.stmtsStack)-1]
}

func exprString(x ast.Expr) string {
	switch t := x.(type) {
	case *ast.Ident:
		return t.Name
	case *ast.BasicLit:
		return t.Value
	case *ast.SelectorExpr:
		return exprString(t.X) + "." + t.Sel.Name
	case *ast.StarExpr:
		return exprString(t.X)
	}
	return ""
}

func exprValue(x ast.Expr) value {
	switch t := x.(type) {
	case *ast.BasicLit:
		switch t.Kind {
		case token.INT:
			i, _ := strconv.ParseInt(t.Value, 10, 0)
			return i
		case token.FLOAT:
			f, _ := strconv.ParseFloat(t.Value, 64)
			return f
		case token.CHAR:
			r, _, _, _ := strconv.UnquoteChar(t.Value, '\'')
			return r
		case token.STRING:
			s, _ := strconv.Unquote(t.Value)
			return s
		}
		return t.Value
	}
	return nil
}

func exprType(x ast.Expr) *dataType {
	if s := exprString(x); s != "" {
		return &dataType{
			Name: s,
		}
	}
	switch t := x.(type) {
	case *ast.ArrayType:
		return &dataType{
			Name:    "vector",
			SubType: exprType(t.Elt),
		}
	}
	return nil
}

type namedType struct {
	vName string
	dType *dataType
	node  ast.Node
}

func flattenNames(baseType ast.Expr, names []*ast.Ident) []namedType {
	t := exprType(baseType)
	if len(names) == 0 {
		return []namedType{
			{vName: "", dType: t},
		}
	}
	var types []namedType
	for _, n := range names {
		types = append(types, namedType{
			vName: n.Name,
			dType: t,
			node:  n,
		})
	}
	return types
}

func flattenFieldList(fieldList *ast.FieldList) []namedType {
	if fieldList == nil {
		return nil
	}
	var types []namedType
	for _, f := range fieldList.List {
		for _, t := range flattenNames(f.Type, f.Names) {
			types = append(types, t)
		}
	}
	return types
}

var basicLitName = map[token.Token]string{
	token.INT:    "int",
	token.FLOAT:  "double",
	token.CHAR:   "char",
	token.STRING: "string",
}

var zeroValues = map[string]value{
	"int":    0,
	"double": 0.0,
	"char":   '\x00',
	"string": "",
}

func (a *AST) parseExpr(expr ast.Expr) expr {
	switch x := expr.(type) {
	case *ast.Ident:
		return &identifier{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  "identifier",
			Value: x.Name,
		}
	case *ast.BasicLit:
		lType, _ := basicLitName[x.Kind]
		return &identifier{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  lType,
			Value: exprValue(x),
		}
	case *ast.UnaryExpr:
		return &unary{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: x.Op.String(),
			Expr: a.parseExpr(x.X),
		}
	case *ast.CallExpr:
		call := &funcCall{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: "function-call",
			Name: exprString(x.Fun),
		}
		for _, e := range x.Args {
			call.Args = append(call.Args, a.parseExpr(e))
		}
		return call
	case *ast.BinaryExpr:
		return &binary{
			id:    a.newID(),
			pos:   a.nodePos(x),
			Type:  x.Op.String(),
			Left:  a.parseExpr(x.X),
			Right: a.parseExpr(x.Y),
		}
	case *ast.ParenExpr:
		return a.parseExpr(x.X)
	default:
		log.Printf("Unknown expression: %#v", x)
	}
	return nil
}

func (a *AST) assignIdToDataType(dType *dataType) *dataType {
	if dType == nil {
		return nil
	}
	dTypeCopy := *dType
	dTypeCopy.id = a.newID()
	if dTypeCopy.SubType != nil {
		dTypeCopy.SubType = a.assignIdToDataType(dTypeCopy.SubType)
	}
	return &dTypeCopy
}

func (a *AST) Visit(node ast.Node) ast.Visitor {
	if node == nil {
		switch a.curNode().(type) {
		case *ast.BlockStmt:
			a.popStmts()
		}
		a.popNode()
		return nil
	}
	a.pos = node.Pos()
	log.Printf("%s%#v", strings.Repeat("  ", len(a.nodeStack)), node)
	switch x := node.(type) {
	case *ast.TypeSpec:
		n := ""
		if x.Name != nil {
			n = exprString(x.Name)
		}
		switch t := x.Type.(type) {
		case *ast.StructType:
			decl := &structDecl{
				id:   a.newID(),
				pos:  a.curPos(),
				Type: "struct-declaration",
				Name: n,
			}
			for _, f := range flattenFieldList(t.Fields) {
				attr := varDecl{
					id:       a.newID(),
					pos:      a.curPos(),
					Type:     "variable-declaration",
					Name:     f.vName,
					DataType: a.assignIdToDataType(f.dType),
				}
				decl.Attrs = append(decl.Attrs, attr)
			}
			a.addStmt(decl)
		}
	case *ast.BasicLit:
		lit := a.parseExpr(x)
		a.addStmt(lit)
	case *ast.UnaryExpr:
		unary := a.parseExpr(x)
		a.addStmt(unary)
		return nil
	case *ast.CallExpr:
		call := a.parseExpr(x)
		a.addStmt(call)
		return nil
	case *ast.FuncDecl:
		name := x.Name.Name
		var retType *dataType
		results := flattenFieldList(x.Type.Results)
		switch len(results) {
		case 1:
			retType = results[0].dType
		}
		fn := &funcDecl{
			id:      a.newID(),
			pos:     a.nodePos(x),
			Type:    "function-declaration",
			Name:    name,
			RetType: a.assignIdToDataType(retType),
			Block: &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			},
		}
		for _, f := range flattenFieldList(x.Type.Params) {
			param := varDecl{
				id:       a.newID(),
				pos:      a.nodePos(f.node),
				Type:     "variable-declaration",
				Name:     f.vName,
				DataType: a.assignIdToDataType(f.dType),
			}
			fn.Params = append(fn.Params, param)
		}
		a.addStmt(fn)
		a.pushStmts(&fn.Block.Stmts)
	case *ast.DeclStmt:
		gd, _ := x.Decl.(*ast.GenDecl)
		for _, spec := range gd.Specs {
			s, ok := spec.(*ast.ValueSpec)
			if !ok {
				continue
			}
			for i, t := range flattenNames(s.Type, s.Names) {
				vType := t.dType.Name
				v, _ := zeroValues[vType]
				if s.Values != nil {
					v = exprValue(s.Values[i])
				}
				decl := &varDecl{
					id:       a.newID(),
					pos:      a.curPos(),
					Type:     "variable-declaration",
					Name:     t.vName,
					DataType: a.assignIdToDataType(t.dType),
					Init: &identifier{
						id:    a.newID(),
						pos:   a.curPos(),
						Type:  vType,
						Value: v,
					},
				}
				a.addStmt(decl)
			}
		}
	case *ast.AssignStmt:
		for i, l := range x.Lhs {
			r := x.Rhs[i]
			var t string
			switch rx := r.(type) {
			case *ast.BasicLit:
				t, _ = basicLitName[rx.Kind]
			case *ast.CompositeLit:
				t = exprString(rx.Type)
			}
			var s stmt
			if x.Tok == token.DEFINE {
				s = &varDecl{
					id:   a.newID(),
					pos:  a.curPos(),
					Type: "variable-declaration",
					Name: exprString(l),
					DataType: &dataType{
						id:   a.newID(),
						Name: t,
					},
					Init: a.parseExpr(r),
				}
			} else {
				s = &binary{
					id:    a.newID(),
					pos:   a.curPos(),
					Type:  x.Tok.String(),
					Left:  a.parseExpr(l),
					Right: a.parseExpr(r),
				}
			}
			a.addStmt(s)
		}
		return nil
	case *ast.IfStmt:
		cond := &conditional{
			id:   a.newID(),
			pos:  a.nodePos(x),
			Type: "conditional",
			Cond: a.parseExpr(x.Cond),
			Then: &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			},
		}
		a.addStmt(cond)
		if x.Else != nil {
			cond.Else = &block{
				id:    a.newID(),
				Stmts: make([]stmt, 0),
			}
			a.pushStmts(&cond.Else.Stmts)
			a.pushNode(node)
		}
		a.pushStmts(&cond.Then.Stmts)
	case *ast.File:
	case *ast.BlockStmt:
	case *ast.ExprStmt:
	case *ast.GenDecl:
	default:
		return nil
	}
	a.pushNode(node)
	return a
}
<|endoftext|>


<commit_before>package vunikbd

import (
	"fmt"
	"time"

	"github.com/bendahl/uinput"
)

type Keyboard struct {
	name  string
	delay time.Duration
	vk    uinput.Keyboard
}

func NewKeyboard(name string, delay time.Duration) (*Keyboard, error) {
	var err error

	k := Keyboard{
		name:  name,
		delay: delay,
	}

	k.vk, err = uinput.CreateKeyboard("/dev/uinput", k.name)

	return &k, err
}

func (k *Keyboard) TypeRune(r rune) {
	h := fmt.Sprintf("%x\n", r)

	k.vk.SendKeyPress(uinput.KEY_LEFTCTRL)
	k.sleep()
	k.vk.SendKeyPress(uinput.KEY_LEFTSHIFT)
	k.sleep()
	k.vk.SendKeyPress(uinput.KEY_U)
	k.sleep()
	k.vk.SendKeyRelease(uinput.KEY_U)
	k.sleep()

	for _, v := range h {
		k.vk.SendKeyPress(keycodes[v])
		k.sleep()
		k.vk.SendKeyRelease(keycodes[v])
		k.sleep()
	}

	k.vk.SendKeyRelease(uinput.KEY_LEFTCTRL)
	k.sleep()
	k.vk.SendKeyRelease(uinput.KEY_LEFTSHIFT)
	k.sleep()
}

func (k *Keyboard) TypeString(s string) {
	for _, r := range s {
		k.TypeRune(r)
	}
}

func (k *Keyboard) sleep() {
	time.Sleep(k.delay)
}

var keycodes map[rune]int

func init() {
	keycodes = make(map[rune]int)
	keycodes['0'] = uinput.KEY_KP0
	keycodes['1'] = uinput.KEY_KP1
	keycodes['2'] = uinput.KEY_KP2
	keycodes['3'] = uinput.KEY_KP3
	keycodes['4'] = uinput.KEY_KP4
	keycodes['5'] = uinput.KEY_KP5
	keycodes['6'] = uinput.KEY_KP6
	keycodes['7'] = uinput.KEY_KP7
	keycodes['8'] = uinput.KEY_KP8
	keycodes['9'] = uinput.KEY_KP9
	keycodes['a'] = uinput.KEY_A
	keycodes['b'] = uinput.KEY_B
	keycodes['c'] = uinput.KEY_C
	keycodes['d'] = uinput.KEY_D
	keycodes['e'] = uinput.KEY_E
	keycodes['f'] = uinput.KEY_F
}
<commit_msg>Use normal numeric keys instead of keypad It is needed for Wayland compatibility<commit_after>package vunikbd

import (
	"fmt"
	"time"

	"github.com/bendahl/uinput"
)

type Keyboard struct {
	name  string
	delay time.Duration
	vk    uinput.Keyboard
}

func NewKeyboard(name string, delay time.Duration) (*Keyboard, error) {
	var err error

	k := Keyboard{
		name:  name,
		delay: delay,
	}

	k.vk, err = uinput.CreateKeyboard("/dev/uinput", k.name)

	return &k, err
}

func (k *Keyboard) TypeRune(r rune) {
	h := fmt.Sprintf("%x\n", r)

	k.vk.SendKeyPress(uinput.KEY_LEFTCTRL)
	k.sleep()
	k.vk.SendKeyPress(uinput.KEY_LEFTSHIFT)
	k.sleep()
	k.vk.SendKeyPress(uinput.KEY_U)
	k.sleep()
	k.vk.SendKeyRelease(uinput.KEY_U)
	k.sleep()

	for _, v := range h {
		k.vk.SendKeyPress(keycodes[v])
		k.sleep()
		k.vk.SendKeyRelease(keycodes[v])
		k.sleep()
	}

	k.vk.SendKeyRelease(uinput.KEY_LEFTCTRL)
	k.sleep()
	k.vk.SendKeyRelease(uinput.KEY_LEFTSHIFT)
	k.sleep()
}

func (k *Keyboard) TypeString(s string) {
	for _, r := range s {
		k.TypeRune(r)
	}
}

func (k *Keyboard) sleep() {
	time.Sleep(k.delay)
}

var keycodes map[rune]int

func init() {
	keycodes = make(map[rune]int)
	keycodes['0'] = uinput.KEY_0
	keycodes['1'] = uinput.KEY_1
	keycodes['2'] = uinput.KEY_2
	keycodes['3'] = uinput.KEY_3
	keycodes['4'] = uinput.KEY_4
	keycodes['5'] = uinput.KEY_5
	keycodes['6'] = uinput.KEY_6
	keycodes['7'] = uinput.KEY_7
	keycodes['8'] = uinput.KEY_8
	keycodes['9'] = uinput.KEY_9
	keycodes['a'] = uinput.KEY_A
	keycodes['b'] = uinput.KEY_B
	keycodes['c'] = uinput.KEY_C
	keycodes['d'] = uinput.KEY_D
	keycodes['e'] = uinput.KEY_E
	keycodes['f'] = uinput.KEY_F
}
<|endoftext|>