extensionSystem: Split out loadExtensionMetadata()
There is no need for sharing the functionality, but moving the code into extensionUtils allows adding unit tests for it. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3379>
This commit is contained in:
parent
0188c453b9
commit
74dcf99ea5
@ -109,3 +109,64 @@ export function deserializeExtension(variant) {
|
|||||||
res.dir = Gio.File.new_for_path(res.path);
|
res.dir = Gio.File.new_for_path(res.path);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load extension metadata from directory
|
||||||
|
*
|
||||||
|
* @param {string} uuid of the extension
|
||||||
|
* @param {GioFile} dir to load metadata from
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
export function loadExtensionMetadata(uuid, dir) {
|
||||||
|
const dirName = dir.get_basename();
|
||||||
|
if (dirName !== uuid)
|
||||||
|
throw new Error(`Directory name "${dirName}" does not match UUID "${uuid}"`);
|
||||||
|
|
||||||
|
const metadataFile = dir.get_child('metadata.json');
|
||||||
|
if (!metadataFile.query_exists(null))
|
||||||
|
throw new Error('Missing metadata.json');
|
||||||
|
|
||||||
|
let metadataContents, success_;
|
||||||
|
try {
|
||||||
|
[success_, metadataContents] = metadataFile.load_contents(null);
|
||||||
|
metadataContents = new TextDecoder().decode(metadataContents);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to load metadata.json: ${e}`);
|
||||||
|
}
|
||||||
|
let meta;
|
||||||
|
try {
|
||||||
|
meta = JSON.parse(metadataContents);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to parse metadata.json: ${e}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const requiredProperties = [{
|
||||||
|
prop: 'uuid',
|
||||||
|
typeName: 'string',
|
||||||
|
}, {
|
||||||
|
prop: 'name',
|
||||||
|
typeName: 'string',
|
||||||
|
}, {
|
||||||
|
prop: 'description',
|
||||||
|
typeName: 'string',
|
||||||
|
}, {
|
||||||
|
prop: 'shell-version',
|
||||||
|
typeName: 'string array',
|
||||||
|
typeCheck: v => Array.isArray(v) && v.length > 0 && v.every(e => typeof e === 'string'),
|
||||||
|
}];
|
||||||
|
for (let i = 0; i < requiredProperties.length; i++) {
|
||||||
|
const {
|
||||||
|
prop, typeName, typeCheck = v => typeof v === typeName,
|
||||||
|
} = requiredProperties[i];
|
||||||
|
|
||||||
|
if (!meta[prop])
|
||||||
|
throw new Error(`missing "${prop}" property in metadata.json`);
|
||||||
|
if (!typeCheck(meta[prop]))
|
||||||
|
throw new Error(`property "${prop}" is not of type ${typeName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uuid !== meta.uuid)
|
||||||
|
throw new Error(`UUID "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,9 @@ import * as Signals from '../misc/signals.js';
|
|||||||
import * as Config from '../misc/config.js';
|
import * as Config from '../misc/config.js';
|
||||||
import * as ExtensionDownloader from './extensionDownloader.js';
|
import * as ExtensionDownloader from './extensionDownloader.js';
|
||||||
import {formatError} from '../misc/errorUtils.js';
|
import {formatError} from '../misc/errorUtils.js';
|
||||||
import {ExtensionState, ExtensionType} from '../misc/extensionUtils.js';
|
import {
|
||||||
|
ExtensionState, ExtensionType, loadExtensionMetadata
|
||||||
|
} from '../misc/extensionUtils.js';
|
||||||
import * as FileUtils from '../misc/fileUtils.js';
|
import * as FileUtils from '../misc/fileUtils.js';
|
||||||
import * as Main from './main.js';
|
import * as Main from './main.js';
|
||||||
import * as MessageTray from './messageTray.js';
|
import * as MessageTray from './messageTray.js';
|
||||||
@ -377,55 +379,10 @@ export class ExtensionManager extends Signals.EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createExtensionObject(uuid, dir, type) {
|
createExtensionObject(uuid, dir, type) {
|
||||||
let metadataFile = dir.get_child('metadata.json');
|
const metadata = loadExtensionMetadata(uuid, dir);
|
||||||
if (!metadataFile.query_exists(null))
|
const extension = {
|
||||||
throw new Error('Missing metadata.json');
|
metadata,
|
||||||
|
uuid,
|
||||||
let metadataContents, success_;
|
|
||||||
try {
|
|
||||||
[success_, metadataContents] = metadataFile.load_contents(null);
|
|
||||||
metadataContents = new TextDecoder().decode(metadataContents);
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(`Failed to load metadata.json: ${e}`);
|
|
||||||
}
|
|
||||||
let meta;
|
|
||||||
try {
|
|
||||||
meta = JSON.parse(metadataContents);
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(`Failed to parse metadata.json: ${e}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const requiredProperties = [{
|
|
||||||
prop: 'uuid',
|
|
||||||
typeName: 'string',
|
|
||||||
}, {
|
|
||||||
prop: 'name',
|
|
||||||
typeName: 'string',
|
|
||||||
}, {
|
|
||||||
prop: 'description',
|
|
||||||
typeName: 'string',
|
|
||||||
}, {
|
|
||||||
prop: 'shell-version',
|
|
||||||
typeName: 'string array',
|
|
||||||
typeCheck: v => Array.isArray(v) && v.length > 0 && v.every(e => typeof e === 'string'),
|
|
||||||
}];
|
|
||||||
for (let i = 0; i < requiredProperties.length; i++) {
|
|
||||||
const {
|
|
||||||
prop, typeName, typeCheck = v => typeof v === typeName,
|
|
||||||
} = requiredProperties[i];
|
|
||||||
|
|
||||||
if (!meta[prop])
|
|
||||||
throw new Error(`missing "${prop}" property in metadata.json`);
|
|
||||||
if (!typeCheck(meta[prop]))
|
|
||||||
throw new Error(`property "${prop}" is not of type ${typeName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uuid !== meta.uuid)
|
|
||||||
throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
|
|
||||||
|
|
||||||
let extension = {
|
|
||||||
metadata: meta,
|
|
||||||
uuid: meta.uuid,
|
|
||||||
type,
|
type,
|
||||||
dir,
|
dir,
|
||||||
path: dir.get_path(),
|
path: dir.get_path(),
|
||||||
@ -434,7 +391,7 @@ export class ExtensionManager extends Signals.EventEmitter {
|
|||||||
enabled: this._enabledExtensions.includes(uuid),
|
enabled: this._enabledExtensions.includes(uuid),
|
||||||
hasUpdate: false,
|
hasUpdate: false,
|
||||||
canChange: false,
|
canChange: false,
|
||||||
sessionModes: meta['session-modes'] ? meta['session-modes'] : ['user'],
|
sessionModes: metadata['session-modes'] ?? ['user'],
|
||||||
};
|
};
|
||||||
this._extensions.set(uuid, extension);
|
this._extensions.set(uuid, extension);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user