rlsbl v0.92.0 /rlsbl.commands.monorepo.extract
On this page

Extract and absorb operations for moving packages in and out of monorepos.

#rlsbl.commands.monorepo.extract

#rlsbl.commands.monorepo.extract

Extract and absorb operations for moving packages in and out of monorepos.

Provides:

  • require_filter_repo(): dependency check for git-filter-repo
  • cmd_extract(): extract a package from a monorepo into a new repository
  • cmd_absorb(): absorb an external repository as a package in the monorepo
  • cmd_extract_releasable(): extract all member packages of a releasable

#ExtractError

Error during extract or absorb operations.

#require_filter_repo

python
def require_filter_repo()

Raise if git-filter-repo is not installed.

Checks that the git-filter-repo command is available on PATH. Raises ExtractError with install instructions if missing.

#_run_git

python
def _run_git(cwd, *args)

Run a git command and return stdout. Raises subprocess.CalledProcessError on failure.

#_find_project

python
def _find_project(projects, package_name)

Find a project by name in the workspace project list.

Returns the WorkspaceProject or raises ExtractError.

#_get_default_branch

python
def _get_default_branch(cwd)

Detect the default branch name (main or master) of a repo.

#_filter_changelog_entries

python
def _filter_changelog_entries(entries, package_path, repo_root)

Filter changelog entries to those touching a specific package path.

An entry matches if:

  • It has a packages field containing the package name, OR
  • Any of its commits touch files under the package path (checked via

git diff-tree if repo_root is provided and the commit exists).

When we cannot determine relevance (e.g. no packages field and commits are not resolvable), the entry is included (conservative approach).

#_migrate_changelog_to_new_repo

python
def _migrate_changelog_to_new_repo(source_changes_dir, target_changes_dir, package_path, repo_root)

Migrate changelog entries relevant to a package into a new repo's changes dir.

Reads unreleased.jsonl and all versioned JSONL files from source_changes_dir, filters entries to those relevant to the package, and writes them into target_changes_dir.

Returns (files_written, entries_migrated) tuple.

#_create_rlsbl_config

python
def _create_rlsbl_config(target_path, source_config_path=None)

Create a .rlsbl/ config in the target repo.

If source_config_path is provided and exists, copies relevant config. Otherwise creates a minimal config.

#_remove_project_from_workspace

python
def _remove_project_from_workspace(workspace_root, package_name, projects)

Remove a project from workspace.toml by name.

Returns the updated project list.

#validate_extract_preconditions

python
def validate_extract_preconditions(workspace_root, package_name, target_repo_path)

Validate that extraction can proceed.

Checks:

  • Package exists in workspace.toml
  • Target path does not already exist
  • git-filter-repo is installed

Returns (projects, project) tuple.

#cmd_extract

python
def cmd_extract(workspace_root, package_name, target_repo_path, *, dry_run=False)

Extract a package from the monorepo into a new repository.

Steps:

  1. Validate package exists in workspace.toml
  2. Clone the monorepo to target_repo_path
  3. Run git filter-repo --path on the clone to keep only

that package's history

  1. Migrate changelog: filter JSONL entries to those touching the

extracted package

  1. Create .rlsbl/ config in the new repo
  2. Update source monorepo: remove project from workspace.toml

Args:

  • workspace_root: path to the monorepo root.
  • package_name: name of the package to extract.
  • target_repo_path: path where the new repo will be created.
  • dry_run: if True, validate but do not perform the extraction.

Returns:

  • A dict with extraction details: package_name, target_path,
  • entries_migrated, files_written.

#validate_absorb_preconditions

python
def validate_absorb_preconditions(workspace_root, source_repo_path, package_name)

Validate that absorption can proceed.

Checks:

  • Source repo exists and is a git repo
  • Package name is not already in workspace.toml

Returns projects list.

#_migrate_changelog_from_source

python
def _migrate_changelog_from_source(source_repo_path, target_changes_dir)

Migrate changelog entries from a source repo into the monorepo's changes dir.

Reads .rlsbl/changes/ from the source repo and writes entries into target_changes_dir, appending to existing files.

Returns (files_written, entries_migrated) tuple.

#cmd_absorb

python
def cmd_absorb(workspace_root, source_repo_path, package_name, releasable_name=None, *, dry_run=False)

Absorb an external repository as a package in the monorepo.

Steps:

  1. Run git subtree add --prefix=
  2. Add project to workspace.toml with the specified releasable
  3. Migrate changelog: read source repo's .rlsbl/changes/, write to

the package's changelog in the monorepo

  1. Return details for the caller to regenerate CI

Args:

  • workspace_root: path to the monorepo root.
  • source_repo_path: path to the external repository.
  • package_name: name for the package in the monorepo.
  • releasable_name: optional releasable to assign the package to.
  • dry_run: if True, validate but do not perform the absorption.

Returns:

  • A dict with absorption details: package_name, source_path,
  • entries_migrated, files_written.

#cmd_extract_releasable

python
def cmd_extract_releasable(workspace_root, releasable_name, target_repo_path, *, dry_run=False)

Extract all member packages of a releasable into a new repository.

If the releasable has one member, the result is a single-project repo. If it has multiple members, the result is a monorepo with workspace.toml.

Steps:

  1. Resolve releasable members from workspace.toml
  2. Clone the monorepo
  3. Run git filter-repo --path --path ... for all

member paths

  1. Migrate changelog for each member
  2. Create appropriate config (single-project or monorepo)
  3. Update source monorepo: remove all member projects from workspace.toml

Args:

  • workspace_root: path to the monorepo root.
  • releasable_name: name of the releasable to extract.
  • target_repo_path: path where the new repo will be created.
  • dry_run: if True, validate but do not perform the extraction.

Returns:

  • A dict with extraction details.