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

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

Issue 2925723004: [vpython] Implement smart probing. (Closed)
Patch Set: sentinel text 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/python/find.go ('k') | vpython/venv/config.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"
11 "os" 11 "os"
12 "os/exec" 12 "os/exec"
13 "path/filepath" 13 "path/filepath"
14 "strings" 14 "strings"
15 "sync" 15 "sync"
16 16
17 "github.com/luci/luci-go/common/errors" 17 "github.com/luci/luci-go/common/errors"
18 "github.com/luci/luci-go/common/system/filesystem" 18 "github.com/luci/luci-go/common/system/filesystem"
19 19
20 "golang.org/x/net/context" 20 "golang.org/x/net/context"
21 ) 21 )
22 22
23 type runnerFunc func(cmd *exec.Cmd, capture bool) (string, error)
24
25 // Interpreter represents a system Python interpreter. It exposes the ability 23 // Interpreter represents a system Python interpreter. It exposes the ability
26 // to use common functionality of that interpreter. 24 // to use common functionality of that interpreter.
27 type Interpreter struct { 25 type Interpreter struct {
28 // Python is the path to the system Python interpreter. 26 // Python is the path to the system Python interpreter.
29 Python string 27 Python string
30 28
31 // cachedVersion is the cached Version for this interpreter. It is popul ated 29 // cachedVersion is the cached Version for this interpreter. It is popul ated
32 // on the first GetVersion call. 30 // on the first GetVersion call.
33 cachedVersion *Version 31 cachedVersion *Version
34 cachedVersionMu sync.Mutex 32 cachedVersionMu sync.Mutex
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 95
98 // We use CombinedOutput here becuase Python2 writes the version to STDE RR, 96 // We use CombinedOutput here becuase Python2 writes the version to STDE RR,
99 // while Python3+ writes it to STDOUT. 97 // while Python3+ writes it to STDOUT.
100 cmd := i.IsolatedCommand(c, "--version") 98 cmd := i.IsolatedCommand(c, "--version")
101 out, err := cmd.CombinedOutput() 99 out, err := cmd.CombinedOutput()
102 if err != nil { 100 if err != nil {
103 err = errors.Annotate(err).Err() 101 err = errors.Annotate(err).Err()
104 return 102 return
105 } 103 }
106 104
107 » if v, err = parseVersionOutput(strings.TrimSpace(string(out))); err != n il { 105 » if v, err = ParseVersionOutput(string(out)); err != nil {
108 » » err = errors.Annotate(err).Err()
109 return 106 return
110 } 107 }
111 108
112 i.cachedVersion = &v 109 i.cachedVersion = &v
113 return 110 return
114 } 111 }
115 112
116 // Hash returns the SHA256 hash string of this interpreter. 113 // Hash returns the SHA256 hash string of this interpreter.
117 // 114 //
118 // The hash value is cached; if called multiple times, the cached value will 115 // The hash value is cached; if called multiple times, the cached value will
(...skipping 15 matching lines...) Expand all
134 131
135 return hex.EncodeToString(hash.Sum(nil)), nil 132 return hex.EncodeToString(hash.Sum(nil)), nil
136 } 133 }
137 134
138 i.cachedHashOnce.Do(func() { 135 i.cachedHashOnce.Do(func() {
139 i.cachedHash, i.cachedHashErr = hashInterpreter(i.Python) 136 i.cachedHash, i.cachedHashErr = hashInterpreter(i.Python)
140 }) 137 })
141 return i.cachedHash, i.cachedHashErr 138 return i.cachedHash, i.cachedHashErr
142 } 139 }
143 140
144 func parseVersionOutput(output string) (Version, error) { 141 // ParseVersionOutput parses a Version out of the output of a "--version" Python
142 // invocation.
143 func ParseVersionOutput(output string) (Version, error) {
144 » s := strings.TrimSpace(string(output))
145
145 // Expected output: 146 // Expected output:
146 // Python X.Y.Z 147 // Python X.Y.Z
147 » parts := strings.SplitN(output, " ", 2) 148 » parts := strings.SplitN(s, " ", 2)
148 if len(parts) != 2 || parts[0] != "Python" { 149 if len(parts) != 2 || parts[0] != "Python" {
149 return Version{}, errors.Reason("unknown version output"). 150 return Version{}, errors.Reason("unknown version output").
150 » » » D("output", output). 151 » » » D("output", s).
151 Err() 152 Err()
152 } 153 }
153 154
154 v, err := ParseVersion(parts[1]) 155 v, err := ParseVersion(parts[1])
155 if err != nil { 156 if err != nil {
156 err = errors.Annotate(err).Reason("failed to parse version from: %(value)q"). 157 err = errors.Annotate(err).Reason("failed to parse version from: %(value)q").
157 D("value", parts[1]). 158 D("value", parts[1]).
158 Err() 159 Err()
159 return v, err 160 return v, err
160 } 161 }
161 return v, nil 162 return v, nil
162 } 163 }
OLDNEW
« no previous file with comments | « vpython/python/find.go ('k') | vpython/venv/config.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698