install: when using a staging root, setup XDG_DATA_DIRS magic

In order for xdg-utils programs to successfully install resources to the
staging root instead of /usr, this variable needs to be set and
additionally some arcane directories must be created that xdg-utils,
astoundingly, does not know how to just gracefully handle.

xdg-mime is simply hopeless as it does not have a --noupdate flag. When
using a staged install, copy it with shutil instead.
This commit is contained in:
Eli Schwartz 2019-05-09 16:14:22 -04:00
parent 61eef65bb6
commit 2a63948440
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
2 changed files with 22 additions and 2 deletions

View File

@ -214,6 +214,8 @@ class Install(Develop):
the environment variables: the environment variables:
XDG_DATA_DIRS=/usr/share equivalent XDG_DATA_DIRS=/usr/share equivalent
XDG_UTILS_INSTALL_MODE=system XDG_UTILS_INSTALL_MODE=system
For staged installs this will be automatically set to:
<staging_root>/share
''') ''')
short_description = 'Install calibre from source' short_description = 'Install calibre from source'

View File

@ -688,6 +688,12 @@ class PostInstall:
self.opts.staging_etc = '/etc' if self.opts.staging_root == '/usr' else \ self.opts.staging_etc = '/etc' if self.opts.staging_root == '/usr' else \
os.path.join(self.opts.staging_root, 'etc') os.path.join(self.opts.staging_root, 'etc')
prefix = getattr(self.opts, 'prefix', None)
if prefix and prefix != self.opts.staging_root:
self.opts.staged_install = True
os.environ['XDG_DATA_DIRS'] = os.path.join(self.opts.staging_root, 'share')
os.environ['XDG_UTILS_INSTALL_MODE'] = 'system'
from calibre.utils.serialize import msgpack_loads from calibre.utils.serialize import msgpack_loads
scripts = msgpack_loads(P('scripts.calibre_msgpack', data=True)) scripts = msgpack_loads(P('scripts.calibre_msgpack', data=True))
self.manifest = manifest or [] self.manifest = manifest or []
@ -799,6 +805,14 @@ class PostInstall:
env['LD_LIBRARY_PATH'] = os.pathsep.join(npaths) env['LD_LIBRARY_PATH'] = os.pathsep.join(npaths)
cc = partial(check_call, env=env) cc = partial(check_call, env=env)
if getattr(self.opts, 'staged_install', False):
for d in {'applications', 'desktop-directories', 'icons/hicolor', 'mime/packages'}:
try:
os.makedirs(os.path.join(self.opts.staging_root, 'share', d))
except OSError:
# python2 does not have exist_ok=True, failure will be reported by xdg-utils
pass
with TemporaryDirectory() as tdir, CurrentDir(tdir), PreserveMIMEDefaults(): with TemporaryDirectory() as tdir, CurrentDir(tdir), PreserveMIMEDefaults():
def install_single_icon(iconsrc, basename, size, context, is_last_icon=False): def install_single_icon(iconsrc, basename, size, context, is_last_icon=False):
@ -876,10 +890,14 @@ class PostInstall:
ak = x.partition('.')[0] ak = x.partition('.')[0]
if ak in APPDATA and os.access(appdata, os.W_OK): if ak in APPDATA and os.access(appdata, os.W_OK):
self.appdata_resources.append(write_appdata(ak, APPDATA[ak], appdata, translators)) self.appdata_resources.append(write_appdata(ak, APPDATA[ak], appdata, translators))
cc(['xdg-desktop-menu', 'forceupdate'])
MIME = P('calibre-mimetypes.xml') MIME = P('calibre-mimetypes.xml')
self.mime_resources.append(MIME) self.mime_resources.append(MIME)
cc(['xdg-mime', 'install', MIME]) if not getattr(self.opts, 'staged_install', False):
cc(['xdg-mime', 'install', MIME])
cc(['xdg-desktop-menu', 'forceupdate'])
else:
from shutil import copyfile
copyfile(MIME, os.path.join(env['XDG_DATA_DIRS'], 'mime', 'packages', os.path.basename(MIME)))
except Exception: except Exception:
if self.opts.fatal_errors: if self.opts.fatal_errors:
raise raise