UNPKG

shipthis

Version:

ShipThis manages building and uploading your Godot games to the App Store and Google Play.

120 lines (117 loc) 3.96 kB
import { B as BaseCommand } from '../../baseCommand-CTn3KGH3.js'; import { Flags, Args } from '@oclif/core'; import * as fs from 'node:fs'; import * as path from 'node:path'; import xcode from 'xcode'; import 'chalk'; import 'axios'; import 'crypto-js'; import 'uuid'; import 'luxon'; import '@expo/apple-utils/build/index.js'; import 'node:crypto'; import 'node:readline'; import 'node:url'; import 'readline-sync'; import 'isomorphic-git'; import 'deepmerge'; import 'ini'; import '@tanstack/react-query'; import 'react'; import 'fast-glob'; import 'yazl'; import 'socket.io-client'; import 'fullscreen-ink'; import 'ink'; async function applyLiquidGlassIcon(opts) { const { projectDir, iconDir, verbose } = opts; const info = (msg) => { if (!verbose) return; console.log(msg); }; const warn = (msg) => console.warn(`Warning: ${msg}`); info(`Applying Liquid Glass icon from: ${iconDir}`); if (!fs.existsSync(projectDir)) { throw new Error(`projectDir not found: ${projectDir}`); } const pbxprojPath = path.join(projectDir, "project.pbxproj"); if (!fs.existsSync(pbxprojPath)) { throw new Error(`project.pbxproj not found at: ${pbxprojPath}`); } if (!fs.existsSync(iconDir)) { throw new Error(`Icon directory not found: ${iconDir}`); } const iconFolderName = path.basename(iconDir); const appIconName = iconFolderName.replace(/\.icon$/i, ""); info(`Detected .icon folder: ${iconFolderName}`); info(`Derived app icon name: ${appIconName}`); const projectRoot = path.dirname(projectDir); const destIconDir = path.join(projectRoot, iconFolderName); if (!fs.existsSync(destIconDir)) { info(`Copying .icon folder into project root: ${destIconDir}`); await fs.promises.cp(iconDir, destIconDir, { recursive: true }); } else { info(`Icon folder already exists in project root, skipping copy.`); } const project = xcode.project(pbxprojPath); project.parseSync(); info(`Adding folder reference to Copy Bundle Resources: ${iconFolderName}`); const firstProject = project.getFirstProject(); const mainGroupId = firstProject.firstProject.mainGroup; const mainGroup = project.getPBXGroupByKey(mainGroupId); const fileRef = project.addResourceFile( iconFolderName, { lastKnownFileType: "folder.iconcomposer.icon" }, mainGroup.name ); if (fileRef) { project.addToPbxResourcesBuildPhase(fileRef); } else { warn(`Folder reference may already exist in project: ${iconFolderName}`); } const configs = project.pbxXCBuildConfigurationSection(); let modified = 0; info(`Updating build settings for app icon: ${appIconName}`); for (const key in configs) { const cfg = configs[key]; if (!cfg || typeof cfg !== "object" || !cfg.buildSettings) continue; cfg.buildSettings["ASSETCATALOG_COMPILER_APPICON_NAME"] = appIconName; cfg.buildSettings["ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS"] = "YES"; modified++; } info(`Modified ${modified} build configurations`); info(`Writing updated project to ${pbxprojPath}`); fs.writeFileSync(pbxprojPath, project.writeSync()); info(`Liquid Glass icon successfully applied.`); } class InternalGlass extends BaseCommand { static description = "Apply a Liquid Glass .icon folder to a local Xcode project"; static flags = { verbose: Flags.boolean({ default: false, description: "Enable verbose logging" }) }; static args = { project: Args.string({ description: "Path to the .xcodeproj directory", required: true }), icon: Args.string({ description: "Path to the .icon folder", required: true }) }; async run() { const { args, flags } = await this.parse(InternalGlass); await applyLiquidGlassIcon({ projectDir: args.project, iconDir: args.icon, verbose: flags.verbose }); this.log("Liquid Glass icon applied."); } } export { applyLiquidGlassIcon, InternalGlass as default };