From 66e1151be40fb07e03e224dc0782a83e42b3ffb7 Mon Sep 17 00:00:00 2001 From: Philip Loche Date: Tue, 21 Feb 2023 23:42:42 +0100 Subject: [PATCH 01/20] Reenable docs deploy --- .github/workflows/docs.yml | 94 +++++++++++++++++++------------------- docs/CHANGELOG.rst | 1 + pyproject.toml | 4 +- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5bf29dc..e055d2f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,59 +21,59 @@ jobs: - name: Build docs run: tox -e docs - # - name: Deploy docs - # if: github.event_name != 'pull_request' - # env: - # GH_USER: github-actions - # GH_EMAIL: "github-action@users.noreply.github.com" - # GH_REPOSITORY: "github.com/${{ github.repository }}.git" - # GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # URL: https://mdacli.mdanalysis.org + - name: Deploy docs + if: github.event_name != 'pull_request' + env: + GH_USER: github-actions + GH_EMAIL: "github-action@users.noreply.github.com" + GH_REPOSITORY: "github.com/${{ github.repository }}.git" + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + URL: https://mdacli.mdanalysis.org - # run: | - # # set up environment variables - # # export URL for the Python script $UPDATE_JSON - # export VERSION=$(grep __version__ src/mdacli/__init__.py | awk '{print $3}' | tr -d "'") - # UPDATE_JSON=$(pwd)/devtools/update_json_stubs_sitemap.py - # BRANCH="${GITHUB_REF#refs/heads/}" + run: | + # set up environment variables + # export URL for the Python script $UPDATE_JSON + export VERSION=$(grep __version__ src/mdacli/__init__.py | awk '{print $3}' | tr -d "'") + UPDATE_JSON=$(pwd)/devtools/update_json_stubs_sitemap.py + BRANCH="${GITHUB_REF#refs/heads/}" - # # the below turns off non-blocking as it causes large writes to stdout to fail - # # (see https://github.com/travis-ci/travis-ci/issues/4704) - # # commented out as this is not a problem with gh-actions - # # python -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK);' + # the below turns off non-blocking as it causes large writes to stdout to fail + # (see https://github.com/travis-ci/travis-ci/issues/4704) + # commented out as this is not a problem with gh-actions + # python -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK);' - # # go into built docs - # cd dist/docs + # go into built docs + cd dist/docs - # # move docs into version subfolder - # mkdir ../${VERSION} && mv * ../${VERSION} && mv ../${VERSION} $VERSION + # move docs into version subfolder + mkdir ../${VERSION} && mv * ../${VERSION} && mv ../${VERSION} $VERSION - # # set up git - # REV=$(git rev-parse --short HEAD) - # git init - # git config user.name $GH_USER - # git config user.email $GH_EMAIL - # git remote add upstream "https://${GH_USER}:${GH_TOKEN}@${GH_REPOSITORY}" - # git fetch --depth 50 upstream $BRANCH gh-pages - # git reset upstream/gh-pages + # set up git + REV=$(git rev-parse --short HEAD) + git init + git config user.name $GH_USER + git config user.email $GH_EMAIL + git remote add upstream "https://${GH_USER}:${GH_TOKEN}@${GH_REPOSITORY}" + git fetch --depth 50 upstream $BRANCH gh-pages + git reset upstream/gh-pages - # # redirects and copies - # mkdir latest - # python $UPDATE_JSON --version $VERSION --url $URL - # touch . - # touch .nojekyll + # redirects and copies + mkdir latest + python $UPDATE_JSON --version $VERSION --url $URL + touch . + touch .nojekyll - # # add this particular version's files - # git add -A ${VERSION}/ - # git add .nojekyll versions.json *.xml *.html index.html latest + # add this particular version's files + git add -A ${VERSION}/ + git add .nojekyll versions.json *.xml *.html index.html latest - # # add other versions, e.g. stable. If a dev branch is added, add dev too - # for dirname in stable dev ; do - # if [ -d $dirname ]; then git add $dirname; fi - # done + # add other versions, e.g. stable. If a dev branch is added, add dev too + for dirname in stable dev ; do + if [ -d $dirname ]; then git add $dirname; fi + done - # # check for anything to commit - # # https://stackoverflow.com/questions/3878624/how-do-i-programmatically-determine-if-there-are-uncommited-changes - # # then push to gh-pages for build - # git diff-index --quiet HEAD -- || git commit -m "rebuilt html docs for version ${VERSION} from branch ${BRANCH} with sphinx at ${REV}" - # git push -q upstream HEAD:gh-pages + # check for anything to commit + # https://stackoverflow.com/questions/3878624/how-do-i-programmatically-determine-if-there-are-uncommited-changes + # then push to gh-pages for build + git diff-index --quiet HEAD -- || git commit -m "rebuilt html docs for version ${VERSION} from branch ${BRANCH} with sphinx at ${REV}" + git push -q upstream HEAD:gh-pages diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 14fc14c..49619b5 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -2,6 +2,7 @@ Changelog ========= +* Reenable docs on https://mdacli.mdanalysis.org v0.1.25 (2023-02-21) ------------------------------------------ diff --git a/pyproject.toml b/pyproject.toml index c64cabc..526499b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,8 +44,8 @@ dependencies = [ ] [project.urls] -homepage = "https://github.com/MDAnalysis/mdacli" -documentation = "https://mdacli.readthedocs.io/en/latest" +homepage = "https://mdacli.mdanalysis.org" +documentation = "https://mdacli.mdanalysis.org" repository = "https://github.com/MDAnalysis/mdacli" changelog = "https://github.com/MDAnalysis/mdacli/blob/main/docs/CHANGELOG.rst" issues = "https://github.com/MDAnalysis/mdacli/issues/" From 53ab0ca028db16fa8776eb97835bd2ee5ed1f52d Mon Sep 17 00:00:00 2001 From: Philip Loche Date: Wed, 22 Feb 2023 00:22:04 +0100 Subject: [PATCH 02/20] update keywords --- pyproject.toml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 526499b..3344c3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,17 @@ authors = [ ] readme = "README.rst" requires-python = ">=3.8" -keywords = ["Science", "Molecular Dynamics", "MDAnalysis"] +keywords = [ + "python", + "cli", + "science", + "command-line", + "molecular-dynamics", + "computational-chemistry", + "molecular-dynamics-simulation", + "command-line-tool", + "trajectory-analysis mdanalysis", +] license = {text = "GPL-3.0-or-later"} classifiers = [ From 8785fcd0cdf27e2fcab06f218042d257b61cf157 Mon Sep 17 00:00:00 2001 From: Philip Loche Date: Tue, 19 Mar 2024 18:03:57 +0100 Subject: [PATCH 03/20] add level to setup_logging function --- src/mdacli/cli.py | 8 +++++++- src/mdacli/logger.py | 17 ++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/mdacli/cli.py b/src/mdacli/cli.py index 248bad6..7e55883 100644 --- a/src/mdacli/cli.py +++ b/src/mdacli/cli.py @@ -8,6 +8,7 @@ """The toplevel command line interface.""" import logging +from selectors import EpollSelector import sys import traceback import warnings @@ -113,7 +114,12 @@ def cli(name, # Ignore all warnings if not in debug mode warnings.filterwarnings("ignore") - with setup_logging(logger, logfile=args.logfile, debug=args.debug): + if args.debug: + level = logging.DEBUG + else: + level = logging.INFO + + with setup_logging(logger, logfile=args.logfile, level=level): # Execute the main client interface. try: analysis_callable = args.analysis_callable diff --git a/src/mdacli/logger.py b/src/mdacli/logger.py index b9ae2c2..0e6e48f 100644 --- a/src/mdacli/logger.py +++ b/src/mdacli/logger.py @@ -15,7 +15,7 @@ @contextlib.contextmanager -def setup_logging(logobj, logfile=None, debug=False): +def setup_logging(logobj, logfile=None, level=logging.INFO): """ Create a logging environment for a given logobj. @@ -25,19 +25,18 @@ def setup_logging(logobj, logfile=None, debug=False): A logging instance logfile : str Name of the log file - debug : bool - If ``True`` detailed debug logs inludcing filename and function name - are displayed. If ``False`` only the message logged from - errors, warnings and infos will be displayed. + level : int + Set the root logger level to the specified level. If for example set to + :py:obj:`logging.DEBUG` detailed debug logs inludcing filename and function name + are displayed. For :py:obj:`logging.INFO only the message logged from errors, + warnings and infos will be displayed. """ try: - format = '{message}' - if debug: + if level == logging.DEBUG: format = "[{levelname}] {filename}:{name}:{funcName}:{lineno}: " \ + format - level = logging.DEBUG else: - level = logging.INFO + format = "{message}" logging.basicConfig(format=format, handlers=[logging.StreamHandler(sys.stdout)], From a1a5506a6ced26100e70eca386e4a3dbb3a9c5ba Mon Sep 17 00:00:00 2001 From: Philip Loche Date: Tue, 19 Mar 2024 18:11:06 +0100 Subject: [PATCH 04/20] update tests and CHANGELOG --- docs/CHANGELOG.rst | 4 ++-- src/mdacli/cli.py | 3 +-- src/mdacli/logger.py | 16 +++++++++------- tests/test_logger.py | 8 ++++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 6248a82..7fc5357 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -2,12 +2,12 @@ Changelog ========= -* Reenable docs on https://mdacli.mdanalysis.org +* Replace Boolean ``debug`` option in ``setup_logging`` by more flexible integer + ``level`` parameter. v0.1.28 (2023-09-29) ------------------------------------------ - * Make choices style parsable (#114) v0.1.27 (2023-08-25) diff --git a/src/mdacli/cli.py b/src/mdacli/cli.py index 7e55883..8eb2aba 100644 --- a/src/mdacli/cli.py +++ b/src/mdacli/cli.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- # -# Copyright (c) 2021 Authors and contributors +# Copyright (c) 2024 Authors and contributors # # Released under the GNU Public Licence, v2 or any higher version # SPDX-License-Identifier: GPL-2.0-or-later """The toplevel command line interface.""" import logging -from selectors import EpollSelector import sys import traceback import warnings diff --git a/src/mdacli/logger.py b/src/mdacli/logger.py index 0e6e48f..7f32cde 100644 --- a/src/mdacli/logger.py +++ b/src/mdacli/logger.py @@ -15,7 +15,7 @@ @contextlib.contextmanager -def setup_logging(logobj, logfile=None, level=logging.INFO): +def setup_logging(logobj, logfile=None, level=logging.WARNING): """ Create a logging environment for a given logobj. @@ -26,15 +26,17 @@ def setup_logging(logobj, logfile=None, level=logging.INFO): logfile : str Name of the log file level : int - Set the root logger level to the specified level. If for example set to - :py:obj:`logging.DEBUG` detailed debug logs inludcing filename and function name - are displayed. For :py:obj:`logging.INFO only the message logged from errors, - warnings and infos will be displayed. + Set the root logger level to the specified level. If for example set + to :py:obj:`logging.DEBUG` detailed debug logs inludcing filename and + function name are displayed. For :py:obj:`logging.INFO only the message + logged from errors, warnings and infos will be displayed. """ try: if level == logging.DEBUG: - format = "[{levelname}] {filename}:{name}:{funcName}:{lineno}: " \ - + format + format = ( + "[{levelname}] {filename}:{name}:{funcName}:{lineno}: " + "{message}" + ) else: format = "{message}" diff --git a/tests/test_logger.py b/tests/test_logger.py index b65390d..caf1389 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- # -# Copyright (c) 2021 Authors and contributors +# Copyright (c) 2024 Authors and contributors # # Released under the GNU Public Licence, v2 or any higher version # SPDX-License-Identifier: GPL-2.0-or-later @@ -20,7 +20,7 @@ def test_default_log(self, caplog): logger = logging.getLogger("test") with mdacli.logger.setup_logging(logger, logfile=None, - debug=False): + level=logging.INFO): logger.info("foo") assert "foo" in caplog.text @@ -33,7 +33,7 @@ def test_info_log(self, tmpdir, caplog): # is created by the function. with mdacli.logger.setup_logging(logger, logfile="logfile", - debug=False): + level=logging.INFO): logger.info("foo") assert "foo" in caplog.text with open("logfile.log", "r") as f: @@ -48,7 +48,7 @@ def test_debug_log(self, tmpdir, caplog): with tmpdir.as_cwd(): with mdacli.logger.setup_logging(logger, logfile="logfile", - debug=True): + level=logging.DEBUG): logger.info("foo") assert "test:test_logger.py:52 foo\n" in caplog.text From 85c05beed1b0d6b0eff3771dd450235e31d98df1 Mon Sep 17 00:00:00 2001 From: hejamu Date: Thu, 21 Mar 2024 13:42:18 +0100 Subject: [PATCH 05/20] Fix verbose argument --- src/mdacli/cli.py | 18 ++++++++++++------ tests/test_cli.py | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/mdacli/cli.py b/src/mdacli/cli.py index 8eb2aba..d920cdf 100644 --- a/src/mdacli/cli.py +++ b/src/mdacli/cli.py @@ -103,20 +103,26 @@ def cli(name, setup_clients(ap, title=f"{name} Analysis Modules", members=modules) # Be case insensitive for the subcommand - sys.argv[1] = sys.argv[1].lower() + module_names = [mod.__name__.split(".")[-1] for mod in modules] + + for i, arg in enumerate(sys.argv[1:]): + if arg in module_names: + sys.argv[i + 1] = arg.lower() args = ap.parse_args() - if args.debug: - args.verbose = True + # Set the logging level based on the verbose argument + # If verbose is not an argument, default to WARNING + if not hasattr(args, "verbose") or not args.verbose: + level = logging.WARNING else: - # Ignore all warnings if not in debug mode - warnings.filterwarnings("ignore") + level = logging.INFO if args.debug: level = logging.DEBUG else: - level = logging.INFO + # Ignore all warnings if not in debug mode, because MDA is noisy + warnings.filterwarnings("ignore") with setup_logging(logger, logfile=args.logfile, level=level): # Execute the main client interface. diff --git a/tests/test_cli.py b/tests/test_cli.py index ae50aa8..4bf3f31 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -33,7 +33,7 @@ def test_extra_options(args): @pytest.mark.parametrize('args', ("RMSF", "rmsf")) def test_case_insensitive(args): - """Test for beeing case insensitive.""" + """Test for being case insensitive.""" subprocess.check_call(['mda', args, "-h"]) From f1558b6354abc7eb5749271c7e89546e41cca0fe Mon Sep 17 00:00:00 2001 From: hejamu Date: Thu, 21 Mar 2024 15:24:23 +0100 Subject: [PATCH 06/20] Test --- src/mdacli/cli.py | 7 ------- src/mdacli/libcli.py | 3 ++- tests/test_cli.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/mdacli/cli.py b/src/mdacli/cli.py index d920cdf..34ad039 100644 --- a/src/mdacli/cli.py +++ b/src/mdacli/cli.py @@ -102,13 +102,6 @@ def cli(name, # sub parser in complete detail. setup_clients(ap, title=f"{name} Analysis Modules", members=modules) - # Be case insensitive for the subcommand - module_names = [mod.__name__.split(".")[-1] for mod in modules] - - for i, arg in enumerate(sys.argv[1:]): - if arg in module_names: - sys.argv[i + 1] = arg.lower() - args = ap.parse_args() # Set the logging level based on the verbose argument diff --git a/src/mdacli/libcli.py b/src/mdacli/libcli.py index cb7caa6..a2b8ade 100644 --- a/src/mdacli/libcli.py +++ b/src/mdacli/libcli.py @@ -367,6 +367,7 @@ def create_cli(sub_parser, interface_name, parameters): # creates the subparser analysis_class_parser = sub_parser.add_parser( interface_name, + aliases=[interface_name.lower()], help=parameters["desc"], description=f"{parameters['desc']}\n\n{parameters['desc_long']}", formatter_class=argparse.RawDescriptionHelpFormatter, @@ -766,7 +767,7 @@ def setup_clients(ap, title, members): # to be writen for member_name, parameters in analysis_interfaces.items(): create_cli(sub_parser=cli_subparser, - interface_name=member_name.lower(), + interface_name=member_name, parameters=parameters) diff --git a/tests/test_cli.py b/tests/test_cli.py index 4bf3f31..ce019e4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -12,6 +12,11 @@ import pytest from MDAnalysisTests.datafiles import TPR, XTC +class TestLogLevel(AnalysisBase): + + def __init__(self): + self.log = logging.getLogger(__name__) + self.log.debug("TestLogLevel.__init__") def test_required_args(): """Test that there is a module given.""" @@ -42,3 +47,9 @@ def test_running_analysis(tmpdir): with tmpdir.as_cwd(): subprocess.check_call( ['mda', "rmsf", "-s", TPR, "-f", XTC, "-atomgroup", "all"]) + + +def test_verbosity_level_debug(): + """Test the debug level.""" + with pytest.raises(subprocess.CalledProcessError): + subprocess.check_call(['mda', --debug]) \ No newline at end of file From dcd544805e3bdb446f1af62ccd7f6bd7af1ca1a2 Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 27 Mar 2024 15:26:41 +0100 Subject: [PATCH 07/20] Try a tester class --- tests/run_tester | 8 ++++++++ tests/test_cli.py | 8 +------- tests/tester/__init__.py | 1 + tests/tester/__main__.py | 28 ++++++++++++++++++++++++++++ tests/tester/tester_class.py | 31 +++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100755 tests/run_tester create mode 100644 tests/tester/__init__.py create mode 100644 tests/tester/__main__.py create mode 100644 tests/tester/tester_class.py diff --git a/tests/run_tester b/tests/run_tester new file mode 100755 index 0000000..5f475e8 --- /dev/null +++ b/tests/run_tester @@ -0,0 +1,8 @@ +#!/opt/homebrew/opt/python@3.11/bin/python3.11 +# -*- coding: utf-8 -*- +import re +import sys +from tester.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index ce019e4..895f2d5 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -12,11 +12,6 @@ import pytest from MDAnalysisTests.datafiles import TPR, XTC -class TestLogLevel(AnalysisBase): - - def __init__(self): - self.log = logging.getLogger(__name__) - self.log.debug("TestLogLevel.__init__") def test_required_args(): """Test that there is a module given.""" @@ -51,5 +46,4 @@ def test_running_analysis(tmpdir): def test_verbosity_level_debug(): """Test the debug level.""" - with pytest.raises(subprocess.CalledProcessError): - subprocess.check_call(['mda', --debug]) \ No newline at end of file + subprocess.check_call(['./tests/run_tester', 'tester', "-s", TPR, "-f","-atomgroup", "all"]) \ No newline at end of file diff --git a/tests/tester/__init__.py b/tests/tester/__init__.py new file mode 100644 index 0000000..1321f92 --- /dev/null +++ b/tests/tester/__init__.py @@ -0,0 +1 @@ +from .tester_class import Tester \ No newline at end of file diff --git a/tests/tester/__main__.py b/tests/tester/__main__.py new file mode 100644 index 0000000..bb69595 --- /dev/null +++ b/tests/tester/__main__.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- +# +# Copyright (c) 2024 Authors and contributors +# (see the AUTHORS.rst file for the full list of names) +# +# Released under the GNU Public Licence, v3 or any higher version +# SPDX-License-Identifier: GPL-3.0-or-later +"""Analyse molecular dynamics simulation of interfacial and confined systems.""" + +from mdacli import cli + +from MDAnalysis.analysis.base import AnalysisBase + +def main(): + """Execute main CLI entry point.""" + cli( + name="Tester", + module_list=["tester"], + base_class=AnalysisBase, + version=0.0, + description="test", + ignore_warnings=True, + ) + + +if __name__ == "__main__": + main() diff --git a/tests/tester/tester_class.py b/tests/tester/tester_class.py new file mode 100644 index 0000000..f640c25 --- /dev/null +++ b/tests/tester/tester_class.py @@ -0,0 +1,31 @@ +from MDAnalysis.analysis.base import AnalysisBase + + +class Tester(AnalysisBase): + """Test class for mdacli. I AM STUPID + + Parameters + ---------- + bins : int + Determines the number of bins used for data averaging; (this parameter sets the + upper limit). The data are by default binned logarithmically. This helps to + reduce noise, particularly in the high-frequency domain, and also prevents plot + files from being too large. + + """ + + def __init__(self, universe, **kwargs): + """Initialise the Tester class.""" + super().__init__(universe, **kwargs) + + def _prepare(self): + """Prepare the analysis.""" + pass + + def _single_frame(self): + """Analyse a single frame.""" + pass + + def _conclude(self): + """Conclude the analysis.""" + pass From 8f6c6298c25166be4e0714556ee28911045b248d Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 27 Mar 2024 16:24:40 +0100 Subject: [PATCH 08/20] Fix tests --- tests/test_cli.py | 65 ++++++++++++++++++++++++++++++------ tests/tester/__init__.py | 2 +- tests/tester/__main__.py | 5 +-- tests/tester/tester_class.py | 32 ++++++++++++------ 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 895f2d5..45ea68c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -16,34 +16,79 @@ def test_required_args(): """Test that there is a module given.""" with pytest.raises(subprocess.CalledProcessError): - subprocess.check_call(['mda']) + subprocess.check_call(["mda"]) def test_wrong_module(): """Test for a non existent module.""" with pytest.raises(subprocess.CalledProcessError): - subprocess.check_call(['mda', 'foo']) + subprocess.check_call(["mda", "foo"]) -@pytest.mark.parametrize('args', ("version", "debug", "help")) +@pytest.mark.parametrize("args", ("version", "debug", "help")) def test_extra_options(args): """Test for a ab extra option.""" - subprocess.check_call(['mda', '--' + args]) + subprocess.check_call(["mda", "--" + args]) -@pytest.mark.parametrize('args', ("RMSF", "rmsf")) +@pytest.mark.parametrize("args", ("RMSF", "rmsf")) def test_case_insensitive(args): """Test for being case insensitive.""" - subprocess.check_call(['mda', args, "-h"]) + subprocess.check_call(["mda", args, "-h"]) def test_running_analysis(tmpdir): """Test running a complete analysis.""" with tmpdir.as_cwd(): subprocess.check_call( - ['mda', "rmsf", "-s", TPR, "-f", XTC, "-atomgroup", "all"]) + ["mda", "rmsf", "-s", TPR, "-f", XTC, "-atomgroup", "all"] + ) -def test_verbosity_level_debug(): - """Test the debug level.""" - subprocess.check_call(['./tests/run_tester', 'tester', "-s", TPR, "-f","-atomgroup", "all"]) \ No newline at end of file +def test_verbosity_level_warning(caplog): + """Test the log level warning.""" + # This should only print warning messages + output = subprocess.check_output( + ["./tests/run_tester", + "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all"], + text=True, + ) + assert "This is a warning" in output + # Cross-check that info and debug messages are not printed + assert "This is a debug message" not in output + assert "This is an info message" not in output + + +def test_verbosity_level_info(caplog): + """Test the log level info.""" + # This should only print warning and info messages + output = subprocess.check_output( + [ + "./tests/run_tester", + "tester", "-s", TPR, "-f", XTC, + "-atomgroup", "all", + "-v", + ], + text=True, + ) + assert "This is an info message" in output + assert "This is a warning" in output + # Cross-check that debug messages are not printed + assert "This is a debug message" not in output + + +def test_verbosity_level_debug(caplog): + """Test the log level debug.""" + # This should print all messages + output = subprocess.check_output( + [ + "./tests/run_tester", "--debug", + "tester", "-s", TPR, "-f", XTC, + "-atomgroup", "all", + "-v", + ], + text=True, + ) + assert "This is an info message" in output + assert "This is a warning" in output + assert "This is a debug message" in output diff --git a/tests/tester/__init__.py b/tests/tester/__init__.py index 1321f92..d0b3e4c 100644 --- a/tests/tester/__init__.py +++ b/tests/tester/__init__.py @@ -1 +1 @@ -from .tester_class import Tester \ No newline at end of file +from .tester_class import Tester # noqa \ No newline at end of file diff --git a/tests/tester/__main__.py b/tests/tester/__main__.py index bb69595..ebf1bab 100644 --- a/tests/tester/__main__.py +++ b/tests/tester/__main__.py @@ -6,11 +6,12 @@ # # Released under the GNU Public Licence, v3 or any higher version # SPDX-License-Identifier: GPL-3.0-or-later -"""Analyse molecular dynamics simulation of interfacial and confined systems.""" +"""Test module for mdacli.""" + +from MDAnalysis.analysis.base import AnalysisBase from mdacli import cli -from MDAnalysis.analysis.base import AnalysisBase def main(): """Execute main CLI entry point.""" diff --git a/tests/tester/tester_class.py b/tests/tester/tester_class.py index f640c25..18b59de 100644 --- a/tests/tester/tester_class.py +++ b/tests/tester/tester_class.py @@ -1,22 +1,34 @@ +#!/usr/bin/env python3 +# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- +# +# Copyright (c) 2024 Authors and contributors +# +# Released under the GNU Public Licence, v2 or any higher version +# SPDX-License-Identifier: GPL-2.0-or-later +"""Test module for mdacli.""" + +import logging + from MDAnalysis.analysis.base import AnalysisBase +logger = logging.getLogger(__name__) + + class Tester(AnalysisBase): - """Test class for mdacli. I AM STUPID - + """Test class for mdacli. I AM STUPID. + Parameters ---------- - bins : int - Determines the number of bins used for data averaging; (this parameter sets the - upper limit). The data are by default binned logarithmically. This helps to - reduce noise, particularly in the high-frequency domain, and also prevents plot - files from being too large. - + atomgroup : AtomGroup or Universe """ - def __init__(self, universe, **kwargs): + def __init__(self, atomgroup, **kwargs): """Initialise the Tester class.""" - super().__init__(universe, **kwargs) + super(Tester, self).__init__(atomgroup.universe.trajectory, **kwargs) + logger.info("This is an info message") + logger.warn("This is a warning") + logger.debug("This is a debug message") def _prepare(self): """Prepare the analysis.""" From ba0fd0f600e1169b0868f0911c2f06d262909fdc Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 27 Mar 2024 16:26:29 +0100 Subject: [PATCH 09/20] lint --- tests/run_tester | 3 +++ tests/tester/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/run_tester b/tests/run_tester index 5f475e8..196c556 100755 --- a/tests/run_tester +++ b/tests/run_tester @@ -2,7 +2,10 @@ # -*- coding: utf-8 -*- import re import sys + from tester.__main__ import main + + if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) \ No newline at end of file diff --git a/tests/tester/__init__.py b/tests/tester/__init__.py index d0b3e4c..190f39f 100644 --- a/tests/tester/__init__.py +++ b/tests/tester/__init__.py @@ -1 +1 @@ -from .tester_class import Tester # noqa \ No newline at end of file +from .tester_class import Tester # noqa \ No newline at end of file From 21afcb0a99ec4e96a4910c086c1f123fd5c24afc Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 27 Mar 2024 16:28:24 +0100 Subject: [PATCH 10/20] PEP8 --- tests/tester/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tester/__init__.py b/tests/tester/__init__.py index 190f39f..8b20676 100644 --- a/tests/tester/__init__.py +++ b/tests/tester/__init__.py @@ -1 +1 @@ -from .tester_class import Tester # noqa \ No newline at end of file +from .tester_class import Tester # noqa From fd4c074e0dbd5d61cb59acdfabac8c141ab58cdf Mon Sep 17 00:00:00 2001 From: hejamu Date: Thu, 28 Mar 2024 11:11:26 +0100 Subject: [PATCH 11/20] Add comments --- tests/run_tester | 9 +++++++-- tests/tester/__init__.py | 9 +++++++++ tests/tester/tester_class.py | 7 +++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/run_tester b/tests/run_tester index 196c556..e6b878a 100755 --- a/tests/run_tester +++ b/tests/run_tester @@ -1,5 +1,10 @@ -#!/opt/homebrew/opt/python@3.11/bin/python3.11 -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- +# +# Copyright (c) 2024 Authors and contributors +# +# Released under the GNU Public Licence, v2 or any higher version +# SPDX-License-Identifier: GPL-2.0-or-later import re import sys diff --git a/tests/tester/__init__.py b/tests/tester/__init__.py index 8b20676..4fd4697 100644 --- a/tests/tester/__init__.py +++ b/tests/tester/__init__.py @@ -1 +1,10 @@ +#!/usr/bin/env python3 +# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- +# +# Copyright (c) 2024 Authors and contributors +# +# Released under the GNU Public Licence, v2 or any higher version +# SPDX-License-Identifier: GPL-2.0-or-later +"""Make the tester module available to mdacli.""" + from .tester_class import Tester # noqa diff --git a/tests/tester/tester_class.py b/tests/tester/tester_class.py index 18b59de..eaa6f35 100644 --- a/tests/tester/tester_class.py +++ b/tests/tester/tester_class.py @@ -5,7 +5,7 @@ # # Released under the GNU Public Licence, v2 or any higher version # SPDX-License-Identifier: GPL-2.0-or-later -"""Test module for mdacli.""" +"""Mock module for mdacli to test logging.""" import logging @@ -16,7 +16,10 @@ class Tester(AnalysisBase): - """Test class for mdacli. I AM STUPID. + """Mock class for mdacli. Implements only the minimum requirements. + + Currently only logs messages at different levels to check the verbosity and + debug flags in the CLI. Parameters ---------- From 48a712d0f12e84ccbae47a0a4b2be48f807d6680 Mon Sep 17 00:00:00 2001 From: Henrik Stooss Date: Thu, 21 Mar 2024 16:03:35 +0100 Subject: [PATCH 12/20] Fix lowercase names (#117) --- docs/CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 2e379c1..83cb714 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -4,6 +4,7 @@ Changelog * Replace Boolean ``debug`` option in ``setup_logging`` by more flexible integer ``level`` parameter. +* Change handling of lowercase module names v0.1.29 (2024-03-21) ------------------------------------------ From 207a681a1d174884b19083b5f42dbba2bf4f256e Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Thu, 21 Mar 2024 15:04:02 +0000 Subject: [PATCH 13/20] [SKIP] version bump 0.1.28 -> 0.1.29 Fix lowercase names (#117) --- docs/CHANGELOG.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 83cb714..3400a9c 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -4,6 +4,10 @@ Changelog * Replace Boolean ``debug`` option in ``setup_logging`` by more flexible integer ``level`` parameter. + +v0.1.29 (2024-03-21) +------------------------------------------ + * Change handling of lowercase module names v0.1.29 (2024-03-21) From f37087ef567e4089444734ef94371528bce04731 Mon Sep 17 00:00:00 2001 From: hejamu Date: Thu, 28 Mar 2024 11:19:31 +0100 Subject: [PATCH 14/20] lint --- docs/CHANGELOG.rst | 5 ----- tests/run_tester | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 3400a9c..2e379c1 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -10,11 +10,6 @@ v0.1.29 (2024-03-21) * Change handling of lowercase module names -v0.1.29 (2024-03-21) ------------------------------------------- - -* Change handling of lowercase module names - v0.1.28 (2023-09-29) ------------------------------------------ diff --git a/tests/run_tester b/tests/run_tester index e6b878a..f9daade 100755 --- a/tests/run_tester +++ b/tests/run_tester @@ -13,4 +13,4 @@ from tester.__main__ import main if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From 8d3e3941527c07a5a780c4507f626a429f685ed4 Mon Sep 17 00:00:00 2001 From: hejamu Date: Tue, 2 Apr 2024 10:02:01 +0200 Subject: [PATCH 15/20] Try to get windows tests running --- tests/test_cli.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 8e37446..d1eb2e8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,6 +8,7 @@ """Test mdacli cli.""" import subprocess +import sys import pytest from MDAnalysisTests.datafiles import TPR, XTC @@ -51,12 +52,16 @@ def test_running_analysis(tmpdir): ["mda", "rmsf", "-s", TPR, "-f", XTC, "-atomgroup", "all"] ) +if sys.platform == "win32": + tester_class = ".\tests\run_tester" +else: + tester_class = "./tests/run_tester" def test_verbosity_level_warning(caplog): """Test the log level warning.""" # This should only print warning messages output = subprocess.check_output( - ["./tests/run_tester", + [tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all"], text=True, ) @@ -71,7 +76,7 @@ def test_verbosity_level_info(caplog): # This should only print warning and info messages output = subprocess.check_output( [ - "./tests/run_tester", + tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", @@ -89,7 +94,7 @@ def test_verbosity_level_debug(caplog): # This should print all messages output = subprocess.check_output( [ - "./tests/run_tester", "--debug", + tester_class, "--debug", "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", From 6fc420f295e1f6b25d17a7fdd315620a2fdca217 Mon Sep 17 00:00:00 2001 From: hejamu Date: Tue, 2 Apr 2024 10:16:07 +0200 Subject: [PATCH 16/20] Try again --- tests/test_cli.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index d1eb2e8..d178a04 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,12 +8,15 @@ """Test mdacli cli.""" import subprocess -import sys +from pathlib import Path import pytest from MDAnalysisTests.datafiles import TPR, XTC +tester_class = (Path('.').absolute() / 'tests/run_tester').as_posix() + + def test_required_args(): """Test that there is a module given.""" with pytest.raises(subprocess.CalledProcessError): @@ -52,10 +55,6 @@ def test_running_analysis(tmpdir): ["mda", "rmsf", "-s", TPR, "-f", XTC, "-atomgroup", "all"] ) -if sys.platform == "win32": - tester_class = ".\tests\run_tester" -else: - tester_class = "./tests/run_tester" def test_verbosity_level_warning(caplog): """Test the log level warning.""" From e868ae5cad58fc0af617ceae6875d8bca2ecc518 Mon Sep 17 00:00:00 2001 From: hejamu Date: Tue, 2 Apr 2024 10:20:42 +0200 Subject: [PATCH 17/20] explicitly use python interpreter --- tests/test_cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index d178a04..87f708f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -60,7 +60,7 @@ def test_verbosity_level_warning(caplog): """Test the log level warning.""" # This should only print warning messages output = subprocess.check_output( - [tester_class, + ["python3", tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all"], text=True, ) @@ -75,7 +75,7 @@ def test_verbosity_level_info(caplog): # This should only print warning and info messages output = subprocess.check_output( [ - tester_class, + "python3", tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", @@ -93,7 +93,7 @@ def test_verbosity_level_debug(caplog): # This should print all messages output = subprocess.check_output( [ - tester_class, "--debug", + "python3", tester_class, "--debug", "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", From 927990c9b5329fffc513728c9972c2fcc283fe94 Mon Sep 17 00:00:00 2001 From: hejamu Date: Tue, 2 Apr 2024 10:25:56 +0200 Subject: [PATCH 18/20] tox python interpreter --- tests/test_cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 87f708f..dba1cf1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -60,7 +60,7 @@ def test_verbosity_level_warning(caplog): """Test the log level warning.""" # This should only print warning messages output = subprocess.check_output( - ["python3", tester_class, + ["python", tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all"], text=True, ) @@ -75,7 +75,7 @@ def test_verbosity_level_info(caplog): # This should only print warning and info messages output = subprocess.check_output( [ - "python3", tester_class, + "python", tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", @@ -93,7 +93,7 @@ def test_verbosity_level_debug(caplog): # This should print all messages output = subprocess.check_output( [ - "python3", tester_class, "--debug", + "python", tester_class, "--debug", "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", From 8b8d5955ce39e24b82428a88a24a9c71130798a7 Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 3 Apr 2024 13:26:47 +0200 Subject: [PATCH 19/20] use sys.executable --- tests/test_cli.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index dba1cf1..2fa7436 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,6 +8,7 @@ """Test mdacli cli.""" import subprocess +import sys from pathlib import Path import pytest @@ -60,7 +61,7 @@ def test_verbosity_level_warning(caplog): """Test the log level warning.""" # This should only print warning messages output = subprocess.check_output( - ["python", tester_class, + [sys.executable, tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all"], text=True, ) @@ -75,7 +76,7 @@ def test_verbosity_level_info(caplog): # This should only print warning and info messages output = subprocess.check_output( [ - "python", tester_class, + sys.executable, tester_class, "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", @@ -93,7 +94,7 @@ def test_verbosity_level_debug(caplog): # This should print all messages output = subprocess.check_output( [ - "python", tester_class, "--debug", + sys.executable, tester_class, "--debug", "tester", "-s", TPR, "-f", XTC, "-atomgroup", "all", "-v", From 798b2f814778b94a00f0ab4313af6398c3229387 Mon Sep 17 00:00:00 2001 From: hejamu Date: Wed, 3 Apr 2024 15:21:58 +0200 Subject: [PATCH 20/20] Fix changelog check --- devtools/check_changelog.py | 32 +++++++++++++++++++++----------- docs/CHANGELOG.rst | 3 +-- tox.ini | 3 ++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/devtools/check_changelog.py b/devtools/check_changelog.py index 6cc79d1..bc46120 100644 --- a/devtools/check_changelog.py +++ b/devtools/check_changelog.py @@ -5,11 +5,10 @@ * additions are reported in CHANGELOG.rst """ +import os from pathlib import Path -folder = Path(__file__).resolve().parents[1] -changelog = Path('docs', 'CHANGELOG.rst') -contributing = Path('docs', 'CONTRIBUTING.rst') +import git class ChangelogError(Exception): @@ -18,13 +17,24 @@ class ChangelogError(Exception): pass -with open(Path(folder, changelog), 'r') as fin: +folder = Path(__file__).resolve().parents[1] +changelog = Path("docs", "CHANGELOG.rst") +contributing = Path("docs", "CONTRIBUTING.rst") + +repo = git.Repo(folder) + +if repo.active_branch.name == "main": + print("You are on the main branch. Nothing to check.") + exit(0) + +with open(Path(folder, changelog), "r") as fin: for line in fin: - if line.startswith('v'): + if line.startswith("v"): raise ChangelogError( - 'You have not updated the CHANGELOG file. ' - f'Please add a summary of your additions to {str(changelog)!r} ' - f'as described in {str(contributing)!r}.' - ) - elif line.startswith('*'): - break + "You have not updated the CHANGELOG file. " + f"Please add a summary of your additions to {str(changelog)!r} " + f"as described in {str(contributing)!r}." + ) + elif line.startswith("*"): + print("Changelog updated.") + exit(0) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 250bde6..8d89f0e 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -2,8 +2,7 @@ Changelog ========= -* Replace Boolean ``debug`` option in ``setup_logging`` by more flexible integer - ``level`` parameter. +* Change handling of CHANGELOG checks v0.1.30 (2024-04-03) ------------------------------------------ diff --git a/tox.ini b/tox.ini index dcc94bc..01e7e52 100644 --- a/tox.ini +++ b/tox.ini @@ -71,7 +71,6 @@ skip_install = true commands_pre = python {toxinidir}/devtools/clean_dist_check.py commands = python --version - python {toxinidir}/devtools/check_changelog.py python -m build twine check dist/*.whl twine check dist/*.tar.gz @@ -95,8 +94,10 @@ commands = usedevelop = true deps = -r{toxinidir}/devtools/docs_requirements.txt + gitpython commands = sphinx-build {posargs:-E} -b html docs/rst dist/docs + python {toxinidir}/devtools/check_changelog.py [testenv:safety] deps = safety