or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-system.mdcli-commands.mdconfiguration.mdcore-api.mdenvironment.mdindex.mdinstallation.mdpackage-management.mdplugins.md

plugins.mddocs/

0

# Plugin System

1

2

Extensibility interfaces for creating Poetry plugins. Enables custom commands, functionality extensions, and integration with external tools through a flexible plugin architecture.

3

4

## Capabilities

5

6

### Base Plugin Interface

7

8

Abstract base class for all Poetry plugins providing the foundation for extensibility.

9

10

```python { .api }

11

class Plugin:

12

"""

13

Base plugin interface for Poetry extensions.

14

15

Abstract base class that all Poetry plugins must implement

16

to integrate with Poetry's functionality.

17

"""

18

19

def activate(self, poetry: Poetry, io) -> None:

20

"""

21

Activate plugin with Poetry instance.

22

23

Args:

24

poetry: Poetry instance

25

io: IO interface for output

26

27

Raises:

28

NotImplementedError: Must be implemented by plugins

29

"""

30

```

31

32

### Application Plugin Interface

33

34

Plugin interface for extending Poetry's CLI with custom commands.

35

36

```python { .api }

37

class ApplicationPlugin:

38

"""

39

Plugin interface for CLI command extensions.

40

41

Allows plugins to register custom commands with Poetry's

42

command-line interface.

43

"""

44

45

@property

46

def commands(self) -> list:

47

"""

48

List of command classes to register.

49

50

Returns:

51

List of command class instances

52

"""

53

54

def activate(self, application) -> None:

55

"""

56

Activate plugin with CLI application.

57

58

Args:

59

application: CLI application instance

60

"""

61

```

62

63

### Plugin Manager

64

65

Manages plugin discovery, loading, and activation within Poetry.

66

67

```python { .api }

68

class PluginManager:

69

"""

70

Plugin discovery and management system.

71

72

Handles loading, activating, and managing Poetry plugins

73

with support for entry point discovery and error handling.

74

"""

75

76

def __init__(self, group: str = "poetry.plugin"):

77

"""

78

Initialize plugin manager.

79

80

Args:

81

group: Entry point group for plugin discovery

82

"""

83

84

def load_plugins(self, env: Env = None) -> None:

85

"""

86

Load plugins from entry points.

87

88

Args:

89

env: Environment for plugin loading

90

"""

91

92

def activate_plugins(self, poetry: Poetry, io = None) -> None:

93

"""

94

Activate loaded plugins.

95

96

Args:

97

poetry: Poetry instance

98

io: IO interface

99

"""

100

101

def get_plugin(self, name: str):

102

"""

103

Get plugin by name.

104

105

Args:

106

name: Plugin name

107

108

Returns:

109

Plugin instance or None

110

"""

111

112

def has_plugins(self) -> bool:

113

"""

114

Check if any plugins are loaded.

115

116

Returns:

117

True if plugins are available

118

"""

119

```

120

121

## Plugin Development

122

123

### Creating a Basic Plugin

124

125

```python

126

from poetry.plugins.plugin import Plugin

127

128

class MyPlugin(Plugin):

129

"""Example Poetry plugin."""

130

131

def activate(self, poetry, io):

132

"""Activate plugin functionality."""

133

io.write_line("My plugin activated!")

134

135

# Access Poetry functionality

136

project_name = poetry.package.name

137

io.write_line(f"Working with project: {project_name}")

138

139

# Plugin-specific initialization

140

self.setup_custom_functionality(poetry)

141

142

def setup_custom_functionality(self, poetry):

143

"""Setup plugin-specific functionality."""

144

pass

145

```

146

147

### Creating a Command Plugin

148

149

```python

150

from poetry.plugins.application_plugin import ApplicationPlugin

151

from poetry.console.commands.command import Command

152

153

class MyCommand(Command):

154

"""Custom Poetry command."""

155

156

name = "my-command"

157

description = "My custom command"

158

159

def handle(self):

160

"""Handle command execution."""

161

self.line("Executing my custom command!")

162

163

# Access Poetry instance

164

poetry = self.poetry

165

self.line(f"Project: {poetry.package.name}")

166

167

# Custom command logic

168

return 0

169

170

class MyCommandPlugin(ApplicationPlugin):

171

"""Plugin that adds custom commands."""

172

173

@property

174

def commands(self):

175

"""Return list of commands to register."""

176

return [MyCommand()]

177

178

def activate(self, application):

179

"""Activate plugin with application."""

180

pass # Commands are automatically registered

181

```

182

183

### Plugin Entry Points

184

185

Configure plugins in `pyproject.toml`:

186

187

```toml

188

[tool.poetry.plugins."poetry.plugin"]

189

my-plugin = "my_package.plugins:MyPlugin"

190

191

[tool.poetry.plugins."poetry.application.plugin"]

192

my-commands = "my_package.plugins:MyCommandPlugin"

193

```

194

195

## Advanced Plugin Patterns

196

197

### Configuration Extension Plugin

198

199

```python

200

from poetry.plugins.plugin import Plugin

201

202

class ConfigExtensionPlugin(Plugin):

203

"""Plugin that extends configuration options."""

204

205

def activate(self, poetry, io):

206

"""Add custom configuration handling."""

207

config = poetry.config

208

209

# Add custom configuration defaults

210

custom_config = {

211

"my-plugin.enabled": True,

212

"my-plugin.custom-setting": "value"

213

}

214

config.merge(custom_config)

215

216

# Register configuration validators

217

self.register_validators(config)

218

219

def register_validators(self, config):

220

"""Register custom configuration validators."""

221

pass

222

```

223

224

### Repository Plugin

225

226

```python

227

from poetry.plugins.plugin import Plugin

228

from poetry.repositories.repository import Repository

229

230

class CustomRepository(Repository):

231

"""Custom repository implementation."""

232

233

def __init__(self, name, url, config):

234

"""Initialize custom repository."""

235

super().__init__(name)

236

self.url = url

237

self.config = config

238

239

def find_packages(self, dependency):

240

"""Find packages in custom repository."""

241

# Custom package discovery logic

242

return []

243

244

class RepositoryPlugin(Plugin):

245

"""Plugin that adds custom repository support."""

246

247

def activate(self, poetry, io):

248

"""Register custom repository."""

249

# Add custom repository to pool

250

custom_repo = CustomRepository(

251

name="custom",

252

url="https://custom-repo.example.com",

253

config=poetry.config

254

)

255

256

poetry.pool.add_repository(custom_repo, priority="supplemental")

257

```

258

259

### Build System Integration Plugin

260

261

```python

262

from poetry.plugins.plugin import Plugin

263

264

class BuildIntegrationPlugin(Plugin):

265

"""Plugin that integrates with build systems."""

266

267

def activate(self, poetry, io):

268

"""Setup build system integration."""

269

# Hook into build process

270

self.setup_build_hooks(poetry)

271

272

# Add custom build steps

273

self.register_build_steps(poetry)

274

275

def setup_build_hooks(self, poetry):

276

"""Setup hooks for build process."""

277

# Pre-build hooks

278

# Post-build hooks

279

pass

280

281

def register_build_steps(self, poetry):

282

"""Register custom build steps."""

283

pass

284

```

285

286

## Plugin Testing

287

288

### Mock Plugin Environment

289

290

```python

291

from poetry.plugins.plugin_manager import PluginManager

292

from poetry.factory import Factory

293

294

def test_plugin_activation():

295

"""Test plugin activation."""

296

# Create Poetry instance

297

poetry = Factory().create_poetry()

298

299

# Create plugin manager

300

plugin_manager = PluginManager()

301

302

# Load and activate plugins

303

plugin_manager.load_plugins()

304

plugin_manager.activate_plugins(poetry)

305

306

# Test plugin functionality

307

assert plugin_manager.has_plugins()

308

```

309

310

### Plugin Integration Testing

311

312

```python

313

import pytest

314

from poetry.console.application import Application

315

316

def test_command_plugin():

317

"""Test command plugin integration."""

318

# Create application with plugins

319

app = Application()

320

321

# Test custom command availability

322

assert app.has("my-command")

323

324

# Test command execution

325

tester = ApplicationTester(app)

326

tester.execute("my-command")

327

328

assert tester.status_code == 0

329

```

330

331

## Error Handling

332

333

Plugin system exceptions and error conditions:

334

335

```python { .api }

336

class PluginError(PoetryError):

337

"""Base plugin error."""

338

339

class PluginLoadError(PluginError):

340

"""Plugin loading failures."""

341

342

class PluginActivationError(PluginError):

343

"""Plugin activation errors."""

344

345

class InvalidPluginError(PluginError):

346

"""Invalid plugin configuration or implementation."""

347

```

348

349

Common plugin errors:

350

- Plugin entry points not found or invalid

351

- Plugin dependencies missing or incompatible

352

- Plugin activation failures

353

- Invalid command registration

354

- Configuration conflicts between plugins

355

- Plugin compatibility issues with Poetry versions