From a297716d5d72fc4f4d806a9b57c233acdfec0869 Mon Sep 17 00:00:00 2001 From: Evan Bolyen Date: Wed, 26 Aug 2026 13:37:03 +0200 Subject: [PATCH 1/6] SKIP: add CLI proxy --- bin/tab-qiime | 54 +++++++++++++++++++++++ hooks/50_activate_qiime_tab_completion.sh | 5 +++ pyproject.toml | 6 +++ src/qiime2/__main__.py | 47 ++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 bin/tab-qiime create mode 100644 hooks/50_activate_qiime_tab_completion.sh create mode 100644 src/qiime2/__main__.py diff --git a/bin/tab-qiime b/bin/tab-qiime new file mode 100644 index 0000000..ca3f5a2 --- /dev/null +++ b/bin/tab-qiime @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Bash completion script that defers to a cached completion script representing +# the state of the current QIIME 2 deployment. +# +# This script is intended to be executed on the command-line or in +# .bashrc/.bash_profile: +# +# source tab-qiime +# + +_qiime_completion() +{ + # Attempt to find the cached completion script. If rachis-cli isn't installed, or + # is an incompatible version, don't attempt completion. + local completion_path="$(python -c "import rachis_cli.util; print(rachis_cli.util.get_completion_path())" 2> /dev/null)" + + if [[ $? != 0 ]]; then + unset COMPREPLY + return 0 + fi + + # If the completion script exists, attempt completion by invoking the script + # in a subshell, supplying COMP_WORDS and COMP_CWORD. Capture the output as + # the completion reply. If the completion script failed, don't attempt + # completion. + if [[ -f "$completion_path" ]] ; then + COMPREPLY=( $(COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD="${COMP_CWORD}" "$completion_path" 2> /dev/null) ) + + if [[ $? != 0 ]]; then + unset COMPREPLY + return 0 + fi + else + unset COMPREPLY + return 0 + fi + + return 0 +} + +# Enable default readline and bash completion behavior when `_qiime_completion` +# doesn't have a reply. +complete -F _qiime_completion -o default -o bashdefault mosh + +# Execute a `qiime` command (any command will do) so that tab-completion will +# work out-of-the-box (e.g. with a fresh installation of q2). Running a +# command will create or refresh the cache if necessary, which contains the +# actual completion script. +# +# Ignore stdout to avoid displaying help text to users enabling tab-completion. +# stderr displays the note about cache refreshing, as that can take a few +# moments to complete. +mosh > /dev/null diff --git a/hooks/50_activate_qiime_tab_completion.sh b/hooks/50_activate_qiime_tab_completion.sh new file mode 100644 index 0000000..2f58385 --- /dev/null +++ b/hooks/50_activate_qiime_tab_completion.sh @@ -0,0 +1,5 @@ +if [ -n "${ZSH_VERSION-}" ]; then + autoload -Uz compinit && compinit && autoload bashcompinit && bashcompinit && source tab-qiime +elif [ -n "${BASH_VERSION-}" ]; then + source tab-qiime +fi diff --git a/pyproject.toml b/pyproject.toml index 025171b..55e8a69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,9 @@ dynamic = ["version"] Homepage = "https://qiime2.org" Repository = "https://github.com/qiime2/q2" +[project.scripts] +"qiime" = "qiime2.__main__:qiime" + [dependency-groups] dev = [ "nox>=2025.11.12", @@ -46,6 +49,9 @@ file = "src/qiime2/_version.py" [tool.setuptools] include-package-data = true +script-files = [ + "bin/tab-qiime" +] [tool.setuptools.packages.find] where = ["src"] diff --git a/src/qiime2/__main__.py b/src/qiime2/__main__.py new file mode 100644 index 0000000..816131e --- /dev/null +++ b/src/qiime2/__main__.py @@ -0,0 +1,47 @@ +# ---------------------------------------------------------------------------- +# Copyright (c) 2016-2026, QIIME 2 development team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file LICENSE, distributed with this software. +# ---------------------------------------------------------------------------- + +import click + +import rachis_cli.commands + + +ROOT_COMMAND_HELP = """\ +QIIME 2 command-line interface (via rachis-cli) +-------------------------------------- + +To get help with QIIME 2, visit https://qiime2.org. + +To enable tab completion in Bash, run the following command or add it to your \ +.bashrc/.bash_profile: + + source tab-qiime + +To enable tab completion in ZSH, run the following commands or add them to \ +your .zshrc: + +\b + autoload -Uz compinit && compinit + autoload bashcompinit && bashcompinit + source tab-qiime + +""" + + +# Entry point for CLI +@click.command(cls=rachis_cli.commands.RootCommand, invoke_without_command=True, + no_args_is_help=True, help=ROOT_COMMAND_HELP) +@click.version_option(prog_name='rachis-cli', + message='%(prog)s version %(version)s\nRun `qiime info` ' + 'for more version details.') +def qiime(): + pass + + +if __name__ == '__main__': + qiime() \ No newline at end of file From dcbc8e8a376605b0c26d6538789ffc24b1db5a7f Mon Sep 17 00:00:00 2001 From: q2d2 Date: Mon, 31 Aug 2026 15:06:02 +0200 Subject: [PATCH 2/6] SKIP: paired PR for qiime2 -> rachis cli migration --- bin/tab-qiime | 54 ----------------------- conda-recipe/meta.yaml | 1 - hooks/50_activate_qiime_tab_completion.sh | 5 --- pyproject.toml | 8 +--- src/qiime2/__main__.py | 47 -------------------- 5 files changed, 1 insertion(+), 114 deletions(-) delete mode 100644 bin/tab-qiime delete mode 100644 hooks/50_activate_qiime_tab_completion.sh delete mode 100644 src/qiime2/__main__.py diff --git a/bin/tab-qiime b/bin/tab-qiime deleted file mode 100644 index ca3f5a2..0000000 --- a/bin/tab-qiime +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -# Bash completion script that defers to a cached completion script representing -# the state of the current QIIME 2 deployment. -# -# This script is intended to be executed on the command-line or in -# .bashrc/.bash_profile: -# -# source tab-qiime -# - -_qiime_completion() -{ - # Attempt to find the cached completion script. If rachis-cli isn't installed, or - # is an incompatible version, don't attempt completion. - local completion_path="$(python -c "import rachis_cli.util; print(rachis_cli.util.get_completion_path())" 2> /dev/null)" - - if [[ $? != 0 ]]; then - unset COMPREPLY - return 0 - fi - - # If the completion script exists, attempt completion by invoking the script - # in a subshell, supplying COMP_WORDS and COMP_CWORD. Capture the output as - # the completion reply. If the completion script failed, don't attempt - # completion. - if [[ -f "$completion_path" ]] ; then - COMPREPLY=( $(COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD="${COMP_CWORD}" "$completion_path" 2> /dev/null) ) - - if [[ $? != 0 ]]; then - unset COMPREPLY - return 0 - fi - else - unset COMPREPLY - return 0 - fi - - return 0 -} - -# Enable default readline and bash completion behavior when `_qiime_completion` -# doesn't have a reply. -complete -F _qiime_completion -o default -o bashdefault mosh - -# Execute a `qiime` command (any command will do) so that tab-completion will -# work out-of-the-box (e.g. with a fresh installation of q2). Running a -# command will create or refresh the cache if necessary, which contains the -# actual completion script. -# -# Ignore stdout to avoid displaying help text to users enabling tab-completion. -# stderr displays the note about cache refreshing, as that can take a few -# moments to complete. -mosh > /dev/null diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 2a320e1..abd3434 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -15,7 +15,6 @@ requirements: run: - python {{ python }} - pip - - click {{ click }} - rachis >={{ rachis }} build: - python {{ python }} diff --git a/hooks/50_activate_qiime_tab_completion.sh b/hooks/50_activate_qiime_tab_completion.sh deleted file mode 100644 index 2f58385..0000000 --- a/hooks/50_activate_qiime_tab_completion.sh +++ /dev/null @@ -1,5 +0,0 @@ -if [ -n "${ZSH_VERSION-}" ]; then - autoload -Uz compinit && compinit && autoload bashcompinit && bashcompinit && source tab-qiime -elif [ -n "${BASH_VERSION-}" ]; then - source tab-qiime -fi diff --git a/pyproject.toml b/pyproject.toml index 55e8a69..3d0396d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "qiime2" authors = [ - { name = "QIIME 2 Developers", email = "developers@qiime2.org" } + { name = "QIIME 2 Developers", email = "developers@qiime2.org" } ] description = "QIIME 2 Proxy Package" readme = {file = "README.md", content-type = "text/markdown"} @@ -12,9 +12,6 @@ dynamic = ["version"] Homepage = "https://qiime2.org" Repository = "https://github.com/qiime2/q2" -[project.scripts] -"qiime" = "qiime2.__main__:qiime" - [dependency-groups] dev = [ "nox>=2025.11.12", @@ -49,9 +46,6 @@ file = "src/qiime2/_version.py" [tool.setuptools] include-package-data = true -script-files = [ - "bin/tab-qiime" -] [tool.setuptools.packages.find] where = ["src"] diff --git a/src/qiime2/__main__.py b/src/qiime2/__main__.py deleted file mode 100644 index 816131e..0000000 --- a/src/qiime2/__main__.py +++ /dev/null @@ -1,47 +0,0 @@ -# ---------------------------------------------------------------------------- -# Copyright (c) 2016-2026, QIIME 2 development team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file LICENSE, distributed with this software. -# ---------------------------------------------------------------------------- - -import click - -import rachis_cli.commands - - -ROOT_COMMAND_HELP = """\ -QIIME 2 command-line interface (via rachis-cli) --------------------------------------- - -To get help with QIIME 2, visit https://qiime2.org. - -To enable tab completion in Bash, run the following command or add it to your \ -.bashrc/.bash_profile: - - source tab-qiime - -To enable tab completion in ZSH, run the following commands or add them to \ -your .zshrc: - -\b - autoload -Uz compinit && compinit - autoload bashcompinit && bashcompinit - source tab-qiime - -""" - - -# Entry point for CLI -@click.command(cls=rachis_cli.commands.RootCommand, invoke_without_command=True, - no_args_is_help=True, help=ROOT_COMMAND_HELP) -@click.version_option(prog_name='rachis-cli', - message='%(prog)s version %(version)s\nRun `qiime info` ' - 'for more version details.') -def qiime(): - pass - - -if __name__ == '__main__': - qiime() \ No newline at end of file From a794bde5ede942ab79d3a6ca91d7d40a6c559f94 Mon Sep 17 00:00:00 2001 From: q2d2 Date: Mon, 31 Aug 2026 15:15:08 +0200 Subject: [PATCH 3/6] testing user From 1bf5d97e7871352088c806c4bcc2f9900cc0f91f Mon Sep 17 00:00:00 2001 From: q2d2 Date: Mon, 31 Aug 2026 17:42:30 +0200 Subject: [PATCH 4/6] remove pip from run reqs --- conda-recipe/meta.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index abd3434..57426cd 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -14,7 +14,6 @@ requirements: - wheel run: - python {{ python }} - - pip - rachis >={{ rachis }} build: - python {{ python }} From 9aabc741c1efa23b3fb2d9be8d9ab035e66a5e7b Mon Sep 17 00:00:00 2001 From: Liz Gehret <54517601+lizgehret@users.noreply.github.com> Date: Tue, 1 Sep 2026 12:06:57 +0200 Subject: [PATCH 5/6] unneccessary formatting change --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3d0396d..025171b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "qiime2" authors = [ - { name = "QIIME 2 Developers", email = "developers@qiime2.org" } + { name = "QIIME 2 Developers", email = "developers@qiime2.org" } ] description = "QIIME 2 Proxy Package" readme = {file = "README.md", content-type = "text/markdown"} From 6094c5c51cb279841cdcc866e78cf3a083824758 Mon Sep 17 00:00:00 2001 From: q2d2 Date: Tue, 1 Sep 2026 12:16:02 +0200 Subject: [PATCH 6/6] lint --- noxfile.py | 2 +- src/qiime2/__init__.py | 3 +-- tests/test_conda_hooks.py | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/noxfile.py b/noxfile.py index 716f3ef..b356c39 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,4 +1,4 @@ -#!/usr/bin/env -S uv run --script +# !/usr/bin/env -S uv run --script # /// script # dependencies = ["nox>=2025.11.12"] diff --git a/src/qiime2/__init__.py b/src/qiime2/__init__.py index 9030847..37e8091 100644 --- a/src/qiime2/__init__.py +++ b/src/qiime2/__init__.py @@ -6,14 +6,13 @@ # The full license is in the file LICENSE, distributed with this software. # ---------------------------------------------------------------------------- -import sys import importlib import importlib.abc import importlib.util +import sys import rachis - # The `.` prevents the hook from running on the root, which doesn't # help. The root is handled by the __dunders__ below QIIME2_PREFIX = "qiime2." diff --git a/tests/test_conda_hooks.py b/tests/test_conda_hooks.py index 8b4a4a6..3d03853 100644 --- a/tests/test_conda_hooks.py +++ b/tests/test_conda_hooks.py @@ -1,6 +1,5 @@ -from pathlib import Path import subprocess - +from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] ACTIVATE_HOOK = REPO_ROOT / "hooks" / "00_activate_qiime2_envs.sh"