From 5412ce276cf9fa0d137b74a31e4263c70020faea Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 11 Jan 2011 22:42:34 +0100 Subject: [PATCH] ExtensionSystem: introduce versioning Require that all extensions have a "shell-version" property in their metadata, which is an array of supported Shell versions. Extensions can target a specific version triple or an entire stable version. Optionally, they can also require a specific GJS version, to ensure compatibility. https://bugzilla.gnome.org/show_bug.cgi?id=639255 --- js/ui/extensionSystem.js | 42 ++++++++++++++++++++++++++++++++++++++-- src/gnome-shell.in | 3 ++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index 5315d90c3..8a514a53f 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -4,6 +4,8 @@ const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; const St = imports.gi.St; +const Config = imports.misc.config; + const ExtensionState = { ENABLED: 1, DISABLED: 2, @@ -25,6 +27,36 @@ var disabledExtensions; // GFile for user extensions var userExtensionsDir = null; +/** + * versionCheck: + * @required: an array of versions we're compatible with + * @current: the version we have + * + * Check if a component is compatible for an extension. + * @required is an array, and at least one version must match. + * @current must be in the format ... + * is always ignored + * is ignored if is even (so you can target the + * whole stable release) + * and must match + * Each target version must be at least and + */ +function versionCheck(required, current) { + let currentArray = current.split('.'); + let major = currentArray[0]; + let minor = currentArray[1]; + let point = currentArray[2]; + for (let i = 0; i < required.length; i++) { + let requiredArray = required[i].split('.'); + if (requiredArray[0] == major && + requiredArray[1] == minor && + (requiredArray[2] == point || + (requiredArray[2] == undefined && parseInt(minor) % 2 == 0))) + return true; + } + return false; +} + function loadExtension(dir, enabled, type) { let info; let baseErrorString = 'While loading extension from "' + dir.get_parse_name() + '": '; @@ -43,8 +75,8 @@ function loadExtension(dir, enabled, type) { global.logError(baseErrorString + 'Failed to parse metadata.json: ' + e); return; } - let requiredProperties = ['uuid', 'name', 'description']; - for (let i = 0; i < requiredProperties; i++) { + let requiredProperties = ['uuid', 'name', 'description', 'shell-version']; + for (let i = 0; i < requiredProperties.length; i++) { let prop = requiredProperties[i]; if (!meta[prop]) { global.logError(baseErrorString + 'missing "' + prop + '" property in metadata.json'); @@ -68,6 +100,12 @@ function loadExtension(dir, enabled, type) { return; } + if (!versionCheck(meta['shell-version'], Config.PACKAGE_VERSION) || + (meta['js-version'] && !versionCheck(meta['js-version'], Config.GJS_VERSION))) { + global.logError(baseErrorString + 'extension is not compatible with current GNOME Shell and/or GJS version'); + return; + } + extensionMeta[meta.uuid] = meta; extensionMeta[meta.uuid].type = type; extensionMeta[meta.uuid].path = dir.get_path(); diff --git a/src/gnome-shell.in b/src/gnome-shell.in index e422adb8d..8500d98cb 100755 --- a/src/gnome-shell.in +++ b/src/gnome-shell.in @@ -672,7 +672,8 @@ use an extension title clicktofocus@janedoe.example.com.''' os.makedirs(extension_path) meta = { 'name': name, 'description': description, - 'uuid': uuid } + 'uuid': uuid, + 'shell-version': ['@VERSION@'] } f = open(os.path.join(extension_path, 'metadata.json'), 'w') try: json.dump(meta, f)