| 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 vpython | 5 package vpython |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "os" | 8 "os" |
| 9 | 9 |
| 10 "golang.org/x/net/context" | 10 "golang.org/x/net/context" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 // Environ is the system environment. It can be used for some default va
lues | 53 // Environ is the system environment. It can be used for some default va
lues |
| 54 // if present. | 54 // if present. |
| 55 Environ environ.Env | 55 Environ environ.Env |
| 56 } | 56 } |
| 57 | 57 |
| 58 func (o *Options) resolve(c context.Context) error { | 58 func (o *Options) resolve(c context.Context) error { |
| 59 // Resolve our working directory to an absolute path. | 59 // Resolve our working directory to an absolute path. |
| 60 if o.WorkDir == "" { | 60 if o.WorkDir == "" { |
| 61 wd, err := os.Getwd() | 61 wd, err := os.Getwd() |
| 62 if err != nil { | 62 if err != nil { |
| 63 » » » return errors.Annotate(err).Reason("failed to get workin
g directory").Err() | 63 » » » return errors.Annotate(err, "failed to get working direc
tory").Err() |
| 64 } | 64 } |
| 65 o.WorkDir = wd | 65 o.WorkDir = wd |
| 66 } | 66 } |
| 67 if err := filesystem.AbsPath(&o.WorkDir); err != nil { | 67 if err := filesystem.AbsPath(&o.WorkDir); err != nil { |
| 68 » » return errors.Annotate(err).Reason("failed to resolve absolute p
ath of WorkDir").Err() | 68 » » return errors.Annotate(err, "failed to resolve absolute path of
WorkDir").Err() |
| 69 } | 69 } |
| 70 | 70 |
| 71 // Resolve our target python script. | 71 // Resolve our target python script. |
| 72 if err := o.ResolveSpec(c); err != nil { | 72 if err := o.ResolveSpec(c); err != nil { |
| 73 » » return errors.Annotate(err).Reason("failed to resolve Python scr
ipt").Err() | 73 » » return errors.Annotate(err, "failed to resolve Python script").E
rr() |
| 74 } | 74 } |
| 75 | 75 |
| 76 // If no environment base directory was supplied, create one under the c
urrent | 76 // If no environment base directory was supplied, create one under the c
urrent |
| 77 // working directory. | 77 // working directory. |
| 78 if o.EnvConfig.BaseDir == "" { | 78 if o.EnvConfig.BaseDir == "" { |
| 79 // Is one specified in our environment? | 79 // Is one specified in our environment? |
| 80 if v, ok := o.Environ.Get(EnvironmentStampPathENV); ok { | 80 if v, ok := o.Environ.Get(EnvironmentStampPathENV); ok { |
| 81 var err error | 81 var err error |
| 82 if o.EnvConfig.BaseDir, err = venv.EnvRootFromStampPath(
v); err != nil { | 82 if o.EnvConfig.BaseDir, err = venv.EnvRootFromStampPath(
v); err != nil { |
| 83 » » » » return errors.Annotate(err).Reason("failed to ge
t env root from environment: %(path)s"). | 83 » » » » return errors.Annotate(err, "failed to get env r
oot from environment: %s", v).Err() |
| 84 » » » » » D("path", v). | |
| 85 » » » » » Err() | |
| 86 } | 84 } |
| 87 logging.Debugf(c, "Loaded environment root from environm
ent variable: %s", o.EnvConfig.BaseDir) | 85 logging.Debugf(c, "Loaded environment root from environm
ent variable: %s", o.EnvConfig.BaseDir) |
| 88 } | 86 } |
| 89 } | 87 } |
| 90 return nil | 88 return nil |
| 91 } | 89 } |
| 92 | 90 |
| 93 // ResolveSpec resolves the configured environment specification. The resulting | 91 // ResolveSpec resolves the configured environment specification. The resulting |
| 94 // spec is installed into o's EnvConfig.Spec field. | 92 // spec is installed into o's EnvConfig.Spec field. |
| 95 func (o *Options) ResolveSpec(c context.Context) error { | 93 func (o *Options) ResolveSpec(c context.Context) error { |
| 96 // If a spec is explicitly provided, we're done. | 94 // If a spec is explicitly provided, we're done. |
| 97 if o.EnvConfig.Spec != nil { | 95 if o.EnvConfig.Spec != nil { |
| 98 return nil | 96 return nil |
| 99 } | 97 } |
| 100 | 98 |
| 101 // Determine our specification from the Python command-line that we are
being | 99 // Determine our specification from the Python command-line that we are
being |
| 102 // invoked with. | 100 // invoked with. |
| 103 cmd, err := python.ParseCommandLine(o.Args) | 101 cmd, err := python.ParseCommandLine(o.Args) |
| 104 if err != nil { | 102 if err != nil { |
| 105 » » return errors.Annotate(err).Reason("failed to parse Python comma
nd-line").Err() | 103 » » return errors.Annotate(err, "failed to parse Python command-line
").Err() |
| 106 } | 104 } |
| 107 | 105 |
| 108 // If we're running a Python script, assert that the target script exist
s. | 106 // If we're running a Python script, assert that the target script exist
s. |
| 109 // Additionally, track whether it's a file or a module (directory). | 107 // Additionally, track whether it's a file or a module (directory). |
| 110 script, isScriptTarget := cmd.Target.(python.ScriptTarget) | 108 script, isScriptTarget := cmd.Target.(python.ScriptTarget) |
| 111 isModule := false | 109 isModule := false |
| 112 if isScriptTarget { | 110 if isScriptTarget { |
| 113 logging.Debugf(c, "Resolved Python target script: %s", cmd.Targe
t) | 111 logging.Debugf(c, "Resolved Python target script: %s", cmd.Targe
t) |
| 114 | 112 |
| 115 // Resolve to absolute script path. | 113 // Resolve to absolute script path. |
| 116 if err := filesystem.AbsPath(&script.Path); err != nil { | 114 if err := filesystem.AbsPath(&script.Path); err != nil { |
| 117 » » » return errors.Annotate(err).Reason("failed to get absolu
te path of: %(path)s"). | 115 » » » return errors.Annotate(err, "failed to get absolute path
of: %s", cmd.Target).Err() |
| 118 » » » » D("path", cmd.Target). | |
| 119 » » » » Err() | |
| 120 } | 116 } |
| 121 | 117 |
| 122 // Confirm that the script path actually exists. | 118 // Confirm that the script path actually exists. |
| 123 st, err := os.Stat(script.Path) | 119 st, err := os.Stat(script.Path) |
| 124 if err != nil { | 120 if err != nil { |
| 125 » » » return errors.Annotate(err).Reason("failed to stat Pytho
n script: %(path)s"). | 121 » » » return errors.Annotate(err, "failed to stat Python scrip
t: %s", cmd.Target).Err() |
| 126 » » » » D("path", cmd.Target). | |
| 127 » » » » Err() | |
| 128 } | 122 } |
| 129 | 123 |
| 130 // If the script is a directory, then we assume that we're doing
a module | 124 // If the script is a directory, then we assume that we're doing
a module |
| 131 // invocation (__main__.py). | 125 // invocation (__main__.py). |
| 132 isModule = st.IsDir() | 126 isModule = st.IsDir() |
| 133 } | 127 } |
| 134 | 128 |
| 135 // If it's a script, try resolving from filesystem first. | 129 // If it's a script, try resolving from filesystem first. |
| 136 if isScriptTarget { | 130 if isScriptTarget { |
| 137 spec, err := o.SpecLoader.LoadForScript(c, script.Path, isModule
) | 131 spec, err := o.SpecLoader.LoadForScript(c, script.Path, isModule
) |
| 138 if err != nil { | 132 if err != nil { |
| 139 » » » return errors.Annotate(err).Reason("failed to load spec
for script: %(path)s"). | 133 » » » return errors.Annotate(err, "failed to load spec for scr
ipt: %s", cmd.Target). |
| 140 » » » » D("path", cmd.Target). | 134 » » » » InternalReason("isModule(%v)", isModule).Err() |
| 141 » » » » D("isModule", isModule). | |
| 142 » » » » Err() | |
| 143 } | 135 } |
| 144 if spec != nil { | 136 if spec != nil { |
| 145 o.EnvConfig.Spec = spec | 137 o.EnvConfig.Spec = spec |
| 146 return nil | 138 return nil |
| 147 } | 139 } |
| 148 } | 140 } |
| 149 | 141 |
| 150 // Do we have a spec file in the environment? | 142 // Do we have a spec file in the environment? |
| 151 if v, ok := o.Environ.Get(EnvironmentStampPathENV); ok { | 143 if v, ok := o.Environ.Get(EnvironmentStampPathENV); ok { |
| 152 var sp vpython.Spec | 144 var sp vpython.Spec |
| 153 if err := spec.Load(v, &sp); err != nil { | 145 if err := spec.Load(v, &sp); err != nil { |
| 154 » » » return errors.Annotate(err).Reason("failed to load envir
onment-supplied spec from: %(path)s"). | 146 » » » return errors.Annotate(err, "failed to load environment-
supplied spec from: %s", v).Err() |
| 155 » » » » D("path", v). | |
| 156 » » » » Err() | |
| 157 } | 147 } |
| 158 | 148 |
| 159 logging.Infof(c, "Loaded spec from environment: %s", v) | 149 logging.Infof(c, "Loaded spec from environment: %s", v) |
| 160 o.EnvConfig.Spec = &sp | 150 o.EnvConfig.Spec = &sp |
| 161 return nil | 151 return nil |
| 162 } | 152 } |
| 163 | 153 |
| 164 // If standard resolution doesn't yield a spec, fall back on our default
spec. | 154 // If standard resolution doesn't yield a spec, fall back on our default
spec. |
| 165 logging.Infof(c, "Unable to resolve specification path. Using default sp
ecification.") | 155 logging.Infof(c, "Unable to resolve specification path. Using default sp
ecification.") |
| 166 o.EnvConfig.Spec = &o.DefaultSpec | 156 o.EnvConfig.Spec = &o.DefaultSpec |
| 167 return nil | 157 return nil |
| 168 } | 158 } |
| OLD | NEW |