@@ -152,21 +152,52 @@ def handle(self, options: argparse.Namespace) -> None:
152152 if script_path .is_dir ():
153153 script_path = script_path / "main.py"
154154
155+ # Keep script filename around so it can be rejoined after adjusting script_dir
156+ script_filename = script_path .name
157+
155158 script_dir = script_path .parent
156159
157- project_dir = Path (script_dir )
160+ def resolve_project_dir (start_dir : Path ) -> Path :
161+ """Walk up from the script directory looking for a pyproject.toml.
162+ If there isn't one, fall back to the closest directory that
163+ contains requirements.txt, otherwise stick with the script dir."""
164+ current_dir = start_dir
165+ requirements_dir = None
166+
167+ while True :
168+ candidate_pyproject = current_dir / "pyproject.toml"
169+ if candidate_pyproject .exists ():
170+ return current_dir
171+
172+ candidate_requirements = current_dir / reqs_filename
173+ if requirements_dir is None and candidate_requirements .exists ():
174+ requirements_dir = current_dir
175+
176+ parent_dir = current_dir .parent
177+ if parent_dir == current_dir :
178+ return requirements_dir or start_dir
179+
180+ current_dir = parent_dir
181+
182+ project_dir = resolve_project_dir (script_dir )
158183 get_pyproject = load_pyproject_toml (project_dir )
159184
160- if get_pyproject ("tool.flet.app.path" ):
161- script_dir = script_dir .joinpath (get_pyproject ("tool.flet.app.path" ))
162- script_path = script_dir .joinpath (
163- os .path .basename (script_path ),
185+ app_path = get_pyproject ("tool.flet.app.path" )
186+ if app_path :
187+ # tool.flet.app.path can point to a subdirectory containing app sources
188+ app_path_path = Path (app_path )
189+ script_dir = (
190+ app_path_path
191+ if app_path_path .is_absolute ()
192+ else project_dir .joinpath (app_path_path )
164193 )
194+ script_path = script_dir .joinpath (script_filename )
165195
166196 # delete "dist" directory
167197 if options .distpath :
168198 dist_dir = Path (options .distpath )
169199 if not dist_dir .is_absolute ():
200+ # Allow relative --distpath values to be resolved against project root
170201 dist_dir = project_dir .joinpath (dist_dir ).resolve ()
171202 else :
172203 dist_dir = project_dir .joinpath (dist_name )
@@ -186,9 +217,12 @@ def handle(self, options: argparse.Namespace) -> None:
186217 # copy assets
187218 assets_dir = options .assets_dir
188219 if assets_dir and not Path (assets_dir ).is_absolute ():
220+ # User provided assets relative to the entry script
189221 assets_dir = str (script_path .joinpath (assets_dir ).resolve ())
190222 else :
191- assets_dir = str (script_dir / assets_name )
223+ # Fall back to ./assets next to the script
224+ computed_default_assets_dir = str (script_dir / assets_name )
225+ assets_dir = computed_default_assets_dir
192226
193227 if os .path .exists (assets_dir ):
194228 copy_tree (assets_dir , str (dist_dir ))
@@ -214,8 +248,10 @@ def handle(self, options: argparse.Namespace) -> None:
214248 print (f"{ reqs_filename } dependencies: { deps } " )
215249
216250 if len (deps ) == 0 :
251+ # Ensure runtime has at least flet dependency if nothing specified
217252 deps = [f"flet=={ flet .version .version } " ]
218253
254+ # write deps to a temporary file to be included in the tar.gz archive
219255 temp_reqs_txt = Path (tempfile .gettempdir ()).joinpath (random_string (10 ))
220256 with open (temp_reqs_txt , "w" , encoding = "utf-8" ) as f :
221257 f .writelines (dep + "\n " for dep in deps )
@@ -236,6 +272,7 @@ def filter_tar(tarinfo: tarfile.TarInfo):
236272 or is_within_directory (dist_dir , full_path )
237273 ):
238274 return None
275+
239276 # tarinfo.uid = tarinfo.gid = 0
240277 # tarinfo.uname = tarinfo.gname = "root"
241278 if tarinfo .name != "" :
@@ -279,14 +316,6 @@ def filter_tar(tarinfo: tarfile.TarInfo):
279316 or get_pyproject ("tool.poetry.description" )
280317 )
281318
282- pwa_background_color = options .pwa_background_color or get_pyproject (
283- "tool.flet.web.pwa_background_color"
284- )
285-
286- pwa_theme_color = options .pwa_theme_color or get_pyproject (
287- "tool.flet.web.pwa_theme_color"
288- )
289-
290319 no_cdn = options .no_cdn or get_pyproject ("tool.flet.web.cdn" ) == False # noqa: E712
291320
292321 print ("Patching index.html" )
@@ -317,8 +346,10 @@ def filter_tar(tarinfo: tarfile.TarInfo):
317346 app_name = app_name ,
318347 app_short_name = app_short_name ,
319348 app_description = app_description ,
320- background_color = pwa_background_color ,
321- theme_color = pwa_theme_color ,
349+ background_color = options .pwa_background_color
350+ or get_pyproject ("tool.flet.web.pwa_background_color" ),
351+ theme_color = options .pwa_theme_color
352+ or get_pyproject ("tool.flet.web.pwa_theme_color" ),
322353 )
323354
324355 if no_cdn :
0 commit comments