-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsvn.js
More file actions
168 lines (155 loc) · 4.6 KB
/
svn.js
File metadata and controls
168 lines (155 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
const { exec, execCommand } = require('./util');
``
const SVN_TYPE_MAP = {
'?': 'add',
A: 'add',
'!': 'delete',
M: 'update',
};
const parseStatus = (data) => {
const changedList = data.trim().split('\n');
const result = [];
changedList.forEach((item) => {
const [type, path] = item.split(' '); // seven blank
if (!type || !path) return;
result.push({
rawType: type,
type: SVN_TYPE_MAP[type],
path,
});
});
return result;
};
const SVN_LOG_REG = /-{12}\n(.*)\|(.*)\|(.*)\|(.*)\n\n(.*)\n-{12}/g;
const parseLog = (data) => {
const result = [];
let regResult;
/* eslint no-cond-assign: "off" */
while (regResult = SVN_LOG_REG.exec(data)) {
result.push({
version: regResult[1].trim(),
author: regResult[2].trim(),
date: regResult[3].trim(),
msg: regResult[5].trim(),
});
}
return result;
};
// @TODO 错误处理catch
// @TODO 所有svn命令执行前都需要检查svn upgrade的问题
class SVN {
static async status(codePath) {
const command = 'svn status';
let statusData = [];
await exec(command, codePath)
.then((data) => {
statusData = parseStatus(data);
})
.catch(async (error) => {
const { message } = error;
// 处理svn upgrade提示:在svn根目录(Working Copy Root Path)执行svn upgrade
// @NOTE 错误提示
// svn: E155036: Please see the 'svn upgrade' command
// svn: E155036: The working copy at 'xxx'
if (message.indexOf('svn upgrade') !== -1) {
const SVN_ROOT_REG = /The working copy at '(.*)'/;
const svnRoot = SVN_ROOT_REG.exec(message)['1'];
await this.upgrade(svnRoot);
statusData = await this.status(codePath);
}
});
return statusData;
}
static async upgrade(codePath) {
const command = 'svn upgrade';
const result = { error: false, msg: '' };
await exec(command, codePath)
.then((data) => {
result.msg = data;
})
.catch(async (error) => {
const { message } = error;
// 处理svn upgrade报错,通过报错找到真正的svn root
if (message.indexOf("Can't upgrade") !== -1) {
const SVN_ROOT_REG = /the root is '(.*)'/;
const svnRoot = SVN_ROOT_REG.exec(message)['1'];
await this.upgrade(svnRoot);
}
});
return result;
}
static async update(codePath) {
const command = 'svn update';
return await execCommand(command, codePath);
}
static async addAll(codePath) {
const statusData = await this.status(codePath);
for (let i = 0; i < statusData.length; i += 1) {
const { rawType, path } = statusData[i];
/* eslint default-case: "off" */
/* eslint no-await-in-loop: "off" */
switch (rawType) {
case '?':
// svn add xxx
await this.add(codePath, path);
break;
case '!':
// svn delete xxx
await this.delete(codePath, path);
break;
}
}
}
static async add(codePath, targetPath) {
const command = `svn add ${targetPath}`;
await exec(command, codePath);
}
static async delete(codePath, targetPath) {
const command = `svn delete ${targetPath}`;
await exec(command, codePath);
}
static async commit(codePath, commitMsg) {
const command = `svn commit -m '${commitMsg}'`;
await this.addAll(codePath);
const result = { error: false, msg: '' };
await exec(command, codePath)
.then((data) => {
result.msg = data;
})
.catch((error) => {
result.error = true;
result.msg = error;
});
return result;
}
// @TODO 支持查询位置
static async log(codePath) {
const countLimit = 10;
const command = `svn log -l ${countLimit}`;
let logData = [];
await exec(command, codePath)
.then((data) => {
logData = parseLog(data);
});
return logData;
}
static async revert(codePath, version, commitMsg) {
// @NOTE 回滚 = 先回退,再commit
// https://stackoverflow.com/questions/13330011/how-do-i-revert-an-svn-commit
const logs = await this.log(codePath);
const [currentVersion, rollbackVersion] = logs;
const command = `svn merge -r ${currentVersion.version}:${version || rollbackVersion.version} .`;
const result = { error: false, msg: '' };
await exec(command, codePath)
.then((data) => {
result.msg = data;
})
.catch((error) => {
result.error = true;
result.msg = error;
});
if (result.error) return result;
return this.commit(codePath, commitMsg);
}
}
module.exports = SVN;