mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-19 11:31:03 +00:00
* feat: support annotate * feat: extract supports --feature * feat: support classify in dev cli
142 lines
4.2 KiB
Python
Generated
142 lines
4.2 KiB
Python
Generated
"""
|
|
Apply Feature - Apply patches for a specific feature.
|
|
"""
|
|
|
|
import yaml
|
|
from typing import List, Tuple, Optional
|
|
|
|
from ...common.context import Context
|
|
from ...common.module import CommandModule, ValidationError
|
|
from ...common.utils import log_info, log_error, log_warning, log_success
|
|
from .common import process_patch_list
|
|
|
|
|
|
def apply_feature_patches(
|
|
build_ctx: Context,
|
|
feature_name: str,
|
|
dry_run: bool = False,
|
|
reset_to: Optional[str] = None,
|
|
) -> Tuple[int, List[str]]:
|
|
"""Apply patches for a specific feature.
|
|
|
|
Args:
|
|
build_ctx: Build context
|
|
feature_name: Name of the feature
|
|
dry_run: Only check if patches would apply
|
|
reset_to: Commit to reset files to before applying (optional)
|
|
|
|
Returns:
|
|
Tuple of (applied_count, failed_list)
|
|
"""
|
|
# Load features.yaml
|
|
features_path = build_ctx.get_features_yaml_path()
|
|
if not features_path.exists():
|
|
log_error("No features.yaml found")
|
|
return 0, []
|
|
|
|
with open(features_path) as f:
|
|
data = yaml.safe_load(f)
|
|
|
|
features = data.get("features", {})
|
|
|
|
if feature_name not in features:
|
|
log_error(f"Feature '{feature_name}' not found")
|
|
log_info("Available features:")
|
|
for name in features:
|
|
log_info(f" - {name}")
|
|
return 0, []
|
|
|
|
file_list = features[feature_name].get("files", [])
|
|
|
|
if not file_list:
|
|
log_warning(f"Feature '{feature_name}' has no files")
|
|
return 0, []
|
|
|
|
log_info(f"Applying patches for feature '{feature_name}' ({len(file_list)} files)")
|
|
|
|
if dry_run:
|
|
log_info("DRY RUN - No changes will be made")
|
|
|
|
# Create patch list
|
|
patches_dir = build_ctx.get_patches_dir()
|
|
patch_list = []
|
|
for file_path in file_list:
|
|
patch_path = build_ctx.get_patch_path_for_file(file_path)
|
|
patch_list.append((patch_path, file_path))
|
|
|
|
# Process patches
|
|
applied, failed = process_patch_list(
|
|
patch_list,
|
|
build_ctx.chromium_src,
|
|
patches_dir,
|
|
dry_run,
|
|
interactive=False, # Feature patches don't support interactive mode
|
|
reset_to=reset_to,
|
|
)
|
|
|
|
# Summary
|
|
log_info(f"\nSummary: {applied} applied, {len(failed)} failed")
|
|
|
|
if failed:
|
|
log_error("Failed patches:")
|
|
for p in failed:
|
|
log_error(f" - {p}")
|
|
|
|
return applied, failed
|
|
|
|
|
|
class ApplyFeatureModule(CommandModule):
|
|
"""Apply patches for a specific feature"""
|
|
|
|
produces = []
|
|
requires = []
|
|
description = "Apply patches for a specific feature"
|
|
|
|
def validate(self, ctx: Context) -> None:
|
|
"""Validate git is available"""
|
|
import shutil
|
|
|
|
if not shutil.which("git"):
|
|
raise ValidationError("Git is not available in PATH")
|
|
if not ctx.chromium_src.exists():
|
|
raise ValidationError(f"Chromium source not found: {ctx.chromium_src}")
|
|
|
|
def execute(
|
|
self,
|
|
ctx: Context,
|
|
feature_name: str,
|
|
interactive: bool = True,
|
|
reset_to: Optional[str] = None,
|
|
annotate: bool = False,
|
|
**kwargs,
|
|
) -> None:
|
|
"""Execute apply feature patches
|
|
|
|
Args:
|
|
feature_name: Name of the feature to apply
|
|
interactive: Interactive mode (ask before each patch)
|
|
reset_to: Commit to reset files to before applying (optional)
|
|
annotate: Create git commit for this feature after applying
|
|
"""
|
|
applied, failed = apply_feature_patches(
|
|
ctx,
|
|
feature_name,
|
|
dry_run=False,
|
|
reset_to=reset_to,
|
|
)
|
|
if failed:
|
|
raise RuntimeError(
|
|
f"Failed to apply {len(failed)} patches for feature '{feature_name}'"
|
|
)
|
|
|
|
# Run annotate for this specific feature if requested
|
|
if annotate:
|
|
from ..annotate import annotate_single_feature
|
|
|
|
log_info("\n" + "=" * 60)
|
|
log_info(f"🏗️ Creating commit for feature '{feature_name}'...")
|
|
if annotate_single_feature(ctx, feature_name):
|
|
log_success(f"✓ Created commit for '{feature_name}'")
|
|
else:
|
|
log_info("No commit created (no modified files found)")
|