Skip to content

Commit 619bff3

Browse files
YasenTmdellweg
authored andcommitted
plugin howto bootstrap
1 parent 9fbbbf4 commit 619bff3

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

docs/dev/guides/bootstrap.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# How to Create a Pulp CLI Plugin
2+
3+
This guide shows you how to create a Pulp CLI plugin using the provided bootstrap templates.
4+
Instead of manually creating all the required files, the bootstrap process will automatically generate the correct structure and files for you.
5+
6+
## Overview
7+
8+
Pulp CLI plugin extend the functionality of the Pulp CLI by adding custom commands and features.
9+
The `pulp-cli` project includes templates that make it easy to bootstrap a new plugin with the correct structure and configuration.
10+
11+
## Prerequisites
12+
13+
Before you begin, ensure you have the following installed:
14+
15+
```bash
16+
pip install cookiecutter click pyyaml tomlkit
17+
```
18+
19+
## Bootstrap a New Pulp CLI Plugin
20+
21+
### Using the Bootstrap Template
22+
23+
Navigate to the directory where you want to create your new plugin and run:
24+
25+
```bash
26+
# Clone the pulp-cli repository if you don't have it already
27+
git clone https://github.com/pulp/pulp-cli.git
28+
29+
# Run the bootstrap script
30+
pulp-cli/cookiecutter/apply_templates.py --bootstrap
31+
```
32+
33+
### Answer the Prompts
34+
35+
You will be prompted for several values during the bootstrap process.
36+
The most important is **app_label**, which by convention (when applicable) should match the Pulp server component your plugin targets (for example, use `file` for `pulp-file`).
37+
This value determines the import paths and command names for your plugin.
38+
You will also see additional prompts for options such as glue integration, documentation, translations, version, repository URL, and CI configuration.
39+
Answer these as appropriate for your project.
40+
41+
### Key Files and Directories
42+
43+
The bootstrap process creates several important directories and files:
44+
45+
- `pulpcore/cli/my-plugin/__init__.py`: Main entry point where you define command groups.
46+
See below for more details
47+
- `pulp-glue-my-plugin/pulp_glue/my-plugin/context.py`: API context class for interacting with Pulp.
48+
See below for more details
49+
- `pyproject.toml`: Project metadata, dependencies, and build configuration.
50+
This file contains essential project information including author details, licensing information, version numbers, package dependencies, and build system configuration.
51+
You'll need to customize the author name, email, project description, license type to match your plugin's specific requirements.
52+
- `CHANGES/`: Directory for changelog fragments (.feature, .bugfix, etc. files).
53+
See the [changelog update guide] for more details.
54+
- `.github/workflows/`: This directory contains GitHub Actions workflow configurations for automated testing and continuous integration.
55+
These files are pre-configured and do not require modification when initially setting up your plugin development environment.
56+
The CI workflows will automatically run tests and validation checks on your plugin code when you push changes to your repository.
57+
58+
## Customizing Your Plugin
59+
60+
### Create API Context Classes
61+
62+
Edit `pulp-glue-my-plugin/pulp_glue/my_plugin/context.py` to define context classes that handle API interactions:
63+
64+
```python
65+
import typing as t
66+
67+
from pulp_glue.common.context import (
68+
PulpEntityContext,
69+
PluginRequirement
70+
)
71+
72+
73+
class PulpMyResourceContext():
74+
"""Context for working with my custom resource."""
75+
76+
ID_PREFIX = "my_resource"
77+
NEEDS_PLUGINS = [PluginRequirement("my_plugin", specifier=">=0.0.1")]
78+
79+
def example_action(self, data: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
80+
"""Execute an example action with specific data.
81+
82+
Args:
83+
data: The data dictionary to send to the API
84+
85+
Returns:
86+
The action result
87+
"""
88+
response = self.call(
89+
operation="example_action",
90+
body=data,
91+
)
92+
return response
93+
```
94+
95+
### Add Subcommands to the CLI
96+
97+
Edit `pulpcore/cli/my_plugin/__init__.py` to define your command groups and add functionality:
98+
99+
```python
100+
import typing as t
101+
import click
102+
from pulp_cli.generic import pulp_group
103+
from pulp_glue.common.i18n import get_translation
104+
105+
# Import your command plugins
106+
from pulpcore.cli.my_plugin.my_resource import my_resource
107+
108+
translation = get_translation(__package__)
109+
_ = translation.gettext
110+
111+
__version__ = "0.1.0" # Matches version in pyproject.toml
112+
113+
114+
@pulp_group(name="my_plugin")
115+
def my_plugin_group() -> None:
116+
"""My plugin commands."""
117+
pass
118+
119+
120+
def mount(main: click.Group, **kwargs: t.Any) -> None:
121+
# Add your command groups here
122+
my_plugin_group.add_command(my_resource)
123+
main.add_command(my_plugin_group)
124+
```
125+
126+
### Create Plugin Commands
127+
128+
Create a new file for your resource, e.g., `pulpcore/cli/my_plugin/my_resource.py`:
129+
130+
```python
131+
import click
132+
from pulp_cli.common.context import pass_pulp_context
133+
from pulp_glue.common.context import PulpContext
134+
from pulp_glue.my_plugin.context import PulpMyResourceContext
135+
from pulp_cli.common.generic import pass_entity_context
136+
137+
138+
@click.group()
139+
@pass_pulp_context
140+
@click.pass_context
141+
def my_resource(ctx: click.Context, pulp_ctx: PulpContext, /) -> None:
142+
"""My custom commands."""
143+
ctx.obj = PulpMyResourceContext(pulp_ctx)
144+
145+
146+
@my_resource.command()
147+
@click.option("--data", required=True, help="Data for the example action")
148+
@pass_entity_context
149+
@pass_pulp_context
150+
def my_command(pulp_ctx: PulpContext, my_resource_ctx: PulpMyResourceContext, /, data: str):
151+
"""Calling example action."""
152+
result = my_resource_ctx.example_action({"data": data})
153+
pulp_ctx.output_result(result)
154+
```
155+
156+
## Development Workflow
157+
158+
### Install Your plugin in Development Mode
159+
160+
For installation instructions, see [here][installation].
161+
162+
### Test Your Commands
163+
164+
After installation, you can test your commands:
165+
166+
```bash
167+
pulp my-plugin my-resource my-command --data "example"
168+
```
169+
170+
Consider [writing tests] for your commands as soon as you implement them.
171+
172+
## Update Templates
173+
174+
If you need to update the project structure with new template changes:
175+
176+
```bash
177+
cd pulp-cli-my-plugin
178+
../pulp-cli/cookiecutter/apply_templates.py
179+
```
180+
181+
[changelog update guide]: site:pulpcore/docs/dev/guides/git/#changelog-update
182+
[installation]: site:pulp-cli/docs/user/guides/installation#from-a-source-checkout
183+
[writing tests]: site:pulp-cli/docs/dev/guides/contributing/#testing

0 commit comments

Comments
 (0)