Exemple #1
0
def execute(args, parser):
    import sys
    import json

    import conda.bundle as bundle
    from conda.fetch import TmpDownload

    if not (args.create or args.extract or args.metadump):
        sys.exit("""Error:
    either one of the following options is required:
       -c/--create  -x/--extract  --metadump
    (see -h for more details)""")
    prefix = common.get_prefix(args)
    if args.no_env:
        prefix = None

    if args.create:
        if args.extra_meta:
            with open(args.extra_meta) as fi:
                extra = json.load(fi)
            if not isinstance(extra, dict):
                sys.exit('Error: no dictionary in: %s' % args.extra_meta)
        else:
            extra = None

        bundle.warn = []
        out_path = bundle.create_bundle(prefix, args.data_path,
                                        args.bundle_name, extra)
        if args.json:
            d = dict(path=out_path, warnings=bundle.warn)
            json.dump(d, sys.stdout, indent=2, sort_keys=True)
        else:
            print(out_path)

    if args.extract:
        if args.data_path or args.extra_meta:
            sys.exit("""\
Error: -x/--extract does not allow --data-path or --extra-meta""")

        with TmpDownload(args.extract, verbose=not args.quiet) as path:
            bundle.clone_bundle(path, prefix, args.bundle_name)

    if args.metadump:
        import tarfile

        with TmpDownload(args.metadump, verbose=not args.quiet) as path:
            try:
                t = tarfile.open(path, 'r:*')
                f = t.extractfile('info/index.json')
                sys.stdout.write(f.read())
                sys.stdout.write('\n')
            except IOError:
                sys.exit("Error: no such file: %s" % path)
            except tarfile.ReadError:
                sys.exit("Error: bad tar archive: %s" % path)
            except KeyError:
                sys.exit("Error: no archive '%s' in: %s" % (bundle.BMJ, path))
            t.close()
Exemple #2
0
    def test_tmpDownload(self):
        url = "https://repo.continuum.io/pkgs/free/osx-64/appscript-1.0.1-py27_0.tar.bz2"
        with TmpDownload(url) as dst:
            assert exists(dst)
            assert isfile(dst)

        msg = "Rock and Roll Never Die"
        with TmpDownload(msg) as result:
            assert result == msg
Exemple #3
0
    def test_tmpDownload(self):
        with env_var('CONDA_REMOTE_CONNECT_TIMEOUT_SECS', 1, reset_context):
            with env_var('CONDA_REMOTE_READ_TIMEOUT_SECS', 1, reset_context):
                with env_var('CONDA_REMOTE_MAX_RETRIES', 1, reset_context):
                    url = "https://repo.continuum.io/pkgs/free/osx-64/appscript-1.0.1-py27_0.tar.bz2"
                    with TmpDownload(url) as dst:
                        assert exists(dst)
                        assert isfile(dst)

                    msg = "Rock and Roll Never Die"
                    with TmpDownload(msg) as result:
                        assert result == msg
Exemple #4
0
def specs_from_url(url, json=False):
    from conda.fetch import TmpDownload

    explicit = False
    with TmpDownload(url, verbose=False) as path:
        specs = []
        try:
            for line in open(path):
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                if line == '@EXPLICIT':
                    explicit = True
                if explicit:
                    specs.append(line)
                    continue
                spec = spec_from_line(line)
                if spec is None:
                    error_and_exit("could not parse '%s' in: %s" % (line, url),
                                   json=json,
                                   error_type="ValueError")
                specs.append(spec)
        except IOError:
            error_and_exit('cannot open file: %s' % path,
                           json=json,
                           error_type="IOError")
    return specs
Exemple #5
0
def get_checksum_and_size(download_url):
    '''
    Looks in the CHECKSUMS file in the same directory as the file specified
    at download_url and returns the md5 hash and file size.
    '''
    base_url = dirname(download_url)
    filename = basename(download_url)
    with TmpDownload(base_url + '/CHECKSUMS') as checksum_path:
        with open(checksum_path) as checksum_file:
            found_file = False
            md5 = None
            size = None
            for line in checksum_file:
                line = line.strip()
                if line.startswith("'" + filename):
                    found_file = True
                elif found_file:
                    if line.startswith("'md5'"):
                        md5 = line.split("=>")[1].strip("', ")
                    elif line.startswith("'size"):
                        size = line.split("=>")[1].strip("', ")
                        break
                    # This should never happen, but just in case
                    elif line.startswith('}'):
                        break
    return md5, size
Exemple #6
0
def dist_for_module(cpan_url, module, perl_version):
    '''
    Given a name that could be a module or a distribution, return the
    distribution.
    '''
    # First check if its already a distribution
    try:
        with TmpDownload('{}/v0/release/{}'.format(cpan_url,
                                                   module)) as json_path:
            with contextlib.closing(gzip.open(json_path)) as dist_json_file:
                rel_dict = json.loads(
                    dist_json_file.read().decode('utf-8-sig'))
    # If there was an error, module may actually be a module
    except RuntimeError:
        rel_dict = None
    else:
        distribution = module

    # Check if
    if rel_dict is None:
        try:
            with TmpDownload('{}/v0/module/{}'.format(cpan_url,
                                                      module)) as json_path:
                with contextlib.closing(
                        gzip.open(json_path)) as dist_json_file:
                    mod_dict = json.loads(
                        dist_json_file.read().decode('utf-8-sig'))
        # If there was an error, report it
        except RuntimeError:
            core_version = core_module_version(module, perl_version)
            if core_version is None:
                sys.exit(
                    ('Error: Could not find module or distribution named' +
                     ' %s on MetaCPAN') % module)
            else:
                distribution = 'perl'
        else:
            distribution = mod_dict['distribution']

    return distribution
Exemple #7
0
def specs_from_url(url):
    from conda.fetch import TmpDownload

    with TmpDownload(url, verbose=False) as path:
        specs = []
        try:
            for line in open(path):
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                specs.append(arg2spec(line))
        except IOError:
            sys.exit('Error: cannot open file: %s' % path)
    return specs
Exemple #8
0
def specs_from_url(url):
    from conda.fetch import TmpDownload

    with TmpDownload(url, verbose=False) as path:
        specs = []
        try:
            for line in open(path):
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                spec = spec_from_line(line)
                if spec is None:
                    sys.exit("Error: could not parse '%s' in: %s" %
                             (line, url))
                specs.append(spec)
        except IOError:
            sys.exit('Error: cannot open file: %s' % path)
    return specs
Exemple #9
0
def get_release_info(cpan_url, package, version, perl_version,
                     dependency=False):
    '''
    Return a dictionary of the JSON information stored at cpan.metacpan.org
    corresponding to the given package/dist/module.
    '''
    # Transform module name to dist name if necessary
    orig_package = package
    package = dist_for_module(cpan_url, package, perl_version)
    package = package.replace('::', '-')

    # Get latest info to find author, which is necessary for retrieving a
    # specific version
    try:
        with TmpDownload('{}/v0/release/{}'.format(cpan_url, package)) as json_path:
            with contextlib.closing(gzip.open(json_path)) as dist_json_file:
                rel_dict = json.loads(dist_json_file.read().decode('utf-8-sig'))
                rel_dict['version'] = rel_dict['version'].lstrip('v')
    except RuntimeError:
        core_version = core_module_version(orig_package, perl_version)
        if core_version is not None and (version is None or
                                         (version == core_version)):
            print(("WARNING: {0} is not available on MetaCPAN, but it's a " +
                   "core module, so we do not actually need the source file, " +
                   "and are omitting the URL and MD5 from the recipe " +
                   "entirely.").format(orig_package))
            rel_dict = {'version': str(core_version), 'download_url': '',
                        'license': ['perl_5'], 'dependency': {}}
        else:
            sys.exit(("Error: Could not find any versions of package %s on " +
                      "MetaCPAN.") % (orig_package))

    # If the latest isn't the version we're looking for, we have to do another
    # request
    version_str = str(version)
    if (version is not None) and (version != LooseVersion('0') and
            (rel_dict['version'] != version_str)):
        author = rel_dict['author']
        try:
            with TmpDownload('{}/v0/release/{}/{}-{}'.format(cpan_url,
                                                             author,
                                                             package,
                                                             version_str)) as json_path:
                with contextlib.closing(gzip.open(json_path)) as dist_json_file:
                    new_rel_dict = json.loads(dist_json_file.read().decode('utf-8-sig'))
                    new_rel_dict['version'] = new_rel_dict['version'].lstrip()
        # Check if this is a core module, and don't die if it is
        except RuntimeError:
            core_version = core_module_version(orig_package, perl_version)
            if core_version is not None and (version == core_version):
                print(("WARNING: Version {0} of {1} is not available on " +
                       "MetaCPAN, but it's a core module, so we do not " +
                       "actually need the source file, and are omitting the " +
                       "URL and MD5 from the recipe " +
                       "entirely.").format(version_str, orig_package))
                rel_dict['version'] = version_str
                rel_dict['download_url'] = ''
            elif LooseVersion(rel_dict['version']) > version:
                if not dependency:
                    print(("WARNING: Version {0} of {1} is not available on " +
                           "MetaCPAN, but a newer version ({2}) is, so we " +
                           "will use that " +
                           "instead.").format(version_str, orig_package,
                                              rel_dict['version']))
            else:
                raise InvalidReleaseError(("Version %s of %s is not available" +
                                           " on MetaCPAN. You may want to use" +
                                           " the latest version, %s, instead.")
                                          % (version_str, orig_package,
                                             rel_dict['version']))
        else:
            rel_dict = new_rel_dict

    return rel_dict