Skip to content

Commit

Permalink
refactor(): Reduce length of runProfile() function.
Browse files Browse the repository at this point in the history
[BRANCH: master]
  • Loading branch information
thezimmee committed Apr 4, 2018
1 parent dbb9601 commit 447b46a
Showing 1 changed file with 125 additions and 86 deletions.
211 changes: 125 additions & 86 deletions lib/stakcss.js
Expand Up @@ -15,6 +15,10 @@ const timer = require('@brikcss/timer');
const merge = require('@brikcss/merge');
const globby = require('globby');

// ------------------
// Primary functions.
//

/**
* Main stakcss controller function.
*
Expand Down Expand Up @@ -49,102 +53,19 @@ function stakcss(config = {}) {
* Run a profile. Iterates through each stak in a profile and returns a promise for each.
*/
function runProfile(config = {}) {
const bundlePromises = [];
let bundlePromises = [];
timer.start('profile-' + config.id);
if (!config.hasWatcher) {
log.info(`Running profile \`${config.id}\`...`);
}
if (config.stakEachFile) {
config.source.forEach((filepath) => {
let output = config.output;
// Determine output path based on `root`.
if (config.stakEachFile) {
// Set full output path, replacing template placeholders.
output = path
.join(
path.dirname(config.output),
config.root ? path.relative(config.root, path.dirname(filepath)) : '',
path.basename(output)
)
.replace(/\[name\]/g, path.basename(filepath, path.extname(filepath)))
.replace(/\[ext\]/g, path.extname(filepath).replace('.', ''));
// Run rename callback.
if (typeof config.rename === 'function') {
output = config.rename(output, config);
}
// Make source path iterable.
filepath = [filepath];
}
// Run the stak.
bundlePromises.push(
bundleStak(
Object.assign({}, config, {
source: filepath,
output
})
)
);
});
bundlePromises = createStaksFromFiles(config);
} else {
bundlePromises.push(bundleStak(config));
}

// After all promises complete, save to output location.
return Promise.all(bundlePromises).then((results) => {
// Create return object.
const result = {
config: config,
all: results,
watcher: undefined,
success: false
};
// Notify user if no results or content was returned.
if (!results || !results.length) {
logError('[!!] Uh oh... no results were returned.', config, true);
} else if (!results[results.length - 1].content) {
log.error(
`[!!] No content was returned from profile \`${
config.id
}\`. Make sure source paths are correct.`
);
} else {
result.success = true;
result.config = Object.assign(result.config, {
content: results[results.length - 1].content
});
}
// Optionally watch the source and watchPath files.
if (config.watch && !config.hasWatcher) {
const chokidar = require('chokidar');
result.watcher = chokidar.watch(config.source.concat(config.watchPaths || []), {
// persistent: true,
// followSymlinks: true,
// disableGlobbing: true
alwaysStat: true
});
result.watcher
.on('change', () => {
config.content = '';
log.warn(`Running profile \`${config.id}\`...`);
return runProfile(config);
})
.on('error', (error) => logError(error, config))
.on('ready', () => {
config.hasWatcher = true;
log.error(`Watching profile \`${config.id}\`...`);
return config.watcher;
});
}
// Return the result object.
timer.stop('profile-' + config.id);
if (!config.hasWatcher && config.profiles && config.profiles.length > 1) {
log.warn(
`Completed profile \`${config.id}\` (${timer.duration('profile-' + config.id)}).`
);
}
timer.clear('profile-' + config.id);
return result;
});
return Promise.all(bundlePromises).then((results) => processResults(results, config));
}

/**
Expand Down Expand Up @@ -254,6 +175,124 @@ function createConfigProfiles(userConfig = {}) {
return config;
}

// -----------------
// Helper functions.
//

/**
* Create a "stak" from each file.
*
* @param {Object} config Configuration object.
* @return {Array} Array of promises. Each Promise is a stak to be bundled.
*/
function createStaksFromFiles(config = {}) {
const promises = [];
config.source.forEach((filepath) => {
let output = config.output;
// Determine output path based on `root`.
if (config.stakEachFile) {
// Set full output path, replacing template placeholders.
output = path
.join(
path.dirname(config.output),
config.root ? path.relative(config.root, path.dirname(filepath)) : '',
path.basename(output)
)
.replace(/\[name\]/g, path.basename(filepath, path.extname(filepath)))
.replace(/\[ext\]/g, path.extname(filepath).replace('.', ''));
// Run rename callback.
if (typeof config.rename === 'function') {
output = config.rename(output, config);
}
// Make source path iterable.
filepath = [filepath];
}
// Run the stak.
promises.push(
bundleStak(
Object.assign({}, config, {
source: filepath,
output
})
)
);
});
return promises;
}

/**
* Process profile results.
*
* @param {Array} results Results from Promise.all, where each promise is a bundled stak.
* @param {Object} config Original configuration object.
* @return {Object} Normalized result object.
*/
function processResults(results, config = {}) {
// Create return object.
const result = {
config,
all: results,
watcher: undefined,
success: false
};
// Notify user if no results or content was returned.
if (!results || !results.length) {
logError('[!!] Uh oh... no results were returned.', config, true);
} else if (!results[results.length - 1].content) {
log.error(
`[!!] No content was returned from profile \`${
config.id
}\`. Make sure source paths are correct.`
);
} else {
result.success = true;
result.config = Object.assign(result.config, {
content: results[results.length - 1].content
});
}
// Optionally watch the source and watchPath files.
if (config.watch && !config.hasWatcher) {
result.watcher = createWatcher(config);
}
// Return the result object.
timer.stop('profile-' + config.id);
if (!config.hasWatcher && config.profiles && config.profiles.length > 1) {
log.warn(`Completed profile \`${config.id}\` (${timer.duration('profile-' + config.id)}).`);
}
timer.clear('profile-' + config.id);
return result;
}

/**
* Create instance of chokidar to watch files and "restak" when a file changes.
*
* @param {Object} config Configuration object.
* @return {Object} Watcher, instance of chokidar.
*/
function createWatcher(config = {}) {
const chokidar = require('chokidar');
const watcher = chokidar.watch(config.source.concat(config.watchPaths || []), {
// persistent: true,
// followSymlinks: true,
// disableGlobbing: true
alwaysStat: true
});
watcher
.on('change', () => {
config.content = '';
log.warn(`Running profile \`${config.id}\`...`);
return runProfile(config);
})
.on('error', (error) => logError(error, config))
.on('ready', () => {
config.hasWatcher = true;
log.error(`Watching profile \`${config.id}\`...`);
return config.watcher;
});

return watcher;
}

/**
* Get config file with cosmiconfig.
*/
Expand Down

0 comments on commit 447b46a

Please sign in to comment.