Пример #1
0
async def gen_main(cmd_input: Optional[List[str]] = None) -> int:
    # Make sure all files are created with global rw permissions
    os.umask(0o000)
    # Setup parser
    parser = argparse.ArgumentParser(
        description="idb: a versatile tool to communicate with iOS Simulators and Devices",
        epilog="See Also: https://www.fbidb.io/docs/guided-tour",
        formatter_class=argparse.RawTextHelpFormatter,
    )
    parser.add_argument(
        "--log",
        dest="log_level",
        choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
        default="WARNING",
        help="Set the logging level",
    )
    parser.add_argument(
        "--companion",
        type=str,
        default=os.environ.get("IDB_COMPANION"),
        help="A string of the form HOSTNAME:PORT that will describe the companion connect to."
        "Can also be set with the IDB_COMPANION environment variable",
    )
    parser.add_argument(
        "--companion-path",
        type=str,
        default="/usr/local/bin/idb_companion" if sys.platform == "darwin" else None,
        help="The path to the idb companion binary. This is only valid when running on macOS platforms",
    )
    parser.add_argument(
        "--companion-local",
        action="store_true",
        default=bool(os.environ.get("IDB_COMPANION_LOCAL")),
        help="If set, any companion provided via IDB_COMPANION or --companion will be assumed to be running on this host."
        "Even if the companion provided is 'localhost' idb will still assume it is remote."
        "The reason for this is that idb shouldn't assume there are no tunnels from localhost to a remote host."
        "Can also be set with the IDB_COMPANION_LOCAL environment variable",
    )
    parser.add_argument(
        "--no-prune-dead-companion",
        dest="prune_dead_companion",
        action="store_false",
        default=True,
        help="If flagged will not modify local state when a companion is known to be unresponsive",
    )
    commands: List[Command] = [
        AppInstallCommand(),
        AppUninstallCommand(),
        AppListCommand(),
        LaunchCommand(),
        AppTerminateCommand(),
        CommandGroup(
            name="xctest",
            description="Operations with xctest on target",
            commands=[
                XctestInstallCommand(),
                XctestsListBundlesCommand(),
                XctestListTestsCommand(),
                XctestRunCommand(),
            ],
        ),
        CommandGroup(
            name="file",
            description="File operations on target",
            commands=[
                FSMoveCommand(),
                FSPullCommand(),
                FSPushCommand(),
                FSMkdirCommand(),
                FSRemoveCommand(),
                FSListCommand(),
                FSShowCommand(),
            ],
        ),
        CommandGroup(
            name="contacts",
            description="Contacts database operations on target",
            commands=[ContactsUpdateCommand()],
        ),
        LogCommand(),
        CommandGroup(
            name="record",
            description="Record what the screen is doing",
            commands=[VideoRecordCommand()],
        ),
        VideoRecordCommand(),
        VideoStreamCommand(),
        DeprecatedPushCommand(),
        DeprecatedPullCommand(),
        UrlOpenCommand(),
        KeychainClearCommand(),
        LocationSetCommand(),
        ApproveCommand(),
        TargetConnectCommand(),
        TargetDisconnectCommand(),
        TargetListCommand(),
        TargetDescribeCommand(),
        TargetCreateCommand(),
        TargetBootCommand(),
        TargetShutdownCommand(),
        TargetEraseCommand(),
        TargetCloneCommand(),
        TargetDeleteCommand(),
        TargetDeleteAllCommand(),
        DaemonCommand(),
        ScreenshotCommand(),
        CommandGroup(
            name="ui",
            description="UI interactions on target",
            commands=[
                AccessibilityInfoAllCommand(),
                AccessibilityInfoAtPointCommand(),
                TapCommand(),
                ButtonCommand(),
                TextCommand(),
                KeyCommand(),
                KeySequenceCommand(),
                SwipeCommand(),
            ],
        ),
        CommandGroup(
            name="crash",
            description="Operations on crashes",
            commands=[CrashListCommand(), CrashShowCommand(), CrashDeleteCommand()],
        ),
        InstrumentsCommand(),
        KillCommand(),
        MediaAddCommand(),
        FocusCommand(),
        CommandGroup(
            name="debugserver",
            description="debugserver interactions",
            commands=[
                DebugServerStartCommand(),
                DebugServerStopCommand(),
                DebugServerStatusCommand(),
            ],
        ),
        CommandGroup(
            name="dsym", description="dsym commands", commands=[DsymInstallCommand()]
        ),
        CommandGroup(
            name="dylib", description="dylib commands", commands=[DylibInstallCommand()]
        ),
        CommandGroup(
            name="framework",
            description="framework commands",
            commands=[FrameworkInstallCommand()],
        ),
        CommandGroup(
            name="companion",
            description="commands related to the companion",
            commands=[CompanionLogCommand()],
        ),
    ]
    commands.extend(plugin.get_commands())
    root_command = CommandGroup(
        name="root_command",
        description="",
        commands=sorted(commands, key=lambda command: command.name),
    )
    root_command.add_parser_arguments(parser)

    # Parse input and run
    cmd_input = cmd_input or sys.argv[1:]

    try:
        args = parser.parse_args(cmd_input)
        plugin.on_launch(logger)
        await root_command.run(args)
        return 0
    except ConnectCommandException as e:
        print(str(e), file=sys.stderr)
        return 1
    except IdbException as e:
        print(e.args[0], file=sys.stderr)
        return 1
    except Exception:
        logger.exception("Exception thrown in main")
        return 1
    finally:
        await plugin.on_close(logger)
        pending = set(asyncio.all_tasks())
        current_task = asyncio.current_task()
        if current_task is not None:
            pending.discard(current_task)
        await drain_coroutines(pending)