Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
fail-fast: false
matrix:
python-version: ['3.10', '3.11']
typedoc-version: ['0.20', '0.21']
typedoc-version: ['0.20', '0.21', '0.22']
experimental: [false]

name: Python ${{ matrix.python-version}} + typedoc ${{ matrix.typedoc-version }}
Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def tests(session: Session) -> None:


@nox.session(python=["3.10", "3.11"])
@nox.parametrize("typedoc", ["0.20", "0.21"])
@nox.parametrize("typedoc", ["0.20", "0.21", "0.22"])
def test_typedoc(session: Session, typedoc: str) -> None:
session.install("-r", "requirements_dev.txt")
session.run(
Expand Down
39 changes: 36 additions & 3 deletions sphinx_js/typedoc.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
"""Converter from TypeDoc output to IR format"""

import pathlib
import re
import subprocess
from collections.abc import Sequence
from errno import ENOENT
from functools import cache
from inspect import isclass
from json import load
from os.path import basename, join, normpath, relpath, sep, splitext
from os.path import basename, relpath, sep, splitext
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Annotated, Any, Literal, TypedDict

from pydantic import BaseModel, Field, ValidationError
from sphinx.application import Sphinx
from sphinx.errors import SphinxError

from . import ir
from .analyzer_utils import Command, is_explicitly_rooted, search_node_modules
Expand All @@ -19,6 +24,21 @@
__all__ = ["Analyzer"]


@cache
def typedoc_version_info(typedoc: str) -> tuple[tuple[int, ...], tuple[int, ...]]:
result = subprocess.run(
[typedoc, "--version"], capture_output=True, encoding="utf8"
)
lines = result.stdout.strip().splitlines()
m = re.search(r"TypeDoc ([0-9]+\.[0-9]+\.[0-9]+)", lines[0])
assert m
typedoc_version = tuple(int(x) for x in m.group(1).split("."))
m = re.search(r"TypeScript ([0-9]+\.[0-9]+\.[0-9]+)", lines[1])
assert m
typescript_version = tuple(int(x) for x in m.group(1).split("."))
return typedoc_version, typescript_version


def typedoc_output(
abs_source_paths: list[str], sphinx_conf_dir: str | pathlib.Path, config_path: str
) -> "Project":
Expand All @@ -28,11 +48,24 @@ def typedoc_output(
command = Command("node")
command.add(typedoc)
if config_path:
command.add("--tsconfig", normpath(join(sphinx_conf_dir, config_path)))
tsconfig_path = str((Path(sphinx_conf_dir) / config_path).absolute())
command.add("--tsconfig", tsconfig_path)
typedoc_version, _ = typedoc_version_info(typedoc)
if typedoc_version >= (0, 22, 0):
command.add("--entryPointStrategy", "expand")

with NamedTemporaryFile(mode="w+b") as temp:
command.add("--json", temp.name, *abs_source_paths)
subprocess.call(command.make())
try:
subprocess.run(command.make())
except OSError as exc:
if exc.errno == ENOENT:
raise SphinxError(
'%s was not found. Install it using "npm install -g typedoc".'
% command.program
)
else:
raise
# typedoc emits a valid JSON file even if it finds no TS files in the dir:
return parse(load(temp))

Expand Down