From f8470287c1c20785fd4bdacf635bf2c41f2d7562 Mon Sep 17 00:00:00 2001
From: Juan Cruz Viotti <juanchiviotti@gmail.com>
Date: Thu, 1 Oct 2015 10:39:36 -0400
Subject: [PATCH] Separate general help per topic relevance

Only list primary commands by default, unless a `--verbose` option is
passed to list the additional ones.

Fixes: https://github.com/resin-io/resin-cli/issues/101
---
 build/actions/app.js      |  3 +++
 build/actions/auth.js     |  1 +
 build/actions/device.js   |  3 +++
 build/actions/help.js     | 33 ++++++++++++++++++++++++++++++---
 build/actions/logs.js     |  1 +
 build/actions/wizard.js   |  1 +
 build/utils/plugins.js    |  1 +
 lib/actions/app.coffee    |  3 +++
 lib/actions/auth.coffee   |  1 +
 lib/actions/device.coffee |  3 +++
 lib/actions/help.coffee   | 28 ++++++++++++++++++++++++++--
 lib/actions/logs.coffee   |  1 +
 lib/actions/wizard.coffee |  1 +
 lib/utils/plugins.coffee  |  1 +
 14 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/build/actions/app.js b/build/actions/app.js
index cf042423..047dcd4c 100644
--- a/build/actions/app.js
+++ b/build/actions/app.js
@@ -30,6 +30,7 @@
       }
     ],
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return resin.models.application.has(params.name).then(function(hasApplication) {
         if (hasApplication) {
@@ -51,6 +52,7 @@
     description: 'list all applications',
     help: 'Use this command to list all your applications.\n\nNotice this command only shows the most important bits of information for each app.\nIf you want detailed information, use resin app <name> instead.\n\nExamples:\n\n	$ resin apps',
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return resin.models.application.getAll().then(function(applications) {
         return console.log(visuals.table.horizontal(applications, ['id', 'app_name', 'device_type', 'online_devices', 'devices_length']));
@@ -63,6 +65,7 @@
     description: 'list a single application',
     help: 'Use this command to show detailed information for a single application.\n\nExamples:\n\n	$ resin app MyApp',
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return resin.models.application.get(params.name).then(function(application) {
         console.log(visuals.table.vertical(application, ["$" + application.app_name + "$", 'id', 'device_type', 'git_repository', 'commit']));
diff --git a/build/actions/auth.js b/build/actions/auth.js
index 43e20943..ae78287d 100644
--- a/build/actions/auth.js
+++ b/build/actions/auth.js
@@ -23,6 +23,7 @@
     signature: 'login [token]',
     description: 'login to resin.io',
     help: 'Use this command to login to your resin.io account.\n\nTo login, you need your token, which is accesible from the preferences page.\n\nExamples:\n\n	$ resin login\n	$ resin login "eyJ0eXAiOiJKV1Qi..."',
+    primary: true,
     action: function(params, options, done) {
       return resin.settings.get('dashboardUrl').then(function(dashboardUrl) {
         return url.resolve(dashboardUrl, '/preferences');
diff --git a/build/actions/device.js b/build/actions/device.js
index 76495f7f..d9cd1be4 100644
--- a/build/actions/device.js
+++ b/build/actions/device.js
@@ -33,6 +33,7 @@
     help: 'Use this command to list all devices that belong to you.\n\nYou can filter the devices by application by using the `--application` option.\n\nExamples:\n\n	$ resin devices\n	$ resin devices --application MyApp\n	$ resin devices --app MyApp\n	$ resin devices -a MyApp',
     options: [commandOptions.optionalApplication],
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return Promise["try"](function() {
         if (options.application != null) {
@@ -50,6 +51,7 @@
     description: 'list a single device',
     help: 'Use this command to show information about a single device.\n\nExamples:\n\n	$ resin device 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9',
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return resin.models.device.get(params.uuid).then(function(device) {
         if (device.last_seen == null) {
@@ -133,6 +135,7 @@
     help: 'Use this command to download the OS image of a certain application and write it to an SD Card.\n\nNotice this command may ask for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nExamples:\n\n	$ resin device init\n	$ resin device init --application MyApp',
     options: [commandOptions.optionalApplication, commandOptions.yes],
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return Promise["try"](function() {
         if (options.application != null) {
diff --git a/build/actions/help.js b/build/actions/help.js
index db720511..1624810b 100644
--- a/build/actions/help.js
+++ b/build/actions/help.js
@@ -36,13 +36,31 @@
   };
 
   general = function(params, options, done) {
-    var commands;
+    var commands, groupedCommands;
     console.log('Usage: resin [COMMAND] [OPTIONS]\n');
-    console.log('Commands:\n');
+    console.log('Primary commands:\n');
     commands = _.reject(capitano.state.commands, function(command) {
       return command.isWildcard();
     });
-    print(parse(commands));
+    groupedCommands = _.groupBy(commands, function(command) {
+      if (command.plugin) {
+        return 'plugins';
+      } else if (command.primary) {
+        return 'primary';
+      }
+      return 'secondary';
+    });
+    print(parse(groupedCommands.primary));
+    if (options.verbose) {
+      if (!_.isEmpty(groupedCommands.plugins)) {
+        console.log('\nInstalled plugins:\n');
+        print(parse(groupedCommands.plugins));
+      }
+      console.log('\nAdditional commands:\n');
+      print(parse(groupedCommands.secondary));
+    } else {
+      console.log('\nRun `resin help --verbose` to list additional commands');
+    }
     if (!_.isEmpty(capitano.state.globalOptions)) {
       console.log('\nGlobal Options:\n');
       print(parse(capitano.state.globalOptions));
@@ -76,6 +94,15 @@
     signature: 'help [command...]',
     description: 'show help',
     help: 'Get detailed help for an specific command.\n\nExamples:\n\n	$ resin help apps\n	$ resin help os download',
+    primary: true,
+    options: [
+      {
+        signature: 'verbose',
+        description: 'show additional commands',
+        boolean: true,
+        alias: 'v'
+      }
+    ],
     action: function(params, options, done) {
       if (params.command != null) {
         return command(params, options, done);
diff --git a/build/actions/logs.js b/build/actions/logs.js
index d731e26f..f7ec87e2 100644
--- a/build/actions/logs.js
+++ b/build/actions/logs.js
@@ -18,6 +18,7 @@
       }
     ],
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       var promise;
       promise = resin.logs.history(params.uuid).each(function(line) {
diff --git a/build/actions/wizard.js b/build/actions/wizard.js
index 3ccd91a6..c1a33636 100644
--- a/build/actions/wizard.js
+++ b/build/actions/wizard.js
@@ -18,6 +18,7 @@
     description: 'getting started with resin.io',
     help: 'Use this command to run a friendly wizard to get started with resin.io.\n\nThe wizard will guide you through:\n\n	- Create an application.\n	- Initialise an SDCard with the resin.io operating system.\n	- Associate an existing project directory with your resin.io application.\n	- Push your project to your devices.\n\nExamples:\n\n	$ sudo resin quickstart\n	$ sudo resin quickstart MyApp',
     permission: 'user',
+    primary: true,
     action: function(params, options, done) {
       return Promise["try"](function() {
         if (params.name != null) {
diff --git a/build/utils/plugins.js b/build/utils/plugins.js
index 97527614..5cc6afeb 100644
--- a/build/utils/plugins.js
+++ b/build/utils/plugins.js
@@ -11,6 +11,7 @@
     return nplugm.list(regex).map(function(plugin) {
       var command;
       command = require(plugin);
+      command.plugin = true;
       if (!_.isArray(command)) {
         return capitano.command(command);
       }
diff --git a/lib/actions/app.coffee b/lib/actions/app.coffee
index fa6a4a98..c3158006 100644
--- a/lib/actions/app.coffee
+++ b/lib/actions/app.coffee
@@ -34,6 +34,7 @@ exports.create =
 		}
 	]
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 
 		# Validate the the application name is available
@@ -64,6 +65,7 @@ exports.list =
 			$ resin apps
 	'''
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		resin.models.application.getAll().then (applications) ->
 			console.log visuals.table.horizontal applications, [
@@ -86,6 +88,7 @@ exports.info =
 			$ resin app MyApp
 	'''
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		resin.models.application.get(params.name).then (application) ->
 			console.log visuals.table.vertical application, [
diff --git a/lib/actions/auth.coffee b/lib/actions/auth.coffee
index a885c7e0..f07c5e8d 100644
--- a/lib/actions/auth.coffee
+++ b/lib/actions/auth.coffee
@@ -21,6 +21,7 @@ exports.login	=
 			$ resin login
 			$ resin login "eyJ0eXAiOiJKV1Qi..."
 	'''
+	primary: true
 	action: (params, options, done) ->
 		resin.settings.get('dashboardUrl').then (dashboardUrl) ->
 			return url.resolve(dashboardUrl, '/preferences')
diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee
index 4c1b400e..d3edd5ba 100644
--- a/lib/actions/device.coffee
+++ b/lib/actions/device.coffee
@@ -30,6 +30,7 @@ exports.list =
 	'''
 	options: [ commandOptions.optionalApplication ]
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		Promise.try ->
 			if options.application?
@@ -59,6 +60,7 @@ exports.info =
 			$ resin device 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9
 	'''
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		resin.models.device.get(params.uuid).then (device) ->
 
@@ -189,6 +191,7 @@ exports.init =
 		commandOptions.yes
 	]
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		Promise.try ->
 			return options.application if options.application?
diff --git a/lib/actions/help.coffee b/lib/actions/help.coffee
index 55476d33..28782f26 100644
--- a/lib/actions/help.coffee
+++ b/lib/actions/help.coffee
@@ -30,14 +30,31 @@ print = (data) ->
 
 general = (params, options, done) ->
 	console.log('Usage: resin [COMMAND] [OPTIONS]\n')
-	console.log('Commands:\n')
+	console.log('Primary commands:\n')
 
 	# We do not want the wildcard command
 	# to be printed in the help screen.
 	commands = _.reject capitano.state.commands, (command) ->
 		return command.isWildcard()
 
-	print(parse(commands))
+	groupedCommands = _.groupBy commands, (command) ->
+		if command.plugin
+			return 'plugins'
+		else if command.primary
+			return 'primary'
+		return 'secondary'
+
+	print(parse(groupedCommands.primary))
+
+	if options.verbose
+		if not _.isEmpty(groupedCommands.plugins)
+			console.log('\nInstalled plugins:\n')
+			print(parse(groupedCommands.plugins))
+
+		console.log('\nAdditional commands:\n')
+		print(parse(groupedCommands.secondary))
+	else
+		console.log('\nRun `resin help --verbose` to list additional commands')
 
 	if not _.isEmpty(capitano.state.globalOptions)
 		console.log('\nGlobal Options:\n')
@@ -76,6 +93,13 @@ exports.help =
 			$ resin help apps
 			$ resin help os download
 	'''
+	primary: true
+	options: [
+		signature: 'verbose'
+		description: 'show additional commands'
+		boolean: true
+		alias: 'v'
+	]
 	action: (params, options, done) ->
 		if params.command?
 			command(params, options, done)
diff --git a/lib/actions/logs.coffee b/lib/actions/logs.coffee
index 2b29afb2..e6adb28a 100644
--- a/lib/actions/logs.coffee
+++ b/lib/actions/logs.coffee
@@ -29,6 +29,7 @@ module.exports =
 		}
 	]
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		promise = resin.logs.history(params.uuid).each (line) ->
 			console.log(line.message)
diff --git a/lib/actions/wizard.coffee b/lib/actions/wizard.coffee
index 0a7f15a2..ed29d162 100644
--- a/lib/actions/wizard.coffee
+++ b/lib/actions/wizard.coffee
@@ -24,6 +24,7 @@ exports.wizard =
 			$ sudo resin quickstart MyApp
 	'''
 	permission: 'user'
+	primary: true
 	action: (params, options, done) ->
 		Promise.try ->
 			return if params.name?
diff --git a/lib/utils/plugins.coffee b/lib/utils/plugins.coffee
index d6f6c06f..f5668387 100644
--- a/lib/utils/plugins.coffee
+++ b/lib/utils/plugins.coffee
@@ -5,6 +5,7 @@ capitano = require('capitano')
 exports.register = (regex) ->
 	nplugm.list(regex).map (plugin) ->
 		command = require(plugin)
+		command.plugin = true
 		return capitano.command(command) if not _.isArray(command)
 		return _.each(command, capitano.command)
 	.catch (error) ->