or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdindex.mdutility-functions.mdvcs-integration.mdversion-creation.mdversion-serialization.md

utility-functions.mddocs/

0

# Utility Functions

1

2

Standalone helper functions for version manipulation, validation, and dynamic version detection.

3

4

## Capabilities

5

6

### Version Bumping

7

8

Increment numerical components of version strings without requiring Version objects.

9

10

```python { .api }

11

def bump_version(base: str, index: int = -1, increment: int = 1) -> str

12

```

13

14

**Parameters**:

15

- `base`: Version core like "1.2.3" (without pre-release identifiers)

16

- `index`: Position to increment using Python indexing (0+ from left, -1 from right)

17

- `increment`: Amount to increment by (default: 1)

18

19

**Returns**: Bumped version string

20

21

**Usage Examples**:

22

23

```python

24

from dunamai import bump_version

25

26

# Bump patch version (rightmost, default)

27

print(bump_version("1.2.3"))

28

# "1.2.4"

29

30

# Bump minor version

31

print(bump_version("1.2.3", index=1))

32

# "1.3.0"

33

34

# Bump major version

35

print(bump_version("1.2.3", index=0))

36

# "2.0.0"

37

38

# Bump by custom amount

39

print(bump_version("1.2.3", increment=5))

40

# "1.2.8"

41

42

# Bump minor by 2

43

print(bump_version("1.2.3", index=1, increment=2))

44

# "1.4.0"

45

46

# Working with longer version strings

47

print(bump_version("1.2.3.4", index=2))

48

# "1.2.4.0"

49

```

50

51

### Version Validation

52

53

Validate version strings against specific versioning standards.

54

55

```python { .api }

56

def check_version(version: str, style: Style = Style.Pep440) -> None

57

```

58

59

**Parameters**:

60

- `version`: Version string to validate

61

- `style`: Versioning style to check against (default: PEP 440)

62

63

**Raises**: `ValueError` if version is invalid for the specified style

64

65

**Usage Examples**:

66

67

```python

68

from dunamai import check_version, Style

69

70

# Valid PEP 440 versions

71

check_version("1.2.3") # OK

72

check_version("1.2.3rc1") # OK

73

check_version("1.2.3.post7.dev0") # OK

74

check_version("2!1.2.3+local.version") # OK

75

76

# Invalid PEP 440 version

77

try:

78

check_version("v1.2.3") # 'v' prefix not allowed in PEP 440

79

except ValueError as e:

80

print(f"Invalid: {e}")

81

82

# Semantic Versioning validation

83

check_version("1.2.3", Style.SemVer) # OK

84

check_version("1.2.3-alpha.1", Style.SemVer) # OK

85

check_version("1.2.3+build.metadata", Style.SemVer) # OK

86

87

try:

88

check_version("1.2", Style.SemVer) # Missing patch version

89

except ValueError as e:

90

print(f"Invalid SemVer: {e}")

91

92

# Haskell PVP validation

93

check_version("1.2.3", Style.Pvp) # OK

94

check_version("1.2.3-alpha", Style.Pvp) # OK

95

96

try:

97

check_version("1.2.3+build", Style.Pvp) # '+' not allowed in PVP

98

except ValueError as e:

99

print(f"Invalid PVP: {e}")

100

```

101

102

### Dynamic Version Detection

103

104

Determine version for installed packages with fallback strategies.

105

106

```python { .api }

107

def get_version(

108

name: str,

109

first_choice: Optional[Callable[[], Optional[Version]]] = None,

110

third_choice: Optional[Callable[[], Optional[Version]]] = None,

111

fallback: Version = Version("0.0.0"),

112

ignore: Optional[Sequence[Version]] = None,

113

parser: Callable[[str], Version] = Version,

114

) -> Version

115

```

116

117

**Parameters**:

118

- `name`: Installed package name

119

- `first_choice`: Primary version detection callback

120

- `third_choice`: Tertiary fallback if package not found in metadata

121

- `fallback`: Ultimate fallback version (default: "0.0.0")

122

- `ignore`: List of versions to ignore

123

- `parser`: Function to convert strings to Version objects

124

125

**Returns**: First available valid version

126

127

**Usage Examples**:

128

129

```python

130

from dunamai import get_version, Version

131

132

# Basic usage - get version from package metadata

133

version = get_version("dunamai")

134

print(version.serialize())

135

136

# With VCS fallback

137

def vcs_fallback():

138

try:

139

return Version.from_any_vcs()

140

except:

141

return None

142

143

version = get_version(

144

"my-package",

145

first_choice=vcs_fallback,

146

fallback=Version("0.0.1")

147

)

148

149

# Complex fallback strategy

150

def git_version():

151

try:

152

return Version.from_git(strict=True)

153

except:

154

return None

155

156

def any_vcs_version():

157

try:

158

return Version.from_any_vcs(strict=True)

159

except:

160

return None

161

162

version = get_version(

163

"my-package",

164

first_choice=git_version,

165

third_choice=any_vcs_version,

166

fallback=Version("0.0.0", distance=1),

167

ignore=[Version("0.0.0")]

168

)

169

170

# Custom parser

171

def custom_parser(version_str):

172

# Custom logic to parse version strings

173

return Version.parse(version_str, pattern="custom-pattern")

174

175

version = get_version("my-package", parser=custom_parser)

176

```

177

178

### Package Version Setting

179

180

Common pattern for setting `__version__` in Python packages.

181

182

**Usage Examples**:

183

184

```python

185

# In your package's __init__.py

186

from dunamai import get_version, Version

187

188

def _get_version():

189

try:

190

return Version.from_any_vcs()

191

except:

192

return None

193

194

__version__ = get_version(

195

"my-package",

196

first_choice=_get_version,

197

fallback=Version("0.0.0")

198

).serialize()

199

200

# For development versions

201

def _get_dev_version():

202

try:

203

version = Version.from_git()

204

return version if version.distance > 0 else None

205

except:

206

return None

207

208

__version__ = get_version(

209

"my-package",

210

first_choice=_get_dev_version,

211

fallback=Version("0.0.0", distance=1)

212

).serialize()

213

```

214

215

## Batch Operations

216

217

### Multiple Version Validation

218

219

```python

220

from dunamai import check_version, Style

221

222

versions_to_check = [

223

("1.2.3", Style.Pep440),

224

("1.2.3-alpha.1", Style.SemVer),

225

("1.2.3-test", Style.Pvp),

226

]

227

228

for version, style in versions_to_check:

229

try:

230

check_version(version, style)

231

print(f"✓ {version} is valid {style.value}")

232

except ValueError as e:

233

print(f"✗ {version} is invalid {style.value}: {e}")

234

```

235

236

### Version Range Bumping

237

238

```python

239

from dunamai import bump_version

240

241

base_versions = ["1.2.3", "2.0.0", "0.1.0"]

242

243

# Bump all patch versions

244

patch_bumped = [bump_version(v) for v in base_versions]

245

print(patch_bumped) # ["1.2.4", "2.0.1", "0.1.1"]

246

247

# Bump all minor versions

248

minor_bumped = [bump_version(v, index=1) for v in base_versions]

249

print(minor_bumped) # ["1.3.0", "2.1.0", "0.2.0"]

250

```

251

252

### Fallback Chain Pattern

253

254

```python

255

from dunamai import get_version, Version

256

257

def create_fallback_chain(*fallback_funcs):

258

"""Create a fallback chain of version detection functions"""

259

def chain():

260

for func in fallback_funcs:

261

try:

262

result = func()

263

if result:

264

return result

265

except:

266

continue

267

return None

268

return chain

269

270

# Define fallback functions

271

def git_version():

272

return Version.from_git(strict=True)

273

274

def any_vcs_version():

275

return Version.from_any_vcs(strict=True)

276

277

def tagged_version():

278

return Version("1.0.0") # From some configuration

279

280

# Create chain

281

fallback_chain = create_fallback_chain(git_version, any_vcs_version, tagged_version)

282

283

# Use in get_version

284

version = get_version(

285

"my-package",

286

first_choice=fallback_chain,

287

fallback=Version("0.0.0")

288

)

289

```