Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add workflow for building the docs #511

Merged
merged 5 commits into from
Dec 8, 2023
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
63 changes: 57 additions & 6 deletions .github/workflows/test_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ env:
--ignore={project}//tests//structure//test_trajectory.py
--ignore={project}//tests//sequence//align//test_statistics.py
--ignore={project}//tests//application
--ignore={project}//tests//database
--ignore={project}//tests//database
--ignore={project}//tests//test_doctest.py
--ignore={project}//tests//test_modname.py
CIBW_DEPENDENCY_VERSIONS: "pinned"
Expand Down Expand Up @@ -90,8 +90,9 @@ jobs:

- uses: actions/upload-artifact@v3
with:
name: release
path: ./wheelhouse/*.whl


test-interfaces:
name: Test interfaces to databases and applications
Expand Down Expand Up @@ -126,7 +127,7 @@ jobs:
tests//test_modname.py
tests//database
tests//application


test-muscle5:
name: Test interface to Muscle 5
Expand Down Expand Up @@ -166,19 +167,69 @@ jobs:
run: pipx run build --sdist
- uses: actions/upload-artifact@v3
with:
path: dist/*.tar.gz
name: release
path: dist//*.tar.gz


make-docs:
name: Build documentation

runs-on: ubuntu-20.04
defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v3
- uses: conda-incubator/setup-miniconda@v2
with:
environment-file: environment.yml
miniforge-variant: Mambaforge
- name: Build distribution
run: pip wheel --no-deps -w dist .
- name: Install distribution
run: pip install .//dist//*.whl
- name: Build base documentation
run: sphinx-build -D plot_gallery=0 doc build//doc
- name: Build tutorial and gallery
if: >
(
github.event_name == 'release' &&
github.event.action == 'published'
)
|| github.event_name == 'workflow_dispatch'
run: sphinx-build doc build//doc
- name: Zip documentation
run: |
cd build
zip -r ..//dist//doc.zip doc
cd ..
- uses: actions/upload-artifact@v3
with:
name: release
path: dist//doc.zip
# Put docs also into separate artifact to allow quicker download of docs
- uses: actions/upload-artifact@v3
with:
name: documentation
path: dist//doc.zip


upload:
name: Upload to GitHub Releases & PyPI
permissions:
contents: write
needs: [test-and-build, make-sdist, test-interfaces, test-muscle5]
needs:
- test-and-build
- make-sdist
- make-docs
- test-interfaces
- test-muscle5
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: artifact
name: release
path: dist
- name: List distributions to be uploaded
run: ls dist
Expand Down
46 changes: 25 additions & 21 deletions doc/viewcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def _index_attributes(package_name, src_path):
Name of the (sub)package.
src_path : str
File path to `package_name`.

Parameters
----------
attribute_index : dict( tuple(str, str) -> (str, bool))
Expand All @@ -45,25 +45,25 @@ def _index_attributes(package_name, src_path):
# Directory is not a Python package/subpackage
# -> Nothing to do
return {}, {}

attribute_index = {}
cython_line_index = {}

# Identify all subdirectories...
directory_content = listdir(src_path)
dirs = [f for f in directory_content if isdir(join(src_path, f))]
# ... and index them recursively
# ... and index them recursively
for directory in dirs:
sub_attribute_index, sub_cython_line_index = _index_attributes(
f"{package_name}.{directory}",
join(src_path, directory),
)
attribute_index.update(sub_attribute_index)
cython_line_index.update(sub_cython_line_index)

# Import package
package = import_module(package_name)

# Import all modules in directory and index attributes
source_files = [
file_name for file_name in directory_content
Expand All @@ -77,17 +77,21 @@ def _index_attributes(package_name, src_path):
for source_file in source_files:
module_name = f"{package_name}.{splitext(source_file)[0]}"
module = import_module(module_name)


if not hasattr(module, "__all__"):
raise AttributeError(
f"Module {module_name} has not attribute '__all__'"
)
# Only index attributes from modules that are available
# via respective Biotite (sub-)package
# If a the attribute is vailable, the module was imported in the
# '__init__.py' -> Expect that all attributes from module are
# available in package
# If a the attribute is available, the module was imported in
# the '__init__.py' -> Expect that all attributes from module
# are available in package
# For example 'biotite.structure.util' is only used for internal
# purposes and is not imported in the '__init__.py'
if not all([hasattr(package, attr) for attr in module.__all__]):
continue

is_cython = source_file.endswith(".pyx")
for attribute in module.__all__:
attribute_index[(package_name, attribute)] \
Expand All @@ -97,7 +101,7 @@ def _index_attributes(package_name, src_path):
lines = cython_file.read().splitlines()
for attribute, (first, last) in _index_cython_code(lines).items():
cython_line_index[(package_name, attribute)] = (first, last)

return attribute_index, cython_line_index


Expand All @@ -113,12 +117,12 @@ def _index_cython_code(code_lines):

By the nature of this approach, methods or inner classes are not
identified.

Parameters
----------
code_lines : list of str
The *Cython* source code splitted into lines.

Returns
-------
line_index : dict (str -> tuple(int, int))
Expand All @@ -130,11 +134,11 @@ def _index_cython_code(code_lines):
for i in range(len(code_lines)):
line = code_lines[i]
stripped_line = line.strip()

# Skip empty and comment lines
if len(stripped_line) == 0 or stripped_line[0] == "#":
continue

if line.startswith(("def")):
attr_type = "def"
# Get name of the function:
Expand Down Expand Up @@ -176,14 +180,14 @@ def _index_cython_code(code_lines):
else:
# Exclusive stop -> +1
attr_line_stop = j + 1

line_index[attr_name] = (
# 'One' based indexing
attr_line_start + 1,
# 'One' based indexing and inclusive stop
attr_line_stop
)

return line_index


Expand All @@ -204,7 +208,7 @@ def _is_package(path):
def linkcode_resolve(domain, info):
if domain != "py":
return None

package_name = info["module"]
attr_name = info["fullname"]
try:
Expand All @@ -224,16 +228,16 @@ def linkcode_resolve(domain, info):
# by the Cython code analyzer
return f"https://github.com/biotite-dev/biotite/blob/master/src/" \
f"{module_name.replace('.', '/')}.pyx"

else:
module = import_module(module_name)

# Get the object defined by the attribute name,
# by traversing the 'attribute tree' to the leaf
obj = module
for attr_name_part in attr_name.split("."):
obj = getattr(obj, attr_name_part)

# Temporarily change the '__module__' attribute, which is set
# to the subpackage in Biotite, back to the actual module in
# order to fool Python's inspect module
Expand Down
Loading
Loading