openSUSE:OSC 插件
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 以获取提交权限。他也会安排提交邮件。