예제 #1
0
    def test_CreatePythonEntryPointAction_noarch_python(self):
        target_python_version = '%d.%d' % sys.version_info[:2]
        transaction_context = {
            'target_python_version': target_python_version,
        }
        package_info = AttrDict(package_metadata=AttrDict(noarch=AttrDict(
            type=NoarchType.python,
            entry_points=(
                'command1=some.module:main',
                'command2=another.somewhere:go',
            ),
        )))

        axns = CreatePythonEntryPointAction.create_actions(
            transaction_context, package_info, self.prefix, LinkType.hardlink)
        grouped_axns = groupby(lambda ax: isinstance(ax, LinkPathAction), axns)
        windows_exe_axns = grouped_axns.get(True, ())
        assert len(windows_exe_axns) == (2 if on_win else 0)
        py_ep_axns = grouped_axns.get(False, ())
        assert len(py_ep_axns) == 2

        py_ep_axn = py_ep_axns[0]

        command, module, func = parse_entry_point_def(
            'command1=some.module:main')
        assert command == 'command1'
        if on_win:
            target_short_path = "%s\\%s-script.py" % (
                get_bin_directory_short_path(), command)
        else:
            target_short_path = "%s/%s" % (get_bin_directory_short_path(),
                                           command)
        assert py_ep_axn.target_full_path == join(self.prefix,
                                                  target_short_path)
        assert py_ep_axn.module == module == 'some.module'
        assert py_ep_axn.func == func == 'main'

        mkdir_p(dirname(py_ep_axn.target_full_path))
        py_ep_axn.execute()
        assert isfile(py_ep_axn.target_full_path)
        if not on_win:
            assert is_executable(py_ep_axn.target_full_path)
        with open(py_ep_axn.target_full_path) as fh:
            lines = fh.readlines()
            first_line = lines[0].strip()
            last_line = lines[-1].strip()
        if not on_win:
            python_full_path = join(
                self.prefix, get_python_short_path(target_python_version))
            assert first_line == "#!%s" % python_full_path
        assert last_line == "sys.exit(%s())" % func

        py_ep_axn.reverse()
        assert not isfile(py_ep_axn.target_full_path)

        if on_win:
            windows_exe_axn = windows_exe_axns[0]
            target_short_path = "%s\\%s.exe" % (get_bin_directory_short_path(),
                                                command)
            assert windows_exe_axn.target_full_path == join(
                self.prefix, target_short_path)

            mkdir_p(dirname(windows_exe_axn.target_full_path))
            windows_exe_axn.verify()
            windows_exe_axn.execute()
            assert isfile(windows_exe_axn.target_full_path)
            assert is_executable(windows_exe_axn.target_full_path)

            src = compute_md5sum(
                join(context.conda_prefix, 'Scripts/conda.exe'))
            assert src == compute_md5sum(windows_exe_axn.target_full_path)

            windows_exe_axn.reverse()
            assert not isfile(windows_exe_axn.target_full_path)
예제 #2
0
    def test_CreatePythonEntryPointAction_noarch_python(self):
        target_python_version = '%d.%d' % sys.version_info[:2]
        transaction_context = {
            'target_python_version': target_python_version,
        }
        package_info = AttrDict(package_metadata=AttrDict(noarch=AttrDict(
            type=NoarchType.python,
            entry_points=(
                'command1=some.module:main',
                'command2=another.somewhere:go',
            ),
        )))

        axns = CreatePythonEntryPointAction.create_actions(transaction_context, package_info,
                                                           self.prefix, LinkType.hardlink)
        grouped_axns = groupby(lambda ax: isinstance(ax, LinkPathAction), axns)
        windows_exe_axns = grouped_axns.get(True, ())
        assert len(windows_exe_axns) == (2 if on_win else 0)
        py_ep_axns = grouped_axns.get(False, ())
        assert len(py_ep_axns) == 2

        py_ep_axn = py_ep_axns[0]

        command, module, func = parse_entry_point_def('command1=some.module:main')
        assert command == 'command1'
        if on_win:
            target_short_path = "%s\\%s-script.py" % (get_bin_directory_short_path(), command)
        else:
            target_short_path = "%s/%s" % (get_bin_directory_short_path(), command)
        assert py_ep_axn.target_full_path == join(self.prefix, target_short_path)
        assert py_ep_axn.module == module == 'some.module'
        assert py_ep_axn.func == func == 'main'

        mkdir_p(dirname(py_ep_axn.target_full_path))
        py_ep_axn.execute()
        assert isfile(py_ep_axn.target_full_path)
        if not on_win:
            assert is_executable(py_ep_axn.target_full_path)
        with open(py_ep_axn.target_full_path) as fh:
            lines = fh.readlines()
            first_line = lines[0].strip()
            last_line = lines[-1].strip()
        if not on_win:
            python_full_path = join(self.prefix, get_python_short_path(target_python_version))
            assert first_line == "#!%s" % python_full_path
        assert last_line == "sys.exit(%s())" % func

        py_ep_axn.reverse()
        assert not isfile(py_ep_axn.target_full_path)

        if on_win:
            windows_exe_axn = windows_exe_axns[0]
            target_short_path = "%s\\%s.exe" % (get_bin_directory_short_path(), command)
            assert windows_exe_axn.target_full_path == join(self.prefix, target_short_path)

            mkdir_p(dirname(windows_exe_axn.target_full_path))
            windows_exe_axn.verify()
            windows_exe_axn.execute()
            assert isfile(windows_exe_axn.target_full_path)
            assert is_executable(windows_exe_axn.target_full_path)

            src = compute_md5sum(join(context.conda_prefix, 'Scripts/conda.exe'))
            assert src == compute_md5sum(windows_exe_axn.target_full_path)

            windows_exe_axn.reverse()
            assert not isfile(windows_exe_axn.target_full_path)
예제 #3
0
def build_or_update_channeldata(channel_data, repodata, subdir):
    legacy_packages = repodata["packages"]
    conda_packages = repodata["packages.conda"]

    use_these_legacy_keys = (set(legacy_packages.keys()) -
                             set(k[:-6] + '.tar.bz2'
                                 for k in conda_packages.keys()))
    all_repodata_packages = conda_packages.copy()
    all_repodata_packages.update(
        {k: legacy_packages[k]
         for k in use_these_legacy_keys})
    package_data = channel_data.get('packages', {})

    for fn, x in all_repodata_packages.items():
        assert "subdir" not in x or x["subdir"] == subdir, x

    def _append_group(groups, candidate):
        pkg_dict = candidate[1]
        pkg_name = pkg_dict['name']

        run_exports = package_data.get(pkg_name, {}).get('run_exports', {})
        if (pkg_name not in package_data or subdir not in package_data.get(
                pkg_name, {}).get('subdirs', [])
                or (package_data.get(pkg_name, {}).get('timestamp', 0) <
                    _make_seconds(pkg_dict.get('timestamp', 0)))
                or run_exports and pkg_dict['version'] not in run_exports):
            groups.append(candidate)

    groups = []
    package_groups = groupby(lambda x: x[1]['name'],
                             all_repodata_packages.items())
    for groupname, group in package_groups.items():
        if (groupname not in package_data
                or package_data[groupname].get('run_exports')):
            # pay special attention to groups that have run_exports
            #   - we need to process each version
            # group by version; take newest per version group.  We handle groups that
            #    are not in the index t all yet similarly, because we can't check
            #    if they have any run_exports
            for vgroup in groupby(lambda x: x[1]['version'], group).values():
                candidate = next(
                    iter(
                        sorted(vgroup,
                               key=lambda x: x[1].get('timestamp', 0),
                               reverse=True)))
                _append_group(groups, candidate)
        else:
            # take newest per group
            candidate = next(
                iter(
                    sorted(group,
                           key=lambda x: x[1].get('timestamp', 0),
                           reverse=True)))
            _append_group(groups, candidate)

    def _replace_if_newer_and_present(pd, data, erec, data_newer, k):
        if data.get(k) and (data_newer or not erec.get(k)):
            pd[k] = data[k]
        else:
            pd[k] = erec.get(k)

    # unzipping
    fns, fn_dicts = [], []
    if groups:
        fns, fn_dicts = zip(*groups)

    for fn_dict, fn in zip(fn_dicts, fns):
        data, _cdver = _load_shard_channeldata(subdir, fn, repodata)
        assert _cdver == CHANNELDATA_VERSION
        if data:
            data.update(fn_dict)
            name = data['name']
            # existing record
            erec = package_data.get(name, {})
            data_v = data.get('version', '0')
            erec_v = erec.get('version', '0')
            data_newer = VersionOrder(data_v) > VersionOrder(erec_v)

            package_data[name] = package_data.get(name, {})
            # keep newer value for these
            for k in ('description', 'dev_url', 'doc_url', 'doc_source_url',
                      'home', 'license', 'source_url', 'source_git_url',
                      'summary', 'icon_url', 'icon_hash', 'tags',
                      'identifiers', 'keywords', 'recipe_origin', 'version'):
                _replace_if_newer_and_present(package_data[name], data, erec,
                                              data_newer, k)

            # keep any true value for these, since we don't distinguish subdirs
            for k in ("binary_prefix", "text_prefix", "activate.d",
                      "deactivate.d", "pre_link", "post_link", "pre_unlink"):
                package_data[name][k] = any((data.get(k), erec.get(k)))

            package_data[name]['subdirs'] = sorted(
                list(set(erec.get('subdirs', []) + [subdir])))
            # keep one run_exports entry per version of the package, since these
            # vary by version
            run_exports = erec.get('run_exports', {})
            exports_from_this_version = data.get('run_exports')
            if exports_from_this_version:
                run_exports[data_v] = data.get('run_exports')
            package_data[name]['run_exports'] = run_exports
            package_data[name]['timestamp'] = _make_seconds(
                max(data.get('timestamp', 0),
                    channel_data.get(name, {}).get('timestamp', 0)))

    channel_data.update({
        'channeldata_version':
        CHANNELDATA_VERSION,
        'subdirs':
        sorted(list(set(channel_data.get('subdirs', []) + [subdir]))),
        'packages':
        package_data,
    })