Skip to content

Commit

Permalink
Add "autodocs", code documentation generated from docstrings
Browse files Browse the repository at this point in the history
Adding a new section into "Contribute" page, "Code documentation", and
besides the actual code documenation, I propose moving "Classes" page
there as well.
  • Loading branch information
happz committed May 26, 2023
1 parent 5e70c85 commit 48c4d3f
Show file tree
Hide file tree
Showing 19 changed files with 116 additions and 59 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# tmt-specific

/tmp/
docs/autodocs/*.rst
docs/_build
docs/spec
docs/stories
Expand Down
7 changes: 6 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext autodocs

help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " autodocs to refresh autodocs generated files"

clean:
rm -rf $(BUILDDIR)/*

autodocs:
rm -f autodocs/*.rst
pushd ../ && sphinx-apidoc --force --implicit-namespaces --no-toc -o docs/autodocs tmt && popd

html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
Expand Down
Empty file added docs/autodocs/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions docs/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -424,5 +424,6 @@ Essential Classes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: tmt
:noindex:
:members:
:undoc-members:
9 changes: 9 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autodoc.typehints',
'sphinx_rtd_theme',
]

Expand Down Expand Up @@ -126,6 +127,14 @@
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

# Autodocs & type hints
autodoc_default_flags = ['members', 'undoc-members', 'show-inheritance', 'private-members']
autoclass_content = "both"

autodoc_typehints_format = 'short'
autodoc_typehints_description_target = 'all'
# This one works, but it's a bit uglier than the default value (`signature`).
# autodoc_typehints = 'description'

# -- Options for HTML output ----------------------------------------------

Expand Down
10 changes: 10 additions & 0 deletions docs/contribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,13 @@ __ https://bodhi.fedoraproject.org/releases/
__ https://github.com/teemtee/tmt/releases/
__ https://pypi.org/project/tmt/
__ https://copr.fedorainfracloud.org/coprs/psss/tmt/builds/


Code documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. toctree::
:maxdepth: 1

Overview of important and interesting classes <classes>
Documentation generated from sources <autodocs/tmt.rst>
1 change: 0 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ Table of Contents
Stories <stories>
Questions <questions>
Contribute <contribute>
Classes <classes>
Plugins <plugins>
2 changes: 1 addition & 1 deletion tmt/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ def __init__(
"""
Create a ``Logger`` instance with given verbosity levels.
:param actual_logger: a :py:class:`logging.Logger` instance, the _raw logger_
:param actual_logger: a :py:class:`logging.Logger` instance, the raw logger
to use for logging.
:param base_shift: shift applied to all messages processed by this logger.
:param labels_padding: if set, rendered labels would be padded to this
Expand Down
12 changes: 6 additions & 6 deletions tmt/queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
if TYPE_CHECKING:
from typing_extensions import Self

from tmt.steps.provision import Guest
import tmt.steps.provision


TaskT = TypeVar('TaskT', bound='_Task')
Expand All @@ -25,15 +25,15 @@ class TaskOutcome(Generic[TaskT]):
executed, where and what was the result.
"""

#: A :py:`_Task` instace the outcome relates to.
#: A :py:class:`_Task` instace the outcome relates to.
task: TaskT

#: A logger to use for logging events related to the outcome.
logger: Logger

#: Guest on which the phase was executed. May be unset, some tasks
#: may handle multiguest actions on their own.
guest: Optional['Guest']
guest: Optional['tmt.steps.provision.Guest']

#: If set, an exception was raised by the running task, and the exception
#: is saved in this field.
Expand All @@ -45,7 +45,7 @@ class _Task:
""" A base class for tasks to be executed on one or more guests """

#: A list of guests to execute the task on.
guests: List['Guest']
guests: List['tmt.steps.provision.Guest']

#: A logger to use for logging events related to the task. It serves as
#: a root logger for new loggers queue may spawn for each guest.
Expand Down Expand Up @@ -115,7 +115,7 @@ def go(self) -> Generator[TaskOutcome['Self'], None, None]:
class Task(_Task):
""" A task that should run on multiple guests at the same time """

def run_on_guest(self, guest: 'Guest', logger: Logger) -> None:
def run_on_guest(self, guest: 'tmt.steps.provision.Guest', logger: Logger) -> None:
raise NotImplementedError

def prepare_loggers(
Expand Down Expand Up @@ -157,7 +157,7 @@ def go(self) -> Generator[TaskOutcome['Self'], None, None]:
old_loggers: Dict[str, Logger] = {}

with ThreadPoolExecutor(max_workers=len(self.guests)) as executor:
futures: Dict[Future[None], Guest] = {}
futures: Dict[Future[None], 'tmt.steps.provision.Guest'] = {}

for guest in self.guests:
# Swap guest's logger for the one we prepared, with labels
Expand Down
23 changes: 11 additions & 12 deletions tmt/steps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
import tmt.cli
import tmt.steps.discover
import tmt.steps.execute
from tmt.base import Plan
from tmt.steps.provision import Guest
import tmt.steps.provision


DEFAULT_PLUGIN_METHOD_ORDER: int = 50
Expand All @@ -59,7 +58,7 @@ def __init__(
super().__init__(**kwargs)
self.order: int = order

def enabled_on_guest(self, guest: 'Guest') -> bool:
def enabled_on_guest(self, guest: 'tmt.steps.provision.Guest') -> bool:
""" Phases are enabled across all guests by default """
return True

Expand Down Expand Up @@ -215,7 +214,7 @@ class Step(tmt.utils.Common):
def __init__(
self,
*,
plan: 'Plan',
plan: 'tmt.base.Plan',
data: Optional[RawStepDataArgument] = None,
name: Optional[str] = None,
workdir: tmt.utils.WorkdirArgumentType = None,
Expand All @@ -226,7 +225,7 @@ def __init__(
super().__init__(name=name, parent=plan, workdir=workdir, logger=logger)

# Initialize data
self.plan: 'Plan' = plan
self.plan: 'tmt.base.Plan' = plan
self._status: Optional[str] = None
self._phases: List[Phase] = []

Expand Down Expand Up @@ -925,7 +924,7 @@ def _emit_key(key: str) -> None:
for key in keys:
_emit_key(key)

def enabled_on_guest(self, guest: 'Guest') -> bool:
def enabled_on_guest(self, guest: 'tmt.steps.provision.Guest') -> bool:
""" Check if the plugin is enabled on the specific guest """

# FIXME: cast() - typeless "dispatcher" method
Expand Down Expand Up @@ -1054,7 +1053,7 @@ class Plugin(BasePlugin):
def go(
self,
*,
guest: 'Guest',
guest: 'tmt.steps.provision.Guest',
environment: Optional[tmt.utils.EnvironmentType] = None,
logger: tmt.log.Logger) -> None:
""" Perform actions shared among plugins when beginning their tasks """
Expand Down Expand Up @@ -1380,7 +1379,7 @@ def prepare_environment(self) -> EnvironmentType:

def prepare_guest_environment(
self,
guest: 'Guest') -> EnvironmentType:
guest: 'tmt.steps.provision.Guest') -> EnvironmentType:
"""
Prepare environment variables related to phase and a particular guest.
"""
Expand All @@ -1397,7 +1396,7 @@ def run(self, logger: tmt.log.Logger) -> None:

self.phase.go()

def run_on_guest(self, guest: 'Guest', logger: tmt.log.Logger) -> None:
def run_on_guest(self, guest: 'tmt.steps.provision.Guest', logger: tmt.log.Logger) -> None:
assert isinstance(self.phase, Plugin) # narrow type

self.phase.go(
Expand All @@ -1421,7 +1420,7 @@ def enqueue(
self,
*,
phase: Union[Action, Plugin],
guests: List['Guest']) -> None:
guests: List['tmt.steps.provision.Guest']) -> None:
"""
Add a phase to queue.
Expand Down Expand Up @@ -1450,7 +1449,7 @@ class PushTask(Task):
def name(self) -> str:
return 'push'

def run_on_guest(self, guest: 'Guest', logger: tmt.log.Logger) -> None:
def run_on_guest(self, guest: 'tmt.steps.provision.Guest', logger: tmt.log.Logger) -> None:
guest.push()


Expand All @@ -1464,7 +1463,7 @@ class PullTask(Task):
def name(self) -> str:
return 'pull'

def run_on_guest(self, guest: 'Guest', logger: tmt.log.Logger) -> None:
def run_on_guest(self, guest: 'tmt.steps.provision.Guest', logger: tmt.log.Logger) -> None:
guest.pull(source=self.source)


Expand Down
8 changes: 4 additions & 4 deletions tmt/steps/discover/fmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ class DiscoverFmf(tmt.steps.discover.DiscoverPlugin):
Related config options (all optional):
* dist-git-merge - set to True if you want to copy in extracted
sources to the local repo
sources to the local repo
* dist-git-init - set to True and 'fmf init' will be called inside
extracted sources (at dist-git-extract or top directory)
extracted sources (at dist-git-extract or top directory)
* dist-git-extract - directory (glob supported) to copy from
extracted sources (defaults to inner fmf-root)
extracted sources (defaults to inner fmf-root)
* dist-git-remove-fmf-root - set to True to remove fmf root from
extracted sources
extracted sources
Selecting tests containing specified link is possible using 'link'
option accepting RELATION:TARGET format of values. Regular
Expand Down
52 changes: 29 additions & 23 deletions tmt/steps/discover/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,39 +191,45 @@ class DiscoverShell(tmt.steps.discover.DiscoverPlugin):
in the plan as a list of dictionaries containing test name, actual
test script and optionally a path to the test. Example config:
discover:
how: shell
tests:
- name: /help/main
test: tmt --help
- name: /help/test
test: tmt test --help
- name: /help/smoke
test: ./smoke.sh
path: /tests/shell
.. code-block:: yaml
discover:
how: shell
tests:
- name: /help/main
test: tmt --help
- name: /help/test
test: tmt test --help
- name: /help/smoke
test: ./smoke.sh
path: /tests/shell
For DistGit repo one can extract source tarball and use its code.
It is extracted to TMT_SOURCE_DIR however no patches are applied
(only source tarball is extracted).
discover:
how: shell
dist-git-source: true
tests:
- name: /upstream
test: cd $TMT_SOURCE_DIR/*/tests && make test
.. code-block:: yaml
discover:
how: shell
dist-git-source: true
tests:
- name: /upstream
test: cd $TMT_SOURCE_DIR/*/tests && make test
To clone a remote repository and use it as a source specify `url`.
It accepts also `ref` to checkout provided reference. Dynamic
reference feature is supported as well.
discover:
how: shell
url: https://github.com/teemtee/tmt.git
ref: "1.18.0"
tests:
- name: first test
test: ./script-from-the-repo.sh
.. code-block:: yaml
discover:
how: shell
url: https://github.com/teemtee/tmt.git
ref: "1.18.0"
tests:
- name: first test
test: ./script-from-the-repo.sh
"""

_data_class = DiscoverShellData
Expand Down
4 changes: 4 additions & 0 deletions tmt/steps/finish/ansible.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ class FinishAnsible(tmt.steps.finish.FinishPlugin, PrepareAnsible):
Single playbook config:
.. code-block:: yaml
finish:
how: ansible
playbook: ansible/packages.yml
Multiple playbooks config:
.. code-block:: yaml
finish:
how: ansible
playbook:
Expand Down
12 changes: 7 additions & 5 deletions tmt/steps/finish/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ class FinishShell(tmt.steps.finish.FinishPlugin):
Example config:
finish:
how: shell
script:
- upload-logs.sh || true
- rm -rf /tmp/temporary-files
.. code-block:: yaml
finish:
how: shell
script:
- upload-logs.sh || true
- rm -rf /tmp/temporary-files
Use the 'order' attribute to select in which order finishing tasks
should happen if there are multiple configs. Default order is '50'.
Expand Down
3 changes: 1 addition & 2 deletions tmt/steps/prepare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
if TYPE_CHECKING:
import tmt.base
import tmt.cli
from tmt.base import Plan


@dataclasses.dataclass
Expand Down Expand Up @@ -105,7 +104,7 @@ class Prepare(tmt.steps.Step):
def __init__(
self,
*,
plan: 'Plan',
plan: 'tmt.base.Plan',
data: tmt.steps.RawStepDataArgument,
logger: tmt.log.Logger) -> None:
""" Initialize prepare step data """
Expand Down

0 comments on commit 48c4d3f

Please sign in to comment.