@@ -131,6 +131,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
131131 args. image_name = Some ( prompt ( "Docker image name" ) ?) ;
132132 }
133133
134+ // Try to auto-detect entrypoint if exactly one .py file exists
135+ if args. entrypoint . is_none ( )
136+ && let Ok ( Some ( py_file) ) = find_single_py_file ( project_home)
137+ {
138+ args. entrypoint = Some ( py_file) ;
139+ }
140+
134141 // Prompt for entrypoint if still not set
135142 if args. entrypoint . is_none ( ) {
136143 args. entrypoint = Some ( prompt ( "Python entrypoint script (e.g., main.py)" ) ?) ;
@@ -436,6 +443,32 @@ fn copy_dir_recursive(src: &Path, dst: &Path) -> io::Result<()> {
436443 Ok ( ( ) )
437444}
438445
446+ fn find_single_py_file ( project_home : & Path ) -> Result < Option < String > , Box < dyn std:: error:: Error > > {
447+ let mut py_files = Vec :: new ( ) ;
448+
449+ for entry in fs:: read_dir ( project_home) ? {
450+ let entry = entry?;
451+ let path = entry. path ( ) ;
452+
453+ // Only check files (not directories) and only at the root level
454+ if path. is_file ( )
455+ && let Some ( extension) = path. extension ( )
456+ && extension == "py"
457+ && let Some ( file_name) = path. file_name ( )
458+ && let Some ( name_str) = file_name. to_str ( )
459+ {
460+ py_files. push ( name_str. to_string ( ) ) ;
461+ }
462+ }
463+
464+ // Return the filename if exactly one .py file is found
465+ if py_files. len ( ) == 1 {
466+ Ok ( Some ( py_files[ 0 ] . clone ( ) ) )
467+ } else {
468+ Ok ( None )
469+ }
470+ }
471+
439472fn read_name_from_pyproject ( project_home : & Path ) -> Result < String , Box < dyn std:: error:: Error > > {
440473 let pyproject_path = project_home. join ( "pyproject.toml" ) ;
441474
0 commit comments