Skip to content

Commit 96739fb

Browse files
committed
Add devices command and refactor build/debug initialization
Introduces a new 'devices' command to list connected devices via Flutter. Refactors build and debug commands to use a unified 'initialize_command' method, moving progress and verbose handling to the base class. Updates CLI registration to include the new devices command.
1 parent 0a23cc7 commit 96739fb

File tree

6 files changed

+107
-33
lines changed

6 files changed

+107
-33
lines changed

sdk/python/packages/flet-cli/src/flet_cli/cli.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import flet_cli.commands.build
66
import flet_cli.commands.create
77
import flet_cli.commands.debug
8+
import flet_cli.commands.devices
89
import flet_cli.commands.doctor # Adding the doctor command
910
import flet_cli.commands.pack
1011
import flet_cli.commands.publish
@@ -83,6 +84,7 @@ def get_parser() -> argparse.ArgumentParser:
8384
flet_cli.commands.pack.Command.register_to(sp, "pack")
8485
flet_cli.commands.publish.Command.register_to(sp, "publish")
8586
flet_cli.commands.serve.Command.register_to(sp, "serve")
87+
flet_cli.commands.devices.Command.register_to(sp, "devices")
8688
flet_cli.commands.doctor.Command.register_to(sp, "doctor")
8789

8890
# set "run" as the default subparser

sdk/python/packages/flet-cli/src/flet_cli/commands/build.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from rich.console import Group
44
from rich.live import Live
5-
from rich.progress import Progress
65

76
from flet_cli.commands.build_base import BaseBuildCommand, console
87

@@ -42,11 +41,8 @@ def handle(self, options: argparse.Namespace) -> None:
4241
f"[bold blue]Initializing {self.target_platform} build...",
4342
spinner="bouncingBall",
4443
)
45-
self.progress = Progress(transient=True)
46-
self.no_rich_output = self.no_rich_output or self.options.no_rich_output
47-
self.verbose = self.options.verbose
4844
with Live(Group(self.status, self.progress), console=console) as self.live:
49-
self.initialize_build()
45+
self.initialize_command()
5046
self.validate_target_platform()
5147
self.validate_entry_point()
5248
self.setup_template_data()

sdk/python/packages/flet-cli/src/flet_cli/commands/build_base.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@
1717
import flet.version
1818
import flet_cli.utils.processes as processes
1919
from flet.utils import copy_tree, is_windows, slugify
20-
from flet.utils.platform_utils import get_bool_env_var
2120
from flet.version import update_version
2221
from flet_cli.commands.flutter_base import (
2322
BaseFlutterCommand,
2423
console,
2524
error_style,
26-
no_rich_output,
2725
verbose1_style,
2826
verbose2_style,
2927
warning_style,
@@ -48,34 +46,22 @@ class BaseBuildCommand(BaseFlutterCommand):
4846
def __init__(self, parser: argparse.ArgumentParser) -> None:
4947
super().__init__(parser)
5048

51-
self.env = {}
5249
self.pubspec_path = None
5350
self.rel_out_dir = None
5451
self.assets_path = None
5552
self.target_platform = None
56-
self.debug_platform = None
57-
self.package_platform = None
58-
self.config_platform = None
5953
self.flutter_dependencies = {}
6054
self.package_app_path = None
61-
self.options = None
6255
self.template_data = None
6356
self.python_module_filename = None
6457
self.out_dir = None
6558
self.python_module_name = None
6659
self.get_pyproject = None
6760
self.python_app_path = None
68-
self.emojis = {}
69-
self.dart_exe = None
70-
self.verbose = False
7161
self.build_dir = None
7262
self.flutter_dir: Optional[Path] = None
7363
self.flutter_packages_dir = None
7464
self.flutter_packages_temp_dir = None
75-
self.flutter_exe = None
76-
self.skip_flutter_doctor = get_bool_env_var("FLET_CLI_SKIP_FLUTTER_DOCTOR")
77-
self.no_rich_output = no_rich_output
78-
self.current_platform = platform.system()
7965
self.platforms = {
8066
"windows": {
8167
"package_platform": "Windows",
@@ -607,16 +593,17 @@ def handle(self, options: argparse.Namespace) -> None:
607593
if "target_platform" in self.options:
608594
self.target_platform = self.options.target_platform
609595

610-
def initialize_build(self):
596+
def initialize_command(self):
611597
assert self.options
612598
assert self.target_platform
613-
super().initialize_build()
614-
615-
self.python_app_path = Path(self.options.python_app_path).resolve()
616599

617600
self.package_platform = self.platforms[self.target_platform]["package_platform"]
618601
self.config_platform = self.platforms[self.target_platform]["config_platform"]
619602

603+
super().initialize_command()
604+
605+
self.python_app_path = Path(self.options.python_app_path).resolve()
606+
620607
if not (
621608
os.path.exists(self.python_app_path) or os.path.isdir(self.python_app_path)
622609
):

sdk/python/packages/flet-cli/src/flet_cli/commands/debug.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from rich.console import Group
77
from rich.live import Live
8-
from rich.progress import Progress
98

109
from flet_cli.commands.build_base import BaseBuildCommand, console, verbose2_style
1110

@@ -17,7 +16,6 @@ class Command(BaseBuildCommand):
1716

1817
def __init__(self, parser: argparse.ArgumentParser) -> None:
1918
super().__init__(parser)
20-
2119
self.debug_platforms = {
2220
"windows": {"target_platform": "windows", "device_id": "windows"},
2321
"macos": {"target_platform": "macos", "device_id": "macos"},
@@ -26,6 +24,7 @@ def __init__(self, parser: argparse.ArgumentParser) -> None:
2624
"ios": {"target_platform": "ipa", "device_id": None},
2725
"android": {"target_platform": "apk", "device_id": None},
2826
}
27+
self.debug_platform = None
2928
self.device_id = None
3029

3130
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
@@ -86,12 +85,9 @@ def handle(self, options: argparse.Namespace) -> None:
8685
f"[bold blue]Initializing {self.target_platform} debug session...",
8786
spinner="bouncingBall",
8887
)
89-
self.progress = Progress(transient=True)
90-
self.no_rich_output = self.no_rich_output or self.options.no_rich_output
91-
self.verbose = self.options.verbose
9288
with Live(Group(self.status, self.progress), console=console) as self.live:
9389
self.check_device_id()
94-
self.initialize_build()
90+
self.initialize_command()
9591
if self.options.show_devices:
9692
self.run_flutter_devices()
9793
self.live.update("", refresh=True)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import argparse
2+
import os
3+
4+
from rich.console import Group
5+
from rich.live import Live
6+
7+
from flet_cli.commands.build_base import BaseFlutterCommand, console, verbose2_style
8+
9+
10+
class Command(BaseFlutterCommand):
11+
"""
12+
List all connected devices.
13+
"""
14+
15+
def __init__(self, parser: argparse.ArgumentParser) -> None:
16+
super().__init__(parser)
17+
self.devices_platform = None
18+
19+
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
20+
parser.add_argument(
21+
"platform",
22+
type=str,
23+
nargs="?",
24+
choices=["ios", "android", "web"],
25+
help="The target platform to list devices for. "
26+
"If not specified, lists all platforms.",
27+
)
28+
# parser.add_argument(
29+
# "--device-id",
30+
# "-d",
31+
# type=str,
32+
# dest="device_id",
33+
# help="Device ID to run the app on for iOS and Android builds.",
34+
# )
35+
# parser.add_argument(
36+
# "--show-devices",
37+
# dest="show_devices",
38+
# action="store_true",
39+
# default=False,
40+
# help="Show connected devices for iOS and Android builds.",
41+
# )
42+
# parser.add_argument(
43+
# "--release",
44+
# dest="release",
45+
# action="store_true",
46+
# default=False,
47+
# help="Build the app in release mode.",
48+
# )
49+
# parser.add_argument(
50+
# "--route",
51+
# type=str,
52+
# dest="route",
53+
# help="Route to open the app on for web, iOS and Android builds.",
54+
# )
55+
super().add_arguments(parser)
56+
57+
def handle(self, options: argparse.Namespace) -> None:
58+
super().handle(options)
59+
if self.options and "platform" in self.options and self.options.platform:
60+
self.devices_platform = self.options.platform
61+
62+
self.status = console.status(
63+
"[bold blue]Initializing environment...",
64+
spinner="bouncingBall",
65+
)
66+
with Live(Group(self.status, self.progress), console=console) as self.live:
67+
self.initialize_command()
68+
# if self.options.show_devices:
69+
# self.run_flutter_devices()
70+
# self.live.update("", refresh=True)
71+
# return
72+
self.run_flutter_devices()
73+
self.cleanup(0, message=(""))
74+
75+
def initialize_command(self):
76+
self.package_platform = ""
77+
self.config_platform = ""
78+
79+
super().initialize_command()
80+
81+
def run_flutter_devices(self):
82+
self.update_status("[bold blue]Checking connected devices...")
83+
flutter_devices = self.run(
84+
[self.flutter_exe, "devices", "--no-version-check", "--suppress-analytics"],
85+
cwd=os.getcwd(),
86+
capture_output=True,
87+
)
88+
if flutter_devices.returncode == 0 and flutter_devices.stdout:
89+
console.log(flutter_devices.stdout, style=verbose2_style)

sdk/python/packages/flet-cli/src/flet_cli/commands/flutter_base.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from packaging import version
1010
from rich.console import Console, Group
1111
from rich.panel import Panel
12+
from rich.progress import Progress
1213
from rich.style import Style
1314
from rich.theme import Theme
1415

@@ -49,9 +50,12 @@ def __init__(self, parser: argparse.ArgumentParser) -> None:
4950
self.dart_exe = None
5051
self.flutter_exe = None
5152
self.verbose = False
53+
self.package_platform = None
54+
self.config_platform = None
5255
self.skip_flutter_doctor = get_bool_env_var("FLET_CLI_SKIP_FLUTTER_DOCTOR")
5356
self.no_rich_output = no_rich_output
5457
self.current_platform = platform.system()
58+
self.progress = Progress(transient=True)
5559

5660
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
5761
parser.add_argument(
@@ -69,10 +73,11 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
6973

7074
def handle(self, options: argparse.Namespace) -> None:
7175
self.options = options
76+
self.no_rich_output = self.no_rich_output or self.options.no_rich_output
77+
self.verbose = self.options.verbose
7278

73-
def initialize_build(self):
79+
def initialize_command(self):
7480
assert self.options
75-
assert self.target_platform
7681
self.emojis = {
7782
"checkmark": "[green]OK[/]" if self.no_rich_output else "✅",
7883
"loading": "" if self.no_rich_output else "⏳",
@@ -238,8 +243,7 @@ def run(self, args, cwd, env: Optional[dict] = None, capture_output=True):
238243

239244
def cleanup(self, exit_code: int, message: Optional[str] = None):
240245
if exit_code == 0:
241-
msg = message or f"Success! {self.emojis['success']}"
242-
self.live.update(Panel(msg), refresh=True)
246+
self.live.update(Panel(message) if message else "", refresh=True)
243247
else:
244248
msg = (
245249
message

0 commit comments

Comments
 (0)