VulpesOS/gaia/build/xpcshell-commonjs.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

190 lines
5.7 KiB
JavaScript
Executable file

'use strict';
/* global Components, FileUtils, Services, XPCOMUtils:false, dump, quit */
/* exported run, require */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
const loaderURI = 'resource://gre/modules/commonjs/toolkit/loader.js';
const env = Cc['@mozilla.org/process/environment;1'].
getService(Ci.nsIEnvironment);
let { Loader } = Cu.import(loaderURI, {});
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/FileUtils.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
const CONTRACT_ID = '@mozilla.org/xre/app-info;1';
let originalAppInfo = Cc[CONTRACT_ID].getService(Ci.nsIXULRuntime);
try {
originalAppInfo.QueryInterface(Ci.nsIXULAppInfo);
} catch(e) {
// Create a fake XULAppInfo to satisfy the eventual needs of the SDK.
// (xpcshell doesn't implement nsIXULAppInfo interface)
let XULAppInfo = {
// nsIXUlAppInfo
vendor: 'Mozilla',
name: 'XPCShell',
ID: 'xpcshell@tests.mozilla.org',
version: '1',
appBuildID: '2007010101',
platformVersion: '1.0',
platformBuildID: '2007010101',
// nsIXUlRuntime (partial)
inSafeMode: originalAppInfo.inSafeMode,
logConsoleErrors: originalAppInfo.logConsoleErrors,
OS: originalAppInfo.OS,
XPCOMABI: originalAppInfo.XPCOMABI,
invalidateCachesOnRestart:
originalAppInfo.invalidateCachesOnRestart.bind(originalAppInfo),
QueryInterface: function (aIID) {
let interfaces = [Ci.nsIXULAppInfo, Ci.nsIXULRuntime];
if (!interfaces.some(aIID.equals.bind(aIID))) {
throw Cr.NS_ERROR_NO_INTERFACE;
}
return this;
}
};
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
let CID = Components.ID('7685dac8-3637-4660-a544-928c5ec0e714}');
registrar.registerFactory(CID, 'XULAppInfo', CONTRACT_ID, {
createInstance: function (aOuter, aIID) {
if (aOuter != null) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return XULAppInfo.QueryInterface(aIID);
},
QueryInterface: XPCOMUtils.generateQI(Ci.nsIFactory)
});
}
// This is a valid use of this
let xpcshellScope = this; // jshint ignore:line
let options;
try {
options = JSON.parse(env.get('BUILD_CONFIG'));
} catch (e) {
// parsing BUILD_CONFIG error or this env variable is not available.
// we simply skip this exception here and detect BUILD_CONFIG
// if it is undefined for |options.GAIA_APPDIRS.split(' ')| in
// CommonjsRunner constructor.
}
var CommonjsRunner = function(module, appOptions) {
appOptions = appOptions || '{}';
try {
appOptions = JSON.parse(appOptions);
} catch (err) {
dump('Unable to parse options ' + err.message);
throw err;
}
const GAIA_DIR = env.get('GAIA_DIR');
const APP_DIR = appOptions.APP_DIR || env.get('APP_DIR');
let gaiaDirFile = new FileUtils.File(GAIA_DIR);
let appBuildDirFile, appDirFile;
if (APP_DIR) {
appDirFile = new FileUtils.File(APP_DIR);
appBuildDirFile = appDirFile.clone();
appBuildDirFile.append('build');
}
let buildDirFile = gaiaDirFile.clone();
buildDirFile.append('build');
let paths = {
'toolkit/': 'resource://gre/modules/commonjs/toolkit/',
'sdk/': 'resource://gre/modules/commonjs/sdk/',
'': Services.io.newFileURI(buildDirFile).spec,
'../../': Services.io.newFileURI(gaiaDirFile).spec
};
if (appBuildDirFile) {
paths['app/'] = Services.io.newFileURI(appBuildDirFile).spec;
}
// generate a specific require path for each app starting with app folder
// name, so that we can load each app 'build.js' module.
if (options && options.GAIA_APPDIRS) {
options.GAIA_APPDIRS.split(' ').forEach(function(appDir) {
let appDirFile = new FileUtils.File(appDir);
let appBuildDirFile = appDirFile.clone();
appBuildDirFile.append('build');
paths[appDirFile.leafName + '/'] =
Services.io.newFileURI(appBuildDirFile).spec + '/';
});
}
// we have to do this the convoluted way to avoid
// problems where atob/btoa aren't defined
let globals = {};
if (typeof atob === 'function') {
globals.atob = atob;
}
if (typeof btoa === 'function') {
globals.btoa = btoa;
}
if (typeof quit === 'function') {
globals.quit = quit;
}
let loader = Loader.Loader({
paths: paths,
modules: {
'toolkit/loader': Loader,
'xpcshell': Object.create(xpcshellScope)
},
globals: globals
});
this.require = Loader.Require(loader, Loader.Module('main', 'gaia://'));
this.gaiaDirFile = gaiaDirFile;
this.module = module;
this.appDirFile = appDirFile;
};
CommonjsRunner.prototype.run = function() {
var output = '';
// Move this code here, to simplify the Makefile...
try {
// ...and to allow doing easily such thing \o/
if (this.appDirFile) {
var stageAppDir = this.gaiaDirFile.clone();
stageAppDir.append('build_stage');
stageAppDir.append(this.appDirFile.leafName);
options.STAGE_APP_DIR = stageAppDir.path;
options.APP_DIR = this.appDirFile.path;
output += this.appDirFile.leafName;
}
output += '/' + this.module;
this.require(this.module).execute(options);
// When an xpcshell module throws exception which is already captured by
// JavaScript module, some exceptions will make xpcshell returns error code.
// We put quit(0); to override the return code when all exceptions are
// handled in JavaScript module.
quit(0);
} catch(e) {
dump('Exception: ' + e + '\n' + e.stack + '\n');
quit(1);
}
};
function run(module, appOptions) {
var runner = new CommonjsRunner(module, appOptions);
runner.run();
}
function require(module, appOptions) {
var runner = new CommonjsRunner(module, appOptions);
return runner.require(module);
}