From 8bf8cff43670856137b9d789c8ce170487ca621b Mon Sep 17 00:00:00 2001
From: Juan Cruz Viotti <juanchiviotti@gmail.com>
Date: Fri, 28 Nov 2014 10:30:07 -0400
Subject: [PATCH] Implement pluginLoader.readPluginsDirectory()

---
 lib/plugin-loader/plugin-loader.coffee      | 25 ++++++++-
 lib/plugin-loader/plugin-loader.spec.coffee | 56 +++++++++++++++++++++
 lib/resin/config.coffee                     |  2 +
 3 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/lib/plugin-loader/plugin-loader.coffee b/lib/plugin-loader/plugin-loader.coffee
index 97d40139..a7172c16 100644
--- a/lib/plugin-loader/plugin-loader.coffee
+++ b/lib/plugin-loader/plugin-loader.coffee
@@ -13,7 +13,7 @@ exports.use = (plugin) ->
 exports.loadPackage = (pluginPath, callback) ->
 	pluginPackageJSON = path.join(pluginPath, 'package.json')
 
-	async.waterfall [
+	async.waterfall([
 
 		(callback) ->
 			fs.exists pluginPackageJSON, (exists) ->
@@ -53,4 +53,25 @@ exports.loadPackage = (pluginPath, callback) ->
 
 			return callback(null, mainFile)
 
-	], callback
+	], callback)
+
+isDirectory = (directory, callback) ->
+	fs.stat directory, (error, stats) ->
+		return callback(false) if error?
+		return callback(stats.isDirectory())
+
+exports.readPluginsDirectory = (directory, callback) ->
+
+	async.waterfall([
+
+		(callback) ->
+			fs.readdir(directory, callback)
+
+		(plugins, callback) ->
+			fullPathPlugins = _.map plugins, (plugin) ->
+				return path.join(directory, plugin)
+
+			async.filter fullPathPlugins, isDirectory, (results) ->
+				return callback(null, results)
+
+	], callback)
diff --git a/lib/plugin-loader/plugin-loader.spec.coffee b/lib/plugin-loader/plugin-loader.spec.coffee
index 3e01b9db..a6337f3c 100644
--- a/lib/plugin-loader/plugin-loader.spec.coffee
+++ b/lib/plugin-loader/plugin-loader.spec.coffee
@@ -1,7 +1,9 @@
 _ = require('lodash')
 chai = require('chai')
 chai.use(require('sinon-chai'))
+chai.use(require('chai-things'))
 expect = chai.expect
+path = require('path')
 sinon = require('sinon')
 mock = require('../../tests/utils/mock')
 resin = require('../resin')
@@ -33,6 +35,24 @@ FILESYSTEM =
 				main: 'app.js'
 			'app.js': 'module.exports = {};'
 
+FILESYSTEM.pluginsDirectory =
+	name: 'pluginsDirectory'
+	contents:
+		firstPlugin: FILESYSTEM.validPackage.contents
+		secondPlugin: FILESYSTEM.validPackage.contents
+		thirdPlugin: FILESYSTEM.validPackage.contents
+FILESYSTEM.invalidPluginsDirectory =
+	name: 'invalidPluginsDirectory'
+	contents:
+		firstPlugin: FILESYSTEM.validPackage.contents
+		secondPlugin: FILESYSTEM.validPackage.contents
+		thirdPlugin: 'Hello World'
+
+compareArrays = (arr1, arr2) ->
+	expect(arr1.length).to.equal(arr2.length)
+	for item in arr2
+		expect(arr1).to.include(item)
+
 describe 'Plugin Loader:', ->
 
 	beforeEach ->
@@ -100,3 +120,39 @@ describe 'Plugin Loader:', ->
 				expect(error).to.be.an.instanceof(Error)
 				expect(plugin).to.not.exist
 				done()
+
+	describe '#readPluginsDirectory()', ->
+
+		it 'should fail if input is not a directory', (done) ->
+			pluginsDirectory = FILESYSTEM.text.name
+			pluginLoader.readPluginsDirectory pluginsDirectory, (error, plugins) ->
+				expect(error).to.be.an.instanceof(Error)
+				expect(plugins).to.not.exist
+				done()
+
+		it 'should return a list of all files inside plugins directory', (done) ->
+			pluginsDirectory = FILESYSTEM.pluginsDirectory
+			pluginLoader.readPluginsDirectory pluginsDirectory.name, (error, plugins) ->
+				expect(error).to.not.exist
+
+				expectedPlugins = _.keys(pluginsDirectory.contents)
+
+				expectedPlugins = _.map expectedPlugins, (value) ->
+					return path.join(pluginsDirectory.name, value)
+
+				compareArrays(plugins, expectedPlugins)
+				done()
+
+		it 'should return omit files inside plugins directory', (done) ->
+			pluginsDirectory = FILESYSTEM.invalidPluginsDirectory
+			pluginLoader.readPluginsDirectory pluginsDirectory.name, (error, plugins) ->
+				expect(error).to.not.exist
+
+				expectedPlugins = _.keys _.omit pluginsDirectory.contents, (value, key) ->
+					return _.isString(value)
+
+				expectedPlugins = _.map expectedPlugins, (value) ->
+					return path.join(pluginsDirectory.name, value)
+
+				compareArrays(plugins, expectedPlugins)
+				done()
diff --git a/lib/resin/config.coffee b/lib/resin/config.coffee
index ee143d5e..d4ac7db6 100644
--- a/lib/resin/config.coffee
+++ b/lib/resin/config.coffee
@@ -13,6 +13,8 @@ config =
 	dataPrefix: path.join(process.env.HOME, '.resin')
 	sshKeyWidth: 43
 
+config.pluginsDirectory = path.join(config.dataPrefix, 'plugins')
+
 config.urls =
 	signup: '/signup'
 	preferences: '/preferences'