From 9fa0360ca4668c5f17ad8b770c8d83a29ac09c3b Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Wed, 6 Jan 2010 17:21:10 +0100 Subject: - drop support for deprecated MOZ_EXT_NAME and MOZ_XPI_MOZILLA_DIRS variable - update src/xpi.mk * install-xpi: - Split xpi installation from xpi.mk into new install-xpi script. - add src/install-xpi - update src/Makefile - update src/xpi.mk - update debian/control --- src/Makefile | 1 + src/dh_xul-ext | 12 ++-- src/install-xpi | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xpi.mk | 114 ++++++-------------------------- 4 files changed, 225 insertions(+), 101 deletions(-) create mode 100755 src/install-xpi (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 94449e4..2fa0295 100644 --- a/src/Makefile +++ b/src/Makefile @@ -53,6 +53,7 @@ extra_files = \ bindir_files = \ dh_xul-ext \ + install-xpi \ xpi-pack \ xpi-unpack \ moz-version diff --git a/src/dh_xul-ext b/src/dh_xul-ext index 39c10d8..0702447 100755 --- a/src/dh_xul-ext +++ b/src/dh_xul-ext @@ -110,16 +110,16 @@ def get_source_package_name(): def get_provided_package_names(package, supported_apps): + ext_name = package + for prefix in ("firefox-", "iceweasel-", "mozilla-", "xul-ext-"): + if ext_name.startswith(prefix): + ext_name = ext_name[len(prefix):] + # check if MOZ_XPI_EXT_NAME is defined in debian/rules lines = open("debian/rules").readlines() - lines = filter(lambda x: x.find("MOZ_XPI_EXT_NAME") != -1 or x.find("MOZ_EXT_NAME") != -1, lines) + lines = filter(lambda x: x.find("MOZ_XPI_EXT_NAME") != -1, lines) if len(lines) > 0: ext_name = lines[-1][line.find("=")+1:].strip() - else: - ext_name = package - for prefix in ("firefox-", "iceweasel-", "mozilla-", "xul-ext-"): - if ext_name.startswith(prefix): - ext_name = ext_name[len(prefix):] provides = set() provides.add("xul-ext-" + ext_name) diff --git a/src/install-xpi b/src/install-xpi new file mode 100755 index 0000000..314fdd4 --- /dev/null +++ b/src/install-xpi @@ -0,0 +1,199 @@ +#!/usr/bin/python + +# Copyright (c) 2009 Benjamin Drung +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import getopt +import os +import stat +import subprocess +import sys +import zipfile + +from rdflib import Namespace +from rdflib.Graph import Graph + +# error codes +COMMAND_LINE_SYNTAX_ERROR = 1 +XPI_FILE_DOES_NOT_EXISTS = 2 + +def get_target_applications(script_name, install_rdf, verbose=False): + target_applications = [] + rdf_graph = Graph() + rdf_graph.parse(install_rdf) + query = "SELECT ?id WHERE { ?x1 em:targetApplication ?x2 . ?x2 em:id ?id }" + results = rdf_graph.query(query, initNs=dict(em=Namespace("http://www.mozilla.org/2004/em-rdf#"))) + for target in results: + target_applications.append(str(target[0])) + return target_applications + +def get_extension_id(install_rdf): + extension_ids = set() + rdf_graph = Graph() + rdf_graph.parse(install_rdf) + query = "SELECT ?id WHERE {?x1 em:targetApplication ?x2 . ?x1 em:id ?id }" + results = rdf_graph.query(query, initNs=dict(em=Namespace("http://www.mozilla.org/2004/em-rdf#"))) + for result in results: + extension_ids.add(str(result[0])) + return extension_ids.pop() + +def get_arch(package): + lines = open("debian/control").readlines() + package_lines = filter(lambda x: x.find("Package:") >= 0, lines) + packages = map(lambda x: x[x.find(":")+1:].strip(), package_lines) + architecture_lines = filter(lambda x: x.find("Architecture:") >= 0, lines) + architectures = map(lambda x: x[x.find(":")+1:].strip(), architecture_lines) + (p, arch) = filter(lambda (x, y): x == package, zip(packages, architectures))[0] + return arch + +def get_mode(filename): + st = os.stat(filename) + mode = st[stat.ST_MODE] + return mode & 0777 + +def install_xpi(script_name, package, xpi_file, exclude, links, correct_permissions, remove_licenses, verbose=False): + # get xpi file content list + if not os.path.isfile(xpi_file): + print >> sys.stderr, "%s: Error: xpi file %s does not exist." % (script_name, xpi_file) + sys.exit(XPI_FILE_DOES_NOT_EXISTS) + zfobj = zipfile.ZipFile(xpi_file) + xpi_content = zfobj.namelist() + + # determine installation directory + if get_arch(package) == "all": + lib_share_dir = "share" + else: + lib_share_dir = "lib" + install_dir = os.path.join("debian", package, "usr", lib_share_dir, package) + if verbose: + print "%s: install directory: %s" % (script_name, install_dir) + + # remove documented license files + if remove_licenses: + pattern_list = ("copying", "gpl.txt", "licence", "license", "licence.txt", "license.txt") + for name in filter(lambda x: not x.endswith('/'), xpi_content): + basename = os.path.basename(name).lower() + if basename in pattern_list: + exclude.append(name) + print "%s: exclude license file %s" % (script_name, name) + + # create directory and extract xpi file + if not os.path.isdir(install_dir): + os.makedirs(install_dir) + command = ["unzip", "-o", "-d", install_dir, xpi_file] + if len(exclude) > 0: + command.append("-x") + command.extend(exclude) + print " ".join(command) + subprocess.call(command) + + # correct permissons of files to 644 and directories to 755 + if correct_permissions: + for name in xpi_content: + filename = os.path.join(install_dir, name) + if os.path.exists(filename): + mode = get_mode(filename) + if os.path.isdir(filename) and mode != 0755: + print "%s: correct permission from %s to %s of %s" % (script_name, oct(mode), oct(0755), name) + os.chmod(filename, 0755) + elif os.path.isfile(filename): + header = open(filename, "r").read(2) + if header != "#!" and mode != 0644: + # file without shebang + print "%s: correct permission from %s to %s of %s" % (script_name, oct(mode), oct(0644), name) + os.chmod(filename, 0644) + elif header == "#!" and mode != 0755: + # file with shebang + print "%s: correct permission from %s to %s of %s" % (script_name, oct(mode), oct(0755), name) + os.chmod(filename, 0755) + + # get symlinks list + extension_id = get_extension_id(os.path.join(install_dir, "install.rdf")) + target_applications = get_target_applications(script_name, os.path.join(install_dir, "install.rdf")) + for target_application in target_applications: + destination = os.path.join("/usr/lib/mozilla/extensions/", target_application, extension_id) + links.add(destination) + + # create symlinks + source = os.path.join("/usr", lib_share_dir, package) + for link in links: + command = ["dh_link", "-p" + package, source, link] + print " ".join(command) + subprocess.call(command) + +def get_first_package(): + lines = open("debian/control").readlines() + package_lines = filter(lambda x: x.find("Package:") >= 0, lines) + packages = map(lambda x: x[x.find(":")+1:].strip(), package_lines) + return packages[0] + +if __name__ == "__main__": + try: + long_opts = ["exclude", "help", "link", "package", + "preserve-permissions", "remove-license-files", "verbose"] + opts, args = getopt.gnu_getopt(sys.argv[1:], "hl:p:rvx:", long_opts) + except getopt.GetoptError, e: + # print help information and exit: + print >> sys.stderr, str(e) # will print something like "option -a not recognized" + usage(sys.stderr) + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + + correct_permissions = True + links = set() + package = None + remove_licenses = False + verbose = False + exclude = list() + + for o, a in opts: + if o in ("-x", "--exclude"): + exclude.append(a) + elif o in ("-h", "--help"): + usage(sys.stdout) + sys.exit() + elif o in ("-l", "--link"): + links.add(a) + elif o in ("-p", "--package"): + package = a + elif o in ("preserve-permissions"): + correct_permissions = False + elif o in ("-r", "--remove-license-files"): + remove_licenses = True + elif o in ("-v", "--verbose"): + verbose = True + else: + assert False, "unhandled option" + + if package is None: + package = get_first_package() + + script_name = os.path.basename(sys.argv[0]) + + if len(args) == 0: + print >> sys.stderr, "%s: Error: No xpi file specified." % (script_name) + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + elif len(args) > 1: + print >> sys.stderr, script_name + ": Error: Multiple xpi files specified: " + ", ".join(args) + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + + if verbose: + print script_name + ": Install %s into package %s." % (args[0], package) + + install_xpi(script_name, package, args[0], exclude, links, correct_permissions, remove_licenses, verbose) diff --git a/src/xpi.mk b/src/xpi.mk index dbf01a3..a5eebe9 100644 --- a/src/xpi.mk +++ b/src/xpi.mk @@ -33,12 +33,6 @@ # if defined the given .xpi file is used; otherwise we try to # guess one using wildcard (*.xpi) # -# MOZ_XPI_EMID (OPTIONAL): -# if defined the given id is used to determine the link name -# in the Firefox extensions directory. if not defined we try -# our best to extract the em:id from the install.rdf file shipped -# by any xpi -# # MOZ_XPI_BUILD_COMMAND (OPTIONAL): # if defined the given command will be run _before_ the extension # gets packaged up the standard .xpi way. Thus, the build command @@ -48,7 +42,6 @@ # build from source, you have to set this variable to nothing. # # MOZ_XPI_MOZILLA_EXTRA_DIRS (OPTIONAL): -# TODO: implement this! # defines extra directories to link the extension in. Usually # xpi.mk creates the right links based on targetApplication # parsed in install.rdf; if you need more directories, use this. @@ -72,59 +65,36 @@ # permission of the files will be set to 644 and the permissions # of scripts (files containing a shebang) will be set to 755. # -# Deprecated variables: -# -# MOZ_XPI_MOZILLA_DIRS /deprecated/ (OPTIONAL/NODEFAULT - see "Note:"): -# defines in which directories to create links for this -# extension. The default is "firefox-addons", which means that -# the extension will be linked appropriately to the -# /usr/lib/firefox-addons/extensions directory. -# '''Note''': this variable is deprecated and will go away; the -# default is already empty; if you still need this variable, -# migrate your code to MOZ_XPI_MOZILLA_EXTRA_DIRS -# -# MOZ_EXT_NAME /deprecated/ (OPTIONAL): -# this variable is deprecated and will go away; it was renamed -# to MOZ_XPI_EXT_NAME +# Unused variables (can be removed): # +# MOZ_XPI_EMID (OPTIONAL): +# if defined the given id is used to determine the link name +# in the Firefox extensions directory. if not defined we try +# our best to extract the em:id from the install.rdf file shipped +# by any xpi +# '''Note''': this variable is not used any more MOZ_EXTENSION_PKG ?= $(strip $(shell grep ^Package: debian/control | head -n 1 | sed "s/^Package://")) -MOZ_XPI_ARCH := $(strip $(shell egrep '^Package:|^Architecture:' debian/control | grep -A1 '^Package:[ \t]*$(MOZ_EXTENSION_PKG)[ \t]*$$' | grep ^Architecture: | sed -e 's/Architecture://')) - MOZ_XPI_BUILD_COMMAND ?= xpi-pack $(CURDIR) $(MOZ_EXTENSION_PKG).xpi ifneq (,$(MOZ_XPI_FILE)) -XPI_FILE = $(wildcard $(MOZ_XPI_FILE)) -else -XPI_FILE = $(wildcard *.xpi) -endif - -XPI_BASE_FILE = $(notdir $(XPI_FILE)) - -ifneq (,$(MOZ_XPI_EMID)) -XPI_EMID = $(MOZ_XPI_EMID) +xpi_file = $(wildcard $(MOZ_XPI_FILE)) else -XPI_EMID = $(shell xpath -q -e '/node()/Description/em:id/text() | /node()/Description/@em:id | //RDF:Description[@RDF:about="urn:mozilla:install-manifest"]/em:id/text() | //RDF:Description[@RDF:about="urn:mozilla:install-manifest"]/@em:id' $(install_dir)/install.rdf 2>/dev/null | sed -e 's/.*"\(.*\)"/\1/') +xpi_file = $(wildcard *.xpi) endif -ifeq (,$(MOZ_XPI_DISABLE_AUTOLINKS)) -RDF_RESOURCES = $(shell xpath -q -e '//em:targetApplication/@RDF:resource' $(install_dir)/install.rdf 2>/dev/null | sed -e 's/.*="\(.*\)"/\1/') - -XPI_TARGET_EMIDs = \ - $(shell xpath -q -e '//em:targetApplication//em:id/text() | //em:targetApplication//@em:id' $(install_dir)/install.rdf 2>/dev/null | sed -e 's/.*"\(.*\)"/\1/') \ - $(foreach resource,$(RDF_RESOURCES),$(shell xpath -q -e '//RDF:Description[@RDF:about="$(resource)"]/@em:id' $(install_dir)/install.rdf 2>/dev/null | sed -e 's/.*"\(.*\)"/\1/')) +ifneq (,$(MOZ_XPI_PRESERVE_PERMISSIONS)) +install_xpi_extra_parameter += --preserve-permissions endif -# local vars -# + lib_share_dir - for arch all this is "share"; otherwise "lib" -ifeq (all, $(MOZ_XPI_ARCH)) -lib_share_dir := share +ifeq ($(origin MOZ_XPI_DOCUMENTED_LICENSE_FILES),undefined) +install_xpi_extra_parameter += --remove-license-files else -lib_share_dir := lib +install_xpi_extra_parameter += $(foreach exclude,$(MOZ_XPI_DOCUMENTED_LICENSE_FILES),-x $(exclude)) endif -install_dir := debian/$(MOZ_EXTENSION_PKG)/usr/$(lib_share_dir)/$(MOZ_EXTENSION_PKG) +install_xpi_extra_parameter += $(foreach dir,$(MOZ_XPI_MOZILLA_EXTRA_DIRS),-l $dir) # ### cdbs hooks # build xpi using MOZ_XPI_BUILD_COMMAND if defined @@ -135,44 +105,8 @@ endif install/$(MOZ_EXTENSION_PKG):: xpi-install -# ### general helper targets -install-%-stamp: $(XPI_FILE) - @if test ! -f "$^" -a -f "$<"; then \ - echo "xpi.mk: Failed to extract the xpi file, there are multiple: $^"; \ - echo "xpi.mk: Either create only one xpi file or specify MOZ_XPI_FILE!"; \ - exit 1; \ - fi - mkdir -p $(install_dir) -ifneq (,$(MOZ_XPI_DOCUMENTED_LICENSE_FILES)) - unzip -o -d $(install_dir) $^ -x $(MOZ_XPI_DOCUMENTED_LICENSE_FILES) -else - unzip -o -d $(install_dir) $^ -ifeq ($(origin MOZ_XPI_DOCUMENTED_LICENSE_FILES),undefined) - cd $(install_dir) && find \( -iname copying -o -iname gpl.txt -o -iname licen[cs]e -o -iname licen[cs]e.txt \) -printf "xpi.mk: deleted %p\n" -delete -endif -endif -ifeq (,$(MOZ_XPI_PRESERVE_PERMISSIONS)) - find $(install_dir) -type d -exec chmod 755 {} \; - cd $(install_dir) && find * -type f | while read fn; do head -n1 "$$fn" | grep -q "^\#\!" && echo "xpi.mk: Made $$fn executable." && chmod 755 "$$fn" || chmod 644 "$$fn"; done -endif - touch $@ - -installlinks-%-stamp: $(patsubst %,install-%-stamp,$(XPI_BASE_FILE)) - dh_link -p$(MOZ_EXTENSION_PKG) /usr/$(lib_share_dir)/$(MOZ_EXTENSION_PKG) /usr/lib/$*/extensions/$(XPI_EMID) - touch $@ - -autolinks-stamp: $(patsubst %,install-%-stamp,$(XPI_BASE_FILE)) $(foreach mozilla,$(MOZ_XPI_MOZILLA_DIRS),installlinks-$(mozilla)-stamp) - $(if $(XPI_FILE),,@echo "xpi.mk: No xpi file found. Did you create one?"; \ - echo "xpi.mk: Please check MOZ_XPI_BUILD_COMMAND and maybe MOZ_XPI_FILE!"; \ - exit 2) - $(if $(XPI_EMID),,@echo "xpi.mk: Detecting the extension manager ID failed."; \ - echo "xpi.mk: This is either a bug in the install.rdf file or in mozilla-devscripts."; \ - echo "xpi.mk: Patch the install.rdf file or use MOZ_XPI_EMID as workaround."; \ - exit 3) - $(foreach id,$(XPI_TARGET_EMIDs),dh_link -p$(MOZ_EXTENSION_PKG) /usr/$(lib_share_dir)/$(MOZ_EXTENSION_PKG) /usr/lib/mozilla/extensions/$(id)/$(XPI_EMID);) - touch $@ - -xpi-install: $(patsubst %,install-%-stamp,$(XPI_BASE_FILE)) autolinks-stamp +xpi-install: + install-xpi -p$(MOZ_EXTENSION_PKG) $(xpi_file) $(install_xpi_extra_parameter) dh_xul-ext -p$(MOZ_EXTENSION_PKG) ifneq ($(shell grep '$${xpi:Depends}' debian/control),) @echo 'xpi.mk: $${xpi:Depends} is deprecated, please use $${xpi:Recommends} instead.' @@ -181,21 +115,11 @@ ifneq ($(shell grep '$${xpi:Depends}' debian/control),) endif # clean build and remove all .xpi in top-level if a MOZ_XPI_BUILD_COMMAND is defined +ifneq (,$(MOZ_XPI_BUILD_COMMAND)) clean:: dh_testdir dh_clean -ifeq ($(shell expr $(shell cat debian/compat) '<' 7),1) - rm -f *-stamp -endif -ifneq (,$(MOZ_XPI_BUILD_COMMAND)) rm -f *.xpi endif -# debug target -print-vars: - @echo "install_dir: $(install_dir)" - @echo "XPI_EMID: $(XPI_EMID)" - @echo "RDF_RESOURCES: $(RDF_RESOURCES)" - @echo "XPI_TARGET_EMIDs: $(XPI_TARGET_EMIDs)" - -.PHONY: clean xpi-install print-vars +.PHONY: clean xpi-install -- cgit v1.2.3