or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconfiguration.mdgit-integration.mdhooks.mdindex.mdlanguage-support.mdrepository-management.md

language-support.mddocs/

0

# Language Support

1

2

Multi-language support system with plugin-based architecture for 22+ programming languages. Pre-commit provides a standardized interface for integrating hooks written in different programming languages, each with their own environment management and execution requirements.

3

4

## Capabilities

5

6

### Language Protocol

7

8

Base protocol that all language implementations must follow.

9

10

```python { .api }

11

class Language(Protocol):

12

"""

13

Protocol defining the interface for language implementations.

14

15

Each supported language must implement this protocol to provide

16

consistent environment management and hook execution.

17

"""

18

19

@property

20

def ENVIRONMENT_DIR(self) -> str | None:

21

"""

22

Directory name for language-specific environments.

23

24

Returns None for languages that don't require separate environments.

25

26

Returns:

27

- str | None: Environment directory name or None

28

"""

29

30

def get_default_version(self) -> str:

31

"""

32

Get the default version identifier for this language.

33

34

Returns:

35

- str: Default version string (e.g., 'default', 'system')

36

"""

37

38

def health_check(self, prefix: Prefix, version: str) -> str | None:

39

"""

40

Check if the language environment is healthy and functional.

41

42

Parameters:

43

- prefix: Installation prefix for the environment

44

- version: Language version to check

45

46

Returns:

47

- str | None: Error message if unhealthy, None if healthy

48

"""

49

50

def install_environment(

51

self,

52

prefix: Prefix,

53

version: str,

54

additional_dependencies: Sequence[str]

55

) -> None:

56

"""

57

Install or update the language environment.

58

59

Parameters:

60

- prefix: Installation prefix for the environment

61

- version: Language version to install

62

- additional_dependencies: Extra packages to install

63

"""

64

65

def in_env(self, prefix: Prefix, version: str) -> ContextManager[None]:

66

"""

67

Context manager for executing within the language environment.

68

69

Parameters:

70

- prefix: Installation prefix for the environment

71

- version: Language version to use

72

73

Returns:

74

- ContextManager: Context for environment activation

75

"""

76

77

def run_hook(

78

self,

79

prefix: Prefix,

80

version: str,

81

cmd: Sequence[str],

82

*,

83

file_args: Sequence[str],

84

prepend_base_dir: bool,

85

require_serial: bool,

86

color: bool

87

) -> tuple[int, bytes]:

88

"""

89

Execute a hook within the language environment.

90

91

Parameters:

92

- prefix: Installation prefix for the environment

93

- version: Language version to use

94

- cmd: Command and arguments to execute

95

- file_args: Files to pass to the hook

96

- prepend_base_dir: Whether to prepend base directory to paths

97

- require_serial: Whether serial execution is required

98

- color: Whether to enable colored output

99

100

Returns:

101

- tuple: (exit_code, output_bytes)

102

"""

103

```

104

105

### Supported Languages

106

107

Complete registry of supported languages with their implementations.

108

109

```python { .api }

110

languages: dict[str, Language] = {

111

'conda': conda, # Conda package manager

112

'coursier': coursier, # Scala/Coursier dependency manager

113

'dart': dart, # Dart programming language

114

'docker': docker, # Docker containers

115

'docker_image': docker_image, # Pre-built Docker images

116

'dotnet': dotnet, # .NET framework

117

'fail': fail, # Always-fail hook for testing

118

'golang': golang, # Go programming language

119

'haskell': haskell, # Haskell programming language

120

'julia': julia, # Julia programming language

121

'lua': lua, # Lua programming language

122

'node': node, # Node.js/npm

123

'perl': perl, # Perl programming language

124

'pygrep': pygrep, # Python regex-based hooks

125

'python': python, # Python programming language

126

'r': r, # R programming language

127

'ruby': ruby, # Ruby programming language

128

'rust': rust, # Rust programming language

129

'script': script, # Shell scripts

130

'swift': swift, # Swift programming language

131

'system': system # System executables

132

}

133

```

134

135

## Individual Language Implementations

136

137

### Python Language Support

138

139

```python { .api }

140

class PythonLanguage:

141

"""Python language implementation with virtual environment support."""

142

143

ENVIRONMENT_DIR = 'py_env'

144

145

def get_default_version(self) -> str:

146

"""Returns 'python3' as default Python version."""

147

148

def install_environment(

149

self,

150

prefix: Prefix,

151

version: str,

152

additional_dependencies: Sequence[str]

153

) -> None:

154

"""

155

Create virtual environment and install dependencies.

156

157

Creates a Python virtual environment and installs the hook

158

package along with any additional dependencies.

159

"""

160

161

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

162

"""Execute hook within Python virtual environment."""

163

```

164

165

### Node.js Language Support

166

167

```python { .api }

168

class NodeLanguage:

169

"""Node.js language implementation with npm package management."""

170

171

ENVIRONMENT_DIR = 'node_env'

172

173

def get_default_version(self) -> str:

174

"""Returns 'node' as default Node.js version."""

175

176

def install_environment(

177

self,

178

prefix: Prefix,

179

version: str,

180

additional_dependencies: Sequence[str]

181

) -> None:

182

"""

183

Install Node.js packages using npm.

184

185

Sets up npm environment and installs hook package with dependencies.

186

"""

187

188

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

189

"""Execute hook with Node.js runtime."""

190

```

191

192

### Go Language Support

193

194

```python { .api }

195

class GolangLanguage:

196

"""Go language implementation with module support."""

197

198

ENVIRONMENT_DIR = 'go_env'

199

200

def get_default_version(self) -> str:

201

"""Returns 'go' as default Go version."""

202

203

def install_environment(

204

self,

205

prefix: Prefix,

206

version: str,

207

additional_dependencies: Sequence[str]

208

) -> None:

209

"""

210

Install Go modules and build binaries.

211

212

Downloads Go modules and builds executable binaries for hook execution.

213

"""

214

215

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

216

"""Execute Go binary hook."""

217

```

218

219

### Ruby Language Support

220

221

```python { .api }

222

class RubyLanguage:

223

"""Ruby language implementation with gem management."""

224

225

ENVIRONMENT_DIR = 'ruby_env'

226

227

def get_default_version(self) -> str:

228

"""Returns 'ruby' as default Ruby version."""

229

230

def install_environment(

231

self,

232

prefix: Prefix,

233

version: str,

234

additional_dependencies: Sequence[str]

235

) -> None:

236

"""

237

Install Ruby gems in isolated environment.

238

239

Creates gem environment and installs hook gem with dependencies.

240

"""

241

242

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

243

"""Execute hook with Ruby runtime."""

244

```

245

246

### Docker Language Support

247

248

```python { .api }

249

class DockerLanguage:

250

"""Docker language implementation for containerized hooks."""

251

252

ENVIRONMENT_DIR = None # No local environment needed

253

254

def get_default_version(self) -> str:

255

"""Returns 'default' for Docker version."""

256

257

def install_environment(

258

self,

259

prefix: Prefix,

260

version: str,

261

additional_dependencies: Sequence[str]

262

) -> None:

263

"""

264

Build Docker image for hook execution.

265

266

Builds Docker image with hook and its dependencies.

267

"""

268

269

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

270

"""Execute hook within Docker container."""

271

```

272

273

### System Language Support

274

275

```python { .api }

276

class SystemLanguage:

277

"""System language for executing system-installed binaries."""

278

279

ENVIRONMENT_DIR = None # Uses system executables

280

281

def get_default_version(self) -> str:

282

"""Returns 'system' for system executables."""

283

284

def install_environment(

285

self,

286

prefix: Prefix,

287

version: str,

288

additional_dependencies: Sequence[str]

289

) -> None:

290

"""

291

No installation needed for system executables.

292

293

Validates that required executables are available on system PATH.

294

"""

295

296

def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]:

297

"""Execute system executable directly."""

298

```

299

300

## Language Utilities

301

302

### Language Resolution

303

304

Functions for resolving and working with language implementations.

305

306

```python { .api }

307

def get_language(language: str) -> Language:

308

"""

309

Get language implementation by name.

310

311

Parameters:

312

- language: Language name

313

314

Returns:

315

- Language: Language implementation instance

316

317

Raises:

318

- ValueError: If language is not supported

319

"""

320

321

def language_version_info(language: str, version: str) -> dict[str, Any]:

322

"""

323

Get version information for a language.

324

325

Parameters:

326

- language: Language name

327

- version: Version string

328

329

Returns:

330

- dict: Version information and capabilities

331

"""

332

```

333

334

### Environment Management

335

336

Utilities for managing language environments across hooks.

337

338

```python { .api }

339

def clean_environment(prefix: Prefix, language: str) -> None:

340

"""

341

Clean up language environment files.

342

343

Parameters:

344

- prefix: Installation prefix

345

- language: Language name

346

"""

347

348

def environment_exists(prefix: Prefix, language: str, version: str) -> bool:

349

"""

350

Check if language environment is installed.

351

352

Parameters:

353

- prefix: Installation prefix

354

- language: Language name

355

- version: Language version

356

357

Returns:

358

- bool: True if environment exists

359

"""

360

```

361

362

## Language-Specific Features

363

364

### Python Features

365

366

```python { .api }

367

def python_venv_info(prefix: Prefix) -> dict[str, str]:

368

"""Get Python virtual environment information."""

369

370

def install_python_requirements(prefix: Prefix, requirements: list[str]) -> None:

371

"""Install Python packages from requirements list."""

372

```

373

374

### Node.js Features

375

376

```python { .api }

377

def node_package_info(prefix: Prefix) -> dict[str, Any]:

378

"""Get Node.js package information."""

379

380

def install_node_packages(prefix: Prefix, packages: list[str]) -> None:

381

"""Install Node.js packages via npm."""

382

```

383

384

### Docker Features

385

386

```python { .api }

387

def docker_image_exists(image: str) -> bool:

388

"""Check if Docker image exists locally."""

389

390

def pull_docker_image(image: str) -> None:

391

"""Pull Docker image from registry."""

392

```

393

394

## Usage Examples

395

396

### Working with Language Implementations

397

398

```python

399

from pre_commit.languages import languages

400

from pre_commit.prefix import Prefix

401

402

# Get Python language implementation

403

python_lang = languages['python']

404

print(f"Python environment dir: {python_lang.ENVIRONMENT_DIR}")

405

print(f"Default version: {python_lang.get_default_version()}")

406

407

# Create prefix for hook installation

408

prefix = Prefix('/tmp/hook-env')

409

410

# Install Python environment with additional dependencies

411

python_lang.install_environment(

412

prefix=prefix,

413

version='python3.9',

414

additional_dependencies=['black', 'flake8']

415

)

416

417

# Check environment health

418

health_result = python_lang.health_check(prefix, 'python3.9')

419

if health_result is None:

420

print("Python environment is healthy")

421

else:

422

print(f"Environment issue: {health_result}")

423

```

424

425

### Executing Hooks with Language Support

426

427

```python

428

from pre_commit.languages import languages

429

430

# Get language implementation

431

node_lang = languages['node']

432

433

# Execute hook within Node.js environment

434

with node_lang.in_env(prefix, 'node'):

435

exit_code, output = node_lang.run_hook(

436

prefix=prefix,

437

version='node',

438

cmd=['eslint', '--fix'],

439

file_args=['src/app.js', 'src/utils.js'],

440

prepend_base_dir=True,

441

require_serial=False,

442

color=True

443

)

444

445

print(f"Hook exit code: {exit_code}")

446

if output:

447

print(f"Hook output: {output.decode()}")

448

```

449

450

### Language Environment Management

451

452

```python

453

from pre_commit.languages import get_language, environment_exists

454

455

# Work with Go language

456

go_lang = get_language('golang')

457

458

# Check if environment exists

459

if environment_exists(prefix, 'golang', 'go1.19'):

460

print("Go environment already installed")

461

else:

462

print("Installing Go environment...")

463

go_lang.install_environment(prefix, 'go1.19', [])

464

465

# Get language version info

466

version_info = language_version_info('golang', 'go1.19')

467

print(f"Go version info: {version_info}")

468

```

469

470

### Multi-Language Hook Processing

471

472

```python

473

from pre_commit.languages import languages

474

475

# Process hooks for different languages

476

hook_configs = [

477

{'language': 'python', 'version': 'python3.9', 'deps': ['black']},

478

{'language': 'node', 'version': 'node16', 'deps': ['eslint']},

479

{'language': 'golang', 'version': 'go1.19', 'deps': []},

480

]

481

482

for config in hook_configs:

483

lang_impl = languages[config['language']]

484

485

# Install environment

486

lang_impl.install_environment(

487

prefix=prefix,

488

version=config['version'],

489

additional_dependencies=config['deps']

490

)

491

492

print(f"Installed {config['language']} environment")

493

```