如何使用exec
工具向RepoSurgeon添加新功能(即不编辑上游代码)以添加新功能,增强现有功能。
问题:如果您正在使用RepoSurgeon,并且从脚本或命令行调用函数,并且函数抛出异常,则会抛出嵌套函数调用。
示例:您希望在单个函数中按分支名称查找分支上的所有化石。以下复合命令将为名为BRANCH
的分支执行作业:
@dsc(@min(/BRANCH/)) list
如果存在BRANCH
,这样可以正常工作。但如果不是呢?在这种情况下,RepoSurgeon将对我们非常生气并抛出异常:
@dsc(@min(/NO_SUCH_BRANCH/)) list
[...]
ValueError: min() arg is an empty sequence
问题在于这意味着您的整个电梯脚本会脱轨。
怎么办?
答案 0 :(得分:1)
也许最简单的解决方案之一就是编写自己的函数并捆绑@dsc(@min(...))
的调用序列,同时防范异常。
假设您有一个提升脚本,请将以下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
这将本地函数brpdsc_handler
植入为同名class RepoSurgeon
的类成员,并使函数@brpdsc
立即可用于脚本或命令提示符。
工厂函数用于继承Recoverable
的名称,reposurgeon
是exec
脚本中定义的异常类,但在reposurgeon: function @brpdsc() called with selection that resolves to empty set
完成后我们的代码不再可用。其他符号可以通过相同的方式传播。
现在所有可能发生的事情是我们收到:
@brpdsc/NO_SUCH_BRANCH/) list
尝试运行{{1}}后,来自RepoSurgeon的。