-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathSemVer.qll
More file actions
102 lines (88 loc) · 2.8 KB
/
SemVer.qll
File metadata and controls
102 lines (88 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* Provides classes for dealing with semantic versions, for dependency versions.
*/
overlay[local?]
module;
import semmle.go.dependencies.Dependencies
/**
* A SemVer-formatted version string in a dependency.
*
* Pre-release information and build metadata is not yet supported.
*/
class DependencySemVer extends string {
Dependency dep;
string normalized;
DependencySemVer() {
this = dep.getDepVersion() and
normalized = normalizeSemver(this)
}
/**
* Holds if this version may be before `last`.
*/
bindingset[last]
predicate maybeBefore(string last) { normalized < normalizeSemver(last) }
/**
* Holds if this version may be after `first`.
*/
bindingset[first]
predicate maybeAfter(string first) { normalizeSemver(first) < normalized }
/**
* Holds if this version may be between `first` (inclusive) and `last` (exclusive).
*/
bindingset[first, last]
predicate maybeBetween(string first, string last) {
normalizeSemver(first) <= normalized and
normalized < normalizeSemver(last)
}
/**
* Holds if this version is equivalent to `other`.
*/
bindingset[other]
predicate is(string other) { normalized = normalizeSemver(other) }
/**
* Gets the dependency that uses this string.
*/
Dependency getDependency() { result = dep }
}
bindingset[str]
private string leftPad(string str) { result = ("000" + str).suffix(str.length()) }
/**
* Normalizes a SemVer string such that the lexicographical ordering
* of two normalized strings is consistent with the SemVer ordering.
*
* Pre-release information and build metadata is not yet supported.
*/
bindingset[orig]
private string normalizeSemver(string orig) {
exists(string pattern, string major, string minor, string patch |
pattern = "v?(\\d+)\\.(\\d+)\\.(\\d+)(\\D.*)?" and
major = orig.regexpCapture(pattern, 1) and
minor = orig.regexpCapture(pattern, 2) and
patch = orig.regexpCapture(pattern, 3)
|
result = leftPad(major) + "." + leftPad(minor) + "." + leftPad(patch)
)
}
/**
* A version string in a dependency that has a SemVer, but also contains a git commit SHA.
*
* This class is useful for interacting with go.mod versions, which use SemVer, but can also contain
* SHAs if no useful tags are found, or when a user wishes to specify a commit SHA.
*
* Pre-release information and build metadata is not yet supported.
*/
class DependencySemShaVersion extends DependencySemVer {
string sha;
DependencySemShaVersion() { sha = this.regexpCapture(".*-([0-9a-f]+)", 1) }
/**
* Gets the commit SHA associated with this version.
*/
string getSha() { result = sha }
bindingset[other]
override predicate is(string other) {
this.getSha() = other.(DependencySemShaVersion).getSha()
or
not other instanceof DependencySemShaVersion and
super.is(other)
}
}