docwright 0.1.4__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {docwright-0.1.4 → docwright-0.1.6}/PKG-INFO +1 -1
- {docwright-0.1.4 → docwright-0.1.6}/docwright/cli.py +87 -1
- {docwright-0.1.4 → docwright-0.1.6}/docwright/config.py +3 -1
- {docwright-0.1.4 → docwright-0.1.6}/docwright/engine.py +1 -1
- docwright-0.1.6/docwright/outputs/factory.py +24 -0
- docwright-0.1.6/docwright/outputs/gitlab_wiki.py +36 -0
- {docwright-0.1.4 → docwright-0.1.6}/pyproject.toml +1 -1
- docwright-0.1.4/docwright/outputs/factory.py +0 -12
- {docwright-0.1.4 → docwright-0.1.6}/LICENSE +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/README.md +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/analyzer.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/readme/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/readme/default.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/adr.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/api-contracts.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/architecture.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/data-model.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/db-schema.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/development-guide.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/home.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/integrations.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/operations.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/security.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/troubleshooting.md.j2 +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/outputs/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/outputs/base.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/outputs/direct.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/outputs/pull_request.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/base.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/claude.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/factory.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/ollama.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/providers/openai.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/registry.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/renderer.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/reporters/__init__.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/reporters/html.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/reporters/terminal.py +0 -0
- {docwright-0.1.4 → docwright-0.1.6}/docwright/scaffolder.py +0 -0
|
@@ -29,10 +29,96 @@ def cli() -> None:
|
|
|
29
29
|
"""AI-powered documentation agent."""
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
def run_interactive_setup(repo_root: Path) -> None:
|
|
33
|
+
"""Run interactive setup wizard and write .ai-docgen/ai-docgen.yml."""
|
|
34
|
+
provider = click.prompt(
|
|
35
|
+
"AI Provider",
|
|
36
|
+
type=click.Choice(["claude", "openai", "ollama"]),
|
|
37
|
+
default="openai",
|
|
38
|
+
show_choices=True,
|
|
39
|
+
)
|
|
40
|
+
model_defaults = {"claude": "claude-opus-4-5", "openai": "gpt-4o", "ollama": "llama3"}
|
|
41
|
+
model = click.prompt("Model", default=model_defaults.get(provider, "gpt-4o"))
|
|
42
|
+
api_key_env_defaults = {
|
|
43
|
+
"claude": "ANTHROPIC_API_KEY",
|
|
44
|
+
"openai": "OPENAI_API_KEY",
|
|
45
|
+
"ollama": "",
|
|
46
|
+
}
|
|
47
|
+
api_key_env = click.prompt(
|
|
48
|
+
"API key environment variable",
|
|
49
|
+
default=api_key_env_defaults.get(provider, "OPENAI_API_KEY"),
|
|
50
|
+
)
|
|
51
|
+
language = click.prompt(
|
|
52
|
+
"Language",
|
|
53
|
+
type=click.Choice(["en", "ru"]),
|
|
54
|
+
default="en",
|
|
55
|
+
show_choices=True,
|
|
56
|
+
)
|
|
57
|
+
output_mode = click.prompt(
|
|
58
|
+
"Output mode",
|
|
59
|
+
type=click.Choice(["direct", "pull_request", "gitlab_wiki"]),
|
|
60
|
+
default="direct",
|
|
61
|
+
show_choices=True,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
wiki_url: str | None = None
|
|
65
|
+
token_env: str | None = None
|
|
66
|
+
if output_mode == "gitlab_wiki":
|
|
67
|
+
wiki_url = click.prompt("GitLab Wiki URL")
|
|
68
|
+
token_env = click.prompt("GitLab token env variable", default="CI_JOB_TOKEN")
|
|
69
|
+
|
|
70
|
+
config_dir = repo_root / ".ai-docgen"
|
|
71
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
72
|
+
config_path = config_dir / "ai-docgen.yml"
|
|
73
|
+
|
|
74
|
+
output_section: dict[str, object] = {"mode": output_mode}
|
|
75
|
+
if wiki_url:
|
|
76
|
+
output_section["wiki_url"] = wiki_url
|
|
77
|
+
if token_env:
|
|
78
|
+
output_section["token_env"] = token_env
|
|
79
|
+
|
|
80
|
+
config_data: dict[str, object] = {
|
|
81
|
+
"provider": {
|
|
82
|
+
"type": provider,
|
|
83
|
+
"model": model,
|
|
84
|
+
"api_key_env": api_key_env,
|
|
85
|
+
},
|
|
86
|
+
"output": output_section,
|
|
87
|
+
"language": language,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
import yaml
|
|
91
|
+
|
|
92
|
+
config_path.write_text(yaml.dump(config_data, default_flow_style=False, allow_unicode=True))
|
|
93
|
+
|
|
94
|
+
click.echo(f"\n✓ Config saved to {config_path.relative_to(repo_root)}\n")
|
|
95
|
+
click.echo("Set these environment variables before running:")
|
|
96
|
+
if api_key_env:
|
|
97
|
+
click.echo(f" export {api_key_env}=... # AI provider key")
|
|
98
|
+
if output_mode == "gitlab_wiki" and token_env:
|
|
99
|
+
click.echo(f" export {token_env}=... # GitLab token (if gitlab_wiki mode)")
|
|
100
|
+
click.echo("\nIn GitLab CI — add them to:")
|
|
101
|
+
click.echo(" Group → Settings → CI/CD → Variables")
|
|
102
|
+
click.echo(" (CI_JOB_TOKEN is provided automatically for GitLab token)")
|
|
103
|
+
else:
|
|
104
|
+
click.echo(
|
|
105
|
+
f"\n export {api_key_env or 'OPENAI_API_KEY'}=... # platform.openai.com → API Keys"
|
|
106
|
+
)
|
|
107
|
+
click.echo("\nIn GitLab CI — add to Group → Settings → CI/CD → Variables")
|
|
108
|
+
|
|
109
|
+
click.echo("\nProceeding with initialization...")
|
|
110
|
+
|
|
111
|
+
|
|
32
112
|
@cli.command()
|
|
33
113
|
def init() -> None:
|
|
34
114
|
"""Generate documentation from scratch."""
|
|
35
|
-
|
|
115
|
+
repo_root = get_repo_root()
|
|
116
|
+
from docwright.config import CONFIG_DIR, CONFIG_FILE
|
|
117
|
+
|
|
118
|
+
config_exists = (repo_root / CONFIG_DIR / CONFIG_FILE).exists()
|
|
119
|
+
if not config_exists:
|
|
120
|
+
run_interactive_setup(repo_root)
|
|
121
|
+
engine = build_engine(repo_root)
|
|
36
122
|
asyncio.run(engine.init())
|
|
37
123
|
click.echo("Documentation initialized.")
|
|
38
124
|
|
|
@@ -19,9 +19,11 @@ class ProviderConfig(BaseModel):
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class OutputConfig(BaseModel):
|
|
22
|
-
mode:
|
|
22
|
+
mode: str = "direct"
|
|
23
23
|
pr_title: str = "docs: auto-update documentation"
|
|
24
24
|
branch_prefix: str = "docs/auto-"
|
|
25
|
+
wiki_url: str | None = None
|
|
26
|
+
token_env: str | None = None
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class TemplatesConfig(BaseModel):
|
|
@@ -72,7 +72,7 @@ class DocsEngine:
|
|
|
72
72
|
for doc_config in self.config.documents:
|
|
73
73
|
target = self.repo_root / doc_config.target
|
|
74
74
|
template_text = self.loader.load(doc_config.template)
|
|
75
|
-
document =
|
|
75
|
+
document = template_text
|
|
76
76
|
section_names = self.renderer.auto_section_names(template_text)
|
|
77
77
|
|
|
78
78
|
for section_name in section_names:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from docwright.config import OutputConfig
|
|
7
|
+
from docwright.outputs.base import Output
|
|
8
|
+
from docwright.outputs.direct import DirectOutput
|
|
9
|
+
from docwright.outputs.pull_request import PullRequestOutput
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def build_output(config: OutputConfig, repo_root: Path) -> Output:
|
|
13
|
+
if config.mode == "direct":
|
|
14
|
+
return DirectOutput(repo_root=repo_root)
|
|
15
|
+
elif config.mode == "gitlab_wiki":
|
|
16
|
+
token = os.getenv(config.token_env or "CI_JOB_TOKEN", "")
|
|
17
|
+
if not token:
|
|
18
|
+
raise OSError("GitLab token not found. Set CI_JOB_TOKEN or configure token_env.")
|
|
19
|
+
if not config.wiki_url:
|
|
20
|
+
raise ValueError("output.wiki_url is required for gitlab_wiki mode.")
|
|
21
|
+
from docwright.outputs.gitlab_wiki import GitLabWikiOutput
|
|
22
|
+
|
|
23
|
+
return GitLabWikiOutput(wiki_url=config.wiki_url, token=token, repo_root=repo_root)
|
|
24
|
+
return PullRequestOutput(repo_root=repo_root, config=config)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import tempfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from urllib.parse import urlparse, urlunparse
|
|
7
|
+
|
|
8
|
+
from git import Repo
|
|
9
|
+
|
|
10
|
+
from docwright.outputs.base import Output
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GitLabWikiOutput(Output):
|
|
14
|
+
def __init__(self, wiki_url: str, token: str, repo_root: Path) -> None:
|
|
15
|
+
self.wiki_url = wiki_url
|
|
16
|
+
self.token = token
|
|
17
|
+
self.repo_root = repo_root
|
|
18
|
+
|
|
19
|
+
def build_auth_url(self) -> str:
|
|
20
|
+
parsed = urlparse(self.wiki_url)
|
|
21
|
+
auth_netloc = f"oauth2:{self.token}@{parsed.netloc}"
|
|
22
|
+
return urlunparse(parsed._replace(netloc=auth_netloc))
|
|
23
|
+
|
|
24
|
+
def apply(self, changed_files: list[Path], message: str) -> None:
|
|
25
|
+
auth_url = self.build_auth_url()
|
|
26
|
+
tmp_dir = tempfile.mkdtemp()
|
|
27
|
+
try:
|
|
28
|
+
repo = Repo.clone_from(auth_url, tmp_dir)
|
|
29
|
+
for file in changed_files:
|
|
30
|
+
dest = Path(tmp_dir) / file.name
|
|
31
|
+
dest.write_bytes(file.read_bytes())
|
|
32
|
+
repo.index.add("*")
|
|
33
|
+
repo.index.commit(message)
|
|
34
|
+
repo.remotes.origin.push()
|
|
35
|
+
finally:
|
|
36
|
+
shutil.rmtree(tmp_dir, ignore_errors=True)
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from docwright.config import OutputConfig
|
|
4
|
-
from docwright.outputs.base import Output
|
|
5
|
-
from docwright.outputs.direct import DirectOutput
|
|
6
|
-
from docwright.outputs.pull_request import PullRequestOutput
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def build_output(config: OutputConfig, repo_root: Path) -> Output:
|
|
10
|
-
if config.mode == "direct":
|
|
11
|
-
return DirectOutput(repo_root=repo_root)
|
|
12
|
-
return PullRequestOutput(repo_root=repo_root, config=config)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{docwright-0.1.4 → docwright-0.1.6}/docwright/built_in_templates/wiki/development-guide.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|