From 8f3710931511136b7e7c3978ff24f7c49983b491 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 28 Jun 2023 18:45:31 -0500 Subject: [PATCH 1/6] Convert conda-build entrypoints into plugins --- conda_build/cli/main_build.py | 26 ++++++------ conda_build/cli/main_convert.py | 11 ++++- conda_build/cli/main_debug.py | 24 ++++++----- conda_build/cli/main_develop.py | 11 ++++- conda_build/cli/main_index.py | 8 +++- conda_build/cli/main_inspect.py | 11 ++++- conda_build/cli/main_metapackage.py | 15 ++++--- conda_build/cli/main_render.py | 17 ++++---- conda_build/cli/main_skeleton.py | 9 +++-- conda_build/cli/plugins.py | 62 +++++++++++++++++++++++++++++ pyproject.toml | 3 ++ 11 files changed, 149 insertions(+), 48 deletions(-) create mode 100644 conda_build/cli/plugins.py diff --git a/conda_build/cli/main_build.py b/conda_build/cli/main_build.py index ca3bb8a3cf..9867a11846 100644 --- a/conda_build/cli/main_build.py +++ b/conda_build/cli/main_build.py @@ -13,23 +13,18 @@ from conda.common.io import dashlist from glob2 import glob -import conda_build.api as api -import conda_build.build as build -import conda_build.source as source -import conda_build.utils as utils -from conda_build.cli.actions import KeyValueAction -from conda_build.cli.main_render import get_render_parser -from conda_build.conda_interface import ( - add_parser_channels, - binstar_upload, - cc_conda_build, -) -from conda_build.config import Config, get_channel_urls, zstd_compression_level_default -from conda_build.utils import LoggingContext +from .. import api, build, source, utils +from ..conda_interface import add_parser_channels, binstar_upload, cc_conda_build +from ..config import Config, get_channel_urls, zstd_compression_level_default +from ..deprecations import deprecated +from ..utils import LoggingContext +from .actions import KeyValueAction +from .main_render import get_render_parser def parse_args(args): p = get_render_parser() + p.prog = "conda build" p.description = dals( """ Tool for building conda packages. A conda package is a binary tarball @@ -588,6 +583,7 @@ def execute(args): return outputs +@deprecated("3.26.0", "4.0.0", addendum="Use `conda build` instead.") def main(): try: execute(sys.argv[1:]) @@ -601,3 +597,7 @@ def main(): ) sys.exit(1) return + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_convert.py b/conda_build/cli/main_convert.py index 43006a1e3b..a05cef0950 100644 --- a/conda_build/cli/main_convert.py +++ b/conda_build/cli/main_convert.py @@ -4,8 +4,9 @@ import sys from os.path import abspath, expanduser -from conda_build import api -from conda_build.conda_interface import ArgumentParser +from .. import api +from ..conda_interface import ArgumentParser +from ..deprecations import deprecated logging.basicConfig(level=logging.INFO) @@ -36,6 +37,7 @@ def parse_args(args): p = ArgumentParser( + prog="conda convert", description=""" Various tools to convert conda packages. Takes a pure Python package build for one platform and converts it to work on one or more other platforms, or @@ -127,5 +129,10 @@ def execute(args): api.convert(f, **args.__dict__) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda convert` instead.") def main(): return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_debug.py b/conda_build/cli/main_debug.py index 702fbfc798..1a9516bbd8 100644 --- a/conda_build/cli/main_debug.py +++ b/conda_build/cli/main_debug.py @@ -4,13 +4,11 @@ import sys from argparse import ArgumentParser -from conda_build import api -from conda_build.cli import validators as valid - -# we extend the render parser because we basically need to render the recipe before -# we can say what env to create. This is not really true for debugging tests, but meh... -from conda_build.cli.main_render import get_render_parser -from conda_build.utils import on_win +from .. import api +from ..deprecations import deprecated +from ..utils import on_win +from . import validators as valid +from .main_render import get_render_parser logging.basicConfig(level=logging.INFO) @@ -18,6 +16,7 @@ def get_parser() -> ArgumentParser: """Returns a parser object for this command""" p = get_render_parser() + p.prog = "conda debug" p.description = """ Set up environments and activation scripts to debug your build or test phase. @@ -87,9 +86,9 @@ def get_parser() -> ArgumentParser: return p -def execute(): +def execute(args): parser = get_parser() - args = parser.parse_args() + args = parser.parse_args(args) try: activation_string = api.debug( @@ -119,5 +118,10 @@ def execute(): sys.exit(1) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda debug` instead.") def main(): - return execute() + return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_develop.py b/conda_build/cli/main_develop.py index ec33555748..f7c3c5ce95 100644 --- a/conda_build/cli/main_develop.py +++ b/conda_build/cli/main_develop.py @@ -5,14 +5,16 @@ from conda.base.context import context, determine_target_prefix -from conda_build import api -from conda_build.conda_interface import ArgumentParser, add_parser_prefix +from .. import api +from ..conda_interface import ArgumentParser, add_parser_prefix +from ..deprecations import deprecated logging.basicConfig(level=logging.INFO) def parse_args(args): p = ArgumentParser( + prog="conda develop", description=""" Install a Python package in 'development mode'. @@ -86,5 +88,10 @@ def execute(args): ) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda develop` instead.") def main(): return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_index.py b/conda_build/cli/main_index.py index 1f596b5d37..c588e73d26 100644 --- a/conda_build/cli/main_index.py +++ b/conda_build/cli/main_index.py @@ -16,8 +16,9 @@ def parse_args(args): p = ArgumentParser( + prog="conda index", description="Update package index metadata files in given directories. " - "Pending deprecated, please use the standalone conda-index project." + "Pending deprecated, please use the standalone conda-index project.", ) p.add_argument( @@ -120,5 +121,10 @@ def execute(args): ) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda index` instead.") def main(): return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_inspect.py b/conda_build/cli/main_inspect.py index 472bd2f3af..ddf392e1a8 100644 --- a/conda_build/cli/main_inspect.py +++ b/conda_build/cli/main_inspect.py @@ -7,14 +7,16 @@ from conda.base.context import context, determine_target_prefix -from conda_build import api -from conda_build.conda_interface import ArgumentParser, add_parser_prefix +from .. import api +from ..conda_interface import ArgumentParser, add_parser_prefix +from ..deprecations import deprecated logging.basicConfig(level=logging.INFO) def parse_args(args): p = ArgumentParser( + prog="conda inspect", description="Tools for inspecting conda packages.", epilog=""" Run --help on the subcommands like 'conda inspect linkages --help' to see the @@ -220,5 +222,10 @@ def execute(args): raise ValueError(f"Unrecognized subcommand: {args.subcommand}.") +@deprecated("3.26.0", "4.0.0", addendum="Use `conda inspect` instead.") def main(): return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_metapackage.py b/conda_build/cli/main_metapackage.py index 7657432fdc..ece55cd94c 100644 --- a/conda_build/cli/main_metapackage.py +++ b/conda_build/cli/main_metapackage.py @@ -4,18 +4,16 @@ import logging import sys -from conda_build import api -from conda_build.conda_interface import ( - ArgumentParser, - add_parser_channels, - binstar_upload, -) +from .. import api +from ..conda_interface import ArgumentParser, add_parser_channels, binstar_upload +from ..deprecations import deprecated logging.basicConfig(level=logging.INFO) def parse_args(args): p = ArgumentParser( + prog="conda metapackage", description=""" Tool for building conda metapackages. A metapackage is a package with no files, only metadata. They are typically used to collect several packages @@ -114,5 +112,10 @@ def execute(args): api.create_metapackage(channel_urls=channel_urls, **args.__dict__) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda metapackage` instead.") def main(): return execute(sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/conda_build/cli/main_render.py b/conda_build/cli/main_render.py index 15cb3bdc4b..a563e87c1b 100644 --- a/conda_build/cli/main_render.py +++ b/conda_build/cli/main_render.py @@ -8,15 +8,12 @@ import yaml from yaml.parser import ParserError -from conda_build import __version__, api -from conda_build.conda_interface import ( - ArgumentParser, - add_parser_channels, - cc_conda_build, -) -from conda_build.config import get_channel_urls, get_or_merge_config -from conda_build.utils import LoggingContext -from conda_build.variants import get_package_variants, set_language_env_vars +from .. import __version__, api +from ..conda_interface import ArgumentParser, add_parser_channels, cc_conda_build +from ..config import get_channel_urls, get_or_merge_config +from ..deprecations import deprecated +from ..utils import LoggingContext +from ..variants import get_package_variants, set_language_env_vars on_win = sys.platform == "win32" log = logging.getLogger(__name__) @@ -44,6 +41,7 @@ def __call__(self, parser, namespace, values, option_string=None): def get_render_parser(): p = ArgumentParser( + prog="conda render", description=""" Tool for expanding the template meta.yml file (containing Jinja syntax and selectors) into the rendered meta.yml files. The template meta.yml file is @@ -245,6 +243,7 @@ def execute(args, print_results=True): return metadata_tuples +@deprecated("3.26.0", "4.0.0", addendum="Use `conda render` instead.") def main(): return execute(sys.argv[1:]) diff --git a/conda_build/cli/main_skeleton.py b/conda_build/cli/main_skeleton.py index 7642bc14da..7bb9e3369f 100644 --- a/conda_build/cli/main_skeleton.py +++ b/conda_build/cli/main_skeleton.py @@ -6,9 +6,10 @@ import pkgutil import sys -import conda_build.api as api -from conda_build.conda_interface import ArgumentParser -from conda_build.config import Config +from .. import api +from ..conda_interface import ArgumentParser +from ..config import Config +from ..deprecations import deprecated thisdir = os.path.dirname(os.path.abspath(__file__)) logging.basicConfig(level=logging.INFO) @@ -16,6 +17,7 @@ def parse_args(args): p = ArgumentParser( + prog="conda skeleton", description=""" Generates a boilerplate/skeleton recipe, which you can then edit to create a full recipe. Some simple skeleton recipes may not even need edits. @@ -60,6 +62,7 @@ def execute(args): ) +@deprecated("3.26.0", "4.0.0", addendum="Use `conda skeleton` instead.") def main(): return execute(sys.argv[1:]) diff --git a/conda_build/cli/plugins.py b/conda_build/cli/plugins.py new file mode 100644 index 0000000000..e15b139cea --- /dev/null +++ b/conda_build/cli/plugins.py @@ -0,0 +1,62 @@ +# Copyright (C) 2014 Anaconda, Inc +# SPDX-License-Identifier: BSD-3-Clause +import conda.plugins + +from .main_build import execute as build +from .main_convert import execute as convert +from .main_debug import execute as debug +from .main_develop import execute as develop +from .main_index import execute as index +from .main_inspect import execute as inspect +from .main_metapackage import execute as metapackage +from .main_render import execute as render +from .main_skeleton import execute as skeleton + + +@conda.plugins.hookimpl +def conda_subcommands(): + yield conda.plugins.CondaSubcommand( + name="build", + summary="Build conda packages from a conda recipe.", + action=build, + ) + yield conda.plugins.CondaSubcommand( + name="convert", + summary="Convert pure Python packages to other platforms (a.k.a., subdirs).", + action=convert, + ) + yield conda.plugins.CondaSubcommand( + name="debug", + summary="Debug the build or test phases of conda recipes.", + action=debug, + ) + yield conda.plugins.CondaSubcommand( + name="develop", + summary="Install a Python package in 'development mode'. Similar to `pip install --editable`.", + action=develop, + ) + yield conda.plugins.CondaSubcommand( + name="index", + summary="Update package index metadata files. Pending deprecation, use https://github.com/conda/conda-index instead.", + action=index, + ) + yield conda.plugins.CondaSubcommand( + name="inspect", + summary="Tools for inspecting conda packages.", + action=inspect, + ) + yield conda.plugins.CondaSubcommand( + name="metapackage", + summary="Specialty tool for generating conda metapackage.", + action=metapackage, + ) + yield conda.plugins.CondaSubcommand( + name="render", + summary="Expand a conda recipe into a platform-specific recipe.", + action=render, + ) + yield conda.plugins.CondaSubcommand( + name="skeleton", + summary="Generate boilerplate conda recipes.", + action=skeleton, + ) diff --git a/pyproject.toml b/pyproject.toml index 33b00c3a1b..df4e8cca3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,9 @@ conda-debug = "conda_build.cli.main_debug:main" [project.entry-points."distutils.commands"] bdist_conda = "conda_build.bdist_conda:bdist_conda" +[project.entry-points.conda] +conda-build = "conda_build.cli.plugins" + [tool.hatch.version] source = "vcs" From 0233db4b132be75fcb21461d048a43c9a395c3d6 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 28 Jun 2023 18:54:43 -0500 Subject: [PATCH 2/6] Add news --- news/4921-convert-entrypoints-to-plugins | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 news/4921-convert-entrypoints-to-plugins diff --git a/news/4921-convert-entrypoints-to-plugins b/news/4921-convert-entrypoints-to-plugins new file mode 100644 index 0000000000..f2b9a78563 --- /dev/null +++ b/news/4921-convert-entrypoints-to-plugins @@ -0,0 +1,20 @@ +### Enhancements + +* Implement subcommands as conda plugins. (#4921) + +### Bug fixes + +* + +### Deprecations + +* Mark executable invocations (e.g., `conda-build`) as pending deprecation. (#4921) +* Mark module based invocations (e.g., `python -m conda_build.cli.main_build`) as pending deprecation. (#4921) + +### Docs + +* + +### Other + +* From d500db8531f952f12de68686bd9609e09ad01596 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Thu, 29 Jun 2023 12:33:13 -0500 Subject: [PATCH 3/6] Move conda_build.cli.plugins to conda_build.plugin --- conda_build/{cli/plugins.py => plugin.py} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename conda_build/{cli/plugins.py => plugin.py} (79%) diff --git a/conda_build/cli/plugins.py b/conda_build/plugin.py similarity index 79% rename from conda_build/cli/plugins.py rename to conda_build/plugin.py index e15b139cea..03a3949f44 100644 --- a/conda_build/cli/plugins.py +++ b/conda_build/plugin.py @@ -2,15 +2,15 @@ # SPDX-License-Identifier: BSD-3-Clause import conda.plugins -from .main_build import execute as build -from .main_convert import execute as convert -from .main_debug import execute as debug -from .main_develop import execute as develop -from .main_index import execute as index -from .main_inspect import execute as inspect -from .main_metapackage import execute as metapackage -from .main_render import execute as render -from .main_skeleton import execute as skeleton +from .cli.main_build import execute as build +from .cli.main_convert import execute as convert +from .cli.main_debug import execute as debug +from .cli.main_develop import execute as develop +from .cli.main_index import execute as index +from .cli.main_inspect import execute as inspect +from .cli.main_metapackage import execute as metapackage +from .cli.main_render import execute as render +from .cli.main_skeleton import execute as skeleton @conda.plugins.hookimpl From 6ec496188919382db96b1d4410172f4262495442 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Thu, 29 Jun 2023 12:33:39 -0500 Subject: [PATCH 4/6] Remove new if __main__ interfaces --- conda_build/cli/main_build.py | 4 ---- conda_build/cli/main_convert.py | 4 ---- conda_build/cli/main_debug.py | 4 ---- conda_build/cli/main_develop.py | 4 ---- conda_build/cli/main_index.py | 4 ---- conda_build/cli/main_inspect.py | 4 ---- conda_build/cli/main_metapackage.py | 4 ---- 7 files changed, 28 deletions(-) diff --git a/conda_build/cli/main_build.py b/conda_build/cli/main_build.py index 9867a11846..999be96663 100644 --- a/conda_build/cli/main_build.py +++ b/conda_build/cli/main_build.py @@ -597,7 +597,3 @@ def main(): ) sys.exit(1) return - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_convert.py b/conda_build/cli/main_convert.py index a05cef0950..4c09cfc1da 100644 --- a/conda_build/cli/main_convert.py +++ b/conda_build/cli/main_convert.py @@ -132,7 +132,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda convert` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_debug.py b/conda_build/cli/main_debug.py index 1a9516bbd8..00c6eeb230 100644 --- a/conda_build/cli/main_debug.py +++ b/conda_build/cli/main_debug.py @@ -121,7 +121,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda debug` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_develop.py b/conda_build/cli/main_develop.py index f7c3c5ce95..a7a202e5ff 100644 --- a/conda_build/cli/main_develop.py +++ b/conda_build/cli/main_develop.py @@ -91,7 +91,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda develop` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_index.py b/conda_build/cli/main_index.py index c588e73d26..b0eefa8aa7 100644 --- a/conda_build/cli/main_index.py +++ b/conda_build/cli/main_index.py @@ -124,7 +124,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda index` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_inspect.py b/conda_build/cli/main_inspect.py index ddf392e1a8..79e0594a4f 100644 --- a/conda_build/cli/main_inspect.py +++ b/conda_build/cli/main_inspect.py @@ -225,7 +225,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda inspect` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() diff --git a/conda_build/cli/main_metapackage.py b/conda_build/cli/main_metapackage.py index ece55cd94c..71be2e7d3d 100644 --- a/conda_build/cli/main_metapackage.py +++ b/conda_build/cli/main_metapackage.py @@ -115,7 +115,3 @@ def execute(args): @deprecated("3.26.0", "4.0.0", addendum="Use `conda metapackage` instead.") def main(): return execute(sys.argv[1:]) - - -if __name__ == "__main__": - main() From f63294ebdc276e62a9de1930d8682ac574f0c843 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Thu, 29 Jun 2023 12:35:22 -0500 Subject: [PATCH 5/6] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index df4e8cca3b..9fb3b5f222 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ conda-debug = "conda_build.cli.main_debug:main" bdist_conda = "conda_build.bdist_conda:bdist_conda" [project.entry-points.conda] -conda-build = "conda_build.cli.plugins" +conda-build = "conda_build.plugin" [tool.hatch.version] source = "vcs" From faa708836cb55f4f1a484b1c32d4d0f6c46e99b8 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Fri, 30 Jun 2023 15:36:24 -0500 Subject: [PATCH 6/6] Plugin system was added in conda 22.11.0 --- recipe/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 850b742901..bc307a23a4 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -31,7 +31,7 @@ requirements: run: - beautifulsoup4 - chardet - - conda >=4.13 + - conda >=22.11.0 - conda-index - conda-package-handling >=1.3 - filelock