Skip to content

Commit

Permalink
Windows installer: Collect information on dependencies & licenses
Browse files Browse the repository at this point in the history
  • Loading branch information
martinling committed Jul 6, 2024
1 parent f2839aa commit a0b3933
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 41 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ jobs:
tool: cargo-wix
if: matrix.os == 'windows-latest'

- name: Install cargo-license (Windows)
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: cargo-license
if: matrix.os == 'windows-latest'

- name: Install dependencies (Windows)
uses: lukka/run-vcpkg@v11
with:
Expand Down Expand Up @@ -104,6 +110,12 @@ jobs:
with:
run: cargo test

- name: List dependencies (Windows)
run: |
python wix/rust_licenses.py > wix/LICENSE-static-libraries.txt
python wix/vcpkg_licenses.py > wix/LICENSE-dynamic-libraries.txt
if: matrix.os == 'windows-latest'

- name: Build installer (Windows)
run: cargo wix --no-build --nocapture -v
if: matrix.os == 'windows-latest'
Expand Down
52 changes: 11 additions & 41 deletions wix/main.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,15 @@
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
<Directory Id='APPLICATIONFOLDER' Name='Packetry'>

<!--
Enabling the license sidecar file in the installer is a four step process:
1. Uncomment the `Component` tag and its contents.
2. Change the value for the `Source` attribute in the `File` tag to a path
to the file that should be included as the license sidecar file. The path
can, and probably should be, relative to this file.
3. Change the value for the `Name` attribute in the `File` tag to the
desired name for the file when it is installed alongside the `bin` folder
in the installation directory. This can be omitted if the desired name is
the same as the file name.
4. Uncomment the `ComponentRef` tag with the Id attribute value of "License"
further down in this file.
-->
<!--
<Component Id='License' Guid='*'>
<File Id='LicenseFile' Name='ChangeMe' DiskId='1' Source='C:\Path\To\File' KeyPath='yes'/>
<Component Id='LICENSE_packetry' Guid='25f09134-ab56-4028-ad5c-461edf5a850a'>
<File Id='LICENSE_packetry' Name='LICENSE-packetry.txt' DiskId='1' Source='LICENSE'/>
</Component>
<Component Id='LICENSE_static_libraries' Guid='3ba11a89-de46-40c8-b2ca-68d4ea7257b1'>
<File Id='LICENSE_static_libraries' Name='LICENSE-static-libraries.txt' DiskId='1' Source='wix/LICENSE-static-libraries.txt'/>
</Component>
<Component Id='LICENSE_dynamic' Guid='40f0f16e-e70f-4f16-af2a-d3e19413375c'>
<File Id='LICENSE_dynamic' Name='LICENSE-dynamic-libraries.txt' DiskId='1' Source='wix/LICENSE-dynamic-libraries.txt'/>
</Component>
-->

<Directory Id='Bin' Name='bin'>
<Component Id='Path' Guid='11E1B3A0-F153-41F2-8080-7225FB20816F' KeyPath='yes'>
Expand Down Expand Up @@ -141,11 +131,9 @@
Display='expand'
Absent='disallow'>

<!--
Uncomment the following `ComponentRef` tag to add the license
sidecar file to the installer.
-->
<!--<ComponentRef Id='License'/>-->
<ComponentRef Id='LICENSE_packetry'/>
<ComponentRef Id='LICENSE_static_libraries'/>
<ComponentRef Id='LICENSE_dynamic_libraries'/>

<ComponentRef Id='binary0'/>

Expand Down Expand Up @@ -225,30 +213,12 @@
<UI>
<UIRef Id='WixUI_FeatureTree'/>

<!--
Enabling the EULA dialog in the installer is a three step process:
1. Comment out or remove the two `Publish` tags that follow the
`WixVariable` tag.
2. Uncomment the `<WixVariable Id='WixUILicenseRtf' Value='Path\to\Eula.rft'>` tag further down
3. Replace the `Value` attribute of the `WixVariable` tag with
the path to a RTF file that will be used as the EULA and
displayed in the license agreement dialog.
-->
<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>
<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>

</UI>


<!--
Enabling the EULA dialog in the installer requires uncommenting
the following `WixUILicenseRTF` tag and changing the `Value`
attribute.
-->
<!-- <WixVariable Id='WixUILicenseRtf' Value='Relative\Path\to\Eula.rtf'/> -->


<!--
Uncomment the next `WixVariable` tag to customize the installer's
Graphical User Interface (GUI) and add a custom banner image across
Expand Down
28 changes: 28 additions & 0 deletions wix/rust_licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import subprocess

cargo_result = subprocess.run(
['cargo', 'license', '--authors', '--do-not-bundle', '--color=never'],
capture_output=True)

cargo_result.check_returncode()

print("The following Rust packages are statically linked into Packetry:")

for line in cargo_result.stdout.decode().rstrip().split("\n"):
package, remainder = line.split(": ")
version, licenses, by, authors = remainder.split(", ")
licenses = licenses[1:-1] \
.replace(' OR ', ' or ') \
.replace(' WITH ', ' with ') \
.replace(' AND ', ' and ')
authors = authors[1:-1].split("|")
print()
print(f"{package} version {version}")
if len(authors) == 1:
print(f"Author: {str.join(', ', authors)}")
else:
print("Authors:")
for author in authors:
print(f" {author}")
print(f"License: {licenses}")
print(f"Link: https://crates.io/crates/{package}")
81 changes: 81 additions & 0 deletions wix/vcpkg_licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import subprocess
import json
import re

vcpkg_result = subprocess.run(
['./vcpkg/vcpkg', 'depend-info', 'gtk'],
capture_output=True)

vcpkg_result.check_returncode()

cargo_result = subprocess.run(
['cargo', 'license', '--authors', '--do-not-bundle', '--color=never'],
capture_output=True)

cargo_result.check_returncode()

packages = set()

# Find all packages we depend on.
for line in vcpkg_result.stderr.decode().rstrip().split('\n'):
header, remainder = line.split(': ')
package = header.split('[')[0]
packages.add(package)
dependencies = remainder.split(', ')
packages |= set(dependencies)

# Discard empty package names.
packages.discard('')

# Discard vcpkg build tools.
packages = set(p for p in packages if not p.startswith('vcpkg-'))

# gperf is needed to build fontconfig, but is not linked to.
packages.discard('gperf')

# gettext is needed to build many dependencies, but is not linked to.
packages.discard('gettext')

# getopt, pthread and pthreads are virtual packages.
packages.discard('getopt')
packages.discard('pthread')
packages.discard('pthreads')

# sassc is used to build GTK, but is not linked to.
packages.discard('sassc')

versions = {}

# These packages are missing license information in vcpkg.
licenses = {
'libiconv': ['LGPL-2.1-or-later'],
'egl-registry': ['Apache-2.0', 'MIT'],
'liblzma': ['BSD-0-Clause'],
'libsass': ['MIT'],
}

# These packages are missing homepage information in vcpkg.
homepages = {
'fribidi': 'https://github.com/fribidi/fribidi',
}

for package in packages:
metadata = json.load(open(f'vcpkg/ports/{package}/vcpkg.json'))
version = metadata.get('version-semver',
metadata.get('version',
metadata.get('version-date')))
if version is None:
raise KeyError(f"Couldn't find a version for package {package}")
versions[package] = version
if metadata.get('homepage') is not None:
homepages[package] = metadata['homepage']
if metadata.get('license') is not None:
licenses[package] = metadata['license'].split(' OR ')

print("The following libraries are dynamically linked into Packetry:")

for package in sorted(packages):
print()
print(f"{package} version {versions[package]}")
print(f"Homepage: {homepages[package]}")
print(f"License: {str.join(' or ', licenses[package])}")

0 comments on commit a0b3933

Please sign in to comment.