mirror of
				https://github.com/open-webui/desktop
				synced 2025-06-26 18:15:59 +00:00 
			
		
		
		
	refac: python tar
This commit is contained in:
		
							parent
							
								
									be467b390c
								
							
						
					
					
						commit
						4e99cf651e
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -91,5 +91,5 @@ typings/ | ||||
| # Electron-Forge | ||||
| out/ | ||||
| 
 | ||||
| 
 | ||||
| resources/python.tar.gz | ||||
| resources/python | ||||
| resources/python.tar.gz | ||||
|  | ||||
| @ -9,7 +9,9 @@ | ||||
|     "package": "electron-forge package", | ||||
|     "make": "electron-forge make", | ||||
|     "publish": "electron-forge publish", | ||||
|     "lint": "eslint --ext .ts,.tsx ." | ||||
|     "lint": "eslint --ext .ts,.tsx .", | ||||
|     "create:conda-lock": "cd resources && rimraf conda-lock.yml && conda-lock -f environment.yml && cd -", | ||||
|     "create:python-tar": "rimraf ./resources/python.tar.gz && conda-lock install --prefix ./resources/python ./resources/conda-lock.yml && conda pack -p ./resources/python -o ./resources/python.tar.gz" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@electron-forge/cli": "^7.6.0", | ||||
|  | ||||
							
								
								
									
										1125
									
								
								resources/conda-lock.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1125
									
								
								resources/conda-lock.yml
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								resources/environment.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								resources/environment.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| # environment.yml | ||||
| channels: | ||||
|   - conda-forge | ||||
| dependencies: | ||||
|   - python=3.11 | ||||
| platforms: | ||||
|   - linux-64 | ||||
|   - linux-aarch64 # aka arm64, use for Docker on Apple Silicon | ||||
|   - osx-64 | ||||
|   - osx-arm64 # For Apple Silicon, e.g. M1/M2 | ||||
|   - win-64 | ||||
|   # TODO: Add win-arm64 when available | ||||
| @ -45,6 +45,9 @@ if (!gotTheLock) { | ||||
| 
 | ||||
|   const onReady = () => { | ||||
|     console.log(process.resourcesPath); | ||||
|     console.log(app.getName()); | ||||
|     console.log(app.getPath("userData")); | ||||
|     console.log(app.getPath("appData")); | ||||
|     mainWindow = new BrowserWindow({ | ||||
|       width: 800, | ||||
|       height: 600, | ||||
|  | ||||
| @ -20,7 +20,7 @@ import { app } from "electron"; | ||||
| //
 | ||||
| ////////////////////////////////////////////////
 | ||||
| 
 | ||||
| export function getAppDir(): string { | ||||
| export function getAppPath(): string { | ||||
|   let appDir = app.getAppPath(); | ||||
|   if (!app.isPackaged) { | ||||
|     appDir = path.dirname(appDir); | ||||
| @ -28,11 +28,11 @@ export function getAppDir(): string { | ||||
|   return appDir; | ||||
| } | ||||
| 
 | ||||
| export function getUserHomeDir(): string { | ||||
| export function getUserHomePath(): string { | ||||
|   return app.getPath("home"); | ||||
| } | ||||
| 
 | ||||
| export function getUserDataDir(): string { | ||||
| export function getUserDataPath(): string { | ||||
|   const userDataDir = app.getPath("userData"); | ||||
| 
 | ||||
|   if (!fs.existsSync(userDataDir)) { | ||||
| @ -52,16 +52,13 @@ export function getUserDataDir(): string { | ||||
| //
 | ||||
| ////////////////////////////////////////////////
 | ||||
| 
 | ||||
| export function getPackagedPythonTarPath(): string { | ||||
|   const appDir = getAppDir(); | ||||
|   return path.join(appDir, "resources", "python.tar.gz"); | ||||
| export function getBundledPythonTarPath(): string { | ||||
|   const appPath = getAppPath(); | ||||
|   return path.join(appPath, "resources", "python.tar.gz"); | ||||
| } | ||||
| 
 | ||||
| export function getBundledPythonEnvDir(): string { | ||||
|   const installDir = | ||||
|     process.platform === "darwin" | ||||
|       ? path.normalize(path.join(app.getPath("home"), "Library", app.getName())) | ||||
|       : app.getPath("userData"); | ||||
| export function getBundledPythonInstallPath(): string { | ||||
|   const installDir = path.join(app.getPath("userData"), "python"); | ||||
| 
 | ||||
|   if (!fs.existsSync(installDir)) { | ||||
|     try { | ||||
| @ -73,12 +70,6 @@ export function getBundledPythonEnvDir(): string { | ||||
|   return installDir; | ||||
| } | ||||
| 
 | ||||
| export function getBundledPythonEnvPath(): string { | ||||
|   const userDataDir = getBundledPythonEnvDir(); | ||||
| 
 | ||||
|   return path.join(userDataDir, "python"); | ||||
| } | ||||
| 
 | ||||
| export function isCondaEnv(envPath: string): boolean { | ||||
|   return fs.existsSync(path.join(envPath, "conda-meta")); | ||||
| } | ||||
| @ -92,3 +83,82 @@ export function getPythonPath(envPath: string, isConda?: boolean) { | ||||
|     return path.join(envPath, "bin", "python"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function getBundledPythonPath() { | ||||
|   return getPythonPath(getBundledPythonInstallPath()); | ||||
| } | ||||
| 
 | ||||
| export function isBundledPythonInstalled() { | ||||
|   return fs.existsSync(getBundledPythonPath()); | ||||
| } | ||||
| 
 | ||||
| ////////////////////////////////////////////////
 | ||||
| //
 | ||||
| // Fixes code-signing issues in macOS by applying ad-hoc signatures to extracted environment files.
 | ||||
| //
 | ||||
| // Unpacking a Conda environment on macOS may break the signatures of binaries, causing macOS
 | ||||
| // Gatekeeper to block them. This script assigns an ad-hoc signature (`-s -`), making the binaries
 | ||||
| // executable while bypassing macOS's strict validation without requiring trusted certificates.
 | ||||
| //
 | ||||
| // It reads an architecture-specific file (`sign-osx-arm64.txt` or `sign-osx-64.txt`), which lists
 | ||||
| // files requiring re-signing, and generates a `codesign` command to fix them all within the `envPath`.
 | ||||
| //
 | ||||
| ////////////////////////////////////////////////
 | ||||
| 
 | ||||
| export function createAdHocSignCommand(envPath: string): string { | ||||
|   const appPath = getAppPath(); | ||||
| 
 | ||||
|   const signListFile = path.join( | ||||
|     appPath, | ||||
|     "resources", | ||||
|     `sign-osx-${process.arch === "arm64" ? "arm64" : "64"}.txt` | ||||
|   ); | ||||
|   const fileContents = fs.readFileSync(signListFile, "utf-8"); | ||||
|   const signList: string[] = []; | ||||
| 
 | ||||
|   fileContents.split(/\r?\n/).forEach((line) => { | ||||
|     if (line) { | ||||
|       signList.push(`"${line}"`); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   // sign all binaries with ad-hoc signature
 | ||||
|   return `cd ${envPath} && codesign -s - -o 0x2 -f ${signList.join( | ||||
|     " " | ||||
|   )} && cd -`;
 | ||||
| } | ||||
| 
 | ||||
| export async function installBundledPython(installPath?: string) { | ||||
|   const platform = process.platform; | ||||
|   const isWin = platform === "win32"; | ||||
|   installPath = installPath || getBundledPythonInstallPath(); | ||||
| 
 | ||||
|   const pythonTarPath = getBundledPythonTarPath(); | ||||
|   if (!fs.existsSync(pythonTarPath)) { | ||||
|     log.error("Python tarball not found"); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   try { | ||||
|     fs.mkdirSync(installPath, { recursive: true }); | ||||
|     await tar.x({ | ||||
|       cwd: installPath, | ||||
|       file: pythonTarPath, | ||||
|     }); | ||||
|   } catch (error) { | ||||
|     log.error(error); | ||||
|   } | ||||
| 
 | ||||
|   let unpackCommand = isWin | ||||
|     ? `${installPath}\\Scripts\\activate.bat && conda-unpack` | ||||
|     : `source "${installPath}/bin/activate" && conda-unpack`; | ||||
| 
 | ||||
|   // only unsign when installing from bundled installer
 | ||||
|   if (platform === "darwin") { | ||||
|     unpackCommand = `${createAdHocSignCommand(installPath)}\n${unpackCommand}`; | ||||
|   } | ||||
| 
 | ||||
|   const commandProcess = exec(unpackCommand, { | ||||
|     shell: isWin ? "cmd.exe" : "/bin/bash", | ||||
|   }); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user