Остання активність 1740032087

Taken from https://gist.github.com/lxe/b167d3ec4e4f94d246ebdc4bcfdfb6ac

anthony's Avatar anthony ревизій цього gist 1740032086. До ревизії

1 file changed, 143 insertions

semver.sh(файл створено)

@@ -0,0 +1,143 @@
1 + #!/bin/bash
2 +
3 + # set -x
4 +
5 + # Stupid Simple Semver range validator
6 + # (no build metadata and no prereleases, and no multiple ranges (||))
7 +
8 + # Prints a list of versions that match a semver range
9 + # ./semver.sh "range" version version version...
10 +
11 + # ./semver.sh ">=0.10.32 <7" 0.10.32 6.7.0 6.9.2 6.9.4 6.10.0 7.3.0 7.4.0 | xargs
12 + # 0.10.32 6.7.0 6.9.2 6.9.4 6.10.0
13 +
14 + # ./semver.sh "^6.9.4" 0.10.32 6.7.0 6.9.2 6.9.4 6.10.0 7.3.0 7.4.0 | xargs
15 + # 6.9.4 6.10.0
16 +
17 + # ./semver.sh "~6.9.4" 0.10.32 6.7.0 6.9.2 6.9.4 6.10.0 7.3.0 7.4.0 | xargs
18 + # 6.9.4
19 +
20 + # TODO: error handling, validation
21 +
22 + # Basic concept:
23 + # 1.x.x = ^1.0.0 = (>=1.0.0 <2.0.0)
24 + # 1.1.x = ~1.1.0 = (>=1.1.0 <1.2.0)
25 + # ^1.x.x = ^1.0.0
26 + # ~1.x.x = ~1.0.0
27 +
28 + SEMVER_RANGE="$1"; shift
29 + SEMVER_AVAILABLE_VERSIONS="$@"
30 +
31 + SEMVER_RE_COMPARATOR='[<>=\^~]*'
32 + SEMVER_RE_VERSION='[0-9x\.]+'
33 +
34 + # Takes a range with multiple comparisons, and splits it into lines
35 + # >=1.2.3 < 3
36 + # >=1.2.3
37 + # < 3
38 + semver_split_range () {
39 + egrep -o "($SEMVER_RE_COMPARATOR\s*$SEMVER_RE_VERSION)"
40 + }
41 +
42 + # Hacky way to make versions comparable
43 + # Won't work if version numbers are over 100k'
44 + # 1.2.3 => 000001000002000003
45 + semver_to_number () {
46 + tr "." " " | xargs printf "%06g"
47 + }
48 +
49 + # Convert a range part into a set of comparison lines processable by bc
50 + # ^1.2.3 => >=1.2.3 <2.0.0
51 + # >= 000001000002000003
52 + # < 000002000000000000
53 + semver_create_comparator () {
54 + local COMPARATOR="$(egrep -o "^$SEMVER_RE_COMPARATOR" <<< "$1")"
55 + local VERSION="$(egrep -o "$SEMVER_RE_VERSION$" <<< "$1")"
56 + local VP
57 +
58 + local ZERO_OR_X
59 + if [[ -n "$COMPARATOR" ]]; then
60 + ZERO_OR_X="0"
61 + else
62 + ZERO_OR_X="x"
63 + fi
64 +
65 + # Append either 0's or x's to the version, depending on comparator presence
66 + # 4 => 4.x.x
67 + # ^4 => 4.0.0
68 + while [[ "$(egrep -o "\." <<< "$VERSION" | wc -l)" -lt "2" ]]; do
69 + VERSION="$VERSION.$ZERO_OR_X"
70 + done
71 +
72 + # If comparator is not defined (1.x.x, 1.x, 1, 1.0.x, 1.0.0 etc),
73 + # assign one based on the number of x's
74 + # 1.x.x => ^ 1.x.x
75 + # 1.0.x => ~ 1.0.x
76 + # 1.0.0 => == 1.0.0
77 + if [[ -z "$COMPARATOR" ]]; then
78 + if [[ "$VERSION" =~ \.x\.x ]]; then
79 + COMPARATOR="^"
80 + elif [[ "$VERSION" =~ \.x ]]; then
81 + COMPARATOR="~"
82 + else
83 + COMPARATOR="=="
84 + fi
85 + fi
86 +
87 + # Finally, replace all the x's with 0s'
88 + # ^ 1.x.x => ^ 1.0.0
89 + VERSION=$(sed -E 's|\.x|\.0|g' <<< "$VERSION")
90 +
91 + # Convert the ~,^ into proper >=, < comparator ranges
92 + # ^1.0.0 = (>=1.0.0 <2.0.0)
93 + # ~1.0.0 = (>=1.0.0 <1.1.0)
94 + if [[ "$COMPARATOR" =~ \^|~ ]]; then
95 + IFS="." read -ra VP <<< "$VERSION"
96 + if [[ "$COMPARATOR" == "~" ]]; then
97 + # Up the minor; 0 the patch
98 + VP[1]=$(( ${VP[1]} + 1 ))
99 + VP[2]=0
100 + else
101 + # Up the major; 0 the minor and patch
102 + VP[0]=$(( ${VP[0]} + 1 ))
103 + VP[1]=0
104 + VP[2]=0
105 + fi
106 + COMPARATOR=">="
107 + echo "< $(semver_to_number <<< "${VP[0]}.${VP[1]}.${VP[2]}")"
108 + fi
109 +
110 + echo "$COMPARATOR $(semver_to_number <<< "$VERSION")"
111 + }
112 +
113 + # Create all of the comparator lines processable by bc for the entire semver range
114 + # TODO: make it break for invalid ranges
115 + semver_create_comparators () {
116 + local R
117 +
118 + while read R; do
119 + semver_create_comparator "$R"
120 + done < <(semver_split_range <<< "$SEMVER_RANGE")
121 + }
122 +
123 + # Run a semver against all comparisons
124 + # If all conditions pass, return success
125 + semver_compare () {
126 + local C
127 +
128 + while read C; do
129 + [[ "$MATCH" == "false" ]] && break
130 + if [[ "$(bc <<< "$1 $C")" == "0" ]]; then
131 + return 1
132 + fi
133 + done < <(echo -e "$V_COMPARATORS")
134 + }
135 +
136 + # Precompute the range into bc-processable comparator strings
137 + V_COMPARATORS="$(semver_create_comparators)"
138 +
139 + # Compare each provided version against the provided range, and print
140 + # the ones that succeed
141 + for A in $SEMVER_AVAILABLE_VERSIONS; do
142 + semver_compare "$(semver_to_number <<< "$A")" && echo $A
143 + done
Новіше Пізніше