<commit_before>/**
 * Concatenate installed Bower packages
 *
 * @author <NAME> (http://sapegin.me)
 */


/*jshint node:true */
module.exports = function(grunt) {
	'use strict';

	var path = require('path');
	var fs = require('fs');
	var bower = require('bower');
	var detective = require('detective');
	var _ = require('lodash');
	_.str = require('underscore.string');
	var dependencyTools = require('../lib/dependencyTools');

	grunt.registerMultiTask('bower_concat', 'Concatenate installed Bower packages.', function() {
		// Options
		this.requiresConfig([this.name, this.target, 'dest'].join('.'));
		var dest = this.data.dest;
		var includes = ensureArray(this.data.include || []);
		var excludes = ensureArray(this.data.exclude || []);
		var dependencies = this.data.dependencies || {};
		var bowerOptions = this.data.bowerOptions || {};

		var done = this.async();

		bowerJavaScripts(function(bowerFiles) {
			// Concatenate
			var src = bowerFiles.join(grunt.util.linefeed);

			// Write result
			grunt.file.write(dest, src);
			grunt.log.writeln('File "' + dest + '" created.');

			done();
		}, includes, excludes, dependencies, bowerOptions);
	});

	function bowerJavaScripts(allDone, includes, excludes, dependencies, bowerOptions) {
		grunt.util.async.parallel({
			map: bowerList('map', bowerOptions),
			components: bowerList('paths', bowerOptions)
		}, function(err, lists) {
			// Ensure all manual defined dependencies are contained in an array
			if (dependencies) {
				_.map(dependencies, function(value, key) {
					dependencies[key] = ensureArray(value);
				});
			}

			// Resolve dependency graph to ensure correct order of components when concat them
			var resolvedDependencies = resolveDependencies(lists.map, dependencies);

			// List of main files
			var jsFiles = {};
			_.each(lists.components, function(component, name) {
				if (includes.length && _.indexOf(includes, name) === -1) return;
				if (excludes.length && _.indexOf(excludes, name) !== -1) return;

				var mainFiles = findMainFiles(name, component);
				if (mainFiles) {
					jsFiles[name] = mainFiles.map(function(file) {
						return grunt.file.read(file);
					});
				}
				else {
					// Try to find npm (?) package: packages/_name_/lib/main.js
					var pkg = getNpmPackage(name, component);
					if (pkg) {
						jsFiles[name] = pkg;
					}
					else {
						grunt.fatal('Bower: can’t detect main file for "' + name + '" component.' +
							'You should add it manually to concat task and exclude from bower task build.');
					}
				}
			});

			// Gather JavaScript files by respecting the order of resolved dependencies
			var modules = [];
			_.each(resolvedDependencies, function(name) {
				if (jsFiles[name]) {
					modules = modules.concat(jsFiles[name]);
				}
			});

			allDone(modules);
		});
	}

	// Should be used inside grunt.util.async.parallel
	function bowerList(kind, bowerOptions) {
		return function(callback) {
			var params = _.extend({}, bowerOptions);
			params[kind] = true;

			bower.commands.list(params)
				.on('error', grunt.fatal.bind(grunt.fail))
				.on('end', function(data) {
					callback(null, data);  // null means "no error" for async.parallel
				});
		};
	}

	function resolveDependencies(map, manualDependencies) {
		var dependencyGraph = manualDependencies || {};
		var resolved = [];
		var unresolved = [];

		// Build dependency graph:
		if (map.dependencies) {
			dependencyTools.buildDependencyGraph(
				undefined,  // First recursion without a start value
				map.dependencies,
				dependencyGraph
			);

			// Flatten/resolve the dependency tree:
			dependencyTools.resolveDependencyGraph(
				undefined,  // First recursion without a start value
				resolved,
				unresolved,
				dependencyGraph
			);
		}

		return resolved;
	}

	function findMainFiles(name, component) {
		// Bower knows main JS file?
		var mainFiles = ensureArray(component);
		var mainJSFiles = _.filter(mainFiles, isJsFile);
		if (mainJSFiles) {
			return mainJSFiles;
		}

		// Try to find main JS file
		var jsFiles = grunt.file.expand(path.join(component, '*.js'));
		if (jsFiles.length === 1) {
			// Only one JS file: no doubt it’s main file
			return jsFiles;
		}
		else {
			// More than one JS file: try to guess
			return [guessBestFile(name, jsFiles)];
		}
	}

	function getNpmPackage(name, component) {
		var pkg = findPackage(name, component);
		if (!pkg) return null;

		var mainjs = path.join(pkg, 'lib/main.js');
		if (!fs.existsSync(mainjs)) return null;<commit_msg>multiple files: fixed error checking length<commit_after>/**
 * Concatenate installed Bower packages
 *
 * @author <NAME> (http://sapegin.me)
 */


/*jshint node:true */
module.exports = function(grunt) {
	'use strict';

	var path = require('path');
	var fs = require('fs');
	var bower = require('bower');
	var detective = require('detective');
	var _ = require('lodash');
	_.str = require('underscore.string');
	var dependencyTools = require('../lib/dependencyTools');

	grunt.registerMultiTask('bower_concat', 'Concatenate installed Bower packages.', function() {
		// Options
		this.requiresConfig([this.name, this.target, 'dest'].join('.'));
		var dest = this.data.dest;
		var includes = ensureArray(this.data.include || []);
		var excludes = ensureArray(this.data.exclude || []);
		var dependencies = this.data.dependencies || {};
		var bowerOptions = this.data.bowerOptions || {};

		var done = this.async();

		bowerJavaScripts(function(bowerFiles) {
			// Concatenate
			var src = bowerFiles.join(grunt.util.linefeed);

			// Write result
			grunt.file.write(dest, src);
			grunt.log.writeln('File "' + dest + '" created.');

			done();
		}, includes, excludes, dependencies, bowerOptions);
	});

	function bowerJavaScripts(allDone, includes, excludes, dependencies, bowerOptions) {
		grunt.util.async.parallel({
			map: bowerList('map', bowerOptions),
			components: bowerList('paths', bowerOptions)
		}, function(err, lists) {
			// Ensure all manual defined dependencies are contained in an array
			if (dependencies) {
				_.map(dependencies, function(value, key) {
					dependencies[key] = ensureArray(value);
				});
			}

			// Resolve dependency graph to ensure correct order of components when concat them
			var resolvedDependencies = resolveDependencies(lists.map, dependencies);

			// List of main files
			var jsFiles = {};
			_.each(lists.components, function(component, name) {
				if (includes.length && _.indexOf(includes, name) === -1) return;
				if (excludes.length && _.indexOf(excludes, name) !== -1) return;

				var mainFiles = findMainFiles(name, component);
				if (mainFiles) {
					jsFiles[name] = mainFiles.map(function(file) {
						return grunt.file.read(file);
					});
				}
				else {
					// Try to find npm (?) package: packages/_name_/lib/main.js
					var pkg = getNpmPackage(name, component);
					if (pkg) {
						jsFiles[name] = pkg;
					}
					else {
						grunt.fatal('Bower: can’t detect main file for "' + name + '" component.' +
							'You should add it manually to concat task and exclude from bower task build.');
					}
				}
			});

			// Gather JavaScript files by respecting the order of resolved dependencies
			var modules = [];
			_.each(resolvedDependencies, function(name) {
				if (jsFiles[name]) {
					modules = modules.concat(jsFiles[name]);
				}
			});

			allDone(modules);
		});
	}

	// Should be used inside grunt.util.async.parallel
	function bowerList(kind, bowerOptions) {
		return function(callback) {
			var params = _.extend({}, bowerOptions);
			params[kind] = true;

			bower.commands.list(params)
				.on('error', grunt.fatal.bind(grunt.fail))
				.on('end', function(data) {
					callback(null, data);  // null means "no error" for async.parallel
				});
		};
	}

	function resolveDependencies(map, manualDependencies) {
		var dependencyGraph = manualDependencies || {};
		var resolved = [];
		var unresolved = [];

		// Build dependency graph:
		if (map.dependencies) {
			dependencyTools.buildDependencyGraph(
				undefined,  // First recursion without a start value
				map.dependencies,
				dependencyGraph
			);

			// Flatten/resolve the dependency tree:
			dependencyTools.resolveDependencyGraph(
				undefined,  // First recursion without a start value
				resolved,
				unresolved,
				dependencyGraph
			);
		}

		return resolved;
	}

	function findMainFiles(name, component) {
		// Bower knows main JS file?
		var mainFiles = ensureArray(component);
		var mainJSFiles = _.filter(mainFiles, isJsFile);
		if (mainJSFiles.length) {
			return mainJSFiles;
		}

		// Try to find main JS file
		var jsFiles = grunt.file.expand(path.join(component, '*.js'));
		if (jsFiles.length === 1) {
			// Only one JS file: no doubt it’s main file
			return jsFiles;
		}
		else {
			// More than one JS file: try to guess
			return [guessBestFile(name, jsFiles)];
		}
	}

	function getNpmPackage(name, component) {
		var pkg = findPackage(name, component);
		if (!pkg) return null;

		var mainjs = path.join(pkg, 'lib/main.js');
		if (!fs.existsSync(mainjs)) return null;
{'fraction_non_alphanumeric': 0.1377027474346243, 'fraction_numerical': 0.0006620324395895399, 'mean_word_length': 3.4366128242780225, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4401795', 'n_tokens_mistral': 3329, 'n_tokens_neox': 2745, 'n_words': 722}