conda-workspaces 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. conda_workspaces-0.1.0/.github/workflows/docs.yml +56 -0
  2. conda_workspaces-0.1.0/.github/workflows/release.yml +74 -0
  3. conda_workspaces-0.1.0/.github/workflows/tests.yml +70 -0
  4. conda_workspaces-0.1.0/.gitignore +62 -0
  5. conda_workspaces-0.1.0/AGENTS.md +148 -0
  6. conda_workspaces-0.1.0/CHANGELOG.md +25 -0
  7. conda_workspaces-0.1.0/CODE_OF_CONDUCT.md +126 -0
  8. conda_workspaces-0.1.0/CONTRIBUTING.md +98 -0
  9. conda_workspaces-0.1.0/DESIGN.md +290 -0
  10. conda_workspaces-0.1.0/LICENSE +28 -0
  11. conda_workspaces-0.1.0/PKG-INFO +144 -0
  12. conda_workspaces-0.1.0/README.md +121 -0
  13. conda_workspaces-0.1.0/conda.lock +2266 -0
  14. conda_workspaces-0.1.0/conda_workspaces/__init__.py +8 -0
  15. conda_workspaces-0.1.0/conda_workspaces/__main__.py +29 -0
  16. conda_workspaces-0.1.0/conda_workspaces/_version.py +34 -0
  17. conda_workspaces-0.1.0/conda_workspaces/cli/__init__.py +7 -0
  18. conda_workspaces-0.1.0/conda_workspaces/cli/activate.py +33 -0
  19. conda_workspaces-0.1.0/conda_workspaces/cli/add.py +91 -0
  20. conda_workspaces-0.1.0/conda_workspaces/cli/clean.py +52 -0
  21. conda_workspaces-0.1.0/conda_workspaces/cli/info.py +71 -0
  22. conda_workspaces-0.1.0/conda_workspaces/cli/init.py +114 -0
  23. conda_workspaces-0.1.0/conda_workspaces/cli/install.py +67 -0
  24. conda_workspaces-0.1.0/conda_workspaces/cli/list.py +55 -0
  25. conda_workspaces-0.1.0/conda_workspaces/cli/lock.py +43 -0
  26. conda_workspaces-0.1.0/conda_workspaces/cli/main.py +320 -0
  27. conda_workspaces-0.1.0/conda_workspaces/cli/remove.py +98 -0
  28. conda_workspaces-0.1.0/conda_workspaces/cli/run.py +64 -0
  29. conda_workspaces-0.1.0/conda_workspaces/cli/shell.py +46 -0
  30. conda_workspaces-0.1.0/conda_workspaces/context.py +87 -0
  31. conda_workspaces-0.1.0/conda_workspaces/env_export.py +94 -0
  32. conda_workspaces-0.1.0/conda_workspaces/env_spec.py +198 -0
  33. conda_workspaces-0.1.0/conda_workspaces/envs.py +209 -0
  34. conda_workspaces-0.1.0/conda_workspaces/exceptions.py +130 -0
  35. conda_workspaces-0.1.0/conda_workspaces/lockfile.py +222 -0
  36. conda_workspaces-0.1.0/conda_workspaces/models.py +235 -0
  37. conda_workspaces-0.1.0/conda_workspaces/parsers/__init__.py +99 -0
  38. conda_workspaces-0.1.0/conda_workspaces/parsers/base.py +42 -0
  39. conda_workspaces-0.1.0/conda_workspaces/parsers/pixi_toml.py +133 -0
  40. conda_workspaces-0.1.0/conda_workspaces/parsers/pyproject_toml.py +161 -0
  41. conda_workspaces-0.1.0/conda_workspaces/parsers/toml.py +145 -0
  42. conda_workspaces-0.1.0/conda_workspaces/plugin.py +68 -0
  43. conda_workspaces-0.1.0/conda_workspaces/resolver.py +119 -0
  44. conda_workspaces-0.1.0/docs/_static/css/custom.css +1 -0
  45. conda_workspaces-0.1.0/docs/changelog.md +2 -0
  46. conda_workspaces-0.1.0/docs/conf.py +57 -0
  47. conda_workspaces-0.1.0/docs/configuration.md +192 -0
  48. conda_workspaces-0.1.0/docs/features.md +210 -0
  49. conda_workspaces-0.1.0/docs/index.md +153 -0
  50. conda_workspaces-0.1.0/docs/motivation.md +99 -0
  51. conda_workspaces-0.1.0/docs/quickstart.md +169 -0
  52. conda_workspaces-0.1.0/docs/reference/api/context.md +9 -0
  53. conda_workspaces-0.1.0/docs/reference/api/environments.md +9 -0
  54. conda_workspaces-0.1.0/docs/reference/api/models.md +13 -0
  55. conda_workspaces-0.1.0/docs/reference/api/parsers.md +25 -0
  56. conda_workspaces-0.1.0/docs/reference/api/resolver.md +9 -0
  57. conda_workspaces-0.1.0/docs/reference/api.md +51 -0
  58. conda_workspaces-0.1.0/docs/reference/cli.md +10 -0
  59. conda_workspaces-0.1.0/docs/robots.txt +4 -0
  60. conda_workspaces-0.1.0/docs/tutorials/ci-pipeline.md +96 -0
  61. conda_workspaces-0.1.0/docs/tutorials/coming-from-pixi.md +93 -0
  62. conda_workspaces-0.1.0/docs/tutorials/first-project.md +119 -0
  63. conda_workspaces-0.1.0/docs/tutorials/index.md +37 -0
  64. conda_workspaces-0.1.0/pixi.lock +7325 -0
  65. conda_workspaces-0.1.0/pyproject.toml +134 -0
  66. conda_workspaces-0.1.0/schema/conda-toml-1.schema.json +340 -0
  67. conda_workspaces-0.1.0/tests/__init__.py +1 -0
  68. conda_workspaces-0.1.0/tests/cli/__init__.py +1 -0
  69. conda_workspaces-0.1.0/tests/cli/conftest.py +33 -0
  70. conda_workspaces-0.1.0/tests/cli/test_activate.py +62 -0
  71. conda_workspaces-0.1.0/tests/cli/test_add_remove.py +247 -0
  72. conda_workspaces-0.1.0/tests/cli/test_clean.py +127 -0
  73. conda_workspaces-0.1.0/tests/cli/test_info.py +114 -0
  74. conda_workspaces-0.1.0/tests/cli/test_init.py +173 -0
  75. conda_workspaces-0.1.0/tests/cli/test_install.py +223 -0
  76. conda_workspaces-0.1.0/tests/cli/test_list.py +83 -0
  77. conda_workspaces-0.1.0/tests/cli/test_lock.py +125 -0
  78. conda_workspaces-0.1.0/tests/cli/test_main.py +147 -0
  79. conda_workspaces-0.1.0/tests/cli/test_run.py +126 -0
  80. conda_workspaces-0.1.0/tests/cli/test_shell.py +130 -0
  81. conda_workspaces-0.1.0/tests/conftest.py +118 -0
  82. conda_workspaces-0.1.0/tests/parsers/__init__.py +1 -0
  83. conda_workspaces-0.1.0/tests/parsers/test_detection.py +129 -0
  84. conda_workspaces-0.1.0/tests/parsers/test_pixi_toml.py +246 -0
  85. conda_workspaces-0.1.0/tests/parsers/test_pyproject_toml.py +251 -0
  86. conda_workspaces-0.1.0/tests/parsers/test_toml.py +189 -0
  87. conda_workspaces-0.1.0/tests/test___main__.py +76 -0
  88. conda_workspaces-0.1.0/tests/test_context.py +138 -0
  89. conda_workspaces-0.1.0/tests/test_env_export.py +155 -0
  90. conda_workspaces-0.1.0/tests/test_env_spec.py +278 -0
  91. conda_workspaces-0.1.0/tests/test_envs.py +535 -0
  92. conda_workspaces-0.1.0/tests/test_exceptions.py +113 -0
  93. conda_workspaces-0.1.0/tests/test_lockfile.py +323 -0
  94. conda_workspaces-0.1.0/tests/test_models.py +257 -0
  95. conda_workspaces-0.1.0/tests/test_plugin.py +48 -0
  96. conda_workspaces-0.1.0/tests/test_resolver.py +181 -0
@@ -0,0 +1,56 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - ".github/workflows/docs.yml"
9
+ - "conda_workspaces/**"
10
+ - "docs/**"
11
+ - "pyproject.toml"
12
+ pull_request:
13
+ paths:
14
+ - ".github/workflows/docs.yml"
15
+ - "docs/**"
16
+ workflow_dispatch:
17
+
18
+ concurrency:
19
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
20
+ cancel-in-progress: true
21
+
22
+ jobs:
23
+ docs:
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27
+ with:
28
+ fetch-depth: 0
29
+ - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3
30
+ with:
31
+ environments: docs
32
+ - name: Build docs
33
+ run: pixi run -e docs docs
34
+ - name: Upload artifact
35
+ uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
36
+ with:
37
+ path: "docs/_build/dirhtml"
38
+
39
+ pages:
40
+ runs-on: ubuntu-latest
41
+ if: github.ref == 'refs/heads/main'
42
+ needs: [docs]
43
+
44
+ permissions:
45
+ contents: read
46
+ pages: write
47
+ id-token: write
48
+
49
+ environment:
50
+ name: github-pages
51
+ url: ${{ steps.deployment.outputs.page_url }}
52
+
53
+ steps:
54
+ - name: Deploy to GitHub Pages
55
+ id: deployment
56
+ uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
@@ -0,0 +1,74 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ build:
16
+ name: Build distribution
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
24
+ with:
25
+ python-version: "3.13"
26
+
27
+ - name: Build sdist and wheel
28
+ run: pipx run build
29
+
30
+ - name: Upload distributions
31
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
32
+ with:
33
+ name: dist
34
+ path: dist/
35
+
36
+ publish-pypi:
37
+ name: Publish to PyPI
38
+ runs-on: ubuntu-latest
39
+ needs: [build]
40
+ environment: pypi
41
+
42
+ permissions:
43
+ id-token: write
44
+
45
+ steps:
46
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
47
+ with:
48
+ name: dist
49
+ path: dist/
50
+
51
+ - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
52
+ with:
53
+ packages-dir: dist/
54
+
55
+ upload-release-assets:
56
+ name: Upload release assets
57
+ runs-on: ubuntu-latest
58
+ needs: [publish-pypi]
59
+
60
+ permissions:
61
+ contents: write
62
+
63
+ steps:
64
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
65
+ with:
66
+ name: dist
67
+ path: dist/
68
+
69
+ - name: Upload assets to GitHub Release
70
+ env:
71
+ GH_TOKEN: ${{ github.token }}
72
+ GH_REPO: ${{ github.repository }}
73
+ TAG_NAME: ${{ github.event.release.tag_name }}
74
+ run: gh release upload "$TAG_NAME" dist/* --repo "$GH_REPO"
@@ -0,0 +1,70 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - ".github/workflows/tests.yml"
9
+ - "conda_workspaces/**"
10
+ - "pixi.lock"
11
+ - "pyproject.toml"
12
+ - "tests/**"
13
+ pull_request:
14
+ branches:
15
+ - main
16
+ paths:
17
+ - ".github/workflows/tests.yml"
18
+ - "conda_workspaces/**"
19
+ - "pixi.lock"
20
+ - "pyproject.toml"
21
+ - "tests/**"
22
+
23
+ concurrency:
24
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
25
+ cancel-in-progress: true
26
+
27
+ jobs:
28
+ lint:
29
+ name: Lint
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
33
+ - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3
34
+ with:
35
+ environments: dev
36
+ - name: Lint
37
+ run: pixi run -e dev lint
38
+ - name: Format check
39
+ run: pixi run -e dev format-check
40
+
41
+ tests:
42
+ name: ${{ matrix.os }}, Python ${{ matrix.python-version }}
43
+ runs-on: ${{ matrix.os }}
44
+ strategy:
45
+ fail-fast: false
46
+ matrix:
47
+ os: [ubuntu-latest, macos-latest, windows-latest]
48
+ python-version: ["3.10", "3.13"]
49
+ include:
50
+ - os: ubuntu-latest
51
+ python-version: "3.11"
52
+ - os: ubuntu-latest
53
+ python-version: "3.12"
54
+ - os: ubuntu-latest
55
+ python-version: "3.14"
56
+ steps:
57
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
58
+ with:
59
+ fetch-depth: 0
60
+ - uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3
61
+ with:
62
+ environments: test
63
+ - name: Run tests
64
+ run: pixi run -e test test-cov
65
+ - name: Upload coverage
66
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
67
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
68
+ with:
69
+ name: coverage-report
70
+ path: htmlcov/
@@ -0,0 +1,62 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # Virtual environments
28
+ .venv/
29
+ venv/
30
+ ENV/
31
+
32
+ # pixi
33
+ .pixi/
34
+
35
+ # conda project-local envs
36
+ .conda/
37
+
38
+ # IDE
39
+ .idea/
40
+ .vscode/
41
+ *.swp
42
+ *.swo
43
+ *~
44
+
45
+ # Testing
46
+ .pytest_cache/
47
+ .coverage
48
+ htmlcov/
49
+
50
+ # Docs
51
+ docs/_build/
52
+
53
+ # OS
54
+ .DS_Store
55
+ Thumbs.db
56
+
57
+ # Type checking
58
+ .ty/
59
+ .mypy_cache/
60
+
61
+ # Version file (auto-generated)
62
+ conda_workspaces/_version.py
@@ -0,0 +1,148 @@
1
+ # AGENTS.md — conda-workspaces coding guidelines
2
+
3
+ ## Project structure
4
+
5
+ - CLI modules are separated by subcommand, mirroring conda's own CLI
6
+ layout. Each subcommand lives in its own module under
7
+ `conda_workspaces/cli/` (e.g., `init.py`, `install.py`, `list.py`,
8
+ `info.py`, `add.py`, `remove.py`, `clean.py`, `run.py`, `activate.py`).
9
+ `cli/main.py` contains parser configuration and dispatch;
10
+ `cli/__init__.py` is a thin re-export shim (`configure_parser`,
11
+ `execute`, `generate_parser`).
12
+
13
+ - Parser implementations use submodules, not subpackages. The canonical
14
+ format parsers live at `conda_workspaces/parsers/toml.py`,
15
+ `conda_workspaces/parsers/pixi_toml.py`, and
16
+ `conda_workspaces/parsers/pyproject_toml.py` — plain modules, not
17
+ directories with `__init__.py`. Only create a subpackage when there
18
+ are multiple files to group.
19
+
20
+ - Tests mirror the source structure. Tests for
21
+ `conda_workspaces/cli/install.py` live in `tests/cli/test_install.py`,
22
+ tests for `conda_workspaces/parsers/toml.py` live in
23
+ `tests/parsers/test_toml.py`, etc. Test module names match their
24
+ corresponding source module names.
25
+
26
+ ## Imports
27
+
28
+ - Use relative imports for all intra-package references
29
+ (`from .models import WorkspaceConfig`,
30
+ `from ..exceptions import CondaWorkspacesError`).
31
+ Absolute `conda_workspaces.*` imports should only appear in tests
32
+ and entry points.
33
+
34
+ - Inline (lazy) imports are reserved for performance-critical paths.
35
+ Acceptable cases: `plugin.py` hooks (loaded on every `conda`
36
+ invocation), `cli/main.py` subcommand dispatch (only the chosen
37
+ handler is loaded), `context.py` property methods (lazy by design),
38
+ and `parsers/toml.py` where `CondaTomlParser.parse()` delegates to
39
+ `PixiTomlParser` (breaks a real circular dependency since
40
+ `pixi_toml` imports helpers from `toml`). Everywhere else, imports
41
+ belong at the top of the module.
42
+
43
+ ## Dependencies
44
+
45
+ - Minimize the dependency graph. Prefer stdlib or already-required
46
+ packages over adding new ones. When a single library covers multiple
47
+ use cases (e.g., `tomlkit` for both reading and writing TOML), use
48
+ it instead of carrying separate read-only and read-write libraries.
49
+
50
+ - Pin minimum versions in `pyproject.toml` dependencies (e.g.,
51
+ `"tomlkit >=0.13"`), not exact versions.
52
+
53
+ ## Typing and linting
54
+
55
+ - All code must be typed using modern annotations (`str | None` not
56
+ `Optional[str]`, `list[str]` not `List[str]`). `ClassVar` from
57
+ `typing` is the correct annotation for class-level attributes — it
58
+ is not deprecated.
59
+
60
+ - Use `ty` for type checking and `ruff` for linting and formatting.
61
+ Both are configured in `pyproject.toml`.
62
+
63
+ - Use `from __future__ import annotations` in all modules.
64
+
65
+ ## Testing
66
+
67
+ - Tests are plain `pytest` functions — no `unittest.TestCase` or other class-based test grouping.
68
+ Do not group tests in classes; use module-level functions with descriptive names.
69
+
70
+ - Do not use section comments (e.g., `# --- Section ---`) to group tests.
71
+ Relay on function naming and module structure for organization.
72
+
73
+ - Use `pytest` native fixtures (`tmp_path`, `monkeypatch`, `capsys`)
74
+ instead of `unittest.mock`. Prefer `monkeypatch.setattr` with simple
75
+ fakes or recording closures over `MagicMock` / `patch`.
76
+
77
+ - Use `pytest.mark.parametrize` extensively. When multiple test cases
78
+ exercise the same logic with different inputs, consolidate them into
79
+ a single parameterized test.
80
+
81
+ - Shared fixtures belong in `conftest.py` at the appropriate level
82
+ (root `tests/conftest.py` for cross-cutting fixtures, subdirectory
83
+ `conftest.py` for module-specific ones).
84
+
85
+ - Coverage is measured with `pytest-cov`. Thresholds and exclusions are
86
+ configured in `pyproject.toml` under `[tool.coverage.*]`. Run
87
+ `pixi run -e <test-env> test-cov` to generate a coverage report.
88
+
89
+ ## Conda integration
90
+
91
+ - Follow standard conda CLI patterns: use `-n`/`--name` and
92
+ `-p`/`--prefix` for environment targeting, not custom flags like
93
+ `--environment`.
94
+
95
+ - Use conda's own APIs where available (e.g., `conda.base.constants`,
96
+ `conda.base.context.context`, `context.plugins.raw_data` for
97
+ `.condarc` settings) rather than reimplementing platform detection or
98
+ config parsing.
99
+
100
+ - The `add_output_and_prompt_options` helper from conda already
101
+ provides `--json`, `--dry-run`, `--yes`, `-v`, `-q`, `--debug`,
102
+ `--trace`, and `--console`. Do not add custom arguments that
103
+ duplicate these — it causes `ArgumentError: conflicting option
104
+ string` at runtime.
105
+
106
+ - The plugin registers via `pluggy` hooks (`conda_subcommands`) and
107
+ the `[project.entry-points.conda]` entry point.
108
+
109
+ ## Parser search order
110
+
111
+ - The parser registry searches for workspace manifests in this order:
112
+ 1. `conda.toml` — conda-native workspace manifest
113
+ 2. `pixi.toml` — pixi-native format (compatibility)
114
+ 3. `pyproject.toml` — embedded under `[tool.conda.*]`,
115
+ `[tool.conda-workspaces.*]` (legacy), or `[tool.pixi.*]`
116
+
117
+ - All parsers produce a `WorkspaceConfig` model, regardless of source
118
+ format. Parser-specific logic stays in the parser; downstream code
119
+ only depends on the model.
120
+
121
+ ## Documentation
122
+
123
+ - Docs use Sphinx with `conda-sphinx-theme`, `myst-parser`, and
124
+ `sphinx-design`.
125
+
126
+ - Follow the Diataxis framework: tutorials, how-to guides, reference,
127
+ and explanation sections.
128
+
129
+ - Key relationship with pixi must be documented prominently:
130
+ `conda-workspaces` reads pixi-compatible manifests but delegates
131
+ solving and environment management to conda's own infrastructure.
132
+ It does not replace pixi — it brings workspace management into the
133
+ conda CLI.
134
+
135
+ - Avoid excessive bold and italic in prose, list items, and headings.
136
+ Don't bold every list item or key term — let the text speak for
137
+ itself. In docstrings, use `*param*` for parameter names (standard
138
+ Sphinx convention) but avoid bold elsewhere.
139
+
140
+ - Keep `sphinx-design` tab labels short. Use "pixi.toml" / "TOML" /
141
+ "pyproject.toml" instead of verbose labels when the tab content
142
+ already identifies the format. This prevents tab overflow on narrow
143
+ viewports.
144
+
145
+ - The API reference is split into focused sub-pages by concern (models,
146
+ parsers, resolver, context, environments) rather than a single
147
+ monolithic page. The index uses `sphinx-design` grid cards for
148
+ navigation.
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to conda-workspaces will be documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## Unreleased
8
+
9
+ ## 0.1.0 — 2026-03-05
10
+
11
+ ### Added
12
+
13
+ - Initial implementation of conda-workspaces plugin
14
+ - `conda workspace` subcommand with `init`, `install`, `list`, `info`,
15
+ `add`, `remove`, `clean`, `run`, and `activate` subcommands
16
+ - `cw` standalone CLI shortcut
17
+ - Parser support for `pixi.toml`, `conda.toml`, and `pyproject.toml`
18
+ manifests
19
+ - Multi-environment workspace model with composable features
20
+ - Solve-group support for version coordination across environments
21
+ - Per-platform dependency overrides via `[target.<platform>]`
22
+ - PyPI dependency parsing (requires conda-pypi for installation)
23
+ - Project-local environments under `.conda/envs/`
24
+ - Sphinx documentation with conda-sphinx-theme
25
+ - PyPI release workflow with trusted publishing
@@ -0,0 +1,126 @@
1
+ # Conda Organization Code of Conduct
2
+
3
+ # The Short Version
4
+
5
+ Be kind to others. Do not insult or put down others. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for the conda Organization.
6
+
7
+ All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate.
8
+
9
+ The conda Organization is dedicated to providing a harassment-free community for everyone, regardless of gender, sexual orientation, gender identity and expression, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of community members in any form.
10
+
11
+ Thank you for helping make this a welcoming, friendly community for all.
12
+
13
+ ## Report an Incident
14
+
15
+ * Report a code of conduct incident [using a form](https://form.jotform.com/221527028480048).
16
+ * Report a code of conduct incident via email: [conduct@conda.org](mailto:conduct@conda.org).
17
+ * Contact [an individual committee member](#committee-membership) or [CoC event representative](#coc-representatives) to report an incident in confidence.
18
+
19
+ &nbsp;
20
+
21
+ And now the longer version...
22
+
23
+ # Conda Organization Diversity Statement
24
+
25
+ The conda Organization welcomes and encourages participation in our community by people of all backgrounds and identities. We are committed to promoting and sustaining a culture that values mutual respect, tolerance, and learning, and we work together as a community to help each other live out these values.
26
+
27
+ We have created this diversity statement because we believe that a diverse community is stronger, more vibrant, and produces better software and better science. A diverse community where people treat each other with respect has more potential contributors, more sources for ideas, and fewer shared assumptions that might hinder development or research.
28
+
29
+ Although we have phrased the formal diversity statement generically to make it all-inclusive, we recognize that there are specific identities that are impacted by systemic discrimination and marginalization. We welcome all people to participate in the conda Organization community regardless of their identity or background.
30
+
31
+ # Conda Organization Code of Conduct: Introduction & Scope
32
+
33
+ This code of conduct should be honored by everyone who participates in the conda Organization community. It should be honored in any conda Organization-related activities, by anyone claiming affiliation with the conda Organization, and especially when someone is representing the conda Organization in any role (including as an event volunteer or speaker).
34
+
35
+ This code of conduct applies to all spaces managed by the conda Organization, including all public and private mailing lists, issue trackers, wikis, forums, and any other communication channel used by our community. The code of conduct equally applies at conda Organization events and governs standards of behavior for attendees, speakers, volunteers, booth staff, and event sponsors.
36
+
37
+ This code is not exhaustive or complete. It serves to distill our understanding of a collaborative, inclusive community culture. Please try to follow this code in spirit as much as in letter, to create a friendly and productive environment that enriches the conda Organization community.
38
+
39
+ The conda Organization Code of Conduct follows below.
40
+
41
+ # Standards for Behavior
42
+
43
+ The conda Organization is a worldwide community. All communication should be appropriate for a professional audience including people of many different backgrounds.
44
+
45
+ **Please always be kind and courteous. There's never a need to be mean or rude or disrespectful.** Thank you for helping make this a welcoming, friendly community for all.
46
+
47
+ We strive to:
48
+
49
+ **Be empathetic, welcoming, friendly, and patient.** We remember that the conda Organization is crafted by human beings who deserve to be treated with kindness and empathy. We work together to resolve conflict and assume good intentions. We may all experience some frustration from time to time, but we do not allow frustration to turn into a personal attack. A community where people feel uncomfortable or threatened is not a productive one.
50
+
51
+ **Be collaborative.** Our work depends on the participation of many people, and in turn others depend on our work. Open source communities depend on effective and friendly collaboration to achieve their goals.
52
+
53
+ **Be inquisitive.** Nobody knows everything! Asking questions early avoids many problems later, so we encourage questions, although we may direct them to the appropriate forum. We will try hard to be responsive and helpful.
54
+
55
+ **Be careful in the words that we choose.** We are careful and respectful in our communication and we take responsibility for our own speech. Be kind to others. Do not insult or put down other members of the community.
56
+
57
+ ## Unacceptable Behavior
58
+
59
+ We are committed to making participation in this community a harassment-free experience.
60
+
61
+ We will not accept harassment or other exclusionary behaviors, such as:
62
+
63
+ - The use of sexualized language or imagery
64
+ - Excessive profanity (please avoid curse words; people differ greatly in their sensitivity to swearing)
65
+ - Posting sexually explicit or violent material
66
+ - Violent or intimidating threats or language directed against another person
67
+ - Inappropriate physical contact and/or unwelcome sexual attention or sexual comments
68
+ - Sexist, racist, or otherwise discriminatory jokes and language
69
+ - Trolling or insulting and derogatory comments
70
+ - Written or verbal comments which have the effect of excluding people on the basis of membership in a specific group, including level of experience, gender, gender identity and expression, sexual orientation, disability, neurotype, personal appearance, body size, race, ethnicity, age, religion, or nationality
71
+ - Public or private harassment
72
+ - Sharing private content, such as emails sent privately or non-publicly, or direct message history, without the sender's consent
73
+ - Continuing to initiate interaction (such as photography, recording, messaging, or conversation) with someone after being asked to stop
74
+ - Sustained disruption of talks, events, or communications, such as heckling of a speaker
75
+ - Publishing (or threatening to post) other people's personally identifying information ("doxing"), such as physical or electronic addresses, without explicit permission
76
+ - Other unethical or unprofessional conduct
77
+ - Advocating for, or encouraging, any of the above behaviors
78
+
79
+ The conda Organization prioritizes marginalized people's safety over privileged people's comfort. The conda CoC Committee reserves the right not to act on complaints including, but not limited to:
80
+
81
+ * 'Reverse' -isms, including 'reverse racism,' 'reverse sexism,' and 'cisphobia'.
82
+ * Reasonable communication of boundaries, such as "leave me alone," "go away," or "I'm not discussing this with you."
83
+ * Communicating in a 'tone' you don't find congenial.
84
+ * Criticizing racist, sexist, cissexist, or otherwise oppressive behavior or assumptions.
85
+
86
+ ## Behavior Outside of conda Organization Spaces
87
+
88
+ The CoC Committee does not influence behavior and membership in spaces outside the conda Organization. However, if you are being harassed by a member of the conda community outside our spaces, you may still report it to the CoC Committee. We will take all good-faith reports of harassment by conda community members seriously. This includes harassment outside our spaces and harassment that took place at any point in time.
89
+
90
+ The CoC Committee reserves the right to exclude people from conda Organization spaces based on their past behavior, including behavior outside conda Organization spaces and behavior towards people who are not in the conda community.
91
+
92
+ # Confidentiality and Public Statements to the Community
93
+
94
+ The CoC Committee will keep the identity of the reporter confidential.
95
+
96
+ Whenever possible, CoC cases will be reported to the community. The level of detail in reports will vary from case to case. Reports will describe at least the type of infraction that was reported, and the Committee's decision and any action taken. In most cases, the report will not include personally identifiable information.
97
+
98
+ # Reporting Guidelines
99
+
100
+ If you believe someone is violating the code of conduct, please report this in a timely manner. Code of conduct violations reduce the value of the community for everyone. The conda Code of Conduct (CoC) Committee and the conda Organization take reports of misconduct very seriously and are committed to preserving and maintaining the welcoming nature of our community.
101
+
102
+ All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The conda CoC Committee commits to maintaining confidentiality with regard to the reporter of an incident.
103
+
104
+ ## How to Submit a Report
105
+
106
+ You can report an incident:
107
+
108
+ * via the [Incident Reporting Form](https://form.jotform.com/221527028480048)
109
+ * via email: [conduct@conda.org](mailto:conduct@conda.org)
110
+ * contact [an individual committee member](#committee-membership) to report an incident in confidence.
111
+
112
+ ## Enforcement
113
+
114
+ The CoC Committee will review all reports and determine appropriate action. Potential consequences include:
115
+
116
+ - Nothing (if no violation occurred)
117
+ - Private feedback or reprimand
118
+ - Warning to cease the behavior
119
+ - Temporary or permanent ban from conda Organization spaces
120
+ - Other responses deemed necessary and appropriate
121
+
122
+ For the full details on enforcement, reporting, and committee membership, see the [conda Organization Code of Conduct](https://github.com/conda/conda/blob/main/CODE_OF_CONDUCT.md).
123
+
124
+ # License
125
+
126
+ This code of conduct is based on the [conda Organization Code of Conduct](https://github.com/conda/conda/blob/main/CODE_OF_CONDUCT.md), which is licensed under the [Creative Commons Attribution 3.0 Unported License](https://creativecommons.org/licenses/by/3.0/).
@@ -0,0 +1,98 @@
1
+ # Contributing to conda-workspaces
2
+
3
+ Thank you for your interest in improving conda-workspaces! This document
4
+ describes how to contribute to the project.
5
+
6
+ ## Code of Conduct
7
+
8
+ This project follows the [conda Organization Code of Conduct](CODE_OF_CONDUCT.md).
9
+ Please read it before participating.
10
+
11
+ ## Getting started
12
+
13
+ 1. Fork the repository on [GitHub](https://github.com/conda-incubator/conda-workspaces).
14
+ 2. Clone your fork locally.
15
+ 3. Install [pixi](https://pixi.sh) (used for development environments).
16
+ 4. Run the tests to make sure everything works:
17
+
18
+ ```bash
19
+ pixi run test
20
+ ```
21
+
22
+ ## Development setup
23
+
24
+ conda-workspaces uses pixi for development environment management. The
25
+ available tasks are defined in `pixi.toml`:
26
+
27
+ ```bash
28
+ pixi run test # run tests
29
+ pixi run test-cov # run tests with coverage
30
+ pixi run lint # run ruff linter
31
+ pixi run format # run ruff formatter
32
+ pixi run typecheck # run ty type checker
33
+ pixi run docs # build documentation
34
+ ```
35
+
36
+ ## Making changes
37
+
38
+ ### Branch workflow
39
+
40
+ 1. Create a new branch from `main` for your changes.
41
+ 2. Keep changes focused on a single issue or feature.
42
+ 3. Write tests for new functionality.
43
+ 4. Make sure all tests pass before submitting.
44
+
45
+ ### Code style
46
+
47
+ - All code must be typed using modern annotations (`str | None`, `list[str]`).
48
+ - Use `from __future__ import annotations` in all modules.
49
+ - Use relative imports for intra-package references.
50
+ - Run `pixi run lint` and `pixi run format` before committing.
51
+ - Run `pixi run typecheck` to verify type annotations.
52
+
53
+ ### Testing
54
+
55
+ - Tests are plain `pytest` functions — no `unittest.TestCase` classes.
56
+ - Use `pytest.mark.parametrize` for multiple test cases with the same logic.
57
+ - Use `monkeypatch` and native pytest fixtures instead of `unittest.mock`.
58
+ - Tests mirror the source structure (e.g., tests for
59
+ `conda_workspaces/cli/install.py` live in `tests/cli/test_install.py`).
60
+
61
+ ### Documentation
62
+
63
+ - Docs use Sphinx with MyST Markdown.
64
+ - Build locally with `pixi run docs`.
65
+ - Follow the [Diataxis framework](https://diataxis.fr/) for new content.
66
+
67
+ ## Submitting a pull request
68
+
69
+ 1. Push your branch to your fork.
70
+ 2. Open a pull request against `main`.
71
+ 3. Describe what your change does and why.
72
+ 4. Link any related issues.
73
+ 5. Make sure CI passes.
74
+
75
+ ## Conda Contributor License Agreement
76
+
77
+ To contribute to conda ecosystem projects, you need to sign the
78
+ [Conda Contributor License Agreement (CLA)](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement).
79
+
80
+ ## Generative AI
81
+
82
+ You're welcome to use generative AI tools when contributing. However:
83
+
84
+ - You are responsible for all of your contributions. Review and understand any
85
+ AI-generated content before including it in a pull request.
86
+ - Be prepared to discuss changes during review — do not paste AI responses
87
+ verbatim.
88
+ - Make minimal, focused changes that match the existing style and patterns.
89
+ - Ensure AI-assisted changes actually fix the underlying problem rather than
90
+ altering tests to make them pass.
91
+
92
+ Pull requests consisting of unchecked AI-generated content may be closed.
93
+
94
+ ## Getting help
95
+
96
+ - Open an [issue](https://github.com/conda-incubator/conda-workspaces/issues) for
97
+ bug reports or feature requests.
98
+ - Join the [conda community chat](https://conda.zulipchat.com) for questions.