def get_installed_version(self, pkgname): """ Return the currently installed version. If pkgname is not installed, return False. """ pkgarch = None if pkgname.find('.') != -1: pkgname, pkgarch = pkgname.split('.', 1) # zypper is very slow for mere queries of installed packages, # if we have rpm do that if self.fastcommand is not None: try: # using RPM we can query just what we want, and much faster pkg, ver, arch = subproc.check_output( [self.fastcommand, "-q", '--qf=%{NAME}\ %{VERSION}-%{RELEASE}\ %{ARCH}', pkgname]).strip().split() if pkg == pkgname and (pkgarch is None or arch == pkgarch): self.log.debug("Package {0} has version {1} in {2}".format(pkgname, ver, self.fastcommand)) return ver # exception for unpack error if package not found except subproc.CalledProcessError: pass except Exception as ex: self.log.error("Parsing `{0} list installed` failed.".format(self.fastcommand)) self.log.trace(str(ex)) return False try: # 'list installed' will return non-zero if package does not exist, thus will throw out = subproc.check_output( [self.command, "search", "-is", pkgname], stderr=subprocess.STDOUT ).strip().split("\n") # Output looks like this: # <status>|<pkgname>|<type>|<version>|<arch>|<repo> # So, two steps: # 1) Check that pkgname is correct (and, if necessary, the package arch) # 2) return version match_pat = r"^(?P<status>)\s+\|\s+(?P<pkg>[^\.]+)\s+\| \ \s+(?P<pkgtype>\S+)\s+\| \ \s+(?P<ver>[0-9]+([.-][0-9a-z]+))\s+\| \ \s+(?P<arch>\S+)\s+(\d+:)" matcher = re.compile(match_pat) for line in out: mobj = matcher.match(line) if mobj and mobj.group('pkg') == pkgname: if pkgarch is not None and mobj.group('arch') != pkgarch: continue ver = mobj.group('ver') self.log.debug("Package {0} has version {1} in {2}".format(pkgname, ver, self.command)) return ver return False except subproc.CalledProcessError: # This usually means the packet is not installed return False except Exception as ex: self.log.error("Parsing `{0} list installed` failed.".format(self.command)) self.log.trace(str(ex)) return False
def _load_environ_from_script(self, setup_env_file): """ Run setup_env_file, return the new env FIXME make this portable! """ self.log.debug('Loading environment from shell script: {0}'.format(setup_env_file)) # It would be nice if we could do os.path.expandvars() with a custom # env, wouldn't it setup_env_file = setup_env_file.replace('${0}'.format(self.env_prefix_var), self.prefix_dir) setup_env_file = setup_env_file.replace('${{{0}}}'.format(self.env_prefix_var), self.prefix_dir) # TODO add some checks this is a legit script # Damn, I hate just running stuff :/ # TODO unportable command: separator = '<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>' get_env_cmd = "source {env_file} && echo '{sep}' && env".format(env_file=setup_env_file, sep=separator) from pybombs.utils import subproc try: script_output = subproc.check_output(get_env_cmd, shell=True) except subproc.CalledProcessError: self.log.error("Trouble sourcing file {env_file}".format(env_file=setup_env_file)) raise PBException("Could not source env file.") env_output = script_output.split(separator)[-1] # TODO assumption is that env_output now just holds the env output env_output = env_output.split('\n') env = {} for env_line in env_output: env_line = env_line.strip() if len(env_line) == 0: continue k, v = env_line.split('=', 1) env[k] = v return env
def installed(self, name, return_pkgr_name=False): """ Check to see if this recipe is installed (identified by its name). If not, return False. If yes, return value depends on return_pkgr_name and is either a list of packager name that installed it, or a version string (if the version string can't be determined, returns True instead). """ if not return_pkgr_name and name in self.pmc.known_installed: self.log.obnoxious("{0} is cached and known to be installed.".format(name)) return True self.log.debug("Checking if package {} is installed.".format(name)) if self.check_package_flag(name, 'forceinstalled'): self.log.debug("Package {} is forced to state 'installed'.".format(name)) # TODO maybe we can figure out a version string return ['force-installed'] if return_pkgr_name else True r = recipe.get_recipe(name) self.current_prefix = self.cfg.get_active_prefix() virtualenv = config_manager.extract_cfg_items(self.current_prefix.cfg_file, 'virtualenv') self.log.debug("Checking if the prefix has a virtualenv") if virtualenv and 'python' in r.depends: try: if 'pip' in r.satisfy: #This pip list is specific to virtualenv pip_output = subproc.check_output(["pip", "list"]) pip_list = [x.split(' ')[0] for x in str(pip_output).strip(). lower().split("\n")] if not name in pip_list: return False except AttributeError: self.log.debug("Package depends on python, but isn't pip installable") pkgrs = [] for pkgr in self.get_packagers(name): pkg_version = pkgr.installed(r) if pkg_version is None or not pkg_version: continue else: self.pmc.known_installed.add(name) if return_pkgr_name: pkgrs.append(pkgr.name) else: return pkg_version else: pkgrs = [] for pkgr in self.get_packagers(name): pkg_version = pkgr.installed(r) if pkg_version is None or not pkg_version: continue else: self.pmc.known_installed.add(name) if return_pkgr_name: pkgrs.append(pkgr.name) else: return pkg_version if return_pkgr_name and len(pkgrs): return pkgrs return False
def get_installed_version(self, pkgname): """ Return the currently installed version. If pkgname is not installed, return False. """ pkgarch = None if pkgname.find('.') != -1: pkgname, pkgarch = pkgname.split('.', 1) try: # 'list installed' will return non-zero if package does not exist, thus will throw out = subproc.check_output( [self.command, "list", "installed", pkgname], stderr=subprocess.STDOUT ).strip().split("\n") # Output looks like this: # <pkgname>.<arch> <version> <more info> # So, two steps: # 1) Check that pkgname is correct (and, if necessary, the package arch) # 2) return version for line in out: mobj = re.match(r"^(?P<pkg>[^\.]+)\.(?P<arch>\S+)\s+(\d+:)?(?P<ver>[0-9]+(\.[0-9]+){0,2})", line) if mobj and mobj.group('pkg') == pkgname: if pkgarch is not None and mobj.group('arch') != pkgarch: continue ver = mobj.group('ver') self.log.debug("Package {} has version {} in {}".format(pkgname, ver, self.command)) return ver return False except subprocess.CalledProcessError: # This usually means the packet is not installed return False except Exception as ex: self.log.error("Parsing `{0} list installed` failed.".format(self.command)) self.log.obnoxious(str(ex)) return False
def get_installed_version(self, pkgname): """ Check which version has been installed by brew. Note: By default, homebrew does not uninstall old versions of packages. Figure out which version is the newest. If older versions of the package exist, tell the user they may want to run "brew cleanup".? """ try: self.log.obnoxious("Checking homebrew for `{0}'".format(pkgname)) out = subproc.check_output(["brew", "info", "--json=v1", pkgname]) # Returns non-zero exit status if package does not exist in brew taps if len(out) >= 0: # Get the version. pkgdata = json.loads(out)[ 0] # Wrapped in a list. get the first element. installed = pkgdata["installed"] if len(installed) > 0: version = installed[0]["version"] else: return False self.log.obnoxious( "{0} version {1} installed through homebrew".format( pkgname, version)) return version else: return False except subproc.CalledProcessError: self.log.error("Unable to find package") except KeyError: self.log.error("Package is not installed") except Exception as ex: # Non-zero return. self.log.error("Error running brew info") self.log.error(repr(ex)) return False
def get_installed_version(self, pkgname): """ Check which version has been installed by brew. Note: By default, homebrew does not uninstall old versions of packages. Figure out which version is the newest. If older versions of the package exist, tell the user they may want to run "brew cleanup".? """ try: self.log.obnoxious("Checking homebrew for `{0}'".format(pkgname)) out = subproc.check_output(["brew", "info", "--json=v1", pkgname]) # Returns non-zero exit status if package does not exist in brew taps if len(out) >= 0: # Get the version. pkgdata = json.loads(out)[0] # Wrapped in a list. get the first element. installed = pkgdata["installed"] if len(installed) > 0: version = installed[0]["version"] else: return False self.log.obnoxious("{0} version {1} installed through homebrew".format(pkgname, version)) return version else: return False except subproc.CalledProcessError: self.log.error("Unable to find package") except KeyError: self.log.error("Package is not installed") except Exception as ex: # Non-zero return. self.log.error("Error running brew info") self.log.error(repr(ex)) return False
def run_git_command(self, args): " Run a git command in path, return to previous cwd, return output " git_cmd = ['git'] + args cwd = os.getcwd() os.chdir(self.path) output = subproc.check_output(git_cmd) os.chdir(cwd) return output
def get_git_version(): """ Return the currently installed git version as a string. """ try: return re.search(r'[0-9.]+', subproc.check_output(['git', '--version'])).group(0) except OSError: raise PBException("Unable to execute git!") except subproc.CalledProcessError: raise PBException("Error executing 'git --version'!") except AttributeError: raise PBException("Unexpected output from 'git --version'!")
def get_available_version(self, pkgname): """ Search for package with 'port search' """ try: out = subproc.check_output(["port", "search", "--name", "--glob", pkgname]).strip() if "No match" in out: return False ver = re.search(r'@(?P<ver>[0-9,.]*)', str(out)).group('ver') return ver except subprocess.CalledProcessError: return False except Exception as e: self.log.error("Error running port search") return False
def get_git_version(): """ Return the currently installed git version as a string. """ try: return re.search( r'[0-9.]+', subproc.check_output(['git', '--version']) ).group(0) except OSError: raise PBException("Unable to execute git!") except subproc.CalledProcessError: raise PBException("Error executing 'git --version'!") except AttributeError: raise PBException("Unexpected output from 'git --version'!")
def get_installed_version(self, pkgname): """ Retrun installed version. Return False if package is not installed """ try: out = subproc.check_output(["port", "installed", pkgname]).strip() if "None of the specified ports" in out: return False ver = re.search(r'@(?P<ver>[0-9,.]*)', str(out)).group('ver') return ver except subprocess.CalledProcessError: # This usually means the packet is not installed -- not a problem. return False except Exception as e: self.log.error("Running port installed failed.") self.log.obnoxious(str(e))
def get_available_version(self, pkgname): """ See if 'pip search' finds our package. """ try: out = subproc.check_output(["pip", "search", pkgname]) if len(out) == 0: return True if re.search(r'^\b{pkg}\b'.format(pkg=pkgname), str(out), re.MULTILINE): return True except subprocess.CalledProcessError: return False except Exception as ex: self.log.error("Error running pip search") self.log.debug(ex) return False
def get_installed_version(self, pkgname): """ Use pkg-config to determine and return the currently installed version. If pkgname is not installed, return None. """ try: # pkg-config will return non-zero if package does not exist, thus will throw ver = subproc.check_output(["pkg-config", "--modversion", pkgname], stderr=subprocess.STDOUT).strip() self.log.debug("Package {0} has version {1} in pkg-config".format(pkgname, ver)) return ver except subprocess.CalledProcessError: # This usually means the packet is not installed return False except Exception as e: self.log.error("Running `pkg-config --modversion` failed.") self.log.obnoxious(str(e)) return False
def get_installed_version(self, pkgname): """ Use pkg-config to determine and return the currently installed version. If pkgname is not installed, return None. """ try: # pkg-config will return non-zero if package does not exist, thus will throw ver = subproc.check_output(["pkg-config", "--modversion", pkgname], stderr=subprocess.STDOUT).strip() self.log.debug("Package {0} has version {1} in pkg-config".format( pkgname, ver)) return ver except subprocess.CalledProcessError: # This usually means the packet is not installed return False except Exception as e: self.log.error("Running `pkg-config --modversion` failed.") self.log.trace(str(e)) return False
def load_install_cache(self): """ Populate the installed cache. """ global PIP_INSTALLED_CACHE self.log.debug("Loading pip install cache.") PIP_INSTALLED_CACHE = {} try: installed_packages = str(subproc.check_output(["pip", "list"])).strip().split("\n") for pkg in installed_packages: mobj = re.match(r'(?P<pkg>\S+)\s+\((?P<ver>[^)]+)\)', str(pkg)) if mobj is None: continue PIP_INSTALLED_CACHE[mobj.group('pkg')] = mobj.group('ver') return except subproc.CalledProcessError as e: self.log.error("Could not run pip list. Hm.") self.log.error(str(e)) except Exception as e: self.log.error("Some error while running pip list.") self.log.error(str(e))
def load_install_cache(self): """ Populate the installed cache. """ global PIP_INSTALLED_CACHE self.log.debug("Loading pip install cache.") PIP_INSTALLED_CACHE = {} try: installed_packages = str(subproc.check_output( ["pip", "list"])).strip().split("\n") for pkg in installed_packages: mobj = re.match(r'(?P<pkg>\S+)\s+\((?P<ver>[^)]+)\)', str(pkg)) if mobj is None: continue PIP_INSTALLED_CACHE[mobj.group('pkg')] = mobj.group('ver') return except subproc.CalledProcessError as e: self.log.error("Could not run pip list. Hm.") self.log.error(str(e)) except Exception as e: self.log.error("Some error while running pip list.") self.log.error(str(e))
def get_available_version(self, pkgname): """ Check which version is currently installed. """ try: self.log.obnoxious("Checking homebrew for `{0}'".format(pkgname)) out = subproc.check_output(["brew", "info", "--json=v1", pkgname]) # Returns non-zero exit status if package does not exist in brew taps if len(out) >= 0: # Get the version. pkgdata = json.loads(out)[0] # Wrapped in a list. get the first element. version = pkgdata["versions"]["stable"] return version else: return False except subproc.CalledProcessError: # This usually means the packet is not installed return False except Exception as e: self.log.error("Running brew info failed.") self.log.obnoxious(str(e)) return False
def get_available_version(self, pkgname): """ Check which version is currently installed. """ try: self.log.obnoxious("Checking homebrew for `{0}'".format(pkgname)) out = subproc.check_output(["brew", "info", "--json=v1", pkgname]) # Returns non-zero exit status if package does not exist in brew taps if len(out) >= 0: # Get the version. pkgdata = json.loads(out)[ 0] # Wrapped in a list. get the first element. version = pkgdata["versions"]["stable"] return version else: return False except subproc.CalledProcessError: # This usually means the packet is not installed return False except Exception as e: self.log.error("Running brew info failed.") self.log.obnoxious(str(e)) return False
def get_installed_version(self, pkgname): """ Return the currently installed version. If pkgname is not installed, return False. """ pkgarch = None if pkgname.find('.') != -1: pkgname, pkgarch = pkgname.split('.', 1) # zypper is very slow for mere queries of installed packages, # if we have rpm do that if self.fastcommand is not None: try: # using RPM we can query just what we want, and much faster pkg, ver, arch = subproc.check_output([ self.fastcommand, "-q", '--qf=%{NAME}\ %{VERSION}-%{RELEASE}\ %{ARCH}', pkgname ]).strip().split() if pkg == pkgname and (pkgarch is None or arch == pkgarch): self.log.debug("Package {0} has version {1} in {2}".format( pkgname, ver, self.fastcommand)) return ver # exception for unpack error if package not found except subprocess.CalledProcessError: pass except Exception as ex: self.log.error("Parsing `{0} list installed` failed.".format( self.fastcommand)) self.log.obnoxious(str(ex)) return False try: # 'list installed' will return non-zero if package does not exist, thus will throw out = subproc.check_output( [self.command, "search", "-is", pkgname], stderr=subprocess.STDOUT).strip().split("\n") # Output looks like this: # <status>|<pkgname>|<type>|<version>|<arch>|<repo> # So, two steps: # 1) Check that pkgname is correct (and, if necessary, the package arch) # 2) return version match_pat = r"^(?P<status>)\s+\|\s+(?P<pkg>[^\.]+)\s+\| \ \s+(?P<pkgtype>\S+)\s+\| \ \s+(?P<ver>[0-9]+([.-][0-9a-z]+))\s+\| \ \s+(?P<arch>\S+)\s+(\d+:)" matcher = re.compile(match_pat) for line in out: mobj = matcher.match(line) if mobj and mobj.group('pkg') == pkgname: if pkgarch is not None and mobj.group('arch') != pkgarch: continue ver = mobj.group('ver') self.log.debug("Package {0} has version {1} in {2}".format( pkgname, ver, self.command)) return ver return False except subprocess.CalledProcessError: # This usually means the packet is not installed return False except Exception as ex: self.log.error("Parsing `{0} list installed` failed.".format( self.command)) self.log.obnoxious(str(ex)) return False