Svnhooks--用python写个网页控制svn提交开关
一般在项目切了分支以后,会有锁定svn的需求,防止大家频繁的在分支版本提交不相关的内容,影响分支的稳定性,在前面的文章说到了,我们可以利用svnkoos的pre-commit在用户提交前做一些判断,来让用户是否可以提交。
如果只是简单的想让所有用户都无法提交,可以用些简单粗暴的办法
1:直接exit 1 一直返还非0状态,锁定svn仓库,让所有用户都无法提交
#!/bin/sh # 永真判断,始终返回非零状态 exit 1
如果想要解除锁定状态,可以把代码改成exit0 或者把pre-commit文件删除即可
#!/bin/sh exit 0
2:把配置文件 svnserve文件修改
auth-access = read
这样即使用户经过身份验证也只能读取,无法提交。
如果您使用的是 SVN 服务器(如 svnserve 或 Apache),在修改配置文件后,可能需要重启服务以使更改生效。所以也不太推荐这个方法,每次修改以后都需要重启
下面就着重的讲一下如何把这个开关集合到一个web里面,让用户做开关操作即可实现svn仓库的锁定
其实也是利用了pre-commit脚本,只不过判断是否能提交的依据变成了从web里面获取当前的锁定状态# 设置超时时间(以秒为单位)
TIMEOUT=2
START_TIME=$(date +%s)
# 尝试获取 commit_switch 状态
while true; do
COMMIT_SWITCH=$(curl -s http://xxxx:5000/get_switch | jq -r '.commit_switch' 2>/dev/null)
CURL_EXIT_CODE=$?
if [ $CURL_EXIT_CODE -eq 0 ] && [ -n "$COMMIT_SWITCH" ]; then
exit 0
else
echo "提交被拒绝,SVN仓库已锁定,请联系管理员授予权限。" >&2
exit 1
fi
# 检查是否超时
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -ge $TIMEOUT ]; then
echo "超时了,获取失败。"
exit 0 # 超时,允许提交
fi
# 等待一段时间后重试
sleep 1
done
exit 0
这里面一开始设定了超时变量,然后while循环使用 curl
向指定的服务器发送请求,以获取 commit_switch
的值,
jq
用于解析 JSON 响应,提取commit_switch
字段。- 如果请求失败,错误信息将被重定向到
/dev/null
,并且$CURL_EXIT_CODE
将被设置为curl
的退出代码。 - 如果 curl 请求成功且 COMMIT_SWITCH 不为空,进入条件块。exit 0 就代表可以提交
- 否则的话 exit 1 不给提交,并给出提示
- 后面就是加了一个超时判断,防止网络不好,请求不到结果一直死循环,我是如果请求不到就允许提交了,可以根据自己的业务常见,修改 exit 的参数
- curl的请求就填入接口的ip地址和接口地址
下面是我get方法接口的核心代码
# 获取当前状态 @app.route('/get_switch', methods=['GET']) def get_switch(): with open(STATE_FILE, 'r') as f: commit_switch = f.read().strip() return jsonify({'commit_switch': commit_switch})
我是把当前的开关状态放在了一个文本里面,从打开的文件里面读取内容,并且去除空白字符后存储在commit_switch上,然后转换成json格式
这个方法前端也可以用来请求状态,这样用户打开页面时就能获取服务端当前的锁定状态
简单的列一下我前端的核心代码,就是根据向服务端请求commitSwitch的状态来显示页面的开关状态
<div class="text-center"> <label class="toggle-label" for="commitSwitch">提交开关:</label> <label class="switch"> <input type="checkbox" id="commitSwitch" name="commitSwitch" {% if commitSwitch=='true' %}checked{% endif %}> <span class="slider"></span> </label> </div>
服务端需要在index方法传入commitswitch值,也可以在html写个ajax方法请求,但是我偷懒就没有写,一样也能达到效果
@app.route('/') def index(): # 读取当前状态 with open(STATE_FILE, 'r') as f: commit_switch = f.read().strip() return render_template('index.html', commitSwitch=commit_switch)
一开始需要初始化一下STATE_FILE文件的初始状态
STATE_FILE = 'commit_switch.txt' # 初始化状态文件 def initialize_state(): with open(STATE_FILE, 'w') as f: f.write('false') # 默认状态为 false # 开关状态 commit_switch = False
然后要写一个set方法,来接收用户改变仓库锁定状态的操作
# 切换状态 @app.route('/set_switch', methods=['POST']) def set_switch(): new_state = request.json.get('commit_switch') if new_state in ['true', 'false']: with open(STATE_FILE, 'w') as f: f.write(new_state) return jsonify({'message': '状态已更新', 'commit_switch': new_state}), 200 return jsonify({'message': '无效的状态'}), 400
下面是客户端在进行开关操作时向服务端请求的操作,就是在commitSwitch在改变时,我后面做了一些显示列表的工作,其实commitSwitch11就是我向服务端get请求获取当前的开关状态,下面的post就是用户改变状态我向服务端请求修改开关状态
$('#commitSwitch').change(function () {
const isChecked = $('#commitSwitch').is(':checked');
getCommitSwitchStatus(function (commitSwitch11) {
if (commitSwitch11 === 'true') {
$('#userList').css('display', 'flex'); // 切换用户列表的显示状态
} else {
$('#userList').toggle(false); // 切换用户列表的显示状态
}
});
// 发送POST请求更新开关状态
$.ajax({
url: '/set_switch',
type: 'POST',
contentType: 'application/json', // 设置请求头为JSON
data: JSON.stringify({commit_switch: isChecked.toString()}), // 转换为字符串
success: function (response) {
console.log('成功更新:', response); // 处理成功响应
},
error: function (jqXHR, textStatus, errorThrown) {
console.error('更新失败:', textStatus, errorThrown); // 处理错误
}
});
});
大概的页面就是下面这样,一个简单的开关,可以控制SVN仓库是否允许用户提交