* Download template from GitHub release
(
platform: 'iOS' | 'macOS',
commandExecutor: CommandExecutor,
fileSystemExecutor: FileSystemExecutor,
)
| 62 | * Download template from GitHub release |
| 63 | */ |
| 64 | private static async downloadTemplate( |
| 65 | platform: 'iOS' | 'macOS', |
| 66 | commandExecutor: CommandExecutor, |
| 67 | fileSystemExecutor: FileSystemExecutor, |
| 68 | ): Promise<string> { |
| 69 | const repo = platform === 'iOS' ? this.IOS_TEMPLATE_REPO : this.MACOS_TEMPLATE_REPO; |
| 70 | const defaultVersion = |
| 71 | platform === 'iOS' ? String(iOSTemplateVersion) : String(macOSTemplateVersion); |
| 72 | const config = getConfig(); |
| 73 | const version = String( |
| 74 | platform === 'iOS' |
| 75 | ? (config.iosTemplateVersion ?? defaultVersion) |
| 76 | : (config.macosTemplateVersion ?? defaultVersion), |
| 77 | ); |
| 78 | |
| 79 | // Create temp directory for download |
| 80 | const tempDir = join(tmpdir(), `xcodebuild-mcp-template-${randomUUID()}`); |
| 81 | await fileSystemExecutor.mkdir(tempDir, { recursive: true }); |
| 82 | |
| 83 | try { |
| 84 | const downloadUrl = `https://github.com/${this.GITHUB_ORG}/${repo}/releases/download/${version}/${repo}-${version.substring(1)}.zip`; |
| 85 | const zipPath = join(tempDir, 'template.zip'); |
| 86 | |
| 87 | log('info', `Downloading ${platform} template ${version} from GitHub...`); |
| 88 | log('info', `Download URL: ${downloadUrl}`); |
| 89 | |
| 90 | const curlResult = await commandExecutor( |
| 91 | ['curl', '-L', '-f', '-o', zipPath, downloadUrl], |
| 92 | 'Download Template', |
| 93 | true, |
| 94 | undefined, |
| 95 | ); |
| 96 | |
| 97 | if (!curlResult.success) { |
| 98 | throw new Error(`Failed to download template: ${curlResult.error}`); |
| 99 | } |
| 100 | |
| 101 | // Extract the zip file |
| 102 | // Temporarily change to temp directory for extraction |
| 103 | const originalCwd = process.cwd(); |
| 104 | try { |
| 105 | process.chdir(tempDir); |
| 106 | const unzipResult = await commandExecutor( |
| 107 | ['unzip', '-q', zipPath], |
| 108 | 'Extract Template', |
| 109 | true, |
| 110 | undefined, |
| 111 | ); |
| 112 | |
| 113 | if (!unzipResult.success) { |
| 114 | throw new Error(`Failed to extract template: ${unzipResult.error}`); |
| 115 | } |
| 116 | } finally { |
| 117 | process.chdir(originalCwd); |
| 118 | } |
| 119 | |
| 120 | // Find the extracted directory and return the template subdirectory |
| 121 | const extractedDir = join(tempDir, `${repo}-${version.substring(1)}`); |
no test coverage detected