class NpmRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``npm`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('npm')} def __init__(self, package, version=""): """ Constructs a new ``NpmRequirement``, using the ``PackageRequirement`` constructor. >>> pr = NpmRequirement('ramllint', '6.2') >>> pr.type 'npm' >>> pr.package 'ramllint' >>> pr.version '6.2' >>> str(pr) 'ramllint 6.2' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'npm', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> NpmRequirement('alex', '2').install_command() ['npm', 'install', 'alex@2'] >>> NpmRequirement('alex').install_command() ['npm', 'install', 'alex'] :param return: A string with the installation command. """ result = [ 'npm', 'install', self.package + "@" + self.version if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ for cmd in ('npm list ' + self.package, 'npm list -g ' + self.package): if not run(cmd, stdout=Capture(), stderr=Capture()).returncode: return True return False
class LuarocksRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``luarocks`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('luarocks')} def __init__(self, package, version=''): """ Constructs a new ``Luarocks``, using the ``PackageRequirement`` constructor. >>> pr = LuarocksRequirement('luasocket', '3.0rc1') >>> pr.type 'luarocks' >>> pr.package 'luasocket' >>> pr.version '3.0rc1' >>> str(pr) 'luasocket 3.0rc1' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'luarocks', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> LuarocksRequirement('luacheck', '0.19.1').install_command() ['luarocks', 'install', 'luacheck 0.19.1'] >>> LuarocksRequirement('luacheck').install_command() ['luarocks', 'install', 'luacheck'] :param return: A string with the installation command. """ result = [ 'luarocks', 'install', self.package + ' ' + self.version if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ cmd = 'luarocks show ' + self.package if not run(cmd, stdout=Capture(), stderr=Capture()).returncode: return True return False
class JuliaRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``julia`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('julia')} def __init__(self, package, version=""): """ Constructs a new ``JuliaRequirement``, using the ``PackageRequirement`` constructor. >>> pr = JuliaRequirement('Lint', '19.2') >>> pr.type 'julia' >>> pr.package 'Lint' >>> pr.version '19.2' >>> str(pr) 'Lint 19.2' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'julia', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> JuliaRequirement('Lint').install_command() 'julia -e \\'Pkg.add("Lint")\\'' :return: A string with the installation command. """ code = 'Pkg.add("{}")'.format(escape(self.package, '\\"')) args = ('julia', '-e', shlex.quote(code)) return ' '.join(args) def is_installed(self): """ Checks if the dependency is installed. :return: ``True`` if dependency is installed, ``False`` otherwise. """ # We need to check explicitly if `nothing` is returned, as this happens # when the package is *registered*, but *not installed*. If it's not # even registered, julia will throw an exception which lets julia exit # with an error code different from 0. code = 'Pkg.installed("{}")==nothing?exit(1):exit(0)'.format( escape(self.package, '\\"')) args = 'julia -e ' + shlex.quote(code) return not run(args, stdout=Capture(), stderr=Capture()).returncode
class CabalRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``, It specifies the proper type for ``cabal`` packages automatically and provides a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('cabal')} def __init__(self, package, version=''): """ Constructs a new ``CabalRequirement``, using the ``PackageRequirement`` constructor. >>> cr = CabalRequirement('zoom', '0.1') >>> cr.type 'cabal' >>> cr.package 'zoom' >>> cr.version '0.1' >>> str(cr) 'zoom 0.1' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'cabal', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> CabalRequirement('foo', '3').install_command() ['cabal', 'install', 'foo-3'] >>> CabalRequirement('foo').install_command() ['cabal', 'install', 'foo'] :param return: A list with the installation command parameters. """ result = [ 'cabal', 'install', self.package + '-' + self.version if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ return not run('cabal info ' + self.package, stdout=Capture(), stderr=Capture()).returncode
class GoRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``go`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('go')} def __init__(self, package, version="", flag=""): """ Constructs a new ``GoRequirement``, using the ``PackageRequirement`` constructor. >>> pr = GoRequirement('github.com/golang/lint/golint', '19.2', '-u') >>> pr.type 'go' >>> pr.package 'github.com/golang/lint/golint' >>> pr.version '19.2' >>> pr.flag '-u' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. :param flag: A string that specifies any additional flags, that are passed to the manager. """ PackageRequirement.__init__(self, 'go', package, version) self.flag = flag def install_command(self): """ Creates the installation command for the instance of the class. >>> GoRequirement( ... 'github.com/golang/lint/golint', '' , '-u' ).install_command() ['go', 'get', '-u', 'github.com/golang/lint/golint'] :param return: A string with the installation command. """ return ['go', 'get', self.flag, self.package] def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ return not run('go list ' + self.package, stdout=Capture(), stderr=Capture()).returncode
def get_all_requirements(bears): bear_requirements = {} for bear in bears: instance_dict = collections.defaultdict(set) executable = None if hasattr(bear, 'get_executable'): executable = bear.get_executable() if executable: requirement = ExecutableRequirement(_clean_executable(executable)) instance_dict['ExecutableRequirement'].add(requirement) helper(bear.REQUIREMENTS, instance_dict) bear_requirements[str(bear.name)] = instance_dict return bear_requirements
class GemRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``ruby`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('gem')} def __init__(self, package, version="", require=""): """ Constructs a new ``GemRequirement``, using the ``PackageRequirement`` constructor. >>> pr = GemRequirement('setuptools', '19.2', 'flag') >>> pr.type 'gem' >>> pr.package 'setuptools' >>> pr.version '19.2' >>> pr.require 'flag' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. :param require: A string that specifies any additional flags, that would be used with ``require``. """ PackageRequirement.__init__(self, 'gem', package, version) self.require = require def install_command(self): """ Creates the installation command for the instance of the class. >>> GemRequirement('rubocop').install_command() ['gem', 'install', 'rubocop'] >>> GemRequirement('scss_lint', '', 'false').install_command() ['gem', 'install', 'scss_lint'] >>> GemRequirement('rake', '10.5.0').install_command() ['gem', 'install', 'rake:10.5.0'] :param return: A string with the installation command. """ gem = self.package if self.version: gem += ':' + self.version result = ['gem', 'install', gem] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ cmd = 'gem list -i ' + self.package return not run(cmd, stdout=Capture(), stderr=Capture()).returncode
class RscriptRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``R`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('R')} def __init__(self, package, version="", flag="", repo="http://cran.rstudio.com"): """ Constructs a new ``RscriptRequirement``, using the ``PackageRequirement`` constructor. >>> pr = RscriptRequirement( ... 'formatR', version='1.4', flag='-e', ... repo="http://cran.rstudio.com") >>> pr.type 'R' >>> pr.package 'formatR' >>> pr.version '1.4' >>> str(pr) 'formatR 1.4' >>> pr.flag '-e' >>> pr.repo 'http://cran.rstudio.com' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. :param flag: A string that specifies any additional flags, that are passed to the type. :param repo: The repository from which the package is to be installed. """ PackageRequirement.__init__(self, 'R', package, version, repo) self.flag = flag def install_command(self): """ Creates the installation command for the instance of the class. >>> RscriptRequirement( ... 'formatR', '' , '-e', ... 'http://cran.rstudio.com').install_command() ['R', '-e', '"install.packages("formatR", repo="http://cran.rstudio.com", dependencies=TRUE)"'] :param return: A list with the installation command. """ install = '"install.packages(\"{}\", repo=\"{}\", dependencies=TRUE)"' result = ['R', '-e', install.format(self.package, self.repo)] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ return not run( ('R -e \'library(\"{}\", quietly=TRUE)\''.format(self.package)), stdout=Capture(), stderr=Capture()).returncode
class CondaRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``conda`` packages automatically and provides a function to check for the requirement. """ REQUIREMENTS = { ExecutableRequirement('conda'), ExecutableRequirement('grep') } def __init__(self, package, version='', repo=''): """ Constructs a new ``CondaRequirement``, using the ``PackageRequirement`` constructor. >>> pr = CondaRequirement('scipy', '0.15.0') >>> pr.type 'conda' >>> pr.package 'scipy' >>> pr.version '0.15.0' >>> str(pr) 'scipy 0.15.0' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. :param repo: The repository from which the package is to be installed. """ PackageRequirement.__init__(self, 'conda', package, version, repo) def install_command(self): """ Creates the installation command for the instance of the class. >>> CondaRequirement('scipy', '0.15.0').install_command() ['conda', 'install', '--yes', 'scipy=0.15.0'] >>> CondaRequirement('scipy').install_command() ['conda', 'install', '--yes', 'scipy'] >>> CondaRequirement('bottleneck', '0.8.0', 'pandas').install_command() ['conda', 'install', '--yes', '-c', 'pandas', 'bottleneck=0.8.0'] :param return: A string with the installation command. """ conda_install = ['conda', 'install', '--yes'] conda_package_version = [ self.package + '=' + self.version if self.version else self.package ] if self.repo: result = conda_install + ['-c', self.repo] + conda_package_version else: result = conda_install + conda_package_version return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ cmd = 'conda list {} | grep "^{}"' if not run(cmd.format(self.package, self.package), stdout=Capture(), stderr=Capture()).returncode: return True return False
class CPDBear(GlobalBear): language_dict = { 'C#': 'cs', 'CPP': 'cpp', 'JavaScript': 'ecmascript', 'Fortran': 'fortran', 'Go': 'go', 'Java': 'java', 'JSP': 'jsp', 'Matlab': 'matlab', 'Octave': 'matlab', 'Objective-C': 'objectivec', 'PHP': 'php', 'PLSQL': 'plsql', 'Python': 'python', 'Python 2': 'python', 'Python 3': 'python', 'Ruby': 'ruby', 'Scala': 'scala', 'Swift': 'swift' } LANGUAGES = set(language_dict.keys()) REQUIREMENTS = { AnyOneOfRequirements([ ExecutableRequirement('cpd'), ExecutableRequirement('run.sh'), ]), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Duplication'} def run( self, language: language, minimum_tokens: int = 20, ignore_annotations: bool = False, ignore_identifiers: bool = True, ignore_literals: bool = False, ignore_usings: bool = False, skip_duplicate_files: bool = True, ): """ Checks for similar code that looks as it could be replaced to reduce redundancy. For more details see: <https://pmd.github.io/pmd-6.4.0/pmd_userdocs_cpd.html> :param language: One of the supported languages of this bear. :param minimum_tokens: The minimum token length which should be reported as a duplicate. :param ignore_annotations: Ignore language annotations when comparing text. :param ignore_identifiers: Ignore constant and variable names when comparing text. :param ignore_literals: Ignore number values and string contents when comparing text. :param ignore_usings: Ignore ``using`` directives in C#. :param skip_duplicate_files: Ignore multiple copies of files of the same name and length in comparison. """ for supported_lang in self.language_dict: if supported_lang in language: cpd_language = self.language_dict[supported_lang] break else: self.err('This bear does not support files with the extension ' "'{}'.".format(language)) return options = { '--ignore-annotations': ignore_annotations, '--ignore-identifiers': ignore_identifiers, '--ignore-literals': ignore_literals, '--ignore-usings': ignore_usings, '--skip-duplicate-files': skip_duplicate_files } files = ','.join(self.file_dict.keys()) executable = which('cpd') or which('run.sh') executable = tuple([executable] if not executable.endswith('run.sh') else [executable, 'cpd']) arguments = ('--skip-lexical-errors', '--minimum-tokens', str(minimum_tokens), '--language', cpd_language, '--files', files, '--format', 'xml') arguments += tuple(option for option, enable in options.items() if enable is True) arguments = executable + arguments stdout_output, _ = run_shell_command(arguments) if stdout_output: root = ElementTree.fromstring(stdout_output) for duplication in root.findall('duplication'): length = int(duplication.attrib['lines']) affected_code = list() for xml_file in duplication.findall('file'): filename = xml_file.attrib['path'] start_line = int(xml_file.attrib['line']) end_line = min(start_line + length - 1, len(self.file_dict[filename])) affected_code.append( SourceRange.from_values(filename, start_line=start_line, end_line=end_line)) yield Result( self, 'Duplicate code found.', affected_code, additional_info=( 'Duplicate code is an indicator ' 'that you have more code than you need. Consider' ' refactor your code to remove one of the' ' occurrences. For more information go here:' 'http://tinyurl.com/coala-clone'))
class CargoRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``cargo`` packages automatically and provides a function to check for the requirement. """ REQUIREMENTS = { ExecutableRequirement('cargo'), ExecutableRequirement('grep'), } def __init__(self, package, version=''): """ Constructs a new ``CargoRequirement``, using the ``PackageRequirement`` constructor. >>> pr = CargoRequirement('pulldown-cmark', '0.0.14') >>> pr.type 'cargo' >>> pr.package 'pulldown-cmark' >>> pr.version '0.0.14' >>> str(pr) 'pulldown-cmark 0.0.14' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'cargo', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> CargoRequirement('pulldown-cmark', '0.0.14').install_command() ['cargo', 'install', '--vers 0.0.14 pulldown-cmark'] >>> CargoRequirement('pulldown-cmark').install_command() ['cargo', 'install', 'pulldown-cmark'] :param return: A string with the installation command. """ result = [ 'cargo', 'install', '--vers ' + self.version + ' ' + self.package if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ cmd = 'cargo install --list | grep "^{}"' if not run(cmd.format(self.package), stdout=Capture(), stderr=Capture()).returncode: return True return False
class PipRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``python`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement(sys.executable)} def __init__(self, package, version=""): """ Constructs a new ``PipRequirement``, using the ``PackageRequirement`` constructor. >>> pr = PipRequirement('setuptools', '19.2') >>> pr.type 'pip' >>> pr.package 'setuptools' >>> pr.version '19.2' >>> str(pr) 'setuptools 19.2' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'pip', package, version) def install_command(self): """ Creates the installation command for the instance of the class. :param return: A list with the installation command parameters. """ result = [ sys.executable, '-m', 'pip', 'install', self.package + '==' + self.version if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ return not run(sys.executable + ' -m pip show ' + self.package, stdout=Capture(), stderr=Capture()).returncode def upgrade_package(self): """ Runs the upgrade command for the package given in a sub-process. """ run(sys.executable + ' -m pip install ' + self.package + ' --upgrade', stdout=Capture(), stderr=Capture()) def uninstall_package(self): """ Runs the uninstall command for the package given in a sub-process. """ run(sys.executable + ' -m pip uninstall -y ' + self.package, stdout=Capture(), stderr=Capture())
class ComposerRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type for ``Composer`` packages automatically and provides a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('composer')} def __init__(self, package, version=""): """ Constructs a new ``ComposerRequirement``, using the ``PackageRequirement`` constructor. >>> pr = ComposerRequirement('phpstan/phpstan', '0.6.4') >>> pr.type 'composer' >>> pr.package 'phpstan/phpstan' >>> pr.version '0.6.4' >>> str(pr) 'phpstan/phpstan 0.6.4' :param package: A string with the name of the package to be installed. :param version: A version string. Leave empty to specify latest version. """ PackageRequirement.__init__(self, 'composer', package, version) def install_command(self): """ Creates the installation command for the instance of the class. >>> ComposerRequirement('phpstan/phpstan', '0.6.4').install_command() ['composer', 'require', 'phpstan/phpstan:0.6.4'] >>> ComposerRequirement('phpstan/phpstan').install_command() ['composer', 'require', 'phpstan/phpstan'] :param return: A string with the installation command. """ result = [ 'composer', 'require', self.package + ":" + self.version if self.version else self.package ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ for cmd in ('composer show ' + self.package, 'composer global show ' + self.package): if not run(cmd, stdout=Capture(), stderr=Capture()).returncode: return True return False
class DistributionRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifies the proper type automatically. """ """ List of supported package manager with their command respectively """ SUPPORTED_PACKAGE_MANAGERS = { 'apt_get': 'apt-get', 'brew': 'brew', 'dnf': 'dnf', 'pacman': 'pacman', 'portage': 'emerge', 'xbps': 'xbps-install', 'yum': 'yum', 'zypper': 'zypper', } _available_managers = None REQUIREMENTS = { AnyOneOfRequirements( list( ExecutableRequirement(name) for name in SUPPORTED_PACKAGE_MANAGERS.values())), ExecutableRequirement('grep'), } """ List of commands that can be used to verify if the package is installed. """ CHECKER_COMMANDS = { 'apt_get': 'dpkg-query -l {}', 'brew': 'brew list {}', 'dnf': 'rpm -qa | grep "^{}"', 'pacman': 'pacman -Qs {}', 'portage': 'equery list {}', 'xbps': 'xbps-query {}', 'yum': 'rpm -qa | grep "^{}"', 'zypper': 'rpm -qa | grep "^{}"', } """ List of commands that can be used to install a package. """ _INSTALL_COMMANDS = { 'apt_get': ('apt-get', 'install', '--yes'), 'brew': ('brew', 'install'), 'dnf': ('dnf', 'install', '--assumeyes'), 'pacman': ('pacman', ), 'portage': ('emerge', ), 'xbps': ('xbps-install', '--yes'), 'yum': ('yum', 'install', '--assumeyes'), 'zypper': ('zypper', '--non-interactive', 'install'), } def __init__(self, package: str = None, version='', repo='', **package_overrides): """ Constructs a new ``DistributionRequirement``, using the ``PackageRequirement`` constructor. When a ``package`` name is provided, it is used as the package attribute, even when override package names are provided for specific package managers. >>> dr = DistributionRequirement(package='clang', ... apt_get='libclang', ... dnf='libclangg') >>> dr.package 'clang' >>> dr.packages['apt_get'] 'libclang' >>> dr.packages['dnf'] 'libclangg' When no ``package`` name is provided, the override package name for the local host's package manager is used if possible, otherwise the most common override is used. >>> dr = DistributionRequirement(unknown1='libclangg', ... unknown2='libclang', ... unknown3='libclang') >>> dr.package 'libclang' >>> dr.packages['unknown1'] 'libclangg' >>> dr.packages['unknown2'] 'libclang' >>> dr.packages['unknown3'] 'libclang' >>> from pprint import pprint >>> len(dr.REQUIREMENTS) 2 >>> not_grep_req = [dep for dep in dr.REQUIREMENTS ... if str(dep) != 'grep'][0] >>> pprint(str(not_grep_req)) ('ExecutableRequirement(apt-get) ExecutableRequirement(brew) ' 'ExecutableRequirement(dnf) ExecutableRequirement(emerge) ' 'ExecutableRequirement(pacman) ExecutableRequirement(xbps-install) ' 'ExecutableRequirement(yum) ExecutableRequirement(zypper)') :param package: A string with the name of the package to be installed. :param version: A version string. Unused. :param repo: The repository from which the package is to be installed. Unused. :param kwargs: Override package names for supported package managers. """ self._managers = None self._manager = None self.packages = package_overrides if not package and not package_overrides: raise NoArgsNotImplementedError('No package managers specified') if package: defaults = {(pm, package) for pm in self.SUPPORTED_PACKAGE_MANAGERS.keys() if pm not in package_overrides} self.packages.update(defaults) else: package = self._get_best_package_name() PackageRequirement.__init__(self, 'distribution', package, version) def _get_best_package_name(self): package_names = Counter(self.packages.values()) if len(package_names) == 1: return package_names.most_common()[0][0] try: return self.packages[self.get_available_package_manager()] except NotImplementedError: return package_names.most_common()[0][0] def get_available_package_manager(self): """ Returns the available package manager that can be used to satisfy the requirement. Raises NotImplementedError if there's no supported package manager. :return: Supported package manager key """ if not self._manager: self._manager = next(self.get_package_managers()) return self._manager def get_package_managers(self): """ Yield package managers that can satisfy requirement. :raises NotImplementedError: There are no package managers for requirement. """ found = False available_managers = self.available_package_managers supported_managers = self.SUPPORTED_PACKAGE_MANAGERS.keys() for manager in self.packages.keys(): if manager in available_managers: found = True yield manager elif manager not in supported_managers: raise NotImplementedError( "{} is not supported".format(manager)) if found: return raise NotImplementedError("This platform doesn't have any of the " 'specified package manager(s): ' '{}'.format(','.join(self.packages.keys()))) @property def package_managers(self): """ Return package managers that can satisfy requirement. :raises NotImplementedError: There are no package managers for requirement. """ if self._managers is None: self._managers = list(self.get_package_managers()) return self._managers @property def available_package_managers(self): """ Return all available package managers. :raises NotImplementedError: There are no package managers for requirement. """ if self._available_managers is None: self._available_managers = list( self.get_all_available_package_managers()) return self._available_managers @classmethod def get_all_available_package_managers(self): """ Yield the available package managers. :raises NotImplementedError: There are no supported package managers. """ found = False for manager, exe in self.SUPPORTED_PACKAGE_MANAGERS.items(): if is_executable_exists(exe): found = True yield manager if found: return raise NotImplementedError( "This platform doesn't have any of the supported package " 'manager(s): {}'.format(', '.join( self.SUPPORTED_PACKAGE_MANAGERS))) def is_installed(self): """ Check if the requirement is satisfied by calling various package managers that are mentioned. Raises NotImplementedError if executable is not defined when there's no supported package manager. :return: True if the dependency is installed, false otherwise """ package_manager = self.get_available_package_manager() command = self.CHECKER_COMMANDS[package_manager] package = self.packages[package_manager] return not run(command.format(package), stdout=Capture(), stderr=Capture()).returncode def install_command(self): """ Creates the installation command for the instance of the class. >>> DistributionRequirement('indent').install_command()[-1] 'indent' :param return: A list with the installation command. """ package_manager = self.get_available_package_manager() package = self.packages[package_manager] command = list(self._INSTALL_COMMANDS[package_manager]) command.append(package) return command
class MavenRequirement(PackageRequirement): """ This class is a subclass of ``PackageRequirement``. It specifices the proper type for ``java`` packages automatically and provide a function to check for the requirement. """ REQUIREMENTS = {ExecutableRequirement('mvn')} def __init__(self, package, version: str, repo="https://repo.maven.apache.org/maven2"): """ Constructs a new ``MavenRequirement``, using the ``PackageRequirement`` constructor. >>> mr = MavenRequirement('com.puppycrawl.tools:checkstyle', '6.15') >>> mr.type 'mvn' >>> mr.package 'com.puppycrawl.tools:checkstyle' >>> mr.version '6.15' >>> str(mr) 'com.puppycrawl.tools:checkstyle 6.15' >>> mr.repo 'https://repo.maven.apache.org/maven2' :param package: A string with the {groupId:artifactId} of the package to be installed. :param version: A version string. :param repo: The repository from which the package is to be installed. """ package_regex = '([^: /]*:[^: /]*)' package_match = (re.compile(package_regex)).match(package) if not package_match: raise ValueError( 'The package must be of the form [groupId:artifactId]') PackageRequirement.__init__(self, 'mvn', package, version, repo) def install_command(self): """ Creates the installation command for the instance of the class. >>> from pprint import pprint >>> r = MavenRequirement( ... 'com.puppycrawl.tools:checkstyle', '6.15', ... 'https://repo.maven.apache.org/maven2') >>> pprint(r.install_command()) ['mvn', 'dependency:get', '-DrepoUrl=https://repo.maven.apache.org/maven2/', '-Dartifact=com.puppycrawl.tools:checkstyle:6.15'] :param return: A string with the installation command. """ result = [ 'mvn', 'dependency:get', '-DrepoUrl={}/'.format(self.repo), '-Dartifact={}:{}'.format(self.package, self.version) ] return result def is_installed(self): """ Checks if the dependency is installed. :param return: True if dependency is installed, false otherwise. """ return not run('mvn dependency:get -Dartifact={}:{} --offline'.format( self.package, self.version), stdout=Capture(), stderr=Capture()).returncode