common-python-tasks 0.6.0__py3-none-any.whl → 0.7.0__py3-none-any.whl

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.
@@ -5,16 +5,15 @@ prepend_sys_path = .
5
5
  output_encoding = utf-8
6
6
 
7
7
  [post_write_hooks]
8
- hooks = black,isort
8
+ hooks = ruff_check,ruff_format
9
9
 
10
- black.type = console_scripts
11
- black.entrypoint = black
10
+ ruff_check.type = exec
11
+ ruff_check.executable = ruff
12
+ ruff_check.options = check --fix-only --select F401,I REVISION_SCRIPT_FILENAME
12
13
 
13
- autoflake.type = console_scripts
14
- autoflake.entrypoint = autoflake
15
-
16
- isort.type = console_scripts
17
- isort.entrypoint = isort
14
+ ruff_format.type = exec
15
+ ruff_format.executable = ruff
16
+ ruff_format.options = format REVISION_SCRIPT_FILENAME
18
17
 
19
18
  # Logging configuration
20
19
  [loggers]
@@ -0,0 +1,6 @@
1
+ line-length = 88
2
+ extend-exclude = [".dist", ".poetry", "build"]
3
+
4
+ [lint]
5
+ select = ["E4", "E7", "E9", "F", "I", "W"]
6
+ ignore = ["W191"]
@@ -185,7 +185,7 @@ def infer_bump_component_from_git_cliff() -> ReleaseComponent:
185
185
  try:
186
186
  current = Version.parse(current_version)
187
187
  except Exception:
188
- utils.fatal("Unable to parse current project version: " f"{current_version!r}")
188
+ utils.fatal(f"Unable to parse current project version: {current_version!r}")
189
189
 
190
190
  def _parse_semver(version_value: str | Any) -> tuple[int, int, int]:
191
191
  if not isinstance(version_value, str):
@@ -434,7 +434,7 @@ def publish_github_release(
434
434
  release_name = release_name or tag_name
435
435
  release_body = body if body is not None else _changelog()
436
436
  if release_body is not None and _is_unreleased_placeholder(release_body):
437
- LOGGER.info(
437
+ LOGGER.debug(
438
438
  "git-cliff returned an unreleased placeholder; using latest tagged release notes instead"
439
439
  )
440
440
  release_body = _latest_tagged_changelog()
@@ -10,7 +10,7 @@ from importlib import metadata
10
10
  from pathlib import Path
11
11
  from typing import Any, Sequence
12
12
 
13
- from packaging.specifiers import SpecifierSet
13
+ from packaging.specifiers import InvalidSpecifier, SpecifierSet
14
14
  from packaging.version import Version
15
15
 
16
16
  from . import utils
@@ -123,7 +123,7 @@ def get_package_manager() -> PackageManager:
123
123
  override = _find_package_manager_override()
124
124
  if override is None:
125
125
  package_manager, reason = _resolve_package_manager_auto()
126
- LOGGER.info(
126
+ LOGGER.debug(
127
127
  "Using package manager backend: %s (%s)",
128
128
  package_manager,
129
129
  reason,
@@ -133,12 +133,12 @@ def get_package_manager() -> PackageManager:
133
133
  env_var, raw_value = override
134
134
  if raw_value not in PackageManager:
135
135
  utils.fatal(
136
- f"Invalid {env_var} value {raw_value!r}. " "Use one of: poetry, uv, auto."
136
+ f"Invalid {env_var} value {raw_value!r}. Use one of: poetry, uv, auto."
137
137
  )
138
138
 
139
139
  if raw_value == PackageManager.AUTO:
140
140
  package_manager, reason = _resolve_package_manager_auto()
141
- LOGGER.info(
141
+ LOGGER.debug(
142
142
  "Using package manager backend: %s (%s via %s=%s)",
143
143
  package_manager,
144
144
  reason,
@@ -149,7 +149,7 @@ def get_package_manager() -> PackageManager:
149
149
 
150
150
  package_manager = PackageManager(raw_value)
151
151
  _ensure_package_manager_available(package_manager)
152
- LOGGER.info(
152
+ LOGGER.debug(
153
153
  "Using package manager backend: %s (from %s)",
154
154
  package_manager,
155
155
  env_var,
@@ -179,7 +179,9 @@ def get_package_manager_build_command(wheel_only: bool = False) -> list[str]:
179
179
  return command
180
180
 
181
181
 
182
- def get_package_manager_update_command(dependencies: Sequence[str] | None = None) -> list[str]:
182
+ def get_package_manager_update_command(
183
+ dependencies: Sequence[str] | None = None,
184
+ ) -> list[str]:
183
185
  """Return the dependency update command for the selected package manager.
184
186
 
185
187
  Args:
@@ -427,7 +429,7 @@ def read_pyproject_toml() -> dict[str, Any]:
427
429
  return tomllib.loads(Path("pyproject.toml").read_text())
428
430
 
429
431
 
430
- BLACK_TARGET_PYTHON_MINORS = range(7, 17)
432
+ RUFF_TARGET_PYTHON_MINORS = range(7, 16)
431
433
 
432
434
 
433
435
  def _specifier_supports_python_minor(specifier_set: SpecifierSet, minor: int) -> bool:
@@ -436,11 +438,11 @@ def _specifier_supports_python_minor(specifier_set: SpecifierSet, minor: int) ->
436
438
  )
437
439
 
438
440
 
439
- def get_black_target_version() -> str | None:
440
- """Return the Black target-version token based on `project.requires-python`.
441
+ def get_ruff_target_version() -> str | None:
442
+ """Return the Ruff target-version token based on `project.requires-python`.
441
443
 
442
444
  Returns:
443
- The lowest supported Python version in Black format, such as
445
+ The lowest supported Python version in Ruff format, such as
444
446
  `py311`, or `None` when the project metadata is missing or invalid.
445
447
  """
446
448
  requires_python = read_pyproject_toml().get("project", {}).get("requires-python")
@@ -449,13 +451,13 @@ def get_black_target_version() -> str | None:
449
451
 
450
452
  try:
451
453
  specifier_set = SpecifierSet(requires_python)
452
- except Exception:
454
+ except InvalidSpecifier:
453
455
  LOGGER.warning("Unable to parse requires-python specifier: %s", requires_python)
454
456
  return None
455
457
 
456
- for minor in BLACK_TARGET_PYTHON_MINORS:
458
+ for minor in RUFF_TARGET_PYTHON_MINORS:
457
459
  if _specifier_supports_python_minor(specifier_set, minor):
458
- return f"py3{minor:02d}"
460
+ return f"py3{minor}"
459
461
  return None
460
462
 
461
463
 
@@ -638,7 +640,7 @@ def get_project_version_from_poetry() -> str:
638
640
  parts = poetry_version_output.rsplit(" ", 1)
639
641
  if len(parts) != 2 or not parts[1].strip():
640
642
  utils.fatal(
641
- "Unexpected poetry version output format: " f"{poetry_version_output!r}"
643
+ f"Unexpected poetry version output format: {poetry_version_output!r}"
642
644
  )
643
645
  return parts[1].strip()
644
646
 
@@ -7,9 +7,10 @@ from functools import partial, wraps
7
7
  from pathlib import Path
8
8
  from typing import Callable
9
9
 
10
- from common_python_tasks.utils import confirm
11
10
  from poethepoet_tasks import TaskCollection
12
11
 
12
+ from common_python_tasks.utils import confirm
13
+
13
14
 
14
15
  class _ColoredFormatter(logging.Formatter):
15
16
  COLORS = {
@@ -246,149 +247,33 @@ def _update_release_changelog(release_tag: str, dry_run: bool = False) -> None:
246
247
  )
247
248
 
248
249
 
249
- @tasks.script(task_name="_black", tags=["format", "internal", "common"])
250
- def black() -> None:
251
- """Run black formatting."""
252
- from .project import get_black_target_version
253
- from .utils import require_package, run_command
254
-
255
- require_package("black")
256
- target_version = get_black_target_version()
257
- command = ["black", "--quiet"]
258
- if target_version:
259
- command.extend(["--target-version", target_version])
260
- command.append(".")
261
-
262
- run_command(command)
263
-
264
-
265
- @tasks.script(task_name="_isort", tags=["format", "internal", "common"])
266
- def isort() -> None:
267
- """Run isort formatting."""
268
- from .utils import get_config_path, require_package, run_command
269
-
270
- require_package("isort")
271
- isort_config_path = get_config_path(
272
- "ISORT_CONFIG",
273
- ".isort.cfg",
274
- ".isort.cfg",
275
- tool_name="isort",
276
- )
250
+ def _get_ruff_command(*args: str | Path) -> list[str | Path]:
251
+ from .project import get_ruff_target_version
252
+ from .utils import get_ruff_config_path
277
253
 
278
- run_command(
279
- [
280
- "isort",
281
- "--quiet",
282
- ".",
283
- "--settings-path" if isort_config_path else None,
284
- isort_config_path,
254
+ config_path, is_bundled = get_ruff_config_path()
255
+ target_version = get_ruff_target_version() if is_bundled else None
256
+ return [
257
+ arg
258
+ for arg in [
259
+ "ruff",
260
+ *args,
261
+ "--config" if config_path else None,
262
+ config_path,
263
+ "--target-version" if target_version else None,
264
+ target_version,
285
265
  ]
286
- )
287
-
288
-
289
- @tasks.script(task_name="_autoflake", tags=["format", "internal", "common"])
290
- def autoflake() -> None:
291
- """Run autoflake to remove unused imports."""
292
- from .utils import require_package, run_command
293
-
294
- require_package("autoflake")
295
- run_command(
296
- [
297
- "autoflake",
298
- "--quiet",
299
- "--remove-all-unused-imports",
300
- "--recursive",
301
- "-i",
302
- Path("."),
303
- ]
304
- )
305
-
306
-
307
- @tasks.script(task_name="_black_check", tags=["lint", "internal", "common"])
308
- def black_check() -> None:
309
- """Run black in check mode."""
310
- from .project import get_black_target_version
311
- from .utils import require_package, run_command
312
-
313
- require_package("black")
314
- target_version = get_black_target_version()
315
- command = ["black", "--quiet"]
316
- if target_version:
317
- command.extend(["--target-version", target_version])
318
- command.extend(["--diff", Path("."), "--check"])
319
-
320
- run_command(command)
321
-
322
-
323
- @tasks.script(task_name="_isort_check", tags=["lint", "common"])
324
- def isort_check() -> None:
325
- """Run isort linting."""
326
- from .utils import get_config_path, require_package, run_command
327
-
328
- require_package("isort")
329
- isort_config_path = get_config_path(
330
- "ISORT_CONFIG",
331
- ".isort.cfg",
332
- ".isort.cfg",
333
- tool_name="isort",
334
- )
335
-
336
- run_command(
337
- [
338
- "isort",
339
- "--quiet",
340
- ".",
341
- "--check-only",
342
- "--settings-path" if isort_config_path else None,
343
- isort_config_path,
344
- ]
345
- )
346
-
347
-
348
- @tasks.script(task_name="_autoflake_check", tags=["lint", "internal", "common"])
349
- def autoflake_check() -> None:
350
- """Run autoflake in check mode."""
351
- from .utils import require_package, run_command
352
-
353
- require_package("autoflake")
354
- run_command(
355
- [
356
- "autoflake",
357
- "--quiet",
358
- "--remove-all-unused-imports",
359
- "--recursive",
360
- "-cd",
361
- Path("."),
362
- ]
363
- )
364
-
365
-
366
- @tasks.script(task_name="_flake8_check", tags=["lint", "common"])
367
- def flake8_check() -> None:
368
- """Run flake8 linting."""
369
- from .utils import get_config_path, require_package, run_command
370
-
371
- require_package("flake8")
372
-
373
- flake8_config_path = get_config_path("FLAKE8_CONFIG", ".flake8", ".flake8")
374
-
375
- run_command(
376
- [
377
- "flake8",
378
- Path("."),
379
- "--config" if flake8_config_path else None,
380
- flake8_config_path,
381
- ]
382
- )
266
+ if arg is not None
267
+ ]
383
268
 
384
269
 
385
270
  @tasks.script(tags=["test", "common"])
386
271
  def test(*paths: str, quiet: bool = False) -> None:
387
- """Run the test suite with coverage (if `pytest-cov` is installed).
272
+ """Run the test suite with coverage (if pytest-cov is installed).
388
273
 
389
274
 
390
275
  Args:
391
- quiet: If `True`, run tests in a quieter mode.
276
+ quiet: Run tests in a quieter mode.
392
277
  *paths: Optional test file paths or directories to pass through to pytest.
393
278
  """
394
279
  from .utils import (
@@ -454,8 +339,7 @@ def clean(dist_only: bool = False) -> None:
454
339
  """Clean up temporary files and directories.
455
340
 
456
341
  Args:
457
- dist_only: If `True`, only clean the `dist` directory (and related build
458
- artifacts)
342
+ dist_only: Only clean the dist directory (and related build artifacts)
459
343
  """
460
344
  from .utils import remove_path
461
345
 
@@ -477,33 +361,30 @@ def clean(dist_only: bool = False) -> None:
477
361
 
478
362
  @tasks.script(task_name="format", tags=["format", "common"])
479
363
  def format_all() -> None:
480
- """Format Python code with autoflake, black, and isort."""
481
- from .utils import run_available_tools
364
+ """Fix import issues and format Python code with Ruff."""
365
+ from .utils import require_package, run_command
482
366
 
483
- run_available_tools(
484
- [
485
- (autoflake, "autoflake"),
486
- (black, "black"),
487
- (isort, "isort"),
488
- ],
489
- "No formatting tools are installed. Install one or more of: autoflake, black, isort",
367
+ require_package("ruff")
368
+ run_command(
369
+ _get_ruff_command(
370
+ "check",
371
+ "--fix-only",
372
+ "--select",
373
+ "F401,I",
374
+ Path("."),
375
+ )
490
376
  )
377
+ run_command(_get_ruff_command("format", Path(".")))
491
378
 
492
379
 
493
380
  @tasks.script(task_name="lint", tags=["lint", "common"])
494
381
  def lint_all() -> None:
495
- """Lint Python code with autoflake, black, isort, and flake8."""
496
- from .utils import run_available_tools
382
+ """Check Python lint and formatting with Ruff."""
383
+ from .utils import require_package, run_command
497
384
 
498
- run_available_tools(
499
- [
500
- (autoflake_check, "autoflake"),
501
- (black_check, "black"),
502
- (isort_check, "isort"),
503
- (flake8_check, "flake8"),
504
- ],
505
- "No linting tools are installed. Install one or more of: autoflake, black, isort, flake8",
506
- )
385
+ require_package("ruff")
386
+ run_command(_get_ruff_command("check", Path(".")))
387
+ run_command(_get_ruff_command("format", "--check", Path(".")))
507
388
 
508
389
 
509
390
  @tasks.script(tags=["containers", "build"])
@@ -523,15 +404,15 @@ def build_image(
523
404
  no_cache: Do not use cache when building the image.
524
405
  plain: Do not pretty-print output.
525
406
  single_arch: Build images for a single architecture.
526
- build_args: Additional build arguments as repeated `KEY=VALUE` values.
527
- Overrides `CONTAINER_BUILD_ARGS` if provided.
407
+ build_args: Additional build arguments as repeated KEY=VALUE values.
408
+ Overrides CONTAINER_BUILD_ARGS if provided.
528
409
  container_env: Builder-stage environment declarations as repeated
529
- `KEY=VALUE` values.
410
+ KEY=VALUE values.
530
411
  container_envfile: Optional repeated list of files containing builder-stage
531
412
  environment declarations.
532
413
 
533
- Precedence for container env declarations is: `.containerenv`, `container_envfile`, `CONTAINER_ENV`, then `container_env`.
534
- All supported sources are stacked in that order.
414
+ Precedence for container env declarations is: .containerenv, container_envfile,
415
+ CONTAINER_ENV, then container_env. All supported sources are stacked in that order.
535
416
  """
536
417
  from .docker import build_image as _build_image
537
418
  from .docker import (
@@ -735,8 +616,8 @@ def build_deps_image_task(
735
616
  no_cache: Do not use cache when building the deps image.
736
617
  plain: Do not pretty-print output.
737
618
  single_arch: Build images for a single architecture.
738
- build_args: Additional build arguments as repeated `KEY=VALUE` values.
739
- Overrides `CONTAINER_BUILD_ARGS` if provided.
619
+ build_args: Additional build arguments as repeated KEY=VALUE values.
620
+ Overrides CONTAINER_BUILD_ARGS if provided.
740
621
  """
741
622
  from .docker import build_deps_image
742
623
  from .env import (
@@ -787,19 +668,18 @@ def run_container(
787
668
  ) -> None:
788
669
  """Run the Docker image as a container for this project.
789
670
 
790
- By default (when `tag` is `None`) this will run the most-recently-built tag for
791
- the project's image.
671
+ By default, this will run the most-recently-built tag for the project's image.
792
672
 
793
673
  Args:
794
- tag: Image tag to run. If `None`, use the most-recently-built tag.
674
+ tag: Image tag to run. Default: Use the most-recently-built tag.
795
675
  entrypoint: Optional entrypoint override.
796
676
  command: Optional command to pass to the entrypoint.
797
677
  root: Whether to run as root (only relevant with a shell entrypoint).
798
678
  echo_env: Whether to prepend an env dump to the command.
799
- env: Repeated `KEY=VALUE` or `KEY` values to pass with `-e`.
800
- envfile: Repeated envfile paths to pass with `--env-file`.
801
- privileged: Whether to run the container with `--privileged`.
802
- volumes: Repeated volume mounts to pass with `-v`.
679
+ env: Repeated KEY=VALUE or KEY values to pass with -e.
680
+ envfile: Repeated envfile paths to pass with --env-file.
681
+ privileged: Whether to run the container with --privileged.
682
+ volumes: Repeated volume mounts to pass with -v.
803
683
  """
804
684
  from .utils import (
805
685
  compose_image_name,
@@ -970,7 +850,7 @@ def publish_package(
970
850
  """Publish the package to the PyPI server.
971
851
 
972
852
  Args:
973
- build_first: If `True`, build the package before publishing.
853
+ build_first: Build the package before publishing.
974
854
  repository: Optional configured repository name to publish to.
975
855
  repository_url: Optional repository upload URL to publish to.
976
856
  """
@@ -1016,7 +896,7 @@ def publish_github_release(
1016
896
  release_name or os.getenv("GITHUB_RELEASE_NAME") or resolved_tag_name
1017
897
  )
1018
898
  resolved_body = body or os.getenv("GITHUB_RELEASE_BODY")
1019
- # Poe supplies `[]` when an optional repeated CLI argument is omitted.
899
+ # Poe supplies an empty list when an optional repeated CLI argument is omitted.
1020
900
  asset_paths = get_github_release_asset_paths(assets or None)
1021
901
 
1022
902
  return publish_github_release_helper(
@@ -1159,13 +1039,13 @@ def update_dependencies(
1159
1039
  Args:
1160
1040
  *dependencies: Optional dependency names to update. When omitted, update
1161
1041
  all dependencies.
1162
- branch: If `True`, create a dependency update branch after updating.
1042
+ branch: Create a dependency update branch after updating.
1163
1043
  branch_name: Optional branch name to use instead of generating one.
1164
- commit: If `True`, commit the dependency update files.
1165
- pr: If `True`, create and push a branch, commit the changes, and open
1166
- a GitHub pull request.
1167
- draft: If `True`, create the pull request as a draft.
1168
- run_tests: If `True`, run the test task before committing.
1044
+ commit: Commit the dependency update files.
1045
+ pr: Create and push a branch, commit the changes, and open a GitHub pull
1046
+ request.
1047
+ draft: Create the pull request as a draft.
1048
+ run_tests: Run the test task before committing.
1169
1049
  """
1170
1050
  from .github import create_pull_request
1171
1051
  from .project import get_package_manager_update_command
@@ -1252,11 +1132,11 @@ def bump_version(
1252
1132
  """Bump the project version.
1253
1133
 
1254
1134
  Args:
1255
- component: The version component to bump: `major`, `minor`, `patch`, or
1256
- `auto` to infer the bump from git history using git-cliff.
1257
- stage: Optional pre-release stage to apply: `alpha`, `beta`, or `rc`.
1258
- dry_run: If `True`, print what would happen without making changes.
1259
- allow_dirty: If `True`, allow version bumping with uncommitted changes.
1135
+ component: The version component to bump: major, minor, patch, or auto to
1136
+ infer the bump from git history using git-cliff.
1137
+ stage: Optional pre-release stage to apply: alpha, beta, or rc.
1138
+ dry_run: Print what would happen without making changes.
1139
+ allow_dirty: Allow version bumping with uncommitted changes.
1260
1140
 
1261
1141
  Returns:
1262
1142
  The new version string that was/would be set.
@@ -1479,17 +1359,17 @@ def release(
1479
1359
  """Run a full release flow for package and containers.
1480
1360
 
1481
1361
  Args:
1482
- component: The version component to bump: `major`, `minor`, or `patch`.
1483
- stage: Optional pre-release stage to apply: `alpha`, `beta`, or `rc`.
1484
- dry_run: If `True`, only perform a dry-run version bump.
1362
+ component: The version component to bump: major, minor, or patch.
1363
+ stage: Optional pre-release stage to apply: alpha, beta, or rc.
1364
+ dry_run: Only perform a dry-run version bump.
1485
1365
  debug: Build/push debug container image tags when releasing containers.
1486
1366
  no_cache: Do not use cache when building container images.
1487
1367
  plain: Do not pretty-print container build output.
1488
1368
  single_arch: Build container image for a single architecture.
1489
1369
  build_args: Additional build arguments for the Docker build as repeated
1490
- `KEY=VALUE` values.
1370
+ KEY=VALUE values.
1491
1371
  container_env: Inline container environment variables as repeated
1492
- `KEY=VALUE` values.
1372
+ KEY=VALUE values.
1493
1373
  container_envfile: Repeated list of container environment files.
1494
1374
  assets: Optional repeated list of release asset patterns or paths.
1495
1375
  repository: Optional configured repository name to publish to.
@@ -1531,9 +1411,9 @@ def release_without_containers(
1531
1411
  """Run a full release flow for package artifacts without container publishing.
1532
1412
 
1533
1413
  Args:
1534
- component: The version component to bump: `major`, `minor`, or `patch`.
1535
- stage: Optional pre-release stage to apply: `alpha`, `beta`, or `rc`.
1536
- dry_run: If `True`, only perform a dry-run version bump.
1414
+ component: The version component to bump: major, minor, or patch.
1415
+ stage: Optional pre-release stage to apply: alpha, beta, or rc.
1416
+ dry_run: Only perform a dry-run version bump.
1537
1417
  assets: Optional repeated list of release asset patterns or paths.
1538
1418
  repository: Optional configured repository name to publish to.
1539
1419
  repository_url: Optional repository upload URL to publish to.
@@ -1615,9 +1495,9 @@ def build_with_containers(
1615
1495
  plain: Do not pretty-print output.
1616
1496
  single_arch: Build images for a single architecture.
1617
1497
  build_args: Additional build arguments for the Docker build as repeated
1618
- `KEY=VALUE` values.
1619
- container_env: Inline container environment variables as repeated
1620
- `KEY=VALUE` values.
1498
+ KEY=VALUE values.
1499
+ container_env: Inline container environment variables as repeated KEY=VALUE
1500
+ values.
1621
1501
  container_envfile: Repeated list of container environment files.
1622
1502
  """
1623
1503
 
@@ -1653,15 +1533,15 @@ def fastapi_stack_up(
1653
1533
  """Bring up the development stack for the application.
1654
1534
 
1655
1535
  Args:
1656
- debug: Enable debug mode (auto-loads all `*-debug.yml` compose files).
1536
+ debug: Enable debug mode (auto-loads all *-debug.yml compose files).
1657
1537
  no_cache: Do not use cache when building the image.
1658
1538
  detach: Run the stack in detached mode.
1659
1539
  services: Optional repeated list of services to start. If not provided,
1660
1540
  all services will be started.
1661
1541
  build_args: Additional build arguments for the Docker build as repeated
1662
- `KEY=VALUE` values.
1663
- container_env: Inline container environment variables as repeated
1664
- `KEY=VALUE` values.
1542
+ KEY=VALUE values.
1543
+ container_env: Inline container environment variables as repeated KEY=VALUE
1544
+ values.
1665
1545
  container_envfile: Repeated list of container environment files.
1666
1546
  """
1667
1547
  from .docker_compose import (
@@ -1741,8 +1621,8 @@ def fastapi_stack_up(
1741
1621
  )
1742
1622
  api_port = int(compose_env["API_PORT"])
1743
1623
 
1744
- # When watch mode is active, `docker compose` needs the Dockerfile present
1745
- # in the project directory so that watch-triggered rebuilds can find it.
1624
+ # When watch mode is active, docker compose needs the Dockerfile present in the
1625
+ # project directory so that watch-triggered rebuilds can find it.
1746
1626
  watch_mode = debug and not detach
1747
1627
  local_dockerfile = Path("Dockerfile")
1748
1628
  wrote_dockerfile = False
@@ -1763,7 +1643,8 @@ def fastapi_stack_up(
1763
1643
  try:
1764
1644
  LOGGER.info("Building and starting the application stack...")
1765
1645
  LOGGER.info(
1766
- "Starting application. Once the stack is up, check the API docs at http://localhost:%i/api/docs",
1646
+ "Starting application. Once the stack is up, check the API docs at "
1647
+ "http://localhost:%i/api/docs",
1767
1648
  api_port,
1768
1649
  )
1769
1650
  if detach:
@@ -1929,15 +1810,15 @@ def container_shell(
1929
1810
  """Run the debug image with an interactive shell.
1930
1811
 
1931
1812
  Args:
1932
- tag: Image tag to use. If `None`, use the most-recently-built tag.
1933
- shell: Preferred shell name or path. If `None`, use the first available from
1934
- `zsh`, `fish`, `ksh`, `bash`, and `sh`.
1813
+ tag: Image tag to use. Default: Use the most-recently-built tag.
1814
+ shell: Preferred shell name or path. Default: Use the first available from zsh,
1815
+ fish, ksh, bash, and sh.
1935
1816
  root: Whether to run the shell as root.
1936
1817
  no_echo_env: Whether to suppress printing environment variables on startup for debugging.
1937
- env: Repeated `KEY=VALUE` or `KEY` values to pass with `-e`.
1938
- envfile: Repeated envfile paths to pass with `--env-file`.
1939
- privileged: Whether to run the container with `--privileged`.
1940
- volumes: Repeated volume mounts to pass with `-v`.
1818
+ env: Repeated KEY=VALUE or KEY values to pass with -e.
1819
+ envfile: Repeated envfile paths to pass with --env-file.
1820
+ privileged: Whether to run the container with --privileged.
1821
+ volumes: Repeated volume mounts to pass with -v.
1941
1822
  """
1942
1823
  from shlex import quote
1943
1824