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

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

Issue 2701073002: vpython: Add Python interpreter handling package. (Closed)
Patch Set: rebase Created 3 years, 10 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/python_test.go ('k') | vpython/python/version_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package python
6
7 import (
8 "fmt"
9 "strconv"
10 "strings"
11
12 "github.com/luci/luci-go/common/errors"
13 )
14
15 // Version is a Python interpreter version.
16 type Version struct {
17 Major int
18 Minor int
19 Patch int
20 }
21
22 // ParseVersion parses a Python version from a version string (e.g., "1.2.3").
23 func ParseVersion(s string) (Version, error) {
24 if len(s) == 0 {
25 return Version{}, nil
26 }
27
28 parseVersion := func(value string) (int, error) {
29 version, err := strconv.Atoi(value)
30 if err != nil {
31 return 0, errors.Annotate(err).Reason("invalid number va lue: %(value)q").
32 D("value", value).
33 Err()
34 }
35 if version < 0 {
36 return 0, errors.Reason("version (%(version)d) must not be negative").
37 D("version", version).
38 Err()
39 }
40 return version, nil
41 }
42
43 var v Version
44 parts := strings.Split(s, ".")
45 var err error
46 switch l := len(parts); l {
47 case 3:
48 if v.Patch, err = parseVersion(parts[2]); err != nil {
49 return v, errors.Annotate(err).Reason("invalid patch val ue").Err()
50 }
51 fallthrough
52
53 case 2:
54 if v.Minor, err = parseVersion(parts[1]); err != nil {
55 return v, errors.Annotate(err).Reason("invalid minor val ue").Err()
56 }
57 fallthrough
58
59 case 1:
60 if v.Major, err = parseVersion(parts[0]); err != nil {
61 return v, errors.Annotate(err).Reason("invalid major val ue").Err()
62 }
63 if v.IsZero() {
64 return v, errors.Reason("version is incomplete").Err()
65 }
66 return v, nil
67
68 default:
69 return v, errors.Reason("unsupported number of parts (%(count)d) ").
70 D("count", l).
71 Err()
72 }
73 }
74
75 func (v Version) String() string {
76 if v.IsZero() {
77 return ""
78 }
79 return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
80 }
81
82 // IsZero returns true if the Version is empty. This is true if the Major field,
83 // which must be set, is empty.
84 func (v *Version) IsZero() bool { return v.Major <= 0 }
85
86 // PythonBase returns the base Python interpreter name for this version.
87 func (v *Version) PythonBase() string {
88 switch {
89 case v.IsZero():
90 return "python"
91 case v.Minor > 0:
92 return fmt.Sprintf("python%d.%d", v.Major, v.Minor)
93 default:
94 return fmt.Sprintf("python%d", v.Major)
95 }
96 }
97
98 // IsSatisfiedBy returns true if "other" is a suitable match for this version. A
99 // suitable match:
100 //
101 // - MUST have a Major version.
102 // - If v is zero, other is automatically suitable.
103 // - If v is non-zero, other must have the same Major version as v, and a
104 // minor/patch version that is >= v's.
105 func (v *Version) IsSatisfiedBy(other Version) bool {
106 switch {
107 case other.Major <= 0:
108 // "other" must have a Major version.
109 return false
110 case v.IsZero():
111 // "v" is zero (anything), so "other" satisfies it.
112 return true
113 case v.Major != other.Major:
114 // "other" must match "v"'s Major version precisely.
115 return false
116 case v.Minor > other.Minor:
117 // "v" requires a Minor version that is greater than "other"'s.
118 return false
119 case v.Minor < other.Minor:
120 // "v" requires a Minor version that is less than "other"'s.
121 return true
122 case v.Patch > other.Patch:
123 // "v" requires a Patch version that is greater than "other"'s.
124 return false
125 default:
126 return true
127 }
128 }
129
130 // Less returns true if "v"'s Version semantically precedes "other".
131 func (v *Version) Less(other *Version) bool {
132 switch {
133 case v.Major < other.Major:
134 return true
135 case v.Major > other.Major:
136 return false
137 case v.Minor < other.Minor:
138 return true
139 case v.Minor > other.Minor:
140 return false
141 default:
142 return (v.Patch < other.Patch)
143 }
144 }
OLDNEW
« no previous file with comments | « vpython/python/python_test.go ('k') | vpython/python/version_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698