[Yum-devel] [PATCH] yum help and --help cleanup

James Bowes jbowes at redhat.com
Fri Jan 25 00:32:06 UTC 2008


Hi all:

Attached are two patches, the first implements the 'help' subcommand, so
you can do:

$> yum help install
install PACKAGE...

Install a package or packages on your system
$>

The second uses these help strings to format --help a little better (IMO
at least).

I wrote up some summaries for all the commands, but it would also be
nice to have some longer help messages, probably with a getHelp() method
on YumCommand.

What do people think?

-James
-------------- next part --------------
From 6856757535ad4af0ba636c12968b4e7d37c149ee Mon Sep 17 00:00:00 2001
From: James Bowes <jbowes at redhat.com>
Date: Thu, 24 Jan 2008 18:54:04 -0500
Subject: [PATCH] Add a help command, to display command usage

---
 cli.py         |    1 +
 yumcommands.py |  162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/cli.py b/cli.py
index 581776a..5d6f160 100644
--- a/cli.py
+++ b/cli.py
@@ -92,6 +92,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         self.registerCommand(yumcommands.ShellCommand())
         self.registerCommand(yumcommands.DepListCommand())
         self.registerCommand(yumcommands.RepoListCommand())
+        self.registerCommand(yumcommands.HelpCommand())
 
     def registerCommand(self, command):
         for name in command.getNames():
diff --git a/yumcommands.py b/yumcommands.py
index 7286f04..bc22a3b 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -121,7 +121,16 @@ class YumCommand:
         return []
 
     def getUsage(self):
-        return ''
+        """
+        @return: A usage string for the command, including arguments.
+        """
+        return "No usage for command"
+
+    def getSummary(self):
+        """
+        @return: A one line summary of what the command does.
+        """
+        return "No summary for command"
     
     def doCheck(self, base, basecmd, extcmds):
         pass
@@ -142,6 +151,12 @@ class InstallCommand(YumCommand):
     def getNames(self):
         return ['install']
 
+    def getUsage(self):
+        return "PACKAGE..."
+
+    def getSummary(self):
+        return "Install a package or packages on your system"
+    
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGPGKey(base)
@@ -159,6 +174,12 @@ class UpdateCommand(YumCommand):
     def getNames(self):
         return ['update']
 
+    def getUsage(self):
+        return "PACKAGE..."
+
+    def getSummary(self):
+        return "Update a package or packages on your system"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGPGKey(base)
@@ -175,6 +196,12 @@ class InfoCommand(YumCommand):
     def getNames(self):
         return ['info', 'list']
 
+    def getUsage(self):
+        return "[PACKAGE|all|installed|updates|extras|obsoletes|recent]"
+
+    def getSummary(self):
+        return "Display details about a package or group of packages"
+
     def doCommand(self, base, basecmd, extcmds):
         try:
             ypl = base.returnPkgLists(extcmds)
@@ -213,6 +240,12 @@ class EraseCommand(YumCommand):
     def getNames(self):
         return ['erase', 'remove']
 
+    def getUsage(self):
+        return "PACKAGE..."
+
+    def getSummary(self):
+        return "Remove a package or packages from your system"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkPackageArg(base, basecmd, extcmds)
@@ -246,6 +279,12 @@ class GroupListCommand(GroupCommand):
     def getNames(self):
         return ['grouplist']
 
+    def getUsage(self):
+        return ""
+
+    def getSummary(self):
+        return "List available package groups"
+    
     def doCommand(self, base, basecmd, extcmds):
         GroupCommand.doCommand(self, base, basecmd, extcmds)
         return base.returnGroupLists(extcmds)
@@ -257,6 +296,12 @@ class GroupInstallCommand(GroupCommand):
     def getNames(self):
         return ['groupinstall', 'groupupdate']
 
+    def getUsage(self):
+        return "GROUP..."
+
+    def getSummary(self):
+        return "Install the packages in a group on your system"
+    
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGPGKey(base)
@@ -273,6 +318,12 @@ class GroupRemoveCommand(GroupCommand):
     def getNames(self):
         return ['groupremove', 'grouperase']
 
+    def getUsage(self):
+        return "GROUP..."
+
+    def getSummary(self):
+        return "Remove the packages in a group from your system"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGroupArg(base, basecmd, extcmds)
@@ -291,6 +342,12 @@ class GroupInfoCommand(GroupCommand):
     def getNames(self):
         return ['groupinfo']
 
+    def getUsage(self):
+        return "GROUP..."
+
+    def getSummary(self):
+        return "Display details about a package group"
+
     def doCheck(self, base, basecmd, extcmds):
         checkGroupArg(base, basecmd, extcmds)
 
@@ -309,6 +366,12 @@ class MakeCacheCommand(YumCommand):
     def getNames(self):
         return ['makecache']
 
+    def getUsage(self):
+        return ""
+
+    def getSummary(self):
+        return "Generate the metadata cache"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
 
@@ -336,6 +399,12 @@ class CleanCommand(YumCommand):
     def getNames(self):
         return ['clean']
 
+    def getUsage(self):
+        return "[headers|packages|metadata|dbcache|plugins|all]"
+
+    def getSummary(self):
+        return "Remove cached data"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkCleanArg(base, basecmd, extcmds)
@@ -351,6 +420,12 @@ class ProvidesCommand(YumCommand):
     def getNames(self):
         return ['provides', 'whatprovides']
 
+    def getUsage(self):
+        return "SOME_STRING"
+    
+    def getSummary(self):
+        return "Find what package provides the given value"
+
     def doCheck(self, base, basecmd, extcmds):
         checkItemArg(base, basecmd, extcmds)
 
@@ -365,6 +440,12 @@ class CheckUpdateCommand(YumCommand):
     def getNames(self):
         return ['check-update']
 
+    def getUsage(self):
+        return "[PACKAGE...]"
+
+    def getSummary(self):
+        return "Check for available package updates"
+
     def doCommand(self, base, basecmd, extcmds):
         base.extcmds.insert(0, 'updates')
         result = 0
@@ -382,6 +463,12 @@ class SearchCommand(YumCommand):
     def getNames(self):
         return ['search']
 
+    def getUsage(self):
+        return "SOME_STRING"
+
+    def getSummary(self):
+        return "Search package details for the given string"
+
     def doCheck(self, base, basecmd, extcmds):
         checkItemArg(base, basecmd, extcmds)
 
@@ -399,6 +486,12 @@ class UpgradeCommand(YumCommand):
     def getNames(self):
         return ['upgrade']
 
+    def getUsage(self):
+        return 'PACKAGE...'
+
+    def getSummary(self):
+        return "Update packages taking obsoletes into account"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGPGKey(base)
@@ -416,6 +509,12 @@ class LocalInstallCommand(YumCommand):
     def getNames(self):
         return ['localinstall', 'localupdate']
 
+    def getUsage(self):
+        return "FILE"
+
+    def getSummary(self):
+        return "Install a local RPM"
+
     def doCheck(self, base, basecmd, extcmds):
         checkRootUID(base)
         checkGPGKey(base)
@@ -438,6 +537,12 @@ class ResolveDepCommand(YumCommand):
     def getNames(self):
         return ['resolvedep']
 
+    def getUsage(self):
+        return "DEPENDENCY"
+
+    def getSummary(self):
+        return "Determine which package provides the given dependency"
+
     def doCommand(self, base, basecmd, extcmds):
         base.logger.debug("Searching Packages for Dependency:")
         try:
@@ -449,6 +554,12 @@ class ShellCommand(YumCommand):
     def getNames(self):
         return ['shell']
 
+    def getUsage(self):
+        return "[FILENAME]"
+
+    def getSummary(self):
+        return "Run an interactive yum shell"
+
     def doCheck(self, base, basecmd, extcmds):
         checkShellArg(base, basecmd, extcmds)
 
@@ -467,6 +578,12 @@ class DepListCommand(YumCommand):
     def getNames(self):
         return ['deplist']
 
+    def getUsage(self):
+        return 'PACKAGE...'
+
+    def getSummary(self):
+        return "List a package's dependencies"
+
     def doCheck(self, base, basecmd, extcmds):
         checkPackageArg(base, basecmd, extcmds)
 
@@ -478,13 +595,16 @@ class DepListCommand(YumCommand):
           return 1, [str(e)]
 
 
-class RepoListCommand:
-    usage = 'repolist [all|enabled|disabled]'
+class RepoListCommand(YumCommand):
+    
     def getNames(self):
         return ('repolist',)
 
     def getUsage(self):
-        return usage
+        return '[all|enabled|disabled]'
+
+    def getSummary(self):
+        return 'Display the configured software repositories'
 
     def doCheck(self, base, basecmd, extcmds):
         if len(extcmds) == 0:
@@ -517,4 +637,36 @@ class RepoListCommand:
 
     def needTs(self, base, basecmd, extcmds):
         return False
-    
+
+
+class HelpCommand(YumCommand):
+
+    def getNames(self):
+        return ['help']
+
+    def getUsage(self):
+        return "COMMAND"
+
+    def getSummary(self):
+        return "Display a helpful usage message"
+
+    def doCheck(self, base, basecmd, extcmds):
+        if len(extcmds) == 0:
+            base.usage()
+            raise cli.CliError
+        elif len(extcmds) > 1 or extcmds[0] not in base.yum_cli_commands:
+            base.usage()
+            raise cli.CliError
+
+    def doCommand(self, base, basecmd, extcmds):
+        if base.yum_cli_commands.has_key(extcmds[0]):
+            command = base.yum_cli_commands[extcmds[0]]
+            canonical_name = command.getNames()[0]
+            # XXX need detailed help here, too
+            usagestr = "%s %s\n\n%s" % (canonical_name, command.getUsage(),
+                    command.getSummary())
+            base.verbose_logger.log(logginglevels.INFO_2, usagestr)
+        return 0, []
+
+    def needTs(self, base, basecmd, extcmds):
+        return False
-- 
1.5.4.rc4.1142.gf5a97

-------------- next part --------------
From ef87f64e34d8deb3ede0ab62d8e38f7df685e3f4 Mon Sep 17 00:00:00 2001
From: James Bowes <jbowes at redhat.com>
Date: Thu, 24 Jan 2008 19:23:34 -0500
Subject: [PATCH] Display subcommand summaries on --help

--help used to output subcommand names on the same line. Instead format
them one per line, along with their summary string.
---
 cli.py |   26 ++++++++++++++++++--------
 1 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/cli.py b/cli.py
index 5d6f160..c806b6d 100644
--- a/cli.py
+++ b/cli.py
@@ -124,16 +124,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
             self._getSacks(thisrepo=thisrepo)
         
         return self._repos
-        
+
+    def _makeUsage(self):
+        """
+        Format an attractive usage string for yum, listing subcommand
+        names and summary usages.
+        """
+        usage = 'yum [options] COMMAND\n\nList of Commands:\n\n'
+        commands = yum.misc.unique(self.yum_cli_commands.values())
+        commands.sort(cmp=lambda x,y : cmp(x.getNames()[0], y.getNames()[0]))
+        for command in commands:
+            usage += "%-15s%s\n" % (command.getNames()[0],
+                    command.getSummary())
+
+        return usage
+
     def getOptionsConfig(self, args):
         """parses command line arguments, takes cli args:
         sets up self.conf and self.cmds as well as logger objects 
         in base instance"""
-        
-
-        self.optparser = YumOptionParser(base=self, 
-            usage='yum [options] < %s >' % (', '.join(self.yum_cli_commands)))
-
+       
+        self.optparser = YumOptionParser(base=self, usage=self._makeUsage())
         
         # Parse only command line options that affect basic yum setup
         opts = self.optparser.firstParse(args)
@@ -169,8 +180,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
             sys.exit(1)
 
         # update usage in case plugins have added commands
-        self.optparser.set_usage('yum [options] < %s >''' % (
-            ', '.join(self.yum_cli_commands)))
+        self.optparser.set_usage(self._makeUsage())
         
         # Now parse the command line for real and 
         # apply some of the options to self.conf
-- 
1.5.4.rc4.1142.gf5a97

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.baseurl.org/pipermail/yum-devel/attachments/20080124/796d4911/attachment.pgp 


More information about the Yum-devel mailing list