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

Side by Side Diff: vpython/python/interpreter.go

Issue 2963503003: [errors] Greatly simplify common/errors package. (Closed)
Patch Set: fix nits Created 3 years, 5 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/python/find.go ('k') | vpython/python/python.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 python 5 package python
6 6
7 import ( 7 import (
8 "crypto/sha256" 8 "crypto/sha256"
9 "encoding/hex" 9 "encoding/hex"
10 "io" 10 "io"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 } 43 }
44 44
45 // Normalize normalizes the Interpreter configuration by resolving relative 45 // Normalize normalizes the Interpreter configuration by resolving relative
46 // paths into absolute paths and evaluating symlnks. 46 // paths into absolute paths and evaluating symlnks.
47 func (i *Interpreter) Normalize() error { 47 func (i *Interpreter) Normalize() error {
48 if err := filesystem.AbsPath(&i.Python); err != nil { 48 if err := filesystem.AbsPath(&i.Python); err != nil {
49 return err 49 return err
50 } 50 }
51 resolved, err := filepath.EvalSymlinks(i.Python) 51 resolved, err := filepath.EvalSymlinks(i.Python)
52 if err != nil { 52 if err != nil {
53 » » return errors.Annotate(err).Reason("could not evaluate symlinks for: %(path)q"). 53 » » return errors.Annotate(err, "could not evaluate symlinks for: %q ", i.Python).Err()
54 » » » D("path", i.Python).
55 » » » Err()
56 } 54 }
57 i.Python = resolved 55 i.Python = resolved
58 return nil 56 return nil
59 } 57 }
60 58
61 // IsolatedCommand returns a configurable exec.Cmd structure bound to this 59 // IsolatedCommand returns a configurable exec.Cmd structure bound to this
62 // Interpreter. 60 // Interpreter.
63 // 61 //
64 // The supplied arguments have several Python isolation flags prepended to them 62 // The supplied arguments have several Python isolation flags prepended to them
65 // to remove environmental factors such as: 63 // to remove environmental factors such as:
(...skipping 25 matching lines...) Expand all
91 if i.cachedVersion != nil { 89 if i.cachedVersion != nil {
92 v = *i.cachedVersion 90 v = *i.cachedVersion
93 return 91 return
94 } 92 }
95 93
96 // We use CombinedOutput here becuase Python2 writes the version to STDE RR, 94 // We use CombinedOutput here becuase Python2 writes the version to STDE RR,
97 // while Python3+ writes it to STDOUT. 95 // while Python3+ writes it to STDOUT.
98 cmd := i.IsolatedCommand(c, "--version") 96 cmd := i.IsolatedCommand(c, "--version")
99 out, err := cmd.CombinedOutput() 97 out, err := cmd.CombinedOutput()
100 if err != nil { 98 if err != nil {
101 » » err = errors.Annotate(err).Err() 99 » » err = errors.Annotate(err, "").Err()
102 return 100 return
103 } 101 }
104 102
105 if v, err = ParseVersionOutput(string(out)); err != nil { 103 if v, err = ParseVersionOutput(string(out)); err != nil {
106 return 104 return
107 } 105 }
108 106
109 i.cachedVersion = &v 107 i.cachedVersion = &v
110 return 108 return
111 } 109 }
112 110
113 // Hash returns the SHA256 hash string of this interpreter. 111 // Hash returns the SHA256 hash string of this interpreter.
114 // 112 //
115 // The hash value is cached; if called multiple times, the cached value will 113 // The hash value is cached; if called multiple times, the cached value will
116 // be returned. 114 // be returned.
117 func (i *Interpreter) Hash() (string, error) { 115 func (i *Interpreter) Hash() (string, error) {
118 hashInterpreter := func(path string) (string, error) { 116 hashInterpreter := func(path string) (string, error) {
119 fd, err := os.Open(i.Python) 117 fd, err := os.Open(i.Python)
120 if err != nil { 118 if err != nil {
121 » » » return "", errors.Annotate(err).Reason("failed to open i nterpreter").Err() 119 » » » return "", errors.Annotate(err, "failed to open interpre ter").Err()
122 } 120 }
123 defer fd.Close() 121 defer fd.Close()
124 122
125 hash := sha256.New() 123 hash := sha256.New()
126 if _, err := io.Copy(hash, fd); err != nil { 124 if _, err := io.Copy(hash, fd); err != nil {
127 » » » return "", errors.Annotate(err).Reason("failed to read [ %(path)s] for hashing"). 125 » » » return "", errors.Annotate(err, "failed to read [%s] for hashing", path).Err()
128 » » » » D("path", path).
129 » » » » Err()
130 } 126 }
131 127
132 return hex.EncodeToString(hash.Sum(nil)), nil 128 return hex.EncodeToString(hash.Sum(nil)), nil
133 } 129 }
134 130
135 i.cachedHashOnce.Do(func() { 131 i.cachedHashOnce.Do(func() {
136 i.cachedHash, i.cachedHashErr = hashInterpreter(i.Python) 132 i.cachedHash, i.cachedHashErr = hashInterpreter(i.Python)
137 }) 133 })
138 return i.cachedHash, i.cachedHashErr 134 return i.cachedHash, i.cachedHashErr
139 } 135 }
140 136
141 // ParseVersionOutput parses a Version out of the output of a "--version" Python 137 // ParseVersionOutput parses a Version out of the output of a "--version" Python
142 // invocation. 138 // invocation.
143 func ParseVersionOutput(output string) (Version, error) { 139 func ParseVersionOutput(output string) (Version, error) {
144 s := strings.TrimSpace(string(output)) 140 s := strings.TrimSpace(string(output))
145 141
146 // Expected output: 142 // Expected output:
147 // Python X.Y.Z 143 // Python X.Y.Z
148 parts := strings.SplitN(s, " ", 2) 144 parts := strings.SplitN(s, " ", 2)
149 if len(parts) != 2 || parts[0] != "Python" { 145 if len(parts) != 2 || parts[0] != "Python" {
150 return Version{}, errors.Reason("unknown version output"). 146 return Version{}, errors.Reason("unknown version output").
151 » » » D("output", s). 147 » » » InternalReason("output(%q)", s).Err()
152 » » » Err()
153 } 148 }
154 149
155 v, err := ParseVersion(parts[1]) 150 v, err := ParseVersion(parts[1])
156 if err != nil { 151 if err != nil {
157 » » err = errors.Annotate(err).Reason("failed to parse version from: %(value)q"). 152 » » err = errors.Annotate(err, "failed to parse version from: %q", p arts[1]).Err()
158 » » » D("value", parts[1]).
159 » » » Err()
160 return v, err 153 return v, err
161 } 154 }
162 return v, nil 155 return v, nil
163 } 156 }
OLDNEW
« no previous file with comments | « vpython/python/find.go ('k') | vpython/python/python.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698