如何列出将在Macports中安装的软件包和依赖项?

时间:2015-05-13 00:19:19

标签: macports

有没有办法只列出{{1>}将为给定命令安装的所有 包及其依赖项?

例如,考虑使用建议的安装SciPy堆栈:

port

安装了上面命令中未列出的大量软件包和依赖项。

此外,其中一些我已经拥有。

我已经知道sudo port install py27-numpy py27-scipy py27-matplotlib py27-ipython +notebook py27-pandas py27-sympy py27-nose开关,但它提供了所有内容的详细输出,包括我已安装​​的软件包。

我有兴趣让-y告诉我将安装哪些 新的 包(无论是否依赖)。

是否有已知方法或人们只是解析命令的port输出,将每个报告的包与现有已安装的包进行比较?

干杯

P.S。我是Macports和MacOSX的新手(在Linux中,apt-get总是告诉你将安装哪些新软件包)

2 个答案:

答案 0 :(得分:2)

您可以使用端口表达式打印要安装的内容:

port echo rdepof:$yourport and not installed

或多个端口

port echo \( rdepof:$yourport rdepof:$yourport2 ... \) and not installed

由于此中涉及的Portfiles的数量以及如何实现集合操作,这将是相当慢的。话虽这么说,我们也在努力改进这一点,并在安装之前提供反馈,例如未来的MacPorts版本中的apt-get。

答案 1 :(得分:0)

neverpanic已经给出了答案,但它似乎无法处理变体(如+notebook)和命令行选项(如configure.compiler=macports-clang-3.7)。我有一个单独的解决方案。以下Python脚本可以递归显示新的依赖项:

#!/usr/bin/env python
#coding: utf-8

import re
import sys
import subprocess

# Gets command output as a list of lines
def popen_readlines(cmd):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    p.wait()
    if p.returncode != 0:
        raise subprocess.CalledProcessError(p.returncode, cmd)
    else:
        return map(lambda line: line.rstrip('\n'), p.stdout.readlines())

# Gets the port name from a line like "  gcc6 @6.1.0_0 (active)"
def get_port_name(port_line):
    return re.sub(r'^  (\S+).*', r'\1', port_line)

# Gets installed ports as a set
def get_installed():
    installed_ports_lines = popen_readlines(['port', 'installed'])[1:]
    installed_ports = set(map(get_port_name, installed_ports_lines))
    return installed_ports

# Gets port names from items that may contain version specifications,
# variants, or options
def get_ports(ports_and_specs):
    requested_ports = set()
    for item in ports_and_specs:
        if not (re.search(r'^[-+@]', item) or re.search(r'=', item)):
            requested_ports.add(item)
    return requested_ports

# Gets dependencies for the given port list (which may contain options
# etc.), as a list of tuples (combining with level), excluding items in
# ignored_ports
def get_deps(ports, ignored_ports, level):
    if ports == []:
        return []

    deps_raw = popen_readlines(['port', 'deps'] + ports)
    uninstalled_ports = []
    for line in deps_raw:
        if re.search(r'Dependencies:', line):
            deps = re.sub(r'.*Dependencies:\s*', '', line).split(', ')
            uninstalled_ports += [x for x in deps if x not in ignored_ports]
            ignored_ports |= set(deps)

    port_level_pairs = []
    for port in uninstalled_ports:
        port_level_pairs += [(port, level)]
        port_level_pairs += get_deps([port], ignored_ports, level + 1)
    return port_level_pairs

def main():
    if sys.argv[1:]:
        ports_and_specs = sys.argv[1:]
        ignored_ports = get_installed() | get_ports(ports_and_specs)
        uninstalled_ports = get_deps(ports_and_specs, ignored_ports, 0)
        for (port, level) in uninstalled_ports:
            print ' ' * (level * 2) + port

if __name__ == '__main__':
    main()

可以像port_rdeps.py libomp configure.compiler=macports-clang-3.7一样调用它。作为奖励,它可以将未安装的依赖项显示为树。