Skip to content
This repository has been archived by the owner on Jul 23, 2019. It is now read-only.

Commit

Permalink
Merge pull request #8 from spryker/develop
Browse files Browse the repository at this point in the history
Version 2.0.0
Alessandro Bellini committed Mar 31, 2016
2 parents 7873f8e + 2278c3c commit 423e229
Showing 14 changed files with 395 additions and 368 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

### 2.0.0
- version test added (check Spryker GUI bundle compatibility - temporary disabled)

### 2.0.0-beta2
- legacy compatibility for v1 projects with `-l|--legacy` flag

### 2.0.0-beta1
- code refactor
- webpack configuration moved ouside the tool
- new provider implementation

### 1.1.3
- new provider implementation

129 changes: 71 additions & 58 deletions lib/automation.js
Original file line number Diff line number Diff line change
@@ -10,13 +10,22 @@ let path = require('path');
let R = require('ramda');
let context = require('./context');
let errors = require('./errors');
let configurator = require('./automation/webpack');
let collector = require('./automation/collector');
let provider = require('./automation/provider');
let compiler = require('./automation/compiler');
let themes = require('./automation/themes');
let cwd = process.cwd();

function processAssets(targetConfigName, configurator, targetPattern, theme) {
function automation(target, targetPattern, theme) {
console.log(`\n${target.toUpperCase()}`.bold.gray);

if (!!theme) {
console.log(`${theme.toUpperCase()} theme`.gray);
}

console.log('- collecting data...'.gray);

return new Promise((resolve, reject) => {
return Promise.all([
collector.entryPoints(targetPattern, theme),
@@ -26,97 +35,101 @@ function processAssets(targetConfigName, configurator, targetPattern, theme) {
let entryPoints = results[0];
let extensions = results[1];
let manifests = results[2];
let defaultConfig;
let config;
let config = {};

console.log(`\n${targetConfigName.toUpperCase()}`.bold.gray);
function skip(message) {
console.warn('- build'.gray, 'skipped'.yellow, message.gray);
resolve();
}

if (!!theme) {
console.log(`${theme.toUpperCase()} theme`.gray);
function compile() {
compiler.build(config).then(resolve, reject);
}

console.log(`- entry points:`.gray,
console.log(` ${String.fromCharCode(0x2517)} entry points:`.gray,
`${entryPoints.count.valid} valid`.green,
'|'.gray,
`${entryPoints.count.duplicates} duplicates`.yellow,
'|'.gray,
`${entryPoints.count.total} total`.cyan);

try {
defaultConfig = configurator.load(entryPoints.valid, manifests.valid);
} catch (err) {
reject(errors.enrich(err, 'loading default configuration'));
}

if (extensions.count.valid > 0) {
if (extensions.count.valid > 1) {
console.log('- warning: more than one extension for the same application/theme - first will be processed, the others ignored'.yellow);
}
if (extensions.count.valid > 0) {
if (extensions.count.valid > 1) {
console.warn(` ${String.fromCharCode(0x2517)} warning: more than one extension for the same application/theme - first will be processed, the others ignored`.yellow);
}

try {
let extensionName = R.keys(extensions.valid)[0];
let extension = provider.import(path.join(cwd, extensions.valid[extensionName]));
config = R.merge(defaultConfig, extension);
console.log(` ${String.fromCharCode(0x2517)} configuration:`.gray, extensions.valid[extensionName].magenta);

if (!config) {
reject(errors.enrich(new Error('undefined/null/invalid configuration extension returned'), 'extending configuration'));
}
let extension = provider.import(path.join(cwd, extensions.valid[extensionName]), entryPoints.valid, manifests.valid);
config = R.merge(configurator.getDefault(), extension);

console.log('- custom configuration loaded:'.gray, extensions.valid[extensionName].magenta);
} catch (extensionErr) {
config = R.clone(defaultConfig);
console.error('- custom configuration ignored due to error: %s'.red, extensionErr);
}
// LEGACY
if (context.has('legacy') && target === 'yves') {
config = R.merge(configurator.legacy.yves(entryPoints.valid, manifests.valid), extension);
}
// END LEGACY

if (context.has('debug')) {
provider.report();
if (!config) {
throw new Error('undefined/null/invalid configuration returned');
} else {
if (config.antelope && config.antelope.disabled) {
skip('by configuration');
} else {
compile();
}
}
} else {
// LEGACY
if (context.has('legacy') && target === 'zed') {
config = configurator.legacy.zed(entryPoints.valid, manifests.valid);
compile();
} else {
if (target === 'zed') {
console.warn('\n[!] Zed missing configuration may be caused by antelope v2'.yellow);
console.warn(' Run this tool using'.yellow, '-l', 'flag to provide legacy for v1 projects'.yellow, '\n');
}
// END LEGACY

skip('due to missing configuration');
}
}
} else {
config = R.clone(defaultConfig);
console.log('- default configuration loaded'.gray);
}

if (config.antelope && config.antelope.disabled) {
console.log('- build'.gray, 'disabled'.yellow, 'by config'.gray);
resolve();
} else {
compiler.build(config).then(resolve, reject);
} catch (err) {
console.error('- build'.gray, 'aborted'.red);
reject(err);
}
}, reject);
});
}

function automation(targetConfigName, targetPattern, themePattern) {
let configurator = require(`./webpack/configs/${targetConfigName}.js`);

if (targetConfigName === 'zed') {
return processAssets(targetConfigName, configurator, targetPattern, themePattern);
}

return R.reduce((promise, theme) => {
return promise.then(() => {
return processAssets(targetConfigName, configurator, targetPattern, theme);
});
}, Promise.resolve(), themes.getFromPattern(themePattern));
}

module.exports = {
run: () => {
let targetPatterns = context.patterns.target();
let themePatterns = context.patterns.theme();

function processYves() {
return R.reduce((promise, theme) => {
return promise.then(() => {
return automation('yves', targetPatterns.yves, theme);
});
}, Promise.resolve(), themes.getFromPattern(themePatterns.yves));
}

function processZed() {
return automation('zed', targetPatterns.zed);
}

if (context.isAll()) {
return automation('yves', targetPatterns.yves, themePatterns.yves).then(() => {
return automation('zed', targetPatterns.zed);
});
return processYves().then(processZed);
}

if (context.isYves()) {
return automation('yves', targetPatterns.yves, themePatterns.yves);
return processYves();
}

if (context.isZed()) {
return automation('zed', targetPatterns.zed);
return processZed();
}
}
};
3 changes: 2 additions & 1 deletion lib/automation/collector.js
Original file line number Diff line number Diff line change
@@ -58,14 +58,15 @@ module.exports = {
manifests: () => {
return collect('manifests (package.json)', [
path.join(cwd, `./package.json`),
path.join(cwd, `./vendor/spryker/**/assets/package.json`)
path.join(cwd, `./vendor/spryker/**/assets/*/package.json`)
]);
},
extensions: (targetPattern, themePattern) => {
targetPattern = targetPattern || '';
themePattern = themePattern || '';

return collect('extensions', [
path.join(cwd, `./vendor/spryker/**/assets/*/*${targetPattern}*${themePattern}*${context.patterns.extension()}`),
path.join(cwd, `./assets/**/*${targetPattern}*${themePattern}*${context.patterns.extension()}`)
], context.patterns.extension());
},
28 changes: 20 additions & 8 deletions lib/automation/compiler.js
Original file line number Diff line number Diff line change
@@ -14,6 +14,11 @@ let errors = require('../errors');
let cwd = process.cwd();
let watching = false;

function showModuleNotFoundMessage() {
console.error('\n[!] Something is missing: did you run'.red, 'antelope install', 'before building?'.red);
console.error(' If you did, then it may be a typo...'.red);
}

module.exports = {
build: (config) => {
return new Promise((resolve, reject) => {
@@ -31,9 +36,13 @@ module.exports = {

if (!!stats.compilation.errors && stats.compilation.errors.length > 0) {
withErrors = true;

R.forEach(function(compilationErr) {
withModuleNotFound = (compilationErr.name === 'ModuleNotFoundError');
console.error(' - %s'.red, compilationErr);
if (compilationErr.name == 'ModuleNotFoundError') {
withModuleNotFound = true;
}

console.error(` ${String.fromCharCode(0x2517)} %s`.red, compilationErr);
}, stats.compilation.errors);

if (!config.watch) {
@@ -42,22 +51,22 @@ module.exports = {
}

if (!!stats.compilation.fileDependencies) {
console.log(' - built:'.gray, `${stats.compilation.fileDependencies.length}`.green);
console.log(` ${String.fromCharCode(0x2517)} built:`.gray, `${stats.compilation.fileDependencies.length}`.green);

if (context.has('debug') && stats.compilation.fileDependencies.length > 0) {
R.forEach(function(file) {
console.log(' -'.gray, `${path.relative(cwd, file)}`.magenta);
console.log(` ${String.fromCharCode(0x2517)}`.gray, `${path.relative(cwd, file)}`.magenta);
}, stats.compilation.fileDependencies);
}
}

if (!!stats.compilation.missingDependencies) {
console.warn(' - missing:'.gray, `${stats.compilation.missingDependencies.length}`.yellow);
console.warn(` ${String.fromCharCode(0x2517)} missing:`.gray, `${stats.compilation.missingDependencies.length}`.yellow);

if (stats.compilation.missingDependencies.length) {
withWarnings = true;
R.forEach(function(file) {
console.warn(` - ${path.relative(cwd, file)}`.yellow);
console.warn(` ${String.fromCharCode(0x2517)} ${path.relative(cwd, file)}`.yellow);
}, stats.compilation.missingDependencies);
}
}
@@ -66,15 +75,18 @@ module.exports = {
console.error('- build failed'.gray, 'due to errors'.red);

if (withModuleNotFound) {
console.error(' [!] something is missing: did you run'.red, 'antelope install', 'before building?'.red);
console.error(' if you did, then it may be a typo...'.red);
showModuleNotFoundMessage();
}
} else if (withWarnings) {
console.warn('- build completed'.gray, 'with some warning'.yellow);
} else {
console.log('- build completed'.gray, 'successfully'.green, 'in'.gray, `${(stats.endTime - stats.startTime) / 1000}`.cyan, 'seconds'.gray);
}
} catch (err) {
if (withModuleNotFound) {
showModuleNotFoundMessage();
}

reject(errors.enrich(err, 'compilation report'));
}

54 changes: 34 additions & 20 deletions lib/automation/provider.js
Original file line number Diff line number Diff line change
@@ -9,37 +9,51 @@
let path = require('path');
let fs = require('graceful-fs');
let R = require('ramda');
let context = require('../context');
let cwd = process.cwd();
let report = {};

function extendedRequire(id) {
let requiredModule;

function contextRequire(id) {
try {
requiredModule = require(`${cwd}/node_modules/${id}`);
report[id] = 'project';
return requiredModule;
return require(`${cwd}/node_modules/${id}`);
} catch (err) {
requiredModule = require(id);
report[id] = 'antelope';
return requiredModule;
return require(id);
}
}

function getAntelope(entryPoints, manifests) {
let loadersPaths = process.mainModule.paths.concat([path.join(cwd, './node_modules')]);
let rootPaths = [
cwd,
path.join(cwd, './node_modules')
].concat(R.map((manifest) => {
return path.join(path.dirname(manifest), './node_modules');
}, R.keys(manifests)));

return {
remote: (id) => require(id),
options: context.options(),
entryPoints: entryPoints,
paths: {
root: rootPaths,
loaders: loadersPaths
}
};
}

module.exports = {
import: (id) => {
import: (id, entryPoints, manifest) => {
let context = require('module');
let body = fs.readFileSync(id, 'utf8');
let fn = new Function('module', 'exports', 'require', body);
let fn = new Function('module', 'exports', 'require', '__dirname', 'antelope', body);
let args = [
context,
context.exports,
contextRequire,
path.dirname(id),
getAntelope(entryPoints, manifest)
];

fn.apply(context, [context, context.exports, extendedRequire]);
fn.apply(context, args);
return context.exports;
},
report: () => {
R.forEach((id) => {
console.log(' -'.gray, id.magenta, 'imported from'.gray, report[id].cyan);
}, R.keys(report));

report = {};
}
};
158 changes: 158 additions & 0 deletions lib/automation/webpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/**
* This file is part of Antelope frontend automation tool
* (c) Spryker Systems GmbH
* For full copyright and license information, please view the LICENSE file that was distributed with this source code.
*/

'use strict';

const cwd = process.cwd();

module.exports = {
getDefault: () => {
return {
antelope: {},
context: cwd
};
},
legacy: {
yves: (entryPoints, manifests) => {
let path = require('path');
let context = require('../context');
let loadersPaths = process.mainModule.paths.concat([path.join(cwd, './node_modules')]);
let rootPaths = [
cwd,
path.join(cwd, './node_modules')
];

let config = {
antelope: {},
context: cwd,
entry: entryPoints,
resolve: {
root: rootPaths
},
resolveLoader: {
root: loadersPaths
},
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
plugins: [],
progress: true,
failOnError: false,
debug: context.has('debug'),
watch: context.has('watch')
};

return config;
},
zed: (entryPoints, manifests) => {
let path = require('path');
let R = require('ramda');
let globby = require('globby');
let webpack = require('webpack');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let context = require('../context');
let anchor = globby.sync([
'**/spryker-zed-gui-commons.entry.js'
], {
cwd: cwd,
nocase: true
});
let guiPath = path.join(cwd, anchor[0], '../../../../');
let bundlesPath = path.join(guiPath, '../');
let loadersPaths = process.mainModule.paths.concat([path.join(cwd, './node_modules')]);
let rootPaths = [
path.join(cwd, './node_modules'),
bundlesPath
].concat(R.map((manifest) => {
return path.join(path.dirname(manifest), './node_modules');
}, R.keys(manifests)));

let config = {
antelope: {},
context: cwd,
entry: entryPoints,
resolve: {
root: rootPaths,
alias: {
ZedGui: `${path.basename(guiPath)}/assets/Zed/js/modules/commons`
}
},
resolveLoader: {
root: loadersPaths
},
output: {
path: path.join(cwd, './public/Zed'),
filename: 'assets/js/[name].js'
},
module: {
loaders: [{
test: /\.css\??(\d*\w*=?\.?)+$/i,
loader: ExtractTextPlugin.extract('style', 'css')
}, {
test: /\.scss$/i,
loader: ExtractTextPlugin.extract('style', 'css!resolve-url!sass?sourceMap')
}, {
test: /\.(ttf|woff2?|eot)\??(\d*\w*=?\.?)+$/i,
loader: 'file?name=/assets/fonts/[name].[ext]'
}, {
test: /\.(jpe?g|png|gif|svg)\??(\d*\w*=?\.?)+$/i,
loader: 'file?name=/assets/img/[name].[ext]'
}]
},
sassLoader: {
includePaths: loadersPaths
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('spryker-zed-gui-commons', 'assets/js/spryker-zed-gui-commons.js'),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',

// legacy provider
SprykerAjax: 'Gui/assets/Zed/js/modules/legacy/SprykerAjax',
SprykerAjaxCallbacks: 'Gui/assets/Zed/js/modules/legacy/SprykerAjaxCallbacks',
SprykerAlert: 'Gui/assets/Zed/js/modules/legacy/SprykerAlert'
}),
new ExtractTextPlugin('assets/css/[name].css', {
allChunks: true
}),
new webpack.DefinePlugin({
PRODUCTION: context.has('production'),
WATCH: context.has('watch'),
'require.specified': 'require.resolve'
})
],
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
progress: true,
failOnError: false,
devtool: 'sourceMap',
debug: context.has('debug'),
watch: context.has('watch')
};

if (context.has('production')) {
config.plugins = config.plugins.concat([
new webpack.optimize.UglifyJsPlugin({
comments: false,
sourceMap: context.has('debug'),
compress: {
warnings: context.has('debug')
},
mangle: {
except: ['$', 'exports', 'require']
}
})
]);
}

return config;
}
}
};
53 changes: 32 additions & 21 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@ let exit = require('exit');
let context = require('./context');
let errors = require('./errors');
let install = require('./install');
let test = require('./test');
let automation = require('./automation');
let test = require('./test');
let versionTest = require('./test/version');
let pkg = require('../package.json');
let cwd = process.cwd();
let start = new Date().getTime();
@@ -53,16 +54,30 @@ function runInstall(options) {
function runTest(options) {
context.init('test', options);

printInfo();
console.log('\nSettings'.bold.grey);
console.log('- project root (cwd):'.grey, cwd.magenta);
if (context.has('compatibility')) {
versionTest.print()
} else {
printInfo();
console.log('\nSettings'.bold.grey);
console.log('- project root (cwd):'.grey, cwd.magenta);

test.full().then(() => {
console.log('\nTest completed'.gray, 'succesfully'.green);
return exitAndLog();
}).catch((err) => {
return exitAndLog(errors.log('test', err));
});
test.full().then(() => {
console.log('\nTest completed'.gray, 'succesfully'.green);
return exitAndLog();
}).catch((err) => {
return exitAndLog(errors.log('test', err));
});
}
}

function runPrint(options) {
context.init('print', options);

if (context.has('range')) {
versionTest.print()
} else {
printInfo();
}
}

function runAutomation(target, options) {
@@ -105,6 +120,11 @@ function runAutomation(target, options) {
console.log('- mode:'.grey, context.output.mode().cyan);
console.log('- watch:'.grey, `${context.has('watch')}`.cyan);

if (context.has('legacy')) {
console.warn('\n[!] You are running in legacy mode'.yellow);
console.warn(' Please update your project to antelope v2'.yellow);
}

if (context.has('debug')) {
automationPromise = test.full().then(() => automation.run());
} else {
@@ -118,17 +138,6 @@ function runAutomation(target, options) {
});
}

function runProvider(options) {
context.init('provider', options);

printInfo();
console.log('\nProvider'.bold.gray);
console.log('Show provided modules available in YVES and ZED custom configurations'.gray, '\n');
provider.show();

return exitAndLog();
}

commander
.on('--help', () => {
console.log(` Run 'antelope <command> --help' to output command specific usage information`);
@@ -142,6 +151,7 @@ commander
commander
.command('test')
.description('Perform functionality and project checks')
.option('-c, --compatibility', 'Perform a fast compatibility test')
.action(runTest);

commander
@@ -151,6 +161,7 @@ commander
.option('-w, --watch', 'enable the watch mode over source files')
.option('-f, --follow', 'follow symlinks when search for extensions and entry points')
.option('-d, --debug', 'enable the debug mode (output verbosity)')
.option('-l, --legacy', 'enable legacy mode for antelope v1 projects')
.option('--production', 'enable the production mode')
.action(runAutomation);

1 change: 1 addition & 0 deletions lib/test.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
'use strict';

let projectTest = require('./test/project');
let versionTest = require('./test/version');
let collectorTest = require('./test/collector');

module.exports = {
81 changes: 0 additions & 81 deletions lib/test/dependency.js

This file was deleted.

1 change: 0 additions & 1 deletion lib/test/project.js
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ module.exports = {
return new Promise((resolve, reject) => {
console.log('\nProject test'.bold.gray);
console.log('Check for current workin directory'.gray);
console.log('You must run antelope from project root folder'.gray);
console.log('|'.gray);

fs.stat(`${cwd}/public`, (err, stats) => {
63 changes: 63 additions & 0 deletions lib/test/version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* This file is part of Antelope frontend automation tool
* (c) Spryker Systems GmbH
* For full copyright and license information, please view the LICENSE file that was distributed with this source code.
*/

'use strict';

const path = require('path');
const globby = require('globby');
const semver = require('semver');
const errors = require('../errors');
const pkg = require('../../package');
const cwd = process.cwd();

function checkCompatibility() {
let composer = {};
let isCompatible = false;
let manifests = globby.sync([
'**/gui/composer.json'
], {
cwd: cwd,
nocase: true
});

if (manifests.length === 1) {
composer = require(path.join(cwd, manifests[0]));
isCompatible = semver.satisfies(pkg.version, composer.antelope || '0');
}

return {
isCompatible: isCompatible,
version: pkg.version,
range: composer.antelope || 'unknown'
};
}

module.exports = {
run: () => {
return new Promise((resolve, reject) => {
let results = checkCompatibility();

console.log('\nVersion test'.bold.gray);
console.log('Check compatibilty with Spryker GUI bundle'.gray);
console.log('|'.gray);
console.log('| Version'.gray, results.version.cyan, '-> Range'.gray, results.range.cyan);

if (results.isCompatible) {
console.log('|'.gray, 'This version is'.gray, 'compatible'.green);
return resolve();
} else {
console.error('|'.gray, 'This version is'.gray, 'not compatible'.red);
return reject(errors.enrich(new Error('Update this tool targeting a version within the required range'), 'version test'));
}
});
},
print: () => {
let results = checkCompatibility();
console.log('version:'.gray, results.version.cyan);
console.log('range:'.gray, results.range.cyan);
console.log('compatible:'.gray, results.isCompatible ? 'true'.green : 'false'.red);
}
};
51 changes: 0 additions & 51 deletions lib/webpack/configs/yves.js

This file was deleted.

125 changes: 0 additions & 125 deletions lib/webpack/configs/zed.js

This file was deleted.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "antelope",
"version": "1.1.3",
"version": "2.0.0",
"description": "Spryker frontend automation tool",
"main": "antelope.js",
"preferGlobal": "true",
@@ -33,11 +33,12 @@
"file-loader": "^0.8.5",
"globby": "^4.0.0",
"graceful-fs": "^4.1.2",
"organizer-loader": "github:ilmente/organizer-loader",
"node-sass": "^3.4.2",
"organizer-loader": "github:ilmente/organizer-loader",
"ramda": "^0.18.0",
"resolve-url-loader": "^1.4.3",
"sass-loader": "^3.1.1",
"semver": "^5.1.0",
"shelljs": "^0.5.3",
"style-loader": "^0.13.0",
"url-loader": "^0.5.7",

0 comments on commit 423e229

Please sign in to comment.