1*60517a1eSAndroid Build Coastguard Worker# Copyright 2024 The Bazel Authors. All rights reserved. 2*60517a1eSAndroid Build Coastguard Worker# 3*60517a1eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*60517a1eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*60517a1eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*60517a1eSAndroid Build Coastguard Worker# 7*60517a1eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*60517a1eSAndroid Build Coastguard Worker# 9*60517a1eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*60517a1eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*60517a1eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*60517a1eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*60517a1eSAndroid Build Coastguard Worker# limitations under the License. 14*60517a1eSAndroid Build Coastguard Worker 15*60517a1eSAndroid Build Coastguard Worker"A semver version parser" 16*60517a1eSAndroid Build Coastguard Worker 17*60517a1eSAndroid Build Coastguard Workerdef _key(version): 18*60517a1eSAndroid Build Coastguard Worker return ( 19*60517a1eSAndroid Build Coastguard Worker version.major, 20*60517a1eSAndroid Build Coastguard Worker version.minor or 0, 21*60517a1eSAndroid Build Coastguard Worker version.patch or 0, 22*60517a1eSAndroid Build Coastguard Worker # non pre-release versions are higher 23*60517a1eSAndroid Build Coastguard Worker version.pre_release == "", 24*60517a1eSAndroid Build Coastguard Worker # then we compare each element of the pre_release tag separately 25*60517a1eSAndroid Build Coastguard Worker tuple([ 26*60517a1eSAndroid Build Coastguard Worker ( 27*60517a1eSAndroid Build Coastguard Worker i if not i.isdigit() else "", 28*60517a1eSAndroid Build Coastguard Worker # digit values take precedence 29*60517a1eSAndroid Build Coastguard Worker int(i) if i.isdigit() else 0, 30*60517a1eSAndroid Build Coastguard Worker ) 31*60517a1eSAndroid Build Coastguard Worker for i in version.pre_release.split(".") 32*60517a1eSAndroid Build Coastguard Worker ]) if version.pre_release else None, 33*60517a1eSAndroid Build Coastguard Worker # And build info is just alphabetic 34*60517a1eSAndroid Build Coastguard Worker version.build, 35*60517a1eSAndroid Build Coastguard Worker ) 36*60517a1eSAndroid Build Coastguard Worker 37*60517a1eSAndroid Build Coastguard Workerdef _to_dict(self): 38*60517a1eSAndroid Build Coastguard Worker return { 39*60517a1eSAndroid Build Coastguard Worker "build": self.build, 40*60517a1eSAndroid Build Coastguard Worker "major": self.major, 41*60517a1eSAndroid Build Coastguard Worker "minor": self.minor, 42*60517a1eSAndroid Build Coastguard Worker "patch": self.patch, 43*60517a1eSAndroid Build Coastguard Worker "pre_release": self.pre_release, 44*60517a1eSAndroid Build Coastguard Worker } 45*60517a1eSAndroid Build Coastguard Worker 46*60517a1eSAndroid Build Coastguard Workerdef semver(version): 47*60517a1eSAndroid Build Coastguard Worker """Parse the semver version and return the values as a struct. 48*60517a1eSAndroid Build Coastguard Worker 49*60517a1eSAndroid Build Coastguard Worker Args: 50*60517a1eSAndroid Build Coastguard Worker version: {type}`str` the version string. 51*60517a1eSAndroid Build Coastguard Worker 52*60517a1eSAndroid Build Coastguard Worker Returns: 53*60517a1eSAndroid Build Coastguard Worker A {type}`struct` with `major`, `minor`, `patch` and `build` attributes. 54*60517a1eSAndroid Build Coastguard Worker """ 55*60517a1eSAndroid Build Coastguard Worker 56*60517a1eSAndroid Build Coastguard Worker # Implement the https://semver.org/ spec 57*60517a1eSAndroid Build Coastguard Worker major, _, tail = version.partition(".") 58*60517a1eSAndroid Build Coastguard Worker minor, _, tail = tail.partition(".") 59*60517a1eSAndroid Build Coastguard Worker patch, _, build = tail.partition("+") 60*60517a1eSAndroid Build Coastguard Worker patch, _, pre_release = patch.partition("-") 61*60517a1eSAndroid Build Coastguard Worker 62*60517a1eSAndroid Build Coastguard Worker # buildifier: disable=uninitialized 63*60517a1eSAndroid Build Coastguard Worker self = struct( 64*60517a1eSAndroid Build Coastguard Worker major = int(major), 65*60517a1eSAndroid Build Coastguard Worker minor = int(minor) if minor.isdigit() else None, 66*60517a1eSAndroid Build Coastguard Worker # NOTE: this is called `micro` in the Python interpreter versioning scheme 67*60517a1eSAndroid Build Coastguard Worker patch = int(patch) if patch.isdigit() else None, 68*60517a1eSAndroid Build Coastguard Worker pre_release = pre_release, 69*60517a1eSAndroid Build Coastguard Worker build = build, 70*60517a1eSAndroid Build Coastguard Worker # buildifier: disable=uninitialized 71*60517a1eSAndroid Build Coastguard Worker key = lambda: _key(self), 72*60517a1eSAndroid Build Coastguard Worker str = lambda: version, 73*60517a1eSAndroid Build Coastguard Worker to_dict = lambda: _to_dict(self), 74*60517a1eSAndroid Build Coastguard Worker ) 75*60517a1eSAndroid Build Coastguard Worker return self 76