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()
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
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
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
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
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
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
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
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