예제 #1
0
 def display(self):
     """Log a pretty display of the depgraph with marks if any"""
     LOG.info('DepGraph with %d nodes:-', len(self.nodes))
     LOG.info('Nodes:')
     LOG.info(wrapped(', '.join(self.nodes.keys()), prefix='\t'))
     LOG.info('Edges:')
     for n1, v in self.edges.items():
         n1_once = n1
         for n2, rl in v.items():
             LOG.info(wrapped('{0:18} <- {1:18} [{2}]'.format(
                 n1_once, n2, ', '.join([str(r) for r in rl])), prefix='\t'))
             n1_once = ' ' * len(n1_once)
             
     LOG.info('Marks:')
     marks = self.get_marks()
     for pkg in marks['install']:
         LOG.info('\t[+] %s', pkg.full_name)
     for pkg in marks['remove']:
         LOG.info('\t[-] %s', pkg.full_name)
     for p1, p2 in marks['change']:
         LOG.info('\t[c] %s -> %s', p1.full_name, p2.full_name)
         if p1.version_key > p2.version_key:
             # show reasonf for downgrade
             because = 'because '
             for name0, rl in self.edges[p1.name].items():
                 for r in rl:
                     LOG.info(wrapped('\t    {0}{1} requires {2}'.format(
                         because, name0, r)))
                     because = ' ' * len(because)  # reset
예제 #2
0
    def display(self):
        """Log a pretty display of the depgraph with marks if any"""
        LOG.info('DepGraph with %d nodes:-', len(self.nodes))
        LOG.info('Nodes:')
        LOG.info(wrapped(', '.join(self.nodes.keys()), prefix='\t'))
        LOG.info('Edges:')
        for n1, v in self.edges.items():
            n1_once = n1
            for n2, rl in v.items():
                LOG.info(
                    wrapped('{0:18} <- {1:18} [{2}]'.format(
                        n1_once, n2, ', '.join([str(r) for r in rl])),
                            prefix='\t'))
                n1_once = ' ' * len(n1_once)

        LOG.info('Marks:')
        marks = self.get_marks()
        for pkg in marks['install']:
            LOG.info('\t[+] %s', pkg.full_name)
        for pkg in marks['remove']:
            LOG.info('\t[-] %s', pkg.full_name)
        for p1, p2 in marks['change']:
            LOG.info('\t[c] %s -> %s', p1.full_name, p2.full_name)
            if p1.version_key > p2.version_key:
                # show reasonf for downgrade
                because = 'because '
                for name0, rl in self.edges[p1.name].items():
                    for r in rl:
                        LOG.info(
                            wrapped('\t    {0}{1} requires {2}'.format(
                                because, name0, r)))
                        because = ' ' * len(because)  # reset
예제 #3
0
파일: fs.py 프로젝트: Augus-Wang/xunlei_vip
    def download_package(self, package):
        assert type(package) is RepoPackage

        sh.mkdirs(DOWNLOAD_CACHE)
        
        
        auth = licensing.get_be_license_auth()
        send_license = package.requires_be_license
        license_installed = auth is not None
        
        # A license is required for this package, but no license is installed
        if not license_installed and send_license:
            msg = '\n'.join([
                    wrapped('If you have purchased ActivePython Business Edition, '
                            'please login to your account at:'),
                    '  https://account.activestate.com/',
                    wrapped('and download and run the license installer for your '
                            'platform.'),
                    '',
                    wrapped('Please visit <%s> to learn more about the '
                            'ActivePython Business Edition offering.' % \
                                licensing.BE_HOME_PAGE)])
            raise error.PackageAccessError(
                package, 'requires Business Edition subscription', msg)
       
        try:
            # At this point, the user is already known to have a BE license
            file_location, _ = net.download_file(
                package.download_url,
                DOWNLOAD_CACHE,
                dict(
                    auth=auth,
                    use_cache=True,  # XXX: this introduces network delay
                                     # (If-None-Match) despite having the file
                                     # in download cache
                                     # TODO: abstract client.store...autosync
                    save_properties=True,
                    start_info='{{status}}: [{0}] {1} {2}'.format(
                        six.moves.urlparse(package.download_url).netloc,
                        package.name,
                        package.printable_version)),
                interactive=self.pypmenv.options['interactive'])
        except six.moves.HTTPError as e:
            reason = str(e)
            LOG.debug("HTTPError while accessing URL: %s -- reason: %s",
                      package.download_url, reason)
            
            if send_license and e.code in (401, 402, 403):
                msg = wrapped(
                    'Your ActivePython Business Edition subscription seems to '
                    'have expired. Please visit your account at '
                    'https://account.activestate.com/ to renew your subscription.'
                )
            else:
                msg = ''
                
            raise error.PackageAccessError(package, reason, msg)

        return file_location
예제 #4
0
    def download_package(self, package):
        assert type(package) is RepoPackage

        sh.mkdirs(DOWNLOAD_CACHE)

        auth = licensing.get_be_license_auth()
        send_license = package.requires_be_license
        license_installed = auth is not None

        # A license is required for this package, but no license is installed
        if not license_installed and send_license:
            msg = '\n'.join([
                    wrapped('If you have purchased ActivePython Business Edition, '
                            'please login to your account at:'),
                    '  https://account.activestate.com/',
                    wrapped('and download and run the license installer for your '
                            'platform.'),
                    '',
                    wrapped('Please visit <%s> to learn more about the '
                            'ActivePython Business Edition offering.' % \
                                licensing.BE_HOME_PAGE)])
            raise error.PackageAccessError(
                package, 'requires Business Edition subscription', msg)

        try:
            # At this point, the user is already known to have a BE license
            file_location, _ = net.download_file(
                package.download_url,
                DOWNLOAD_CACHE,
                dict(
                    auth=auth,
                    use_cache=True,  # XXX: this introduces network delay
                    # (If-None-Match) despite having the file
                    # in download cache
                    # TODO: abstract client.store...autosync
                    save_properties=True,
                    start_info='{{status}}: [{0}] {1} {2}'.format(
                        six.moves.urlparse(package.download_url).netloc,
                        package.name, package.printable_version)),
                interactive=self.pypmenv.options['interactive'])
        except six.moves.HTTPError as e:
            reason = str(e)
            LOG.debug("HTTPError while accessing URL: %s -- reason: %s",
                      package.download_url, reason)

            if send_license and e.code in (401, 402, 403):
                msg = wrapped(
                    'Your ActivePython Business Edition subscription seems to '
                    'have expired. Please visit your account at '
                    'https://account.activestate.com/ to renew your subscription.'
                )
            else:
                msg = ''

            raise error.PackageAccessError(package, reason, msg)

        return file_location
예제 #5
0
    def download_package(self, package):
        assert type(package) is RepoPackage

        sh.mkdirs(DOWNLOAD_CACHE)
        
        LOG.info('Get: [%s] %s %s',
                 six.moves.urlparse(package.download_url).netloc,
                 package.name,
                 package.printable_version)
        
        auth = licensing.get_be_license_auth()
        send_license = package.requires_be_license
        license_installed = auth is not None
        
        # A license is required for this package, but no license is installed
        if not license_installed and send_license:
            msg = '\n'.join([
                    wrapped('If you have purchased ActivePython Business Edition, '
                            'please login to your account at:'),
                    '  https://account.activestate.com/',
                    wrapped('and download and run the license installer for your '
                            'platform.'),
                    '',
                    wrapped('Please visit <%s> to learn more about the '
                            'ActivePython Business Edition offering.' % \
                                licensing.BE_HOME_PAGE)])
            raise error.PackageAccessError(
                package, 'requires Business Edition subscription', msg)
       
        try:
            # At this point, the user is already known to have a BE license
            file_location = net.download_file(
                package.download_url,
                DOWNLOAD_CACHE,
                dict(auth=auth),
                interactive=self.pypmenv.options['interactive'])
        except six.moves.HTTPError as e:
            reason = str(e)
            LOG.debug("HTTPError while accessing URL: %s -- reason: %s",
                      package.download_url, reason)
            
            if send_license and e.code in (401, 402, 403):
                msg = wrapped(
                    'Your ActivePython Business Edition subscription seems to '
                    'have expired. Please visit your account at '
                    'https://account.activestate.com/ to renew your subscription.'
                )
            else:
                msg = ''
                
            raise error.PackageAccessError(package, reason, msg)

        return file_location
예제 #6
0
파일: error.py 프로젝트: wyj5230/xunlei_vip
 def __init__(self, requirement, required_by=None):
     self.requirement = requirement
     self.required_by = required_by
     msg =  'no such package found for requirement "%s"' % requirement
     if required_by:
         msg += '; required by "%s"' % required_by
     msg += "; try PyPM Index:  http://code.activestate.com/pypm/search:%s/" % requirement
     super(PackageNotFound, self).__init__(wrapped(msg))
예제 #7
0
 def mark_show(verb, list, item_print_func):
     if not list:
         return
     messages.append(
         'The following packages will be {verb} {0}:\n{1}'.format(
             self.pypmenv.pyenv.printable_location,
             wrapped(' '.join(item_print_func(item) for item in list),
                     prefix=' ',
                     break_on_hyphens=False),
             verb=verb))
예제 #8
0
 def mark_show(verb, list, item_print_func):
     if not list:
         return
     messages.append(
         'The following packages will be {verb} {0}:\n{1}'.format(
             self.pypmenv.pyenv.printable_location,
             wrapped(' '.join(item_print_func(item) for item in list),
                     prefix=' ',
                     break_on_hyphens=False),
             verb=verb))
예제 #9
0
def _pep370_fix_path_unix():
    """If ~/.local/bin is not in $PATH, automatically add them
    
    Do this only with the user's consent. And do not run this check more than
    once (i.e., run only when PyPM is *first run*).
    """
    if sys.platform.startswith('win'):
        return  # MSI does this on Windows

    # Proceed only when the terminal is interactive and was never run before
    isatty = (sys.stdin.isatty() and sys.stdout.isatty())
    firstrun_file = P.join(application.locations.user_cache_dir,
                           '.firstrun-pep370')
    if (not isatty) or P.exists(firstrun_file):
        return

    import site
    from datetime import datetime
    pathenv = [
        P.abspath(x.strip()) for x in os.environ.get('PATH', '').split(':')
    ]
    binpath = P.abspath(P.join(site.USER_BASE, 'bin'))
    profile = P.expanduser('~/.profile' if sys.platform ==
                           'darwin' else '~/.bashrc')
    profile_lines = [
        '# PEP 370 PATH added by PyPM on %s' % datetime.now(),
        'export PATH=%s:$PATH' % binpath,
    ]
    already_in_profile = P.exists(profile) and profile_lines[1] in [
        l.strip() for l in open(profile).readlines()
    ]

    # Proceed only if ~/.local/bin is neither in $PATH, nor added to profile
    if binpath in pathenv or already_in_profile:
        return

    # Add to profile on the user's consent
    msg = ('Packages will install their script files to "%s" '
           '(as per PEP 370). This directory is not yet in your $PATH. '
           'Would you like PyPM to add it by appending to "%s"?') % (
               concise_path(binpath), concise_path(profile))
    if textui.askyesno(wrapped(msg, '*** '), default=True):
        if P.exists(profile):
            sh.cp(profile, profile + '.bak')  # take a backup first

        with open(profile, 'a') as f:
            f.write('\n%s\n' % '\n'.join(profile_lines))
        print('You may now reopen your shell for the changes to take effect.')

    sh.mkdirs(P.dirname(firstrun_file))
    with open(firstrun_file, 'w') as f:
        pass  # prevent future runs
예제 #10
0
def _pep370_fix_path_unix():
    """If ~/.local/bin is not in $PATH, automatically add them
    
    Do this only with the user's consent. And do not run this check more than
    once (i.e., run only when PyPM is *first run*).
    """
    if sys.platform.startswith('win'):
        return # MSI does this on Windows

    # Proceed only when the terminal is interactive and was never run before
    isatty = (sys.stdin.isatty() and sys.stdout.isatty())
    firstrun_file = P.join(application.locations.user_cache_dir, '.firstrun-pep370')
    if (not isatty) or P.exists(firstrun_file):
        return
        
    import site
    from datetime import datetime
    pathenv = [P.abspath(x.strip()) for x in os.environ.get('PATH', '').split(':')]
    binpath = P.abspath(P.join(site.USER_BASE, 'bin'))
    profile = P.expanduser('~/.profile' if sys.platform == 'darwin' else '~/.bashrc')
    profile_lines = [
        '# PEP 370 PATH added by PyPM on %s' % datetime.now(),
        'export PATH=%s:$PATH' % binpath,
    ]
    already_in_profile = P.exists(profile) and profile_lines[1] in [
        l.strip() for l in open(profile).readlines()
    ]
    
    # Proceed only if ~/.local/bin is neither in $PATH, nor added to profile
    if binpath in pathenv or already_in_profile:
        return
    
    # Add to profile on the user's consent
    msg = (
        'Packages install script files to "%s" '
        '(as per PEP 370). This directory is not yet in your $PATH. '
        'Would you like PyPM to add it to $PATH by modifying (with backup) "%s"?'
    ) % (binpath, profile)
    if textui.askyesno(wrapped(msg, '*** '), default=True):
        if P.exists(profile):
            sh.cp(profile, profile+'.bak') # take a backup first
            
        with open(profile, 'a') as f:
            f.write('\n%s\n' % '\n'.join(profile_lines))
        print ('You may now reopen your shell for the changes to take effect.')
            
    sh.mkdirs(P.dirname(firstrun_file))
    with open(firstrun_file, 'w') as f: pass # prevent future runs
예제 #11
0
 def __init__(self, name, version):
     msg = 'package "{0}{1}" is not installed'.format(
         name,
         '-'+version if version else '')
     super(NoPackageInstalled, self).__init__(wrapped(msg))
예제 #12
0
 def __init__(self, requirement, required_by=None):
     msg =  'no such package "%s"; see pypm.activestate.com' % requirement
     if required_by:
         msg += '; required by "%s"' % required_by
     super(PackageNotFound, self).__init__(wrapped(msg))
예제 #13
0
    def do_show(self, subcmd, opts, name, version=None):
        """${cmd_name}: Display detailed information about a package

        If the package is already installed, show the location of the
        site-packages directory under which it is installed.
        
        ${cmd_usage}
        ${cmd_option_list}
        """
        with self.bootstrapped():
            self._autosync()
            
            pkg = self.pypmenv.repo_store.find_package(name, version)
            dependencies = pkg.install_requires['']
            extra_dependencies = []
            for extra in pkg.install_requires:
                if extra == '': continue
                extra_dependencies.append('`pypm install {0}[{1}]` ->\n    {2}'.format(
                    pkg.name,
                    extra,
                    ',\n    '.join(pkg.install_requires[extra])))
            
            # Show package metadata
            LOG.info('Name: %s', pkg.name)
            LOG.info('Latest version: %s', pkg.printable_version)
            if pkg.author or pkg.author_email:
                LOG.info('Author: %s %s',
                         pkg.author,
                         pkg.author_email and '<%s>' % pkg.author_email or '')
            LOG.info('Summary: %s', pkg.summary)
            if pkg.home_page:
                LOG.info('Home Page: %s', pkg.home_page)
            if pkg.license:
                LOG.info('License: %s', pkg.license)
            
            # Show package dependencies
            if dependencies:
                LOG.info('Dependencies:')
                for dep in dependencies:
                    LOG.info(' %s', dep)
                if extra_dependencies:
                    LOG.info('Optional dependencies:')
                    for ed in extra_dependencies:
                        LOG.info(' %s', ed)
                        
            # Optionally, show packages depending on it
            if opts.rdepends:
                LOG.info('Depended by:')
                rdependencies = {}
                for rpkg in self.pypmenv.repo_store._query():
                    for req in rpkg.install_requires['']:
                        req = Requirement.parse(req)
                        if pkg.name == req_name(req):
                            if pkg.version in req:
                                prev_rpkg = rdependencies.get(rpkg.name, None)
                                if (not prev_rpkg) or (
                                    rpkg.version_key > prev_rpkg.version_key):
                                        rdependencies[rpkg.name] = rpkg
                if rdependencies:
                    LOG.info(wrapped(
                        ', '.join(sorted(
                            [p.full_name for p in rdependencies.values()])),
                        prefix=' ',
                        break_on_hyphens=False))
            
            # Show list of (older) versions available in the repository
            if not version:
                pkglist = self.pypmenv.repo_store.find_package_releases(name)
                LOG.info('Available versions: %s', ', '.join(
                    [p.printable_version for p in pkglist]))
            
            # Status: is this package installed or not? Does it require BE?
            try:
                ipkg = self.pypmenv.installed_store.find_only_package(name)
            except error.NoPackageInstalled:
                LOG.info('Status: Not installed')
                if pkg.requires_be_license and not licensing.user_has_be_license():
                    LOG.info(
                        'NOTE: This package requires a valid Business Edition '
                        'license. Please visit %s for more details.',
                        licensing.BE_HOME_PAGE)
            else:
                # Is this package installed because another package?
                depgraph = installer.PyPMDepGraph(self.pypmenv)
                required_by = depgraph.edges[ipkg.name].items()
                if required_by:
                    LOG.info('Required by:')
                    for rpkg, rl in required_by:
                        LOG.info(' %s [%s]', rpkg, req2str(*rl))
                    
                LOG.info('Status: Already installed (%s) at %s',
                         ipkg.printable_version,
                         self.pypmenv.pyenv.printable_location)
                # Is a newer version available for upgrade?
                if ipkg.version_key < pkg.version_key:
                    # TODO: Need --force
                    LOG.info('Status: '
                             'A newer version (%s) is available. '
                             'Type "pypm install %s" to upgrade',
                             pkg.printable_version,
                             pkg.name)

            # Show postinstall notes for this package
            for note in pkg.get_notes(postinstall=True):
                LOG.info('***NOTE***: %s', note['content'].strip())
                    
            if opts.open_home_page:
                import webbrowser
                u = 'http://code.activestate.com/pypm/{0}/'.format(pkg.name)
                webbrowser.open(pkg.home_page or u)
                
            return pkg
예제 #14
0
파일: error.py 프로젝트: wyj5230/xunlei_vip
 def __init__(self, name, version):
     msg = 'package "{0}{1}" is not installed'.format(
         name,
         '-'+version if version else '')
     super(NoPackageInstalled, self).__init__(wrapped(msg))
예제 #15
0
    def _extract_to_install_scheme(self, bpkgfile, name):
        pyenv = self.pypmenv.pyenv
        # Install scheme used by the build environment (i.e., pyenv used by
        # pypm-builder on our build machines).
        as_build_scheme = {
            'win': {
                'purelib': 'lib/site-packages',
                'stdlib': 'lib',
                'scripts': 'scripts',
            },
            'unix': {
                'purelib': 'lib/python{0}/site-packages'.format(pyenv.pyver),
                'stdlib': 'lib/python{0}'.format(pyenv.pyver),
                'scripts': 'bin',
            },
        }
        plat = PLATNAME.startswith('win') and 'win' or 'unix'

        # Scheme used by pyenv
        pyenv_scheme = {
            'purelib': self._pyenv_scheme_path('purelib'),
            'stdlib': self._pyenv_scheme_path('stdlib'),
            'scripts': self._pyenv_scheme_path('scripts'),
        }

        files_to_overwrite = []
        force_overwrite = self.pypmenv.options['force']
        # Hack #1: Don't check for distribute and pip, as virtualenvs usually
        # already have a copy of them installed.
        if name in ('distribute', 'setuptools', 'pip'):
            force_overwrite = True

        with bpkgfile.extract_over2(pyenv.base_dir) as tf:
            for tinfo in tf.getmembers():
                # Replace AS build virtualenv scheme with the user's scheme
                # Eg: lib/site-packages/XYZ -> %APPDATA%/Python/Python26/XYZ
                for name, prefix in as_build_scheme[plat].items():
                    if tinfo.name.lower().startswith(prefix):
                        old = tinfo.name
                        new = pyenv_scheme[name] + old[len(prefix):]
                        if new != old:
                            LOG.debug('fs:extract: transforming "%s" to "%s"',
                                      old, new)
                            tinfo.name = new

                # Check for overwrites
                if os.path.lexists(
                        tinfo.name) and not os.path.isdir(tinfo.name):
                    # Hack #2: allow overwriting of *.pth files (setuptools
                    # hackishness) eg: [...]/site-packages/setuptools.pth
                    if not tinfo.name.endswith('.pth'):
                        files_to_overwrite.append(tinfo.name)

            if files_to_overwrite:

                LOG.debug(
                    'install requires overwriting of %d files:\n%s',
                    len(files_to_overwrite), '\n'.join([
                        os.path.join(pyenv.base_dir, f)
                        for f in files_to_overwrite
                    ]))
                if force_overwrite:
                    LOG.warn('overwriting %d files' % len(files_to_overwrite))
                else:
                    errmsg = [
                        'cannot overwrite "%s"' % concise_path(
                            os.path.join(pyenv.base_dir,
                                         files_to_overwrite[0]))
                    ]
                    if len(files_to_overwrite) > 1:
                        errmsg.append(' (and %d other files)' %
                                      (len(files_to_overwrite) - 1, ))
                    errmsg.append(
                        '; run pypm as "pypm --force ..." to overwrite anyway')
                    if len(files_to_overwrite) > 1:
                        errmsg.append(
                            '; run "pypm log" to see the full list of files to be overwritten'
                        )
                    raise IOError(wrapped(''.join(errmsg)))

            return tf.getnames()
예제 #16
0
    def _extract_to_install_scheme(self, bpkgfile, name):
        pyenv = self.pypmenv.pyenv
        # Install scheme used by the build environment (i.e., pyenv used by
        # pypm-builder on our build machines).
        as_build_scheme = {
            'win': {
                'purelib': 'lib/site-packages',
                'stdlib':  'lib',
                'scripts': 'scripts',
            },
            'unix': {
                'purelib': 'lib/python{0}/site-packages'.format(pyenv.pyver),
                'stdlib':  'lib/python{0}'.format(pyenv.pyver),
                'scripts': 'bin',
            },
        }
        plat = PLATNAME.startswith('win') and 'win' or 'unix'

        # Scheme used by pyenv
        pyenv_scheme = {
            'purelib': self._pyenv_scheme_path('purelib'),
            'stdlib':  self._pyenv_scheme_path('stdlib'),
            'scripts': self._pyenv_scheme_path('scripts'),
        }
        
        files_to_overwrite = []
        force_overwrite = self.pypmenv.options['force']
        # Hack #1: Don't check for distribute and pip, as virtualenvs usually
        # already have a copy of them installed.
        if name in ('distribute', 'setuptools', 'pip'):
            force_overwrite = True

        with bpkgfile.extract_over2(pyenv.base_dir) as tf:
            for tinfo in tf.getmembers():
                # Replace AS build virtualenv scheme with the user's scheme
                # Eg: lib/site-packages/XYZ -> %APPDATA%/Python/Python26/XYZ
                for name, prefix in as_build_scheme[plat].items():
                    if tinfo.name.lower().startswith(prefix):
                        old = tinfo.name
                        new = pyenv_scheme[name] + old[len(prefix):]
                        if new != old:
                            LOG.debug('fs:extract: transforming "%s" to "%s"',
                                      old, new)
                            tinfo.name = new
                            
                # Check for overwrites
                if os.path.exists(tinfo.name) and not os.path.isdir(tinfo.name):
                    # Hack #2: allow overwriting of *.pth files (setuptools
                    # hackishness) eg: [...]/site-packages/setuptools.pth
                    if not tinfo.name.endswith('.pth'):
                        files_to_overwrite.append(tinfo.name)
                    
            if files_to_overwrite:
                
                LOG.debug(
                    'install requires overwriting of %d files:\n%s',
                    len(files_to_overwrite),
                   '\n'.join([os.path.join(pyenv.base_dir, f)
                              for f in files_to_overwrite]))
                if force_overwrite:
                    LOG.warn('overwriting %d files' % len(files_to_overwrite))
                else:
                    errmsg = ['cannot overwrite "%s"' % concise_path(os.path.join(
                        pyenv.base_dir, files_to_overwrite[0]))]
                    if len(files_to_overwrite) > 1:
                        errmsg.append(' (and %d other files)' % (len(files_to_overwrite)-1,))
                    errmsg.append('; run pypm as "pypm --force ..." to overwrite anyway')
                    if len(files_to_overwrite) > 1:
                        errmsg.append('; run "pypm log" to see the full list of files to be overwritten')
                    raise IOError(wrapped(''.join(errmsg)))

            return tf.getnames()