openSUSE:OSC 插件

跳转到:导航搜索
本文档展示了如何编写 osc 插件,以及如何从外部 Python 脚本中使用 osc 模块。

独立脚本的简单示例

最好通过示例来展示。

假设您想编写一个脚本,该脚本查看 openSUSE:Tools 项目,并显示该项目内所有软件包的元数据。

通过 fork osc 可执行文件的方法

您可以这样做

#!/usr/bin/python

import os

project = 'openSUSE:Tools'

def run(command):
    input, output = os.popen2(command)
    lines = output.readlines()
    return lines

lines = run('osc ls ' + project)
for line in lines:
    package = line.rstrip('\n')
    meta = run('osc meta pkg ' + project + ' ' + package)
    for line in meta:
        print line

但是,这种方式只是将 osc 作为外部进程调用。这意味着 osc 每次都会初始化,并且您无法访问 osc 的内部功能。

使用 osc API

相反,您可以编写一个导入 osc 模块并使用它的脚本

#!/usr/bin/python

import os
import osc.conf
import osc.core

project = 'openSUSE:Tools'

# initialize osc configuration
osc.conf.get_config()
packages = osc.core.meta_get_packagelist(osc.conf.config['apiurl'], 
                                       project)
for package in packages:

    m = osc.core.show_package_meta(osc.conf.config['apiurl'], project, package)
    print ''.join(m)

这更容易。

将独立脚本转换为插件

现在,假设您编写了一些更通用的东西。将该功能集成为新的 osc 命令是否有意义?如果是这样,很容易做到。自定义 osc 命令可以放入 ~/.osc-plugins 或 /var/lib/osc-plugins 中,并从那里被 osc 加载。上面的代码片段如下所示

def do_show_packages(self, subcmd, opts, project):
    """${cmd_name}: Show metadata of all packages in an project

    This command shows metadata of all packages in a given project.
    
    ${cmd_usage}
    ${cmd_option_list}
    """

    packages = meta_get_packagelist(conf.config['apiurl'], 
                                        project)

    for package in packages:
        m = show_package_meta(conf.config['apiurl'], project, package)
        print ''.join(m)

文件名很重要;它必须以 .py 结尾。除此之外,命名没有限制,当然,明智的做法是使其名称与它实现的命令名称匹配。

调试插件

在编写和调试 osc 插件时,如果出现问题,查看您出错的地方会有所帮助。osc 有一个 "--trace" 选项(您也可以将 "traceback=1" 添加到您的 ~/.oscrc 以永久激活它)。此外,您可能会发现 "--debugger" 和 "--post-mortem" 选项有用。

实现的方法必须以 "do_" 开头。还有一些其他的魔法在起作用。一个名为 cmdln 的 Python 模块(有关更多信息,请参阅 pydoc osc.cmdln)会自动处理文档记录、参数检查等。安装插件后,如果您调用 'osc help',您会在长帮助输出中看到一个新的命令

   show_packages     Show metadata of all packages in an project

该命令会自动记录

% osc help show_packages     
show_packages: Show metadata of all packages in an project

This command shows metadata of all packages in a given project.

usage:
    osc show_packages PROJECT

并且可以像这样调用:“osc show_packages <prj>”。

带有 CLI 选项的更复杂的示例

这是一个更复杂的示例,它还展示了命令行内容

@cmdln.option('-q', '--quiet', action='store_true',
              help='do not show downloading progress')
@cmdln.option('--package', metavar='PACKAGE',
              help='only binaries of this package')
@cmdln.option('-d', '--destdir', default='.', metavar='DIR',
              help='destination directory')
def do_mirror_binaries(self, subcmd, opts, project, repository, architecture):
    """${cmd_name}: Mirror binaries of a project to local directory

    It does download directly from the api server. 
    
    Packages don't need to be "published" to be downloaded.

    ${cmd_usage}
    ${cmd_option_list}
    """

    # Get package list
    filenames = get_binarylist(conf.config['apiurl'],
                               project, repository, architecture,
                               package=opts.package)

    if not os.path.isdir(opts.destdir):
        print "Creating %s" % opts.destdir
        os.makedirs(opts.destdir, 0755)

    for filename in filenames:

        if os.path.exists('%s/%s' % (opts.destdir, filename)):
            continue

        target_filename = '%s/%s' % (opts.destdir, filename)

        get_binary_file(conf.config['apiurl'],
                        project, repository, architecture,
                        filename,
                        target_filename=target_filename,
                        package=opts.package,
                        progress_meter = not opts.quiet)

帮助输出如下所示

% osc help mirror_binaries
mirror_binaries: Mirror binaries of a project to local directory

It does download directly from the api server.

Packages don't need to be "published" to be downloaded.

usage:
    osc mirror_binaries PROJECT REPOSITORY ARCHITECTURE 

options:
    -h, --help          show this help message and exit
    -d DIR, --destdir=DIR
                        destination directory
    --package=PACKAGE   only binaries of this package
    -q, --quiet         do not show downloading progress

更多信息

还有更多内容。使用 Python 函数装饰器很容易将命令行选项添加到您的命令中。最好通过查看 osc 代码中具有类似功能的代码来完成此操作。浏览 osc 源代码 tar-ball 或 git 仓库中找到的 "osc/commandline.py" 文件,或在 <python-libdir> 中查找。

要了解 osc 内部函数,请参阅

pydoc osc.commandline
pydoc osc.core

以获取更高和更低级别的函数。

可以通过查看以下内容找到更多示例<python-libdir>/osc/command.py.

这种方法非常适合覆盖或改进任何现有的 osc 命令。如果您对 ls 命令不满意,只需编写您自己的命令。或者,如果您有改进它或添加新功能的想法,请从osc.command.py复制命令到您的 osc 插件目录并开始修改它。

osc.command.py和插件命令之间有一个区别。由于缩进对 Python 很重要,因此如果您将其复制到osc.command.py中,则需要缩进 4 个空格,或者反向删除 4 个空格。除此之外,简单的复制和粘贴应该就可以。

可能会作为进一步的示例;它描述了一个基于 osc 插件的更复杂的系统。

现有插件

已经存在的 osc 插件包括

您可以通过 在 software.opensuse.org 上搜索 osc-plugin 找到更多。

贡献

如果您实现了一个很棒的命令,并且希望将其集成到上游 osc 中,请立即写信给 buildservice-mailinglist

贡献 osc

  • Fork https://github.com/openSUSE/osc
  • 将您的补丁/想法/错误修复发布到 buildservice 邮件列表 (opensuse-buildservice_AT_opensuse.org)。
  • 联系 adrian_AT_suse.de 以获取提交权限。他也会安排提交邮件。