Passed
Pull Request — master (#10)
by Konstantinos
01:14
created

process_sem_ver   A

Complexity

Total Complexity 0

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 0
eloc 57
dl 0
loc 140
rs 10
c 0
b 0
f 0
1
#!/usr/bin/env python
2
3
# 'Assumptions': input string follows Sem Ver 2.0
4
# with 2 'Limitations' on pre-release metadata and build metadata:
5
6
# 1) if user wants to include pre-release info, they must
7
#     - separate with dash (-) from M.m.p (ie 1.0.0-dev)
8
#     - only include characters from [a-z]
9
# 2) no build metadata are supported and string MUST end with patch or pre-release metadata
10
11
import sys
12
13
if len(sys.argv) != 2:
14
    print("Usage: process_sem_ver.py <version>")
15
    print(f"Example: process_sem_ver.py 1.0.0-dev")
16
    sys.exit(1)
17
18
semver: str = sys.argv[1]
19
20
# Verify input string meets our 'Hard Requirements', otherwise show message:
21
# - indicating what happened and crashed the program
22
# - what caused the crash
23
# - how the user input is part of the cause
24
# -  what the user should try to do, to fix the issue
25
26
# 'Hard Requirements', based on 'Assumptions' and 'Limitations' (see above):
27
# - string must be at least 5 characters long
28
# - string mush have 2 dots
29
# - string must end with a patch or pre-release metadata
30
# - string must have a dash (-) if pre-release metadata is included
31
# - if prerelase metadata is included, it must be only characheters from [a-z]
32
33
# Verify string is at least 5 characters long
34
if len(semver) < 5:
35
    print("[ERROR]: Sem Ver Version string must be at least 5 characters long")
36
    print(f"Your input: {semver}")
37
    print(f"Your input is only {len(semver)} characters long")
38
    print("Please try again with a version string that is at least 5 characters long")
39
    sys.exit(1)
40
41
# Verify string has 2 dots
42
if semver.count(".") != 2:
43
    print("[ERROR]: Version string must have 2 dots")
44
    print(f"Your input: {semver}")
45
    print(f"Your input has {semver.count('.')} dots")
46
    print("Please try again with a version string that has 2 dots")
47
    sys.exit(1)
48
49
50
# Interact with the Sem Ver 2.0 Regular Expression at https://regex101.com/r/Ly7O1x/3/
51
# Sem Ver 2.0 Docs related section at: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
52
53
# Note: Sem Ver 2.0 requires dash (-) to separate pre-release metadata
54
55
# Verify string ends with a patch or pre-release metadata
56
## Sem Ver 2.0 requires dash (-) to separate pre-release metadata
57
58
if '-' not in semver:  # if no Sem Ver 2.0 prerelease separator found in the string
59
    # for us now it is impossible to have pre-release metadata
60
    # and the string MUST be in Major.Minor.Patch format only
61
62
    if semver[-1] not in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
63
        # ERROR: Should be dealing with M.m.p case, but last character is not digit
64
        print("[ERROR]: Version string must end with a patch or pre-release metadata")
65
        print(f"Your input: {semver}")
66
        print(f"Your input ends with {semver[-0]}")
67
        print("Please try again with a version string that ends with a patch or pre-release metadata")
68
        print(f"EXPLANATION: Since we did not find a dash (-) in the input, we expect to",
69
        " the Input Version String to be of 'Major.Minor.Patch' format."
70
        " So, 'Patch' must be the last part of the string, thus the last digit must be a number."
71
        f"But we found {semver[-0]} instead\n."
72
        "If you intended to include 'pre-release' metadata,"
73
        " please concatenate a dash (-) to the mandatory starting 'Major.Minor.Patch' part"
74
        " and then add your 'pre-release' metadata, ie '1.0.0-dev'.")
75
        sys.exit(1)
76
77
    # more reg ex checks can go here, but that not really the purpose of this script
78
79
else:  # if Sem Ver 2.0 prerelease separator found in the string
80
    
81
    # 1) Given the above condition
82
    # 2) Given scripts 'Limitations':
83
    #    - only characters [a-z] are allowed for prerelease metadata
84
    #    - we do not support 'build metadata' of Sem Ver 2.0
85
    
86
    # Then
87
    #  - expect to find exactly 1 dash (-), 
88
    #  - the dash is right after Patch (ie Major.Minor.Patch-Prerelaese)
89
    #  - only [a-z] characters are found in prerelease substring
90
    #  - prerelease substring is not empty
91
92
    if semver.count("-") != 1:
93
        # ERROR: Should be dealing with M.m.p-prerelase case, but more than 1 dash found
94
        print("[ERROR]: Version string must have exactly 1 dash (-)")
95
        print(f"Your input: {semver}")
96
        print(f"Your input has {semver.count('-')} dashes")
97
        print("Please try again with a version string that has exactly 1 dash (-)")
98
        print(f"EXPLANATION: Since, we found a dash (-) in the input, and given the script 'Limitation' that we do not support build-metadata, we expect",
99
        " the Input Version String to be of 'Major.Minor.Patch-Prerelease' format.")
100
        sys.exit(1)
101
102
    prerelease: str = semver.split('-')[1]  # get the prerelease substring
103
104
    if prerelease == '':
105
        # ERROR: Should be dealing with M.m.p-prerelase case, but prerelease substring is empty
106
        print("[ERROR]: Version string must have a non-empty prerelease substring")
107
        print(f"Your input: {semver}")
108
        print(f"Your input has an empty prerelease substring")
109
        print("Please try again with a version string that has a non-empty prerelease substring")
110
        print(f"EXPLANATION: Since, we found a dash (-) in the input, and given the script 'Limitation' that we do not support build-metadata, we expect",
111
        " the Input Version String to be of 'Major.Minor.Patch-Prerelease' format.")
112
        sys.exit(1)
113
114
    # english alphabet has 26 characters
115
    lowercase_chars = set(chr(ord('a') + i) for i in range(26))
116
    if lowercase_chars.issuperset(prerelease) is False:
117
        # ERROR: Should be dealing with M.m.p-prerelase case, but found non [a-z] characters in prerelease substring
118
        print("[ERROR]: Version string's prerelease must have only [a-z] characters")
119
        print(f"Your input: {semver}")
120
        print(f"Your input has {prerelease}")
121
        print("Please try again with a version string that has only [a-z] characters in prerelease substring")
122
        print(f"EXPLANATION: Since we found a dash (-) in the input, we expect to",
123
        " the Input Version String to be of 'Major.Minor.Patch-Prerelease' format.")
124
        sys.exit(1)
125
126
    # more reg ex checks can go here, but that not really the purpose of this script
127
128
129
# If we got here, then the input string is a valid Sem Ver 2.0 string
130
# And valid as input to the rest of the script
131
132
assert sys.argv[1] == semver
133
134
# CRITICAL to be in par with Pip sdist /wheel and python -m build operations
135
136
# here it safe to implement the logic simply as:
137
# if there is a dash then convert to dot and add trailing zero (0), else return as it is
138
print(
139
    sys.argv[1] if "-" not in sys.argv[1] else sys.argv[1].replace("-", ".") + "0"
140
)
141
142
# ALT Format 1
143
# we provide oneliner with exa same print statement, except we skip all checks
144
145
# print(sys.argv[1] if "-" not in sys.argv[1] else sys.argv[1].replace("-", ".") + "0")
146
147
148
# ALT Format 2
149
# We provide python script, as shell command, with same input and output as this script
150
# ( we skip all the checks, and provide the shell starting with python -c '' )
151
152
# python -c 'import sys; print(sys.argv[1] if "-" not in sys.argv[1] else sys.argv[1].replace("-", ".") + "0")' 1.0.0-dev
153
154
155
        # PARSED_DISTRO_SEMVER=$(python -c 'import sys; print(sys.argv[1] if "-" not in sys.argv[1] else sys.argv[1].replace("-", ".") + "0")' "${PARSED_VERSION}")
156
157
        #         if [[ "${PARSED_DISTRO_SEMVER}" != "${TAG_SEM_VER}" ]]; then
158
        #   echo "ERROR: Version in __init__.py (${PARSED_DISTRO_SEMVER}) does not match tag (${TAG_SEM_VER})"
159
        #   exit 1
160
        # fi
161
162
163
        # PARSER="scripts/parse_version.py"
164
        # PARSED_VERSION=$(python "${PARSER}")