Objective
Add support for organizing cloned repositories by their Bitbucket project, instead of a flat directory structure. This is optional and controlled by an environment variable or command-line flag.
Current Behavior
All repositories are cloned into a flat structure:
output/bbr-workspace-2026-03-05-T10.00.00/
repo-1/
repo-2/
repo-3/
repo-4/
Desired Behavior
When project folder mode is enabled, organize repositories by their Bitbucket project:
output/bbr-workspace-2026-03-05-T10.00.00/
PROJECT-A/
repo-1/
repo-2/
PROJECT-B/
repo-3/
UNASSIGNED/
repo-4/
Implementation Requirements
1. Environment Variable
Add new optional environment variable:
BB_USE_PROJECT_FOLDERS=true # Enable project folder organization
BB_USE_PROJECT_FOLDERS=false # Disable (default, flat structure)
2. Code Changes
In ripper_utils.py - clone_repo() function:
Current:
clone_dir = f"{output_dir}/{repo.name}"
Updated:
if os.environ.get('BB_USE_PROJECT_FOLDERS', 'false').lower() == 'true':
# Use project key/name for folder organization
project_key = repo.project.get('key', 'UNASSIGNED') if repo.project else 'UNASSIGNED'
clone_dir = f"{output_dir}/{project_key}/{repo.name}"
else:
# Default flat structure
clone_dir = f"{output_dir}/{repo.name}"
Notes:
- Use
repo.project['key'] as the folder name (e.g., PROJECT-A, INFRA)
- If
repo.project is None or empty, use UNASSIGNED as the project folder
- Create parent directories as needed (
os.makedirs(clone_dir) already handles this)
3. Documentation Updates
Update README.md:
Add to the "Optional Settings" section:
`BB_USE_PROJECT_FOLDERS` Enable organization of repositories by Bitbucket project (true/false, default: false).
Update docenv.example:
# Optional: Organize repos by project
# BB_USE_PROJECT_FOLDERS=true
Edge Cases
- Repos without a project → Use
UNASSIGNED folder
- Project key is null/empty → Use
UNASSIGNED folder
- Invalid project key characters → Sanitize if needed (Bitbucket project keys should be safe, but verify)
- Existing behavior → Must remain default (backward compatibility)
Testing
Manual Testing
Test with both modes:
Flat mode (default):
unset BB_USE_PROJECT_FOLDERS
python3 bb-ripper/.
# Verify flat structure
Project folder mode:
export BB_USE_PROJECT_FOLDERS=true
python3 bb-ripper/.
# Verify repos grouped by project
# Verify UNASSIGNED folder for repos without projects
Verification Checklist
Acceptance Criteria
References
- Current code:
bb-ripper/ripper_utils.py - clone_repo() function
- Project data available in
BBRepo.project (already populated by API)
- Project key format: Uppercase alphanumeric + hyphens (e.g.,
PROJ-A, INFRA)
Notes
- This is a simple change (~5 lines of code + docs)
- No external dependencies needed
- Project data is already available from Bitbucket API in
BBRepo objects
- Keeps default flat structure for backward compatibility
Objective
Add support for organizing cloned repositories by their Bitbucket project, instead of a flat directory structure. This is optional and controlled by an environment variable or command-line flag.
Current Behavior
All repositories are cloned into a flat structure:
Desired Behavior
When project folder mode is enabled, organize repositories by their Bitbucket project:
Implementation Requirements
1. Environment Variable
Add new optional environment variable:
2. Code Changes
In
ripper_utils.py-clone_repo()function:Current:
Updated:
Notes:
repo.project['key']as the folder name (e.g.,PROJECT-A,INFRA)repo.projectisNoneor empty, useUNASSIGNEDas the project folderos.makedirs(clone_dir)already handles this)3. Documentation Updates
Update
README.md:Add to the "Optional Settings" section:
Update
docenv.example:Edge Cases
UNASSIGNEDfolderUNASSIGNEDfolderTesting
Manual Testing
Test with both modes:
Flat mode (default):
Project folder mode:
Verification Checklist
{project_key}/foldersUNASSIGNED/folderAcceptance Criteria
BB_USE_PROJECT_FOLDERScontrols behaviorUNASSIGNED/folderReferences
bb-ripper/ripper_utils.py-clone_repo()functionBBRepo.project(already populated by API)PROJ-A,INFRA)Notes
BBRepoobjects