Files
letro-ios/Tools/Sources/Commands/AppIconBanner.swift
Doug ea4f1ba9f3 Automatically open a PR to bump the calver (#4167)
* Update our tools package to Swift 6.1

Also improves the package layout with subdirectories 📁

* Update GenerateSDKMocks to be an Async command.

* Add a tool to bump the project CalVer every month.

* Add a workflow to automatically bump the calendar version.

Note: This only does year & month, the patch is handled by the release script.
2025-06-03 17:52:16 +01:00

66 lines
2.2 KiB
Swift

import ArgumentParser
import SwiftUI
struct AppIconBanner: AsyncParsableCommand {
static let configuration = CommandConfiguration(abstract: "A Swift command-line tool to add a banner to an app icons.")
@Argument(help: "Path to the input image.")
var path: String
@Option(help: "Text for the banner.")
var bannerText: String
@MainActor
func run() async throws {
let currentDirectoryURL = URL(filePath: FileManager.default.currentDirectoryPath)
let pathURL = currentDirectoryURL.appending(path: path)
guard let image = NSImage(contentsOf: pathURL) else {
throw ValidationError("Could not load the image at \(pathURL).")
}
let renderer = ImageRenderer(content: BannerImage(image: image,
text: bannerText))
do {
guard let cgImage = renderer.cgImage else {
throw ValidationError("Couldn't generate CG image.")
}
let bitmap = NSBitmapImageRep(cgImage: cgImage)
guard let pngData = bitmap.representation(using: .png, properties: [:]) else {
throw ValidationError("Couldn't create png data from image.")
}
try pngData.write(to: pathURL)
print("Successfully saved the image with a banner to \(pathURL).")
} catch {
throw ValidationError("Failed to save the image: \(error).")
}
}
}
struct BannerImage: View {
let image: NSImage
let text: String
var body: some View {
ZStack(alignment: .bottom) {
Image(nsImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
Text(text)
.frame(maxWidth: .infinity)
.padding()
.background(Color.black.opacity(0.5))
.foregroundColor(.white)
.font(.system(size: 140))
.lineLimit(1)
.allowsTightening(true)
}
.frame(width: image.size.width, height: image.size.height)
}
}