|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import dataclasses |
3 | 4 | import logging
|
4 | 5 | import re
|
5 | 6 | import warnings
|
@@ -119,21 +120,73 @@ def _get_version(
|
119 | 120 | return version_string
|
120 | 121 |
|
121 | 122 |
|
| 123 | +def _find_scm_in_parents(config: Configuration) -> Path | None: |
| 124 | + """ |
| 125 | + Search parent directories for SCM repositories when relative_to is not set. |
| 126 | + Uses the existing entrypoint system for SCM discovery. |
| 127 | + """ |
| 128 | + if config.search_parent_directories: |
| 129 | + return None |
| 130 | + |
| 131 | + searching_config = dataclasses.replace(config, search_parent_directories=True) |
| 132 | + |
| 133 | + from .discover import iter_matching_entrypoints |
| 134 | + |
| 135 | + for _ep in iter_matching_entrypoints( |
| 136 | + config.absolute_root, "setuptools_scm.parse_scm", searching_config |
| 137 | + ): |
| 138 | + # xxx: iter_matching_entrypoints should return the parent directory, we do a hack atm |
| 139 | + assert searching_config.parent is not None |
| 140 | + return Path(searching_config.parent) |
| 141 | + |
| 142 | + return None |
| 143 | + |
| 144 | + |
122 | 145 | def _version_missing(config: Configuration) -> NoReturn:
|
123 |
| - raise LookupError( |
| 146 | + base_error = ( |
124 | 147 | f"setuptools-scm was unable to detect version for {config.absolute_root}.\n\n"
|
125 |
| - "Make sure you're either building from a fully intact git repository " |
126 |
| - "or PyPI tarballs. Most other sources (such as GitHub's tarballs, a " |
127 |
| - "git checkout without the .git folder) don't contain the necessary " |
128 |
| - "metadata and will not work.\n\n" |
129 |
| - "For example, if you're using pip, instead of " |
130 |
| - "https://github.com/user/proj/archive/master.zip " |
131 |
| - "use git+https://github.com/user/proj.git#egg=proj\n\n" |
132 |
| - "Alternatively, set the version with the environment variable " |
133 |
| - "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_${NORMALIZED_DIST_NAME} as described " |
134 |
| - "in https://setuptools-scm.readthedocs.io/en/latest/config." |
135 | 148 | )
|
136 | 149 |
|
| 150 | + # If relative_to is not set, check for SCM repositories in parent directories |
| 151 | + scm_parent = None |
| 152 | + if config.relative_to is None: |
| 153 | + scm_parent = _find_scm_in_parents(config) |
| 154 | + |
| 155 | + if scm_parent is not None: |
| 156 | + # Found an SCM repository in a parent directory |
| 157 | + error_msg = ( |
| 158 | + base_error |
| 159 | + + f"However, a repository was found in a parent directory: {scm_parent}\n\n" |
| 160 | + f"To fix this, you have a few options:\n\n" |
| 161 | + f"1. Use the 'relative_to' parameter to specify the file that setuptools-scm should use as reference:\n" |
| 162 | + f" setuptools_scm.get_version(relative_to=__file__)\n\n" |
| 163 | + f"2. Enable parent directory search in your configuration:\n" |
| 164 | + f" [tool.setuptools_scm]\n" |
| 165 | + f" search_parent_directories = true\n\n" |
| 166 | + f"3. Change your working directory to the repository root: {scm_parent}\n\n" |
| 167 | + f"4. Set the root explicitly in your configuration:\n" |
| 168 | + f" [tool.setuptools_scm]\n" |
| 169 | + f' root = "{scm_parent}"\n\n' |
| 170 | + "For more information, see: https://setuptools-scm.readthedocs.io/en/latest/config/" |
| 171 | + ) |
| 172 | + else: |
| 173 | + # No SCM repository found in parent directories either |
| 174 | + error_msg = ( |
| 175 | + base_error |
| 176 | + + "Make sure you're either building from a fully intact git repository " |
| 177 | + "or PyPI tarballs. Most other sources (such as GitHub's tarballs, a " |
| 178 | + "git checkout without the .git folder) don't contain the necessary " |
| 179 | + "metadata and will not work.\n\n" |
| 180 | + "For example, if you're using pip, instead of " |
| 181 | + "https://github.com/user/proj/archive/master.zip " |
| 182 | + "use git+https://github.com/user/proj.git#egg=proj\n\n" |
| 183 | + "Alternatively, set the version with the environment variable " |
| 184 | + "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_${NORMALIZED_DIST_NAME} as described " |
| 185 | + "in https://setuptools-scm.readthedocs.io/en/latest/config/" |
| 186 | + ) |
| 187 | + |
| 188 | + raise LookupError(error_msg) |
| 189 | + |
137 | 190 |
|
138 | 191 | def get_version(
|
139 | 192 | root: _t.PathT = ".",
|
|
0 commit comments