Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/usethis/_config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
from typing import TYPE_CHECKING

from usethis._integrations.backend.uv.toml import UVTOMLManager
from usethis._integrations.ci.bitbucket.yaml import BitbucketPipelinesYAMLManager
from usethis._integrations.file.ini.io_ import INIFileManager
from usethis._integrations.file.pyproject_toml.io_ import PyprojectTOMLManager
from usethis._integrations.file.setup_cfg.io_ import SetupCFGManager
from usethis._integrations.file.toml.io_ import TOMLFileManager
from usethis._integrations.file.yaml.io_ import YAMLFileManager
from usethis._integrations.pre_commit.yaml import PreCommitConfigYAMLManager

if TYPE_CHECKING:
from collections.abc import Iterator
Expand All @@ -20,13 +22,15 @@ def files_manager() -> Iterator[None]:
with (
PyprojectTOMLManager(),
SetupCFGManager(),
BitbucketPipelinesYAMLManager(),
DotCodespellRCManager(),
DotCoverageRCManager(),
DotCoverageRCTOMLManager(),
DotRuffTOMLManager(),
DotPytestINIManager(),
DotImportLinterManager(),
MkDocsYMLManager(),
PreCommitConfigYAMLManager(),
PytestINIManager(),
RuffTOMLManager(),
ToxINIManager(),
Expand Down
76 changes: 36 additions & 40 deletions src/usethis/_integrations/ci/bitbucket/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@
from typing import TYPE_CHECKING

from usethis._console import tick_print
from usethis._integrations.ci.bitbucket.dump import bitbucket_fancy_dump
from usethis._integrations.ci.bitbucket.io_ import (
edit_bitbucket_pipelines_yaml,
read_bitbucket_pipelines_yaml,
from usethis._integrations.ci.bitbucket.init import (
ensure_bitbucket_pipelines_config_exists,
)
from usethis._integrations.ci.bitbucket.schema import Definitions
from usethis._integrations.file.yaml.update import update_ruamel_yaml_map
from usethis._integrations.ci.bitbucket.yaml import BitbucketPipelinesYAMLManager

if TYPE_CHECKING:
from usethis._integrations.ci.bitbucket.io_ import BitbucketPipelinesYAMLDocument
from usethis._integrations.ci.bitbucket.schema import Cache
from usethis._integrations.ci.bitbucket.schema import Cache, PipelinesConfiguration


def get_cache_by_name() -> dict[str, Cache]:
with read_bitbucket_pipelines_yaml() as doc:
config = doc.model
mgr = BitbucketPipelinesYAMLManager()
config = mgr.model_validate()

if config.definitions is None:
return {}
Expand All @@ -32,53 +29,52 @@ def get_cache_by_name() -> dict[str, Cache]:


def add_caches(cache_by_name: dict[str, Cache]) -> None:
with edit_bitbucket_pipelines_yaml() as doc:
_add_caches_via_doc(cache_by_name, doc=doc)
dump = bitbucket_fancy_dump(doc.model, reference=doc.content)
update_ruamel_yaml_map(doc.content, dump, preserve_comments=True)
ensure_bitbucket_pipelines_config_exists()

mgr = BitbucketPipelinesYAMLManager()
model = mgr.model_validate()
_add_caches_via_model(cache_by_name, model=model)
mgr.commit_model(model)

def _add_caches_via_doc(
cache_by_name: dict[str, Cache], *, doc: BitbucketPipelinesYAMLDocument
) -> None:
config = doc.model

if config.definitions is None:
config.definitions = Definitions()
if config.definitions.caches is None:
config.definitions.caches = {}
def _add_caches_via_model(
cache_by_name: dict[str, Cache], *, model: PipelinesConfiguration
) -> None:
if model.definitions is None:
model.definitions = Definitions()
if model.definitions.caches is None:
model.definitions.caches = {}

for name, cache in cache_by_name.items():
if not _cache_exists(name, doc=doc):
if not _cache_exists(name, model=model):
tick_print(
f"Adding cache '{name}' definition to 'bitbucket-pipelines.yml'."
)
config.definitions.caches[name] = cache
model.definitions.caches[name] = cache


def remove_cache(cache: str) -> None:
with edit_bitbucket_pipelines_yaml() as doc:
config = doc.model
mgr = BitbucketPipelinesYAMLManager()
model = mgr.model_validate()

if config.definitions is None or config.definitions.caches is None:
return
if model.definitions is None or model.definitions.caches is None:
return

if cache in config.definitions.caches:
tick_print(
f"Removing cache '{cache}' definition from 'bitbucket-pipelines.yml'."
)
del config.definitions.caches[cache]
if cache in model.definitions.caches:
tick_print(
f"Removing cache '{cache}' definition from 'bitbucket-pipelines.yml'."
)
del model.definitions.caches[cache]

# Remove an empty caches section
if not config.definitions.caches:
del config.definitions.caches
# Remove an empty caches section
if not model.definitions.caches:
del model.definitions.caches

dump = bitbucket_fancy_dump(config, reference=doc.content)
update_ruamel_yaml_map(doc.content, dump, preserve_comments=True)
mgr.commit_model(model)


def _cache_exists(name: str, *, doc: BitbucketPipelinesYAMLDocument) -> bool:
if doc.model.definitions is None or doc.model.definitions.caches is None:
def _cache_exists(name: str, *, model: PipelinesConfiguration) -> bool:
if model.definitions is None or model.definitions.caches is None:
return False

return name in doc.model.definitions.caches
return name in model.definitions.caches
38 changes: 0 additions & 38 deletions src/usethis/_integrations/ci/bitbucket/dump.py

This file was deleted.

11 changes: 10 additions & 1 deletion src/usethis/_integrations/ci/bitbucket/errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from usethis.errors import UsethisError
from usethis.errors import FileConfigError, UsethisError


class UnexpectedImportPipelineError(UsethisError):
Expand All @@ -9,3 +9,12 @@ class UnexpectedImportPipelineError(UsethisError):

class MissingStepError(ValueError):
"""Raised when a step cannot be found in the pipeline."""


class BitbucketPipelinesYAMLSchemaError(FileConfigError):
"""Raised when there the 'bitbucket-pipelines.yml' file does not conform to the expected schema."""

@property
def name(self) -> str:
"""The name of the file that has a configuration error."""
return "bitbucket-pipelines.yml"
16 changes: 16 additions & 0 deletions src/usethis/_integrations/ci/bitbucket/init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import annotations

from usethis._config import usethis_config
from usethis._console import tick_print


def ensure_bitbucket_pipelines_config_exists() -> None:
"""Ensure 'bitbucket-pipelines.yml' exists with minimal valid content."""
name = "bitbucket-pipelines.yml"
path = usethis_config.cpd() / name

if not path.exists():
tick_print(f"Writing '{name}'.")
# N.B. where necessary, we can opt to use a different image from this default
# on a per-step basis, so this is safe even when we want to use Python images.
path.write_text("image: atlassian/default-image:3\n", encoding="utf-8")
93 changes: 0 additions & 93 deletions src/usethis/_integrations/ci/bitbucket/io_.py

This file was deleted.

32 changes: 16 additions & 16 deletions src/usethis/_integrations/ci/bitbucket/pipeweld.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
from typing_extensions import assert_never

import usethis._pipeweld.containers
from usethis._integrations.ci.bitbucket.dump import bitbucket_fancy_dump
from usethis._integrations.ci.bitbucket.errors import (
MissingStepError,
UnexpectedImportPipelineError,
)
from usethis._integrations.ci.bitbucket.io_ import (
edit_bitbucket_pipelines_yaml,
from usethis._integrations.ci.bitbucket.init import (
ensure_bitbucket_pipelines_config_exists,
)
from usethis._integrations.ci.bitbucket.schema import (
ImportPipeline,
Expand All @@ -29,11 +28,10 @@
StepItem,
)
from usethis._integrations.ci.bitbucket.schema_utils import step1tostep
from usethis._integrations.file.yaml.update import update_ruamel_yaml_map
from usethis._integrations.ci.bitbucket.yaml import BitbucketPipelinesYAMLManager
from usethis._pipeweld.ops import InsertParallel, InsertSuccessor, Instruction

if TYPE_CHECKING:
from usethis._integrations.ci.bitbucket.io_ import BitbucketPipelinesYAMLDocument
from usethis._integrations.ci.bitbucket.schema import PipelinesConfiguration


Expand Down Expand Up @@ -119,24 +117,26 @@ def _(item: StageItem):
def apply_pipeweld_instruction(
instruction: Instruction, *, step_to_insert: Step
) -> None:
with edit_bitbucket_pipelines_yaml() as doc:
apply_pipeweld_instruction_via_doc(
instruction, doc=doc, step_to_insert=step_to_insert
)
dump = bitbucket_fancy_dump(doc.model, reference=doc.content)
update_ruamel_yaml_map(doc.content, dump, preserve_comments=True)
ensure_bitbucket_pipelines_config_exists()

mgr = BitbucketPipelinesYAMLManager()
model = mgr.model_validate()
apply_pipeweld_instruction_via_model(
instruction, model=model, step_to_insert=step_to_insert
)
mgr.commit_model(model)


def apply_pipeweld_instruction_via_doc(
def apply_pipeweld_instruction_via_model(
instruction: Instruction,
*,
step_to_insert: Step,
doc: BitbucketPipelinesYAMLDocument,
model: PipelinesConfiguration,
) -> None:
if doc.model.pipelines is None:
doc.model.pipelines = Pipelines()
if model.pipelines is None:
model.pipelines = Pipelines()

pipelines = doc.model.pipelines
pipelines = model.pipelines
default = pipelines.default

if default is None:
Expand Down
Loading