caffeinated-whale-cli 2.3.1__tar.gz → 2.4.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 (90) hide show
  1. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/PKG-INFO +5 -1
  2. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/README.md +4 -0
  3. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/pyproject.toml +1 -1
  4. caffeinated_whale_cli-2.4.0/src/caffeinated_whale_cli/__init__.py +1 -0
  5. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/axi.py +8 -0
  6. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/init.py +11 -0
  7. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/init.py +46 -21
  8. caffeinated_whale_cli-2.3.1/src/caffeinated_whale_cli/__init__.py +0 -1
  9. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/LICENSE +0 -0
  10. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/setup.cfg +0 -0
  11. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/__init__.py +0 -0
  12. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/apps.py +0 -0
  13. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/backup.py +0 -0
  14. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/config.py +0 -0
  15. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/console.html +0 -0
  16. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/doctor.py +0 -0
  17. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/inspect.py +0 -0
  18. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/label.py +0 -0
  19. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/list.py +0 -0
  20. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/logs.py +0 -0
  21. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/open.py +0 -0
  22. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/restart.py +0 -0
  23. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/restore.py +0 -0
  24. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/rm.py +0 -0
  25. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/rm_site.py +0 -0
  26. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/run.py +0 -0
  27. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/scale.py +0 -0
  28. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/self_update.py +0 -0
  29. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/serve.py +0 -0
  30. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/start.py +0 -0
  31. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/status.py +0 -0
  32. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/stop.py +0 -0
  33. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/unlock.py +0 -0
  34. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/update.py +0 -0
  35. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/utils.py +0 -0
  36. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/commands/where.py +0 -0
  37. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/__init__.py +0 -0
  38. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/apps.py +0 -0
  39. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/auto_inspect.py +0 -0
  40. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/backup.py +0 -0
  41. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/bench_ops.py +0 -0
  42. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/config.py +0 -0
  43. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/credbridge.py +0 -0
  44. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/docker.py +0 -0
  45. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/doctor.py +0 -0
  46. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/envelope.py +0 -0
  47. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/errors.py +0 -0
  48. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/exec_stream.py +0 -0
  49. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/fleet.py +0 -0
  50. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/inspect.py +0 -0
  51. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/label.py +0 -0
  52. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/list.py +0 -0
  53. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/logs.py +0 -0
  54. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/open.py +0 -0
  55. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/resolvers.py +0 -0
  56. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/restart.py +0 -0
  57. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/restore.py +0 -0
  58. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/rm.py +0 -0
  59. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/rm_site.py +0 -0
  60. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/run.py +0 -0
  61. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/scale.py +0 -0
  62. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/start.py +0 -0
  63. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/status.py +0 -0
  64. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/stop.py +0 -0
  65. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/supervision.py +0 -0
  66. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/unlock.py +0 -0
  67. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/update.py +0 -0
  68. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/url.py +0 -0
  69. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/version.py +0 -0
  70. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/core/where.py +0 -0
  71. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/main.py +0 -0
  72. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/update_notice.py +0 -0
  73. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/__init__.py +0 -0
  74. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/agent_hooks.py +0 -0
  75. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/auto_inspect.py +0 -0
  76. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/bench_labels.py +0 -0
  77. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/bench_sites.py +0 -0
  78. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/cache.py +0 -0
  79. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/completion_utils.py +0 -0
  80. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/config_utils.py +0 -0
  81. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/console.py +0 -0
  82. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/db_utils.py +0 -0
  83. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/docker_utils.py +0 -0
  84. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/port_utils.py +0 -0
  85. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/sendme_utils.py +0 -0
  86. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/startup.py +0 -0
  87. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/tips.py +0 -0
  88. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/toon.py +0 -0
  89. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli/utils/vscode_utils.py +0 -0
  90. {caffeinated_whale_cli-2.3.1 → caffeinated_whale_cli-2.4.0}/src/caffeinated_whale_cli.egg-info/SOURCES.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: caffeinated-whale-cli
3
- Version: 2.3.1
3
+ Version: 2.4.0
4
4
  Summary: A CLI tool to help manage Frappe Docker instances.
5
5
  Author-email: Christopher McKay <mckay.christopher73@outlook.com>
6
6
  License: MIT
@@ -201,6 +201,7 @@ cwcli init [OPTIONS] [PROJECT_NAME]
201
201
  | `--bench-parent TEXT` | Directory inside container where bench is created (default: /workspace); also the container mount point for the persisted host `data/` directory, fixed for the life of the instance - changing it on a re-init errors, naming the mounted directory |
202
202
  | `--frappe-branch TEXT` | Frappe branch or tag for bench init, e.g. `version-16` or `v16.26.3` (default: version-16). Mutually exclusive with `--version` |
203
203
  | `--version TEXT` | Frappe version for bench init, resolved by shape: a bare major (`16` → `version-16` branch) or a full semantic version (`16.26.3` → `v16.26.3` tag). Malformed values are rejected with a non-zero exit. Mutually exclusive with `--frappe-branch` |
204
+ | `--frappe-url TEXT` | Custom Frappe repository URL to build from (a fork), passed to `bench init --frappe-path`. Omit to use the default `frappe/frappe` repo. Pair with `--frappe-branch` to check out the fork's branch. A private fork authenticates through the same credential bridge as `apps install`/`apps update` (host `gh`/`glab`, no token in the container); sign in on the host first |
204
205
  | `--db-root-password TEXT` | MariaDB root password (default: 123) |
205
206
  | `--admin-password TEXT` | Administrator password for the site, used verbatim. If omitted, a strong password is generated and printed once (interactive runs only); a non-interactive run must supply this flag |
206
207
  | `--install-erpnext` | Install ERPNext application after initialization |
@@ -271,6 +272,9 @@ cwcli init my-project --version 16
271
272
  # ...or a full semantic version -> vX.Y.Z tag
272
273
  cwcli init my-project --version 16.26.3
273
274
 
275
+ # Build from a Frappe fork, checking out its branch
276
+ cwcli init my-project --frappe-url https://github.com/me/frappe --frappe-branch my-feature
277
+
274
278
  # Full customization
275
279
  cwcli init my-project \
276
280
  --port 12000 \
@@ -161,6 +161,7 @@ cwcli init [OPTIONS] [PROJECT_NAME]
161
161
  | `--bench-parent TEXT` | Directory inside container where bench is created (default: /workspace); also the container mount point for the persisted host `data/` directory, fixed for the life of the instance - changing it on a re-init errors, naming the mounted directory |
162
162
  | `--frappe-branch TEXT` | Frappe branch or tag for bench init, e.g. `version-16` or `v16.26.3` (default: version-16). Mutually exclusive with `--version` |
163
163
  | `--version TEXT` | Frappe version for bench init, resolved by shape: a bare major (`16` → `version-16` branch) or a full semantic version (`16.26.3` → `v16.26.3` tag). Malformed values are rejected with a non-zero exit. Mutually exclusive with `--frappe-branch` |
164
+ | `--frappe-url TEXT` | Custom Frappe repository URL to build from (a fork), passed to `bench init --frappe-path`. Omit to use the default `frappe/frappe` repo. Pair with `--frappe-branch` to check out the fork's branch. A private fork authenticates through the same credential bridge as `apps install`/`apps update` (host `gh`/`glab`, no token in the container); sign in on the host first |
164
165
  | `--db-root-password TEXT` | MariaDB root password (default: 123) |
165
166
  | `--admin-password TEXT` | Administrator password for the site, used verbatim. If omitted, a strong password is generated and printed once (interactive runs only); a non-interactive run must supply this flag |
166
167
  | `--install-erpnext` | Install ERPNext application after initialization |
@@ -231,6 +232,9 @@ cwcli init my-project --version 16
231
232
  # ...or a full semantic version -> vX.Y.Z tag
232
233
  cwcli init my-project --version 16.26.3
233
234
 
235
+ # Build from a Frappe fork, checking out its branch
236
+ cwcli init my-project --frappe-url https://github.com/me/frappe --frappe-branch my-feature
237
+
234
238
  # Full customization
235
239
  cwcli init my-project \
236
240
  --port 12000 \
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "caffeinated-whale-cli"
7
- version = "2.3.1"
7
+ version = "2.4.0"
8
8
  authors = [
9
9
  { name = "Christopher McKay", email = "mckay.christopher73@outlook.com" },
10
10
  ]
@@ -0,0 +1 @@
1
+ __version__ = "2.4.0"
@@ -2157,6 +2157,13 @@ def axi_init(
2157
2157
  help="Frappe version resolved by shape: a bare major (16 -> version-16) or a full "
2158
2158
  "semantic version (16.26.3 -> v16.26.3). Mutually exclusive with --frappe-branch.",
2159
2159
  ),
2160
+ frappe_url: str = typer.Option(
2161
+ None,
2162
+ "--frappe-url",
2163
+ help="Custom Frappe repository URL to build from (a fork), passed to 'bench init "
2164
+ "--frappe-path'. Omit for the default frappe/frappe repo. Pair with --frappe-branch "
2165
+ "to check out the fork's branch.",
2166
+ ),
2160
2167
  db_root_password: str = typer.Option(
2161
2168
  None,
2162
2169
  "--db-root-password",
@@ -2283,6 +2290,7 @@ def axi_init(
2283
2290
  site_name=site,
2284
2291
  bench_parent=bench_parent,
2285
2292
  frappe_ref=frappe_ref,
2293
+ frappe_url=frappe_url,
2286
2294
  db_root_password=db_root,
2287
2295
  admin_password=resolved_admin,
2288
2296
  reuse_bench=reuse_bench,
@@ -487,6 +487,15 @@ def init(
487
487
  "(16.26.3 -> v16.26.3 tag). Mutually exclusive with --frappe-branch."
488
488
  ),
489
489
  ),
490
+ frappe_url: str | None = typer.Option(
491
+ None,
492
+ "--frappe-url",
493
+ help=(
494
+ "Custom Frappe repository URL to build from (a fork), passed to "
495
+ "'bench init --frappe-path'. Omit to use the default frappe/frappe repo. "
496
+ "Pair with --frappe-branch to check out the fork's branch."
497
+ ),
498
+ ),
490
499
  db_root_password: str = typer.Option(
491
500
  "123",
492
501
  "--db-root-password",
@@ -562,6 +571,7 @@ def init(
562
571
  cwcli init my-project --version 16 --install-erpnext
563
572
  cwcli init my-project --version 16.26.3
564
573
  cwcli init my-project --frappe-branch version-16 --admin-password mypass
574
+ cwcli init my-project --frappe-url https://github.com/me/frappe --frappe-branch my-feature
565
575
  """
566
576
  # Resolve the Frappe git ref first so a malformed --version fails fast,
567
577
  # before any project dir / container work.
@@ -644,6 +654,7 @@ def init(
644
654
  site_name=site,
645
655
  bench_parent=bench_parent,
646
656
  frappe_ref=frappe_branch,
657
+ frappe_url=frappe_url,
647
658
  db_root_password=db_root_password,
648
659
  admin_password=admin_password,
649
660
  reuse_bench=reuse_answer,
@@ -30,6 +30,7 @@ value the old path did not print.
30
30
 
31
31
  from __future__ import annotations
32
32
 
33
+ import contextlib
33
34
  import json
34
35
  import re
35
36
  import shlex
@@ -42,8 +43,8 @@ from pathlib import Path
42
43
 
43
44
  from ..utils import config_utils, db_utils
44
45
  from ..utils.port_utils import check_ports_in_use, format_port_list
46
+ from . import credbridge, resolvers
45
47
  from . import docker as core_docker
46
- from . import resolvers
47
48
  from .envelope import Choice, Message, Result, Status
48
49
  from .errors import CwcliError, ErrorKind
49
50
  from .exec_stream import ExecChunk, ExecDone, exec_stream
@@ -866,6 +867,7 @@ def init_bench(
866
867
  site_name: str,
867
868
  bench_parent: str = "/workspace",
868
869
  frappe_ref: str = DEFAULT_FRAPPE_BRANCH,
870
+ frappe_url: str | None = None,
869
871
  db_root_password: str = "123",
870
872
  admin_password: str,
871
873
  reuse_bench: bool | None = None,
@@ -887,6 +889,16 @@ def init_bench(
887
889
  it mirrors - the downloaded compose's hardcoded ``MYSQL_ROOT_PASSWORD:
888
890
  123`` - lives in the compose file the core itself downloads; it is
889
891
  shielded off the argv/echo, not randomized.
892
+
893
+ ``frappe_url`` is the optional custom Frappe repository (a fork) passed
894
+ through to ``bench init --frappe-path``; ``None`` (the default) builds from
895
+ the upstream ``frappe/frappe`` repo exactly as before. ``frappe_ref`` is the
896
+ branch/tag within that repo, so a fork tracking a custom branch pairs the two
897
+ (``frappe_url=<fork>``, ``frappe_ref=<branch>``). When ``frappe_url`` is a
898
+ PRIVATE fork, the ``bench init`` clone is wrapped in the same
899
+ :func:`core.credbridge.credential_bridge` context ``apps`` install/update
900
+ use, so it authenticates through the host's ``gh``/``glab`` with no token
901
+ ever entering the container.
890
902
  """
891
903
  emit = on_event or _noop
892
904
  warnings: list[Message] = []
@@ -1041,31 +1053,44 @@ def init_bench(
1041
1053
  else:
1042
1054
  emit(InitTrace(text="yarn installed successfully."))
1043
1055
 
1056
+ bench_init_args = [
1057
+ "bench",
1058
+ "init",
1059
+ "--skip-redis-config-generation",
1060
+ "--frappe-branch",
1061
+ shlex.quote(frappe_ref),
1062
+ ]
1063
+ # A custom Frappe repo (a fork) rides bench's own --frappe-path; frappe_ref
1064
+ # above is the branch/tag to check out within it. Omitted -> upstream repo.
1065
+ if frappe_url:
1066
+ bench_init_args += ["--frappe-path", shlex.quote(frappe_url)]
1067
+ bench_init_args += [shlex.quote(bench_name), "--verbose"]
1044
1068
  bench_init_cmd = _build_cd_command(
1045
- bench_parent_path,
1046
- nvm_prefix
1047
- + env_prefix
1048
- + " ".join(
1049
- [
1050
- "bench",
1051
- "init",
1052
- "--skip-redis-config-generation",
1053
- "--frappe-branch",
1054
- shlex.quote(frappe_ref),
1055
- shlex.quote(bench_name),
1056
- "--verbose",
1057
- ]
1058
- ),
1069
+ bench_parent_path, nvm_prefix + env_prefix + " ".join(bench_init_args)
1059
1070
  )
1060
1071
 
1061
1072
  emit(InitStepStart(phase="bench_init", item=bench_name))
1062
- _run_exec(
1063
- frappe_container,
1064
- bench_init_cmd,
1065
- phase="bench_init",
1066
- emit=emit,
1067
- collect=not stream_output,
1073
+ # A custom Frappe fork may be a PRIVATE repo, so bridge the container's
1074
+ # git back to the host's gh/glab for the clone `bench init` performs -
1075
+ # the same context apps install/update wrap their get-app fetch in
1076
+ # (see core.credbridge). The upstream default (frappe_url is None) is the
1077
+ # public frappe/frappe repo and needs no bridge, so that common path is
1078
+ # left untouched; the bridge is inert for a public fork too (git only
1079
+ # calls a credential helper on a 401). bench_full_path is under the
1080
+ # workspace mount, which is what credbridge resolves against.
1081
+ bridge: contextlib.AbstractContextManager[None] = (
1082
+ credbridge.credential_bridge(frappe_container, bench_full_path)
1083
+ if frappe_url
1084
+ else contextlib.nullcontext()
1068
1085
  )
1086
+ with bridge:
1087
+ _run_exec(
1088
+ frappe_container,
1089
+ bench_init_cmd,
1090
+ phase="bench_init",
1091
+ emit=emit,
1092
+ collect=not stream_output,
1093
+ )
1069
1094
  emit(InitStepEnd(phase="bench_init"))
1070
1095
  bench_created = True
1071
1096
 
@@ -1 +0,0 @@
1
- __version__ = "2.3.1"