Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: vpython/options.go

Issue 2702873002: vpython: Add primary execution package. (Closed)
Patch Set: more windows signals Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « vpython/doc.go ('k') | vpython/python/interpreter.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package vpython
6
7 import (
8 "context"
9 "os"
10
11 "github.com/luci/luci-go/vpython/python"
12 "github.com/luci/luci-go/vpython/spec"
13 "github.com/luci/luci-go/vpython/venv"
14
15 "github.com/luci/luci-go/common/errors"
16 "github.com/luci/luci-go/common/logging"
17 "github.com/luci/luci-go/common/system/environ"
18 "github.com/luci/luci-go/common/system/filesystem"
19 )
20
21 // Options is the set of options to use to construct and execute a VirtualEnv
22 // Python application.
23 type Options struct {
24 // EnvConfig is the VirtualEnv configuration to run from.
25 EnvConfig venv.Config
26
27 // Args are the arguments to forward to the Python process.
28 Args []string
29
30 // WaitForEnv, if true, means that if another agent holds a lock on the target
31 // environment, we will wait until it is available. If false, we will
32 // immediately exit Setup with an error.
33 WaitForEnv bool
34
35 // WorkDir is the Python working directory. If empty, the current workin g
36 // directory will be used.
37 //
38 // If EnvRoot is empty, WorkDir will be used as the base enviornment roo t.
39 WorkDir string
40
41 // Environ is the system environment. It can be used for some default va lues
42 // if present.
43 Environ environ.Env
44 }
45
46 func (o *Options) resolve(c context.Context) error {
47 // Resolve our working directory to an absolute path.
48 if o.WorkDir == "" {
49 wd, err := os.Getwd()
50 if err != nil {
51 return errors.Annotate(err).Reason("failed to get workin g directory").Err()
52 }
53 o.WorkDir = wd
54 }
55 if err := filesystem.AbsPath(&o.WorkDir); err != nil {
56 return errors.Annotate(err).Reason("failed to resolve absolute p ath of WorkDir").Err()
57 }
58
59 // Resolve our target python script.
60 if err := o.resolveEnvSpec(c); err != nil {
61 return errors.Annotate(err).Reason("failed to resolve Python scr ipt").Err()
62 }
63
64 // If no enviornment base directory was supplied, create one under the c urrent
65 // working directory.
66 if o.EnvConfig.BaseDir == "" {
67 // Is one specified in our environment?
68 if v, ok := o.Environ.Get(EnvSpecPath); ok {
69 var err error
70 if o.EnvConfig.BaseDir, err = venv.EnvRootFromSpecPath(v ); err != nil {
71 return errors.Annotate(err).Reason("failed to ge t env root from environment: %(path)s").
72 D("path", v).
73 Err()
74 }
75 logging.Debugf(c, "Loaded environment root from environm ent variable: %s", o.EnvConfig.BaseDir)
76 }
77 }
78 return nil
79 }
80
81 func (o *Options) resolveEnvSpec(c context.Context) error {
82 cmd, err := python.ParseCommandLine(o.Args)
83 if err != nil {
84 return errors.Annotate(err).Reason("failed to parse Python comma nd-line").Err()
85 }
86
87 // If we're running a Python script, assert that the target script exist s.
88 // Additionally, track whether it's a file or a module (directory).
89 script, isScriptTarget := cmd.Target.(python.ScriptTarget)
90 isModule := false
91 if isScriptTarget {
92 logging.Debugf(c, "Resolved Python target script: %s", cmd.Targe t)
93
94 // Resolve to absolute script path.
95 if err := filesystem.AbsPath(&script.Path); err != nil {
96 return errors.Annotate(err).Reason("failed to get absolu te path of: %(path)s").
97 D("path", cmd.Target).
98 Err()
99 }
100
101 // Confirm that the script path actually exists.
102 st, err := os.Stat(script.Path)
103 if err != nil {
104 return errors.Annotate(err).Reason("failed to stat Pytho n script: %(path)s").
105 D("path", cmd.Target).
106 Err()
107 }
108
109 // If the script is a directory, then we assume that we're doing a module
110 // invocation (__main__.py).
111 isModule = st.IsDir()
112 }
113
114 // If a spec is explicitly provided, we're done.
115 if o.EnvConfig.Spec != nil {
116 return nil
117 }
118
119 // If it's a script, try resolving from filesystem first.
120 if isScriptTarget {
121 spec, err := spec.LoadForScript(c, script.Path, isModule)
122 if err != nil {
123 return errors.Annotate(err).Reason("failed to load spec for script: %(path)s").
124 D("path", cmd.Target).
125 D("isModule", isModule).
126 Err()
127 }
128 if spec != nil {
129 o.EnvConfig.Spec = spec
130 return nil
131 }
132 }
133
134 // Do we have a spec file in the enviornment?
135 if v, ok := o.Environ.Get(EnvSpecPath); ok {
136 if o.EnvConfig.Spec, err = spec.Load(v); err != nil {
137 return errors.Annotate(err).Reason("failed to load envio rnment-supplied spec from: %(path)s").
138 D("path", v).
139 Err()
140 }
141 logging.Infof(c, "Loaded spec from environment: %s", v)
142 return nil
143 }
144
145 // Unable to load a spec.
146 logging.Infof(c, "Unable to resolve specification path. Using empty spec ification.")
147 return nil
148 }
OLDNEW
« no previous file with comments | « vpython/doc.go ('k') | vpython/python/interpreter.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698