or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mdgit-operations.mdhook-management.mdindex.mdpath-utilities.mdplugin-api.md

path-utilities.mddocs/

0

# Path Utilities

1

2

Path matching and validation utilities for file processing in plugins. This API provides convenient functions for filtering and validating file paths based on patterns and file types.

3

4

## Capabilities

5

6

### Python Path Validation

7

8

Check if paths represent Python source files with proper extension matching.

9

10

```python { .api }

11

def is_python_path(path: Optional[Path]) -> bool:

12

"""

13

Function to check if path is a Python file.

14

15

Args:

16

path: A path to a file

17

18

Returns:

19

True if path is a Python file (ends with .py), False otherwise

20

"""

21

```

22

23

**Usage Examples:**

24

25

```python

26

from autohooks.api.path import is_python_path

27

from autohooks.api.git import get_staged_status

28

from pathlib import Path

29

30

def precommit(config, report_progress, **kwargs):

31

# Get staged files

32

staged_files = get_staged_status()

33

34

# Filter for Python files using utility

35

python_files = []

36

for status_entry in staged_files:

37

if is_python_path(status_entry.path):

38

python_files.append(status_entry)

39

40

# Process Python files

41

for status_entry in python_files:

42

process_python_file(status_entry.absolute_path())

43

44

return 0

45

46

# Direct path checking

47

test_paths = [

48

Path("script.py"), # True

49

Path("module.py"), # True

50

Path("README.md"), # False

51

Path("config.toml"), # False

52

None # False

53

]

54

55

for path in test_paths:

56

result = is_python_path(path)

57

print(f"{path}: {result}")

58

```

59

60

### Pattern Matching

61

62

Match file paths against multiple patterns using fnmatch-style glob patterns with support for complex filtering rules.

63

64

```python { .api }

65

def match(path: PathLike, pattern_list: Iterable[str]) -> bool:

66

"""

67

Check if a path like object matches to one of the patterns.

68

69

Internally fnmatch is used.

70

See https://docs.python.org/3/library/fnmatch.html for details.

71

72

Args:

73

path: PathLike to check if it matches to one of the patterns

74

pattern_list: Iterable (e.g tuple or list) of patterns to match against the path

75

76

Returns:

77

True if path matches a pattern of the list, False otherwise

78

"""

79

```

80

81

**Usage Examples:**

82

83

```python

84

from autohooks.api.path import match

85

from autohooks.api.git import get_staged_status

86

from pathlib import Path

87

88

def precommit(config, report_progress, **kwargs):

89

# Get staged files

90

staged_files = get_staged_status()

91

92

# Define patterns for different file types

93

python_patterns = ["*.py", "*.pyi"]

94

config_patterns = ["*.toml", "*.yaml", "*.yml", "*.json"]

95

documentation_patterns = ["*.md", "*.rst", "*.txt"]

96

97

python_files = []

98

config_files = []

99

doc_files = []

100

101

for status_entry in staged_files:

102

path = status_entry.path

103

104

if match(path, python_patterns):

105

python_files.append(status_entry)

106

elif match(path, config_patterns):

107

config_files.append(status_entry)

108

elif match(path, documentation_patterns):

109

doc_files.append(status_entry)

110

111

# Process different file types

112

if python_files:

113

info(f"Processing {len(python_files)} Python files")

114

115

if config_files:

116

info(f"Processing {len(config_files)} config files")

117

118

return 0

119

120

# Pattern matching examples

121

test_files = [

122

"src/main.py",

123

"tests/test_module.py",

124

"docs/README.md",

125

"pyproject.toml",

126

"requirements.txt"

127

]

128

129

# Match Python files

130

python_patterns = ["*.py", "**/*.py"]

131

for filepath in test_files:

132

if match(Path(filepath), python_patterns):

133

print(f"Python file: {filepath}")

134

135

# Match configuration files

136

config_patterns = ["*.toml", "*.yaml", "*.yml", "*.json", "*.ini"]

137

for filepath in test_files:

138

if match(Path(filepath), config_patterns):

139

print(f"Config file: {filepath}")

140

141

# Match by directory patterns

142

test_patterns = ["tests/**", "test_*"]

143

for filepath in test_files:

144

if match(Path(filepath), test_patterns):

145

print(f"Test file: {filepath}")

146

```

147

148

### Advanced Pattern Usage

149

150

Complex pattern matching scenarios for sophisticated file filtering.

151

152

**Usage Examples:**

153

154

```python

155

from autohooks.api.path import match, is_python_path

156

from autohooks.api.git import get_staged_status

157

158

def precommit(config, report_progress, **kwargs):

159

staged_files = get_staged_status()

160

161

# Plugin configuration patterns

162

plugin_config = config.get("tool", "my-plugin")

163

include_patterns = plugin_config.get_value("include", ["*.py"])

164

exclude_patterns = plugin_config.get_value("exclude", [])

165

166

# Filter files based on patterns

167

target_files = []

168

for status_entry in staged_files:

169

path = status_entry.path

170

171

# Check include patterns

172

if match(path, include_patterns):

173

# Check exclude patterns

174

if exclude_patterns and match(path, exclude_patterns):

175

continue # Skip excluded files

176

target_files.append(status_entry)

177

178

# Advanced filtering combining utilities

179

python_files = [

180

entry for entry in target_files

181

if is_python_path(entry.path)

182

]

183

184

# Pattern-based exclusions

185

test_patterns = ["test_*.py", "*_test.py", "tests/**/*.py"]

186

non_test_files = [

187

entry for entry in python_files

188

if not match(entry.path, test_patterns)

189

]

190

191

return 0

192

193

# Complex pattern examples

194

complex_patterns = [

195

"src/**/*.py", # Python files in src directory tree

196

"!src/**/test_*.py", # Exclude test files (Note: fnmatch doesn't support !)

197

"*.{py,pyi}", # Python implementation and interface files

198

"[Mm]akefile*", # Makefiles with different cases

199

"config.{yml,yaml,json}" # Multiple config file extensions

200

]

201

202

# Note: For exclusion patterns, you need to handle them separately

203

include_patterns = ["src/**/*.py", "*.py"]

204

exclude_patterns = ["test_*.py", "*_test.py", "tests/**"]

205

206

def should_process_file(path: Path) -> bool:

207

"""Check if file should be processed based on include/exclude patterns."""

208

# Must match include patterns

209

if not match(path, include_patterns):

210

return False

211

212

# Must not match exclude patterns

213

if match(path, exclude_patterns):

214

return False

215

216

return True

217

```

218

219

### Integration with Git Operations

220

221

Combining path utilities with git operations for comprehensive file filtering.

222

223

**Usage Examples:**

224

225

```python

226

from autohooks.api.path import is_python_path, match

227

from autohooks.api.git import get_staged_status, is_staged_status

228

229

def precommit(config, report_progress, **kwargs):

230

# Get all status entries

231

all_status = get_staged_status()

232

233

# Multi-stage filtering

234

processable_files = []

235

236

for status_entry in all_status:

237

# Only staged files

238

if not is_staged_status(status_entry):

239

continue

240

241

# Only Python files

242

if not is_python_path(status_entry.path):

243

continue

244

245

# Apply custom patterns

246

source_patterns = ["src/**/*.py", "lib/**/*.py"]

247

if not match(status_entry.path, source_patterns):

248

continue

249

250

# Exclude patterns

251

exclude_patterns = ["**/migrations/*.py", "**/__pycache__/**"]

252

if match(status_entry.path, exclude_patterns):

253

continue

254

255

processable_files.append(status_entry)

256

257

if not processable_files:

258

info("No Python source files to process")

259

return 0

260

261

report_progress.init(len(processable_files))

262

263

for status_entry in processable_files:

264

process_python_file(status_entry.absolute_path())

265

report_progress.update()

266

267

return 0

268

```

269

270

## Pattern Syntax

271

272

The `match` function uses Python's `fnmatch` module, which supports Unix shell-style wildcards:

273

274

- `*` - matches everything

275

- `?` - matches any single character

276

- `[seq]` - matches any character in seq

277

- `[!seq]` - matches any character not in seq

278

- `**` - matches directories recursively (when using `pathlib`)

279

280

**Pattern Examples:**

281

282

```python

283

patterns = [

284

"*.py", # All Python files

285

"test_*.py", # Test files starting with test_

286

"*_test.py", # Test files ending with _test

287

"src/**/*.py", # Python files in src directory tree

288

"*.{py,pyi}", # Multiple extensions (not standard fnmatch)

289

"[Tt]est*.py", # Files starting with Test or test

290

"config.?ml", # config.yml, config.xml, etc.

291

]

292

```

293

294

## Types

295

296

```python { .api }

297

from pathlib import Path

298

from typing import Iterable, Optional

299

from os import PathLike

300

```