1179860b2SJed Brown'''This module is meant to provide support for information and help systems based upon RDict.''' 25b6bfdb9SJed Brownfrom __future__ import print_function 35b6bfdb9SJed Brownfrom __future__ import absolute_import 4179860b2SJed Brownimport logger 5179860b2SJed Brown 6179860b2SJed Brownclass Info(logger.Logger): 7179860b2SJed Brown '''This basic class provides information independent of RDict''' 8179860b2SJed Brown def __init__(self, argDB = None): 9179860b2SJed Brown '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList)''' 10179860b2SJed Brown logger.Logger.__init__(self, None, argDB) 11179860b2SJed Brown self.sections = {} 12179860b2SJed Brown return 13179860b2SJed Brown 14179860b2SJed Brown def getTitle(self): 15179860b2SJed Brown return self._title 16179860b2SJed Brown 17179860b2SJed Brown def setTitle(self, title): 18179860b2SJed Brown self._title = str(title) 19179860b2SJed Brown title = property(getTitle, setTitle, None, 'Title of the Information Menu') 20179860b2SJed Brown 21179860b2SJed Brown def getDescription(self, section, name): 22179860b2SJed Brown return self._desc[(section, name)] 23179860b2SJed Brown 24179860b2SJed Brown def setDescription(self, section, name, desc): 25179860b2SJed Brown if not hasattr(self, '_desc'): 26179860b2SJed Brown self._desc = {} 27179860b2SJed Brown self._desc[(section, name)] = desc 28179860b2SJed Brown return 29179860b2SJed Brown 30179860b2SJed Brown def addArgument(self, section, name, desc): 31179860b2SJed Brown '''Add an argument with given name and string to an information section''' 32179860b2SJed Brown if not section in self.sections: 33179860b2SJed Brown self.sections[section] = (len(self.sections), []) 34179860b2SJed Brown if name in self.sections[section][1]: 35bb3dd2f6SJed Brown name += '@'+str(len([n for n in self.sections[section][1] if name == n.split('@')[0]])+1) 36179860b2SJed Brown self.sections[section][1].append(name) 37179860b2SJed Brown self.setDescription(section, name, desc) 38179860b2SJed Brown return 39179860b2SJed Brown 40179860b2SJed Brown def printBanner(self, f): 41179860b2SJed Brown '''Print a banner for the information screen''' 42179860b2SJed Brown f.write(self.title+'\n') 43179860b2SJed Brown for i in range(max(map(len, self.title.split('\n')))): f.write('-') 44179860b2SJed Brown f.write('\n') 45179860b2SJed Brown return 46179860b2SJed Brown 47179860b2SJed Brown def getTextSizes(self): 48179860b2SJed Brown '''Returns the maximum name and description lengths''' 49179860b2SJed Brown nameLen = 1 50179860b2SJed Brown descLen = 1 51179860b2SJed Brown for section in self.sections: 52179860b2SJed Brown nameLen = max([nameLen, max(map(lambda n: len(n.split('@')[0]), self.sections[section][1]))+1]) 53179860b2SJed Brown descLen = max([descLen, max(map(lambda name: len(self.getDescription(section, name)), self.sections[section][1]))+1]) 54179860b2SJed Brown return (nameLen, descLen) 55179860b2SJed Brown 56179860b2SJed Brown def output(self, f = None): 57179860b2SJed Brown '''Print a help screen with all the argument information.''' 58179860b2SJed Brown if f is None: 59179860b2SJed Brown import sys 60179860b2SJed Brown f = sys.stdout 61179860b2SJed Brown self.printBanner(f) 62179860b2SJed Brown (nameLen, descLen) = self.getTextSizes() 63179860b2SJed Brown format = ' %-'+str(nameLen)+'s: %s\n' 64*b8b3d021SJed Brown items = sorted(self.sections.items(), key=lambda a: a[1][0]) 65179860b2SJed Brown for section, names in items: 66179860b2SJed Brown f.write(section+':\n') 67179860b2SJed Brown for name in names[1]: 68179860b2SJed Brown f.write(format % (name.split('@')[0], self.getDescription(section, name))) 69179860b2SJed Brown return 70179860b2SJed Brown 71b93f8388SBarry Smith# I don't know how to not have this stupid global variable 72b93f8388SBarry Smith_outputDownloadDone = 0 73b93f8388SBarry Smith 74179860b2SJed Brownclass Help(Info): 75179860b2SJed Brown '''Help provides a simple help system for RDict''' 76179860b2SJed Brown def __init__(self, argDB): 77179860b2SJed Brown '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList). Also provide the RDict upon which this will be based.''' 78179860b2SJed Brown Info.__init__(self, argDB) 79179860b2SJed Brown self.title = 'Help' 80179860b2SJed Brown return 81179860b2SJed Brown 82179860b2SJed Brown def getDescription(self, section, name): 83179860b2SJed Brown return self.argDB.getType(self.getArgName(name)).help 84179860b2SJed Brown 85179860b2SJed Brown def setDescription(self, section, name, desc): 86179860b2SJed Brown return 87179860b2SJed Brown 88179860b2SJed Brown def getArgName(self, name): 89179860b2SJed Brown '''Return the RDict key corresponding to a more verbose help name. Right now, this means discard everything after "=".''' 90179860b2SJed Brown #return name.split('=')[0].strip('-') 91179860b2SJed Brown argName = name.split('=')[0] 92179860b2SJed Brown while argName[0] == '-': argName = argName[1:] 93179860b2SJed Brown return argName 94179860b2SJed Brown 95179860b2SJed Brown def addArgument(self, section, name, argType, ignoreDuplicates = 0): 96179860b2SJed Brown '''Add an argument with given name and type to a help section. The type, which can also have an initializer and help string, will be put into RDict.''' 97179860b2SJed Brown## super(Info, self).addArgument(section, name, None) 98179860b2SJed Brown if section in self.sections: 99179860b2SJed Brown if name in self.sections[section][1]: 100179860b2SJed Brown if ignoreDuplicates: 101179860b2SJed Brown return 102179860b2SJed Brown raise RuntimeError('Duplicate configure option '+name+' in section '+section) 103179860b2SJed Brown else: 104179860b2SJed Brown self.sections[section] = (len(self.sections), []) 105179860b2SJed Brown if not argType.deprecated: 106179860b2SJed Brown self.sections[section][1].append(name) 107179860b2SJed Brown 108179860b2SJed Brown self.argDB.setType(self.getArgName(name), argType, forceLocal = 1) 109179860b2SJed Brown return 110179860b2SJed Brown 11175f179b0SBarry Smith def addDownload(self,name,dlist): 11275f179b0SBarry Smith if not hasattr(self.argDB,'dlist'): 11375f179b0SBarry Smith self.argDB.dlist = {} 11475f179b0SBarry Smith else: 11575f179b0SBarry Smith self.argDB.dlist[name] = dlist 11675f179b0SBarry Smith 117179860b2SJed Brown def output(self, f = None, sections = None): 118179860b2SJed Brown '''Print a help screen with all the argument information.''' 119179860b2SJed Brown if f is None: 120179860b2SJed Brown import sys 121179860b2SJed Brown f = sys.stdout 122179860b2SJed Brown if sections: sections = [s.lower() for s in sections] 123179860b2SJed Brown self.printBanner(f) 124179860b2SJed Brown (nameLen, descLen) = self.getTextSizes() 125179860b2SJed Brown# format = ' -%-'+str(nameLen)+'s: %s\n' 126179860b2SJed Brown# formatDef = ' -%-'+str(nameLen)+'s: %-'+str(descLen)+'s current: %s\n' 127179860b2SJed Brown format = ' -%s\n %s\n' 128179860b2SJed Brown formatDef = ' -%s\n %s current: %s\n' 129179860b2SJed Brown items = self.sections.items() 130f20c2d65SJed Brown items.sort(key=lambda a: a[1][0]) 131179860b2SJed Brown for section, names in items: 132179860b2SJed Brown if sections and not section.lower() in sections: continue 133179860b2SJed Brown f.write(section+':\n') 134179860b2SJed Brown for name in names[1]: 135179860b2SJed Brown argName = self.getArgName(name) 136179860b2SJed Brown type = self.argDB.getType(argName) 137179860b2SJed Brown if argName in self.argDB: 138179860b2SJed Brown f.write(formatDef % (name, type.help, str(self.argDB.getType(argName)))) 139179860b2SJed Brown else: 140179860b2SJed Brown f.write(format % (name, type.help)) 141179860b2SJed Brown return 14275f179b0SBarry Smith 143b93f8388SBarry Smith 14475f179b0SBarry Smith def outputDownload(self): 1450aa1f76dSSatish Balay ''' Looks for downloaded packages in --with-packages-download-dir 146b93f8388SBarry Smith For any it finds it updates the --download-xxx= argument to point to this local copy 147b93f8388SBarry Smith If it does not find some needed packages then prints the packages that need to be downloaded and exits''' 14875f179b0SBarry Smith import nargs 14975f179b0SBarry Smith import os 15075f179b0SBarry Smith import sys 151b93f8388SBarry Smith global _outputDownloadDone 152b93f8388SBarry Smith if _outputDownloadDone: return 153b93f8388SBarry Smith _outputDownloadDone = 1 1540aa1f76dSSatish Balay pkgdir = os.path.abspath(os.path.expanduser(nargs.Arg.findArgument('with-packages-download-dir', self.clArgs))) 15575f179b0SBarry Smith missing = 0 156b93f8388SBarry Smith for i in self.argDB.dlist.keys(): 157b93f8388SBarry Smith if not nargs.Arg.findArgument('download-'+i, self.clArgs) == None and not nargs.Arg.findArgument('download-'+i, self.clArgs) == '0': 158b93f8388SBarry Smith dlist = self.argDB.dlist[i] 159b93f8388SBarry Smith found = 0 160b93f8388SBarry Smith for k in range(0,len(dlist)): 161b93f8388SBarry Smith fd = os.path.join(pkgdir,os.path.basename(dlist[k])) 162b93f8388SBarry Smith if os.path.isdir(fd) or os.path.isfile(fd): 163b93f8388SBarry Smith found = 1 164b93f8388SBarry Smith break 165b93f8388SBarry Smith if not found: 166b93f8388SBarry Smith missing = 1 167b93f8388SBarry Smith if missing: 1685b6bfdb9SJed Brown print('Download the following packages to '+pkgdir+' \n') 16975f179b0SBarry Smith for i in self.argDB.dlist.keys(): 17075f179b0SBarry Smith if not nargs.Arg.findArgument('download-'+i, self.clArgs) == None and not nargs.Arg.findArgument('download-'+i, self.clArgs) == '0': 17175f179b0SBarry Smith dlist = self.argDB.dlist[i] 17275f179b0SBarry Smith found = 0 17375f179b0SBarry Smith for k in range(0,len(dlist)): 17475f179b0SBarry Smith fd = os.path.join(pkgdir,os.path.basename(dlist[k])) 17575f179b0SBarry Smith if os.path.isdir(fd) or os.path.isfile(fd): 17675f179b0SBarry Smith found = 1 17775f179b0SBarry Smith for k in range(0,len(self.clArgs)): 17875f179b0SBarry Smith if self.clArgs[k].startswith('--download-'+i): 17975f179b0SBarry Smith self.clArgs[k] = 'download-'+i+'='+fd 18075f179b0SBarry Smith self.argDB.insertArgs([self.clArgs[k]]) 18175f179b0SBarry Smith break 18275f179b0SBarry Smith if not found: 1835b6bfdb9SJed Brown print(i + ' ' + str(self.argDB.dlist[i])) 1849e6d21dfSBarry Smith if missing: 1855b6bfdb9SJed Brown print('\nThen run the script again\n') 186c524ecbbSBarry Smith sys.exit(10) 18775f179b0SBarry Smith 188