forked from toolshed/abra
chore: go mod vendor / tidy
This commit is contained in:
171
vendor/github.com/mmcloughlin/avo/build/cli.go
generated
vendored
Normal file
171
vendor/github.com/mmcloughlin/avo/build/cli.go
generated
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
|
||||
"github.com/mmcloughlin/avo/pass"
|
||||
"github.com/mmcloughlin/avo/printer"
|
||||
)
|
||||
|
||||
// Config contains options for an avo main function.
|
||||
type Config struct {
|
||||
ErrOut io.Writer
|
||||
MaxErrors int // max errors to report; 0 means unlimited
|
||||
CPUProfile io.WriteCloser
|
||||
Passes []pass.Interface
|
||||
}
|
||||
|
||||
// Main is the standard main function for an avo program. This extracts the
|
||||
// result from the build Context (logging and exiting on error), and performs
|
||||
// configured passes.
|
||||
func Main(cfg *Config, context *Context) int {
|
||||
diag := log.New(cfg.ErrOut, "", 0)
|
||||
|
||||
if cfg.CPUProfile != nil {
|
||||
defer cfg.CPUProfile.Close()
|
||||
if err := pprof.StartCPUProfile(cfg.CPUProfile); err != nil {
|
||||
diag.Println("could not start CPU profile: ", err)
|
||||
return 1
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
f, err := context.Result()
|
||||
if err != nil {
|
||||
LogError(diag, err, cfg.MaxErrors)
|
||||
return 1
|
||||
}
|
||||
|
||||
p := pass.Concat(cfg.Passes...)
|
||||
if err := p.Execute(f); err != nil {
|
||||
diag.Println(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Flags represents CLI flags for an avo program.
|
||||
type Flags struct {
|
||||
errout *outputValue
|
||||
allerrors bool
|
||||
cpuprof *outputValue
|
||||
pkg string
|
||||
printers []*printerValue
|
||||
}
|
||||
|
||||
// NewFlags initializes avo flags for the given FlagSet.
|
||||
func NewFlags(fs *flag.FlagSet) *Flags {
|
||||
f := &Flags{}
|
||||
|
||||
f.errout = newOutputValue(os.Stderr)
|
||||
fs.Var(f.errout, "log", "diagnostics output")
|
||||
|
||||
fs.BoolVar(&f.allerrors, "e", false, "no limit on number of errors reported")
|
||||
|
||||
f.cpuprof = newOutputValue(nil)
|
||||
fs.Var(f.cpuprof, "cpuprofile", "write cpu profile to `file`")
|
||||
|
||||
fs.StringVar(&f.pkg, "pkg", "", "package name (defaults to current directory name)")
|
||||
|
||||
goasm := newPrinterValue(printer.NewGoAsm, os.Stdout)
|
||||
fs.Var(goasm, "out", "assembly output")
|
||||
f.printers = append(f.printers, goasm)
|
||||
|
||||
stubs := newPrinterValue(printer.NewStubs, nil)
|
||||
fs.Var(stubs, "stubs", "go stub file")
|
||||
f.printers = append(f.printers, stubs)
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// Config builds a configuration object based on flag values.
|
||||
func (f *Flags) Config() *Config {
|
||||
pc := printer.NewGoRunConfig()
|
||||
if f.pkg != "" {
|
||||
pc.Pkg = f.pkg
|
||||
}
|
||||
passes := []pass.Interface{pass.Compile}
|
||||
for _, pv := range f.printers {
|
||||
p := pv.Build(pc)
|
||||
if p != nil {
|
||||
passes = append(passes, p)
|
||||
}
|
||||
}
|
||||
|
||||
cfg := &Config{
|
||||
ErrOut: f.errout.w,
|
||||
MaxErrors: 10,
|
||||
CPUProfile: f.cpuprof.w,
|
||||
Passes: passes,
|
||||
}
|
||||
|
||||
if f.allerrors {
|
||||
cfg.MaxErrors = 0
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type outputValue struct {
|
||||
w io.WriteCloser
|
||||
filename string
|
||||
}
|
||||
|
||||
func newOutputValue(dflt io.WriteCloser) *outputValue {
|
||||
return &outputValue{w: dflt}
|
||||
}
|
||||
|
||||
func (o *outputValue) String() string {
|
||||
if o == nil {
|
||||
return ""
|
||||
}
|
||||
return o.filename
|
||||
}
|
||||
|
||||
func (o *outputValue) Set(s string) error {
|
||||
o.filename = s
|
||||
if s == "-" {
|
||||
o.w = nopwritecloser{os.Stdout}
|
||||
return nil
|
||||
}
|
||||
f, err := os.Create(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.w = f
|
||||
return nil
|
||||
}
|
||||
|
||||
type printerValue struct {
|
||||
*outputValue
|
||||
Builder printer.Builder
|
||||
}
|
||||
|
||||
func newPrinterValue(b printer.Builder, dflt io.WriteCloser) *printerValue {
|
||||
return &printerValue{
|
||||
outputValue: newOutputValue(dflt),
|
||||
Builder: b,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *printerValue) Build(cfg printer.Config) pass.Interface {
|
||||
if p.outputValue.w == nil {
|
||||
return nil
|
||||
}
|
||||
return &pass.Output{
|
||||
Writer: p.outputValue.w,
|
||||
Printer: p.Builder(cfg),
|
||||
}
|
||||
}
|
||||
|
||||
// nopwritecloser wraps a Writer and provides a null implementation of Close().
|
||||
type nopwritecloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (nopwritecloser) Close() error { return nil }
|
Reference in New Issue
Block a user