Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(wip): added generation of file_version_info.txt to include metadata in Windows executables #88

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 98 additions & 2 deletions aw-qt.spec
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,105 @@
import platform
import os
import sys
from datetime import datetime

WIN = platform.system() == "Windows"

VS_VERSION_INFO = """
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four
# items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=%(ver_tup)r,
prodvers=%(ver_tup)r,
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x0,
# Contains a bitmask that specifies the Boolean attributes
# of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
# NOTE: Nobody ever sets this: https://stackoverflow.com/q/67851414/965332
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904E4',
[StringStruct(u'FileDescription', u'%(name)s'),
StringStruct(u'FileVersion', u'%(ver_str)s'),
StringStruct(u'InternalName', u'%(internal_name)s'),
StringStruct(u'LegalCopyright', u'Copyright © %(year) ActivityWatch Contributors'),
StringStruct(u'OriginalFilename', u'%(exe_name)s'),
StringStruct(u'ProductName', u'%(name)s'),
StringStruct(u'ProductVersion', u'%(ver_str)s')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1252])])
]
)"""


extra_pathex = []
if platform.system() == "Windows":
if WIN:
# The Windows version includes paths to Qt binaries which are
# not automatically found due to bug in PyInstaller 3.2.
# See: https://github.com/pyinstaller/pyinstaller/issues/2152
import PyQt5
pyqt_path = os.path.dirname(PyQt5.__file__)
extra_pathex.append(pyqt_path + "\\Qt\\bin")

file_ext = '.exe' if WIN else ''


# Read version information on Windows.
# We need to construct a file_version_info.txt file for the Windows installer.
# Eventually we might want this for all modules, if worth the effort (its a bit messy...).
# Based on: https://github.com/Yubico/python-yubicommon/blob/master/yubicommon/setup/pyinstaller_spec.py
VERSION = None
if WIN:
NAME = "ActivityWatch"
INTERNAL_NAME = "aw-qt" # TODO: fetch from package info
VERSION = 'build/file_version_info.txt'
# FIXME: Don't hardcode
ver_str = "0.12.0"

global int_or_zero # Needed due to how this script is invoked

def int_or_zero(v):
try:
return int(v)
except ValueError:
return 0

ver_tup = tuple(int_or_zero(v) for v in ver_str.split('.'))
# Windows needs 4-tuple.
if len(ver_tup) < 4:
ver_tup += (0,) * (4-len(ver_tup))
elif len(ver_tup) > 4:
ver_tup = ver_tup[:4]

# Write version info.
with open(VERSION, 'w') as f:
f.write(VS_VERSION_INFO % {
'name': NAME,
'internal_name': INTERNAL_NAME,
'ver_tup': ver_tup,
'ver_str': ver_str,
'exe_name': INTERNAL_NAME + file_ext,
'year': datetime.now().year,
})



icon = 'media/logo/logo.ico'
block_cipher = None
Expand Down Expand Up @@ -46,11 +134,19 @@ exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='aw-qt',
version=VERSION,
debug=False,
strip=False,
upx=True,
icon=icon,
console=False if platform.system() == "Windows" else True)
console=False if WIN else True)

# Sign the executable
# This is how it's done for the python-yubicommon package (linked above), should take some inspiration.
#if WIN:
# os.system("signtool.exe sign /fd SHA256 /t http://timestamp.verisign.com/scripts/timstamp.dll \"%s\"" %
# (exe.name))

coll = COLLECT(exe,
a.binaries,
a.zipfiles,
Expand Down