Исправил adb окружение для списка устройств
Этот коммит содержится в:
@@ -8,21 +8,35 @@ DATA_DIR = Path(os.getenv('DEVCONSOLE_DATA_DIR', '/var/lib/devconsole'))
|
|||||||
PROJECTS_DIR = DATA_DIR / 'projects'
|
PROJECTS_DIR = DATA_DIR / 'projects'
|
||||||
|
|
||||||
|
|
||||||
|
def _runtime_env_prefix() -> str:
|
||||||
|
runtime_home = os.getenv('DEVCONSOLE_RUNTIME_HOME') or os.getenv('HOME') or '/home/devconsole'
|
||||||
|
android_home = os.getenv('ANDROID_HOME') or os.getenv('ANDROID_SDK_ROOT') or f'{runtime_home}/Android'
|
||||||
|
flutter_home = os.getenv('FLUTTER_HOME') or f'{runtime_home}/flutter'
|
||||||
|
return (
|
||||||
|
f'export HOME="{runtime_home}" '
|
||||||
|
f'ANDROID_HOME="{android_home}" '
|
||||||
|
f'ANDROID_SDK_ROOT="{android_home}" '
|
||||||
|
f'PATH="{flutter_home}/bin:{android_home}/cmdline-tools/latest/bin:{android_home}/platform-tools:$PATH" && '
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _adb(command: str) -> str:
|
||||||
|
return f'{_runtime_env_prefix()}adb {command}'
|
||||||
|
|
||||||
|
|
||||||
def list_devices() -> dict:
|
def list_devices() -> dict:
|
||||||
result = run_command('adb devices -l', PROJECTS_DIR.as_posix(), timeout=60)
|
result = run_command(_adb('devices -l'), PROJECTS_DIR.as_posix(), timeout=60)
|
||||||
result['devices'] = parse_devices(result.get('stdout', ''))
|
result['devices'] = parse_devices(result.get('stdout', ''))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _parse_adb_line_metadata(parts: list[str]) -> dict[str, str]:
|
def _parse_adb_line_metadata(parts: list[str]) -> dict[str, str]:
|
||||||
metadata: dict[str, str] = {}
|
metadata: dict[str, str] = {}
|
||||||
|
|
||||||
for part in parts[2:]:
|
for part in parts[2:]:
|
||||||
if ':' not in part:
|
if ':' not in part:
|
||||||
continue
|
continue
|
||||||
key, value = part.split(':', 1)
|
key, value = part.split(':', 1)
|
||||||
metadata[key.strip()] = value.strip()
|
metadata[key.strip()] = value.strip()
|
||||||
|
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
@@ -32,36 +46,25 @@ def _pretty_token(value: str) -> str:
|
|||||||
|
|
||||||
def parse_devices(stdout: str) -> list[dict]:
|
def parse_devices(stdout: str) -> list[dict]:
|
||||||
devices: list[dict] = []
|
devices: list[dict] = []
|
||||||
|
|
||||||
for line in stdout.splitlines():
|
for line in stdout.splitlines():
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line or line.startswith('List of devices'):
|
if not line or line.startswith('List of devices'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
parts = line.split()
|
parts = line.split()
|
||||||
if len(parts) < 2:
|
if len(parts) < 2:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
serial = parts[0]
|
serial = parts[0]
|
||||||
state = parts[1]
|
state = parts[1]
|
||||||
adb_meta = _parse_adb_line_metadata(parts)
|
adb_meta = _parse_adb_line_metadata(parts)
|
||||||
|
|
||||||
if state != 'device':
|
if state != 'device':
|
||||||
devices.append({
|
devices.append({'serial': serial, 'state': state, 'title': f'{serial} ({state})', 'subtitle': 'Устройство не готово'})
|
||||||
'serial': serial,
|
|
||||||
'state': state,
|
|
||||||
'title': f'{serial} ({state})',
|
|
||||||
'subtitle': 'Устройство не готово',
|
|
||||||
})
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
props = get_device_props(serial)
|
props = get_device_props(serial)
|
||||||
brand = props.get('brand') or adb_meta.get('product') or ''
|
brand = props.get('brand') or adb_meta.get('product') or ''
|
||||||
model = props.get('model') or adb_meta.get('model') or ''
|
model = props.get('model') or adb_meta.get('model') or ''
|
||||||
device = props.get('device') or adb_meta.get('device') or ''
|
device = props.get('device') or adb_meta.get('device') or ''
|
||||||
android = props.get('android') or ''
|
android = props.get('android') or ''
|
||||||
sdk = props.get('sdk') or ''
|
sdk = props.get('sdk') or ''
|
||||||
|
|
||||||
title_parts = []
|
title_parts = []
|
||||||
if brand:
|
if brand:
|
||||||
title_parts.append(_pretty_token(brand).title())
|
title_parts.append(_pretty_token(brand).title())
|
||||||
@@ -69,9 +72,7 @@ def parse_devices(stdout: str) -> list[dict]:
|
|||||||
title_parts.append(_pretty_token(model))
|
title_parts.append(_pretty_token(model))
|
||||||
if not title_parts and device:
|
if not title_parts and device:
|
||||||
title_parts.append(_pretty_token(device))
|
title_parts.append(_pretty_token(device))
|
||||||
|
|
||||||
title = ' '.join(title_parts).strip() or serial
|
title = ' '.join(title_parts).strip() or serial
|
||||||
|
|
||||||
subtitle_parts = []
|
subtitle_parts = []
|
||||||
if android:
|
if android:
|
||||||
subtitle_parts.append(f'Android {android}')
|
subtitle_parts.append(f'Android {android}')
|
||||||
@@ -82,7 +83,6 @@ def parse_devices(stdout: str) -> list[dict]:
|
|||||||
if adb_meta.get('transport_id'):
|
if adb_meta.get('transport_id'):
|
||||||
subtitle_parts.append(f"transport {adb_meta['transport_id']}")
|
subtitle_parts.append(f"transport {adb_meta['transport_id']}")
|
||||||
subtitle_parts.append(serial)
|
subtitle_parts.append(serial)
|
||||||
|
|
||||||
devices.append({
|
devices.append({
|
||||||
'serial': serial,
|
'serial': serial,
|
||||||
'state': state,
|
'state': state,
|
||||||
@@ -95,28 +95,24 @@ def parse_devices(stdout: str) -> list[dict]:
|
|||||||
'title': title,
|
'title': title,
|
||||||
'subtitle': ' · '.join(subtitle_parts),
|
'subtitle': ' · '.join(subtitle_parts),
|
||||||
})
|
})
|
||||||
|
|
||||||
return devices
|
return devices
|
||||||
|
|
||||||
|
|
||||||
def get_device_props(serial: str) -> dict:
|
def get_device_props(serial: str) -> dict:
|
||||||
commands = {
|
commands = {
|
||||||
'brand': f'adb -s {serial} shell getprop ro.product.brand',
|
'brand': _adb(f'-s {serial} shell getprop ro.product.brand'),
|
||||||
'model': f'adb -s {serial} shell getprop ro.product.model',
|
'model': _adb(f'-s {serial} shell getprop ro.product.model'),
|
||||||
'device': f'adb -s {serial} shell getprop ro.product.device',
|
'device': _adb(f'-s {serial} shell getprop ro.product.device'),
|
||||||
'android': f'adb -s {serial} shell getprop ro.build.version.release',
|
'android': _adb(f'-s {serial} shell getprop ro.build.version.release'),
|
||||||
'sdk': f'adb -s {serial} shell getprop ro.build.version.sdk',
|
'sdk': _adb(f'-s {serial} shell getprop ro.build.version.sdk'),
|
||||||
}
|
}
|
||||||
|
|
||||||
props: dict[str, str] = {}
|
props: dict[str, str] = {}
|
||||||
|
|
||||||
for key, command in commands.items():
|
for key, command in commands.items():
|
||||||
try:
|
try:
|
||||||
result = run_command(command, PROJECTS_DIR.as_posix(), timeout=20)
|
result = run_command(command, PROJECTS_DIR.as_posix(), timeout=20)
|
||||||
props[key] = (result.get('stdout') or '').strip()
|
props[key] = (result.get('stdout') or '').strip()
|
||||||
except Exception:
|
except Exception:
|
||||||
props[key] = ''
|
props[key] = ''
|
||||||
|
|
||||||
return props
|
return props
|
||||||
|
|
||||||
|
|
||||||
@@ -135,17 +131,13 @@ def find_apks(workspace: str) -> list[str]:
|
|||||||
|
|
||||||
def build_android(workspace: str) -> dict:
|
def build_android(workspace: str) -> dict:
|
||||||
root = Path(workspace).resolve()
|
root = Path(workspace).resolve()
|
||||||
|
|
||||||
if (root / 'pubspec.yaml').exists():
|
if (root / 'pubspec.yaml').exists():
|
||||||
return run_command('flutter build apk --debug', root.as_posix(), timeout=1800)
|
return run_command('flutter build apk --debug', root.as_posix(), timeout=1800)
|
||||||
|
|
||||||
gradlew = root / 'gradlew'
|
gradlew = root / 'gradlew'
|
||||||
if gradlew.exists():
|
if gradlew.exists():
|
||||||
return run_command('chmod +x ./gradlew && ./gradlew assembleDebug', root.as_posix(), timeout=1800)
|
return run_command('chmod +x ./gradlew && ./gradlew assembleDebug', root.as_posix(), timeout=1800)
|
||||||
|
|
||||||
if (root / 'android' / 'gradlew').exists():
|
if (root / 'android' / 'gradlew').exists():
|
||||||
return run_command('cd android && chmod +x ./gradlew && ./gradlew assembleDebug', root.as_posix(), timeout=1800)
|
return run_command('cd android && chmod +x ./gradlew && ./gradlew assembleDebug', root.as_posix(), timeout=1800)
|
||||||
|
|
||||||
return run_command('gradle assembleDebug', root.as_posix(), timeout=1800)
|
return run_command('gradle assembleDebug', root.as_posix(), timeout=1800)
|
||||||
|
|
||||||
|
|
||||||
@@ -153,4 +145,4 @@ def install_latest_apk(workspace: str) -> dict:
|
|||||||
apks = find_apks(workspace)
|
apks = find_apks(workspace)
|
||||||
if not apks:
|
if not apks:
|
||||||
raise ValueError('APK not found. Build project first.')
|
raise ValueError('APK not found. Build project first.')
|
||||||
return run_command(f'adb install -r "{apks[0]}"', Path(workspace).resolve().as_posix(), timeout=600)
|
return run_command(_adb(f'install -r "{apks[0]}"'), Path(workspace).resolve().as_posix(), timeout=600)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user