diff --git a/conda_build/api.py b/conda_build/api.py index 8c47ef1e6d..571f08f534 100644 --- a/conda_build/api.py +++ b/conda_build/api.py @@ -22,7 +22,6 @@ # make the Config class available in the api namespace from .config import DEFAULT_PREFIX_LENGTH as _prefix_length from .config import Config, get_channel_urls, get_or_merge_config -from .deprecations import deprecated from .metadata import MetaData, MetaDataTuple from .utils import ( CONDA_PACKAGE_EXTENSIONS, @@ -186,32 +185,6 @@ def get_output_file_paths( return sorted(set(outs)) -@deprecated("24.3.0", "24.5.0", addendum="Use `get_output_file_paths` instead.") -def get_output_file_path( - recipe_path_or_metadata: str - | os.PathLike - | Path - | MetaData - | Iterable[MetaDataTuple], - no_download_source: bool = False, - config: Config | None = None, - variants: dict[str, Any] | None = None, - **kwargs, -) -> list[str]: - """Get output file paths for any packages that would be created by a recipe - - Both split packages (recipes with more than one output) and build matrices, - created with variants, contribute to the list of file paths here. - """ - return get_output_file_paths( - recipe_path_or_metadata, - no_download_source=no_download_source, - config=config, - variants=variants, - **kwargs, - ) - - def check( recipe_path: str | os.PathLike | Path, no_download_source: bool = False, diff --git a/conda_build/bdist_conda.py b/conda_build/bdist_conda.py deleted file mode 100644 index 45a1ff845e..0000000000 --- a/conda_build/bdist_conda.py +++ /dev/null @@ -1,298 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -import configparser -import sys -import time -from collections import defaultdict -from io import StringIO - -from conda.cli.common import spec_from_line -from setuptools.command.install import install -from setuptools.dist import Distribution -from setuptools.errors import BaseError, OptionError - -from . import api -from .build import handle_anaconda_upload -from .config import Config -from .deprecations import deprecated -from .metadata import MetaData -from .skeletons import pypi - -deprecated.module("24.3", "24.5") - - -class GetoptError(BaseError): - """The option table provided to 'fancy_getopt()' is bogus.""" - - -class CondaDistribution(Distribution): - """ - Distribution subclass that supports bdist_conda options - - This class is required if you want to pass any bdist_conda specific - options to setup(). To use, set distclass=CondaDistribution in setup(). - - Options that can be passed to setup() (must include - distclass=CondaDistribution): - - - conda_buildnum: The build number. Defaults to 0. Can be overridden on - the command line with the --buildnum flag. - - - conda_buildstr: The build string. Default is generated automatically - from the Python version, NumPy version if relevant, and the build - number, like py34_0. - - - conda_import_tests: Whether to automatically run import tests. The - default is True, which runs import tests for the all the modules in - "packages". Also allowed are False, which runs no tests, or a list of - module names to be tested on import. - - - conda_command_tests: Command line tests to run. Default is True, which - runs ``command --help`` for each ``command`` in the console_scripts and - gui_scripts entry_points. Also allowed are False, which doesn't run any - command tests, or a list of command tests to run. - - - conda_binary_relocation: Whether binary files should be made relocatable - (using install_name_tool on OS X or patchelf on Linux). The default is - True. See the "making packages relocatable" section in the conda build - documentation for more information on this. - - - conda_preserve_egg_dir: Whether to preserve the egg directory as - installed by setuptools. The default is True if the package depends on - setuptools or has a setuptools entry_points other than console_scripts - and gui_scripts. - - Command line options: - - --buildnum: Set the build number. Defaults to the conda_buildnum passed to - setup(), or 0. Overrides any conda_buildnum passed to setup(). - - """ - - # Unfortunately, there's no way to warn the users that they need to use - # distclass=CondaDistribution when they try to use a conda option to - # setup(). Distribution.__init__ will just print a warning when it sees an - # attr it doesn't recognize, and then it is discarded. - - # attr: default - conda_attrs = { - "conda_buildnum": 0, - "conda_buildstr": None, - "conda_import_tests": True, - "conda_command_tests": True, - "conda_binary_relocation": True, - "conda_preserve_egg_dir": None, - "conda_features": None, - "conda_track_features": None, - } - - def __init__(self, attrs=None): - given_attrs = {} - # We need to remove the attrs so that Distribution.__init__ doesn't - # warn about them. - if attrs: - for attr in self.conda_attrs: - if attr in attrs: - given_attrs[attr] = attrs.pop(attr) - - super().__init__(attrs) - - for attr in self.conda_attrs: - setattr(self.metadata, attr, given_attrs.get(attr, self.conda_attrs[attr])) - - -class bdist_conda(install): - description = "create a conda package" - config = Config( - build_id="bdist_conda" + "_" + str(int(time.time() * 1000)), build_is_host=True - ) - - def initialize_options(self): - super().initialize_options() - self.buildnum = None - self.anaconda_upload = False - - def finalize_options(self): - opt_dict = self.distribution.get_option_dict("install") - if self.prefix: - raise OptionError("--prefix is not allowed") - opt_dict["prefix"] = ("bdist_conda", self.config.host_prefix) - super().finalize_options() - - def run(self): - # Make sure the metadata has the conda attributes, even if the - # distclass isn't CondaDistribution. We primarily do this to simplify - # the code below. - - metadata = self.distribution.metadata - - for attr in CondaDistribution.conda_attrs: - if not hasattr(metadata, attr): - setattr(metadata, attr, CondaDistribution.conda_attrs[attr]) - - # The command line takes precedence - if self.buildnum is not None: - metadata.conda_buildnum = self.buildnum - - d = defaultdict(dict) - # PyPI allows uppercase letters but conda does not, so we fix the - # name here. - d["package"]["name"] = metadata.name.lower() - d["package"]["version"] = metadata.version - d["build"]["number"] = metadata.conda_buildnum - - # MetaData does the auto stuff if the build string is None - d["build"]["string"] = metadata.conda_buildstr - - d["build"]["binary_relocation"] = metadata.conda_binary_relocation - d["build"]["preserve_egg_dir"] = metadata.conda_preserve_egg_dir - d["build"]["features"] = metadata.conda_features - d["build"]["track_features"] = metadata.conda_track_features - - # XXX: I'm not really sure if it is correct to combine requires - # and install_requires - d["requirements"]["run"] = d["requirements"]["build"] = [ - spec_from_line(i) - for i in (metadata.requires or []) - + (getattr(self.distribution, "install_requires", []) or []) - ] + ["python"] - if hasattr(self.distribution, "tests_require"): - # A lot of packages use extras_require['test'], but - # tests_require is the one that is officially supported by - # setuptools. - d["test"]["requires"] = [ - spec_from_line(i) for i in self.distribution.tests_require or [] - ] - - d["about"]["home"] = metadata.url - # Don't worry about classifiers. This isn't skeleton pypi. We - # don't need to make this work with random stuff in the wild. If - # someone writes their setup.py wrong and this doesn't work, it's - # their fault. - d["about"]["license"] = metadata.license - d["about"]["summary"] = metadata.description - - # This is similar logic from conda skeleton pypi - entry_points = getattr(self.distribution, "entry_points", []) - if entry_points: - if isinstance(entry_points, str): - # makes sure it is left-shifted - newstr = "\n".join(x.strip() for x in entry_points.splitlines()) - c = configparser.ConfigParser() - entry_points = {} - try: - c.read_file(StringIO(newstr)) - except Exception as err: - # This seems to be the best error here - raise GetoptError( - "ERROR: entry-points not understood: " - + str(err) - + "\nThe string was" - + newstr - ) - else: - for section in c.sections(): - if section in ["console_scripts", "gui_scripts"]: - value = [ - f"{option}={c.get(section, option)}" - for option in c.options(section) - ] - entry_points[section] = value - else: - # Make sure setuptools is added as a dependency below - entry_points[section] = None - - if not isinstance(entry_points, dict): - raise GetoptError( - "ERROR: Could not add entry points. They were:\n" + entry_points - ) - else: - rs = entry_points.get("scripts", []) - cs = entry_points.get("console_scripts", []) - gs = entry_points.get("gui_scripts", []) - # We have *other* kinds of entry-points so we need - # setuptools at run-time - if not rs and not cs and not gs and len(entry_points) > 1: - d["requirements"]["run"].append("setuptools") - d["requirements"]["build"].append("setuptools") - entry_list = rs + cs + gs - if gs and self.config.platform == "osx": - d["build"]["osx_is_app"] = True - if len(cs + gs) != 0: - d["build"]["entry_points"] = entry_list - if metadata.conda_command_tests is True: - d["test"]["commands"] = list( - map(str, pypi.make_entry_tests(entry_list)) - ) - - if "setuptools" in d["requirements"]["run"]: - d["build"]["preserve_egg_dir"] = True - - if metadata.conda_import_tests: - if metadata.conda_import_tests is True: - d["test"]["imports"] = (self.distribution.packages or []) + ( - self.distribution.py_modules or [] - ) - else: - d["test"]["imports"] = metadata.conda_import_tests - - if metadata.conda_command_tests and not isinstance( - metadata.conda_command_tests, bool - ): - d["test"]["commands"] = list(map(str, metadata.conda_command_tests)) - - d = dict(d) - self.config.keep_old_work = True - m = MetaData.fromdict(d, config=self.config) - # Shouldn't fail, but do you really trust the code above? - m.check_fields() - m.config.set_build_id = False - m.config.variant["python"] = ".".join( - (str(sys.version_info.major), str(sys.version_info.minor)) - ) - api.build(m, build_only=True, notest=True) - self.config = m.config - # prevent changes in the build ID from here, so that we're working in the same prefix - # Do the install - super().run() - output = api.build(m, post=True, notest=True)[0] - api.test(output, config=m.config) - m.config.clean() - if self.anaconda_upload: - - class args: - anaconda_upload = self.anaconda_upload - - handle_anaconda_upload(output, args) - else: - no_upload_message = ( - """\ -# If you want to upload this package to anaconda.org later, type: -# -# $ anaconda upload %s -""" - % output - ) - print(no_upload_message) - - -# Distutils looks for user_options on the class (not instance). It also -# requires that it is an instance of list. So we do this here because we want -# to keep the options from the superclass (and because I don't feel like -# making a metaclass just to make this work). - -bdist_conda.user_options.extend( - [ - ( - "buildnum=", - None, - """The build number of - the conda package. Defaults to 0, or the conda_buildnum specified in the - setup() function. The command line flag overrides the option to - setup().""", - ), - ("anaconda-upload", None, ("""Upload the finished package to anaconda.org""")), - ] -) - -bdist_conda.boolean_options.extend(["anaconda-upload"]) diff --git a/conda_build/build.py b/conda_build/build.py index 531b38323f..f1bf8eec02 100644 --- a/conda_build/build.py +++ b/conda_build/build.py @@ -42,7 +42,6 @@ from . import environ, noarch_python, source, tarcheck, utils from .config import Config from .create_test import create_all_test_files -from .deprecations import deprecated from .exceptions import CondaBuildException, DependencyNeedsBuildingError from .index import _delegated_update_index, get_build_index from .metadata import FIELDS, MetaData @@ -184,121 +183,6 @@ def prefix_replacement_excluded(path): return False -@deprecated("24.3", "24.5") -def have_prefix_files(files, prefix): - """ - Yields files that contain the current prefix in them, and modifies them - to replace the prefix with a placeholder. - - :param files: Filenames to check for instances of prefix - :type files: list of tuples containing strings (prefix, mode, filename) - """ - - prefix_bytes = prefix.encode(utils.codec) - prefix_placeholder_bytes = PREFIX_PLACEHOLDER.encode(utils.codec) - searches = {prefix: prefix_bytes} - if utils.on_win: - # some windows libraries use unix-style path separators - forward_slash_prefix = prefix.replace("\\", "/") - forward_slash_prefix_bytes = forward_slash_prefix.encode(utils.codec) - searches[forward_slash_prefix] = forward_slash_prefix_bytes - # some windows libraries have double backslashes as escaping - double_backslash_prefix = prefix.replace("\\", "\\\\") - double_backslash_prefix_bytes = double_backslash_prefix.encode(utils.codec) - searches[double_backslash_prefix] = double_backslash_prefix_bytes - searches[PREFIX_PLACEHOLDER] = prefix_placeholder_bytes - min_prefix = min(len(k) for k, _ in searches.items()) - - # mm.find is incredibly slow, so ripgrep is used to pre-filter the list. - # Really, ripgrep could be used on its own with a bit more work though. - rg_matches = [] - prefix_len = len(prefix) + 1 - rg = external.find_executable("rg") - if rg: - for rep_prefix, _ in searches.items(): - try: - args = [ - rg, - "--unrestricted", - "--no-heading", - "--with-filename", - "--files-with-matches", - "--fixed-strings", - "--text", - rep_prefix, - prefix, - ] - matches = subprocess.check_output(args) - rg_matches.extend( - matches.decode("utf-8").replace("\r\n", "\n").splitlines() - ) - except subprocess.CalledProcessError: - continue - # HACK: this is basically os.path.relpath, just simpler and faster - # NOTE: path normalization needs to be in sync with create_info_files - if utils.on_win: - rg_matches = [ - rg_match.replace("\\", "/")[prefix_len:] for rg_match in rg_matches - ] - else: - rg_matches = [rg_match[prefix_len:] for rg_match in rg_matches] - else: - print( - "WARNING: Detecting which files contain PREFIX is slow, installing ripgrep makes it faster." - " 'conda install ripgrep'" - ) - - for f in files: - if os.path.isabs(f): - f = f[prefix_len:] - if rg_matches and f not in rg_matches: - continue - path = os.path.join(prefix, f) - if prefix_replacement_excluded(path): - continue - - # dont try to mmap an empty file, and no point checking files that are smaller - # than the smallest prefix. - if os.stat(path).st_size < min_prefix: - continue - - try: - fi = open(path, "rb+") - except OSError: - log = utils.get_logger(__name__) - log.warn("failed to open %s for detecting prefix. Skipping it." % f) - continue - try: - mm = utils.mmap_mmap( - fi.fileno(), 0, tagname=None, flags=utils.mmap_MAP_PRIVATE - ) - except OSError: - mm = fi.read() - - mode = "binary" if mm.find(b"\x00") != -1 else "text" - if mode == "text": - # TODO :: Ask why we do not do this on Windows too?! - if not utils.on_win and mm.find(prefix_bytes) != -1: - # Use the placeholder for maximal backwards compatibility, and - # to minimize the occurrences of usernames appearing in built - # packages. - data = mm[:] - mm.close() - fi.close() - rewrite_file_with_new_prefix( - path, data, prefix_bytes, prefix_placeholder_bytes - ) - fi = open(path, "rb+") - mm = utils.mmap_mmap( - fi.fileno(), 0, tagname=None, flags=utils.mmap_MAP_PRIVATE - ) - for rep_prefix, rep_prefix_bytes in searches.items(): - if mm.find(rep_prefix_bytes) != -1: - yield (rep_prefix, mode, f) - mm.close() - fi.close() - - # It may be that when using the list form of passing args to subprocess # what matters is the number of arguments rather than the accumulated # string length. In that case, len(l[i]) should become 1, and we should @@ -3734,8 +3618,7 @@ def build_tree( reset_build_id=not cfg.dirty, bypass_env_check=True, ) - # restrict to building only one variant for bdist_conda. The way it splits the build - # job breaks variants horribly. + if post in (True, False): metadata_tuples = metadata_tuples[:1] diff --git a/conda_build/conda_interface.py b/conda_build/conda_interface.py index c5acfbfd06..18056cc368 100644 --- a/conda_build/conda_interface.py +++ b/conda_build/conda_interface.py @@ -35,14 +35,12 @@ from conda.exceptions import UnsatisfiableError as _UnsatisfiableError from conda.exports import Completer as _Completer from conda.exports import InstalledPackages as _InstalledPackages -from conda.exports import get_index as _get_index from conda.exports import symlink_conda as _symlink_conda from conda.gateways.connection.download import TmpDownload as _TmpDownload from conda.gateways.connection.download import download as _download from conda.gateways.connection.session import CondaSession as _CondaSession from conda.gateways.disk.create import TemporaryDirectory as _TemporaryDirectory from conda.gateways.disk.link import lchmod as _lchmod -from conda.gateways.disk.read import compute_sum as _compute_sum from conda.misc import untracked as _untracked from conda.misc import walk_prefix as _walk_prefix from conda.models.channel import Channel as _Channel @@ -433,13 +431,6 @@ _get_conda_build_local_url, addendum="Use `conda.models.channel.get_conda_build_local_url` instead.", ) -deprecated.constant( - "24.1.0", - "24.5.0", - "get_index", - _get_index, - addendum="Use `conda.core.index.get_index` instead.", -) deprecated.constant( "24.5", "24.7", @@ -550,33 +541,6 @@ ) -@deprecated( - "24.3", - "24.5", - addendum="Handled by `conda.gateways.connection.session.CondaSession`.", -) -def handle_proxy_407(x, y): - pass - - -deprecated.constant( - "24.3", - "24.5", - "hashsum_file", - _compute_sum, - addendum="Use `conda.gateways.disk.read.compute_sum` instead.", -) - - -@deprecated( - "24.3", - "24.5", - addendum="Use `conda.gateways.disk.read.compute_sum(path, 'md5')` instead.", -) -def md5_file(path: str | _os.PathLike) -> str: - return _compute_sum(path, "md5") - - deprecated.constant( "24.5", "24.7", @@ -584,14 +548,3 @@ def md5_file(path: str | _os.PathLike) -> str: __version__, addendum="Use `conda.__version__` instead.", ) - - -@deprecated( - "24.3", - "24.5", - addendum="Use `conda_build.environ.get_version_from_git_tag` instead.", -) -def get_version_from_git_tag(tag): - from .environ import get_version_from_git_tag - - return get_version_from_git_tag(tag) diff --git a/conda_build/environ.py b/conda_build/environ.py index 5a24d83172..5aae94e682 100644 --- a/conda_build/environ.py +++ b/conda_build/environ.py @@ -3,7 +3,6 @@ from __future__ import annotations import contextlib -import json import logging import multiprocessing import os @@ -44,7 +43,6 @@ from conda.models.records import PackageRecord from . import utils -from .deprecations import deprecated from .exceptions import BuildLockError, DependencyNeedsBuildingError from .features import feature_list from .index import get_build_index @@ -73,9 +71,6 @@ class InstallActionsType(TypedDict): log = getLogger(__name__) -deprecated.constant("24.3", "24.5", "PREFIX_ACTION", _PREFIX_ACTION := "PREFIX") -deprecated.constant("24.3", "24.5", "LINK_ACTION", _LINK_ACTION := "LINK") - # these are things that we provide env vars for more explicitly. This list disables the # pass-through of variant values to env vars for these keys. LANGUAGES = ("PERL", "LUA", "R", "NUMPY", "PYTHON") @@ -819,71 +814,9 @@ def os_vars(m, prefix): return d -@deprecated("24.3", "24.5") -class InvalidEnvironment(Exception): - pass - - -# Stripped-down Environment class from conda-tools ( https://github.com/groutr/conda-tools ) -# Vendored here to avoid the whole dependency for just this bit. -@deprecated("24.3", "24.5") -def _load_json(path): - with open(path) as fin: - x = json.load(fin) - return x - - -@deprecated("24.3", "24.5") -def _load_all_json(path): - """ - Load all json files in a directory. Return dictionary with filenames mapped to json - dictionaries. - """ - root, _, files = next(utils.walk(path)) - result = {} - for f in files: - if f.endswith(".json"): - result[f] = _load_json(join(root, f)) - return result - - -@deprecated("24.3", "24.5", addendum="Use `conda.core.prefix_data.PrefixData` instead.") -class Environment: - def __init__(self, path): - """ - Initialize an Environment object. - - To reflect changes in the underlying environment, a new Environment object should be - created. - """ - self.path = path - self._meta = join(path, "conda-meta") - if os.path.isdir(path) and os.path.isdir(self._meta): - self._packages = {} - else: - raise InvalidEnvironment(f"Unable to load environment {path}") - - def _read_package_json(self): - if not self._packages: - self._packages = _load_all_json(self._meta) - - def package_specs(self): - """ - List all package specs in the environment. - """ - self._read_package_json() - json_objs = self._packages.values() - specs = [] - for i in json_objs: - p, v, b = i["name"], i["version"], i["build"] - specs.append(f"{p} {v} {b}") - return specs - - cached_precs: dict[ tuple[tuple[str | MatchSpec, ...], Any, Any, Any, bool], list[PackageRecord] ] = {} -deprecated.constant("24.3", "24.5", "cached_actions", cached_precs) last_index_ts = 0 @@ -1378,7 +1311,6 @@ def install_actions( del install_actions -@deprecated.argument("24.3", "24.5", "actions", rename="precs") def _execute_actions(prefix, precs): # This is copied over from https://github.com/conda/conda/blob/23.11.0/conda/plan.py#L575 # but reduced to only the functionality actually used within conda-build. @@ -1403,7 +1335,6 @@ def _execute_actions(prefix, precs): unlink_link_transaction.execute() -@deprecated.argument("24.3", "24.5", "actions", rename="precs") def _display_actions(prefix, precs): # This is copied over from https://github.com/conda/conda/blob/23.11.0/conda/plan.py#L58 # but reduced to only the functionality actually used within conda-build. diff --git a/conda_build/index.py b/conda_build/index.py index 28f29063aa..3a2f9ab10b 100644 --- a/conda_build/index.py +++ b/conda_build/index.py @@ -4,7 +4,6 @@ import logging import os import time -from concurrent.futures import Executor from functools import partial from os.path import dirname @@ -17,42 +16,20 @@ from . import utils from .deprecations import deprecated from .utils import ( - CONDA_PACKAGE_EXTENSION_V1, - CONDA_PACKAGE_EXTENSION_V2, JSONDecodeError, get_logger, - on_win, ) log = get_logger(__name__) -@deprecated("24.3", "24.5") -class DummyExecutor(Executor): - def map(self, func, *iterables): - for iterable in iterables: - for thing in iterable: - yield func(thing) - - local_index_timestamp = 0 cached_index = None local_subdir = "" local_output_folder = "" cached_channels = [] _channel_data = {} -deprecated.constant("24.1", "24.5", "channel_data", _channel_data) - - -# TODO: support for libarchive seems to have broken ability to use multiple threads here. -# The new conda format is so much faster that it more than makes up for it. However, it -# would be nice to fix this at some point. -_MAX_THREADS_DEFAULT = os.cpu_count() or 1 -if on_win: # see https://github.com/python/cpython/commit/8ea0fd85bc67438f679491fae29dfe0a3961900a - _MAX_THREADS_DEFAULT = min(48, _MAX_THREADS_DEFAULT) -deprecated.constant("24.3", "24.5", "MAX_THREADS_DEFAULT", _MAX_THREADS_DEFAULT) -deprecated.constant("24.3", "24.5", "LOCK_TIMEOUT_SECS", 3 * 3600) -deprecated.constant("24.3", "24.5", "LOCKFILE_NAME", ".lock") +deprecated.constant("24.1", "24.7", "channel_data", _channel_data) # TODO: this is to make sure that the index doesn't leak tokens. It breaks use of private channels, though. # os.environ['CONDA_ADD_ANACONDA_TOKEN'] = "false" @@ -251,54 +228,3 @@ def _delegated_update_index( current_index_versions=current_index_versions, debug=debug, ) - - -@deprecated( - "24.1.0", "24.5.0", addendum="Use `conda_index._apply_instructions` instead." -) -def _apply_instructions(subdir, repodata, instructions): - repodata.setdefault("removed", []) - utils.merge_or_update_dict( - repodata.get("packages", {}), - instructions.get("packages", {}), - merge=False, - add_missing_keys=False, - ) - # we could have totally separate instructions for .conda than .tar.bz2, but it's easier if we assume - # that a similarly-named .tar.bz2 file is the same content as .conda, and shares fixes - new_pkg_fixes = { - k.replace(CONDA_PACKAGE_EXTENSION_V1, CONDA_PACKAGE_EXTENSION_V2): v - for k, v in instructions.get("packages", {}).items() - } - - utils.merge_or_update_dict( - repodata.get("packages.conda", {}), - new_pkg_fixes, - merge=False, - add_missing_keys=False, - ) - utils.merge_or_update_dict( - repodata.get("packages.conda", {}), - instructions.get("packages.conda", {}), - merge=False, - add_missing_keys=False, - ) - - for fn in instructions.get("revoke", ()): - for key in ("packages", "packages.conda"): - if fn.endswith(CONDA_PACKAGE_EXTENSION_V1) and key == "packages.conda": - fn = fn.replace(CONDA_PACKAGE_EXTENSION_V1, CONDA_PACKAGE_EXTENSION_V2) - if fn in repodata[key]: - repodata[key][fn]["revoked"] = True - repodata[key][fn]["depends"].append("package_has_been_revoked") - - for fn in instructions.get("remove", ()): - for key in ("packages", "packages.conda"): - if fn.endswith(CONDA_PACKAGE_EXTENSION_V1) and key == "packages.conda": - fn = fn.replace(CONDA_PACKAGE_EXTENSION_V1, CONDA_PACKAGE_EXTENSION_V2) - popped = repodata[key].pop(fn, None) - if popped: - repodata["removed"].append(fn) - repodata["removed"].sort() - - return repodata diff --git a/docs/source/user-guide/recipes/build-without-recipe.rst b/docs/source/user-guide/recipes/build-without-recipe.rst deleted file mode 100644 index 51c465db4a..0000000000 --- a/docs/source/user-guide/recipes/build-without-recipe.rst +++ /dev/null @@ -1,157 +0,0 @@ -================================================= -Building a package without a recipe (bdist_conda) -================================================= - -You can use conda-build to build packages for Python to install -rather than conda by using ``setup.py bdist_conda``. This is a -quick way to build packages without using a recipe, but it has -limitations. The script is limited to the Python version used in -the build and it is not as reproducible as using a recipe. We -recommend using a recipe with conda-build. - -.. note:: - If you use Setuptools, you must first import Setuptools and - then import ``conda_build.bdist_conda``, because Setuptools - monkey patches ``distutils.dist.Distribution``. - -EXAMPLE: A minimal ``setup.py`` file using the setup options -``name`` and ``version``: - -.. code:: - - from setuptools import setup - import conda_build.bdist_conda - - setup( - name="foo", - version="1.0", - distclass=conda_build.bdist_conda.CondaDistribution, - conda_buildnum=1, - ) - - -Setup options -============= - -You can pass the following options to ``setup()``. You must -include ``distclass=conda_build.bdist_conda.CondaDistribution``. - -Build number ------------- - -The number of the build. Can be overridden on the command line -with the ``--buildnum`` flag. Defaults to ``0``. - -.. code:: - - conda_buildnum=1 - - -Build string ------------- - -The build string. Default is generated automatically from the -Python version, NumPy version---if relevant---and the build -number, such as ``py34_0``. - -.. code:: - - conda_buildstr=py34_0 - - -Import tests ------------- - -Whether to automatically run import tests. The default is -``True``, which runs import tests for all the modules in -``packages``. Also allowed are ``False``, which runs no tests, or -a list of module names to be tested on import. - -.. code:: - - conda_import_tests=False - - -Command line tests ------------------- - -Command line tests to run. Default is ``True``, which runs -``command --help`` for each command in the console_scripts and -gui_scripts entry_points. Also allowed are ``False``, which does -not run any command tests, or a list of command tests to run. - -.. code:: - - conda_command_tests=False - - -Binary files relocatable ------------------------- - -Whether binary files should be made relocatable, using -install_name_tool on macOS or patchelf on Linux. The default is -``True``. - -.. code:: - - conda_binary_relocation=False - -For more information, see :ref:`Making packages relocatable `. - - -Preserve egg directory ----------------------- - -Whether to preserve the egg directory as installed by Setuptools. -The default is ``True`` if the package depends on Setuptools or -has Setuptools entry_points other than console_scripts and -gui_scripts. - -.. code:: - - conda_preserve_egg_dir=False - - -Command line options -==================== - -Build number ------------- - -Set the build number. Defaults to the conda_buildnum passed -to ``setup()`` or ``0``. Overrides any conda_buildnum passed to -``setup()``. - -.. code:: - - --buildnum=1 - - -Notes -===== - -* You must install ``bdist_conda`` into a root conda environment, - as it imports ``conda`` and ``conda_build``. It is included as - part of the ``conda-build`` package. - -* All metadata is gathered from the standard metadata from the - ``setup()`` function. Metadata that are not directly supported - by ``setup()`` can be added using one of the options specified - above. - -* By default, import tests are run for each subpackage specified - by packages, and command line tests ``command --help`` are run - for each ``setuptools entry_points`` command. This is done to - ensure that the package is built correctly. You can disable or - change these using the ``conda_import_tests`` and - ``conda_command_tests`` options specified above. - -* The Python version used in the build must be the same as where - conda is installed, as ``bdist_conda`` uses ``conda-build``. - -* ``bdist_conda`` uses the metadata provided to the ``setup()`` - function. - -* If you want to pass any ``bdist_conda`` specific options to - ``setup()``, in ``setup()`` you must set - ``distclass=conda_build.bdist_conda.CondaDistribution``. diff --git a/docs/source/user-guide/recipes/index.rst b/docs/source/user-guide/recipes/index.rst index d482f27415..876b500396 100644 --- a/docs/source/user-guide/recipes/index.rst +++ b/docs/source/user-guide/recipes/index.rst @@ -8,6 +8,5 @@ conda-build recipes. .. toctree:: :maxdepth: 1 - build-without-recipe sample-recipes debugging diff --git a/news/5299-remove-deprecations b/news/5299-remove-deprecations new file mode 100644 index 0000000000..c78531ea4d --- /dev/null +++ b/news/5299-remove-deprecations @@ -0,0 +1,39 @@ +### Enhancements + +* + +### Bug fixes + +* + +### Deprecations + +* Postpone `conda_build.index.channel_data` deprecation. (#5299) +* Remove `conda_build.api.get_output_file_path`. Use `conda_build.api.get_output_file_paths` instead. (#5299) +* Remove `conda_build.bdist_conda`. (#5299) +* Remove `conda_build.build.have_prefix_files`. (#5299) +* Remove `conda_build.conda_interface.get_index`. Use `conda.core.index.get_index` instead. (#5299) +* Remove `conda_build.conda_interface.get_version_from_git_tag`. Use `conda_build.environ.get_version_from_git_tag` instead. (#5299) +* Remove `conda_build.conda_interface.handle_proxy_407`. Handled by `conda.gateways.connection.session.CondaSession`. (#5299) +* Remove `conda_build.conda_interface.hashsum_file`. Use `conda.gateways.disk.read.compute_sum` instead. (#5299) +* Remove `conda_build.conda_interface.md5_file`. Use `conda.gateways.disk.read.compute_sum(path, 'md5')` instead. (#5299) +* Remove `conda_build.environ._load_all_json`. (#5299) +* Remove `conda_build.environ._load_json`. (#5299) +* Remove `conda_build.environ.cached_actions`. (#5299) +* Remove `conda_build.environ.Environment`. Use `conda.core.prefix_data.PrefixData` instead. (#5299) +* Remove `conda_build.environ.InvalidEnvironment`. (#5299) +* Remove `conda_build.environ.LINK_ACTION`. (#5299) +* Remove `conda_build.environ.PREFIX_ACTION`. (#5299) +* Remove `conda_build.index._apply_instructions`. Use `conda_index._apply_instructions` instead. (#5299) +* Remove `conda_build.index.DummyExecutor`. (#5299) +* Remove `conda_build.index.LOCK_TIMEOUT_SECS`. (#5299) +* Remove `conda_build.index.LOCKFILE_NAME`. (#5299) +* Remove `conda_build.index.MAX_THREADS_DEFAULT`. (#5299) + +### Docs + +* + +### Other + +* diff --git a/pyproject.toml b/pyproject.toml index 334c119996..a8b907644a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,9 +53,6 @@ requires-python = ">=3.8" [project.entry-points.conda] conda-build = "conda_build.plugin" -[project.entry-points."distutils.commands"] -bdist_conda = "conda_build.bdist_conda:bdist_conda" - [project.scripts] conda-build = "conda_build.cli.main_build:execute" conda-convert = "conda_build.cli.main_convert:execute" diff --git a/recipe/meta.yaml b/recipe/meta.yaml index d1b6440118..33f8fe9125 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -64,8 +64,6 @@ test: requires: - setuptools - pip - files: - - test_bdist_conda_setup.py commands: - python -m pip check # subcommands @@ -91,8 +89,6 @@ test: - conda-render --help - conda-skeleton --help - conda-debug --help - # bdist_conda - - python test_bdist_conda_setup.py bdist_conda --help about: home: https://conda.org diff --git a/recipe/test_bdist_conda_setup.py b/recipe/test_bdist_conda_setup.py deleted file mode 100644 index c7b3d34abf..0000000000 --- a/recipe/test_bdist_conda_setup.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -from setuptools import setup - -import conda_build.bdist_conda - -setup( - name="package", - version="1.0.0", - distclass=conda_build.bdist_conda.CondaDistribution, -) diff --git a/tests/bdist-recipe/bin/test-script-setup.py b/tests/bdist-recipe/bin/test-script-setup.py deleted file mode 100644 index c515fb849e..0000000000 --- a/tests/bdist-recipe/bin/test-script-setup.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -import conda_build_test - -conda_build_test - -print("Test script setup.py") - -if __name__ == "__main__": - from conda_build_test import manual_entry - - manual_entry.main() diff --git a/tests/bdist-recipe/conda_build_test/__init__.py b/tests/bdist-recipe/conda_build_test/__init__.py deleted file mode 100644 index 1f22b11325..0000000000 --- a/tests/bdist-recipe/conda_build_test/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -""" -conda build test package -""" - -print("conda_build_test has been imported") diff --git a/tests/bdist-recipe/conda_build_test/empty.py b/tests/bdist-recipe/conda_build_test/empty.py deleted file mode 100644 index 3f48e8b789..0000000000 --- a/tests/bdist-recipe/conda_build_test/empty.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause diff --git a/tests/bdist-recipe/conda_build_test/manual_entry.py b/tests/bdist-recipe/conda_build_test/manual_entry.py deleted file mode 100644 index 1a63c8a8e9..0000000000 --- a/tests/bdist-recipe/conda_build_test/manual_entry.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -def main(): - import argparse - - # Just picks them up from `sys.argv`. - parser = argparse.ArgumentParser(description="Basic parser.") - parser.parse_args() - - print("Manual entry point") diff --git a/tests/bdist-recipe/setup.py b/tests/bdist-recipe/setup.py deleted file mode 100644 index 74982e5865..0000000000 --- a/tests/bdist-recipe/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2014 Anaconda, Inc -# SPDX-License-Identifier: BSD-3-Clause -from setuptools import setup - -import conda_build.bdist_conda - -setup( - name="conda-build-test-project", - version="1.0", - distclass=conda_build.bdist_conda.CondaDistribution, - conda_buildnum=1, - conda_features=[], - author="Continuum Analytics, Inc.", - url="https://github.com/conda/conda-build", - license="BSD", - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - ], - description="test package for testing conda-build", - packages=["conda_build_test"], - scripts=[ - "bin/test-script-setup.py", - ], -) diff --git a/tests/test_api_consistency.py b/tests/test_api_consistency.py index 9d88b60eee..9dac14351c 100644 --- a/tests/test_api_consistency.py +++ b/tests/test_api_consistency.py @@ -42,7 +42,7 @@ def test_api_output_yaml(): assert argspec.defaults == (None, False) -def test_api_get_output_file_path(): +def test_api_get_output_file_paths(): argspec = getargspec(api.get_output_file_paths) assert argspec.args == [ "recipe_path_or_metadata", diff --git a/tests/test_api_render.py b/tests/test_api_render.py index 293ca09815..0882de0df1 100644 --- a/tests/test_api_render.py +++ b/tests/test_api_render.py @@ -56,7 +56,7 @@ def test_render_yaml_output(testing_workdir, testing_config): assert "package:" in open(os.path.join(testing_workdir, "output.yaml")).read() -def test_get_output_file_path(testing_workdir, testing_metadata): +def test_get_output_file_paths(testing_workdir, testing_metadata): testing_metadata = render.finalize_metadata(testing_metadata) api.output_yaml(testing_metadata, "recipe/meta.yaml") @@ -68,21 +68,21 @@ def test_get_output_file_path(testing_workdir, testing_metadata): assert build_path == os.path.join( testing_metadata.config.croot, testing_metadata.config.host_subdir, - "test_get_output_file_path-1.0-1.tar.bz2", + "test_get_output_file_paths-1.0-1.tar.bz2", ) -def test_get_output_file_path_metadata_object(testing_metadata): +def test_get_output_file_paths_metadata_object(testing_metadata): testing_metadata.final = True build_path = api.get_output_file_paths(testing_metadata)[0] assert build_path == os.path.join( testing_metadata.config.croot, testing_metadata.config.host_subdir, - "test_get_output_file_path_metadata_object-1.0-1.tar.bz2", + "test_get_output_file_paths_metadata_object-1.0-1.tar.bz2", ) -def test_get_output_file_path_jinja2(testing_config): +def test_get_output_file_paths_jinja2(testing_config): # If this test does not raise, it's an indicator that the workdir is not # being cleaned as it should. recipe = os.path.join(metadata_dir, "source_git_jinja2") diff --git a/tests/test_build.py b/tests/test_build.py index fd6a3a8f67..839cce4b9e 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -14,31 +14,11 @@ from pathlib import Path import pytest -from conda.common.compat import on_win from conda_build import api, build from .utils import get_noarch_python_meta, metadata_dir -PREFIX_TESTS = {"normal": os.path.sep} -if on_win: - PREFIX_TESTS.update({"double_backslash": "\\\\", "forward_slash": "/"}) - - -def test_find_prefix_files(testing_workdir): - """ - Write test output that has the prefix to be found, then verify that the prefix finding - identified the correct number of files. - """ - # create text files to be replaced - files = [] - for style, replacement in PREFIX_TESTS.items(): - filename = Path(testing_workdir, f"{style}.txt") - filename.write_text(testing_workdir.replace(os.path.sep, replacement)) - files.append(str(filename)) - - assert len(list(build.have_prefix_files(files, testing_workdir))) == len(files) - def test_build_preserves_PATH(testing_config): metadata = api.render( diff --git a/tests/test_environ.py b/tests/test_environ.py index 327accaeea..f446420feb 100644 --- a/tests/test_environ.py +++ b/tests/test_environ.py @@ -1,14 +1,8 @@ # Copyright (C) 2014 Anaconda, Inc # SPDX-License-Identifier: BSD-3-Clause import os -import sys -import pytest -from conda.core.prefix_data import PrefixData -from packaging.version import parse - -import conda_build -from conda_build.environ import Environment, create_env +from conda_build.environ import create_env def test_environment_creation_preserves_PATH(testing_workdir, testing_config): @@ -21,17 +15,3 @@ def test_environment_creation_preserves_PATH(testing_workdir, testing_config): subdir=testing_config.build_subdir, ) assert os.environ["PATH"] == ref_path - - -def test_environment(): - """Asserting PrefixData can accomplish the same thing as Environment.""" - with pytest.warns( - PendingDeprecationWarning - if parse(conda_build.__version__) < parse("24.3") - else DeprecationWarning, - ): - assert (specs := Environment(sys.prefix).package_specs()) - assert specs == [ - f"{prec.name} {prec.version} {prec.build}" - for prec in PrefixData(sys.prefix).iter_records() - ]