Source code for PyFoam.Applications.BinarySize

"""
Application-class that implements pyFoamBinarySize.py
"""
from optparse import OptionGroup

from .PyFoamApplication import PyFoamApplication

from PyFoam.ThirdParty.six import print_
from PyFoam.ThirdParty.tqdm import tqdm

from PyFoam.Basics.Utilities import diskUsage,humanReadableSize

import PyFoam.FoamInformation as FI

from os import listdir,path

[docs]class BinarySize(PyFoamApplication): def __init__(self, args=None, **kwargs): description="""\ Goes through the OpenFOAM-installation and records the size of all the binary files (linked as well as object files) and reports them for each compiliation option separately (Debug/Opt, compilers) This should provide the user with an overview how much disk space each variation of the binaries needs. The reported OpenfOAM-installation can be selected using the usual Foam-version switching. """ examples="""\ %prog List the disk space used by the current OpenFOAM-installation %prog --foamVersion=1.7.x List the disk space used by binaries in OpenFOAM-1.7.x %prog --all-installations List the disk space used by all the available installations %prog --all-installations --follow-symlinked-installations Also follow symlinked installations (this may count binaries twice)""" PyFoamApplication.__init__(self, args=args, description=description, examples=examples, usage="%prog <caseDirectory>", interspersed=True, changeVersion=True, nr=0, exactNr=True, **kwargs)
[docs] def addOptions(self): what=OptionGroup(self.parser, "What", "What should be reported") self.parser.add_option_group(what) what.add_option("--all-installations", action="store_true", dest="allInstallations", default=False, help="Report the disk usage for all installations (this may take quite a while)") what.add_option("--follow-symlinked-installations", action="store_true", dest="symlinkInstallations", default=False, help="Also count the installation if it is a symlink (otherwise only report the original installation and skip it)") what.add_option("--no-documentation", action="store_false", dest="doDocumentation", default=True, help="Do not process the amount of memory needed by the documentation") what.add_option("--no-third-party", action="store_false", dest="doThirdParty", default=True, help="Do not process the amount of memory needed by the Third-party directory") display=OptionGroup(self.parser, "Display", "Output on the screen") self.parser.add_option_group(display) display.add_option("--progress-maximum-depth", action="store", type=int, dest="maximumProgressDepth", default=2, help="Maximum level of recursion depth for which the progress should be reported. Default: %default") display.add_option("--no-progress-bar", action="store_const", const=0, dest="maximumProgressDepth", help="Switch off the progress bars")
[docs] def output(self,*args): if self.opts.maximumProgressDepth>0: self.out+=" ".join(str(a) for a in args)+"\n" else: print_(*args)
[docs] def scanDir(self, dPath, usages, depth=1, thirdParty=False): dName=path.basename(dPath) dirs= ["Make","platform","bin","platforms","build"] if self.opts.doDocumentation: dirs+=["Doxygen"] if dName[0]==".": return elif dName in ["lnInclude"]: return elif dName in dirs: for f in tqdm(listdir(dPath), desc=path.basename(dPath), disable=depth>self.opts.maximumProgressDepth, unit="files"): if f[0]==".": continue nPath=path.join(dPath,f) if path.isdir(nPath): isBin=False for end in ["Opt","Debug","Prof"]: if f.find(end)>0 and (f.find(end)+len(end))==len(f): isBin=True if f in ["html"] and self.opts.doDocumentation: isBin=True if thirdParty: for c in ["Gcc", "Clang", "linux"]: if f.find(c)>=0: isBin = True if isBin: sz=diskUsage(nPath) try: usages[f]+=sz except KeyError: usages[f]=sz # self.output("Found architecture",f,"in",dPath) else: try: for f in tqdm(listdir(dPath), unit="files", disable=depth>self.opts.maximumProgressDepth, desc=path.basename(dPath)): nPath=path.join(dPath,f) if path.isdir(nPath) and not path.islink(nPath): self.scanDir(nPath,usages,depth=depth+1, thirdParty=thirdParty) except OSError: self.warning("Can't process",dPath)
[docs] def reportInstallation(self, fName, thirdParty=False): """Report the usages of a OpenFOAM-installation""" self.output("\nScanning",fName) totalSize = diskUsage(fName) self.output(" Total size:",humanReadableSize(totalSize)) if path.islink(fName): self.output("Symlinked to",path.realpath(fName)) if not self.opts.symlinkInstallations: self.output("Skipping symlinked installation") return 0 usages={} self.scanDir(fName, usages, thirdParty=thirdParty) if len(usages)>0: nameLength=max([len(k) for k in usages.keys()]) sizeLength=max([len(str(k)) for k in usages.values()]) formatString=" %%%ds - %%%dd (%%s)" % (nameLength,sizeLength) total=0 for k in sorted(usages.keys()): v=usages[k] total+=v self.output(formatString % (k,v,humanReadableSize(v))) self.output("Sum of binaries",humanReadableSize(total)) return total, totalSize else: self.output(" No binaries found") return 0, totalSize
[docs] def run(self): self.out="" if self.opts.allInstallations: installed=FI.foamInstalledVersions() total, size = 0, 0 for k in tqdm(sorted(installed.keys()), desc="Distro", unit="distro"): instPath=installed[k] t, s = self.reportInstallation(instPath) total += t size += s if self.opts.doThirdParty: thirdPartyDir = FI.findThirdPartyDir(k) if thirdPartyDir is not None: t, s = self.reportInstallation(thirdPartyDir, thirdParty=True) total += t size += s self.output("\nTotal disk space used by binaries: {} (Complete size: {})".format( humanReadableSize(total), humanReadableSize(size))) else: try: self.reportInstallation(FI.installationPath()) if self.opts.doThirdParty: installed = FI.foamInstalledVersions() version = None for k in installed: if installed[k] == FI.installationPath(): version = k break if k is not None: self.reportInstallation(FI.findThirdPartyDir(version), thirdParty=True) except KeyError: self.error("No Foam-installation active. Specify one") if len(self.out)>0: print_("\n") print_(self.out)