Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #15835 from comoyo/build-keyboard
Browse files Browse the repository at this point in the history
Bug 964216 - Use build_stage to build keyboard app. r=janjongboom
  • Loading branch information
janjongboom committed Jan 30, 2014
2 parents 5df7622 + 7df9f58 commit a77ae31
Show file tree
Hide file tree
Showing 154 changed files with 260 additions and 72 deletions.
1 change: 1 addition & 0 deletions .jshintignore
Expand Up @@ -27,3 +27,4 @@ apps/gallery/js/metadata_scripts.js
apps/keyboard/js/layouts/**
apps/music/js/metadata_scripts.js
apps/keyboard/js/imes/jszhuyin/tools/cook.js
apps/keyboard/build/keyboard-config.js
16 changes: 12 additions & 4 deletions Makefile
Expand Up @@ -220,13 +220,15 @@ ifneq (,$(findstring MINGW32_,$(SYS)))
CURDIR:=$(shell pwd -W | sed -e 's|/|\\\\|g')
SEP=\\
SEP_FOR_SED=\\\\
BUILDDIR := file:///$(shell pwd -W)/build/
GAIA_BUILD_DIR := file:///$(shell pwd -W)/build/
# Mingw mangle path and append c:\mozilla-build\msys\data in front of paths
MSYS_FIX=/
else
BUILDDIR := file://$(CURDIR)/build/
GAIA_BUILD_DIR := file://$(CURDIR)/build/
endif

export GAIA_BUILD_DIR

ifndef GAIA_APP_CONFIG
GAIA_APP_CONFIG=build$(SEP)config$(SEP)apps-$(GAIA_APP_TARGET).list
endif
Expand Down Expand Up @@ -399,7 +401,7 @@ endef

# Generate profile/

$(PROFILE_FOLDER): preferences local-apps app-makefiles test-agent-config offline contacts extensions install-xulrunner-sdk .git/hooks/pre-commit $(PROFILE_FOLDER)/settings.json create-default-data $(PROFILE_FOLDER)/installed-extensions.json
$(PROFILE_FOLDER): preferences local-apps app-makefiles copy-build-stage-manifest test-agent-config offline contacts extensions install-xulrunner-sdk .git/hooks/pre-commit $(PROFILE_FOLDER)/settings.json create-default-data $(PROFILE_FOLDER)/installed-extensions.json
ifeq ($(BUILD_APP_NAME),*)
@echo "Profile Ready: please run [b2g|firefox] -profile $(CURDIR)$(SEP)$(PROFILE_FOLDER)"
endif
Expand Down Expand Up @@ -588,7 +590,7 @@ define run-js-command
# in JavaScript module.
echo "run-js-command $1";
$(XULRUNNERSDK) $(XPCSHELLSDK) \
-e "const GAIA_BUILD_DIR='$(BUILDDIR)'" \
-e "const GAIA_BUILD_DIR='$(GAIA_BUILD_DIR)'" \
-f build/xpcshell-commonjs.js \
-e "try { require('$(strip $1)').execute($$BUILD_CONFIG); quit(0);} \
catch(e) { \
Expand Down Expand Up @@ -999,6 +1001,12 @@ really-clean: clean
adb-remount:
$(ADB) remount

# Generally we got manifest from webapp-manifest.js which is execute in
# applications-data.js unless manifest is generated from Makefile of app.
# so we will copy manifest.webapp if it's avaiable in build_stage/
copy-build-stage-manifest:
@$(call run-js-command, copy-build-stage-manifest)

build-test-unit: $(NPM_INSTALLED_PROGRAMS)
@$(call run-build-test, $(shell find build/test/unit/*.test.js))

Expand Down
4 changes: 0 additions & 4 deletions apps/keyboard/.gitignore
@@ -1,4 +0,0 @@
/js/imes
/js/imes/\!latin
/js/imes/latin/dictionaries/*.dict
/js/layouts/*.js
20 changes: 11 additions & 9 deletions apps/keyboard/CONFIGURE
@@ -1,19 +1,21 @@
The keyboard app uses large dictionary files for autocorrection. If we
include all the dictionaries we have, our builds become too large. So
the keyboard is configured at build time to include only the layouts
and dictionaries we need for a particular build.
the keyboard is configured at build time to include only the IMEs,
layouts, and dictionaries we need for a particular build.

Dictionaries live in gaia/keyboard/dictionaries and layouts are
defined in gaia/keyboard/layouts. Files are copied into this app, but
are not checked into github in this app.
Dictionaries files currently only apply for the latin IME and live in
js/imes/latin/dictionaries, along with the source files (in XML) in
Android format. There is a Makefile present to convert the source files
into Firefox OS dictionaries.

At build time we only package the IMEs and dictionaries required by the
specified keyboard layouts.

We also configure the manifest.webapp file at build time, to add entry
points for each layout.

Configuration is done with the GAIA_KEYBOARD_LAYOUTS environment
variable, and there is a default value defined in the Makefile.

The actual configuration code is in build/keyboard-config.js. The
functions defined by that file are used by build/application-data.js
and build/webapp-manifests.js

The build happens in gaia/build_stage.
The actual configuration code is in build/keyboard-config.js.
22 changes: 22 additions & 0 deletions apps/keyboard/Makefile
@@ -0,0 +1,22 @@
ifndef GAIA_BUILD_DIR
GAIA_BUILD_DIR=$(PWD)/build
endif

BUILD_DIR=$(PWD)/build_stage/keyboard

.PHONY: all clean
all: clean
@echo Building keyboard app to build_stage...
@mkdir -p $(BUILD_DIR)
@$(XULRUNNERSDK) $(XPCSHELLSDK) \
-e "const GAIA_BUILD_DIR='$(GAIA_BUILD_DIR)'" \
-e "const APP_BUILD_DIR='$(GAIA_BUILD_DIR)../apps/keyboard/build/'" \
-f ../../build/xpcshell-commonjs.js \
-e "try { require('app/build').execute($$BUILD_CONFIG); quit(0);} \
catch(e) { \
dump('Exception: ' + e + '\n' + e.stack + '\n'); \
throw(e); \
}"

clean:
@rm -rf $(BUILD_DIR)
149 changes: 149 additions & 0 deletions apps/keyboard/build/build.js
@@ -0,0 +1,149 @@
'use strict';

/* global require, exports */

var utils = require('utils');
var keyboardConfig = require('./keyboard-config');

var KeyboardAppBuilder = function() {
};
KeyboardAppBuilder.prototype.APP_DIR = 'apps/keyboard';
KeyboardAppBuilder.prototype.DIST_DIR = 'build_stage/keyboard';

// set options
KeyboardAppBuilder.prototype.setOptions = function(options) {
this.allLayouts = options.GAIA_KEYBOARD_LAYOUTS.split(',');

var distDirPath = [options.GAIA_DIR].concat(this.DIST_DIR.split('/'));
this.distDir = utils.getFile.apply(utils, distDirPath);

var appDirPath = [options.GAIA_DIR].concat(this.APP_DIR.split('/'));
this.appDir = utils.getFile.apply(utils, appDirPath);
};

KeyboardAppBuilder.prototype.getLayoutsForVersion = function(version) {
var layouts = [];
switch (version) {
case 'one':
this.allLayouts.forEach(function(layoutName) {
var file = utils.getFile(
this.appDir.path, 'js', 'layouts', layoutName + '.js');
if (file.exists()) {
layouts.push(layoutName);
}
}.bind(this));

break;

case 'two':
// TBD

break;
}

return layouts;
};

KeyboardAppBuilder.prototype.throwForNoneExistLayouts = function() {
this.allLayouts.forEach(function(layoutName) {
if (this.versionOneLayouts.indexOf(layoutName) === -1 &&
this.versionTwoLayouts.indexOf(layoutName) === -1) {
throw new Error('Keyboard layout ' + layoutName + '.js specified by ' +
'GAIA_KEYBOARD_LAYOUTS not found.');
}
}.bind(this));
};

// Copy static files to build_stage.
KeyboardAppBuilder.prototype.copyStaticFiles = function() {
// Files to blindly copy to build_stage regardless of versions
var filenames = ['resources'];
var dirs = [];

if (this.versionOneLayouts.length) {
dirs = dirs.concat('js', 'js/imes', 'js/imes/latin');
// Unfortunately we have to explicitly list many files here
// because the whitelist most not include optional layout
// specific files.
filenames = filenames.concat('index.html', 'locales',
'settings.html', 'style',
'js/keyboard.js', 'js/layout.js',
'js/render.js', 'js/settings',
'js/imes/latin/latin.js',
'js/imes/latin/predictions.js',
'js/imes/latin/worker.js');
}
if (this.versionTwoLayouts.length) {
/* TBD, maybe
filenames = filenames.concat('index2.html', 'style2', 'js2');
and move more shared files out of the two `if` blocks.
*/
}

dirs.forEach(function(dirName) {
var dir = utils.getFile.apply(utils,
[this.appDir.path].concat(dirName.split('/')));
utils.ensureFolderExists(dir);
}.bind(this));

filenames.forEach(function(filename) {
var filenameArr = filename.split('/');

var file = utils.getFile.apply(utils,
[this.appDir.path].concat(filenameArr));
var distSubDir = utils.getFile.apply(utils,
[this.distDir.path].concat(filenameArr.slice(0, filenameArr.length - 1)));
file.copyTo(distSubDir, file.leafName);
}.bind(this));
};

KeyboardAppBuilder.prototype.copyLayouts = function() {
// XXX we probably need better separation between this
// and keyboard-config.js

// For v1 keyboard
keyboardConfig.copyLayoutsAndResources(
this.appDir, this.distDir, this.versionOneLayouts);

// TBD: v2
};

KeyboardAppBuilder.prototype.generateManifest = function() {
// XXX we probably need better separation between this
// and keyboard-config.js

var manifest =
utils.getJSON(utils.getFile(this.appDir.path, 'manifest.webapp'));

// For v1 keyboard
manifest = keyboardConfig.addEntryPointsToManifest(
this.appDir, this.distDir, this.versionOneLayouts, manifest);

// TBD: v2

// Write content to build_stage
utils.writeContent(utils.getFile(this.distDir.path, 'manifest.webapp'),
JSON.stringify(manifest));
};

KeyboardAppBuilder.prototype.execute = function(options) {
this.setOptions(options);

// Check against allLayouts. Most of the code should be gone with v1 keyboard.
this.versionOneLayouts = this.getLayoutsForVersion('one');
this.versionTwoLayouts = this.getLayoutsForVersion('two');
this.throwForNoneExistLayouts();

this.copyStaticFiles();
this.copyLayouts();
this.generateManifest();
};

exports.execute = function(options) {
// We cannot export prototype functions out :(
// so we run execute() this way.
(new KeyboardAppBuilder()).execute(options);
};
36 changes: 12 additions & 24 deletions build/keyboard-config.js → apps/keyboard/build/keyboard-config.js
@@ -1,34 +1,25 @@
let utils = require('./utils');
let utils = require('utils');
const { Cc, Ci, Cr, Cu, CC } = require('chrome');
Cu.import('resource://gre/modules/Services.jsm');

exports.copyLayoutsAndResources = copyLayoutsAndResources;
exports.addEntryPointsToManifest = addEntryPointsToManifest;

function copyLayoutsAndResources(config) {
// This is the source dir for the keyboard app
let appDir = utils.getFile(config.GAIA_DIR, 'apps', 'keyboard');

function copyLayoutsAndResources(appDir, distDir, layoutNames) {
// Here is where the layouts and dictionaries get copied to
let layoutDest = utils.getFile(appDir.path, 'js', 'layouts');
let dictDest = utils.getFile(appDir.path,
let layoutDest = utils.getFile(distDir.path, 'js', 'layouts');
let dictDest = utils.getFile(distDir.path,
'js', 'imes', 'latin', 'dictionaries');

let imeDest = utils.getFile(appDir.path, 'js', 'imes');
let imeDest = utils.getFile(distDir.path, 'js', 'imes');

// First delete any layouts or dictionaries that are in the src dir
// from the last time.
utils.ensureFolderExists(layoutDest);
utils.ensureFolderExists(dictDest);
utils.ls(layoutDest, false).forEach(function(f) { f.remove(false); });
utils.ls(dictDest).forEach(function(f) { f.remove(false); });
utils.ls(imeDest).forEach(function(f) {
if (f.leafName !== 'latin')
f.remove(true);
});

// Now get the set of layouts for this build
let layouts = getLayouts(config);
let layouts = getLayouts(appDir, layoutNames);

// Loop through the layouts and copy the layout file and dictionary file
layouts.forEach(function(layout) {
Expand Down Expand Up @@ -57,9 +48,9 @@ function copyLayoutsAndResources(config) {
});
}

function addEntryPointsToManifest(config, manifest) {
function addEntryPointsToManifest(appDir, distDir, layoutNames, manifest) {
// Get the set of layouts
let layouts = getLayouts(config);
let layouts = getLayouts(appDir, layoutNames);

// The inputs property of the manifest object has one property
// for each keyboard layout we support. The manifest file has a hard-coded
Expand All @@ -79,14 +70,11 @@ function addEntryPointsToManifest(config, manifest) {

// Read the keyboard layout file for each of the named keyboard layouts in
// GAIA_KEYBOARD_LAYOUTS, and return an array of layout objects
function getLayouts(config) {
// These are the keyboard layouts requested at build time
let layoutNames = config.GAIA_KEYBOARD_LAYOUTS.split(',');

function getLayouts(appDir, layoutNames) {
// Here is where the layouts and dictionaries come from
let layoutSrc = utils.getFile(config.GAIA_DIR, 'keyboard', 'layouts');
let dictSrc = utils.getFile(config.GAIA_DIR, 'keyboard', 'dictionaries');
let imeSrc = utils.getFile(config.GAIA_DIR, 'keyboard', 'imes');
let layoutSrc = utils.getFile(appDir.path, 'js', 'layouts');
let dictSrc = utils.getFile(appDir.path, 'js', 'imes', 'latin', 'dictionaries');
let imeSrc = utils.getFile(appDir.path, 'js', 'imes');

// Read the layout files and find their names and dictionaries,
// and copy them into the app package
Expand Down
3 changes: 3 additions & 0 deletions apps/keyboard/gaia_build.json
@@ -0,0 +1,3 @@
{
"dir": "../../build_stage/keyboard"
}

0 comments on commit a77ae31

Please sign in to comment.