Skip to content

Commit

Permalink
Add post-installation trigger scripts
Browse files Browse the repository at this point in the history
Several things in the GNOME stack have file-based caches, like
gdk-pixbuf's loaders.cache.  These need to be regenerated, and
historically that worked in jhbuild because these modules include bits
in their Makefile to run then relevant commands, if DESTDIR is not
set.

Package managers have post-installation scripts in packages, and OS
builders typically support this as well.

Jhbuild historically relied on the post-installation scripts in
modules, but in (see bug 647231) we switched to using DESTDIR for all
module types.  So we need to move closer to the package model here.

We call them "triggers" as they're run after any kind of build
operation (including "uninstall").

This patch adds a proof-of-concept trigger script for gdk-pixbuf
loaders.

https://bugzilla.gnome.org/show_bug.cgi?id=653842
  • Loading branch information
cgwalters committed Jul 12, 2011
1 parent 66ad15a commit c350169
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS = po scripts jhbuild buildbot
SUBDIRS = po scripts triggers jhbuild buildbot

if DOC_INSTALLATION_ENABLED
SUBDIRS += doc
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ AC_CONFIG_FILES([
doc/Makefile
po/Makefile.in
scripts/Makefile
triggers/Makefile
jhbuild/Makefile
jhbuild/buildbot/Makefile
jhbuild/buildbot/status/web/Makefile
Expand Down
20 changes: 20 additions & 0 deletions jhbuild/frontends/buildscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import os
import logging

from jhbuild.utils import packagedb
from jhbuild.utils import trigger
from jhbuild.errors import FatalError, CommandError, SkipToPhase, SkipToEnd

class BuildScript:
Expand Down Expand Up @@ -84,6 +86,7 @@ def build(self, phases=None):
self.start_build()

failures = [] # list of modules that couldn't be built
successes = []
self.module_num = 0
for module in self.modulelist:
self.module_num = self.module_num + 1
Expand Down Expand Up @@ -197,11 +200,28 @@ def build(self, phases=None):
num_phase += 1

self.end_module(module.name, failed)
if not failed:
self.run_triggers(module.name)
self.end_build(failures)
if failures:
return 1
return 0

def run_triggers(self, module_name):
"""See triggers/README."""
all_triggers = trigger.load_all(os.path.join(PKGDATADIR, 'triggers'))
triggers_to_run = []
for trig in all_triggers:
# Skip if somehow the module isn't really installed
if self.packagedb.installdate(module_name) is None:
continue
pkg = self.packagedb.entries[module_name]
if trig.matches(pkg.manifest):
triggers_to_run.append(trig)
for trig in triggers_to_run:
logging.info(_('Running post-installation trigger script: %r') % (trig.name, ))
trig.run()

def get_build_phases(self, module, targets=None):
'''returns the list of required phases'''
if targets:
Expand Down
1 change: 1 addition & 0 deletions jhbuild/utils/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ app_PYTHON = \
notify.py \
packagedb.py \
sxml.py \
trigger.py \
trayicon.py \
unpack.py

89 changes: 89 additions & 0 deletions jhbuild/utils/trigger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# jhbuild - a build script for GNOME 1.x and 2.x
# Copyright (C) 2011 Red Hat, Inc.
#
# trigger.py - Run scripts after packages are installed
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import os
import sys
import subprocess
import re

from . import cmds

class Trigger(object):
SUFFIX = '.trigger'
def __init__(self, filepath):
assert filepath.endswith(self.SUFFIX)
self._rematches = []
self._literal_matches = []
self._executable = None
self._file = filepath
self.name = os.path.basename(filepath)[:-len(self.SUFFIX)]

f = open(self._file)
for line in f:
key = '# IfExecutable: '
if line.startswith(key):
text = line[len(key):].strip()
self._executable = text
continue
key = '# REMatch: '
if line.startswith(key):
text = line[len(key):].strip()
r = re.compile(text)
self._rematches.append(r)
continue
key = '# LiteralMatch: '
if line.startswith(key):
text = line[len(key):].strip()
self._literal_matches.append(text)
continue
f.close()
if len(self._rematches) == 0 and len(self._literal_matches) == 0:
raise ValueError("No keys specified in trigger script %r" % (filepath, ))

def matches(self, files_list):
"""@files_list should be a list of absolute file paths. Return True if this trigger script
should be run."""
if self._executable is not None:
if not cmds.has_command(self._executable):
return False
for path in files_list:
for r in self._rematches:
match = r.search(path)
if match:
return True
for literal in self._literal_matches:
if path.find(literal) >= 0:
return True
return False

def run(self):
"""Synchronously execute this trigger script."""
assert 'JHBUILD_PREFIX' in os.environ
subprocess.check_call(['/bin/sh', self._file], stdin=open('/dev/null'))

def load_all(dirpath):
result = []
for filename in os.listdir(dirpath):
if not filename.endswith(Trigger.SUFFIX):
continue
filepath = os.path.join(dirpath, filename)
p = Trigger(filepath)
result.append(p)
return result

2 changes: 2 additions & 0 deletions triggers/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
triggerdir = $(datadir)/jhbuild/triggers
trigger_DATA = gdk-pixbuf.trigger
23 changes: 23 additions & 0 deletions triggers/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
This directory contains GNOME post-installation trigger scripts (in
theory these could go with the modules, but there aren't many of them,
so eh).

A .trigger file is a set of regular expressions (or literal matches)
which are evaluated against files installed after any "make install
DESTDIR=", combined with a shell script to run if any of them match.
In the future, these may also be matched against deleted files.

The contents of a .trigger file are just /bin/sh shell script, with a
few magic comments. During the run of a .trigger file, the
environment variable JHBUILD_PREFIX is guaranteed to be set.

Currently recognized comments:

# IfExecutable: STRING
Only run if the given executable is available in $PATH
# LiteralMatch: STRING
Match against installed/removed manifest if the given STRING is a substring of a file or directory.
# REMatch: REGEXP
Match against installed/removed manifest using the given REGEXP in Python syntax.


24 changes: 24 additions & 0 deletions triggers/gdk-pixbuf.trigger
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Post-installation hook for gdk-pixbuf. -*- mode: sh -*-
# Corresponds to gdk-pixbuf/gdk-pixbuf/Makefile.am:install-data-hook
#
# Written by Colin Walters <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


# IfExecutable: gdk-pixbuf-query-loaders
# LiteralMatch: /gdk-pixbuf-2.0/2.10.0/loaders/

gdk-pixbuf-query-loaders --update-cache

0 comments on commit c350169

Please sign in to comment.