Spracherkennung für: .go vermutete Sprache: Abap {ABAP[56] SPS[44] Fortran[27]} [Methode: maximale Elemente, drei Dimensionen]
// Copyright
2017 Google Inc. All rights reserved.
//
// Licensed
under the Apache License, Version
2.
0 (the
"License");
// you may not use this
file except
in compliance with the License.
// You may obtain a
copy of the License
at
//
//
http://www.apache.org/licenses/LICENSE-2.
0
//
// Unless required
by applicable law
or agreed
to in writing, software
// distributed
under the License
is distributed
on an
"AS IS" BASIS,
// WITHOUT WARRANTIES
OR CONDITIONS
OF ANY KIND, either express
or implied.
// See the License
for the specific
language governing permissions
and
// limitations
under the License.
package build
import (
"bufio"
"fmt"
"io"
"os/exec"
"strings"
"syscall"
"time"
)
// Cmd
is a wrapper
of os/
exec.Cmd that integrates with the build context
for
// logging, the config
's Environment for simpler environment modification, and
// implements hooks
for sandboxing
type Cmd struct {
*exec.Cmd
Environment
*Environment
Sandbox Sandbox
ctx Context
config Config
event
*TraceEvent
name
string
started
time.
Time
}
func Command(ctx Context, config Config, event
*TraceEvent, name string, executable string, args ...string) *Cmd {
ret := &Cmd{
Cmd:
exec.CommandContext(ctx.Context, executable, args...),
Environment: config.Environment().
Copy(),
Sandbox: noSandbox,
ctx: ctx,
config: config,
event: event,
name: name,
}
return ret
}
func (c
*Cmd) Kill() error {
if c.Cmd.Process != nil {
return c.Cmd.Process.Kill()
}
return nil
}
func (c
*Cmd) prepare() {
if c.Env == nil {
c.Env = c.Environment.Environ()
}
if c.sandboxSupported() {
c.wrapSandbox()
}
c.ctx.Verbosef(
"%q executing %q %v\n", c.name, c.Path, c.Args)
c.started =
time.Now()
}
func (c
*Cmd) report() {
if state := c.Cmd.ProcessState; state != nil {
if c.event != nil {
c.event.AddProcResInfo(c.name, state)
}
rusage := state.SysUsage().(
*syscall.Rusage)
c.ctx.Verbosef(
"%q finished with exit code %d (%s real, %s user, %s system, %dMB maxrss)",
c.name, c.Cmd.ProcessState.ExitCode(),
time.Since(c.started).
Round(
time.Millisecond),
c.Cmd.ProcessState.UserTime().
Round(
time.Millisecond),
c.Cmd.ProcessState.SystemTime().
Round(
time.Millisecond),
rusage.Maxrss/
1024)
}
}
// fatal reports a fatal error
to the event
if present,
as well
as to the context.
func (c
*Cmd) fatal(str string) {
if c.event != nil {
c.event.SetFatalOrPanicMessage(str)
}
c.ctx.Fatal(str)
}
// fatalf reports a fatal error
to the event
if present,
as well
as to the context.
func (c
*Cmd) fatalf(format string, args ...interface{}) {
str := fmt.Sprintf(
format, args...)
c.fatal(str)
}
func (c
*Cmd) Start() error {
c.prepare()
return c.Cmd.Start()
}
func (c
*Cmd) Run() error {
c.prepare()
err := c.Cmd.
Run()
c.
report()
return err
}
func (c
*Cmd) Output() ([]byte, error) {
c.prepare()
bytes, err := c.Cmd.Output()
c.
report()
return bytes, err
}
func (c
*Cmd) CombinedOutput() ([]byte, error) {
c.prepare()
bytes, err := c.Cmd.CombinedOutput()
c.
report()
return bytes, err
}
func (c
*Cmd) Wait() error {
err := c.Cmd.Wait()
c.
report()
return err
}
// StartOrFatal
is equivalent
to Start, but handles the error with a
call to fatal
func (c
*Cmd) StartOrFatal() {
if err := c.Start(); err != nil {
c.fatalf(
"Failed to run %s: %v", c.name, err)
}
}
func (c
*Cmd) reportError(err error) {
if err == nil {
return
}
if e, ok := err.(
*exec.ExitError); ok {
c.fatalf(
"%s failed with: %v", c.name, e.ProcessState.
String())
}
else {
c.fatalf(
"Failed to run %s: %v", c.name, err)
}
}
// RunOrFatal
is equivalent
to Run, but handles the error with a
call to fatal
func (c
*Cmd) RunOrFatal() {
c.reportError(c.
Run())
}
// WaitOrFatal
is equivalent
to Wait, but handles the error with a
call to fatal
func (c
*Cmd) WaitOrFatal() {
c.reportError(c.Wait())
}
// OutputOrFatal
is equivalent
to Output, but handles the error with a
call to fatal
func (c
*Cmd) OutputOrFatal() []byte {
ret, err := c.Output()
c.reportError(err)
return ret
}
// CombinedOutputOrFatal
is equivalent
to CombinedOutput, but handles the error with
// a
call to fatal
func (c
*Cmd) CombinedOutputOrFatal() []byte {
ret, err := c.CombinedOutput()
c.reportError(err)
return ret
}
// RunAndPrintOrFatal will
run the command, then after finishing
//
print any output, then handling
any errors with a
call to
// fatal
func (c
*Cmd) RunAndPrintOrFatal() {
ret, err := c.CombinedOutput()
st := c.ctx.Status.StartTool()
if len(ret) >
0 {
if err != nil {
st.Error(
string(ret))
}
else {
st.
Print(
string(ret))
}
}
st.Finish()
c.reportError(err)
}
// RunAndStreamOrFatal will
run the command,
while running
print
//
any output, then handle
any errors with a
call to fatal
func (c
*Cmd) RunAndStreamOrFatal() {
out, err := c.StdoutPipe()
if err != nil {
c.fatal(err.Error())
}
c.Stderr = c.Stdout
st := c.ctx.Status.StartTool()
c.StartOrFatal()
buf := bufio.NewReaderSize(out,
2*1024*1024)
for {
// Attempt
to read whole
lines, but
write partial
lines that are too long
to fit
in the
buffer or hi
t EOF
line, err := buf.ReadString('\n')
if line != "" {
st.Print(strings.TrimSuffix(line, "\n"))
} else if err == io.EOF {
break
} else if err != nil {
c.fatal(err.Error())
}
}
err = c.Wait()
st.Finish()
c.reportError(err)
}