@@ -80,93 +80,67 @@ exports.default = async function afterPack(context) {
8080 }
8181 }
8282
83- // Find prebuilt Python executable in uv_python directory
84- function findPrebuiltPython ( ) {
85- const uvPythonDir = path . join ( prebuiltPath , 'uv_python' ) ;
86- if ( ! fs . existsSync ( uvPythonDir ) ) {
87- return null ;
88- }
83+ // Clean Python symlinks in venv/bin
84+ const venvBinDir = path . join ( prebuiltPath , 'venv' , 'bin' ) ;
85+ if ( fs . existsSync ( venvBinDir ) ) {
86+ const pythonNames = [ 'python' , 'python3' , 'python3.10' , 'python3.11' , 'python3.12' ] ;
87+ const bundlePath = path . resolve ( appPath ) ;
8988
90- // UV stores Python in cpython-* subdirectories
91- try {
92- const entries = fs . readdirSync ( uvPythonDir , { withFileTypes : true } ) ;
93- for ( const entry of entries ) {
94- if ( entry . isDirectory ( ) && entry . name . startsWith ( 'cpython-' ) ) {
95- const pythonPath = path . join ( uvPythonDir , entry . name , 'install' , 'bin' , 'python' ) ;
96- if ( fs . existsSync ( pythonPath ) ) {
97- return pythonPath ;
89+ for ( const pythonName of pythonNames ) {
90+ const pythonSymlink = path . join ( venvBinDir , pythonName ) ;
91+
92+ if ( fs . existsSync ( pythonSymlink ) ) {
93+ try {
94+ const stats = fs . lstatSync ( pythonSymlink ) ;
95+ if ( stats . isSymbolicLink ( ) ) {
96+ const target = fs . readlinkSync ( pythonSymlink ) ;
97+ const resolvedPath = path . resolve ( path . dirname ( pythonSymlink ) , target ) ;
98+
99+ // If symlink points outside bundle, remove it
100+ if ( ! resolvedPath . startsWith ( bundlePath ) ) {
101+ console . log ( `Removing invalid ${ pythonName } symlink: ${ target } ` ) ;
102+ fs . unlinkSync ( pythonSymlink ) ;
103+ }
98104 }
105+ } catch ( error ) {
106+ console . warn ( `Warning: Could not process ${ pythonName } symlink: ${ error . message } ` ) ;
99107 }
100108 }
101- } catch ( error ) {
102- console . warn ( `Warning: Could not search for prebuilt Python: ${ error . message } ` ) ;
103109 }
104- return null ;
105- }
106-
107- const prebuiltPython = findPrebuiltPython ( ) ;
108- if ( prebuiltPython ) {
109- console . log ( `Found prebuilt Python: ${ prebuiltPython } ` ) ;
110110 }
111111
112- // Clean and fix Python symlinks in a venv bin directory
113- function fixPythonSymlinks ( binDir , venvName ) {
114- if ( ! fs . existsSync ( binDir ) ) {
115- return ;
116- }
117-
112+ // Clean Python symlinks in terminal_venv/bin (same as venv/bin)
113+ const terminalVenvBinDir = path . join ( prebuiltPath , 'terminal_venv' , 'bin' ) ;
114+ if ( fs . existsSync ( terminalVenvBinDir ) ) {
118115 const pythonNames = [ 'python' , 'python3' , 'python3.10' , 'python3.11' , 'python3.12' ] ;
119116 const bundlePath = path . resolve ( appPath ) ;
120117
121118 for ( const pythonName of pythonNames ) {
122- const pythonSymlink = path . join ( binDir , pythonName ) ;
123-
124- try {
125- const stats = fs . lstatSync ( pythonSymlink ) ;
126- if ( stats . isSymbolicLink ( ) ) {
127- const target = fs . readlinkSync ( pythonSymlink ) ;
128- const resolvedPath = path . resolve ( path . dirname ( pythonSymlink ) , target ) ;
129-
130- // If symlink points outside bundle or is broken, remove and recreate it
131- if ( ! resolvedPath . startsWith ( bundlePath ) || ! fs . existsSync ( resolvedPath ) ) {
132- console . log ( `Removing invalid ${ venvName } ${ pythonName } symlink: ${ target } ` ) ;
133- fs . unlinkSync ( pythonSymlink ) ;
134-
135- // Recreate symlink pointing to prebuilt Python (only for main 'python')
136- if ( prebuiltPython && pythonName === 'python' ) {
137- const relativePath = path . relative ( binDir , prebuiltPython ) ;
138- fs . symlinkSync ( relativePath , pythonSymlink ) ;
139- console . log ( `Created ${ venvName } ${ pythonName } symlink -> ${ relativePath } ` ) ;
119+ const pythonSymlink = path . join ( terminalVenvBinDir , pythonName ) ;
120+
121+ if ( fs . existsSync ( pythonSymlink ) ) {
122+ try {
123+ const stats = fs . lstatSync ( pythonSymlink ) ;
124+ if ( stats . isSymbolicLink ( ) ) {
125+ const target = fs . readlinkSync ( pythonSymlink ) ;
126+ const resolvedPath = path . resolve ( path . dirname ( pythonSymlink ) , target ) ;
127+
128+ // If symlink points outside bundle, remove it
129+ if ( ! resolvedPath . startsWith ( bundlePath ) ) {
130+ console . log ( `Removing invalid terminal_venv ${ pythonName } symlink: ${ target } ` ) ;
131+ fs . unlinkSync ( pythonSymlink ) ;
140132 }
141133 }
142- }
143- } catch ( error ) {
144- // Symlink doesn't exist, create it if this is the main python symlink
145- if ( error . code === 'ENOENT' && prebuiltPython && pythonName === 'python' ) {
146- try {
147- const relativePath = path . relative ( binDir , prebuiltPython ) ;
148- fs . symlinkSync ( relativePath , pythonSymlink ) ;
149- console . log ( `Created missing ${ venvName } ${ pythonName } symlink -> ${ relativePath } ` ) ;
150- } catch ( createError ) {
151- console . warn ( `Warning: Could not create ${ venvName } ${ pythonName } symlink: ${ createError . message } ` ) ;
152- }
134+ } catch ( error ) {
135+ console . warn ( `Warning: Could not process terminal_venv ${ pythonName } symlink: ${ error . message } ` ) ;
153136 }
154137 }
155138 }
156139 }
157140
158- // Fix Python symlinks in both venv directories
159- fixPythonSymlinks ( path . join ( prebuiltPath , 'venv' , 'bin' ) , 'venv' ) ;
160- fixPythonSymlinks ( path . join ( prebuiltPath , 'terminal_venv' , 'bin' ) , 'terminal_venv' ) ;
161-
162- // Recursively clean other invalid symlinks (skip already-processed venv bin directories)
163- const processedDirs = new Set ( [
164- path . join ( prebuiltPath , 'venv' , 'bin' ) ,
165- path . join ( prebuiltPath , 'terminal_venv' , 'bin' ) ,
166- ] ) ;
167-
141+ // Recursively clean other invalid symlinks
168142 function cleanSymlinks ( dir , bundleRoot ) {
169- if ( ! fs . existsSync ( dir ) || processedDirs . has ( dir ) ) {
143+ if ( ! fs . existsSync ( dir ) ) {
170144 return ;
171145 }
172146
0 commit comments