From 31a0e67779df70141ef8a5238bf2374809dbaffc Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 1 Jul 2025 16:37:24 -0400 Subject: [PATCH 01/15] pre-commit: line length fix --- src/diffpy/cmi/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diffpy/cmi/__init__.py b/src/diffpy/cmi/__init__.py index 073d76e..18047b8 100644 --- a/src/diffpy/cmi/__init__.py +++ b/src/diffpy/cmi/__init__.py @@ -12,7 +12,8 @@ # See LICENSE.rst for license information. # ############################################################################## -"""Complex modeling infrastructure: a modulare framework for multi-modal modeling of scientific data.""" +"""Complex modeling infrastructure: +a modulare framework for multi-modal modeling of scientific data.""" # package version from diffpy.cmi.version import __version__ # noqa From ce68bce3d474a919742827293dd687b0c21ee45a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 1 Jul 2025 16:38:11 -0400 Subject: [PATCH 02/15] feat: CLI in pyproject.toml --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 00e749b..7e6df7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,9 @@ include = ["*"] # package names should match these glob patterns (["*"] by defa exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[project.scripts] +diffpy-cmi = "diffpy.cmi.app:main" + [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} From 8c8a09f58b7b0650c1d4a943d4289473897d1042 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 1 Jul 2025 16:39:35 -0400 Subject: [PATCH 03/15] feat: add app file for CLI --- src/diffpy/cmi/app.py | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/diffpy/cmi/app.py diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py new file mode 100644 index 0000000..d3e9277 --- /dev/null +++ b/src/diffpy/cmi/app.py @@ -0,0 +1,53 @@ +import getopt +import sys + + +def usage(): + """Print short help message.""" + print( + """\ + +DiffPy-CMI is our complex modeling framework. It is a highly flexible library +of Python modules for robust modeling of nanostructures in crystals, +nanomaterials, and amorphous materials. + +Docs: https://www.diffpy.org/diffpy.cmi + +Usage: + diffpy-cmi [--version] [--help] + +Options: + -V, --version Show version and exit + -h, --help Show this message and exit +""" + ) + + +def version(): + from diffpy.cmi.version import __version__ + + print(f"diffpy-cmi {__version__}") + + +def main(): + try: + opts, args = getopt.gnu_getopt(sys.argv[1:], "hV", ["help", "version"]) + except getopt.GetoptError as err: + print(f"Error: {err}", file=sys.stderr) + usage() + sys.exit(1) + + for opt, _ in opts: + if opt in ("-h", "--help"): + usage() + return + elif opt in ("-V", "--version"): + version() + return + + # Default behavior (if no arguments) + usage() + + +if __name__ == "__main__": + main() From 540769bf494b1bd38be6d31183ab5fbe2e2c1dbb Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 1 Jul 2025 16:41:41 -0400 Subject: [PATCH 04/15] chore: news --- news/app-creation.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/app-creation.rst diff --git a/news/app-creation.rst b/news/app-creation.rst new file mode 100644 index 0000000..04b806a --- /dev/null +++ b/news/app-creation.rst @@ -0,0 +1,23 @@ +**Added:** + +* Add CLI to return diffpy.cmi version and help page. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 2cd8244aef7a2cdc3383fe49b4cff9d3b5a4ed4c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 12:33:40 -0400 Subject: [PATCH 05/15] chore: move import to the top and edit description --- src/diffpy/cmi/app.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index d3e9277..eeb4c43 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -1,15 +1,22 @@ import getopt import sys +from diffpy.cmi.version import __version__ + def usage(): """Print short help message.""" print( """\ -DiffPy-CMI is our complex modeling framework. It is a highly flexible library -of Python modules for robust modeling of nanostructures in crystals, -nanomaterials, and amorphous materials. +Welcome to diffpy-CMI, a complex modeling infrastructure +designed for multi-modal analysis of scientific data. +While broadly applicable to a wide range of problems, +including those beyond materials science, diffpy-CMI currently +provides robust tools for modeling atomic structure based on +Pair Distribution Function (PDF) and Small-Angle Scattering (SAS) data. +Its modular Python architecture enables extensible workflows, +with additional capabilities continually being developed. Docs: https://www.diffpy.org/diffpy.cmi @@ -24,8 +31,6 @@ def usage(): def version(): - from diffpy.cmi.version import __version__ - print(f"diffpy-cmi {__version__}") From 7e6880c0fe1c99432730bf221be01e777cc0de28 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 12:40:56 -0400 Subject: [PATCH 06/15] change test.txt to tests.txt based on new skpkg syntax --- requirements/{test.txt => tests.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename requirements/{test.txt => tests.txt} (100%) diff --git a/requirements/test.txt b/requirements/tests.txt similarity index 100% rename from requirements/test.txt rename to requirements/tests.txt From 79b4309b4eb1b6ed0f6f854265d9dee57ee4b799 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:16:25 -0400 Subject: [PATCH 07/15] doc: change test to tests in docs --- doc/source/getting-started.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/getting-started.rst b/doc/source/getting-started.rst index ac7d510..68a04b8 100644 --- a/doc/source/getting-started.rst +++ b/doc/source/getting-started.rst @@ -39,12 +39,12 @@ Here is how you can write a block of code in the documentation. You can use the # Create a new environment, without build dependencies (pure Python package) conda create -n -env python=3.13 \ - --file requirements/test.txt \ + --file requirements/tests.txt \ --file requirements/conda.txt # Create a new environment, with build dependencies (non-pure Python package) conda create -n -env python=3.13 \ - --file requirements/test.txt \ + --file requirements/tests.txt \ --file requirements/conda.txt \ --file requirements/build.txt From 7efdf619be2385c6b31f419305bda7eafd43e713 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:17:24 -0400 Subject: [PATCH 08/15] bug: change version() to print_version() --- src/diffpy/cmi/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index eeb4c43..5a77330 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -30,7 +30,7 @@ def usage(): ) -def version(): +def print_version(): print(f"diffpy-cmi {__version__}") @@ -47,7 +47,7 @@ def main(): usage() return elif opt in ("-V", "--version"): - version() + print_version() return # Default behavior (if no arguments) From 2408c8280e2e508969b29d95c478047367224446 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:25:53 -0400 Subject: [PATCH 09/15] feat: add cmi to pyproject.toml for CLI --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 7e6df7c..42f3a42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ namespaces = false # to disable scanning PEP 420 namespaces (true by default) [project.scripts] diffpy-cmi = "diffpy.cmi.app:main" +cmi = "diffpy.cmi.app:main" [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} From ae124b443f6ff9c4be2ab501ca4bbea278d64f07 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:26:52 -0400 Subject: [PATCH 10/15] feat: add new function for invalid input and remove -V flag --- src/diffpy/cmi/app.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index 5a77330..2278d33 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -5,7 +5,7 @@ def usage(): - """Print short help message.""" + """Print full help message.""" print( """\ @@ -24,29 +24,37 @@ def usage(): diffpy-cmi [--version] [--help] Options: - -V, --version Show version and exit + --version Show version and exit -h, --help Show this message and exit """ ) +def short_usage(): + """Print brief usage message for invalid input.""" + print( + "Usage: diffpy-cmi [--version] [--help]\nUse --help to see more.", + file=sys.stderr, + ) + + def print_version(): print(f"diffpy-cmi {__version__}") def main(): try: - opts, args = getopt.gnu_getopt(sys.argv[1:], "hV", ["help", "version"]) + opts, args = getopt.gnu_getopt(sys.argv[1:], "h", ["help", "version"]) except getopt.GetoptError as err: print(f"Error: {err}", file=sys.stderr) - usage() + short_usage() sys.exit(1) for opt, _ in opts: if opt in ("-h", "--help"): usage() return - elif opt in ("-V", "--version"): + elif opt == "--version": print_version() return From 7170b0758440f04b95cd1e296dbc81d5bc49158f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:29:08 -0400 Subject: [PATCH 11/15] chore: fix modulare in short description across 3 files --- doc/source/index.rst | 2 +- pyproject.toml | 2 +- src/diffpy/cmi/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/index.rst b/doc/source/index.rst index 11508cc..84c46cb 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,7 +4,7 @@ .. |title| replace:: diffpy.cmi documentation -``diffpy.cmi`` - Complex modeling infrastructure: a modulare framework for multi-modal modeling of scientific data. +``diffpy.cmi`` - Complex modeling infrastructure: a modular framework for multi-modal modeling of scientific data. | Software version |release| | Last updated |today|. diff --git a/pyproject.toml b/pyproject.toml index 42f3a42..1146c0c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [ maintainers = [ { name="Simon Billinge", email="sb2896@columbia.edu" }, ] -description = "Complex modeling infrastructure: a modulare framework for multi-modal modeling of scientific data." +description = "Complex modeling infrastructure: a modular framework for multi-modal modeling of scientific data." keywords = ['modelling', 'regression', 'diffraction', 'PDF', 'complex-modeling'] readme = "README.rst" requires-python = ">=3.11, <3.14" diff --git a/src/diffpy/cmi/__init__.py b/src/diffpy/cmi/__init__.py index 18047b8..158d6da 100644 --- a/src/diffpy/cmi/__init__.py +++ b/src/diffpy/cmi/__init__.py @@ -13,7 +13,7 @@ # ############################################################################## """Complex modeling infrastructure: -a modulare framework for multi-modal modeling of scientific data.""" +a modular framework for multi-modal modeling of scientific data.""" # package version from diffpy.cmi.version import __version__ # noqa From a247ec66338b44276f315e6dc7d37318d2f53ff7 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 13:41:37 -0400 Subject: [PATCH 12/15] feat: migration main() to argparse --- src/diffpy/cmi/app.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index 2278d33..455b21b 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -1,4 +1,4 @@ -import getopt +import argparse import sys from diffpy.cmi.version import __version__ @@ -43,22 +43,31 @@ def print_version(): def main(): - try: - opts, args = getopt.gnu_getopt(sys.argv[1:], "h", ["help", "version"]) - except getopt.GetoptError as err: - print(f"Error: {err}", file=sys.stderr) + parser = argparse.ArgumentParser( + prog="diffpy-cmi", + add_help=False, + ) + parser.add_argument( + "--version", action="store_true", help="Show version and exit" + ) + parser.add_argument( + "-h", "--help", action="store_true", help="Show this message and exit" + ) + args, unknown = parser.parse_known_args() + if unknown: + print( + f"Error: unrecognized arguments: {' '.join(unknown)}", + file=sys.stderr, + ) short_usage() sys.exit(1) - - for opt, _ in opts: - if opt in ("-h", "--help"): - usage() - return - elif opt == "--version": - print_version() - return - - # Default behavior (if no arguments) + if args.help: + usage() + return + if args.version: + print_version() + return + # Default behavior (no args) usage() From 89328df2ef22781e296457297cfd3602f0e23903 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 22:07:00 -0500 Subject: [PATCH 13/15] feat: use argsparse description feature --- src/diffpy/cmi/app.py | 76 ++++++++++--------------------------------- 1 file changed, 17 insertions(+), 59 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index 455b21b..1581daa 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -1,74 +1,32 @@ import argparse -import sys from diffpy.cmi.version import __version__ -def usage(): - """Print full help message.""" - print( - """\ - -Welcome to diffpy-CMI, a complex modeling infrastructure -designed for multi-modal analysis of scientific data. -While broadly applicable to a wide range of problems, -including those beyond materials science, diffpy-CMI currently -provides robust tools for modeling atomic structure based on -Pair Distribution Function (PDF) and Small-Angle Scattering (SAS) data. -Its modular Python architecture enables extensible workflows, -with additional capabilities continually being developed. - -Docs: https://www.diffpy.org/diffpy.cmi - -Usage: - diffpy-cmi [--version] [--help] - -Options: - --version Show version and exit - -h, --help Show this message and exit -""" - ) - - -def short_usage(): - """Print brief usage message for invalid input.""" - print( - "Usage: diffpy-cmi [--version] [--help]\nUse --help to see more.", - file=sys.stderr, - ) - - -def print_version(): - print(f"diffpy-cmi {__version__}") - - def main(): parser = argparse.ArgumentParser( prog="diffpy-cmi", - add_help=False, - ) - parser.add_argument( - "--version", action="store_true", help="Show version and exit" + description=( + "Welcome to diffpy-CMI, a complex modeling infrastructure " + "for multi-modal analysis of scientific data.\n\n" + "Docs: https://www.diffpy.org/diffpy.cmi" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, ) + parser.add_argument( - "-h", "--help", action="store_true", help="Show this message and exit" + "--version", + action="store_true", + help="Show the program's version number and exit", ) - args, unknown = parser.parse_known_args() - if unknown: - print( - f"Error: unrecognized arguments: {' '.join(unknown)}", - file=sys.stderr, - ) - short_usage() - sys.exit(1) - if args.help: - usage() - return + + args = parser.parse_args() + if args.version: - print_version() - return - # Default behavior (no args) - usage() + print(f"diffpy-cmi {__version__}") + else: + # Default behavior when no arguments are given + parser.print_help() if __name__ == "__main__": From fd40eedc1e761bcfe7030e98c65765826d95c89d Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 2 Jul 2025 22:45:02 -0500 Subject: [PATCH 14/15] change diffpy-cmi to diffpy.cmi --- src/diffpy/cmi/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index 1581daa..4226d85 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -23,7 +23,7 @@ def main(): args = parser.parse_args() if args.version: - print(f"diffpy-cmi {__version__}") + print(f"diffpy.cmi {__version__}") else: # Default behavior when no arguments are given parser.print_help() From b1566079d27f71f9d0e42e2aaa070ec7b48fd999 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 3 Jul 2025 10:38:47 -0500 Subject: [PATCH 15/15] style: remove extra lines --- src/diffpy/cmi/app.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/diffpy/cmi/app.py b/src/diffpy/cmi/app.py index 4226d85..1a46163 100644 --- a/src/diffpy/cmi/app.py +++ b/src/diffpy/cmi/app.py @@ -13,15 +13,12 @@ def main(): ), formatter_class=argparse.RawDescriptionHelpFormatter, ) - parser.add_argument( "--version", action="store_true", help="Show the program's version number and exit", ) - args = parser.parse_args() - if args.version: print(f"diffpy.cmi {__version__}") else: