| OLD | NEW |
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package application | 5 package application |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "flag" | 8 "flag" |
| 9 "fmt" | 9 "fmt" |
| 10 "io/ioutil" | 10 "io/ioutil" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 a.logConfig.AddFlags(fs) | 160 a.logConfig.AddFlags(fs) |
| 161 } | 161 } |
| 162 | 162 |
| 163 func (a *application) mainImpl(c context.Context, argv0 string, args []string) e
rror { | 163 func (a *application) mainImpl(c context.Context, argv0 string, args []string) e
rror { |
| 164 // Determine our VirtualEnv base directory. | 164 // Determine our VirtualEnv base directory. |
| 165 if v, ok := a.opts.Environ.Get(VirtualEnvRootENV); ok { | 165 if v, ok := a.opts.Environ.Get(VirtualEnvRootENV); ok { |
| 166 a.opts.EnvConfig.BaseDir = v | 166 a.opts.EnvConfig.BaseDir = v |
| 167 } else { | 167 } else { |
| 168 hdir, err := homedir.Dir() | 168 hdir, err := homedir.Dir() |
| 169 if err != nil { | 169 if err != nil { |
| 170 » » » return errors.Annotate(err).Reason("failed to get user h
ome directory").Err() | 170 » » » return errors.Annotate(err, "failed to get user home dir
ectory").Err() |
| 171 } | 171 } |
| 172 a.opts.EnvConfig.BaseDir = filepath.Join(hdir, ".vpython") | 172 a.opts.EnvConfig.BaseDir = filepath.Join(hdir, ".vpython") |
| 173 } | 173 } |
| 174 | 174 |
| 175 // Extract "vpython" arguments and parse them. | 175 // Extract "vpython" arguments and parse them. |
| 176 fs := flag.NewFlagSet("", flag.ExitOnError) | 176 fs := flag.NewFlagSet("", flag.ExitOnError) |
| 177 fs.SetOutput(os.Stdout) // Python uses STDOUT for help and flag informat
ion. | 177 fs.SetOutput(os.Stdout) // Python uses STDOUT for help and flag informat
ion. |
| 178 | 178 |
| 179 a.addToFlagSet(fs) | 179 a.addToFlagSet(fs) |
| 180 selfArgs, args := extractFlagsForSet(args, fs) | 180 selfArgs, args := extractFlagsForSet(args, fs) |
| 181 if err := fs.Parse(selfArgs); err != nil && err != flag.ErrHelp { | 181 if err := fs.Parse(selfArgs); err != nil && err != flag.ErrHelp { |
| 182 » » return errors.Annotate(err).Reason("failed to parse flags").Err(
) | 182 » » return errors.Annotate(err, "failed to parse flags").Err() |
| 183 } | 183 } |
| 184 | 184 |
| 185 // Identify the "self" executable. Use this to construct a "lookPath", w
hich | 185 // Identify the "self" executable. Use this to construct a "lookPath", w
hich |
| 186 // will be used to locate the base Python interpreter. | 186 // will be used to locate the base Python interpreter. |
| 187 lp := lookPath{ | 187 lp := lookPath{ |
| 188 probeBase: prober.Probe{ | 188 probeBase: prober.Probe{ |
| 189 RelativePathOverride: a.RelativePathOverride, | 189 RelativePathOverride: a.RelativePathOverride, |
| 190 }, | 190 }, |
| 191 env: a.opts.Environ, | 191 env: a.opts.Environ, |
| 192 } | 192 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 203 | 203 |
| 204 // If an spec path was manually specified, load and use it. | 204 // If an spec path was manually specified, load and use it. |
| 205 if a.specPath != "" { | 205 if a.specPath != "" { |
| 206 var sp vpythonAPI.Spec | 206 var sp vpythonAPI.Spec |
| 207 if err := spec.Load(a.specPath, &sp); err != nil { | 207 if err := spec.Load(a.specPath, &sp); err != nil { |
| 208 return err | 208 return err |
| 209 } | 209 } |
| 210 a.opts.EnvConfig.Spec = &sp | 210 a.opts.EnvConfig.Spec = &sp |
| 211 } else if specPath := a.opts.Environ.GetEmpty(DefaultSpecENV); specPath
!= "" { | 211 } else if specPath := a.opts.Environ.GetEmpty(DefaultSpecENV); specPath
!= "" { |
| 212 if err := spec.Load(specPath, &a.opts.DefaultSpec); err != nil { | 212 if err := spec.Load(specPath, &a.opts.DefaultSpec); err != nil { |
| 213 » » » return errors.Annotate(err). | 213 » » » return errors.Annotate(err, "failed to load default spec
ification file (%s) from %s", |
| 214 » » » » Reason("failed to load default specification fil
e ("+DefaultSpecENV+"from: %(path)s"). | 214 » » » » DefaultSpecENV, specPath).Err() |
| 215 » » » » D("path", specPath). | |
| 216 » » » » Err() | |
| 217 } | 215 } |
| 218 } | 216 } |
| 219 | 217 |
| 220 // If an empty BaseDir was specified, use a temporary directory and clea
n it | 218 // If an empty BaseDir was specified, use a temporary directory and clea
n it |
| 221 // up on completion. | 219 // up on completion. |
| 222 if a.opts.EnvConfig.BaseDir == "" { | 220 if a.opts.EnvConfig.BaseDir == "" { |
| 223 tdir, err := ioutil.TempDir("", "vpython") | 221 tdir, err := ioutil.TempDir("", "vpython") |
| 224 if err != nil { | 222 if err != nil { |
| 225 » » » return errors.Annotate(err).Reason("failed to create tem
porary directory").Err() | 223 » » » return errors.Annotate(err, "failed to create temporary
directory").Err() |
| 226 } | 224 } |
| 227 defer func() { | 225 defer func() { |
| 228 logging.Debugf(c, "Removing temporary directory: %s", td
ir) | 226 logging.Debugf(c, "Removing temporary directory: %s", td
ir) |
| 229 if terr := filesystem.RemoveAll(tdir); terr != nil { | 227 if terr := filesystem.RemoveAll(tdir); terr != nil { |
| 230 logging.WithError(terr).Warningf(c, "Failed to c
lean up temporary directory; leaking: %s", tdir) | 228 logging.WithError(terr).Warningf(c, "Failed to c
lean up temporary directory; leaking: %s", tdir) |
| 231 } | 229 } |
| 232 }() | 230 }() |
| 233 a.opts.EnvConfig.BaseDir = tdir | 231 a.opts.EnvConfig.BaseDir = tdir |
| 234 } | 232 } |
| 235 | 233 |
| 236 // Development mode (subcommands). | 234 // Development mode (subcommands). |
| 237 if a.devMode { | 235 if a.devMode { |
| 238 return a.mainDev(c, args) | 236 return a.mainDev(c, args) |
| 239 } | 237 } |
| 240 | 238 |
| 241 a.opts.Args = args | 239 a.opts.Args = args |
| 242 if err := vpython.Run(c, a.opts); err != nil { | 240 if err := vpython.Run(c, a.opts); err != nil { |
| 243 // If the process failed because of a non-zero return value, ret
urn that | 241 // If the process failed because of a non-zero return value, ret
urn that |
| 244 // as our error. | 242 // as our error. |
| 245 if rc, has := exitcode.Get(errors.Unwrap(err)); has { | 243 if rc, has := exitcode.Get(errors.Unwrap(err)); has { |
| 246 err = ReturnCodeError(rc) | 244 err = ReturnCodeError(rc) |
| 247 } | 245 } |
| 248 | 246 |
| 249 » » return errors.Annotate(err).Err() | 247 » » return errors.Annotate(err, "").Err() |
| 250 } | 248 } |
| 251 return nil | 249 return nil |
| 252 } | 250 } |
| 253 | 251 |
| 254 func (a *application) showPythonHelp(c context.Context, fs *flag.FlagSet, lp *lo
okPath) error { | 252 func (a *application) showPythonHelp(c context.Context, fs *flag.FlagSet, lp *lo
okPath) error { |
| 255 self, err := os.Executable() | 253 self, err := os.Executable() |
| 256 if err != nil { | 254 if err != nil { |
| 257 self = "vpython" | 255 self = "vpython" |
| 258 } | 256 } |
| 259 vers, err := cipdVersion.GetStartupVersion() | 257 vers, err := cipdVersion.GetStartupVersion() |
| 260 if err == nil && vers.PackageName != "" && vers.InstanceID != "" { | 258 if err == nil && vers.PackageName != "" && vers.InstanceID != "" { |
| 261 self = fmt.Sprintf("%s (%s@%s)", self, vers.PackageName, vers.In
stanceID) | 259 self = fmt.Sprintf("%s (%s@%s)", self, vers.PackageName, vers.In
stanceID) |
| 262 } | 260 } |
| 263 | 261 |
| 264 fmt.Fprintf(os.Stdout, "Usage of %s:\n", self) | 262 fmt.Fprintf(os.Stdout, "Usage of %s:\n", self) |
| 265 fs.SetOutput(os.Stdout) | 263 fs.SetOutput(os.Stdout) |
| 266 fs.PrintDefaults() | 264 fs.PrintDefaults() |
| 267 | 265 |
| 268 i, err := python.Find(c, python.Version{}, lp.look) | 266 i, err := python.Find(c, python.Version{}, lp.look) |
| 269 if err != nil { | 267 if err != nil { |
| 270 » » return errors.Annotate(err).Reason("could not find Python interp
reter for help").Err() | 268 » » return errors.Annotate(err, "could not find Python interpreter f
or help").Err() |
| 271 } | 269 } |
| 272 | 270 |
| 273 // Redirect all "--help" to Stdout for consistency. | 271 // Redirect all "--help" to Stdout for consistency. |
| 274 fmt.Fprintf(os.Stdout, "\nPython help for %s:\n", i.Python) | 272 fmt.Fprintf(os.Stdout, "\nPython help for %s:\n", i.Python) |
| 275 cmd := i.IsolatedCommand(c, "--help") | 273 cmd := i.IsolatedCommand(c, "--help") |
| 276 cmd.Stdout = os.Stdout | 274 cmd.Stdout = os.Stdout |
| 277 cmd.Stderr = os.Stdout | 275 cmd.Stderr = os.Stdout |
| 278 if err := cmd.Run(); err != nil { | 276 if err := cmd.Run(); err != nil { |
| 279 » » return errors.Annotate(err).Reason("failed to dump Python help f
rom: %(interpreter)s"). | 277 » » return errors.Annotate(err, "failed to dump Python help from: %s
", i.Python).Err() |
| 280 » » » D("interpreter", i.Python). | |
| 281 » » » Err() | |
| 282 } | 278 } |
| 283 return nil | 279 return nil |
| 284 } | 280 } |
| 285 | 281 |
| 286 // Main is the main application entry point. | 282 // Main is the main application entry point. |
| 287 func (cfg *Config) Main(c context.Context) int { | 283 func (cfg *Config) Main(c context.Context) int { |
| 288 // Implementation of "checkWrapper": if CheckWrapperENV is set, we immed
iately | 284 // Implementation of "checkWrapper": if CheckWrapperENV is set, we immed
iately |
| 289 // exit with a non-zero value. | 285 // exit with a non-zero value. |
| 290 env := environ.System() | 286 env := environ.System() |
| 291 if wrapperCheck(env) { | 287 if wrapperCheck(env) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 312 }, | 308 }, |
| 313 logConfig: logging.Config{ | 309 logConfig: logging.Config{ |
| 314 Level: logging.Error, | 310 Level: logging.Error, |
| 315 }, | 311 }, |
| 316 } | 312 } |
| 317 | 313 |
| 318 return run(c, func(c context.Context) error { | 314 return run(c, func(c context.Context) error { |
| 319 return a.mainImpl(c, os.Args[0], os.Args[1:]) | 315 return a.mainImpl(c, os.Args[0], os.Args[1:]) |
| 320 }) | 316 }) |
| 321 } | 317 } |
| OLD | NEW |