[英]How to add a new function to RepoSurgeon (just like dsc or amp or min)
This is a specialized version of: How to replace existing Python class methods of (or otherwise extend) RepoSurgeon by means of 'exec' and 'eval'? 这是以下内容的专门版本: 如何通过exec和eval替换RepoSurgeon的现有Python类方法(或以其他方式扩展)?
How can one add a new function to RepoSurgeon using the exec
facility (ie without editing the upstream code) to add a new function, augmenting existing functionality. 如何使用exec
工具(即,无需编辑上游代码)向RepoSurgeon添加新功能来添加新功能,从而增强现有功能。
Problem: if you are using RepoSurgeon and you call a function from your script or on the command line and the function throws an exception, this will throw off nested function calls. 问题:如果您正在使用RepoSurgeon,并且从脚本或在命令行上调用函数,并且该函数引发异常,则将引发嵌套函数调用。
Example: you want to find all fossils on a branch by branch name in a single function. 示例:您要在单个函数中按分支名称查找分支上的所有化石。 The following compound command will do the job for a branch named BRANCH
: 以下复合命令将对名为BRANCH
的分支执行此工作:
@dsc(@min(/BRANCH/)) list
This works fine if BRANCH
exists. 如果BRANCH
存在,则可以正常工作。 But what if it doesn't? 但是,如果没有呢? In such a case RepoSurgeon will get quite angry with us and throw an exception: 在这种情况下,RepoSurgeon会很生我们的气,并抛出异常:
@dsc(@min(/NO_SUCH_BRANCH/)) list
[...]
ValueError: min() arg is an empty sequence
The problem is that this means that your whole lift script will get derailed. 问题是这意味着您的整个举升脚本将脱轨。
What to do? 该怎么办?
Perhaps one of the easiest solutions is to write your own function and bundle the call sequence of @dsc(@min(...))
while guarding against exceptions. 也许最简单的解决方案之一是编写自己的函数并捆绑@dsc(@min(...))
的调用序列,同时防止出现异常。
Assuming you have a lift script, embed the following here-doc as argument to exec
into it: 假设您有一个提升脚本,请将以下here-doc作为自变量嵌入到exec
:
exec <<EOF
if self:
def brpdsc_factory(recov):
Recoverable = recov
def brpdsc_handler(self, subarg):
if not subarg:
raise Recoverable("function @brpdsc() called with selection that resolves to empty set")
minset = set([])
descendants = set([])
try:
minset = self.min_handler(subarg)
except ValueError as e:
raise Recoverable("invalid value passed to function @min()")
try:
descendants = self.dsc_handler(minset)
except:
raise Recoverable("the implicit call to @dsc() failed")
return descendants
return brpdsc_handler
brpdsc_handler = brpdsc_factory(Recoverable)
setattr(self, 'brpdsc_handler', brpdsc_handler.__get__(self, self.__class__))
EOF
This implants the local function brpdsc_handler
as class member of the same name of class RepoSurgeon
and makes a function @brpdsc
immediately available to scripts or the command prompt. 这brpdsc_handler
本地函数brpdsc_handler
植入为与brpdsc_handler
类同名的class RepoSurgeon
,并使函数@brpdsc
立即可用于脚本或命令提示符。
The factory function exists to carry over the name for Recoverable
which is an exception class defined in the reposurgeon
script but not available to our code anymore after the exec
has finished. 存在工厂函数以保留Recoverable
的名称,该名称是reposurgeon
脚本中定义的异常类,但在exec
完成后不再可用于我们的代码。 Other symbols can be carried over the same way. 其他符号可以相同的方式携带。
Now all that can happen is that we receive: 现在所有可能发生的就是我们收到:
reposurgeon: function @brpdsc() called with selection that resolves to empty set
from RepoSurgeon after attempting to run @brpdsc/NO_SUCH_BRANCH/) list
. 尝试运行@brpdsc/NO_SUCH_BRANCH/) list
后从RepoSurgeon @brpdsc/NO_SUCH_BRANCH/) list
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.