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

Side by Side Diff: vpython/venv/config.go

Issue 2905943002: [vpython] Incorporate interpreter path/hash. (Closed)
Patch Set: Created 3 years, 6 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/spec/spec_test.go ('k') | vpython/venv/venv.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 venv 5 package venv
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "os" 9 "os"
10 "path/filepath" 10 "path/filepath"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // 67 //
68 // This can be used to enforce "shebang" length limits, whereupon genera ted 68 // This can be used to enforce "shebang" length limits, whereupon genera ted
69 // VirtualEnv scripts may be generated with a "shebang" (#!) line longer than 69 // VirtualEnv scripts may be generated with a "shebang" (#!) line longer than
70 // what is allowed by the operating system. 70 // what is allowed by the operating system.
71 MaxScriptPathLen int 71 MaxScriptPathLen int
72 72
73 // si is the system Python interpreter. It is resolved during 73 // si is the system Python interpreter. It is resolved during
74 // "resolvePythonInterpreter". 74 // "resolvePythonInterpreter".
75 si *python.Interpreter 75 si *python.Interpreter
76 76
77 // rt is the resolved Python runtime.
78 rt vpython.Runtime
79
77 // testPreserveInstallationCapability is a testing parameter. If true, t he 80 // testPreserveInstallationCapability is a testing parameter. If true, t he
78 // VirtualEnv's ability to install will be preserved after the setup. Th is is 81 // VirtualEnv's ability to install will be preserved after the setup. Th is is
79 // used by the test whell generation bootstrap code. 82 // used by the test whell generation bootstrap code.
80 testPreserveInstallationCapability bool 83 testPreserveInstallationCapability bool
81 84
82 // testLeaveReadWrite, if true, instructs the VirtualEnv setup to leave the 85 // testLeaveReadWrite, if true, instructs the VirtualEnv setup to leave the
83 // directory read/write. This makes it easier to manage, and is safe sin ce it 86 // directory read/write. This makes it easier to manage, and is safe sin ce it
84 // is not a production directory. 87 // is not a production directory.
85 testLeaveReadWrite bool 88 testLeaveReadWrite bool
86 } 89 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 e = e.Clone() 164 e = e.Clone()
162 e.Spec = cfg.Spec.Clone() 165 e.Spec = cfg.Spec.Clone()
163 166
164 if err := cfg.Loader.Resolve(c, e); err != nil { 167 if err := cfg.Loader.Resolve(c, e); err != nil {
165 return nil, errors.Annotate(err).Reason("failed to resolve packa ges").Err() 168 return nil, errors.Annotate(err).Reason("failed to resolve packa ges").Err()
166 } 169 }
167 170
168 if err := cfg.resolvePythonInterpreter(c, e.Spec); err != nil { 171 if err := cfg.resolvePythonInterpreter(c, e.Spec); err != nil {
169 return nil, errors.Annotate(err).Reason("failed to resolve syste m Python interpreter").Err() 172 return nil, errors.Annotate(err).Reason("failed to resolve syste m Python interpreter").Err()
170 } 173 }
174 rt := vpython.Runtime{
175 Path: cfg.si.Python,
176 Version: e.Spec.PythonVersion,
177 }
178
179 var err error
180 if rt.Hash, err = cfg.si.Hash(); err != nil {
181 return nil, err
182 }
183 e.Runtime = &rt
184 logging.Debugf(c, "Resolved system Python runtime (%s @ %s): %s", rt.Ver sion, rt.Hash, rt.Path)
171 185
172 // Ensure that our base directory exists. 186 // Ensure that our base directory exists.
173 if err := filesystem.MakeDirs(cfg.BaseDir); err != nil { 187 if err := filesystem.MakeDirs(cfg.BaseDir); err != nil {
174 return nil, errors.Annotate(err).Reason("could not create enviro nment root: %(root)s"). 188 return nil, errors.Annotate(err).Reason("could not create enviro nment root: %(root)s").
175 D("root", cfg.BaseDir). 189 D("root", cfg.BaseDir).
176 Err() 190 Err()
177 } 191 }
178 192
179 // Generate our environment name based on the deterministic hash of its 193 // Generate our environment name based on the deterministic hash of its
180 // fully-resolved specification. 194 // fully-resolved specification.
181 » return cfg.envForName(cfg.envNameForSpec(e.Spec), e), nil 195 » return cfg.envForName(cfg.envNameForSpec(e.Spec, e.Runtime), e), nil
182 } 196 }
183 197
184 // EnvName returns the VirtualEnv environment name for the environment that cfg 198 // EnvName returns the VirtualEnv environment name for the environment that cfg
185 // describes. 199 // describes.
186 func (cfg *Config) envNameForSpec(s *vpython.Spec) string { 200 func (cfg *Config) envNameForSpec(s *vpython.Spec, rt *vpython.Runtime) string {
187 » name := spec.Hash(s, EnvironmentVersion) 201 » name := spec.Hash(s, rt, EnvironmentVersion)
188 if cfg.MaxHashLen > 0 && len(name) > cfg.MaxHashLen { 202 if cfg.MaxHashLen > 0 && len(name) > cfg.MaxHashLen {
189 name = name[:cfg.MaxHashLen] 203 name = name[:cfg.MaxHashLen]
190 } 204 }
191 return name 205 return name
192 } 206 }
193 207
194 // Prune performs a pruning round on the environment set described by this 208 // Prune performs a pruning round on the environment set described by this
195 // Config. 209 // Config.
196 func (cfg *Config) Prune(c context.Context) error { 210 func (cfg *Config) Prune(c context.Context) error {
197 if err := prune(c, cfg, nil); err != nil { 211 if err := prune(c, cfg, nil); err != nil {
198 return errors.Annotate(err).Err() 212 return errors.Annotate(err).Err()
199 } 213 }
200 return nil 214 return nil
201 } 215 }
202 216
203 // envForName creates an Env for a named directory. 217 // envForName creates an Env for a named directory.
218 //
219 // The Environment, e, can be nil; however, code paths that require it may not
220 // be called.
204 func (cfg *Config) envForName(name string, e *vpython.Environment) *Env { 221 func (cfg *Config) envForName(name string, e *vpython.Environment) *Env {
205 // Env-specific root directory: <BaseDir>/<name> 222 // Env-specific root directory: <BaseDir>/<name>
206 venvRoot := filepath.Join(cfg.BaseDir, name) 223 venvRoot := filepath.Join(cfg.BaseDir, name)
207 binDir := venvBinDir(venvRoot) 224 binDir := venvBinDir(venvRoot)
208 return &Env{ 225 return &Env{
209 Config: cfg, 226 Config: cfg,
210 Root: venvRoot, 227 Root: venvRoot,
211 Name: name, 228 Name: name,
212 Python: filepath.Join(binDir, "python"), 229 Python: filepath.Join(binDir, "python"),
213 Environment: e, 230 Environment: e,
(...skipping 20 matching lines...) Expand all
234 return errors.Annotate(err).Reason("could not find Pytho n for: %(vers)s"). 251 return errors.Annotate(err).Reason("could not find Pytho n for: %(vers)s").
235 D("vers", specVers). 252 D("vers", specVers).
236 Err() 253 Err()
237 } 254 }
238 cfg.Python = cfg.si.Python 255 cfg.Python = cfg.si.Python
239 } else { 256 } else {
240 cfg.si = &python.Interpreter{ 257 cfg.si = &python.Interpreter{
241 Python: cfg.Python, 258 Python: cfg.Python,
242 } 259 }
243 } 260 }
261 if err := cfg.si.Normalize(); err != nil {
262 return err
263 }
244 264
245 // Confirm that the version of the interpreter matches that which is 265 // Confirm that the version of the interpreter matches that which is
246 // expected. 266 // expected.
247 interpreterVers, err := cfg.si.GetVersion(c) 267 interpreterVers, err := cfg.si.GetVersion(c)
248 if err != nil { 268 if err != nil {
249 return errors.Annotate(err).Reason("failed to determine Python v ersion for: %(python)s"). 269 return errors.Annotate(err).Reason("failed to determine Python v ersion for: %(python)s").
250 D("python", cfg.Python). 270 D("python", cfg.Python).
251 Err() 271 Err()
252 } 272 }
253 if !specVers.IsSatisfiedBy(interpreterVers) { 273 if !specVers.IsSatisfiedBy(interpreterVers) {
254 return errors.Reason("supplied Python version (%(supplied)s) doe sn't match specification (%(spec)s)"). 274 return errors.Reason("supplied Python version (%(supplied)s) doe sn't match specification (%(spec)s)").
255 D("supplied", interpreterVers). 275 D("supplied", interpreterVers).
256 D("spec", specVers). 276 D("spec", specVers).
257 Err() 277 Err()
258 } 278 }
259 s.PythonVersion = interpreterVers.String() 279 s.PythonVersion = interpreterVers.String()
260 280
261 // Resolve to absolute path. 281 // Resolve to absolute path.
262 if err := filesystem.AbsPath(&cfg.Python); err != nil { 282 if err := filesystem.AbsPath(&cfg.Python); err != nil {
263 return errors.Annotate(err).Reason("could not get absolute path for: %(python)s"). 283 return errors.Annotate(err).Reason("could not get absolute path for: %(python)s").
264 D("python", cfg.Python). 284 D("python", cfg.Python).
265 Err() 285 Err()
266 } 286 }
267 logging.Debugf(c, "Resolved system Python interpreter (%s): %s", s.Pytho nVersion, cfg.Python)
268 return nil 287 return nil
269 } 288 }
270 289
271 func (cfg *Config) systemInterpreter() *python.Interpreter { return cfg.si } 290 func (cfg *Config) systemInterpreter() *python.Interpreter { return cfg.si }
OLDNEW
« no previous file with comments | « vpython/spec/spec_test.go ('k') | vpython/venv/venv.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698