mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 21:05:09 +00:00
211 lines
6.3 KiB
Python
211 lines
6.3 KiB
Python
"""
|
|
Apply module - Apply patches to Chromium source
|
|
|
|
Simple and straightforward patch application with minimal error handling.
|
|
"""
|
|
|
|
import click
|
|
import yaml
|
|
from pathlib import Path
|
|
from typing import List, Tuple
|
|
from context import BuildContext
|
|
from modules.dev_cli.utils import run_git_command, GitError
|
|
from utils import log_info, log_error, log_success, log_warning
|
|
|
|
|
|
@click.group(name='apply')
|
|
def apply_group():
|
|
"""Apply patches to Chromium source"""
|
|
pass
|
|
|
|
|
|
@apply_group.command(name='all')
|
|
@click.option('--commit-each', is_flag=True, help='Create git commit after each patch')
|
|
@click.option('--dry-run', is_flag=True, help='Test patches without applying')
|
|
@click.pass_context
|
|
def apply_all(ctx, commit_each, dry_run):
|
|
"""Apply all patches from chromium_src/
|
|
|
|
\b
|
|
Examples:
|
|
dev apply all
|
|
dev apply all --commit-each
|
|
dev apply all --dry-run
|
|
"""
|
|
chromium_src = ctx.parent.obj.get('chromium_src')
|
|
|
|
from dev import create_build_context
|
|
build_ctx = create_build_context(chromium_src)
|
|
if not build_ctx:
|
|
return
|
|
|
|
patches_dir = build_ctx.get_dev_patches_dir()
|
|
if not patches_dir.exists():
|
|
log_error(f"Patches directory does not exist: {patches_dir}")
|
|
ctx.exit(1)
|
|
|
|
# Find all patch files (excluding special markers)
|
|
patch_files = sorted([
|
|
p for p in patches_dir.rglob("*.patch")
|
|
if not p.name.endswith('.deleted') and not p.name.endswith('.binary')
|
|
])
|
|
|
|
if not patch_files:
|
|
log_warning("No patch files found")
|
|
return
|
|
|
|
log_info(f"Found {len(patch_files)} patches")
|
|
|
|
if dry_run:
|
|
log_info("DRY RUN - No changes will be made")
|
|
|
|
applied = 0
|
|
failed = []
|
|
|
|
for patch_path in patch_files:
|
|
rel_path = patch_path.relative_to(patches_dir)
|
|
|
|
if dry_run:
|
|
# Just check if patch would apply
|
|
result = run_git_command(
|
|
['git', 'apply', '--check', '-p1', str(patch_path)],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
if result.returncode == 0:
|
|
log_success(f" ✓ Would apply: {rel_path}")
|
|
applied += 1
|
|
else:
|
|
log_error(f" ✗ Would fail: {rel_path}")
|
|
failed.append(str(rel_path))
|
|
else:
|
|
# Actually apply the patch
|
|
result = run_git_command(
|
|
['git', 'apply', '-p1', str(patch_path)],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
log_success(f" ✓ Applied: {rel_path}")
|
|
applied += 1
|
|
|
|
if commit_each:
|
|
# Create commit
|
|
run_git_command(['git', 'add', '-A'], cwd=build_ctx.chromium_src)
|
|
run_git_command(
|
|
['git', 'commit', '-m', f'Apply patch: {rel_path.stem}'],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
else:
|
|
log_error(f" ✗ Failed: {rel_path}")
|
|
log_error(f" {result.stderr}")
|
|
failed.append(str(rel_path))
|
|
|
|
# Summary
|
|
log_info(f"\nSummary: {applied} applied, {len(failed)} failed")
|
|
|
|
if failed:
|
|
log_error("Failed patches:")
|
|
for p in failed:
|
|
log_error(f" - {p}")
|
|
ctx.exit(1)
|
|
|
|
|
|
@apply_group.command(name='feature')
|
|
@click.argument('feature_name')
|
|
@click.option('--commit-each', is_flag=True, help='Create git commit after each patch')
|
|
@click.option('--dry-run', is_flag=True, help='Test patches without applying')
|
|
@click.pass_context
|
|
def apply_feature(ctx, feature_name, commit_each, dry_run):
|
|
"""Apply patches for a specific feature
|
|
|
|
\b
|
|
Examples:
|
|
dev apply feature llm-chat
|
|
dev apply feature my-feature --commit-each
|
|
"""
|
|
chromium_src = ctx.parent.obj.get('chromium_src')
|
|
|
|
from dev import create_build_context
|
|
build_ctx = create_build_context(chromium_src)
|
|
if not build_ctx:
|
|
return
|
|
|
|
# Load features.yaml
|
|
features_path = build_ctx.get_features_yaml_path()
|
|
if not features_path.exists():
|
|
log_error(f"No features.yaml found")
|
|
ctx.exit(1)
|
|
|
|
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}")
|
|
ctx.exit(1)
|
|
|
|
file_list = features[feature_name].get('files', [])
|
|
|
|
if not file_list:
|
|
log_warning(f"Feature '{feature_name}' has no files")
|
|
return
|
|
|
|
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")
|
|
|
|
applied = 0
|
|
failed = []
|
|
|
|
for file_path in file_list:
|
|
patch_path = build_ctx.get_patch_path_for_file(file_path)
|
|
|
|
if not patch_path.exists():
|
|
log_warning(f" Patch not found: {file_path}")
|
|
failed.append(file_path)
|
|
continue
|
|
|
|
if dry_run:
|
|
result = run_git_command(
|
|
['git', 'apply', '--check', '-p1', str(patch_path)],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
if result.returncode == 0:
|
|
log_success(f" ✓ Would apply: {file_path}")
|
|
applied += 1
|
|
else:
|
|
log_error(f" ✗ Would fail: {file_path}")
|
|
failed.append(file_path)
|
|
else:
|
|
result = run_git_command(
|
|
['git', 'apply', '-p1', str(patch_path)],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
log_success(f" ✓ Applied: {file_path}")
|
|
applied += 1
|
|
|
|
if commit_each:
|
|
run_git_command(['git', 'add', '-A'], cwd=build_ctx.chromium_src)
|
|
run_git_command(
|
|
['git', 'commit', '-m', f'Apply {feature_name}: {Path(file_path).name}'],
|
|
cwd=build_ctx.chromium_src
|
|
)
|
|
else:
|
|
log_error(f" ✗ Failed: {file_path}")
|
|
failed.append(file_path)
|
|
|
|
# Summary
|
|
log_info(f"\nSummary: {applied} applied, {len(failed)} failed")
|
|
|
|
if failed:
|
|
log_error("Failed patches:")
|
|
for p in failed:
|
|
log_error(f" - {p}")
|
|
ctx.exit(1) |