From df895484153d110db0157629947c713028663185 Mon Sep 17 00:00:00 2001
From: Daniel <d.hornung@indiscale.com>
Date: Wed, 7 Aug 2024 11:12:47 +0200
Subject: [PATCH] MAINT, DOC: More documentation, type hints and linting.

---
 src/caosadvancedtools/loadFiles.py | 50 +++++++++++++++++-------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/src/caosadvancedtools/loadFiles.py b/src/caosadvancedtools/loadFiles.py
index 1c7d7bf9..eb40f5c6 100755
--- a/src/caosadvancedtools/loadFiles.py
+++ b/src/caosadvancedtools/loadFiles.py
@@ -23,6 +23,16 @@
 # ** end header
 #
 
+"""Utilities to make the LinkAhead server aware of files.
+
+Installation of `caosadvancedtools` also creates an executable script ``linkahead-loadfiles`` which
+calls the `loadpath` function.  Get the full help with ``linkahead-loadfiles --help``.  In short,
+that script tells the LinkAhead server to create `FILE` entities for existing files in one branch of
+the directory tree.  It is necessary that this directory is already visible for the server (for
+example because it is defined as ``extroot`` in the LinkAhead profile).
+
+"""
+
 import argparse
 import logging
 import os
@@ -31,30 +41,30 @@ import sys
 import re
 from argparse import ArgumentParser
 from tempfile import NamedTemporaryFile
+from typing import Union
 
-import shutil
 import caosdb as db
 
 logger = logging.getLogger(__name__)
 timeout_fallback = 20
 
 
-def convert_size(size):
-    """Convert `size` from B to a human-readable file size in KB,
+def convert_size(size: int):
+    """Convert `size` from bytes to a human-readable file size in KB,
     MB, ...
 
     """
     if (size == 0):
         return '0B'
     size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
-    i = int(math.floor(math.log(size, 1000)))
-    p = math.pow(1000, i)
+    index = int(math.floor(math.log(size, 1000)))
+    p = math.pow(1000, index)
     s = round(size / p, 2)
 
-    return '%s %s' % (s, size_name[i])
+    return f"{s} {size_name[index]}"
 
 
-def combine_ignore_files(caosdbignore, localignore, dirname=None):
+def combine_ignore_files(caosdbignore: str, localignore: str, dirname=None) -> str:
     """Append the contents of localignore to caosdbignore, save the result,
     and return the name.
 
@@ -86,7 +96,7 @@ def combine_ignore_files(caosdbignore, localignore, dirname=None):
     return tmp.name
 
 
-def compile_file_list(caosdbignore, localpath):
+def compile_file_list(caosdbignore: str, localpath: str) -> list[str]:
     """Create a list of files that contain all files under localpath except
     those excluded by caosdbignore.
 
@@ -109,11 +119,11 @@ def compile_file_list(caosdbignore, localpath):
     matches = parse_gitignore(caosdbignore)
     current_ignore = caosdbignore
     non_ignored_files = []
-    ignore_files = []
+    ignore_files: list[tuple[str, str]] = []
     for root, dirs, files in os.walk(localpath):
         # remove local ignore files that do no longer apply to the current subtree (branch switch)
         while len(ignore_files) > 0 and not root.startswith(ignore_files[-1][0]):
-            shutil.os.remove(ignore_files[-1][1])
+            os.remove(ignore_files[-1][1])
             ignore_files.pop()
 
         # use the global one if there are no more local ones
@@ -143,10 +153,10 @@ def compile_file_list(caosdbignore, localpath):
     return non_ignored_files
 
 
-def create_re_for_file_list(files, localroot, remoteroot):
+def create_re_for_file_list(files: list[str], localroot: str, remoteroot: str) -> str:
     """Create a regular expression that matches file paths contained
-    in the files argument and all parent directories. The prefix
-    localroot is replaced by the prefix remoteroot.
+    in the `files` argument and all parent directories. The prefix
+    `localroot is replaced by the prefix `remoteroot`.
 
     Parameters
     ----------
@@ -179,10 +189,10 @@ def create_re_for_file_list(files, localroot, remoteroot):
     return "^("+regexp[1:]+")$"
 
 
-def loadpath(path, include, exclude, prefix, dryrun, forceAllowSymlinks, caosdbignore=None,
-             localpath=None):
-    """Make all files in `path` available to the LinkAhead server as
-    FILE entities.
+def loadpath(path: str, include: Union[str, None], exclude: Union[str, None], prefix: str,
+             dryrun: bool, forceAllowSymlinks: bool, caosdbignore: Union[str, None] = None,
+             localpath: Union[str, None] = None):
+    """Make all files in `path` available to the LinkAhead server as FILE entities.
 
     Notes
     -----
@@ -216,10 +226,8 @@ def loadpath(path, include, exclude, prefix, dryrun, forceAllowSymlinks, caosdbi
         since the check is done locally. If this is given, any
         `include` is ignored.
     localpath : str, optional
-        Path of `path` on the local machine. Only needed in the
-        combination with a `caosdbignore` file since it is processed
-        locally.
-
+        Path of `path` on the local machine. Only needed in combination with a
+        ``caosdbignore`` file since that is processed locally.
     """
 
     if caosdbignore:
-- 
GitLab