Эх сурвалжийг харах

feat(bundler): add dmg settings, closes #4669 (#7964)

Andrew 1 жил өмнө
parent
commit
b0c5b06d06

+ 157 - 0
core/tauri-config-schema/schema.json

@@ -37,6 +37,20 @@
           "deb": {
             "files": {}
           },
+          "dmg": {
+            "appPosition": {
+              "x": 180,
+              "y": 170
+            },
+            "applicationFolderPosition": {
+              "x": 480,
+              "y": 170
+            },
+            "windowSize": {
+              "height": 400,
+              "width": 660
+            }
+          },
           "iOS": {},
           "icon": [],
           "identifier": "",
@@ -171,6 +185,20 @@
             "deb": {
               "files": {}
             },
+            "dmg": {
+              "appPosition": {
+                "x": 180,
+                "y": 170
+              },
+              "applicationFolderPosition": {
+                "x": 480,
+                "y": 170
+              },
+              "windowSize": {
+                "height": 400,
+                "width": 660
+              }
+            },
             "iOS": {},
             "icon": [],
             "identifier": "",
@@ -1003,6 +1031,28 @@
             }
           ]
         },
+        "dmg": {
+          "description": "DMG-specific settings.",
+          "default": {
+            "appPosition": {
+              "x": 180,
+              "y": 170
+            },
+            "applicationFolderPosition": {
+              "x": 480,
+              "y": 170
+            },
+            "windowSize": {
+              "height": 400,
+              "width": 660
+            }
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/DmgConfig"
+            }
+          ]
+        },
         "macOS": {
           "description": "Configuration for the macOS bundles.",
           "default": {
@@ -1318,6 +1368,113 @@
       },
       "additionalProperties": false
     },
+    "DmgConfig": {
+      "description": "Configuration for Apple Disk Image (.dmg) bundles.\n\nSee more: https://tauri.app/v1/api/config#dmgconfig",
+      "type": "object",
+      "properties": {
+        "background": {
+          "description": "Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.",
+          "type": [
+            "string",
+            "null"
+          ]
+        },
+        "windowPosition": {
+          "description": "Position of volume window on screen.",
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Position"
+            },
+            {
+              "type": "null"
+            }
+          ]
+        },
+        "windowSize": {
+          "description": "Size of volume window.",
+          "default": {
+            "height": 400,
+            "width": 660
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Size"
+            }
+          ]
+        },
+        "appPosition": {
+          "description": "Position of app file on window.",
+          "default": {
+            "x": 180,
+            "y": 170
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Position"
+            }
+          ]
+        },
+        "applicationFolderPosition": {
+          "description": "Position of application folder on window.",
+          "default": {
+            "x": 480,
+            "y": 170
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Position"
+            }
+          ]
+        }
+      },
+      "additionalProperties": false
+    },
+    "Position": {
+      "description": "Position coordinates struct.",
+      "type": "object",
+      "required": [
+        "x",
+        "y"
+      ],
+      "properties": {
+        "x": {
+          "description": "X coordinate.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        },
+        "y": {
+          "description": "Y coordinate.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        }
+      },
+      "additionalProperties": false
+    },
+    "Size": {
+      "description": "Size of the window.",
+      "type": "object",
+      "required": [
+        "height",
+        "width"
+      ],
+      "properties": {
+        "width": {
+          "description": "Width of the window.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        },
+        "height": {
+          "description": "Height of the window.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        }
+      },
+      "additionalProperties": false
+    },
     "MacConfig": {
       "description": "Configuration for the macOS bundles.\n\nSee more: <https://tauri.app/v1/api/config#macconfig>",
       "type": "object",

+ 95 - 0
core/tauri-utils/src/config.rs

@@ -282,6 +282,95 @@ pub struct DebConfig {
   pub desktop_template: Option<PathBuf>,
 }
 
+/// Position coordinates struct.
+#[derive(Default, Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
+#[cfg_attr(feature = "schema", derive(JsonSchema))]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct Position {
+  /// X coordinate.
+  pub x: u32,
+  /// Y coordinate.
+  pub y: u32,
+}
+
+/// Size of the window.
+#[derive(Default, Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
+#[cfg_attr(feature = "schema", derive(JsonSchema))]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct Size {
+  /// Width of the window.
+  pub width: u32,
+  /// Height of the window.
+  pub height: u32,
+}
+
+
+
+/// Configuration for Apple Disk Image (.dmg) bundles.
+///
+/// See more: https://tauri.app/v1/api/config#dmgconfig
+#[skip_serializing_none]
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
+#[cfg_attr(feature = "schema", derive(JsonSchema))]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct DmgConfig {
+  /// Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.
+  pub background: Option<PathBuf>,
+  /// Position of volume window on screen.
+  pub window_position: Option<Position>,
+  /// Size of volume window.
+  #[serde(
+    default = "window_size",
+    alias = "window-size"
+  )]
+  pub window_size: Size,
+  /// Position of app file on window.
+  #[serde(
+    default = "app_position",
+    alias = "app-position"
+  )]
+  pub app_position: Position,
+  /// Position of application folder on window.
+  #[serde(
+    default = "application_folder_position",
+    alias = "application-folder-position"
+  )]
+  pub application_folder_position: Position,
+}
+
+impl Default for DmgConfig {
+  fn default() -> Self {
+    Self {
+      background: None,
+      window_position: None,
+      window_size: window_size(),
+      app_position: app_position(),
+      application_folder_position: application_folder_position(),
+    }
+  }
+}
+
+fn window_size() -> Size {
+  Size {
+    width: 660,
+    height: 400,
+  }
+}
+
+fn app_position() -> Position {
+  Position {
+    x: 180,
+    y: 170,
+  }
+}
+
+fn application_folder_position() -> Position {
+  Position {
+    x: 480,
+    y: 170,
+  }
+}
+
 fn de_minimum_system_version<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
 where
   D: Deserializer<'de>,
@@ -850,6 +939,9 @@ pub struct BundleConfig {
   /// Configuration for the Debian bundle.
   #[serde(default)]
   pub deb: DebConfig,
+  /// DMG-specific settings.
+  #[serde(default)]
+  pub dmg: DmgConfig,
   /// Configuration for the macOS bundles.
   #[serde(rename = "macOS", default)]
   pub macos: MacConfig,
@@ -2440,6 +2532,7 @@ mod build {
       let long_description = quote!(None);
       let appimage = quote!(Default::default());
       let deb = quote!(Default::default());
+      let dmg = quote!(Default::default());
       let macos = quote!(Default::default());
       let external_bin = opt_vec_str_lit(self.external_bin.as_ref());
       let windows = &self.windows;
@@ -2463,6 +2556,7 @@ mod build {
         long_description,
         appimage,
         deb,
+        dmg,
         macos,
         external_bin,
         windows,
@@ -2771,6 +2865,7 @@ mod test {
         long_description: None,
         appimage: Default::default(),
         deb: Default::default(),
+        dmg: Default::default(),
         macos: Default::default(),
         external_bin: None,
         windows: Default::default(),

+ 2 - 2
tooling/bundler/src/bundle.rs

@@ -20,8 +20,8 @@ use tauri_utils::display_path;
 pub use self::{
   category::AppCategory,
   settings::{
-    BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings, PackageType,
-    Settings, SettingsBuilder, UpdaterSettings,
+    BundleBinary, BundleSettings, DebianSettings, DmgSettings, MacOsSettings, PackageSettings, PackageType,
+    Settings, SettingsBuilder, UpdaterSettings, Position, Size
   },
 };
 #[cfg(target_os = "macos")]

+ 58 - 14
tooling/bundler/src/bundle/macos/dmg.rs

@@ -96,23 +96,62 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<
     .output()
     .expect("Failed to chmod script");
 
+  let dmg_settings = settings.dmg();
+
+  let app_position = &dmg_settings.app_position;
+  let application_folder_position = &dmg_settings.application_folder_position;
+  let window_size = &dmg_settings.window_size;
+
+  let app_position_x = app_position.x.to_string();
+  let app_position_y = app_position.y.to_string();
+  let application_folder_position_x = application_folder_position.x.to_string();
+  let application_folder_position_y = application_folder_position.y.to_string();
+  let window_size_width = window_size.width.to_string();
+  let window_size_height = window_size.height.to_string();
+
   let mut args = vec![
     "--volname",
     product_name,
     "--icon",
     &bundle_file_name,
-    "180",
-    "170",
+    &app_position_x,
+    &app_position_y,
     "--app-drop-link",
-    "480",
-    "170",
+    &application_folder_position_x,
+    &application_folder_position_y,
     "--window-size",
-    "660",
-    "400",
+    &window_size_width,
+    &window_size_height,
     "--hide-extension",
     &bundle_file_name,
   ];
 
+  let window_position = dmg_settings.window_position.as_ref().map(|position| {
+    (position.x.to_string(), position.y.to_string())
+  });
+
+  if let Some(window_position) = &window_position {
+    args.push("--window-pos");
+    args.push(&window_position.0);
+    args.push(&window_position.1);
+  }
+
+  let background_path_string = if let Some(background_path) = &dmg_settings.background {
+    Some(
+      env::current_dir()?
+        .join(background_path)
+        .to_string_lossy()
+        .to_string(),
+    )
+  } else {
+    None
+  };
+
+  if let Some(background_path_string) = &background_path_string {
+    args.push("--background");
+    args.push(background_path_string);
+  }
+
   let icns_icon_path =
     create_icns_file(&output_path, settings)?.map(|path| path.to_string_lossy().to_string());
   if let Some(icon) = &icns_icon_path {
@@ -120,15 +159,20 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<
     args.push(icon);
   }
 
-  #[allow(unused_assignments)]
-  let mut license_path_ref = "".to_string();
-  if let Some(license_path) = &settings.macos().license {
+  let license_path_string = if let Some(license_path) = &settings.macos().license {
+    Some(
+      env::current_dir()?
+        .join(license_path)
+        .to_string_lossy()
+        .to_string(),
+    )
+  } else {
+    None
+  };
+
+  if let Some(license_path) = &license_path_string {
     args.push("--eula");
-    license_path_ref = env::current_dir()?
-      .join(license_path)
-      .to_string_lossy()
-      .to_string();
-    args.push(&license_path_ref);
+    args.push(license_path);
   }
 
   // Issue #592 - Building MacOS dmg files on CI

+ 40 - 0
tooling/bundler/src/bundle/settings.rs

@@ -183,6 +183,39 @@ pub struct DebianSettings {
   pub desktop_template: Option<PathBuf>,
 }
 
+/// Position coordinates struct.
+#[derive(Clone, Debug, Default)]
+pub struct Position {
+  /// X coordinate.
+  pub x: u32,
+  /// Y coordinate.
+  pub y: u32,
+}
+
+/// Size of the window.
+#[derive(Clone, Debug, Default)]
+pub struct Size {
+  /// Width of the window.
+  pub width: u32,
+  /// Height of the window.
+  pub height: u32,
+}
+
+/// The DMG bundle settings.
+#[derive(Clone, Debug, Default)]
+pub struct DmgSettings {
+  /// Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.
+  pub background: Option<PathBuf>,
+  /// Position of volume window on screen.
+  pub window_position: Option<Position>,
+  /// Size of volume window.
+  pub window_size: Size,
+  /// Position of app file on window.
+  pub app_position: Position,
+  /// Position of application folder on window.
+  pub application_folder_position: Position,
+}
+
 /// The macOS bundle settings.
 #[derive(Clone, Debug, Default)]
 pub struct MacOsSettings {
@@ -416,6 +449,8 @@ pub struct BundleSettings {
   pub external_bin: Option<Vec<String>>,
   /// Debian-specific settings.
   pub deb: DebianSettings,
+  /// DMG-specific settings.
+  pub dmg: DmgSettings,
   /// MacOS-specific settings.
   pub macos: MacOsSettings,
   /// Updater configuration.
@@ -850,6 +885,11 @@ impl Settings {
     &self.bundle_settings.deb
   }
 
+  /// Returns the DMG settings.
+  pub fn dmg(&self) -> &DmgSettings {
+    &self.bundle_settings.dmg
+  }
+
   /// Returns the MacOS settings.
   pub fn macos(&self) -> &MacOsSettings {
     &self.bundle_settings.macos

+ 3 - 0
tooling/bundler/src/error.rs

@@ -67,6 +67,9 @@ pub enum Error {
   /// Couldn't find icons.
   #[error("Could not find Icon paths.  Please make sure they exist in the tauri config JSON file")]
   IconPathError,
+  /// Couldn't find background file.
+  #[error("Could not find background file. Make sure it exists in the tauri config JSON file and extension is png/jpg/gif")]
+  BackgroundPathError,
   /// Error on path util operation.
   #[error("Path Error:`{0}`")]
   PathUtilError(String),

+ 157 - 0
tooling/cli/schema.json

@@ -37,6 +37,20 @@
           "deb": {
             "files": {}
           },
+          "dmg": {
+            "appPosition": {
+              "x": 180,
+              "y": 170
+            },
+            "applicationFolderPosition": {
+              "x": 480,
+              "y": 170
+            },
+            "windowSize": {
+              "height": 400,
+              "width": 660
+            }
+          },
           "iOS": {},
           "icon": [],
           "identifier": "",
@@ -171,6 +185,20 @@
             "deb": {
               "files": {}
             },
+            "dmg": {
+              "appPosition": {
+                "x": 180,
+                "y": 170
+              },
+              "applicationFolderPosition": {
+                "x": 480,
+                "y": 170
+              },
+              "windowSize": {
+                "height": 400,
+                "width": 660
+              }
+            },
             "iOS": {},
             "icon": [],
             "identifier": "",
@@ -1003,6 +1031,28 @@
             }
           ]
         },
+        "dmg": {
+          "description": "DMG-specific settings.",
+          "default": {
+            "appPosition": {
+              "x": 180,
+              "y": 170
+            },
+            "applicationFolderPosition": {
+              "x": 480,
+              "y": 170
+            },
+            "windowSize": {
+              "height": 400,
+              "width": 660
+            }
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/DmgConfig"
+            }
+          ]
+        },
         "macOS": {
           "description": "Configuration for the macOS bundles.",
           "default": {
@@ -1318,6 +1368,113 @@
       },
       "additionalProperties": false
     },
+    "DmgConfig": {
+      "description": "Configuration for Apple Disk Image (.dmg) bundles.\n\nSee more: https://tauri.app/v1/api/config#dmgconfig",
+      "type": "object",
+      "properties": {
+        "background": {
+          "description": "Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.",
+          "type": [
+            "string",
+            "null"
+          ]
+        },
+        "windowPosition": {
+          "description": "Position of volume window on screen.",
+          "anyOf": [
+            {
+              "$ref": "#/definitions/Position"
+            },
+            {
+              "type": "null"
+            }
+          ]
+        },
+        "windowSize": {
+          "description": "Size of volume window.",
+          "default": {
+            "height": 400,
+            "width": 660
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Size"
+            }
+          ]
+        },
+        "appPosition": {
+          "description": "Position of app file on window.",
+          "default": {
+            "x": 180,
+            "y": 170
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Position"
+            }
+          ]
+        },
+        "applicationFolderPosition": {
+          "description": "Position of application folder on window.",
+          "default": {
+            "x": 480,
+            "y": 170
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/Position"
+            }
+          ]
+        }
+      },
+      "additionalProperties": false
+    },
+    "Position": {
+      "description": "Position coordinates struct.",
+      "type": "object",
+      "required": [
+        "x",
+        "y"
+      ],
+      "properties": {
+        "x": {
+          "description": "X coordinate.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        },
+        "y": {
+          "description": "Y coordinate.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        }
+      },
+      "additionalProperties": false
+    },
+    "Size": {
+      "description": "Size of the window.",
+      "type": "object",
+      "required": [
+        "height",
+        "width"
+      ],
+      "properties": {
+        "width": {
+          "description": "Width of the window.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        },
+        "height": {
+          "description": "Height of the window.",
+          "type": "integer",
+          "format": "uint32",
+          "minimum": 0.0
+        }
+      },
+      "additionalProperties": false
+    },
     "MacConfig": {
       "description": "Configuration for the macOS bundles.\n\nSee more: <https://tauri.app/v1/api/config#macconfig>",
       "type": "object",

+ 24 - 2
tooling/cli/src/interface/rust.rs

@@ -22,8 +22,8 @@ use notify::RecursiveMode;
 use notify_debouncer_mini::new_debouncer;
 use serde::Deserialize;
 use tauri_bundler::{
-  AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings,
-  UpdaterSettings, WindowsSettings,
+  AppCategory, BundleBinary, BundleSettings, DebianSettings, DmgSettings, MacOsSettings, PackageSettings,
+  UpdaterSettings, WindowsSettings, Position, Size
 };
 use tauri_utils::config::parse::is_configuration_file;
 
@@ -1177,6 +1177,28 @@ fn tauri_config_to_bundle_settings(
       files: config.deb.files,
       desktop_template: config.deb.desktop_template,
     },
+    dmg: DmgSettings {
+      background: config.dmg.background,
+      window_position: match config.dmg.window_position {
+        Some(window_position) => Some(Position {
+          x: window_position.x,
+          y: window_position.y,
+        }),
+        None => None,
+      },
+      window_size: Size {
+          width: config.dmg.window_size.width,
+          height: config.dmg.window_size.height,
+      },
+      app_position: Position {
+        x: config.dmg.app_position.x,
+        y: config.dmg.app_position.y,
+      },
+      application_folder_position: Position {
+        x: config.dmg.application_folder_position.x,
+        y: config.dmg.application_folder_position.y,
+      },
+    },
     macos: MacOsSettings {
       frameworks: config.macos.frameworks,
       minimum_system_version: config.macos.minimum_system_version,