mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-03 13:21:56 +02:00
Fixed circleci build
This commit is contained in:
parent
959d6fa2ca
commit
87d1b9a547
@ -3,6 +3,7 @@
|
||||
package commands
|
||||
|
||||
// RunCommandWithOutputLiveWrapper runs a command live but because of windows compatibility this command can't be ran there
|
||||
// TODO: Remove this hack and replace it with a propper way to run commands live on windows
|
||||
func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(string) string) error {
|
||||
return c.RunCommand(command)
|
||||
}
|
||||
|
30
vendor/github.com/ionrock/procs/Gopkg.toml
generated
vendored
Normal file
30
vendor/github.com/ionrock/procs/Gopkg.toml
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/apoydence/onpar"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/flynn/go-shlex"
|
13
vendor/github.com/ionrock/procs/LICENSE.md
generated
vendored
Normal file
13
vendor/github.com/ionrock/procs/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright 2017 Eric Larson <eric@ionrock.org>
|
||||
|
||||
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.
|
32
vendor/github.com/ionrock/procs/Makefile
generated
vendored
Normal file
32
vendor/github.com/ionrock/procs/Makefile
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
SOURCEDIR=.
|
||||
SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
|
||||
|
||||
test: dep
|
||||
dep ensure
|
||||
go test .
|
||||
|
||||
race: dep
|
||||
dep ensure
|
||||
go test -race .
|
||||
|
||||
|
||||
dep:
|
||||
ifeq (, $(shell which dep))
|
||||
go get -u github.com/golang/dep/cmd/dep
|
||||
endif
|
||||
|
||||
all: prelog cmdtmpl procmon
|
||||
|
||||
prelog: $(SOURCES)
|
||||
go build ./cmd/prelog
|
||||
|
||||
cmdtmpl: $(SOURCES)
|
||||
go build ./cmd/cmdtmpl
|
||||
|
||||
procmon: $(SOURCES)
|
||||
go build ./cmd/procmon
|
||||
|
||||
clean:
|
||||
rm -f prelog
|
||||
rm -f cmdtmpl
|
||||
rm -f procmon
|
168
vendor/github.com/ionrock/procs/README.md
generated
vendored
Normal file
168
vendor/github.com/ionrock/procs/README.md
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
# Procs
|
||||
|
||||
[![](https://travis-ci.org/ionrock/procs.svg?branch=master)](https://travis-ci.org/ionrock/procs)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/ionrock/procs)](https://goreportcard.com/report/github.com/ionrock/procs)
|
||||
[![GoDoc](https://godoc.org/github.com/ionrock/procs?status.svg)](https://godoc.org/github.com/ionrock/procs)
|
||||
|
||||
Procs is a library to make working with command line applications a
|
||||
little nicer.
|
||||
|
||||
The primary use case is when you have to use a command line client in
|
||||
place of an API. Often times you want to do things like output stdout
|
||||
within your own logs or ensure that every time the command is called,
|
||||
there are a standard set of flags that are used.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
The majority of this functionality is intended to be included the
|
||||
procs.Process.
|
||||
|
||||
### Defining a Command
|
||||
|
||||
A command can be defined by a string rather than a []string. Normally,
|
||||
this also implies that the library will run the command in a shell,
|
||||
exposing a potential man in the middle attack. Rather than using a
|
||||
shell, procs [lexically
|
||||
parses](https://github.com/flynn-archive/go-shlex) the command for the
|
||||
different arguments. It also allows for pipes in order to string
|
||||
commands together.
|
||||
|
||||
```go
|
||||
p := procs.NewProcess("kubectl get events | grep dev")
|
||||
```
|
||||
|
||||
You can also define a new `Process` by passing in predefined commands.
|
||||
|
||||
```go
|
||||
cmds := []*exec.Cmd{
|
||||
exec.Command("kubectl", "get", "events"),
|
||||
exec.Command("grep", "dev"),
|
||||
}
|
||||
|
||||
p := procs.Process{Cmds: cmds}
|
||||
```
|
||||
|
||||
### Output Handling
|
||||
|
||||
One use case that is cumbersome is using the piped output from a
|
||||
command. For example, lets say we wanted to start a couple commands
|
||||
and have each command have its own prefix in stdout, while still
|
||||
capturing the output of the command as-is.
|
||||
|
||||
```go
|
||||
p := procs.NewProcess("cmd1")
|
||||
p.OutputHandler = func(line string) string {
|
||||
fmt.Printf("cmd1 | %s\n")
|
||||
return line
|
||||
}
|
||||
out, _ := p.Run()
|
||||
fmt.Println(out)
|
||||
```
|
||||
|
||||
Whatever is returned from the `OutputHandler` will be in the buffered
|
||||
output. In this way you can choose to filter or skip output buffering
|
||||
completely.
|
||||
|
||||
You can also define a `ErrHandler` using the same signature to get the
|
||||
same filtering for stderr.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Rather than use the `exec.Cmd` `[]string` environment variables, a
|
||||
`procs.Process` uses a `map[string]string` for environment variables.
|
||||
|
||||
```go
|
||||
p := procs.NewProcess("echo $FOO")
|
||||
p.Env = map[string]string{"FOO": "foo"}
|
||||
```
|
||||
|
||||
Also, environment variables defined by the `Process.Env` can be
|
||||
expanded automatically using the `os.Expand` semantics and the
|
||||
provided environment.
|
||||
|
||||
There is a `ParseEnv` function that can help to merge the parent
|
||||
processes' environment with any new values.
|
||||
|
||||
```go
|
||||
env := ParseEnv(os.Environ())
|
||||
env["USER"] = "foo"
|
||||
```
|
||||
|
||||
Finally, if you are building commands manually, the `Env` function can
|
||||
take a `map[string]string` and convert it to a `[]string` for use with
|
||||
an `exec.Cmd`. The `Env` function also accepts a `useEnv` bool to help
|
||||
include the parent process environment.
|
||||
|
||||
```go
|
||||
cmd := exec.Command("knife", "cookbook", "show", cb)
|
||||
cmd.Env = Env(map[string]string{"USER": "knife-user"}, true)
|
||||
```
|
||||
|
||||
## Example Applications
|
||||
|
||||
Take a look in the [`cmd`](./cmd/) dir for some simple applications
|
||||
that use the library. You can also `make all` to build them. The
|
||||
examples below assume you've built them locally.
|
||||
|
||||
### Prelog
|
||||
|
||||
The `prelog` command allows running a command and prefixing the output
|
||||
with a value.
|
||||
|
||||
```bash
|
||||
$ ./prelog -prefix foo -- echo 'hello world!'
|
||||
Running the command
|
||||
foo | hello world!
|
||||
Accessing the output without a prefix.
|
||||
hello world!
|
||||
Running the command with Start / Wait
|
||||
foo | hello world!
|
||||
```
|
||||
|
||||
### Cmdtmpl
|
||||
|
||||
The `cmdtmpl` command uses the `procs.Builder` to create a command
|
||||
based on some paramters. It will take a `data.yml` file and
|
||||
`template.yml` file to create a command.
|
||||
|
||||
```bash
|
||||
$ cat example/data.json
|
||||
{
|
||||
"source": "https://my.example.org",
|
||||
"user": "foo",
|
||||
"model": "widget",
|
||||
"action": "create",
|
||||
"args": "-f new -i improved"
|
||||
}
|
||||
$ cat example/template.json
|
||||
[
|
||||
"mysvc ${model} ${action} ${args}",
|
||||
"--endpoint ${source}",
|
||||
"--username ${user}"
|
||||
]
|
||||
$ ./cmdtmpl -data example/data.json -template example/template.json
|
||||
Command: mysvc foo widget create -f new -i imporoved --endpoint https://my.example.org --username foo
|
||||
$ ./cmdtmpl -data example/data.json -template example/template.json -field user=bar
|
||||
Command: mysvc foo widget create -f new -i imporoved --endpoint https://my.example.org --username bar
|
||||
```
|
||||
|
||||
### Procmon
|
||||
|
||||
The `procmon` command acts like
|
||||
[foreman](https://github.com/ddollar/foreman) with the difference
|
||||
being it uses a JSON file with key value pairs instead of a
|
||||
Procfile. This example uses the `procs.Manager` to manage a set of
|
||||
`procs.Processes`.
|
||||
|
||||
```bash
|
||||
$ cat example/procfile.json
|
||||
{
|
||||
"web": "python -m SimpleHTTPServer"
|
||||
}
|
||||
$ ./procmon -procfile example/procfile.json
|
||||
web | Starting web with python -m SimpleHTTPServer
|
||||
```
|
||||
|
||||
You can then access http://localhost:8000 to see the logs. You can
|
||||
also kill the child process and see `procmon` recognizing it has
|
||||
exited and exit itself.
|
58
vendor/github.com/ionrock/procs/builder.go
generated
vendored
Normal file
58
vendor/github.com/ionrock/procs/builder.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package procs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Builder helps construct commands using templates.
|
||||
type Builder struct {
|
||||
Context map[string]string
|
||||
Templates []string
|
||||
}
|
||||
|
||||
func (b *Builder) getConfig(ctx map[string]string) func(string) string {
|
||||
return func(key string) string {
|
||||
if v, ok := ctx[key]; ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) expand(v string, ctx map[string]string) string {
|
||||
return os.Expand(v, b.getConfig(ctx))
|
||||
}
|
||||
|
||||
// Command returns the result of the templates as a single string.
|
||||
func (b *Builder) Command() string {
|
||||
parts := []string{}
|
||||
for _, t := range b.Templates {
|
||||
parts = append(parts, b.expand(t, b.Context))
|
||||
}
|
||||
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
// CommandContext returns the result of the templates as a single
|
||||
// string, but allows providing an environment context as a
|
||||
// map[string]string for expansions.
|
||||
func (b *Builder) CommandContext(ctx map[string]string) string {
|
||||
// Build our environment context by starting with our Builder
|
||||
// context and overlay the passed in context map.
|
||||
env := make(map[string]string)
|
||||
for k, v := range b.Context {
|
||||
env[k] = b.expand(v, b.Context)
|
||||
}
|
||||
|
||||
for k, v := range ctx {
|
||||
env[k] = b.expand(v, env)
|
||||
}
|
||||
|
||||
parts := []string{}
|
||||
for _, t := range b.Templates {
|
||||
parts = append(parts, b.expand(t, env))
|
||||
}
|
||||
|
||||
return strings.Join(parts, " ")
|
||||
}
|
58
vendor/github.com/ionrock/procs/builder_test.go
generated
vendored
Normal file
58
vendor/github.com/ionrock/procs/builder_test.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func TestCommandContext(t *testing.T) {
|
||||
b := &procs.Builder{
|
||||
Context: map[string]string{
|
||||
"options": "-Fj -s https://example.com/chef -k knife.pem",
|
||||
},
|
||||
|
||||
Templates: []string{
|
||||
"knife",
|
||||
"${model} ${action}",
|
||||
"${args}",
|
||||
"${options}",
|
||||
},
|
||||
}
|
||||
|
||||
cmd := b.CommandContext(map[string]string{
|
||||
"model": "data bag",
|
||||
"action": "from file",
|
||||
"args": "foo data_bags/foo/bar.json",
|
||||
})
|
||||
|
||||
expected := "knife data bag from file foo data_bags/foo/bar.json -Fj -s https://example.com/chef -k knife.pem"
|
||||
if cmd != expected {
|
||||
t.Fatalf("failed building command: %q != %q", cmd, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommand(t *testing.T) {
|
||||
b := &procs.Builder{
|
||||
Context: map[string]string{
|
||||
"options": "-Fj -s https://example.com/chef -k knife.pem",
|
||||
"model": "data bag",
|
||||
"action": "from file",
|
||||
"args": "foo data_bags/foo/bar.json",
|
||||
},
|
||||
|
||||
Templates: []string{
|
||||
"knife",
|
||||
"${model} ${action}",
|
||||
"${args}",
|
||||
"${options}",
|
||||
},
|
||||
}
|
||||
|
||||
cmd := b.CommandContext(map[string]string{})
|
||||
|
||||
expected := "knife data bag from file foo data_bags/foo/bar.json -Fj -s https://example.com/chef -k knife.pem"
|
||||
if cmd != expected {
|
||||
t.Fatalf("failed building command: %q != %q", cmd, expected)
|
||||
}
|
||||
}
|
48
vendor/github.com/ionrock/procs/env.go
generated
vendored
Normal file
48
vendor/github.com/ionrock/procs/env.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package procs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseEnv takes an environment []string and converts it to a map[string]string.
|
||||
func ParseEnv(environ []string) map[string]string {
|
||||
env := make(map[string]string)
|
||||
for _, e := range environ {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
|
||||
// There is a chance we can get an env with empty values
|
||||
if len(pair) == 2 {
|
||||
env[pair[0]] = pair[1]
|
||||
}
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// Env takes a map[string]string and converts it to a []string that
|
||||
// can be used with exec.Cmd. The useEnv boolean flag will include the
|
||||
// current process environment, overlaying the provided env
|
||||
// map[string]string.
|
||||
func Env(env map[string]string, useEnv bool) []string {
|
||||
envlist := []string{}
|
||||
|
||||
// update our env by loading our env and overriding any values in
|
||||
// the provided env.
|
||||
if useEnv {
|
||||
environ := ParseEnv(os.Environ())
|
||||
for k, v := range env {
|
||||
environ[k] = v
|
||||
}
|
||||
env = environ
|
||||
}
|
||||
|
||||
for key, val := range env {
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
envlist = append(envlist, fmt.Sprintf("%s=%s", key, val))
|
||||
}
|
||||
|
||||
return envlist
|
||||
}
|
83
vendor/github.com/ionrock/procs/env_test.go
generated
vendored
Normal file
83
vendor/github.com/ionrock/procs/env_test.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func TestParseEnv(t *testing.T) {
|
||||
env := []string{
|
||||
"FOO=bar",
|
||||
"BAZ=`echo 'hello=world'`",
|
||||
}
|
||||
|
||||
m := procs.ParseEnv(env)
|
||||
|
||||
v, ok := m["FOO"]
|
||||
if !ok {
|
||||
t.Errorf("error missing FOO from env: %#v", m)
|
||||
}
|
||||
|
||||
if v != "bar" {
|
||||
t.Errorf("error FOO != bar: %s", v)
|
||||
}
|
||||
|
||||
v, ok = m["BAZ"]
|
||||
|
||||
if !ok {
|
||||
t.Errorf("error missing BAZ from env: %#v", m)
|
||||
}
|
||||
|
||||
expectBaz := "`echo 'hello=world'`"
|
||||
if v != expectBaz {
|
||||
t.Errorf("error BAZ != %s: %s", expectBaz, v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvBuilder(t *testing.T) {
|
||||
env := procs.Env(map[string]string{
|
||||
"FOO": "bar",
|
||||
"BAZ": "hello world",
|
||||
}, false)
|
||||
|
||||
if len(env) != 2 {
|
||||
t.Errorf("error loading env: %s", env)
|
||||
}
|
||||
}
|
||||
|
||||
func helperEnvCommand(env map[string]string) *exec.Cmd {
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestEnvBuilderOverrides")
|
||||
cmd.Env = procs.Env(env, false)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func TestEnvBuilderOverrides(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
return
|
||||
}
|
||||
for _, envvar := range procs.Env(map[string]string{"FOO": "override"}, true) {
|
||||
fmt.Println(envvar)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvBuilderWithEnv(t *testing.T) {
|
||||
cmd := helperEnvCommand(map[string]string{
|
||||
"GO_WANT_HELPER_PROCESS": "1",
|
||||
"FOO": "default",
|
||||
})
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatalf("error running helper: %s", err)
|
||||
}
|
||||
|
||||
env := procs.ParseEnv(strings.Split(string(out), "\n"))
|
||||
|
||||
if env["FOO"] != "override" {
|
||||
t.Errorf("error overriding envvar: %s", string(out))
|
||||
}
|
||||
}
|
33
vendor/github.com/ionrock/procs/example_basic_test.go
generated
vendored
Normal file
33
vendor/github.com/ionrock/procs/example_basic_test.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
|
||||
b := procs.Builder{
|
||||
Context: map[string]string{
|
||||
"NAME": "eric",
|
||||
},
|
||||
Templates: []string{
|
||||
"echo $NAME |",
|
||||
"grep $NAME",
|
||||
},
|
||||
}
|
||||
|
||||
cmd := b.Command()
|
||||
|
||||
fmt.Println(cmd)
|
||||
|
||||
p := procs.NewProcess(cmd)
|
||||
|
||||
p.Run()
|
||||
out, _ := p.Output()
|
||||
fmt.Println(string(out))
|
||||
// Output:
|
||||
// echo eric | grep eric
|
||||
// eric
|
||||
}
|
23
vendor/github.com/ionrock/procs/example_predefined_cmds_test.go
generated
vendored
Normal file
23
vendor/github.com/ionrock/procs/example_predefined_cmds_test.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func Example_predefinedCmds() {
|
||||
p := procs.Process{
|
||||
Cmds: []*exec.Cmd{
|
||||
exec.Command("echo", "foo"),
|
||||
exec.Command("grep", "foo"),
|
||||
},
|
||||
}
|
||||
|
||||
p.Run()
|
||||
out, _ := p.Output()
|
||||
fmt.Println(string(out))
|
||||
// Output:
|
||||
// foo
|
||||
}
|
43
vendor/github.com/ionrock/procs/examples_test.go
generated
vendored
Normal file
43
vendor/github.com/ionrock/procs/examples_test.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func ExampleSplitCommand() {
|
||||
parts := procs.SplitCommand("echo 'hello world'")
|
||||
for i, p := range parts {
|
||||
fmt.Printf("%d %s\n", i+1, p)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1 echo
|
||||
// 2 hello world
|
||||
}
|
||||
|
||||
func ExampleSplitCommandEnv() {
|
||||
env := map[string]string{
|
||||
"GREETING": "hello",
|
||||
"NAME": "world!",
|
||||
"PASSWORD": "secret",
|
||||
}
|
||||
|
||||
getenv := func(key string) string {
|
||||
if v, ok := env[key]; ok && key != "PASSWORD" {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
parts := procs.SplitCommandEnv("echo '$GREETING $NAME $PASSWORD'", getenv)
|
||||
|
||||
for i, p := range parts {
|
||||
fmt.Printf("%d %s\n", i+1, p)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1 echo
|
||||
// 2 hello world!
|
||||
}
|
119
vendor/github.com/ionrock/procs/manager.go
generated
vendored
Normal file
119
vendor/github.com/ionrock/procs/manager.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
package procs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Manager manages a set of Processes.
|
||||
type Manager struct {
|
||||
Processes map[string]*Process
|
||||
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewManager creates a new *Manager.
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
Processes: make(map[string]*Process),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// StdoutHandler returns an OutHandler that will ensure the underlying
|
||||
// process has an empty stdout buffer and logs to stdout a prefixed value
|
||||
// of "$name | $line".
|
||||
func (m *Manager) StdoutHandler(name string) OutHandler {
|
||||
return func(line string) string {
|
||||
fmt.Printf("%s | %s\n", name, line)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// StderrHandler returns an OutHandler that will ensure the underlying
|
||||
// process has an empty stderr buffer and logs to stdout a prefixed value
|
||||
// of "$name | $line".
|
||||
func (m *Manager) StderrHandler(name string) OutHandler {
|
||||
return func(line string) string {
|
||||
fmt.Printf("%s | %s\n", name, line)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Start and managed a new process using the default handlers from a
|
||||
// string.
|
||||
func (m *Manager) Start(name, cmd string) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
p := NewProcess(cmd)
|
||||
p.OutputHandler = m.StdoutHandler(name)
|
||||
p.ErrHandler = m.StderrHandler(name)
|
||||
err := p.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.Processes[name] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartProcess starts and manages a predifined process.
|
||||
func (m *Manager) StartProcess(name string, p *Process) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
err := p.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.Processes[name] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop will try to stop a managed process. If the process does not
|
||||
// exist, no error is returned.
|
||||
func (m *Manager) Stop(name string) error {
|
||||
p, ok := m.Processes[name]
|
||||
// We don't mind stopping a process that doesn't exist.
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return p.Stop()
|
||||
}
|
||||
|
||||
// Remove will try to stop and remove a managed process.
|
||||
func (m *Manager) Remove(name string) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
err := m.Stop(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Note that if the stop fails we don't remove it from the map of
|
||||
// processes to avoid losing the reference.
|
||||
delete(m.Processes, name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wait will block until all managed processes have finished.
|
||||
func (m *Manager) Wait() error {
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(m.Processes))
|
||||
|
||||
for _, p := range m.Processes {
|
||||
go func(proc *Process) {
|
||||
defer wg.Done()
|
||||
proc.Wait()
|
||||
}(p)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
55
vendor/github.com/ionrock/procs/manager_test.go
generated
vendored
Normal file
55
vendor/github.com/ionrock/procs/manager_test.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func TestManagerStartHelper(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
return
|
||||
}
|
||||
|
||||
port := flag.String("p", "12212", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse()
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
|
||||
log.Fatal(http.ListenAndServe(":"+*port, nil))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func TestManagerStart(t *testing.T) {
|
||||
m := procs.NewManager()
|
||||
|
||||
err := m.Start("test", fmt.Sprintf("%s -test.run=TestManagerStartHelper", os.Args[0]))
|
||||
if err != nil {
|
||||
t.Errorf("failed to start test process: %s", err)
|
||||
}
|
||||
|
||||
if len(m.Processes) != 1 {
|
||||
t.Error("failed to add process")
|
||||
}
|
||||
|
||||
err = m.Stop("test")
|
||||
if err != nil {
|
||||
t.Errorf("error stopping process: %s", err)
|
||||
}
|
||||
|
||||
err = m.Remove("test")
|
||||
if err != nil {
|
||||
t.Errorf("error removing process: %s", err)
|
||||
}
|
||||
|
||||
if len(m.Processes) != 0 {
|
||||
t.Error("failed to remove processes")
|
||||
}
|
||||
}
|
36
vendor/github.com/ionrock/procs/parse.go
generated
vendored
Normal file
36
vendor/github.com/ionrock/procs/parse.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package procs
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
shlex "github.com/flynn/go-shlex"
|
||||
)
|
||||
|
||||
// SplitCommand parses a command and splits it into lexical arguments
|
||||
// like a shell, returning a []string that can be used as arguments to
|
||||
// exec.Command.
|
||||
func SplitCommand(cmd string) []string {
|
||||
return SplitCommandEnv(cmd, nil)
|
||||
}
|
||||
|
||||
// SplitCommandEnv parses a command and splits it into lexical
|
||||
// arguments like a shell, returning a []string that can be used as
|
||||
// arguments to exec.Command. It also allows providing an expansion
|
||||
// function that will be used when expanding values within the parsed
|
||||
// arguments.
|
||||
func SplitCommandEnv(cmd string, getenv func(key string) string) []string {
|
||||
parts, err := shlex.Split(strings.TrimSpace(cmd))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if getenv != nil {
|
||||
for i, p := range parts {
|
||||
parts[i] = os.Expand(p, getenv)
|
||||
}
|
||||
}
|
||||
|
||||
return parts
|
||||
}
|
44
vendor/github.com/ionrock/procs/parse_test.go
generated
vendored
Normal file
44
vendor/github.com/ionrock/procs/parse_test.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/apoydence/onpar"
|
||||
. "github.com/apoydence/onpar/expect"
|
||||
. "github.com/apoydence/onpar/matchers"
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func matchSplitCommand(t *testing.T, parts, expected []string) {
|
||||
for i, part := range parts {
|
||||
Expect(t, part).To(Equal(expected[i]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitCommand(t *testing.T) {
|
||||
o := onpar.New()
|
||||
defer o.Run(t)
|
||||
|
||||
o.Group("split with pipe", func() {
|
||||
o.BeforeEach(func(t *testing.T) (*testing.T, []string, []string) {
|
||||
parts := procs.SplitCommand("echo 'foo' | grep o")
|
||||
expected := []string{"echo", "foo", "|", "grep", "o"}
|
||||
return t, parts, expected
|
||||
})
|
||||
|
||||
o.Spec("pass with a pipe", matchSplitCommand)
|
||||
})
|
||||
|
||||
o.Group("replace with specific context", func() {
|
||||
o.BeforeEach(func(t *testing.T) (*testing.T, []string, []string) {
|
||||
parts := procs.SplitCommandEnv("echo ${FOO}", func(k string) string {
|
||||
return "bar"
|
||||
})
|
||||
|
||||
expected := []string{"echo", "bar"}
|
||||
return t, parts, expected
|
||||
})
|
||||
|
||||
o.Spec("expand values found in provided env", matchSplitCommand)
|
||||
})
|
||||
}
|
307
vendor/github.com/ionrock/procs/process.go
generated
vendored
Normal file
307
vendor/github.com/ionrock/procs/process.go
generated
vendored
Normal file
@ -0,0 +1,307 @@
|
||||
// Procs is a library to make working with command line applications a
|
||||
// little nicer.
|
||||
//
|
||||
// The goal is to expand on the os/exec package by providing some
|
||||
// features usually accomplished in a shell, without having to resort to
|
||||
// a shell. Procs also tries to make working with output simpler by
|
||||
// providing a simple line handler API over working with io pipes.
|
||||
//
|
||||
// Finally, while the hope is that procs provides some convenience, it
|
||||
// is also a goal to help make it easier to write more secure
|
||||
// code. For example, avoiding a shell and the ability to manage the
|
||||
// environment as a map[string]string are both measures that intend to
|
||||
// make it easier to accomplish things like avoiding outputting
|
||||
// secrets and opening the door for MITM attacks. With that said, it is
|
||||
// always important to consider the security implications, especially
|
||||
// when you are working with untrusted input or sensitive data.
|
||||
package procs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// OutHandler defines the interface for writing output handlers for
|
||||
// Process objects.
|
||||
type OutHandler func(string) string
|
||||
|
||||
// Process is intended to be used like exec.Cmd where possible.
|
||||
type Process struct {
|
||||
// CmdString takes a string and parses it into the relevant cmds
|
||||
CmdString string
|
||||
|
||||
// Cmds is the list of command delmited by pipes.
|
||||
Cmds []*exec.Cmd
|
||||
|
||||
// Env provides a map[string]string that can mutated before
|
||||
// running a command.
|
||||
Env map[string]string
|
||||
|
||||
// Dir defines the directory the command should run in. The
|
||||
// Default is the current dir.
|
||||
Dir string
|
||||
|
||||
// OutputHandler can be defined to perform any sort of processing
|
||||
// on the output. The simple interface is to accept a string (a
|
||||
// line of output) and return a string that will be included in the
|
||||
// buffered output and/or output written to stdout.'
|
||||
//
|
||||
// For example defining the Process as:
|
||||
//
|
||||
// prefix := "myapp"
|
||||
// p := &procs.Process{
|
||||
// OutputHandler: func(line string) string {
|
||||
// return fmt.Sprintf("%s | %s", prefix, line)
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// This would prefix the stdout lines with a "myapp | ".
|
||||
//
|
||||
// By the default, this function is nil and will be skipped, with
|
||||
// the unchanged line being added to the respective output buffer.
|
||||
OutputHandler OutHandler
|
||||
|
||||
// ErrHandler is a OutputHandler for stderr.
|
||||
ErrHandler OutHandler
|
||||
|
||||
// When no output is given, we'll buffer output in these vars.
|
||||
errBuffer bytes.Buffer
|
||||
outBuffer bytes.Buffer
|
||||
|
||||
// When a output handler is provided, we ensure we're handling a
|
||||
// single line at at time.
|
||||
outputWait *sync.WaitGroup
|
||||
}
|
||||
|
||||
// NewProcess creates a new *Process from a command string.
|
||||
//
|
||||
// It is assumed that the user will mutate the resulting *Process by
|
||||
// setting the necessary attributes.
|
||||
func NewProcess(command string) *Process {
|
||||
return &Process{CmdString: command}
|
||||
}
|
||||
|
||||
// internal expand method to use the proc env.
|
||||
func (p *Process) expand(s string) string {
|
||||
return os.Expand(s, func(key string) string {
|
||||
v, _ := p.Env[key]
|
||||
return v
|
||||
})
|
||||
}
|
||||
|
||||
// addCmd adds a new command to the list of commands, ensuring the Dir
|
||||
// and Env have been added to the underlying *exec.Cmd instances.
|
||||
func (p *Process) addCmd(cmdparts []string) {
|
||||
var cmd *exec.Cmd
|
||||
if len(cmdparts) == 1 {
|
||||
cmd = exec.Command(cmdparts[0])
|
||||
} else {
|
||||
cmd = exec.Command(cmdparts[0], cmdparts[1:]...)
|
||||
}
|
||||
|
||||
if p.Dir != "" {
|
||||
cmd.Dir = p.Dir
|
||||
}
|
||||
|
||||
if p.Env != nil {
|
||||
env := []string{}
|
||||
for k, v := range p.Env {
|
||||
env = append(env, fmt.Sprintf("%s=%s", k, p.expand(v)))
|
||||
}
|
||||
|
||||
cmd.Env = env
|
||||
}
|
||||
|
||||
p.Cmds = append(p.Cmds, cmd)
|
||||
}
|
||||
|
||||
// findCmds parses the CmdString to find the commands that should be
|
||||
// run by spliting the lexically parsed command by pipes ("|").
|
||||
func (p *Process) findCmds() {
|
||||
// Skip if the cmd set is already set. This allows manual creation
|
||||
// of piped commands.
|
||||
if len(p.Cmds) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if p.CmdString == "" {
|
||||
return
|
||||
}
|
||||
|
||||
parts := SplitCommand(p.CmdString)
|
||||
for i := range parts {
|
||||
parts[i] = p.expand(parts[i])
|
||||
}
|
||||
|
||||
cmd := []string{}
|
||||
for _, part := range parts {
|
||||
if part == "|" {
|
||||
p.addCmd(cmd)
|
||||
cmd = []string{}
|
||||
} else {
|
||||
cmd = append(cmd, part)
|
||||
}
|
||||
}
|
||||
|
||||
p.addCmd(cmd)
|
||||
}
|
||||
|
||||
// lineReader takes will read a line in the io.Reader and write to the
|
||||
// Process output buffer and use any OutputHandler that exists.
|
||||
func (p *Process) lineReader(wg *sync.WaitGroup, r io.Reader, w *bytes.Buffer, handler OutHandler) {
|
||||
defer wg.Done()
|
||||
|
||||
reader := bufio.NewReader(r)
|
||||
var buffer bytes.Buffer
|
||||
|
||||
for {
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
n, err := reader.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf = buf[:n]
|
||||
|
||||
for {
|
||||
i := bytes.IndexByte(buf, '\n')
|
||||
if i < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
buffer.Write(buf[0:i])
|
||||
outLine := buffer.String()
|
||||
if handler != nil {
|
||||
outLine = handler(outLine)
|
||||
}
|
||||
w.WriteString(outLine)
|
||||
buffer.Reset()
|
||||
buf = buf[i+1:]
|
||||
}
|
||||
buffer.Write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
// checkErr shortens the creation of the pipes by bailing out with a
|
||||
// log.Fatal.
|
||||
func checkErr(msg string, err error) {
|
||||
if err != nil {
|
||||
log.Fatalf("%s: %s", msg, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Process) setupPipes() error {
|
||||
last := len(p.Cmds) - 1
|
||||
|
||||
if last != 0 {
|
||||
for i, cmd := range p.Cmds[:last] {
|
||||
var err error
|
||||
|
||||
p.Cmds[i+1].Stdin, err = cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Printf("error creating stdout pipe: %s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Stderr = &p.errBuffer
|
||||
}
|
||||
}
|
||||
|
||||
cmd := p.Cmds[last]
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Printf("error creating stdout pipe: %s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
fmt.Printf("error creating stderr pipe: %s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
p.outputWait = new(sync.WaitGroup)
|
||||
p.outputWait.Add(2)
|
||||
|
||||
// These close the stdout/err channels
|
||||
go p.lineReader(p.outputWait, stdout, &p.outBuffer, p.OutputHandler)
|
||||
go p.lineReader(p.outputWait, stderr, &p.errBuffer, p.ErrHandler)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run executes the cmds and returns the output as a string and any error.
|
||||
func (p *Process) Run() error {
|
||||
if err := p.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.Wait()
|
||||
}
|
||||
|
||||
// Start will start the list of cmds.
|
||||
func (p *Process) Start() error {
|
||||
p.findCmds()
|
||||
p.setupPipes()
|
||||
|
||||
for i, cmd := range p.Cmds {
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
defer func() {
|
||||
for _, precmd := range p.Cmds[0:i] {
|
||||
precmd.Wait()
|
||||
}
|
||||
}()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wait will block, waiting for the commands to finish.
|
||||
func (p *Process) Wait() error {
|
||||
if p.outputWait != nil {
|
||||
p.outputWait.Wait()
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, cmd := range p.Cmds {
|
||||
err = cmd.Wait()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop tries to stop the process.
|
||||
func (p *Process) Stop() error {
|
||||
for _, cmd := range p.Cmds {
|
||||
// ProcessState means it is already exited.
|
||||
if cmd.ProcessState != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
err := cmd.Process.Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Output returns the buffered output as []byte.
|
||||
func (p *Process) Output() ([]byte, error) {
|
||||
return p.outBuffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// ErrOutput returns the buffered stderr as []byte
|
||||
func (p *Process) ErrOutput() ([]byte, error) {
|
||||
return p.errBuffer.Bytes(), nil
|
||||
}
|
143
vendor/github.com/ionrock/procs/process_test.go
generated
vendored
Normal file
143
vendor/github.com/ionrock/procs/process_test.go
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
package procs_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/ionrock/procs"
|
||||
)
|
||||
|
||||
func newProcess() *procs.Process {
|
||||
return &procs.Process{
|
||||
Cmds: []*exec.Cmd{
|
||||
exec.Command("echo", "foo"),
|
||||
exec.Command("grep", "foo"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcess(t *testing.T) {
|
||||
p := newProcess()
|
||||
|
||||
err := p.Run()
|
||||
if err != nil {
|
||||
t.Fatalf("error running program: %s", err)
|
||||
}
|
||||
|
||||
out, _ := p.Output()
|
||||
if !bytes.Equal(bytes.TrimSpace(out), []byte("foo")) {
|
||||
t.Errorf("wrong output: expected foo but got %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessWithOutput(t *testing.T) {
|
||||
p := newProcess()
|
||||
|
||||
p.OutputHandler = func(line string) string {
|
||||
return fmt.Sprintf("x | %s", line)
|
||||
}
|
||||
|
||||
err := p.Run()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error running program: %s", err)
|
||||
}
|
||||
expected := []byte("x | foo")
|
||||
out, _ := p.Output()
|
||||
if !bytes.Equal(bytes.TrimSpace(out), expected) {
|
||||
t.Errorf("wrong output: expected %q but got %q", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessStartAndWait(t *testing.T) {
|
||||
p := newProcess()
|
||||
|
||||
p.Start()
|
||||
p.Wait()
|
||||
|
||||
out, _ := p.Output()
|
||||
expected := []byte("foo")
|
||||
if !bytes.Equal(bytes.TrimSpace(out), expected) {
|
||||
t.Errorf("wrong output: expected %q but got %q", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessStartAndWaitWithOutput(t *testing.T) {
|
||||
p := newProcess()
|
||||
p.OutputHandler = func(line string) string {
|
||||
return fmt.Sprintf("x | %s", line)
|
||||
}
|
||||
|
||||
p.Start()
|
||||
p.Wait()
|
||||
|
||||
out, _ := p.Output()
|
||||
expected := []byte("x | foo")
|
||||
if !bytes.Equal(bytes.TrimSpace(out), expected) {
|
||||
t.Errorf("wrong output: expected %q but got %q", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessFromString(t *testing.T) {
|
||||
p := procs.NewProcess("echo 'foo'")
|
||||
err := p.Run()
|
||||
if err != nil {
|
||||
t.Fatalf("error running program: %s", err)
|
||||
}
|
||||
out, _ := p.Output()
|
||||
if !bytes.Equal(bytes.TrimSpace(out), []byte("foo")) {
|
||||
t.Errorf("wrong output: expected foo but got %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessFromStringWithPipe(t *testing.T) {
|
||||
p := procs.NewProcess("echo 'foo' | grep foo")
|
||||
err := p.Run()
|
||||
if err != nil {
|
||||
t.Fatalf("error running program: %s", err)
|
||||
}
|
||||
|
||||
out, _ := p.Output()
|
||||
if !bytes.Equal(bytes.TrimSpace(out), []byte("foo")) {
|
||||
t.Errorf("wrong output: expected foo but got %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStderrOutput(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, "stdout output")
|
||||
fmt.Fprintln(os.Stderr, "stderr output")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func TestProcessPipeWithFailures(t *testing.T) {
|
||||
|
||||
// This will run a piped command with a failure part way
|
||||
// through. We want to be sure we get output on stderr.
|
||||
p := procs.NewProcess(fmt.Sprintf("echo 'foo' | %s -test.run=TestStderrOutput | grep foo", os.Args[0]))
|
||||
p.Env = map[string]string{"GO_WANT_HELPER_PROCESS": "1"}
|
||||
|
||||
err := p.Run()
|
||||
if err == nil {
|
||||
t.Fatal("expected error running program")
|
||||
|
||||
}
|
||||
|
||||
out, _ := p.Output()
|
||||
expected := []byte("") // expecting no output b/c the grep foo won't run
|
||||
if !bytes.Equal(out, expected) {
|
||||
t.Errorf("wrong stdout output: expected '%s' but got '%s'", expected, out)
|
||||
}
|
||||
|
||||
errOut, _ := p.ErrOutput()
|
||||
expected = []byte("stderr output")
|
||||
if !bytes.Equal(bytes.TrimSpace(errOut), expected) {
|
||||
t.Errorf("wrong stderr output: expected '%s' but got '%s'", expected, out)
|
||||
}
|
||||
}
|
23
vendor/github.com/kr/pty/License
generated
vendored
Normal file
23
vendor/github.com/kr/pty/License
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright (c) 2011 Keith Rarick
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall
|
||||
be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
100
vendor/github.com/kr/pty/README.md
generated
vendored
Normal file
100
vendor/github.com/kr/pty/README.md
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
# pty
|
||||
|
||||
Pty is a Go package for using unix pseudo-terminals.
|
||||
|
||||
## Install
|
||||
|
||||
go get github.com/kr/pty
|
||||
|
||||
## Example
|
||||
|
||||
### Command
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kr/pty"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := exec.Command("grep", "--color=auto", "bar")
|
||||
f, err := pty.Start(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
f.Write([]byte("foo\n"))
|
||||
f.Write([]byte("bar\n"))
|
||||
f.Write([]byte("baz\n"))
|
||||
f.Write([]byte{4}) // EOT
|
||||
}()
|
||||
io.Copy(os.Stdout, f)
|
||||
}
|
||||
```
|
||||
|
||||
### Shell
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/kr/pty"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
func test() error {
|
||||
// Create arbitrary command.
|
||||
c := exec.Command("bash")
|
||||
|
||||
// Start the command with a pty.
|
||||
ptmx, err := pty.Start(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure to close the pty at the end.
|
||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
||||
|
||||
// Handle pty size.
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGWINCH)
|
||||
go func() {
|
||||
for range ch {
|
||||
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
|
||||
log.Printf("error resizing pty: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
ch <- syscall.SIGWINCH // Initial resize.
|
||||
|
||||
// Set stdin in raw mode.
|
||||
oldState, err := terminal.MakeRaw(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
|
||||
|
||||
// Copy stdin to the pty and the pty to stdout.
|
||||
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
|
||||
_, _ = io.Copy(os.Stdout, ptmx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := test(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
16
vendor/github.com/kr/pty/doc.go
generated
vendored
Normal file
16
vendor/github.com/kr/pty/doc.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Package pty provides functions for working with Unix terminals.
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ErrUnsupported is returned if a function is not
|
||||
// available on the current platform.
|
||||
var ErrUnsupported = errors.New("unsupported")
|
||||
|
||||
// Opens a pty and its corresponding tty.
|
||||
func Open() (pty, tty *os.File, err error) {
|
||||
return open()
|
||||
}
|
13
vendor/github.com/kr/pty/ioctl.go
generated
vendored
Normal file
13
vendor/github.com/kr/pty/ioctl.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// +build !windows
|
||||
|
||||
package pty
|
||||
|
||||
import "syscall"
|
||||
|
||||
func ioctl(fd, cmd, ptr uintptr) error {
|
||||
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
|
||||
if e != 0 {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
39
vendor/github.com/kr/pty/ioctl_bsd.go
generated
vendored
Normal file
39
vendor/github.com/kr/pty/ioctl_bsd.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package pty
|
||||
|
||||
// from <sys/ioccom.h>
|
||||
const (
|
||||
_IOC_VOID uintptr = 0x20000000
|
||||
_IOC_OUT uintptr = 0x40000000
|
||||
_IOC_IN uintptr = 0x80000000
|
||||
_IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
|
||||
_IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
|
||||
|
||||
_IOC_PARAM_SHIFT = 13
|
||||
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
|
||||
)
|
||||
|
||||
func _IOC_PARM_LEN(ioctl uintptr) uintptr {
|
||||
return (ioctl >> 16) & _IOC_PARAM_MASK
|
||||
}
|
||||
|
||||
func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num
|
||||
}
|
||||
|
||||
func _IO(group byte, ioctl_num uintptr) uintptr {
|
||||
return _IOC(_IOC_VOID, group, ioctl_num, 0)
|
||||
}
|
||||
|
||||
func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_OUT, group, ioctl_num, param_len)
|
||||
}
|
||||
|
||||
func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_IN, group, ioctl_num, param_len)
|
||||
}
|
||||
|
||||
func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
||||
return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len)
|
||||
}
|
19
vendor/github.com/kr/pty/mktypes.bash
generated
vendored
Executable file
19
vendor/github.com/kr/pty/mktypes.bash
generated
vendored
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GOOSARCH="${GOOS}_${GOARCH}"
|
||||
case "$GOOSARCH" in
|
||||
_* | *_ | _)
|
||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
GODEFS="go tool cgo -godefs"
|
||||
|
||||
$GODEFS types.go |gofmt > ztypes_$GOARCH.go
|
||||
|
||||
case $GOOS in
|
||||
freebsd|dragonfly|openbsd)
|
||||
$GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go
|
||||
;;
|
||||
esac
|
65
vendor/github.com/kr/pty/pty_darwin.go
generated
vendored
Normal file
65
vendor/github.com/kr/pty/pty_darwin.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
p := os.NewFile(uintptr(pFD), "/dev/ptmx")
|
||||
// In case of error after this point, make sure we close the ptmx fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := grantpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := unlockpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile(sname, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
|
||||
|
||||
err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range n {
|
||||
if c == 0 {
|
||||
return string(n[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
||||
|
||||
func grantpt(f *os.File) error {
|
||||
return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0)
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0)
|
||||
}
|
80
vendor/github.com/kr/pty/pty_dragonfly.go
generated
vendored
Normal file
80
vendor/github.com/kr/pty/pty_dragonfly.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// same code as pty_darwin.go
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// In case of error after this point, make sure we close the ptmx fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := grantpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := unlockpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile(sname, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func grantpt(f *os.File) error {
|
||||
_, err := isptmaster(f.Fd())
|
||||
return err
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
_, err := isptmaster(f.Fd())
|
||||
return err
|
||||
}
|
||||
|
||||
func isptmaster(fd uintptr) (bool, error) {
|
||||
err := ioctl(fd, syscall.TIOCISPTMASTER, 0)
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
emptyFiodgnameArg fiodgnameArg
|
||||
ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
||||
)
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
name := make([]byte, _C_SPECNAMELEN)
|
||||
fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}}
|
||||
|
||||
err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range name {
|
||||
if c == 0 {
|
||||
s := "/dev/" + string(name[:i])
|
||||
return strings.Replace(s, "ptm", "pts", -1), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
78
vendor/github.com/kr/pty/pty_freebsd.go
generated
vendored
Normal file
78
vendor/github.com/kr/pty/pty_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func posixOpenpt(oflag int) (fd int, err error) {
|
||||
r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)
|
||||
fd = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return fd, err
|
||||
}
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
p := os.NewFile(uintptr(fd), "/dev/pts")
|
||||
// In case of error after this point, make sure we close the pts fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func isptmaster(fd uintptr) (bool, error) {
|
||||
err := ioctl(fd, syscall.TIOCPTMASTER, 0)
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
emptyFiodgnameArg fiodgnameArg
|
||||
ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
||||
)
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
master, err := isptmaster(f.Fd())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !master {
|
||||
return "", syscall.EINVAL
|
||||
}
|
||||
|
||||
const n = _C_SPECNAMELEN + 1
|
||||
var (
|
||||
buf = make([]byte, n)
|
||||
arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))}
|
||||
)
|
||||
if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range buf {
|
||||
if c == 0 {
|
||||
return string(buf[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("FIODGNAME string not NUL-terminated")
|
||||
}
|
51
vendor/github.com/kr/pty/pty_linux.go
generated
vendored
Normal file
51
vendor/github.com/kr/pty/pty_linux.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// In case of error after this point, make sure we close the ptmx fd.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = p.Close() // Best effort.
|
||||
}
|
||||
}()
|
||||
|
||||
sname, err := ptsname(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := unlockpt(p); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return p, t, nil
|
||||
}
|
||||
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
var n _C_uint
|
||||
err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "/dev/pts/" + strconv.Itoa(int(n)), nil
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
var u _C_int
|
||||
// use TIOCSPTLCK with a zero valued arg to clear the slave pty lock
|
||||
return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
||||
}
|
33
vendor/github.com/kr/pty/pty_openbsd.go
generated
vendored
Normal file
33
vendor/github.com/kr/pty/pty_openbsd.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
/*
|
||||
* from ptm(4):
|
||||
* The PTMGET command allocates a free pseudo terminal, changes its
|
||||
* ownership to the caller, revokes the access privileges for all previous
|
||||
* users, opens the file descriptors for the master and slave devices and
|
||||
* returns them to the caller in struct ptmget.
|
||||
*/
|
||||
|
||||
p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
var ptm ptmget
|
||||
if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm")
|
||||
tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm")
|
||||
|
||||
return pty, tty, nil
|
||||
}
|
11
vendor/github.com/kr/pty/pty_unsupported.go
generated
vendored
Normal file
11
vendor/github.com/kr/pty/pty_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build !linux,!darwin,!freebsd,!dragonfly,!openbsd
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func open() (pty, tty *os.File, err error) {
|
||||
return nil, nil, ErrUnsupported
|
||||
}
|
34
vendor/github.com/kr/pty/run.go
generated
vendored
Normal file
34
vendor/github.com/kr/pty/run.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// +build !windows
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
|
||||
// and c.Stderr, calls c.Start, and returns the File of the tty's
|
||||
// corresponding pty.
|
||||
func Start(c *exec.Cmd) (pty *os.File, err error) {
|
||||
pty, tty, err := Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tty.Close()
|
||||
c.Stdout = tty
|
||||
c.Stdin = tty
|
||||
c.Stderr = tty
|
||||
if c.SysProcAttr == nil {
|
||||
c.SysProcAttr = &syscall.SysProcAttr{}
|
||||
}
|
||||
c.SysProcAttr.Setctty = true
|
||||
c.SysProcAttr.Setsid = true
|
||||
err = c.Start()
|
||||
if err != nil {
|
||||
pty.Close()
|
||||
return nil, err
|
||||
}
|
||||
return pty, err
|
||||
}
|
10
vendor/github.com/kr/pty/types.go
generated
vendored
Normal file
10
vendor/github.com/kr/pty/types.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// +build ignore
|
||||
|
||||
package pty
|
||||
|
||||
import "C"
|
||||
|
||||
type (
|
||||
_C_int C.int
|
||||
_C_uint C.uint
|
||||
)
|
17
vendor/github.com/kr/pty/types_dragonfly.go
generated
vendored
Normal file
17
vendor/github.com/kr/pty/types_dragonfly.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// +build ignore
|
||||
|
||||
package pty
|
||||
|
||||
/*
|
||||
#define _KERNEL
|
||||
#include <sys/conf.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/filio.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */
|
||||
)
|
||||
|
||||
type fiodgnameArg C.struct_fiodname_args
|
15
vendor/github.com/kr/pty/types_freebsd.go
generated
vendored
Normal file
15
vendor/github.com/kr/pty/types_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// +build ignore
|
||||
|
||||
package pty
|
||||
|
||||
/*
|
||||
#include <sys/param.h>
|
||||
#include <sys/filio.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */
|
||||
)
|
||||
|
||||
type fiodgnameArg C.struct_fiodgname_arg
|
14
vendor/github.com/kr/pty/types_openbsd.go
generated
vendored
Normal file
14
vendor/github.com/kr/pty/types_openbsd.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// +build ignore
|
||||
|
||||
package pty
|
||||
|
||||
/*
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/tty.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type ptmget C.struct_ptmget
|
||||
|
||||
var ioctl_PTMGET = C.PTMGET
|
64
vendor/github.com/kr/pty/util.go
generated
vendored
Normal file
64
vendor/github.com/kr/pty/util.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
// +build !windows
|
||||
|
||||
package pty
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// InheritSize applies the terminal size of master to slave. This should be run
|
||||
// in a signal handler for syscall.SIGWINCH to automatically resize the slave when
|
||||
// the master receives a window size change notification.
|
||||
func InheritSize(master, slave *os.File) error {
|
||||
size, err := GetsizeFull(master)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = Setsize(slave, size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setsize resizes t to s.
|
||||
func Setsize(t *os.File, ws *Winsize) error {
|
||||
return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ)
|
||||
}
|
||||
|
||||
// GetsizeFull returns the full terminal size description.
|
||||
func GetsizeFull(t *os.File) (size *Winsize, err error) {
|
||||
var ws Winsize
|
||||
err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ)
|
||||
return &ws, err
|
||||
}
|
||||
|
||||
// Getsize returns the number of rows (lines) and cols (positions
|
||||
// in each line) in terminal t.
|
||||
func Getsize(t *os.File) (rows, cols int, err error) {
|
||||
ws, err := GetsizeFull(t)
|
||||
return int(ws.Rows), int(ws.Cols), err
|
||||
}
|
||||
|
||||
// Winsize describes the terminal size.
|
||||
type Winsize struct {
|
||||
Rows uint16 // ws_row: Number of rows (in cells)
|
||||
Cols uint16 // ws_col: Number of columns (in cells)
|
||||
X uint16 // ws_xpixel: Width in pixels
|
||||
Y uint16 // ws_ypixel: Height in pixels
|
||||
}
|
||||
|
||||
func windowRectCall(ws *Winsize, fd, a2 uintptr) error {
|
||||
_, _, errno := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
fd,
|
||||
a2,
|
||||
uintptr(unsafe.Pointer(ws)),
|
||||
)
|
||||
if errno != 0 {
|
||||
return syscall.Errno(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
9
vendor/github.com/kr/pty/ztypes_386.go
generated
vendored
Normal file
9
vendor/github.com/kr/pty/ztypes_386.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
9
vendor/github.com/kr/pty/ztypes_amd64.go
generated
vendored
Normal file
9
vendor/github.com/kr/pty/ztypes_amd64.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
9
vendor/github.com/kr/pty/ztypes_arm.go
generated
vendored
Normal file
9
vendor/github.com/kr/pty/ztypes_arm.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
11
vendor/github.com/kr/pty/ztypes_arm64.go
generated
vendored
Normal file
11
vendor/github.com/kr/pty/ztypes_arm64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
// +build arm64
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
14
vendor/github.com/kr/pty/ztypes_dragonfly_amd64.go
generated
vendored
Normal file
14
vendor/github.com/kr/pty/ztypes_dragonfly_amd64.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_dragonfly.go
|
||||
|
||||
package pty
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = 0x3f
|
||||
)
|
||||
|
||||
type fiodgnameArg struct {
|
||||
Name *byte
|
||||
Len uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
}
|
13
vendor/github.com/kr/pty/ztypes_freebsd_386.go
generated
vendored
Normal file
13
vendor/github.com/kr/pty/ztypes_freebsd_386.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_freebsd.go
|
||||
|
||||
package pty
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = 0x3f
|
||||
)
|
||||
|
||||
type fiodgnameArg struct {
|
||||
Len int32
|
||||
Buf *byte
|
||||
}
|
14
vendor/github.com/kr/pty/ztypes_freebsd_amd64.go
generated
vendored
Normal file
14
vendor/github.com/kr/pty/ztypes_freebsd_amd64.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_freebsd.go
|
||||
|
||||
package pty
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = 0x3f
|
||||
)
|
||||
|
||||
type fiodgnameArg struct {
|
||||
Len int32
|
||||
Pad_cgo_0 [4]byte
|
||||
Buf *byte
|
||||
}
|
13
vendor/github.com/kr/pty/ztypes_freebsd_arm.go
generated
vendored
Normal file
13
vendor/github.com/kr/pty/ztypes_freebsd_arm.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_freebsd.go
|
||||
|
||||
package pty
|
||||
|
||||
const (
|
||||
_C_SPECNAMELEN = 0x3f
|
||||
)
|
||||
|
||||
type fiodgnameArg struct {
|
||||
Len int32
|
||||
Buf *byte
|
||||
}
|
12
vendor/github.com/kr/pty/ztypes_mipsx.go
generated
vendored
Normal file
12
vendor/github.com/kr/pty/ztypes_mipsx.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
// +build linux
|
||||
// +build mips mipsle mips64 mips64le
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
13
vendor/github.com/kr/pty/ztypes_openbsd_386.go
generated
vendored
Normal file
13
vendor/github.com/kr/pty/ztypes_openbsd_386.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_openbsd.go
|
||||
|
||||
package pty
|
||||
|
||||
type ptmget struct {
|
||||
Cfd int32
|
||||
Sfd int32
|
||||
Cn [16]int8
|
||||
Sn [16]int8
|
||||
}
|
||||
|
||||
var ioctl_PTMGET = 0x40287401
|
13
vendor/github.com/kr/pty/ztypes_openbsd_amd64.go
generated
vendored
Normal file
13
vendor/github.com/kr/pty/ztypes_openbsd_amd64.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_openbsd.go
|
||||
|
||||
package pty
|
||||
|
||||
type ptmget struct {
|
||||
Cfd int32
|
||||
Sfd int32
|
||||
Cn [16]int8
|
||||
Sn [16]int8
|
||||
}
|
||||
|
||||
var ioctl_PTMGET = 0x40287401
|
11
vendor/github.com/kr/pty/ztypes_ppc64.go
generated
vendored
Normal file
11
vendor/github.com/kr/pty/ztypes_ppc64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build ppc64
|
||||
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
11
vendor/github.com/kr/pty/ztypes_ppc64le.go
generated
vendored
Normal file
11
vendor/github.com/kr/pty/ztypes_ppc64le.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build ppc64le
|
||||
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
11
vendor/github.com/kr/pty/ztypes_s390x.go
generated
vendored
Normal file
11
vendor/github.com/kr/pty/ztypes_s390x.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build s390x
|
||||
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types.go
|
||||
|
||||
package pty
|
||||
|
||||
type (
|
||||
_C_int int32
|
||||
_C_uint uint32
|
||||
)
|
19
vendor/vendor.json
vendored
Normal file
19
vendor/vendor.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"comment": "",
|
||||
"ignore": "",
|
||||
"package": [
|
||||
{
|
||||
"checksumSHA1": "AcczqNgc2/sR/+4gklvFe8zs2eE=",
|
||||
"path": "github.com/ionrock/procs",
|
||||
"revision": "f53ef5630f1a1fd42c4e528a04cdaa81265cc66d",
|
||||
"revisionTime": "2018-01-02T00:55:58Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "KU+GT3javo9S9oVEJfqQUKPPUwo=",
|
||||
"path": "github.com/kr/pty",
|
||||
"revision": "fa756f09eeb418bf1cc6268c66ceaad9bb98f598",
|
||||
"revisionTime": "2018-06-20T15:12:22Z"
|
||||
}
|
||||
],
|
||||
"rootPath": "github.com/jesseduffield/lazygit"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user