flet-cli 0.82.3.dev7877__tar.gz → 0.82.3.dev7883__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/PKG-INFO +2 -2
  2. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/pyproject.toml +2 -2
  3. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/build.py +2 -0
  4. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/build_base.py +58 -17
  5. flet_cli-0.82.3.dev7883/src/flet_cli/utils/cli.py +8 -0
  6. flet_cli-0.82.3.dev7883/src/flet_cli/utils/plist.py +42 -0
  7. flet_cli-0.82.3.dev7883/src/flet_cli/version.py +1 -0
  8. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/PKG-INFO +2 -2
  9. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/SOURCES.txt +4 -1
  10. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/requires.txt +1 -1
  11. flet_cli-0.82.3.dev7883/tests/test_plist.py +52 -0
  12. flet_cli-0.82.3.dev7877/src/flet_cli/version.py +0 -1
  13. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/README.md +0 -0
  14. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/setup.cfg +0 -0
  15. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/__init__.py +0 -0
  16. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/config.py +0 -0
  17. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/hook-flet.py +0 -0
  18. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/macos_utils.py +0 -0
  19. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/rthooks/pyi_rth_localhost_fletd.py +0 -0
  20. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/utils.py +0 -0
  21. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/__pyinstaller/win_utils.py +0 -0
  22. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/cli.py +0 -0
  23. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/base.py +0 -0
  24. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/create.py +0 -0
  25. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/debug.py +0 -0
  26. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/devices.py +0 -0
  27. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/doctor.py +0 -0
  28. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/emulators.py +0 -0
  29. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/flutter_base.py +0 -0
  30. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/options.py +0 -0
  31. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/pack.py +0 -0
  32. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/publish.py +0 -0
  33. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/run.py +0 -0
  34. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/commands/serve.py +0 -0
  35. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/android_sdk.py +0 -0
  36. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/distros.py +0 -0
  37. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/flutter.py +0 -0
  38. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/hash_stamp.py +0 -0
  39. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/jdk.py +0 -0
  40. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/merge.py +0 -0
  41. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/processes.py +0 -0
  42. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/project_dependencies.py +0 -0
  43. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli/utils/pyproject_toml.py +0 -0
  44. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/dependency_links.txt +0 -0
  45. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/entry_points.txt +0 -0
  46. {flet_cli-0.82.3.dev7877 → flet_cli-0.82.3.dev7883}/src/flet_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-cli
3
- Version: 0.82.3.dev7877
3
+ Version: 0.82.3.dev7883
4
4
  Summary: Flet CLI
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet==0.82.3.dev7877
12
+ Requires-Dist: flet==0.82.3.dev7883
13
13
  Requires-Dist: watchdog>=4.0.0
14
14
  Requires-Dist: packaging>=25.0
15
15
  Requires-Dist: qrcode>=7.4.2
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "flet-cli"
3
- version = "0.82.3.dev7877"
3
+ version = "0.82.3.dev7883"
4
4
  description = "Flet CLI"
5
5
  authors = [{ name = "Appveyor Systems Inc.", email = "hello@flet.dev" }]
6
6
  license = "Apache-2.0"
7
7
  readme = "README.md"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
- "flet==0.82.3.dev7877",
10
+ "flet==0.82.3.dev7883",
11
11
  "watchdog >=4.0.0",
12
12
  "packaging >=25.0",
13
13
  "qrcode >=7.4.2",
@@ -12,6 +12,8 @@ class Command(BaseBuildCommand):
12
12
  installable bundle. It supports building for desktop (macOS, Linux, Windows), web,
13
13
  Android (APK/AAB), and iOS (IPA and simulator .app), with a wide range of
14
14
  customization options for metadata, assets, splash screens, and signing.
15
+
16
+ Detailed guide with usage examples: https://docs.flet.dev/publish
15
17
  """
16
18
 
17
19
  def __init__(self, parser: argparse.ArgumentParser) -> None:
@@ -23,8 +23,10 @@ from flet_cli.commands.flutter_base import (
23
23
  verbose2_style,
24
24
  warning_style,
25
25
  )
26
+ from flet_cli.utils.cli import parse_cli_bool_value
26
27
  from flet_cli.utils.hash_stamp import HashStamp
27
28
  from flet_cli.utils.merge import merge_dict
29
+ from flet_cli.utils.plist import is_supported_plist_value, parse_cli_plist_value
28
30
  from flet_cli.utils.project_dependencies import (
29
31
  get_poetry_dependencies,
30
32
  get_project_dependencies,
@@ -250,8 +252,8 @@ class BaseBuildCommand(BaseFlutterCommand):
250
252
  action="extend",
251
253
  nargs="+",
252
254
  default=[],
253
- help="Files and/or directories to exclude from the package "
254
- "(can be used multiple times)",
255
+ help="Files and/or directories to exclude from the package"
256
+ "; can be used multiple times",
255
257
  )
256
258
  parser.add_argument(
257
259
  "--clear-cache",
@@ -499,42 +501,49 @@ class BaseBuildCommand(BaseFlutterCommand):
499
501
  parser.add_argument(
500
502
  "--info-plist",
501
503
  dest="info_plist",
504
+ action="extend",
502
505
  nargs="+",
503
506
  default=[],
504
- help="The list of `<key>=<value>|True|False` pairs to add to Info.plist "
505
- "for macOS and iOS builds (macos, ipa and ios-simulator only)",
507
+ help="The list of `<key>=<value>` pairs to add to Info.plist. Values can "
508
+ "be booleans, strings, numbers, TOML arrays, or TOML inline tables "
509
+ "(macos, ipa and ios-simulator only); can be used multiple times",
506
510
  )
507
511
  parser.add_argument(
508
512
  "--macos-entitlements",
509
513
  dest="macos_entitlements",
514
+ action="extend",
510
515
  nargs="+",
511
516
  default=[],
512
- help="The list of `<key>=<value>|True|False` entitlements for "
513
- "macOS builds (macos only)",
517
+ help="The list of `<key>=<value>` entitlements. Values can be booleans, "
518
+ "strings, numbers, TOML arrays, or TOML inline tables "
519
+ "(macos only); can be used multiple times",
514
520
  )
515
521
  parser.add_argument(
516
522
  "--android-features",
517
523
  dest="android_features",
524
+ action="extend",
518
525
  nargs="+",
519
526
  default=[],
520
- help="The list of `<feature_name>=True|False` features to add to "
521
- "AndroidManifest.xml for Android builds (android only)",
527
+ help="The list of `<feature_name>=true|false` features to add to "
528
+ "AndroidManifest.xml (android only); can be used multiple times",
522
529
  )
523
530
  parser.add_argument(
524
531
  "--android-permissions",
525
532
  dest="android_permissions",
533
+ action="extend",
526
534
  nargs="+",
527
535
  default=[],
528
- help="The list of `<permission_name>=True|False` permissions to add to "
529
- "AndroidManifest.xml for Android builds (android only)",
536
+ help="The list of `<permission_name>=true|false` permissions to add to "
537
+ "AndroidManifest.xml (android only); can be used multiple times",
530
538
  )
531
539
  parser.add_argument(
532
540
  "--android-meta-data",
533
541
  dest="android_meta_data",
542
+ action="extend",
534
543
  nargs="+",
535
544
  default=[],
536
545
  help="The list of `<name>=<value>` app meta-data entries to add to "
537
- "AndroidManifest.xml for Android builds (android only)",
546
+ "AndroidManifest.xml (android only); can be used multiple times",
538
547
  )
539
548
  parser.add_argument(
540
549
  "--permissions",
@@ -853,12 +862,20 @@ class BaseBuildCommand(BaseFlutterCommand):
853
862
  if i > -1:
854
863
  k = p[:i]
855
864
  v = p[i + 1 :]
856
- info_plist[k] = (
857
- (v.lower() == "true") if v.lower() in {"true", "false"} else v
858
- )
865
+ info_plist[k] = parse_cli_plist_value(v)
859
866
  else:
860
867
  self.cleanup(1, f"Invalid Info.plist option: {p}")
861
868
 
869
+ for key, value in info_plist.items():
870
+ if not is_supported_plist_value(value):
871
+ self.cleanup(
872
+ 1,
873
+ "Unsupported Info.plist value type for "
874
+ f"{key}: {type(value).__name__}. Supported types are "
875
+ "string, boolean, integer, float, dictionary, and arrays "
876
+ "containing those values.",
877
+ )
878
+
862
879
  macos_entitlements = merge_dict(
863
880
  macos_entitlements,
864
881
  self.get_pyproject("tool.flet.macos.entitlement") or {},
@@ -868,10 +885,20 @@ class BaseBuildCommand(BaseFlutterCommand):
868
885
  for p in self.options.macos_entitlements:
869
886
  i = p.find("=")
870
887
  if i > -1:
871
- macos_entitlements[p[:i]] = p[i + 1 :] == "True"
888
+ macos_entitlements[p[:i]] = parse_cli_plist_value(p[i + 1 :])
872
889
  else:
873
890
  self.cleanup(1, f"Invalid macOS entitlement option: {p}")
874
891
 
892
+ for key, value in macos_entitlements.items():
893
+ if not is_supported_plist_value(value):
894
+ self.cleanup(
895
+ 1,
896
+ "Unsupported macOS entitlement value type for "
897
+ f"{key}: {type(value).__name__}. Supported types are "
898
+ "string, boolean, integer, float, dictionary, and arrays "
899
+ "containing those values.",
900
+ )
901
+
875
902
  android_permissions = merge_dict(
876
903
  android_permissions,
877
904
  self.get_pyproject("tool.flet.android.permission") or {},
@@ -881,7 +908,14 @@ class BaseBuildCommand(BaseFlutterCommand):
881
908
  for p in self.options.android_permissions:
882
909
  i = p.find("=")
883
910
  if i > -1:
884
- android_permissions[p[:i]] = p[i + 1 :] == "True"
911
+ try:
912
+ android_permissions[p[:i]] = parse_cli_bool_value(p[i + 1 :])
913
+ except ValueError:
914
+ self.cleanup(
915
+ 1,
916
+ f"Invalid Android permission option value for {p[:i]}: "
917
+ f"{p[i + 1 :]}. Expected true or false.",
918
+ )
885
919
  else:
886
920
  self.cleanup(1, f"Invalid Android permission option: {p}")
887
921
 
@@ -894,7 +928,14 @@ class BaseBuildCommand(BaseFlutterCommand):
894
928
  for p in self.options.android_features:
895
929
  i = p.find("=")
896
930
  if i > -1:
897
- android_features[p[:i]] = p[i + 1 :] == "True"
931
+ try:
932
+ android_features[p[:i]] = parse_cli_bool_value(p[i + 1 :])
933
+ except ValueError:
934
+ self.cleanup(
935
+ 1,
936
+ f"Invalid Android feature option value for {p[:i]}: "
937
+ f"{p[i + 1 :]}. Expected true or false.",
938
+ )
898
939
  else:
899
940
  self.cleanup(1, f"Invalid Android feature option: {p}")
900
941
 
@@ -0,0 +1,8 @@
1
+ def parse_cli_bool_value(value: str) -> bool:
2
+ """Parse a CLI boolean value, accepting only true/false tokens."""
3
+ normalized = value.strip().lower()
4
+ if normalized == "true":
5
+ return True
6
+ if normalized == "false":
7
+ return False
8
+ raise ValueError("expected true or false")
@@ -0,0 +1,42 @@
1
+ try:
2
+ import tomllib
3
+ except ModuleNotFoundError:
4
+ import tomli as tomllib
5
+
6
+
7
+ def is_supported_plist_value(value) -> bool:
8
+ """Checks if the value is a supported type for plist values."""
9
+ # string and boolean
10
+ if isinstance(value, (str, bool)):
11
+ return True
12
+ # integer and float/real
13
+ if isinstance(value, (int, float)):
14
+ return True
15
+ # array
16
+ if isinstance(value, list):
17
+ return all(is_supported_plist_value(item) for item in value)
18
+ # dictionary
19
+ if isinstance(value, dict):
20
+ return all(
21
+ isinstance(key, str) and is_supported_plist_value(item)
22
+ for key, item in value.items()
23
+ )
24
+ return False
25
+
26
+
27
+ def parse_cli_plist_value(value: str):
28
+ """Parses a CLI-provided plist value, supporting TOML syntax for complex types."""
29
+ value = value.strip()
30
+ lowered = value.lower()
31
+ if lowered in {"true", "false"}:
32
+ return lowered == "true"
33
+
34
+ try:
35
+ parsed = tomllib.loads(f"value = {value}")["value"]
36
+ except Exception:
37
+ return value
38
+
39
+ if is_supported_plist_value(parsed):
40
+ return parsed
41
+
42
+ return value
@@ -0,0 +1 @@
1
+ version = "0.82.3.dev7883"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-cli
3
- Version: 0.82.3.dev7877
3
+ Version: 0.82.3.dev7883
4
4
  Summary: Flet CLI
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet==0.82.3.dev7877
12
+ Requires-Dist: flet==0.82.3.dev7883
13
13
  Requires-Dist: watchdog>=4.0.0
14
14
  Requires-Dist: packaging>=25.0
15
15
  Requires-Dist: qrcode>=7.4.2
@@ -30,11 +30,14 @@ src/flet_cli/commands/publish.py
30
30
  src/flet_cli/commands/run.py
31
31
  src/flet_cli/commands/serve.py
32
32
  src/flet_cli/utils/android_sdk.py
33
+ src/flet_cli/utils/cli.py
33
34
  src/flet_cli/utils/distros.py
34
35
  src/flet_cli/utils/flutter.py
35
36
  src/flet_cli/utils/hash_stamp.py
36
37
  src/flet_cli/utils/jdk.py
37
38
  src/flet_cli/utils/merge.py
39
+ src/flet_cli/utils/plist.py
38
40
  src/flet_cli/utils/processes.py
39
41
  src/flet_cli/utils/project_dependencies.py
40
- src/flet_cli/utils/pyproject_toml.py
42
+ src/flet_cli/utils/pyproject_toml.py
43
+ tests/test_plist.py
@@ -1,4 +1,4 @@
1
- flet==0.82.3.dev7877
1
+ flet==0.82.3.dev7883
2
2
  watchdog>=4.0.0
3
3
  packaging>=25.0
4
4
  qrcode>=7.4.2
@@ -0,0 +1,52 @@
1
+ from flet_cli.utils.plist import is_supported_plist_value, parse_cli_plist_value
2
+
3
+
4
+ def test_parse_cli_plist_value_supports_strings_and_booleans():
5
+ """Strings and booleans should parse into their respective Python types."""
6
+ assert parse_cli_plist_value("true") is True
7
+ assert parse_cli_plist_value("False") is False
8
+ assert parse_cli_plist_value("TEAMID.example.app") == "TEAMID.example.app"
9
+
10
+
11
+ def test_parse_cli_plist_value_keeps_quoted_literals_as_strings():
12
+ """Quoted literals should remain strings even if they look typed."""
13
+ assert parse_cli_plist_value('"true"') == "true"
14
+ assert parse_cli_plist_value('"false"') == "false"
15
+ assert parse_cli_plist_value('"42"') == "42"
16
+ assert parse_cli_plist_value('"3.14"') == "3.14"
17
+
18
+
19
+ def test_parse_cli_plist_value_supports_integers_and_floats():
20
+ """Numeric TOML literals should parse into Python numbers."""
21
+ assert parse_cli_plist_value("42") == 42
22
+ assert parse_cli_plist_value("3.14") == 3.14
23
+
24
+
25
+ def test_parse_cli_plist_value_supports_toml_arrays():
26
+ """TOML arrays should parse into Python lists."""
27
+ assert parse_cli_plist_value('["group.dev.example", "group.dev.shared"]') == [
28
+ "group.dev.example",
29
+ "group.dev.shared",
30
+ ]
31
+
32
+
33
+ def test_parse_cli_plist_value_supports_toml_inline_tables():
34
+ """TOML inline tables should parse into Python dictionaries."""
35
+ assert parse_cli_plist_value('{ "com.apple.mail" = ["compose"] }') == {
36
+ "com.apple.mail": ["compose"]
37
+ }
38
+
39
+
40
+ def test_supported_plist_value_accepts_numbers():
41
+ """The plist validator should accept integer and real values."""
42
+ assert is_supported_plist_value(1)
43
+ assert is_supported_plist_value(1.5)
44
+ assert is_supported_plist_value(["group.dev.example", 1, 1.5])
45
+ assert is_supported_plist_value({"com.apple.mail": 1})
46
+
47
+
48
+ def test_unsupported_plist_types_are_rejected():
49
+ """The plist validator should reject null values recursively."""
50
+ assert not is_supported_plist_value(None)
51
+ assert not is_supported_plist_value(["group.dev.example", None])
52
+ assert not is_supported_plist_value({"com.apple.mail": None})
@@ -1 +0,0 @@
1
- version = "0.82.3.dev7877"