Skip to content

Commit 1ee1989

Browse files
committed
fix(wip): added generation of file_version_info.txt to include metadata in Windows executables
1 parent 0040f9b commit 1ee1989

File tree

1 file changed

+96
-2
lines changed

1 file changed

+96
-2
lines changed

aw-qt.spec

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,102 @@ import platform
99
import os
1010
import sys
1111

12+
WIN = platform.system() == "Windows"
13+
14+
VS_VERSION_INFO = """
15+
VSVersionInfo(
16+
ffi=FixedFileInfo(
17+
# filevers and prodvers should be always a tuple with four
18+
# items: (1, 2, 3, 4)
19+
# Set not needed items to zero 0.
20+
filevers=%(ver_tup)r,
21+
prodvers=%(ver_tup)r,
22+
# Contains a bitmask that specifies the valid bits 'flags'r
23+
mask=0x0,
24+
# Contains a bitmask that specifies the Boolean attributes
25+
# of the file.
26+
flags=0x0,
27+
# The operating system for which this file was designed.
28+
# 0x4 - NT and there is no need to change it.
29+
OS=0x4,
30+
# The general type of file.
31+
# 0x1 - the file is an application.
32+
fileType=0x1,
33+
# The function of the file.
34+
# 0x0 - the function is not defined for this fileType
35+
subtype=0x0,
36+
# Creation date and time stamp.
37+
# NOTE: Nobody ever sets this: https://stackoverflow.com/q/67851414/965332
38+
date=(0, 0)
39+
),
40+
kids=[
41+
StringFileInfo(
42+
[
43+
StringTable(
44+
u'040904E4',
45+
[StringStruct(u'FileDescription', u'%(name)s'),
46+
StringStruct(u'FileVersion', u'%(ver_str)s'),
47+
StringStruct(u'InternalName', u'%(internal_name)s'),
48+
StringStruct(u'LegalCopyright', u'Copyright © %(year) ActivityWatch Contributors'),
49+
StringStruct(u'OriginalFilename', u'%(exe_name)s'),
50+
StringStruct(u'ProductName', u'%(name)s'),
51+
StringStruct(u'ProductVersion', u'%(ver_str)s')])
52+
]),
53+
VarFileInfo([VarStruct(u'Translation', [1033, 1252])])
54+
]
55+
)"""
56+
1257

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

67+
file_ext = '.exe' if WIN else ''
68+
69+
70+
# Read version information on Windows.
71+
# We need to construct a file_version_info.txt file for the Windows installer.
72+
# Eventually we might want this for all modules, if worth the effort (its a bit messy...).
73+
# Based on: https://github.com/Yubico/python-yubicommon/blob/master/yubicommon/setup/pyinstaller_spec.py
74+
VERSION = None
75+
if WIN:
76+
NAME = "ActivityWatch"
77+
INTERNAL_NAME = "aw-qt" # TODO: fetch from package info
78+
VERSION = 'build/file_version_info.txt'
79+
# FIXME: Don't hardcode
80+
ver_str = "0.12.0"
81+
82+
global int_or_zero # Needed due to how this script is invoked
83+
84+
def int_or_zero(v):
85+
try:
86+
return int(v)
87+
except ValueError:
88+
return 0
89+
90+
ver_tup = tuple(int_or_zero(v) for v in ver_str.split('.'))
91+
# Windows needs 4-tuple.
92+
if len(ver_tup) < 4:
93+
ver_tup += (0,) * (4-len(ver_tup))
94+
elif len(ver_tup) > 4:
95+
ver_tup = ver_tup[:4]
96+
97+
# Write version info.
98+
with open(VERSION, 'w') as f:
99+
f.write(VS_VERSION_INFO % {
100+
'name': NAME,
101+
'internal_name': INTERNAL_NAME,
102+
'ver_tup': ver_tup,
103+
'ver_str': ver_str,
104+
'exe_name': INTERNAL_NAME + file_ext
105+
})
106+
107+
22108

23109
icon = 'media/logo/logo.ico'
24110
block_cipher = None
@@ -46,11 +132,19 @@ exe = EXE(pyz,
46132
a.scripts,
47133
exclude_binaries=True,
48134
name='aw-qt',
135+
version=VERSION,
49136
debug=False,
50137
strip=False,
51138
upx=True,
52139
icon=icon,
53-
console=False if platform.system() == "Windows" else True)
140+
console=False if WIN else True)
141+
142+
# Sign the executable
143+
# This is how it's done for the python-yubicommon package (linked above), should take some inspiration.
144+
#if WIN:
145+
# os.system("signtool.exe sign /fd SHA256 /t http://timestamp.verisign.com/scripts/timstamp.dll \"%s\"" %
146+
# (exe.name))
147+
54148
coll = COLLECT(exe,
55149
a.binaries,
56150
a.zipfiles,

0 commit comments

Comments
 (0)