mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-13 12:23:38 +01:00
build(wix): the komorebi installer ships komorebi-recorder, which has no installer of its own
This commit is contained in:
1 parent
c64c71541b
commit
9854f90db7
4 files changed
+13
-242
No files matched your search
@@ -1,17 +1,10 @@
|
||||
//! The Windows installer (`wix/main.wxs`) has to ship every binary the crate builds and has to be
|
||||
//! its own product: `WiX` itself only runs on Windows, so these checks are what a Mac or Linux
|
||||
//! The recorder ships in the komorebi installer (`wix/main.wxs`), so that installer has to ship every
|
||||
//! binary this crate builds: `WiX` itself only runs on Windows, so this check is what a Mac or Linux
|
||||
//! machine can say about the installer.
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// komorebi's own installer: reusing its `UpgradeCode` would make the two products upgrade and
|
||||
/// uninstall each other.
|
||||
const KOMOREBI_UPGRADE_CODE: &str = "F8B967B5-7E7B-4E3A-895B-B789EC898B54";
|
||||
|
||||
/// komorebi's `PATH` component, which the installer tracks the `PATH` entry by.
|
||||
const KOMOREBI_PATH_COMPONENT: &str = "6C6DF276-06C4-4675-BDED-48C5C2BC9BC5";
|
||||
|
||||
fn repository() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
@@ -23,28 +16,6 @@ fn installer() -> String {
|
||||
std::fs::read_to_string(repository().join("wix/main.wxs")).expect("wix/main.wxs")
|
||||
}
|
||||
|
||||
/// The value of attribute `name` on the first element of `tag` in the installer.
|
||||
fn attribute(text: &str, tag: &str, name: &str) -> String {
|
||||
let start = text
|
||||
.find(&format!("<{tag} "))
|
||||
.unwrap_or_else(|| panic!("no <{tag}> in the installer"));
|
||||
let element = &text[start..start + text[start..].find('>').expect("a closed tag")];
|
||||
let key = format!("{name}='");
|
||||
let value = element
|
||||
.find(&key)
|
||||
.unwrap_or_else(|| panic!("<{tag}> has no {name}"))
|
||||
+ key.len();
|
||||
element[value..][..element[value..].find('\'').expect("a closed value")].to_string()
|
||||
}
|
||||
|
||||
fn is_guid(text: &str) -> bool {
|
||||
let parts: Vec<&str> = text.split('-').collect();
|
||||
parts.iter().map(|part| part.len()).collect::<Vec<_>>() == [8, 4, 4, 4, 12]
|
||||
&& parts
|
||||
.iter()
|
||||
.all(|part| part.chars().all(|c| c.is_ascii_hexdigit()))
|
||||
}
|
||||
|
||||
/// The binaries cargo builds for this crate: the package's own (`src/main.rs`) and one for each
|
||||
/// file in `src/bin`.
|
||||
fn binaries() -> Vec<String> {
|
||||
@@ -68,7 +39,7 @@ fn binaries() -> Vec<String> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_binary_the_crate_builds_is_in_the_installer() {
|
||||
fn every_binary_the_crate_builds_is_in_the_komorebi_installer() {
|
||||
let text = installer();
|
||||
for name in binaries() {
|
||||
assert!(
|
||||
@@ -81,86 +52,3 @@ fn every_binary_the_crate_builds_is_in_the_installer() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_installer_installs_nothing_the_crate_does_not_build() {
|
||||
let text = installer();
|
||||
let built = binaries();
|
||||
for piece in text.split("Name='").skip(1) {
|
||||
let name = &piece[..piece.find('\'').expect("a closed value")];
|
||||
if let Some(binary) = name.strip_suffix(".exe") {
|
||||
assert!(
|
||||
built.iter().any(|built| built == binary),
|
||||
"wix/main.wxs installs {name}, which this crate does not build"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_installer_is_its_own_product() {
|
||||
let text = installer();
|
||||
|
||||
let upgrade_code = attribute(&text, "Product", "UpgradeCode");
|
||||
assert!(
|
||||
is_guid(&upgrade_code),
|
||||
"UpgradeCode is not a GUID: {upgrade_code}"
|
||||
);
|
||||
assert!(
|
||||
!upgrade_code.eq_ignore_ascii_case(KOMOREBI_UPGRADE_CODE),
|
||||
"UpgradeCode is komorebi's: the two products would replace each other"
|
||||
);
|
||||
assert_eq!(attribute(&text, "Product", "Name"), env!("CARGO_PKG_NAME"));
|
||||
|
||||
assert!(
|
||||
!text
|
||||
.to_uppercase()
|
||||
.contains(&KOMOREBI_PATH_COMPONENT.to_uppercase()),
|
||||
"the PATH component has komorebi's GUID"
|
||||
);
|
||||
let path_guid = attribute(&text, "Component Id='Path'", "Guid");
|
||||
assert!(
|
||||
is_guid(&path_guid),
|
||||
"the PATH component's Guid: {path_guid}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_license_the_installer_shows_is_there_and_is_the_projects() {
|
||||
let rtf = std::fs::read_to_string(repository().join("wix/License.rtf")).expect("License.rtf");
|
||||
assert!(
|
||||
rtf.contains("Komorebi License"),
|
||||
"not the project's license"
|
||||
);
|
||||
assert!(rtf.contains("Version 2.0.0"), "not the project's license");
|
||||
assert!(
|
||||
installer().contains("wix\\License.rtf"),
|
||||
"main.wxs does not refer to wix\\License.rtf"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_installer_shows_the_icon_the_executables_carry() {
|
||||
let text = installer();
|
||||
|
||||
let id = attribute(&text, "Icon", "Id");
|
||||
let source = attribute(&text, "Icon", "SourceFile");
|
||||
assert!(
|
||||
text.contains(&format!("<Property Id='ARPPRODUCTICON' Value='{id}'")),
|
||||
"Apps & features is not told to show the icon {id}"
|
||||
);
|
||||
assert!(
|
||||
repository().join(source.replace('\\', "/")).is_file(),
|
||||
"wix/main.wxs takes its icon from {source}, which is not there"
|
||||
);
|
||||
|
||||
// the resource build.rs compiles into the executables names the same file
|
||||
let resource =
|
||||
std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("assets/watermelon.rc"))
|
||||
.expect("assets/watermelon.rc");
|
||||
let icon = source.rsplit('\\').next().expect("a file name");
|
||||
assert!(
|
||||
resource.contains(&format!("\"{icon}\"")),
|
||||
"the executables carry an icon other than the installer's {icon}: {resource}"
|
||||
);
|
||||
}
|
||||
Binary file not shown.
@@ -1,127 +0,0 @@
|
||||
<?xml version='1.0' encoding='windows-1252'?>
|
||||
<!--
|
||||
Copyright (C) 2017 Christopher R. Field.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
The "cargo wix" subcommand provides a variety of predefined variables available
|
||||
for customization of this template. The values for each variable are set at
|
||||
installer creation time. The following variables are available:
|
||||
|
||||
TargetTriple = The rustc target triple name.
|
||||
TargetEnv = The rustc target environment. This is typically either
|
||||
"msvc" or "gnu" depending on the toolchain downloaded and
|
||||
installed.
|
||||
TargetVendor = The rustc target vendor. This is typically "pc", but Rust
|
||||
does support other vendors, like "uwp".
|
||||
CargoTargetBinDir = The complete path to the binary (exe). The default would
|
||||
be "target\release\<BINARY_NAME>.exe" where
|
||||
"<BINARY_NAME>" is replaced with the name of each binary
|
||||
target defined in the package's manifest (Cargo.toml). If
|
||||
a different rustc target triple is used than the host,
|
||||
i.e. cross-compiling, then the default path would be
|
||||
"target\<CARGO_TARGET>\<CARGO_PROFILE>\<BINARY_NAME>.exe",
|
||||
where "<CARGO_TARGET>" is replaced with the "CargoTarget"
|
||||
variable value and "<CARGO_PROFILE>" is replaced with the
|
||||
value from the `CargoProfile` variable.
|
||||
CargoTargetDir = The path to the directory for the build artifacts, i.e.
|
||||
"target".
|
||||
CargoProfile = Either "debug" or `release` depending on the build
|
||||
profile. The default is "release".
|
||||
Version = The version for the installer. The default is the
|
||||
"Major.Minor.Fix" semantic versioning number of the Rust
|
||||
package.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Please do not remove these pre-processor If-Else blocks. These are used with
|
||||
the `cargo wix` subcommand to automatically determine the installation
|
||||
destination for 32-bit versus 64-bit installers. Removal of these lines will
|
||||
cause installation errors.
|
||||
-->
|
||||
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder"?>
|
||||
<?else ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFilesFolder"?>
|
||||
<?endif ?>
|
||||
|
||||
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
||||
|
||||
<!--
|
||||
The identifiers below belong to this product alone. `UpgradeCode` is what lets a newer
|
||||
installer replace an older one, and the GUID of the `Path` component is what the installer
|
||||
tracks the PATH entry by; reusing either from another product (komorebi has its own) would
|
||||
make the two upgrade and uninstall each other.
|
||||
-->
|
||||
<Product Id='*' Name='komorebi-recorder' UpgradeCode='720EAF41-F769-4E8D-8C47-9BD62A92F107' Manufacturer='LGUG2Z' Language='1033' Codepage='1252' Version='$(var.Version)'>
|
||||
|
||||
<Package Id='*' Keywords='Installer' Description='Synchronized screen, log and trace capture for komorebi bug reproduction' Manufacturer='LGUG2Z' InstallerVersion='500' Languages='1033' Compressed='yes' InstallScope='perMachine' SummaryCodepage='1252' />
|
||||
|
||||
<MajorUpgrade Schedule='afterInstallInitialize' DowngradeErrorMessage='A newer version of [ProductName] is already installed. Setup will now exit.' />
|
||||
|
||||
<Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1' />
|
||||
<Property Id='DiskPrompt' Value='komorebi-recorder Installation' />
|
||||
|
||||
<Directory Id='TARGETDIR' Name='SourceDir'>
|
||||
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
|
||||
<Directory Id='APPLICATIONFOLDER' Name='komorebi-recorder'>
|
||||
<Component Id='License' Guid='*'>
|
||||
<File Id='LicenseFile' Name='License.rtf' DiskId='1' Source='wix\License.rtf' KeyPath='yes' />
|
||||
</Component>
|
||||
|
||||
<Directory Id='Bin' Name='bin'>
|
||||
<Component Id='Path' Guid='F8CA04B7-C3A0-42D2-8C02-B38EBAA8842F' KeyPath='yes'>
|
||||
<Environment Id='PATH' Name='PATH' Value='[Bin]' Permanent='no' Part='last' Action='set' System='yes' />
|
||||
</Component>
|
||||
<Component Id='binary0' Guid='*'>
|
||||
<File Id='exe0' Name='komorebi-recorder.exe' DiskId='1' Source='$(var.CargoTargetBinDir)\komorebi-recorder.exe' KeyPath='yes' />
|
||||
</Component>
|
||||
<Component Id='binary1' Guid='*'>
|
||||
<File Id='exe1' Name='komorebi-recorder-gui.exe' DiskId='1' Source='$(var.CargoTargetBinDir)\komorebi-recorder-gui.exe' KeyPath='yes' />
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Feature Id='Binaries' Title='Application' Description='Installs all binaries and the license.' Level='1' ConfigurableDirectory='APPLICATIONFOLDER' AllowAdvertise='no' Display='expand' Absent='disallow'>
|
||||
<ComponentRef Id='License' />
|
||||
|
||||
<ComponentRef Id='binary0' />
|
||||
|
||||
<ComponentRef Id='binary1' />
|
||||
|
||||
<Feature Id='Environment' Title='PATH Environment Variable' Description='Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.' Level='1' Absent='allow'>
|
||||
<ComponentRef Id='Path' />
|
||||
</Feature>
|
||||
</Feature>
|
||||
|
||||
<SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize' />
|
||||
|
||||
<Property Id='ARPHELPLINK' Value='https://github.com/LGUG2Z/komorebi-recorder' />
|
||||
|
||||
<!-- the icon of the entry in Apps & features; the executables carry the same one -->
|
||||
<Icon Id='watermelon.ico' SourceFile='komorebi-recorder\assets\watermelon.ico' />
|
||||
<Property Id='ARPPRODUCTICON' Value='watermelon.ico' />
|
||||
|
||||
<UI>
|
||||
<UIRef Id='WixUI_FeatureTree' />
|
||||
</UI>
|
||||
|
||||
<WixVariable Id='WixUILicenseRtf' Value='wix\License.rtf' />
|
||||
|
||||
</Product>
|
||||
|
||||
</Wix>
|
||||
@@ -104,6 +104,12 @@
|
||||
<Component Id='binary5' Guid='*'>
|
||||
<File Id='exe5' Name='komorebi-shortcuts.exe' DiskId='1' Source='$(var.CargoTargetBinDir)\komorebi-shortcuts.exe' KeyPath='yes' />
|
||||
</Component>
|
||||
<Component Id='binary6' Guid='*'>
|
||||
<File Id='exe6' Name='komorebi-recorder.exe' DiskId='1' Source='$(var.CargoTargetBinDir)\komorebi-recorder.exe' KeyPath='yes' />
|
||||
</Component>
|
||||
<Component Id='binary7' Guid='*'>
|
||||
<File Id='exe7' Name='komorebi-recorder-gui.exe' DiskId='1' Source='$(var.CargoTargetBinDir)\komorebi-recorder-gui.exe' KeyPath='yes' />
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
@@ -128,6 +134,10 @@
|
||||
|
||||
<ComponentRef Id='binary5' />
|
||||
|
||||
<ComponentRef Id='binary6' />
|
||||
|
||||
<ComponentRef Id='binary7' />
|
||||
|
||||
<Feature Id='Environment' Title='PATH Environment Variable' Description='Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.' Level='1' Absent='allow'>
|
||||
<ComponentRef Id='Path' />
|
||||
</Feature>
|
||||
|
||||
Reference in new issue
Block a user