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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
|
# AwesomeVersion
[](https://codecov.io/gh/ludeeus/awesomeversion)


[](https://pypi.org/project/awesomeversion)

_One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind them._
Make anything a version object, and compare against a vast section of other version formats.
## Installation
```bash
python3 -m pip install awesomeversion
```
## Development
> **Note**
>
> Development is only supported inside the provided devcontainer (such as GitHub Codespaces or VS Code Remote - Containers). Other local or system Python environments are not supported for development or contribution. All scripts and workflows assume the devcontainer environment.
This project uses the ["Scripts to Rule Them All"](https://github.blog/engineering/scripts-to-rule-them-all/) pattern for development tasks:
```bash
# Set up the project for development
./script/setup
# Run tests
./script/test
# Run linting and formatting
./script/lint
# Run coverage
./script/coverage
```
When using the devcontainer or GitHub Codespaces, a welcome message with available scripts is automatically displayed on startup.
## AwesomeVersion class
The AwesomeVersion class takes a version as the first argument, you can also pass in additional kwargs to customize the version object.
Argument | Description
--- | ---
`version` | The version string to parse.
`ensure_strategy` | Match the `AwesomeVersion` object against spesific strategies when creating if. If it does not match `AwesomeVersionStrategyException` will be raised
`find_first_match` | If True, the version given will be scanned for the first match of the given `ensure_strategy`. Raises `AwesomeVersionStrategyException` If it is not found for any of the given strategies.
## AwesomeVersion methods
<details>
<summary><code>AwesomeVersion.in_range</code></summary>
This is a helper method to check if the version is in a range.
This method takes two arguments, `lowest` and `highest`, both are required, and returns a boolean.
> **Note** This method is the same as doing `lowest <= AwesomeVersion <= highest`
Example:
```python
from awesomeversion import AwesomeVersion
print(AwesomeVersion("1.2.2").in_range("1.2.1", "1.3"))
> True
print(AwesomeVersion("1.2.0").in_range("1.2.1", "1.3"))
> False
```
</details>
<details>
<summary><code>AwesomeVersion.diff</code></summary>
This is a helper method to get the difference between two versions.
This method takes one argument which is the version to compare against, and returns a `AwesomeVersionDiff` object.
> **Note** This method is the same as doing `AwesomeVersion - version`
Example:
```python
from awesomeversion import AwesomeVersion
> print(AwesomeVersion("1.0").diff("2.1"))
AwesomeVersionDiff(major=True, minor=True, patch=False, modifier=False, strategy=False)
```
</details>
<details>
<summary><code>AwesomeVersion.section</code></summary>
This is a helper method to get a section of the version.
This method takes one argument which is the section to get, and returns an integer representing it (or 0 if it does not exist).
Example:
```python
from awesomeversion import AwesomeVersion
> print(AwesomeVersion("1.0").section(0))
1
```
</details>
## AwesomeVersion properties
Argument | Description
--- | ---
`alpha` | This is a boolean representing if the version is an alpha version.
`beta` | This is a boolean representing if the version is a beta version.
`dev` | This is a boolean representing if the version is a dev version.
`major` | This is an `AwesomeVersion` object representing the major version or `None` if not present.
`micro` | This is an `AwesomeVersion` object representing the micro version or `None` if not present.
`minor` | This is an `AwesomeVersion` object representing the minor version or `None` if not present.
`modifier_type` | This is a string representing the modifier type of the version or `None` if not present.
`modifier` | This is a string representing the modifier of the version or `None` if not present.
`patch` | This is an `AwesomeVersion` object representing the patch version or `None` if not present.
`prefix` | This is the prefix of the version or `None` if not present.
`release_candidate` | This is a boolean representing if the version is a release candidate version.
`simple` | This is a boolean representing if the version is a simple version.
`strategy_description` | This is a `AwesomeVersionStrategyDescription` object representing the strategy description of the version.
`strategy` | This is a `AwesomeVersionStrategy` object representing the strategy of the version.
`string` | This is the string representation of the version (without the v prefix if present).
`valid` | This is a boolean representing if the version is valid (not unknown strategy).
`year` | This is alias to `major`, and is an `AwesomeVersion` object representing the year.
## Example usage
Here are some examples of how you can use this package, more examples can be found in the `tests` directory.
<details>
<summary><code>Basic compare</code></summary>
```python
from awesomeversion import AwesomeVersion
current = AwesomeVersion("1.2.2")
upstream = AwesomeVersion("1.2.3")
print(upstream > current)
> True
```
</details>
<details>
<summary><code>Compare beta version</code></summary>
```python
from awesomeversion import AwesomeVersion
current = AwesomeVersion("2021.1.0")
upstream = AwesomeVersion("2021.1.0b2")
print(current > upstream)
> True
```
</details>
<details>
<summary><code>Check if version is a beta version</code></summary>
```python
from awesomeversion import AwesomeVersion
print(AwesomeVersion("1.2.3b0").beta)
> True
print(AwesomeVersion("1.2.3").beta)
> False
```
</details>
<details>
<summary>Use <code>AwesomeVersion</code> with <code>with ...</code></summary>
```python
from awesomeversion import AwesomeVersion
with AwesomeVersion("20.12.0") as current:
with AwesomeVersion("20.12.1") as upstream:
print(upstream > current)
> True
```
</details>
<details>
<summary>Compare <code>AwesomeVersion</code> with other non-<code>AwesomeVersion</code> formats</summary>
```python
from awesomeversion import AwesomeVersion
base = AwesomeVersion("20.12.0")
print(base > "20.12.1")
> False
print(base > "19")
> True
print(base > 5)
> True
```
</details>
## General behavior
You can test your versions on the [demo page][awesomeversion_demo].
### Modifiers
When comparing versions with modifiers, if the base version is the same the modifier will be used to determine the order.
If one of the versions do not have a modifier, the one without will be considered newer.
The order of the modifiers are:
- No modifier
- RC
- Beta
- Alpha
- Dev
<details>
<summary>Examples</summary>
```python
from awesomeversion import AwesomeVersion
print(AwesomeVersion("1.0.0") > AwesomeVersion("1.0.0b6"))
> True
print(AwesomeVersion("1.0.0") > AwesomeVersion("1.0.0.dev6"))
> True
print(AwesomeVersion("1.0.0.dev19") > AwesomeVersion("1.0.0b4"))
> False
```
</details>
### Special versions (container)
There are some special versions for container that are handled differently than typical version formats.
The special versions are in the following order:
- `dev` (newest)
- `latest`
- `beta`
- `stable` (oldest)
If only the first version is this special version, it will be considered newer.
If only the second version is this special version, it will be considered older.
<details>
<summary>Examples</summary>
```python
from awesomeversion import AwesomeVersion
print(AwesomeVersion("latest") > AwesomeVersion("1.0.0b6"))
> True
print(AwesomeVersion("1.0.0") > AwesomeVersion("latest"))
> False
print(AwesomeVersion("stable") > AwesomeVersion("latest"))
> False
print(AwesomeVersion("beta") > AwesomeVersion("dev"))
> False
```
</details>
## Contribute
**All** contributions are welcome!
1. Fork the repository
2. Clone the repository locally and open the devcontainer or use GitHub codespaces
3. Do your changes
4. Lint the files with `script/lint`
5. Ensure all tests passes with `script/test`
6. Ensure 100% coverage with `script/coverage`
7. Commit your work, and push it to GitHub
8. Create a PR against the `main` branch
[awesomeversion_demo]: https://awesomeversion.ludeeus.dev
|