Skip to content

Instantly share code, notes, and snippets.

@balanza
Last active March 14, 2017 01:25
Show Gist options
  • Save balanza/dba8dd63dd38072c1dce to your computer and use it in GitHub Desktop.
Save balanza/dba8dd63dd38072c1dce to your computer and use it in GitHub Desktop.
Alloy compile hook for reenginering file structure of a project
task("pre:compile", function(event, logger) {
//a decorator for path.join that consider arrays as arguments
function superJoin() {
var args = Array.prototype.slice.call(arguments);
var p = [];
_.each(args, function(e) {
if (_.isArray(e)) p = p.concat(e);
else if (e) p.push(e);
});
logger.info(JSON.stringify(p));
return path.join.apply(this, p);
}
//get extension of a file
function getExtension(file) {
return file.substring(file.lastIndexOf(".") + 1);
}
//copy a file into another
function copyFileSync(srcFile, destFile) {
logger.info('copyFileSync ' + srcFile + ' --> ' + destFile);
var BUF_LENGTH, buff, bytesRead, fdr, fdw, pos;
BUF_LENGTH = 64 * 1024;
buff = ''; // new Buffer(BUF_LENGTH);
fdr = fs.readFileSync(srcFile);
// logger.info('file ' + fdr);
var dir = path.dirname(destFile);
logger.info('dir ' + dir);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
fdw = fs.writeFileSync(destFile, fdr);
return fdw;
};
//copy all folder content into destination
function copyFolderRecursiveSync(source, target) {
var files = [];
//check if folder needs to be created or integrated
var targetFolder = path.join(target, path.basename(source));
if (!fs.existsSync(targetFolder)) {
fs.mkdirSync(targetFolder);
}
//copy
if (fs.lstatSync(source).isDirectory()) {
files = fs.readdirSync(source);
files.forEach(function(file) {
var curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
copyFolderRecursiveSync(curSource, targetFolder);
} else {
copyFileSync(curSource, path.join(targetFolder, file));
}
});
}
}
//clear all files and subfolders from a folder
function cleanFolderRecursiveSync(source, remove) {
var files = [];
var sourceFolder = source;
if (fs.existsSync(sourceFolder)) {
logger.info('cleaning folder ' + source);
//clean
if (fs.lstatSync(source).isDirectory()) {
files = fs.readdirSync(source);
files.forEach(function(file) {
var curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
cleanFolderRecursiveSync(curSource, true);
} else {
// if (file.indexOf('index') >= 0) return;
var filePath = path.join(source, file)
logger.info('unlink file ' + filePath);
fs.unlinkSync(filePath);
}
});
}
if (remove) {
fs.rmdirSync(source);
}
} else {
logger.info('cant find folder ' + sourceFolder);
}
}
//add a widget reference in config.json
function installWidget(widgetId) {
//write dependency in config.json
var fileName = path.join(folders.app, 'config.json');
var config = require(fileName);
if (!config.dependencies[widgetId]) {
config.dependencies[widgetId] = '*';
}
fs.writeFileSync(fileName, JSON.stringify(config, null, 4));
}
//remove all widget references in config.json
function clearAllWidgets() {
//write dependency in config.json
var fileName = path.join(folders.app, 'config.json');
var config = require(fileName);
config.dependencies = {};
fs.writeFileSync(fileName, JSON.stringify(config, null, 4));
}
/**
* PROCESS START
*/
//profile start
var start = new Date();
var fs = require('fs');
var path = require('path');
var platform = event.alloyConfig.platform === 'ios' ? 'iphone' : event.alloyConfig.platform;
var _ = require(path.join(event.dir.resources, platform, 'alloy', 'underscore.js'))
var folders = {
app: eve\nt.dir.project + '/app',
controllers: event.dir.project + '/app/controllers',
styles: event.dir.project + '/app/styles',
views: event.dir.project + '/app/views',
widgets: event.dir.project + '/app/widgets',
ui: event.dir.project + '/app/ui',
};
/**
* clean previous generated files
*/
_(['controllers', 'views', 'widgets', 'styles']).each(function(key) {
cleanFolderRecursiveSync(folders[key]);
});
clearAllWidgets();
/**
* scan /ui folder for file to copy
*/
//procedure scanUI(base, hierarchy) :=
//for each e in base
// if e is directory
// if e is windget
// copy e/* --> folders.widgets/*
// install widget on config.json
// else
// copy e/index.js --> folders.controllers/e.js
// copy e/index.tss --> folders.styles/e.tss
// copy e/index.xml --> folders.views/e.xml
// hierarchy.push(e)
// call scanUI(e, hierarchy)
// else
// if isRoot //for first-level elements that aren't in a folder
// copy *.js --> folders/controllers/*.js
// copy *.tss --> folders/styles/*.tss
// copy *.xml --> folders/views/*.xml
function scanUI(base, hierarchy) {
logger.info('scanUI ' + base + ' ' + hierarchy);
if (fs.lstatSync(base).isDirectory()) {
files = fs.readdirSync(base);
files.forEach(function(file) {
var e = path.join(base, file);
logger.info('iterate e ' + e);
//if e is directory
if (fs.lstatSync(e).isDirectory()) {
//if e is widget
if (fs.existsSync(path.join(e, 'widget.json'))) {
//copy e/* --> folders.widgets/*
copyFolderRecursiveSync(e, path.join(folders.widgets));
//install widget on config.json
installWidget(file);
} else { //is an entity
//copy e/index.js --> folders.controllers/e.js
copyFileSync(superJoin(e, 'index.js'), superJoin(folders.controllers, hierarchy, file + '.js'));
//copy e/index.tss --> folders.styles/e.tss
copyFileSync(superJoin(e, 'index.tss'), superJoin(folders.styles, hierarchy, file + '.tss'));
//copy e/index.xml --> folders.views/e.xml
copyFileSync(superJoin(e, 'index.xml'), superJoin(folders.views, hierarchy, file + '.xml'));
//call scanUI(e)
scanUI(e, (hierarchy || []).concat([file]));
}
} else {
var isRoot = _.isEmpty(hierarchy);
if (isRoot) {
switch (getExtension(file)) {
case 'js':
copyFileSync(path.join(base, file), path.join(folders.controllers, file));
break;
case 'tss':
copyFileSync(path.join(base, file), path.join(folders.styles, file));
break;
case 'xml':
copyFileSync(path.join(base, file), path.join(folders.views, file));
break;
default:
//??
}
}
}
});
}
}
scanUI(folders.ui);
//end of profiling
var end = new Date();
//profile
var duration = Math.abs((end.getTime() - start.getTime()) / 1000);
logger.info('pre:compile duration ' + duration + 's');
});
/myProject
|_ /app
|_ /assets
|_ /models
|_ /ui
|_ /entity1
|_ index.js
|_ index.tss
|_ index.xml
|_ /sub_entity1
|_ index.js
|_ index.tss
|_ index.xml
|_ /entity2
|_ index.js
|_ index.tss
|_ index.xml
|_ index.js
|_ index.tss
|_ index.xml
|_ alloy.js
|_ config.json
|_ alloy.jmk
|
|_ tiapp.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment