-
-
Couldn't load subscription status.
- Fork 348
Workspace Support #2073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Workspace Support #2073
Changes from 41 commits
eef04fe
0058046
9fc0f41
c0152b2
4dc4339
203b30e
ef09d2a
9079b2a
83b119d
74d0daa
4260722
f448239
9c7a880
9d83042
0a4b9af
6215222
00f6c98
6f07123
e089124
49640c1
2e82dc2
1251148
405a31b
29d8169
53f0a70
ecb2bad
a81b13e
6d3bd15
c76dcd5
5146231
ba36be5
98cd0e6
91e117c
176faee
7c48bf9
8be9965
fa5272a
2ebe183
88138e5
8416d4a
da10a4f
9a54b4d
af09e9a
8261fce
aaa232c
56e809b
89d105e
5502734
1a5d7ae
f55f61a
a136f72
718be5e
b140f13
36570a8
07b4b90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,3 +17,4 @@ | |
| - Olga Matoula [:material-github:](https://github.com/olgarithms) [:material-twitter:](https://twitter.com/olgarithms_) | ||
| - Philip Blair [:material-email:](mailto:[email protected]) | ||
| - Robert Rosca [:material-github:](https://github.com/robertrosca) | ||
| - Cary Hawkins [:material-github](https://github.com/cjames23) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,38 @@ | |
| from hatch.utils.fs import Path | ||
|
|
||
|
|
||
| def find_workspace_root(path: Path) -> Path | None: | ||
| """Find workspace root by traversing up from given path.""" | ||
| from hatch.utils.toml import load_toml_file | ||
|
|
||
| current = path | ||
| while current.parent != current: | ||
| # Check hatch.toml first | ||
| hatch_toml = current / "hatch.toml" | ||
| if hatch_toml.exists() and _has_workspace_config(load_toml_file, str(hatch_toml), "workspace"): | ||
cjames23 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return current | ||
|
|
||
| # Then check pyproject.toml | ||
| pyproject = current / "pyproject.toml" | ||
| if pyproject.exists() and _has_workspace_config(load_toml_file, str(pyproject), "tool.hatch.workspace"): | ||
|
||
| return current | ||
|
|
||
| current = current.parent | ||
| return None | ||
|
|
||
|
|
||
| def _has_workspace_config(load_func, file_path: str, config_path: str) -> bool: | ||
| """Check if file has workspace configuration, returning False on any error.""" | ||
| try: | ||
| config = load_func(file_path) | ||
| if config_path == "workspace": | ||
| return bool(config.get("workspace")) | ||
| # "tool.hatch.workspace" | ||
| return bool(config.get("tool", {}).get("hatch", {}).get("workspace")) | ||
| except (OSError, ValueError, TypeError, KeyError): | ||
| return False | ||
|
|
||
|
|
||
| @click.group( | ||
| context_settings={"help_option_names": ["-h", "--help"], "max_content_width": 120}, invoke_without_command=True | ||
| ) | ||
|
|
@@ -170,8 +202,20 @@ def hatch(ctx: click.Context, env_name, project, verbose, quiet, color, interact | |
| app.project.set_app(app) | ||
| return | ||
|
|
||
| app.project = Project(Path.cwd()) | ||
| app.project.set_app(app) | ||
| # Discover workspace-aware project | ||
| workspace_root = find_workspace_root(Path.cwd()) | ||
| if workspace_root: | ||
| # Create project from workspace root with workspace context | ||
| app.project = Project(workspace_root, locate=False) | ||
| app.project.set_app(app) | ||
| # Set current member context if we're in a member directory | ||
| current_dir = Path.cwd() | ||
| if current_dir != workspace_root: | ||
| app.project.current_member_path = current_dir | ||
| else: | ||
| # No workspace, use current directory as before | ||
| app.project = Project(Path.cwd()) | ||
| app.project.set_app(app) | ||
|
|
||
| if app.config.mode == "local": | ||
| return | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from functools import cached_property | ||
|
|
||
| from packaging.requirements import InvalidRequirement, Requirement | ||
|
|
||
| from hatch.utils.fs import Path | ||
|
|
||
| InvalidDependencyError = InvalidRequirement | ||
|
|
||
|
|
||
| class Dependency(Requirement): | ||
| def __init__(self, s: str, *, editable: bool = False) -> None: | ||
| super().__init__(s) | ||
|
|
||
| if editable and self.url is None: | ||
| message = f"Editable dependency must refer to a local path: {s}" | ||
| raise InvalidDependencyError(message) | ||
|
|
||
| self.__editable = editable | ||
|
|
||
| @property | ||
| def editable(self) -> bool: | ||
| return self.__editable | ||
|
|
||
| @cached_property | ||
| def path(self) -> Path | None: | ||
| if self.url is None: | ||
| return None | ||
|
|
||
| import hyperlink | ||
|
|
||
| uri = hyperlink.parse(self.url) | ||
| if uri.scheme != "file": | ||
| return None | ||
|
|
||
| return Path.from_uri(self.url) |
Uh oh!
There was an error while loading. Please reload this page.