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

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

Issue 2918623003: [vpython] Verify environment, named installs. (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 15 matching lines...) Expand all
26 // 26 //
27 // A VirtualEnv is specified based on its resolved vpython.Spec. 27 // A VirtualEnv is specified based on its resolved vpython.Spec.
28 type Config struct { 28 type Config struct {
29 // MaxHashLen is the maximum number of hash characters to use in Virtual Env 29 // MaxHashLen is the maximum number of hash characters to use in Virtual Env
30 // directory names. 30 // directory names.
31 MaxHashLen int 31 MaxHashLen int
32 32
33 // BaseDir is the parent directory of all VirtualEnv. 33 // BaseDir is the parent directory of all VirtualEnv.
34 BaseDir string 34 BaseDir string
35 35
36 // OverrideName overrides the name of the specified VirtualEnv.
37 //
38 // Because the name is no longer derived from the specification, this wi ll
39 // force revalidation and deletion of any existing content if it is not a
40 // fully defined and matching VirtualEnv
41 OverrideName string
42
36 // Package is the VirtualEnv package to install. It must be non-nil and 43 // Package is the VirtualEnv package to install. It must be non-nil and
37 // valid. It will be used if the environment specification doesn't suppl y an 44 // valid. It will be used if the environment specification doesn't suppl y an
38 // overriding one. 45 // overriding one.
39 Package vpython.Spec_Package 46 Package vpython.Spec_Package
40 47
41 // Python is the Python interpreter to use. If empty, one will be resolv ed 48 // Python is the Python interpreter to use. If empty, one will be resolv ed
42 // based on the Spec and the current PATH. 49 // based on the Spec and the current PATH.
43 Python string 50 Python string
44 51
45 // Spec is the specification file to use to construct the VirtualEnv. If 52 // Spec is the specification file to use to construct the VirtualEnv. If
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 97
91 // WithoutWheels returns a clone of cfg that depends on no additional packages. 98 // WithoutWheels returns a clone of cfg that depends on no additional packages.
92 // 99 //
93 // If cfg is already an empty it will be returned directly. 100 // If cfg is already an empty it will be returned directly.
94 func (cfg *Config) WithoutWheels() *Config { 101 func (cfg *Config) WithoutWheels() *Config {
95 if !cfg.HasWheels() { 102 if !cfg.HasWheels() {
96 return cfg 103 return cfg
97 } 104 }
98 105
99 clone := *cfg 106 clone := *cfg
107 clone.OverrideName = ""
100 clone.Spec = clone.Spec.Clone() 108 clone.Spec = clone.Spec.Clone()
101 clone.Spec.Wheel = nil 109 clone.Spec.Wheel = nil
102 return &clone 110 return &clone
103 } 111 }
104 112
105 // HasWheels returns true if this environment declares wheel dependencies. 113 // HasWheels returns true if this environment declares wheel dependencies.
106 func (cfg *Config) HasWheels() bool { 114 func (cfg *Config) HasWheels() bool {
107 return cfg.Spec != nil && len(cfg.Spec.Wheel) > 0 115 return cfg.Spec != nil && len(cfg.Spec.Wheel) > 0
108 } 116 }
109 117
(...skipping 28 matching lines...) Expand all
138 if longestPathLen > cfg.MaxScriptPathLen { 146 if longestPathLen > cfg.MaxScriptPathLen {
139 return nil, errors.Reason("expected deepest path length (%(len)d) exceeds threshold (%(threshold)d)"). 147 return nil, errors.Reason("expected deepest path length (%(len)d) exceeds threshold (%(threshold)d)").
140 D("len", longestPathLen). 148 D("len", longestPathLen).
141 D("threshold", cfg.MaxScriptPathLen). 149 D("threshold", cfg.MaxScriptPathLen).
142 D("longestPath", longestPath). 150 D("longestPath", longestPath).
143 Err() 151 Err()
144 } 152 }
145 } 153 }
146 } 154 }
147 155
148 // Ensure and normalize our specification file.
149 if cfg.Spec == nil {
150 cfg.Spec = &vpython.Spec{}
151 } else {
152 cfg.Spec = cfg.Spec.Clone()
153 }
154 if err := spec.Normalize(cfg.Spec, &cfg.Package); err != nil {
155 return nil, errors.Annotate(err).Reason("invalid specification") .Err()
156 }
157
158 // Choose our VirtualEnv package.
159 if cfg.Spec.Virtualenv == nil {
160 cfg.Spec.Virtualenv = &cfg.Package
161 }
162
163 // Construct a new, independent Environment for this Env. 156 // Construct a new, independent Environment for this Env.
164 e = e.Clone() 157 e = e.Clone()
165 » e.Spec = cfg.Spec.Clone() 158 » if cfg.Spec != nil {
159 » » e.Spec = cfg.Spec.Clone()
160 » }
161 » if err := spec.NormalizeEnvironment(e); err != nil {
162 » » return nil, errors.Annotate(err).Reason("invalid environment").E rr()
163 » }
164
165 » // If the environment doesn't specify a VirtualEnv package (expected), u se
166 » // our default.
167 » if e.Spec.Virtualenv == nil {
168 » » e.Spec.Virtualenv = &cfg.Package
169 » }
166 170
167 if err := cfg.Loader.Resolve(c, e); err != nil { 171 if err := cfg.Loader.Resolve(c, e); err != nil {
168 return nil, errors.Annotate(err).Reason("failed to resolve packa ges").Err() 172 return nil, errors.Annotate(err).Reason("failed to resolve packa ges").Err()
169 } 173 }
170 174
171 if err := cfg.resolvePythonInterpreter(c, e.Spec); err != nil { 175 if err := cfg.resolvePythonInterpreter(c, e.Spec); err != nil {
172 return nil, errors.Annotate(err).Reason("failed to resolve syste m Python interpreter").Err() 176 return nil, errors.Annotate(err).Reason("failed to resolve syste m Python interpreter").Err()
173 } 177 }
174 » rt := vpython.Runtime{ 178 » e.Runtime.Path = cfg.si.Python
175 » » Path: cfg.si.Python, 179 » e.Runtime.Version = e.Spec.PythonVersion
176 » » Version: e.Spec.PythonVersion,
177 » }
178 180
179 var err error 181 var err error
180 » if rt.Hash, err = cfg.si.Hash(); err != nil { 182 » if e.Runtime.Hash, err = cfg.si.Hash(); err != nil {
181 return nil, err 183 return nil, err
182 } 184 }
183 » e.Runtime = &rt 185 » logging.Debugf(c, "Resolved system Python runtime (%s @ %s): %s",
184 » logging.Debugf(c, "Resolved system Python runtime (%s @ %s): %s", rt.Ver sion, rt.Hash, rt.Path) 186 » » e.Runtime.Version, e.Runtime.Hash, e.Runtime.Path)
185 187
186 // Ensure that our base directory exists. 188 // Ensure that our base directory exists.
187 if err := filesystem.MakeDirs(cfg.BaseDir); err != nil { 189 if err := filesystem.MakeDirs(cfg.BaseDir); err != nil {
188 return nil, errors.Annotate(err).Reason("could not create enviro nment root: %(root)s"). 190 return nil, errors.Annotate(err).Reason("could not create enviro nment root: %(root)s").
189 D("root", cfg.BaseDir). 191 D("root", cfg.BaseDir).
190 Err() 192 Err()
191 } 193 }
192 194
193 // Generate our environment name based on the deterministic hash of its 195 // Generate our environment name based on the deterministic hash of its
194 // fully-resolved specification. 196 // fully-resolved specification.
195 » return cfg.envForName(cfg.envNameForSpec(e.Spec, e.Runtime), e), nil 197 » envName := cfg.OverrideName
198 » if envName == "" {
199 » » envName = cfg.envNameForSpec(e.Spec, e.Runtime)
200 » }
201 » env := cfg.envForName(envName, e)
202 » return env, nil
196 } 203 }
197 204
198 // EnvName returns the VirtualEnv environment name for the environment that cfg 205 // EnvName returns the VirtualEnv environment name for the environment that cfg
199 // describes. 206 // describes.
200 func (cfg *Config) envNameForSpec(s *vpython.Spec, rt *vpython.Runtime) string { 207 func (cfg *Config) envNameForSpec(s *vpython.Spec, rt *vpython.Runtime) string {
201 name := spec.Hash(s, rt, EnvironmentVersion) 208 name := spec.Hash(s, rt, EnvironmentVersion)
202 if cfg.MaxHashLen > 0 && len(name) > cfg.MaxHashLen { 209 if cfg.MaxHashLen > 0 && len(name) > cfg.MaxHashLen {
203 name = name[:cfg.MaxHashLen] 210 name = name[:cfg.MaxHashLen]
204 } 211 }
205 return name 212 return name
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 // Resolve to absolute path. 288 // Resolve to absolute path.
282 if err := filesystem.AbsPath(&cfg.Python); err != nil { 289 if err := filesystem.AbsPath(&cfg.Python); err != nil {
283 return errors.Annotate(err).Reason("could not get absolute path for: %(python)s"). 290 return errors.Annotate(err).Reason("could not get absolute path for: %(python)s").
284 D("python", cfg.Python). 291 D("python", cfg.Python).
285 Err() 292 Err()
286 } 293 }
287 return nil 294 return nil
288 } 295 }
289 296
290 func (cfg *Config) systemInterpreter() *python.Interpreter { return cfg.si } 297 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