| ... | @@ -23,6 +23,8 @@ import * as Stream from "effect/Stream"; | ... | @@ -23,6 +23,8 @@ import * as Stream from "effect/Stream"; |
| 23 | import { Command, Flag } from "effect/unstable/cli"; | 23 | import { Command, Flag } from "effect/unstable/cli"; |
| 24 | import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; | 24 | import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; |
| 25 | | 25 | |
| | 26 | const LINUX_ICON_SIZES = [16, 22, 24, 32, 48, 64, 128, 256, 512] as const; |
| | 27 | |
| 26 | const BuildPlatform = Schema.Literals(["mac", "linux", "win"]); | 28 | const BuildPlatform = Schema.Literals(["mac", "linux", "win"]); |
| 27 | const BuildArch = Schema.Literals(["arm64", "x64", "universal"]); | 29 | const BuildArch = Schema.Literals(["arm64", "x64", "universal"]); |
| 28 | | 30 | |
| ... | @@ -417,7 +419,7 @@ function stageMacIcons(stageResourcesDir: string, sourcePng: string, verbose: bo | ... | @@ -417,7 +419,7 @@ function stageMacIcons(stageResourcesDir: string, sourcePng: string, verbose: bo |
| 417 | }); | 419 | }); |
| 418 | } | 420 | } |
| 419 | | 421 | |
| 420 | function stageLinuxIcons(stageResourcesDir: string, sourcePng: string) { | 422 | function stageLinuxIcons(stageResourcesDir: string, sourcePng: string, verbose: boolean) { |
| 421 | return Effect.gen(function* () { | 423 | return Effect.gen(function* () { |
| 422 | const fs = yield* FileSystem.FileSystem; | 424 | const fs = yield* FileSystem.FileSystem; |
| 423 | const path = yield* Path.Path; | 425 | const path = yield* Path.Path; |
| ... | @@ -429,9 +431,48 @@ function stageLinuxIcons(stageResourcesDir: string, sourcePng: string) { | ... | @@ -429,9 +431,48 @@ function stageLinuxIcons(stageResourcesDir: string, sourcePng: string) { |
| 429 | | 431 | |
| 430 | const iconPath = path.join(stageResourcesDir, "icon.png"); | 432 | const iconPath = path.join(stageResourcesDir, "icon.png"); |
| 431 | yield* fs.copyFile(sourcePng, iconPath); | 433 | yield* fs.copyFile(sourcePng, iconPath); |
| | 434 | |
| | 435 | const iconsDir = path.join(stageResourcesDir, "icons"); |
| | 436 | yield* fs.makeDirectory(iconsDir, { recursive: true }); |
| | 437 | for (const iconSize of LINUX_ICON_SIZES) { |
| | 438 | yield* stageLinuxIconSize( |
| | 439 | sourcePng, |
| | 440 | path.join(iconsDir, `${iconSize}x${iconSize}.png`), |
| | 441 | iconSize, |
| | 442 | verbose, |
| | 443 | ); |
| | 444 | } |
| 432 | }); | 445 | }); |
| 433 | } | 446 | } |
| 434 | | 447 | |
| | 448 | function stageLinuxIconSize( |
| | 449 | sourcePng: string, |
| | 450 | targetPng: string, |
| | 451 | iconSize: number, |
| | 452 | verbose: boolean, |
| | 453 | ) { |
| | 454 | const resize = (command: string) => |
| | 455 | runCommand( |
| | 456 | ChildProcess.make(command, [sourcePng, "-resize", `${iconSize}x${iconSize}`, targetPng], { |
| | 457 | ...commandOutputOptions(verbose), |
| | 458 | }), |
| | 459 | ); |
| | 460 | |
| | 461 | return resize("magick").pipe( |
| | 462 | Effect.catch(() => |
| | 463 | resize("convert").pipe( |
| | 464 | Effect.mapError( |
| | 465 | () => |
| | 466 | new BuildScriptError({ |
| | 467 | message: |
| | 468 | "ImageMagick is required to generate Linux desktop icon sizes. Install ImageMagick so either `magick` or `convert` is available.", |
| | 469 | }), |
| | 470 | ), |
| | 471 | ), |
| | 472 | ), |
| | 473 | ); |
| | 474 | } |
| | 475 | |
| 435 | function stageWindowsIcons(stageResourcesDir: string, sourceIco: string) { | 476 | function stageWindowsIcons(stageResourcesDir: string, sourceIco: string) { |
| 436 | return Effect.gen(function* () { | 477 | return Effect.gen(function* () { |
| 437 | const fs = yield* FileSystem.FileSystem; | 478 | const fs = yield* FileSystem.FileSystem; |
| ... | @@ -600,7 +641,7 @@ const createBuildConfig = Effect.fn("createBuildConfig")(function* ( | ... | @@ -600,7 +641,7 @@ const createBuildConfig = Effect.fn("createBuildConfig")(function* ( |
| 600 | buildConfig.linux = { | 641 | buildConfig.linux = { |
| 601 | target: [target], | 642 | target: [target], |
| 602 | executableName: "t3code", | 643 | executableName: "t3code", |
| 603 | icon: "icon.png", | 644 | icon: "icons", |
| 604 | category: "Development", | 645 | category: "Development", |
| 605 | desktop: { | 646 | desktop: { |
| 606 | entry: { | 647 | entry: { |
| ... | @@ -639,7 +680,7 @@ const assertPlatformBuildResources = Effect.fn("assertPlatformBuildResources")(f | ... | @@ -639,7 +680,7 @@ const assertPlatformBuildResources = Effect.fn("assertPlatformBuildResources")(f |
| 639 | } | 680 | } |
| 640 | | 681 | |
| 641 | if (platform === "linux") { | 682 | if (platform === "linux") { |
| 642 | yield* stageLinuxIcons(stageResourcesDir, iconAssets.linuxIconPng); | 683 | yield* stageLinuxIcons(stageResourcesDir, iconAssets.linuxIconPng, verbose); |
| 643 | return; | 684 | return; |
| 644 | } | 685 | } |
| 645 | | 686 | |