kivyforge 3.0.0.dev0__py3-none-any.whl
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.
- kivyforge/__init__.py +9 -0
- kivyforge/artifacts/__init__.py +41 -0
- kivyforge/artifacts/cache.py +81 -0
- kivyforge/artifacts/collect.py +354 -0
- kivyforge/artifacts/download.py +125 -0
- kivyforge/artifacts/frameworks.py +240 -0
- kivyforge/artifacts/native_stage_util.py +346 -0
- kivyforge/artifacts/runtime.py +65 -0
- kivyforge/artifacts/verify.py +45 -0
- kivyforge/artifacts/wheels.py +89 -0
- kivyforge/bundle/__init__.py +1 -0
- kivyforge/bundle/pycompile.py +161 -0
- kivyforge/cli/__init__.py +52 -0
- kivyforge/cli/_common.py +62 -0
- kivyforge/cli/_platform.py +84 -0
- kivyforge/cli/build.py +111 -0
- kivyforge/cli/clean.py +135 -0
- kivyforge/cli/doctor.py +52 -0
- kivyforge/cli/init.py +612 -0
- kivyforge/cli/init_writer.py +716 -0
- kivyforge/cli/lock.py +261 -0
- kivyforge/cli/open_cmd.py +15 -0
- kivyforge/cli/package.py +134 -0
- kivyforge/cli/run.py +162 -0
- kivyforge/cli/status.py +20 -0
- kivyforge/cli/upgrade.py +314 -0
- kivyforge/config/__init__.py +46 -0
- kivyforge/config/errors.py +43 -0
- kivyforge/config/icons.py +60 -0
- kivyforge/config/loader.py +3079 -0
- kivyforge/config/model.py +817 -0
- kivyforge/doctor/__init__.py +19 -0
- kivyforge/doctor/checks_common.py +95 -0
- kivyforge/doctor/probe.py +357 -0
- kivyforge/doctor/result.py +41 -0
- kivyforge/lock/__init__.py +42 -0
- kivyforge/lock/_pip_shim.py +63 -0
- kivyforge/lock/find_links.py +182 -0
- kivyforge/lock/model.py +69 -0
- kivyforge/lock/pep751.py +111 -0
- kivyforge/lock/reader.py +30 -0
- kivyforge/lock/resolver.py +124 -0
- kivyforge/lock/wheelruntime/__init__.py +70 -0
- kivyforge/lock/wheelruntime/builder.py +280 -0
- kivyforge/lock/wheelruntime/model.py +94 -0
- kivyforge/lock/wheelruntime/native_binaries.py +127 -0
- kivyforge/lock/wheelruntime/pbs_github.py +133 -0
- kivyforge/lock/wheelruntime/profile.py +104 -0
- kivyforge/lock/wheelruntime/resolver.py +248 -0
- kivyforge/lock/wheelruntime/runtime.py +161 -0
- kivyforge/lock/wheelruntime/serialize.py +245 -0
- kivyforge/platforms/__init__.py +114 -0
- kivyforge/platforms/android/__init__.py +140 -0
- kivyforge/platforms/android/adb.py +215 -0
- kivyforge/platforms/android/bootstrap/__init__.py +7 -0
- kivyforge/platforms/android/bootstrap/contract.py +166 -0
- kivyforge/platforms/android/bootstrap/render.py +244 -0
- kivyforge/platforms/android/bootstrap/templates/androidtest/KivyforgeContractTest.java +76 -0
- kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivy_bootstrap.py +50 -0
- kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_bootstrap.py +54 -0
- kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_selftest.py +97 -0
- kivyforge/platforms/android/bootstrap/templates/cpp/CMakeLists.txt +20 -0
- kivyforge/platforms/android/bootstrap/templates/cpp/main.c +150 -0
- kivyforge/platforms/android/bootstrap/templates/java/org/jnius/NativeInvocationHandler.java +48 -0
- kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonActivity.java +75 -0
- kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonBundle.java +132 -0
- kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonService.java +189 -0
- kivyforge/platforms/android/bootstrap/templates/java/org/renpy/android/Hardware.java +276 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/LICENSE-SDL.txt +18 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/SDL_REVISION.txt +3 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDevice.java +22 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceBLESteamController.java +650 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceManager.java +698 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceUSB.java +309 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDL.java +90 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLActivity.java +2120 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLAudioManager.java +514 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLControllerManager.java +856 -0
- kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLSurface.java +405 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/LICENSE-SDL.txt +18 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/SDL_REVISION.txt +3 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDevice.java +21 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceBLESteamController.java +829 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceManager.java +698 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceUSB.java +354 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDL.java +90 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLActivity.java +2240 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLAudioManager.java +126 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLControllerManager.java +1010 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLDummyEdit.java +66 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLInputConnection.java +136 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSensorManager.java +73 -0
- kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSurface.java +464 -0
- kivyforge/platforms/android/cli.py +1023 -0
- kivyforge/platforms/android/doctor.py +899 -0
- kivyforge/platforms/android/elf.py +148 -0
- kivyforge/platforms/android/generate/__init__.py +1 -0
- kivyforge/platforms/android/generate/manifest.py +261 -0
- kivyforge/platforms/android/generate/project.py +462 -0
- kivyforge/platforms/android/generate/services.py +187 -0
- kivyforge/platforms/android/gradle_wrapper/NOTICE +3 -0
- kivyforge/platforms/android/gradle_wrapper/SHA256SUMS +1 -0
- kivyforge/platforms/android/gradle_wrapper/gradle-wrapper.jar +0 -0
- kivyforge/platforms/android/gradle_wrapper/gradlew +164 -0
- kivyforge/platforms/android/gradle_wrapper/gradlew.bat +90 -0
- kivyforge/platforms/android/gradlew.py +60 -0
- kivyforge/platforms/android/icons.py +237 -0
- kivyforge/platforms/android/lock/__init__.py +1 -0
- kivyforge/platforms/android/lock/archives.py +109 -0
- kivyforge/platforms/android/lock/builder.py +387 -0
- kivyforge/platforms/android/lock/markers.py +71 -0
- kivyforge/platforms/android/lock/maven.py +252 -0
- kivyforge/platforms/android/lock/model.py +113 -0
- kivyforge/platforms/android/lock/python_meta.py +199 -0
- kivyforge/platforms/android/lock/reader.py +206 -0
- kivyforge/platforms/android/lock/resolver.py +276 -0
- kivyforge/platforms/android/lock/writer.py +121 -0
- kivyforge/platforms/android/policy.py +214 -0
- kivyforge/platforms/android/signing.py +145 -0
- kivyforge/platforms/android/smoke.py +43 -0
- kivyforge/platforms/android/splash.py +293 -0
- kivyforge/platforms/android/stage/__init__.py +1 -0
- kivyforge/platforms/android/stage/bundle.py +295 -0
- kivyforge/platforms/android/stage/jnilibs.py +186 -0
- kivyforge/platforms/android/stage/runtime.py +61 -0
- kivyforge/platforms/android/stage/wheels.py +106 -0
- kivyforge/platforms/android/toolchain.py +29 -0
- kivyforge/platforms/base.py +157 -0
- kivyforge/platforms/ios/__init__.py +129 -0
- kivyforge/platforms/ios/assets.py +193 -0
- kivyforge/platforms/ios/buildsettings.py +128 -0
- kivyforge/platforms/ios/cli.py +543 -0
- kivyforge/platforms/ios/doctor.py +410 -0
- kivyforge/platforms/ios/entitlements.py +34 -0
- kivyforge/platforms/ios/generator.py +318 -0
- kivyforge/platforms/ios/lock/__init__.py +71 -0
- kivyforge/platforms/ios/lock/builder.py +393 -0
- kivyforge/platforms/ios/lock/markers.py +69 -0
- kivyforge/platforms/ios/lock/model.py +95 -0
- kivyforge/platforms/ios/lock/python_meta.py +187 -0
- kivyforge/platforms/ios/lock/reader.py +191 -0
- kivyforge/platforms/ios/lock/resolver.py +304 -0
- kivyforge/platforms/ios/lock/spm.py +217 -0
- kivyforge/platforms/ios/lock/writer.py +114 -0
- kivyforge/platforms/ios/lock/xcframework.py +188 -0
- kivyforge/platforms/ios/materialize.py +59 -0
- kivyforge/platforms/ios/plist.py +91 -0
- kivyforge/platforms/ios/privacy.py +39 -0
- kivyforge/platforms/ios/skeleton.py +165 -0
- kivyforge/platforms/ios/sources.py +63 -0
- kivyforge/platforms/ios/staging.py +225 -0
- kivyforge/platforms/ios/swift_packages.py +324 -0
- kivyforge/platforms/ios/templates/kivyforge_bootstrap.h +34 -0
- kivyforge/platforms/ios/templates/kivyforge_bootstrap.m +146 -0
- kivyforge/platforms/ios/templates/main.m +15 -0
- kivyforge/platforms/ios/templates/main_config.h.in +12 -0
- kivyforge/platforms/ios/xcframeworks.py +194 -0
- kivyforge/platforms/ios/xcode/__init__.py +76 -0
- kivyforge/platforms/ios/xcode/commands.py +296 -0
- kivyforge/platforms/ios/xcode/runner.py +316 -0
- kivyforge/platforms/linux/__init__.py +120 -0
- kivyforge/platforms/linux/appimage.py +169 -0
- kivyforge/platforms/linux/bundle.py +235 -0
- kivyforge/platforms/linux/cli.py +232 -0
- kivyforge/platforms/linux/desktop.py +71 -0
- kivyforge/platforms/linux/doctor.py +438 -0
- kivyforge/platforms/linux/elftools.py +95 -0
- kivyforge/platforms/linux/icons.py +129 -0
- kivyforge/platforms/linux/launcher.py +107 -0
- kivyforge/platforms/linux/lock/__init__.py +126 -0
- kivyforge/platforms/linux/lock/profile.py +254 -0
- kivyforge/platforms/linux/lock/runtime.py +75 -0
- kivyforge/platforms/linux/native_stage.py +47 -0
- kivyforge/platforms/linux/runtime_stage.py +107 -0
- kivyforge/platforms/linux/wheels_stage.py +103 -0
- kivyforge/platforms/macos/__init__.py +121 -0
- kivyforge/platforms/macos/bundle.py +255 -0
- kivyforge/platforms/macos/cli.py +269 -0
- kivyforge/platforms/macos/doctor.py +480 -0
- kivyforge/platforms/macos/icns.py +75 -0
- kivyforge/platforms/macos/launcher.py +118 -0
- kivyforge/platforms/macos/lock/__init__.py +112 -0
- kivyforge/platforms/macos/lock/profile.py +119 -0
- kivyforge/platforms/macos/lock/runtime.py +58 -0
- kivyforge/platforms/macos/machotools.py +138 -0
- kivyforge/platforms/macos/native_stage.py +47 -0
- kivyforge/platforms/macos/notarize.py +143 -0
- kivyforge/platforms/macos/plist.py +37 -0
- kivyforge/platforms/macos/runtime_stage.py +110 -0
- kivyforge/platforms/macos/signing.py +78 -0
- kivyforge/platforms/macos/wheels_stage.py +108 -0
- kivyforge/platforms/windows/__init__.py +133 -0
- kivyforge/platforms/windows/assets.py +76 -0
- kivyforge/platforms/windows/bundle.py +298 -0
- kivyforge/platforms/windows/cli.py +314 -0
- kivyforge/platforms/windows/doctor.py +563 -0
- kivyforge/platforms/windows/fsswap.py +87 -0
- kivyforge/platforms/windows/icons.py +64 -0
- kivyforge/platforms/windows/launcher/__init__.py +193 -0
- kivyforge/platforms/windows/launcher/build_launcher.py +507 -0
- kivyforge/platforms/windows/launcher/launcher.c +379 -0
- kivyforge/platforms/windows/lock/__init__.py +112 -0
- kivyforge/platforms/windows/lock/profile.py +101 -0
- kivyforge/platforms/windows/lock/runtime.py +64 -0
- kivyforge/platforms/windows/naming.py +52 -0
- kivyforge/platforms/windows/native_stage.py +66 -0
- kivyforge/platforms/windows/petools.py +98 -0
- kivyforge/platforms/windows/rcedit.py +116 -0
- kivyforge/platforms/windows/runtime_stage.py +221 -0
- kivyforge/platforms/windows/signing.py +168 -0
- kivyforge/platforms/windows/vendor/LICENSE.rcedit +29 -0
- kivyforge/platforms/windows/vendor/NOTICE +17 -0
- kivyforge/platforms/windows/vendor/SHA256SUMS +4 -0
- kivyforge/platforms/windows/vendor/TOOLSET.txt +4 -0
- kivyforge/platforms/windows/vendor/__init__.py +12 -0
- kivyforge/platforms/windows/vendor/fetch_rcedit.py +97 -0
- kivyforge/platforms/windows/vendor/launcher-amd64.exe +0 -0
- kivyforge/platforms/windows/vendor/rcedit-x64.exe +0 -0
- kivyforge/platforms/windows/wheels_stage.py +139 -0
- kivyforge-3.0.0.dev0.dist-info/METADATA +609 -0
- kivyforge-3.0.0.dev0.dist-info/RECORD +225 -0
- kivyforge-3.0.0.dev0.dist-info/WHEEL +5 -0
- kivyforge-3.0.0.dev0.dist-info/entry_points.txt +3 -0
- kivyforge-3.0.0.dev0.dist-info/licenses/LICENSE +21 -0
- kivyforge-3.0.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
"""Typed model of the kivyforge ``pyproject.toml`` surface (spec 01).
|
|
2
|
+
|
|
3
|
+
These dataclasses are the validated, in-memory representation produced by
|
|
4
|
+
``kivyforge.config.loader.load_config``. They intentionally only model the
|
|
5
|
+
fields kivyforge consumes; unknown keys elsewhere in ``pyproject.toml`` are
|
|
6
|
+
ignored (PEP 518 tool-namespace convention).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
|
|
13
|
+
# The iOS schema major version this build understands (spec 01).
|
|
14
|
+
SUPPORTED_IOS_SCHEMA_VERSION = 1
|
|
15
|
+
|
|
16
|
+
# The macOS overlay schema major version this build understands (macos-spec).
|
|
17
|
+
SUPPORTED_MACOS_SCHEMA_VERSION = 1
|
|
18
|
+
|
|
19
|
+
# The Linux overlay schema major version this build understands (linux-spec).
|
|
20
|
+
SUPPORTED_LINUX_SCHEMA_VERSION = 1
|
|
21
|
+
|
|
22
|
+
# macOS build architecture. arm64 only: macOS 27 stops installing on Intel
|
|
23
|
+
# hardware and macOS 28 removes Rosetta, so an x86_64 slice would be one nothing
|
|
24
|
+
# can execute or validate. Kept list-shaped for symmetry with the other
|
|
25
|
+
# platforms, but there is no second arch to add and no universal2 build.
|
|
26
|
+
#
|
|
27
|
+
# This is the *build target* set, deliberately distinct from the *wheel tag* set
|
|
28
|
+
# (macos/lock/profile.py VALID_WHEEL_ARCHS): a universal2 wheel is a perfectly
|
|
29
|
+
# good arm64 wheel and is still accepted.
|
|
30
|
+
VALID_MACOS_ARCHS = frozenset({"arm64"})
|
|
31
|
+
DEFAULT_MACOS_ARCHS = ("arm64",)
|
|
32
|
+
|
|
33
|
+
# Linux build architectures. Only x86_64 is allowed this phase; the field stays
|
|
34
|
+
# list-shaped so aarch64 is purely additive later (linux-spec). Unlike macOS
|
|
35
|
+
# there is no fat binary — each arch would be a separate AppImage.
|
|
36
|
+
VALID_LINUX_ARCHS = frozenset({"x86_64"})
|
|
37
|
+
DEFAULT_LINUX_ARCHS = ("x86_64",)
|
|
38
|
+
|
|
39
|
+
# The Windows overlay schema major version this build understands (windows-spec).
|
|
40
|
+
SUPPORTED_WINDOWS_SCHEMA_VERSION = 1
|
|
41
|
+
|
|
42
|
+
# Windows build architectures. Only amd64 (x86-64) this phase; the field stays
|
|
43
|
+
# list-shaped so win-arm64 is purely additive later (windows-spec). Like Linux
|
|
44
|
+
# and unlike macOS there is no fat binary — each arch is a separate onedir.
|
|
45
|
+
# arm64: add "arm64" to VALID_WINDOWS_ARCHS to accept it; DEFAULT stays amd64
|
|
46
|
+
# (arm64 is opt-in via [tool.kivy.windows].archs). See arm64-windows.md §1.
|
|
47
|
+
VALID_WINDOWS_ARCHS = frozenset({"amd64"})
|
|
48
|
+
DEFAULT_WINDOWS_ARCHS = ("amd64",)
|
|
49
|
+
|
|
50
|
+
# Microsoft's real AppUserModelID hard constraints (windows-spec): no spaces and
|
|
51
|
+
# at most this many characters. Pascal-case / period-delimited *style* is only a
|
|
52
|
+
# doctor warning, so the loader enforces just these two.
|
|
53
|
+
WINDOWS_APP_ID_MAX_LENGTH = 128
|
|
54
|
+
|
|
55
|
+
# The Android overlay schema major version this build understands (spec
|
|
56
|
+
# platforms/android/01).
|
|
57
|
+
SUPPORTED_ANDROID_SCHEMA_VERSION = 1
|
|
58
|
+
|
|
59
|
+
# Android ABIs. 64-bit only, permanently for this schema: the python.org
|
|
60
|
+
# Android runtime ships no 32-bit build (android/01 §ABIs). Underscored
|
|
61
|
+
# wheel-tag spelling; the generator maps to Android's dashed names.
|
|
62
|
+
VALID_ANDROID_ABIS = frozenset({"arm64_v8a", "x86_64"})
|
|
63
|
+
DEFAULT_ANDROID_ABIS = ("arm64_v8a", "x86_64")
|
|
64
|
+
|
|
65
|
+
# minSdk floor: first API level with RUNPATH (auditwheel's requirement), the
|
|
66
|
+
# python.org runtime floor, and the android_* wheel-tag ecosystem floor.
|
|
67
|
+
ANDROID_MIN_SDK_FLOOR = 24
|
|
68
|
+
DEFAULT_ANDROID_MIN_SDK = 24
|
|
69
|
+
# targetSdk default: the latest stable API level this kivyforge release knows.
|
|
70
|
+
DEFAULT_ANDROID_TARGET_SDK = 35
|
|
71
|
+
|
|
72
|
+
# Kivy generations the bootstrap supports: 2 (Kivy 2.3.1, SDL2) or 3 (Kivy
|
|
73
|
+
# 3.0, SDL3). Named after the Kivy major version, not the SDL generation it
|
|
74
|
+
# happens to pair with, so configuring a build never requires knowing that
|
|
75
|
+
# pairing.
|
|
76
|
+
VALID_ANDROID_KIVY_GENERATIONS = frozenset({2, 3})
|
|
77
|
+
DEFAULT_ANDROID_KIVY_GENERATION = 2
|
|
78
|
+
|
|
79
|
+
# Google Play's versionCode ceiling; the auto-derivation formula must stay
|
|
80
|
+
# under it (android/01 §auto-derived version_code).
|
|
81
|
+
ANDROID_VERSION_CODE_CEILING = 2_100_000_000
|
|
82
|
+
|
|
83
|
+
# android:foregroundServiceType values (android/01). Tracks the platform list
|
|
84
|
+
# per kivyforge release; mediaProcessing requires Android 15 / API 35.
|
|
85
|
+
VALID_FOREGROUND_SERVICE_TYPES = frozenset(
|
|
86
|
+
{
|
|
87
|
+
"camera",
|
|
88
|
+
"connectedDevice",
|
|
89
|
+
"dataSync",
|
|
90
|
+
"health",
|
|
91
|
+
"location",
|
|
92
|
+
"mediaPlayback",
|
|
93
|
+
"mediaProcessing",
|
|
94
|
+
"mediaProjection",
|
|
95
|
+
"microphone",
|
|
96
|
+
"phoneCall",
|
|
97
|
+
"remoteMessaging",
|
|
98
|
+
"shortService",
|
|
99
|
+
"specialUse",
|
|
100
|
+
"systemExempted",
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# byte_compile / strip_source / strip_native_libs accept a bool or this string.
|
|
105
|
+
ANDROID_RELEASE_ONLY = "release"
|
|
106
|
+
VALID_ANDROID_DEBUG_SYMBOLS = frozenset({"symbol_table", "full", "none"})
|
|
107
|
+
|
|
108
|
+
# Default env-var names for the release keystore passwords (android/01).
|
|
109
|
+
DEFAULT_ANDROID_STORE_PASSWORD_ENV = "KIVYFORGE_KEYSTORE_PASSWORD"
|
|
110
|
+
DEFAULT_ANDROID_KEY_PASSWORD_ENV = "KIVYFORGE_KEY_PASSWORD"
|
|
111
|
+
|
|
112
|
+
# Default app theme parent (android/01 base_theme).
|
|
113
|
+
DEFAULT_ANDROID_BASE_THEME = "Theme.Material3.DayNight.NoActionBar"
|
|
114
|
+
|
|
115
|
+
# Manifest attributes kivyforge manages (android/01 §managed keys): rejected in
|
|
116
|
+
# the [tool.kivy.android.manifest] application/activity passthrough tables.
|
|
117
|
+
MANAGED_ANDROID_APPLICATION_ATTRS = frozenset(
|
|
118
|
+
{
|
|
119
|
+
"android:label",
|
|
120
|
+
"android:icon",
|
|
121
|
+
"android:roundIcon",
|
|
122
|
+
"android:theme",
|
|
123
|
+
"android:extractNativeLibs",
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
MANAGED_ANDROID_ACTIVITY_ATTRS = frozenset(
|
|
127
|
+
{
|
|
128
|
+
"android:name",
|
|
129
|
+
"android:label",
|
|
130
|
+
"android:screenOrientation",
|
|
131
|
+
"android:theme",
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# gradle.properties keys kivyforge manages (android/01 gradle_properties).
|
|
136
|
+
RESERVED_ANDROID_GRADLE_PROPERTIES = frozenset({"android.useAndroidX"})
|
|
137
|
+
|
|
138
|
+
# Intent-filter <data> attribute names accepted by the structured table.
|
|
139
|
+
VALID_INTENT_DATA_KEYS = frozenset(
|
|
140
|
+
{"scheme", "host", "port", "path", "pathPrefix", "pathPattern", "mimeType"}
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Default Authenticode RFC-3161 timestamp server (signing-windows).
|
|
144
|
+
DEFAULT_WINDOWS_TIMESTAMP_URL = "http://timestamp.digicert.com"
|
|
145
|
+
|
|
146
|
+
# Certificate-store scopes for signtool / the doctor certificate check
|
|
147
|
+
# (signing-windows). ``current_user`` -> ``Cert:\CurrentUser\My``; ``machine``
|
|
148
|
+
# -> ``Cert:\LocalMachine\My`` and adds signtool's ``/sm``.
|
|
149
|
+
VALID_WINDOWS_STORE_SCOPES = frozenset({"current_user", "machine"})
|
|
150
|
+
DEFAULT_WINDOWS_STORE_SCOPE = "current_user"
|
|
151
|
+
|
|
152
|
+
# Default freedesktop main category for the generated .desktop entry.
|
|
153
|
+
DEFAULT_DESKTOP_CATEGORIES = ("Utility",)
|
|
154
|
+
|
|
155
|
+
# The freedesktop **main** categories (desktop-entry menu spec). A generated
|
|
156
|
+
# ``.desktop`` must carry categories from this set so it registers correctly in
|
|
157
|
+
# menus/search; a typo/invalid value is rejected at config time (linux-spec).
|
|
158
|
+
FREEDESKTOP_MAIN_CATEGORIES = frozenset(
|
|
159
|
+
{
|
|
160
|
+
"AudioVideo",
|
|
161
|
+
"Audio",
|
|
162
|
+
"Video",
|
|
163
|
+
"Development",
|
|
164
|
+
"Education",
|
|
165
|
+
"Game",
|
|
166
|
+
"Graphics",
|
|
167
|
+
"Network",
|
|
168
|
+
"Office",
|
|
169
|
+
"Science",
|
|
170
|
+
"Settings",
|
|
171
|
+
"System",
|
|
172
|
+
"Utility",
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
VALID_ORIENTATIONS = frozenset(
|
|
177
|
+
{"portrait", "portrait-upside-down", "landscape-left", "landscape-right"}
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
DEFAULT_DEPLOYMENT_TARGET = "13.0"
|
|
181
|
+
DEFAULT_ENTRY_POINT = "main"
|
|
182
|
+
DEFAULT_ORIENTATION = ("portrait",)
|
|
183
|
+
|
|
184
|
+
# Simulator architectures pinned by ``kivyforge lock`` (spec 01/02). The device
|
|
185
|
+
# slice is always arm64; these are the *simulator* slices. arm64 only: the
|
|
186
|
+
# x86_64 simulator slice had value only on an Intel Mac host, and macOS 27 stops
|
|
187
|
+
# installing on Intel hardware.
|
|
188
|
+
VALID_SIMULATOR_ARCHS = frozenset({"arm64"})
|
|
189
|
+
DEFAULT_SIMULATOR_ARCHS = ("arm64",)
|
|
190
|
+
|
|
191
|
+
# Info.plist keys kivyforge writes from the schema; users may not set these via
|
|
192
|
+
# [tool.kivy.ios.info_plist] (spec 01).
|
|
193
|
+
MANAGED_INFO_PLIST_KEYS = frozenset(
|
|
194
|
+
{
|
|
195
|
+
"CFBundleName",
|
|
196
|
+
"CFBundleDisplayName",
|
|
197
|
+
"CFBundleIdentifier",
|
|
198
|
+
"CFBundleShortVersionString",
|
|
199
|
+
"CFBundleVersion",
|
|
200
|
+
"MinimumOSVersion",
|
|
201
|
+
"UISupportedInterfaceOrientations",
|
|
202
|
+
"UISupportedInterfaceOrientations~ipad",
|
|
203
|
+
"LSRequiresIPhoneOS",
|
|
204
|
+
"CFBundlePackageType",
|
|
205
|
+
"CFBundleInfoDictionaryVersion",
|
|
206
|
+
"CFBundleExecutable",
|
|
207
|
+
"NSHumanReadableCopyright",
|
|
208
|
+
# SDL3 scene lifecycle — written automatically for all Kivy apps.
|
|
209
|
+
"UIApplicationSceneManifest",
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Xcode build settings the toolchain manages; rejected under
|
|
214
|
+
# [tool.kivy.ios.xcode.build_settings] (spec 01).
|
|
215
|
+
RESERVED_BUILD_SETTINGS = frozenset(
|
|
216
|
+
{
|
|
217
|
+
"INFOPLIST_FILE",
|
|
218
|
+
"PRODUCT_BUNDLE_IDENTIFIER",
|
|
219
|
+
"IPHONEOS_DEPLOYMENT_TARGET",
|
|
220
|
+
"TARGETED_DEVICE_FAMILY",
|
|
221
|
+
"DEBUG_INFORMATION_FORMAT",
|
|
222
|
+
"CODE_SIGN_STYLE",
|
|
223
|
+
"CODE_SIGN_IDENTITY",
|
|
224
|
+
"DEVELOPMENT_TEAM",
|
|
225
|
+
"PROVISIONING_PROFILE_SPECIFIER",
|
|
226
|
+
"ENABLE_USER_SCRIPT_SANDBOXING",
|
|
227
|
+
"ENABLE_TESTABILITY",
|
|
228
|
+
"FRAMEWORK_SEARCH_PATHS",
|
|
229
|
+
"HEADER_SEARCH_PATHS",
|
|
230
|
+
"LD_RUNPATH_SEARCH_PATHS",
|
|
231
|
+
"GCC_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER",
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass(frozen=True)
|
|
237
|
+
class Author:
|
|
238
|
+
name: str | None = None
|
|
239
|
+
email: str | None = None
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass(frozen=True)
|
|
243
|
+
class ProjectMeta:
|
|
244
|
+
"""PEP 621 ``[project]`` subset consumed by kivyforge."""
|
|
245
|
+
|
|
246
|
+
name: str
|
|
247
|
+
version: str
|
|
248
|
+
description: str | None = None
|
|
249
|
+
requires_python: str | None = None
|
|
250
|
+
dependencies: tuple[str, ...] = ()
|
|
251
|
+
authors: tuple[Author, ...] = ()
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@dataclass(frozen=True)
|
|
255
|
+
class IconConfig:
|
|
256
|
+
source: str | None = None
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dataclass(frozen=True)
|
|
260
|
+
class SplashConfig:
|
|
261
|
+
source: str | None = None
|
|
262
|
+
background: str | None = None
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@dataclass(frozen=True)
|
|
266
|
+
class XcframeworkDep:
|
|
267
|
+
name: str
|
|
268
|
+
version: str
|
|
269
|
+
source: str
|
|
270
|
+
link: bool = True
|
|
271
|
+
embed: bool = True
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@dataclass(frozen=True)
|
|
275
|
+
class NativeBinaryDep:
|
|
276
|
+
"""One ``[tool.kivy.<platform>.native.binaries]`` entry (macos-spec).
|
|
277
|
+
|
|
278
|
+
A non-wheel native binary (a vendor SDK DLL/dylib/so, or a helper
|
|
279
|
+
executable) declared by name. ``source`` is always explicit: a direct
|
|
280
|
+
``http(s)://`` URL, or a repo-relative path to a vendored artifact. The
|
|
281
|
+
entry is SHA-256-pinned into the lock and staged into the bundle's ``bin``
|
|
282
|
+
directory at build time (see ``NativeBinaryDep`` handling in each desktop
|
|
283
|
+
backend).
|
|
284
|
+
"""
|
|
285
|
+
|
|
286
|
+
name: str
|
|
287
|
+
version: str
|
|
288
|
+
source: str
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# byte_compile / strip_source (desktop build_settings) accept a bool or this
|
|
292
|
+
# string, applying only to `kivyforge package` builds -- shared across
|
|
293
|
+
# Windows/Linux/macOS/iOS since the setting and its semantics are identical on
|
|
294
|
+
# all four. Distinct from ANDROID_RELEASE_ONLY (same value, kept separate so
|
|
295
|
+
# nothing here can accidentally couple to Android's own tri-state).
|
|
296
|
+
DESKTOP_RELEASE_ONLY = "release"
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass(frozen=True)
|
|
300
|
+
class DesktopBuildSettings:
|
|
301
|
+
"""``[tool.kivy.<platform>.build_settings]`` -- shared across Windows,
|
|
302
|
+
Linux, macOS (macos-spec / windows-spec / linux-spec), and iOS's
|
|
303
|
+
``[tool.kivy.ios.python.build_settings]`` (pyproject-ios).
|
|
304
|
+
|
|
305
|
+
Deliberately smaller than ``AndroidBuildSettings``: these backends have no
|
|
306
|
+
Gradle/R8, so there is no ``minify``/``shrink_resources``/``multidex``
|
|
307
|
+
analog, and no native-library stripping distinct from ``strip_source``.
|
|
308
|
+
|
|
309
|
+
``byte_compile`` / ``strip_source`` are a bool or the string ``"release"``
|
|
310
|
+
(apply to `kivyforge package` only -- the default; a plain `build` always
|
|
311
|
+
keeps source, matching the dev-loop/shippable-artifact split each backend
|
|
312
|
+
already draws for signing). **stdlib is never stripped** regardless
|
|
313
|
+
of this setting -- only the app's own code and installed wheels are, since
|
|
314
|
+
the platform runtime ships its stdlib pre-compiled already.
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
byte_compile: bool | str = DESKTOP_RELEASE_ONLY
|
|
318
|
+
strip_source: bool | str = DESKTOP_RELEASE_ONLY
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
# SPM version-rule kinds (spec 07), mapping 1:1 to Swift Package Manager's own
|
|
322
|
+
# requirement rules. Each ``requirement`` inline table sets exactly one of these.
|
|
323
|
+
VALID_SWIFT_REQUIREMENT_KINDS = frozenset(
|
|
324
|
+
{"exact", "from", "up_to_next_minor", "range", "branch", "revision"}
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
@dataclass(frozen=True)
|
|
329
|
+
class SwiftPackageDep:
|
|
330
|
+
"""One ``[tool.kivy.ios.native.swift_packages]`` entry (spec 07).
|
|
331
|
+
|
|
332
|
+
Exactly one of ``url`` (remote, with a ``requirement`` rule) or ``path``
|
|
333
|
+
(local, repo-relative) is set. ``requirement`` is a single-key inline table
|
|
334
|
+
(one of ``VALID_SWIFT_REQUIREMENT_KINDS``); it is ``None`` for local
|
|
335
|
+
packages.
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
name: str
|
|
339
|
+
products: tuple[str, ...]
|
|
340
|
+
url: str | None = None
|
|
341
|
+
path: str | None = None
|
|
342
|
+
requirement: dict[str, object] | None = None
|
|
343
|
+
link: bool = True
|
|
344
|
+
embed: bool = True
|
|
345
|
+
|
|
346
|
+
def __post_init__(self) -> None:
|
|
347
|
+
if bool(self.url) == bool(self.path):
|
|
348
|
+
raise ValueError(
|
|
349
|
+
f"swift package {self.name!r} must have exactly one of url/path"
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
@dataclass(frozen=True)
|
|
354
|
+
class SigningConfig:
|
|
355
|
+
team_id: str = ""
|
|
356
|
+
identity: str = "Apple Development"
|
|
357
|
+
provisioning_profile: str = ""
|
|
358
|
+
auto_signing: bool = True
|
|
359
|
+
upload_symbols: bool = True
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@dataclass(frozen=True)
|
|
363
|
+
class IosConfig:
|
|
364
|
+
"""``[tool.kivy.ios]`` overlay."""
|
|
365
|
+
|
|
366
|
+
schema_version: int
|
|
367
|
+
bundle_id: str
|
|
368
|
+
build: int = 1
|
|
369
|
+
deployment_target: str = DEFAULT_DEPLOYMENT_TARGET
|
|
370
|
+
simulator_archs: tuple[str, ...] = DEFAULT_SIMULATOR_ARCHS
|
|
371
|
+
extra_index_urls: tuple[str, ...] = ()
|
|
372
|
+
find_links: tuple[str, ...] = ()
|
|
373
|
+
exclude: tuple[str, ...] = ()
|
|
374
|
+
python_version: str | None = None
|
|
375
|
+
icons: IconConfig = field(default_factory=IconConfig)
|
|
376
|
+
splash: SplashConfig = field(default_factory=SplashConfig)
|
|
377
|
+
xcframeworks: tuple[XcframeworkDep, ...] = ()
|
|
378
|
+
swift_packages: tuple[SwiftPackageDep, ...] = ()
|
|
379
|
+
entitlements: dict[str, object] = field(default_factory=dict)
|
|
380
|
+
signing: SigningConfig = field(default_factory=SigningConfig)
|
|
381
|
+
privacy_manifest_source: str | None = None
|
|
382
|
+
info_plist: dict[str, object] = field(default_factory=dict)
|
|
383
|
+
build_settings: dict[str, str] = field(default_factory=dict)
|
|
384
|
+
python_build_settings: DesktopBuildSettings = field(
|
|
385
|
+
default_factory=DesktopBuildSettings
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@dataclass(frozen=True)
|
|
390
|
+
class MacosSigningConfig:
|
|
391
|
+
"""``[tool.kivy.macos.signing]`` (macos-spec, Developer ID workstream).
|
|
392
|
+
|
|
393
|
+
``identity`` empty means Developer ID signing is not configured and
|
|
394
|
+
``package`` falls back to the ad-hoc floor. ``notary_profile`` names a
|
|
395
|
+
keychain profile created with ``xcrun notarytool store-credentials`` —
|
|
396
|
+
credentials stay in the keychain, never in ``pyproject.toml``.
|
|
397
|
+
"""
|
|
398
|
+
|
|
399
|
+
identity: str = ""
|
|
400
|
+
team_id: str = ""
|
|
401
|
+
notary_profile: str = ""
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def configured(self) -> bool:
|
|
405
|
+
return bool(self.identity)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@dataclass(frozen=True)
|
|
409
|
+
class MacosConfig:
|
|
410
|
+
"""``[tool.kivy.macos]`` overlay (macos-spec).
|
|
411
|
+
|
|
412
|
+
``archs`` is a lock-level property: it drives which macOS wheel tags and
|
|
413
|
+
per-arch runtimes the lock must cover. ``minimum_system_version`` is
|
|
414
|
+
``None`` when unset, meaning the bundled runtime's own floor applies.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
schema_version: int
|
|
418
|
+
bundle_id: str
|
|
419
|
+
build: int = 1
|
|
420
|
+
minimum_system_version: str | None = None
|
|
421
|
+
archs: tuple[str, ...] = DEFAULT_MACOS_ARCHS
|
|
422
|
+
extra_index_urls: tuple[str, ...] = ()
|
|
423
|
+
find_links: tuple[str, ...] = ()
|
|
424
|
+
exclude: tuple[str, ...] = ()
|
|
425
|
+
python_version: str | None = None
|
|
426
|
+
icons: IconConfig = field(default_factory=IconConfig)
|
|
427
|
+
entitlements: dict[str, object] = field(default_factory=dict)
|
|
428
|
+
signing: MacosSigningConfig = field(default_factory=MacosSigningConfig)
|
|
429
|
+
binaries: tuple[NativeBinaryDep, ...] = ()
|
|
430
|
+
build_settings: DesktopBuildSettings = field(default_factory=DesktopBuildSettings)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
@dataclass(frozen=True)
|
|
434
|
+
class WindowsSigningConfig:
|
|
435
|
+
"""``[tool.kivy.windows.signing]`` (signing-windows, optional).
|
|
436
|
+
|
|
437
|
+
Authenticode identity is a certificate-store **thumbprint**, never a
|
|
438
|
+
``.pfx`` path/password. ``store_scope`` selects which store both ``signtool``
|
|
439
|
+
(via ``/sm`` for ``machine``) and the doctor certificate check inspect, so
|
|
440
|
+
they always agree. ``thumbprint`` empty means signing is not configured and
|
|
441
|
+
``package`` leaves the artifact unsigned.
|
|
442
|
+
"""
|
|
443
|
+
|
|
444
|
+
thumbprint: str = ""
|
|
445
|
+
timestamp_url: str = DEFAULT_WINDOWS_TIMESTAMP_URL
|
|
446
|
+
store_scope: str = DEFAULT_WINDOWS_STORE_SCOPE
|
|
447
|
+
|
|
448
|
+
@property
|
|
449
|
+
def configured(self) -> bool:
|
|
450
|
+
return bool(self.thumbprint)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@dataclass(frozen=True)
|
|
454
|
+
class WindowsConfig:
|
|
455
|
+
"""``[tool.kivy.windows]`` overlay (windows-spec).
|
|
456
|
+
|
|
457
|
+
``archs`` drives which ``win_amd64`` wheel tag and per-arch runtime the lock
|
|
458
|
+
must cover. ``app_id`` is the Windows **AppUserModelID** — a different
|
|
459
|
+
identifier from the Linux reverse-DNS ``app_id`` and the macOS ``bundle_id``;
|
|
460
|
+
the loader enforces only Microsoft's hard constraints (no spaces, ≤128
|
|
461
|
+
chars), leaving pascal-case/period style to a doctor warning.
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
schema_version: int
|
|
465
|
+
app_id: str
|
|
466
|
+
archs: tuple[str, ...] = DEFAULT_WINDOWS_ARCHS
|
|
467
|
+
extra_index_urls: tuple[str, ...] = ()
|
|
468
|
+
find_links: tuple[str, ...] = ()
|
|
469
|
+
exclude: tuple[str, ...] = ()
|
|
470
|
+
python_version: str | None = None
|
|
471
|
+
icons: IconConfig = field(default_factory=IconConfig)
|
|
472
|
+
signing: WindowsSigningConfig = field(default_factory=WindowsSigningConfig)
|
|
473
|
+
binaries: tuple[NativeBinaryDep, ...] = ()
|
|
474
|
+
build_settings: DesktopBuildSettings = field(default_factory=DesktopBuildSettings)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
@dataclass(frozen=True)
|
|
478
|
+
class AndroidPythonConfig:
|
|
479
|
+
"""``[tool.kivy.android.python]`` — the python.org Android runtime pin."""
|
|
480
|
+
|
|
481
|
+
version: str
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
@dataclass(frozen=True)
|
|
485
|
+
class AndroidFeature:
|
|
486
|
+
"""One ``[tool.kivy.android.permissions].features`` entry."""
|
|
487
|
+
|
|
488
|
+
name: str
|
|
489
|
+
required: bool = True
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
@dataclass(frozen=True)
|
|
493
|
+
class AndroidPermissions:
|
|
494
|
+
"""``[tool.kivy.android.permissions]`` (android/01)."""
|
|
495
|
+
|
|
496
|
+
uses: tuple[str, ...] = ()
|
|
497
|
+
features: tuple[AndroidFeature, ...] = ()
|
|
498
|
+
auto_features: bool = True
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
@dataclass(frozen=True)
|
|
502
|
+
class AndroidIconConfig:
|
|
503
|
+
"""``[tool.kivy.android.icons]`` — adaptive-icon inputs."""
|
|
504
|
+
|
|
505
|
+
source: str | None = None
|
|
506
|
+
background: str | None = None
|
|
507
|
+
monochrome: str | None = None
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
@dataclass(frozen=True)
|
|
511
|
+
class AndroidSplashConfig:
|
|
512
|
+
"""``[tool.kivy.android.splash]`` — AndroidX SplashScreen inputs."""
|
|
513
|
+
|
|
514
|
+
source: str | None = None
|
|
515
|
+
background: str | None = None
|
|
516
|
+
icon_background: str | None = None
|
|
517
|
+
animation_duration: int | None = None
|
|
518
|
+
branding: str | None = None
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
@dataclass(frozen=True)
|
|
522
|
+
class AndroidArchiveDep:
|
|
523
|
+
"""One ``[tool.kivy.android.native.aars]`` / ``.jars`` entry (channel 3)."""
|
|
524
|
+
|
|
525
|
+
name: str
|
|
526
|
+
version: str
|
|
527
|
+
source: str
|
|
528
|
+
kind: str # "aar" | "jar"
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
@dataclass(frozen=True)
|
|
532
|
+
class AndroidGradleConfig:
|
|
533
|
+
"""``[tool.kivy.android.gradle]`` — Maven coordinates (channel 4)."""
|
|
534
|
+
|
|
535
|
+
dependencies: tuple[str, ...] = ()
|
|
536
|
+
repositories: tuple[str, ...] = ()
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
@dataclass(frozen=True)
|
|
540
|
+
class AndroidIncludeFile:
|
|
541
|
+
"""One ``[[tool.kivy.android.include_files]]`` entry."""
|
|
542
|
+
|
|
543
|
+
dest: str
|
|
544
|
+
sources: tuple[str, ...]
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
@dataclass(frozen=True)
|
|
548
|
+
class AndroidSrcConfig:
|
|
549
|
+
"""``[tool.kivy.android.src]`` — extra Java/Kotlin source roots."""
|
|
550
|
+
|
|
551
|
+
java: tuple[str, ...] = ()
|
|
552
|
+
kotlin: tuple[str, ...] = ()
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
@dataclass(frozen=True)
|
|
556
|
+
class AndroidNotification:
|
|
557
|
+
"""The mandatory foreground-service notification (android/01 services)."""
|
|
558
|
+
|
|
559
|
+
channel_id: str
|
|
560
|
+
channel_name: str
|
|
561
|
+
title: str
|
|
562
|
+
text: str
|
|
563
|
+
icon: str | None = None
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
@dataclass(frozen=True)
|
|
567
|
+
class AndroidService:
|
|
568
|
+
"""One ``[[tool.kivy.android.services]]`` entry."""
|
|
569
|
+
|
|
570
|
+
name: str
|
|
571
|
+
entry_point: str
|
|
572
|
+
exported: bool = False
|
|
573
|
+
foreground: bool = False
|
|
574
|
+
foreground_service_type: str | None = None
|
|
575
|
+
notification: AndroidNotification | None = None
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
@dataclass(frozen=True)
|
|
579
|
+
class AndroidActivity:
|
|
580
|
+
"""One ``[[tool.kivy.android.activities]]`` entry."""
|
|
581
|
+
|
|
582
|
+
name: str
|
|
583
|
+
exported: bool = False
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
@dataclass(frozen=True)
|
|
587
|
+
class AndroidIntentFilter:
|
|
588
|
+
"""One ``[[tool.kivy.android.intent_filters]]`` entry (main activity)."""
|
|
589
|
+
|
|
590
|
+
action: str
|
|
591
|
+
categories: tuple[str, ...] = ()
|
|
592
|
+
data: tuple[dict[str, str], ...] = ()
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
@dataclass(frozen=True)
|
|
596
|
+
class AndroidManifestConfig:
|
|
597
|
+
"""``[tool.kivy.android.manifest]`` — structured + raw-XML passthrough."""
|
|
598
|
+
|
|
599
|
+
application: dict[str, object] = field(default_factory=dict)
|
|
600
|
+
activity: dict[str, object] = field(default_factory=dict)
|
|
601
|
+
placeholders: dict[str, str] = field(default_factory=dict)
|
|
602
|
+
# Component names the release policy tolerates as exported, on top of the
|
|
603
|
+
# bootstrap's own. Needed because the policy lints the *merged* manifest, so
|
|
604
|
+
# a library's exported component is otherwise unfixable from pyproject.toml.
|
|
605
|
+
allow_exported: tuple[str, ...] = ()
|
|
606
|
+
extra_manifest_xml: str = ""
|
|
607
|
+
extra_application_xml: str = ""
|
|
608
|
+
extra_activity_xml: str = ""
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
@dataclass(frozen=True)
|
|
612
|
+
class AndroidSigningConfig:
|
|
613
|
+
"""``[tool.kivy.android.signing]`` (android/01, android/07).
|
|
614
|
+
|
|
615
|
+
Passwords are **never** stored in ``pyproject.toml`` — only the names of the
|
|
616
|
+
environment variables that hold them. ``keystore`` empty means release
|
|
617
|
+
signing is not configured; ``kivyforge package`` then fails its preflight.
|
|
618
|
+
``v1_signing`` defaults off: the ``min_sdk`` floor is 24, where the platform
|
|
619
|
+
verifies v2+.
|
|
620
|
+
"""
|
|
621
|
+
|
|
622
|
+
keystore: str = ""
|
|
623
|
+
key_alias: str = ""
|
|
624
|
+
store_password_env: str = DEFAULT_ANDROID_STORE_PASSWORD_ENV
|
|
625
|
+
key_password_env: str = DEFAULT_ANDROID_KEY_PASSWORD_ENV
|
|
626
|
+
v1_signing: bool = False
|
|
627
|
+
v2_signing: bool = True
|
|
628
|
+
v3_signing: bool = True
|
|
629
|
+
v4_signing: bool = False
|
|
630
|
+
|
|
631
|
+
@property
|
|
632
|
+
def configured(self) -> bool:
|
|
633
|
+
return bool(self.keystore and self.key_alias)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
@dataclass(frozen=True)
|
|
637
|
+
class AndroidBuildSettings:
|
|
638
|
+
"""``[tool.kivy.android.build_settings]`` (android/01).
|
|
639
|
+
|
|
640
|
+
``byte_compile`` / ``strip_source`` / ``strip_native_libs`` are a bool or
|
|
641
|
+
the string ``"release"`` (apply to release packaging only — the default).
|
|
642
|
+
"""
|
|
643
|
+
|
|
644
|
+
minify: bool = False
|
|
645
|
+
shrink_resources: bool = False
|
|
646
|
+
multidex: bool = True
|
|
647
|
+
byte_compile: bool | str = ANDROID_RELEASE_ONLY
|
|
648
|
+
strip_source: bool | str = ANDROID_RELEASE_ONLY
|
|
649
|
+
strip_native_libs: bool | str = ANDROID_RELEASE_ONLY
|
|
650
|
+
debug_symbols: str = "symbol_table"
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
@dataclass(frozen=True)
|
|
654
|
+
class AndroidConfig:
|
|
655
|
+
"""``[tool.kivy.android]`` overlay (android/01).
|
|
656
|
+
|
|
657
|
+
``version_code`` is the **resolved** integer: an explicit value verbatim, or
|
|
658
|
+
the auto-derived code (``MAJOR*1_000_000 + MINOR*10_000 + PATCH*100 +
|
|
659
|
+
build``) when the overlay says ``"auto"`` (``version_code_auto`` records
|
|
660
|
+
which). ``compile_sdk`` defaults to ``target_sdk`` at parse time.
|
|
661
|
+
"""
|
|
662
|
+
|
|
663
|
+
schema_version: int
|
|
664
|
+
package: str
|
|
665
|
+
version_code: int = 1
|
|
666
|
+
version_code_auto: bool = False
|
|
667
|
+
build: int = 0
|
|
668
|
+
min_sdk: int = DEFAULT_ANDROID_MIN_SDK
|
|
669
|
+
target_sdk: int = DEFAULT_ANDROID_TARGET_SDK
|
|
670
|
+
compile_sdk: int = DEFAULT_ANDROID_TARGET_SDK
|
|
671
|
+
kivy_generation: int = DEFAULT_ANDROID_KIVY_GENERATION
|
|
672
|
+
abis: tuple[str, ...] = DEFAULT_ANDROID_ABIS
|
|
673
|
+
extra_index_urls: tuple[str, ...] = ()
|
|
674
|
+
find_links: tuple[str, ...] = ()
|
|
675
|
+
exclude: tuple[str, ...] = ()
|
|
676
|
+
base_theme: str = DEFAULT_ANDROID_BASE_THEME
|
|
677
|
+
python: AndroidPythonConfig | None = None
|
|
678
|
+
permissions: AndroidPermissions = field(default_factory=AndroidPermissions)
|
|
679
|
+
icons: AndroidIconConfig = field(default_factory=AndroidIconConfig)
|
|
680
|
+
splash: AndroidSplashConfig = field(default_factory=AndroidSplashConfig)
|
|
681
|
+
aars: tuple[AndroidArchiveDep, ...] = ()
|
|
682
|
+
jars: tuple[AndroidArchiveDep, ...] = ()
|
|
683
|
+
gradle: AndroidGradleConfig = field(default_factory=AndroidGradleConfig)
|
|
684
|
+
include_files: tuple[AndroidIncludeFile, ...] = ()
|
|
685
|
+
src: AndroidSrcConfig = field(default_factory=AndroidSrcConfig)
|
|
686
|
+
services: tuple[AndroidService, ...] = ()
|
|
687
|
+
activities: tuple[AndroidActivity, ...] = ()
|
|
688
|
+
intent_filters: tuple[AndroidIntentFilter, ...] = ()
|
|
689
|
+
manifest: AndroidManifestConfig = field(default_factory=AndroidManifestConfig)
|
|
690
|
+
signing: AndroidSigningConfig = field(default_factory=AndroidSigningConfig)
|
|
691
|
+
gradle_properties: dict[str, object] = field(default_factory=dict)
|
|
692
|
+
build_settings: AndroidBuildSettings = field(default_factory=AndroidBuildSettings)
|
|
693
|
+
|
|
694
|
+
@property
|
|
695
|
+
def python_required(self) -> AndroidPythonConfig:
|
|
696
|
+
if self.python is None: # pragma: no cover - loader enforces presence
|
|
697
|
+
raise RuntimeError("AndroidConfig.python is None despite loader rule 11")
|
|
698
|
+
return self.python
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
@dataclass(frozen=True)
|
|
702
|
+
class DesktopConfig:
|
|
703
|
+
"""``[tool.kivy.linux.desktop]`` — freedesktop ``.desktop`` entry options."""
|
|
704
|
+
|
|
705
|
+
categories: tuple[str, ...] = DEFAULT_DESKTOP_CATEGORIES
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
@dataclass(frozen=True)
|
|
709
|
+
class LinuxConfig:
|
|
710
|
+
"""``[tool.kivy.linux]`` overlay (linux-spec).
|
|
711
|
+
|
|
712
|
+
``archs`` drives which manylinux wheel tags and per-arch runtime the lock
|
|
713
|
+
must cover. ``glibc_floor`` is ``None`` when unset, meaning the bundled
|
|
714
|
+
runtime's own glibc floor (2.17) applies; setting it higher admits
|
|
715
|
+
newer-manylinux-only wheels at the cost of raising the artifact's host floor.
|
|
716
|
+
"""
|
|
717
|
+
|
|
718
|
+
schema_version: int
|
|
719
|
+
app_id: str
|
|
720
|
+
glibc_floor: str | None = None
|
|
721
|
+
archs: tuple[str, ...] = DEFAULT_LINUX_ARCHS
|
|
722
|
+
extra_index_urls: tuple[str, ...] = ()
|
|
723
|
+
find_links: tuple[str, ...] = ()
|
|
724
|
+
exclude: tuple[str, ...] = ()
|
|
725
|
+
python_version: str | None = None
|
|
726
|
+
icons: IconConfig = field(default_factory=IconConfig)
|
|
727
|
+
desktop: DesktopConfig = field(default_factory=DesktopConfig)
|
|
728
|
+
binaries: tuple[NativeBinaryDep, ...] = ()
|
|
729
|
+
build_settings: DesktopBuildSettings = field(default_factory=DesktopBuildSettings)
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
@dataclass(frozen=True)
|
|
733
|
+
class KivyMeta:
|
|
734
|
+
"""Cross-platform ``[tool.kivy]`` table."""
|
|
735
|
+
|
|
736
|
+
app_dir: str
|
|
737
|
+
display_name: str | None = None
|
|
738
|
+
entry_point: str = DEFAULT_ENTRY_POINT
|
|
739
|
+
orientation: tuple[str, ...] = DEFAULT_ORIENTATION
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
@dataclass(frozen=True)
|
|
743
|
+
class Config:
|
|
744
|
+
"""Fully-validated kivyforge project configuration."""
|
|
745
|
+
|
|
746
|
+
project: ProjectMeta
|
|
747
|
+
kivy: KivyMeta
|
|
748
|
+
ios: IosConfig | None = None
|
|
749
|
+
macos: MacosConfig | None = None
|
|
750
|
+
linux: LinuxConfig | None = None
|
|
751
|
+
windows: WindowsConfig | None = None
|
|
752
|
+
android: AndroidConfig | None = None
|
|
753
|
+
|
|
754
|
+
@property
|
|
755
|
+
def display_name(self) -> str:
|
|
756
|
+
if self.kivy.display_name:
|
|
757
|
+
return self.kivy.display_name
|
|
758
|
+
return self.project.name
|
|
759
|
+
|
|
760
|
+
@property
|
|
761
|
+
def app_slug(self) -> str:
|
|
762
|
+
"""The Xcode target / folder slug derived from [project].name."""
|
|
763
|
+
return self.project.name
|
|
764
|
+
|
|
765
|
+
@property
|
|
766
|
+
def ios_required(self) -> IosConfig:
|
|
767
|
+
"""``[tool.kivy.ios]`` after ``load_config(..., require_ios=True)``.
|
|
768
|
+
|
|
769
|
+
Pyright cannot infer that ``ios`` is set from the loader alone; iOS CLI
|
|
770
|
+
verbs should use this accessor instead of ``config.ios`` directly.
|
|
771
|
+
"""
|
|
772
|
+
if self.ios is None:
|
|
773
|
+
raise RuntimeError(
|
|
774
|
+
"Config.ios is None; call load_config with require_ios=True "
|
|
775
|
+
"before accessing ios_required."
|
|
776
|
+
)
|
|
777
|
+
return self.ios
|
|
778
|
+
|
|
779
|
+
@property
|
|
780
|
+
def macos_required(self) -> MacosConfig:
|
|
781
|
+
"""``[tool.kivy.macos]`` after ``load_config(..., require_macos=True)``."""
|
|
782
|
+
if self.macos is None:
|
|
783
|
+
raise RuntimeError(
|
|
784
|
+
"Config.macos is None; call load_config with require_macos=True "
|
|
785
|
+
"before accessing macos_required."
|
|
786
|
+
)
|
|
787
|
+
return self.macos
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def linux_required(self) -> LinuxConfig:
|
|
791
|
+
"""``[tool.kivy.linux]`` after ``load_config(..., require_linux=True)``."""
|
|
792
|
+
if self.linux is None:
|
|
793
|
+
raise RuntimeError(
|
|
794
|
+
"Config.linux is None; call load_config with require_linux=True "
|
|
795
|
+
"before accessing linux_required."
|
|
796
|
+
)
|
|
797
|
+
return self.linux
|
|
798
|
+
|
|
799
|
+
@property
|
|
800
|
+
def windows_required(self) -> WindowsConfig:
|
|
801
|
+
"""``[tool.kivy.windows]`` after ``load_config(..., require_windows=True)``."""
|
|
802
|
+
if self.windows is None:
|
|
803
|
+
raise RuntimeError(
|
|
804
|
+
"Config.windows is None; call load_config with require_windows=True "
|
|
805
|
+
"before accessing windows_required."
|
|
806
|
+
)
|
|
807
|
+
return self.windows
|
|
808
|
+
|
|
809
|
+
@property
|
|
810
|
+
def android_required(self) -> AndroidConfig:
|
|
811
|
+
"""``[tool.kivy.android]`` after ``load_config(..., require_android=True)``."""
|
|
812
|
+
if self.android is None:
|
|
813
|
+
raise RuntimeError(
|
|
814
|
+
"Config.android is None; call load_config with require_android=True "
|
|
815
|
+
"before accessing android_required."
|
|
816
|
+
)
|
|
817
|
+
return self.android
|