Skip to content

Commit 7ae67c7

Browse files
authored
Merge pull request #120 from pedro-psb/add-fetch-functionality
Add repository find mechanism
2 parents 9c0d10d + 1c3e210 commit 7ae67c7

File tree

3 files changed

+96
-31
lines changed

3 files changed

+96
-31
lines changed

src/pulp_docs/cli.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from mkdocs.__main__ import cli as mkdocs_cli
77
from mkdocs.config import load_config
8-
from pulp_docs.context import ctx_blog, ctx_docstrings, ctx_draft
8+
from pulp_docs.context import ctx_blog, ctx_docstrings, ctx_draft, ctx_path
99

1010

1111
def blog_callback(ctx: click.Context, param: click.Parameter, value: bool) -> bool:
@@ -25,6 +25,12 @@ def draft_callback(ctx: click.Context, param: click.Parameter, value: bool) -> b
2525
return value
2626

2727

28+
def find_path_callback(ctx: click.Context, param: click.Parameter, value: bool) -> bool:
29+
result = [item.strip() for item in value.split(":") if item.strip()]
30+
ctx_path.set(result)
31+
return result
32+
33+
2834
blog_option = click.option(
2935
"--blog/--no-blog",
3036
default=True,
@@ -47,6 +53,15 @@ def draft_callback(ctx: click.Context, param: click.Parameter, value: bool) -> b
4753
help="Don't fail if repositories are missing.",
4854
)
4955

56+
path_option = click.option(
57+
"--path",
58+
envvar="PULPDOCS_PATH",
59+
expose_value=False,
60+
default="",
61+
callback=find_path_callback,
62+
help="A colon separated list of lookup paths in the form: [repo1@]path1 [:[repo2@]path2 [...]].",
63+
)
64+
5065

5166
async def clone_repositories(repositories: list[str], dest_dir: Path) -> None:
5267
"""Clone multiple repositories concurrently."""
@@ -105,3 +120,7 @@ def fetch(dest, config_file):
105120
draft_option(sub_command)
106121
blog_option(sub_command)
107122
docstrings_option(sub_command)
123+
path_option(sub_command)
124+
serve_options = sub_command.params
125+
config_file_opt = next(filter(lambda opt: opt.name == "config_file", serve_options))
126+
config_file_opt.envvar = "PULPDOCS_DIR"

src/pulp_docs/context.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
ctx_blog = ContextVar("ctx_blog", default=True)
55
ctx_docstrings = ContextVar("ctx_docstrings", default=True)
66
ctx_draft = ContextVar("ctx_draft", default=False)
7+
ctx_path = ContextVar("ctx_path", default=None)

src/pulp_docs/plugin.py

+75-30
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33
import json
44
import tomllib
55
import yaml
6+
import glob
67

78
import httpx
9+
from dataclasses import dataclass
810
from git import Repo, GitCommandError
911
from mkdocs.config import Config, config_options
1012
from mkdocs.config.defaults import MkDocsConfig
1113
from mkdocs.exceptions import PluginError
12-
from mkdocs.plugins import event_priority, get_plugin_logger, BasePlugin
14+
from mkdocs.plugins import get_plugin_logger, BasePlugin
1315
from mkdocs.structure.files import File, Files
1416
from mkdocs.structure.nav import Navigation, Section, Link
1517
from mkdocs.structure.pages import Page
1618
from mkdocs.utils.templates import TemplateContext
1719

18-
from pulp_docs.context import ctx_blog, ctx_docstrings, ctx_draft
20+
from pulp_docs.context import ctx_blog, ctx_docstrings, ctx_draft, ctx_path
1921

2022
log = get_plugin_logger(__name__)
2123

@@ -35,6 +37,42 @@ class ComponentOption(Config):
3537
rest_api = config_options.Type(str, default="")
3638

3739

40+
@dataclass(frozen=True)
41+
class Component:
42+
title: str
43+
path: str
44+
kind: str
45+
git_url: str
46+
rest_api: str
47+
48+
version: str
49+
repository_dir: Path
50+
component_dir: Path
51+
52+
@classmethod
53+
def build(cls, find_path: list[str], component_opt: ComponentOption):
54+
body = dict(component_opt)
55+
repository_name = component_opt.path.split("/")[0]
56+
for dir_spec in find_path:
57+
repo_filter, _, basedir = dir_spec.rpartition("@")
58+
if repo_filter and repo_filter != repository_name:
59+
continue
60+
basedir = Path(basedir)
61+
component_dir = basedir / component_opt.path
62+
if component_dir.exists():
63+
version = "unknown"
64+
try:
65+
pyproject = component_dir / "pyproject.toml"
66+
version = tomllib.loads(pyproject.read_text())["project"]["version"]
67+
except Exception:
68+
pass
69+
body["version"] = version
70+
body["repository_dir"] = basedir / repository_name
71+
body["component_dir"] = component_dir
72+
return cls(**body)
73+
return None
74+
75+
3876
class PulpDocsPluginConfig(Config):
3977
components = config_options.ListOfItems(ComponentOption, default=[])
4078

@@ -175,18 +213,12 @@ def _render_sitemap_item(nav_item: Page | Section) -> str:
175213

176214

177215
def component_data(
178-
component: ComponentOption,
179-
component_dir: Path,
216+
component: Component,
180217
) -> dict[str, str | list[str]]:
181218
"""Generate data for rendering md templates."""
219+
component_dir = component.component_dir
182220
path = component_dir.name
183221

184-
version = "unknown"
185-
try:
186-
pyproject = component_dir / "pyproject.toml"
187-
version = tomllib.loads(pyproject.read_text())["project"]["version"]
188-
except Exception:
189-
pass
190222
github_org = "pulp"
191223
try:
192224
template_config = component_dir / "template_config.yml"
@@ -204,7 +236,7 @@ def component_data(
204236
return {
205237
"title": f"[{component.title}](site:{path}/)",
206238
"kind": component.kind,
207-
"version": version,
239+
"version": component.version,
208240
"links": links,
209241
}
210242

@@ -225,34 +257,47 @@ def rss_items() -> list:
225257
return rss_feed["items"][:20]
226258

227259

260+
def load_components(find_path: list[str], config: MkDocsConfig, draft: bool):
261+
loaded_components = []
262+
for component_opt in config.components:
263+
component = Component.build(find_path, component_opt)
264+
if component:
265+
loaded_components.append(component)
266+
all_components = {o.path for o in config.components}
267+
not_loaded_components = all_components.difference(
268+
{o.path for o in loaded_components}
269+
)
270+
if not_loaded_components:
271+
not_loaded_components = sorted(not_loaded_components)
272+
if draft:
273+
log.warning(f"Skip missing components {not_loaded_components}.")
274+
else:
275+
raise PluginError(f"Components missing: {not_loaded_components}.")
276+
return loaded_components
277+
278+
228279
class PulpDocsPlugin(BasePlugin[PulpDocsPluginConfig]):
229280
def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
230-
# Two directories up from docs is where we expect all the other repositories.
231281
self.blog = ctx_blog.get()
232282
self.docstrings = ctx_docstrings.get()
233283
self.draft = ctx_draft.get()
234284

235285
self.pulp_docs_dir = Path(config.docs_dir).parent
236-
self.repositories_dir = self.pulp_docs_dir.parent
286+
self.find_path = ctx_path.get() or [str(self.pulp_docs_dir.parent)]
287+
288+
loaded_components = load_components(self.find_path, self.config, self.draft)
289+
self.config.components = loaded_components
290+
loaded_component_dirnames = [str(c.component_dir) for c in loaded_components]
291+
log.info(f"Using components={loaded_component_dirnames}")
237292

238293
mkdocstrings_config = config.plugins["mkdocstrings"].config
239294
components_var = []
240-
new_components = []
241295
for component in self.config.components:
242-
component_dir = self.repositories_dir / component.path
243-
if component_dir.exists():
244-
components_var.append(component_data(component, component_dir))
245-
config.watch.append(str(component_dir / "docs"))
246-
mkdocstrings_config.handlers["python"]["paths"].append(
247-
str(component_dir)
248-
)
249-
new_components.append(component)
250-
else:
251-
if self.draft:
252-
log.warning(f"Skip missing component '{component.title}'.")
253-
else:
254-
raise PluginError(f"Component '{component.title}' missing.")
255-
self.config.components = new_components
296+
components_var.append(component_data(component))
297+
config.watch.append(str(component.component_dir / "docs"))
298+
mkdocstrings_config.handlers["python"]["paths"].append(
299+
str(component.component_dir)
300+
)
256301

257302
macros_plugin = config.plugins["macros"]
258303
macros_plugin.register_macros({"rss_items": rss_items})
@@ -273,10 +318,10 @@ def on_files(self, files: Files, /, *, config: MkDocsConfig) -> Files | None:
273318
user_nav: dict[str, t.Any] = {}
274319
dev_nav: dict[str, t.Any] = {}
275320
for component in self.config.components:
276-
component_dir = self.repositories_dir / component.path
321+
component_dir = component.component_dir
277322

278323
log.info(f"Fetching docs from '{component.title}'.")
279-
git_repository_dir = self.repositories_dir / Path(component.path).parts[0]
324+
git_repository_dir = component.repository_dir
280325
try:
281326
git_branch = Repo(git_repository_dir).active_branch.name
282327
except TypeError:

0 commit comments

Comments
 (0)