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
This commit is contained in:
parent
6200daa5bb
commit
5412ce276c
@ -4,6 +4,8 @@ const GLib = imports.gi.GLib;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
|
|
||||||
const ExtensionState = {
|
const ExtensionState = {
|
||||||
ENABLED: 1,
|
ENABLED: 1,
|
||||||
DISABLED: 2,
|
DISABLED: 2,
|
||||||
@ -25,6 +27,36 @@ var disabledExtensions;
|
|||||||
// GFile for user extensions
|
// GFile for user extensions
|
||||||
var userExtensionsDir = null;
|
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 <major>.<minor>.<point>.<micro>
|
||||||
|
* <micro> is always ignored
|
||||||
|
* <point> is ignored if <minor> is even (so you can target the
|
||||||
|
* whole stable release)
|
||||||
|
* <minor> and <major> must match
|
||||||
|
* Each target version must be at least <major> and <minor>
|
||||||
|
*/
|
||||||
|
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) {
|
function loadExtension(dir, enabled, type) {
|
||||||
let info;
|
let info;
|
||||||
let baseErrorString = 'While loading extension from "' + dir.get_parse_name() + '": ';
|
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);
|
global.logError(baseErrorString + 'Failed to parse metadata.json: ' + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let requiredProperties = ['uuid', 'name', 'description'];
|
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
|
||||||
for (let i = 0; i < requiredProperties; i++) {
|
for (let i = 0; i < requiredProperties.length; i++) {
|
||||||
let prop = requiredProperties[i];
|
let prop = requiredProperties[i];
|
||||||
if (!meta[prop]) {
|
if (!meta[prop]) {
|
||||||
global.logError(baseErrorString + 'missing "' + prop + '" property in metadata.json');
|
global.logError(baseErrorString + 'missing "' + prop + '" property in metadata.json');
|
||||||
@ -68,6 +100,12 @@ function loadExtension(dir, enabled, type) {
|
|||||||
return;
|
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] = meta;
|
||||||
extensionMeta[meta.uuid].type = type;
|
extensionMeta[meta.uuid].type = type;
|
||||||
extensionMeta[meta.uuid].path = dir.get_path();
|
extensionMeta[meta.uuid].path = dir.get_path();
|
||||||
|
@ -672,7 +672,8 @@ use an extension title clicktofocus@janedoe.example.com.'''
|
|||||||
os.makedirs(extension_path)
|
os.makedirs(extension_path)
|
||||||
meta = { 'name': name,
|
meta = { 'name': name,
|
||||||
'description': description,
|
'description': description,
|
||||||
'uuid': uuid }
|
'uuid': uuid,
|
||||||
|
'shell-version': ['@VERSION@'] }
|
||||||
f = open(os.path.join(extension_path, 'metadata.json'), 'w')
|
f = open(os.path.join(extension_path, 'metadata.json'), 'w')
|
||||||
try:
|
try:
|
||||||
json.dump(meta, f)
|
json.dump(meta, f)
|
||||||
|
Loading…
Reference in New Issue
Block a user