v.io/jiri@v0.0.0-20160715023856-abfb8b131290/tool/context.go (about) 1 // Copyright 2015 The Vanadium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tool 6 7 import ( 8 "io" 9 "net/url" 10 "os" 11 12 "v.io/jiri/gerrit" 13 "v.io/jiri/jenkins" 14 "v.io/jiri/runutil" 15 "v.io/x/lib/cmdline" 16 "v.io/x/lib/envvar" 17 "v.io/x/lib/timing" 18 ) 19 20 // Context represents an execution context of a tool command 21 // invocation. Its purpose is to enable sharing of state throughout 22 // the lifetime of a command invocation. 23 type Context struct { 24 opts ContextOpts 25 } 26 27 // ContextOpts records the context options. 28 type ContextOpts struct { 29 Color *bool 30 Manifest *string 31 Env map[string]string 32 Stdin io.Reader 33 Stdout io.Writer 34 Stderr io.Writer 35 Verbose *bool 36 Timer *timing.Timer 37 } 38 39 // newContextOpts is the ContextOpts factory. 40 func newContextOpts() *ContextOpts { 41 return &ContextOpts{ 42 Color: &ColorFlag, 43 Env: map[string]string{}, 44 Manifest: &ManifestFlag, 45 Stdin: os.Stdin, 46 Stdout: os.Stdout, 47 Stderr: os.Stderr, 48 Verbose: &VerboseFlag, 49 Timer: nil, 50 } 51 } 52 53 // initOpts initializes all unset options to the given defaults. 54 func initOpts(defaultOpts, opts *ContextOpts) { 55 if opts.Color == nil { 56 opts.Color = defaultOpts.Color 57 } 58 if opts.Env == nil { 59 opts.Env = defaultOpts.Env 60 } 61 if opts.Manifest == nil { 62 opts.Manifest = defaultOpts.Manifest 63 } 64 if opts.Stdin == nil { 65 opts.Stdin = defaultOpts.Stdin 66 } 67 if opts.Stdout == nil { 68 opts.Stdout = defaultOpts.Stdout 69 } 70 if opts.Stderr == nil { 71 opts.Stderr = defaultOpts.Stderr 72 } 73 if opts.Verbose == nil { 74 opts.Verbose = defaultOpts.Verbose 75 } 76 if opts.Timer == nil { 77 opts.Timer = defaultOpts.Timer 78 } 79 } 80 81 // NewContext is the Context factory. 82 func NewContext(opts ContextOpts) *Context { 83 initOpts(newContextOpts(), &opts) 84 return &Context{opts: opts} 85 } 86 87 // NewContextFromEnv returns a new context instance based on the given 88 // cmdline environment. 89 func NewContextFromEnv(env *cmdline.Env) *Context { 90 opts := ContextOpts{} 91 initOpts(newContextOpts(), &opts) 92 opts.Env = envvar.CopyMap(env.Vars) 93 opts.Stdin = env.Stdin 94 opts.Stdout = env.Stdout 95 opts.Stderr = env.Stderr 96 opts.Timer = env.Timer 97 return NewContext(opts) 98 } 99 100 // NewDefaultContext returns a new default context. 101 func NewDefaultContext() *Context { 102 return NewContext(ContextOpts{}) 103 } 104 105 // Clone creates a clone of the given context, overriding select 106 // settings using the given options. 107 func (ctx Context) Clone(opts ContextOpts) *Context { 108 initOpts(&ctx.opts, &opts) 109 return NewContext(opts) 110 } 111 112 // Color returns the color setting of the context. 113 func (ctx Context) Color() bool { 114 return *ctx.opts.Color 115 } 116 117 // Env returns the environment of the context. 118 func (ctx Context) Env() map[string]string { 119 return ctx.opts.Env 120 } 121 122 // Gerrit returns the Gerrit instance of the context. 123 func (ctx Context) Gerrit(host *url.URL) *gerrit.Gerrit { 124 return gerrit.New(ctx.NewSeq(), host) 125 } 126 127 // Jenkins returns a new Jenkins instance that can be used to 128 // communicate with a Jenkins server running at the given host. 129 func (ctx Context) Jenkins(host string) (*jenkins.Jenkins, error) { 130 return jenkins.New(host) 131 } 132 133 // Manifest returns the manifest of the context. 134 func (ctx Context) Manifest() string { 135 return *ctx.opts.Manifest 136 } 137 138 // NewSeq returns a new instance of Sequence initialized using the options 139 // stored in the context. 140 func (ctx Context) NewSeq() runutil.Sequence { 141 return runutil.NewSequence(ctx.opts.Env, ctx.opts.Stdin, ctx.opts.Stdout, ctx.opts.Stderr, *ctx.opts.Color, *ctx.opts.Verbose) 142 } 143 144 // Stdin returns the standard input of the context. 145 func (ctx Context) Stdin() io.Reader { 146 return ctx.opts.Stdin 147 } 148 149 // Stdout returns the standard output of the context. 150 func (ctx Context) Stdout() io.Writer { 151 return ctx.opts.Stdout 152 } 153 154 // Stderr returns the standard error output of the context. 155 func (ctx Context) Stderr() io.Writer { 156 return ctx.opts.Stderr 157 } 158 159 // Verbose returns the verbosity setting of the context. 160 func (ctx Context) Verbose() bool { 161 return *ctx.opts.Verbose 162 } 163 164 // Timer returns the timer associated with the context, which may be nil. 165 func (ctx Context) Timer() *timing.Timer { 166 return ctx.opts.Timer 167 } 168 169 // TimerPush calls ctx.Timer().Push(name), only if the Timer is non-nil. 170 func (ctx Context) TimerPush(name string) { 171 if ctx.opts.Timer != nil { 172 ctx.opts.Timer.Push(name) 173 } 174 } 175 176 // TimerPop calls ctx.Timer().Pop(), only if the Timer is non-nil. 177 func (ctx Context) TimerPop() { 178 if ctx.opts.Timer != nil { 179 ctx.opts.Timer.Pop() 180 } 181 }