Skip to content

Commit 331fd95

Browse files
committed
seperated some svnFinder and svnRepository from svn file
1 parent e0dc065 commit 331fd95

File tree

5 files changed

+323
-296
lines changed

5 files changed

+323
-296
lines changed

src/extension.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ExtensionContext, Disposable, workspace, window } from "vscode";
2-
import { Svn, findSvn } from "./svn";
2+
import { Svn } from "./svn";
3+
import { SvnFinder } from "./svnFinder";
34
import { SvnContentProvider } from "./svnContentProvider";
45
import { SvnCommands } from "./commands";
56
import { Model } from "./model";
@@ -9,19 +10,20 @@ async function init(context: ExtensionContext, disposables: Disposable[]) {
910
const outputChannel = window.createOutputChannel("Svn");
1011
disposables.push(outputChannel);
1112

12-
const config = workspace.getConfiguration('svn');
13-
const enabled = config.get<boolean>('enabled') === true;
14-
const pathHint = config.get<string>('path');
13+
const config = workspace.getConfiguration("svn");
14+
const enabled = config.get<boolean>("enabled") === true;
15+
const pathHint = config.get<string>("path");
16+
const svnFinder = new SvnFinder();
1517

1618
let info = null;
1719
try {
18-
info = await findSvn(pathHint);
20+
info = await svnFinder.findSvn(pathHint);
1921
} catch (error) {
2022
outputChannel.appendLine(error);
2123
return;
2224
}
2325

24-
const svn = new Svn({svnPath: info.path, version: info.version});
26+
const svn = new Svn({ svnPath: info.path, version: info.version });
2527
const model = new Model(svn);
2628
const contentProvider = new SvnContentProvider(model);
2729
const commands = new SvnCommands(model);
@@ -42,10 +44,11 @@ async function init(context: ExtensionContext, disposables: Disposable[]) {
4244

4345
function activate(context: ExtensionContext): any {
4446
const disposables: Disposable[] = [];
45-
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
47+
context.subscriptions.push(
48+
new Disposable(() => Disposable.from(...disposables).dispose())
49+
);
4650

47-
init(context, disposables)
48-
.catch(err => console.error(err));
51+
init(context, disposables).catch(err => console.error(err));
4952
}
5053

5154
exports.activate = activate;

src/repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from "vscode";
1313
import { Resource } from "./resource";
1414
import { throttleAsync, debounce } from "./decorators";
15-
import { Repository as BaseRepository } from "./svn";
15+
import { Repository as BaseRepository } from "./svnRepository";
1616
import { SvnStatusBar } from "./statusBar";
1717
import { dispose } from "./util";
1818

src/svn.ts

Lines changed: 16 additions & 286 deletions
Original file line numberDiff line numberDiff line change
@@ -4,122 +4,32 @@ import * as cp from "child_process";
44
import * as iconv from "iconv-lite";
55
import * as jschardet from "jschardet";
66
import * as path from "path";
7+
import { Repository } from "./svnRepository";
78

8-
interface CpOptions {
9+
export interface CpOptions {
910
cwd?: string;
1011
encoding?: string;
1112
log?: boolean;
1213
}
1314

14-
export interface ISvn {
15-
path: string;
16-
version: string;
17-
}
18-
19-
function parseVersion(raw: string): string {
20-
const match = raw.match(/(\d+\.\d+\.\d+ \(r\d+\))/);
21-
22-
if (match && match[0]) {
23-
return match[0];
24-
}
25-
return raw.split(/[\r\n]+/)[0];
26-
}
27-
28-
function findSpecificSvn(path: string): Promise<ISvn> {
29-
return new Promise<ISvn>((c, e) => {
30-
const buffers: Buffer[] = [];
31-
const child = cp.spawn(path, ["--version"]);
32-
child.stdout.on("data", (b: Buffer) => buffers.push(b));
33-
child.on("error", cpErrorHandler(e));
34-
child.on(
35-
"exit",
36-
code =>
37-
code
38-
? e(new Error("Not found"))
39-
: c({
40-
path,
41-
version: parseVersion(
42-
Buffer.concat(buffers)
43-
.toString("utf8")
44-
.trim()
45-
)
46-
})
47-
);
48-
});
49-
}
50-
51-
function findSvnDarwin(): Promise<ISvn> {
52-
return new Promise<ISvn>((c, e) => {
53-
cp.exec("which svn", (err, svnPathBuffer) => {
54-
if (err) {
55-
return e("svn not found");
56-
}
57-
58-
const path = svnPathBuffer.toString().replace(/^\s+|\s+$/g, "");
59-
60-
function getVersion(path: string) {
61-
// make sure svn executes
62-
cp.exec("svn --version", (err, stdout) => {
63-
if (err) {
64-
return e("svn not found");
65-
}
66-
67-
return c({ path, version: parseVersion(stdout.trim()) });
68-
});
69-
}
70-
71-
if (path !== "/usr/bin/svn") {
72-
return getVersion(path);
73-
}
74-
75-
// must check if XCode is installed
76-
cp.exec("xcode-select -p", (err: any) => {
77-
if (err && err.code === 2) {
78-
// svn is not installed, and launching /usr/bin/svn
79-
// will prompt the user to install it
80-
81-
return e("svn not found");
82-
}
83-
84-
getVersion(path);
85-
});
86-
});
87-
});
88-
}
89-
90-
function findSystemSvnWin32(base: string): Promise<ISvn> {
91-
if (!base) {
92-
return Promise.reject<ISvn>("Not found");
93-
}
94-
95-
return findSpecificSvn(path.join(base, "TortoiseSVN", "bin", "svn.exe"));
96-
}
97-
98-
function findSvnWin32(): Promise<ISvn> {
99-
return findSystemSvnWin32(process.env["ProgramW6432"])
100-
.then(void 0, () => findSystemSvnWin32(process.env["ProgramFiles(x86)"]))
101-
.then(void 0, () => findSystemSvnWin32(process.env["ProgramFiles"]))
102-
.then(void 0, () => findSpecificSvn("svn"));
15+
export interface ISvnErrorData {
16+
error?: Error;
17+
message?: string;
18+
stdout?: string;
19+
stderr?: string;
20+
exitCode?: number;
21+
svnErrorCode?: string;
22+
svnCommand?: string;
10323
}
10424

105-
export function findSvn(hint: string | undefined): Promise<ISvn> {
106-
var first = hint ? findSpecificSvn(hint) : Promise.reject<ISvn>(null);
107-
108-
return first
109-
.then(void 0, () => {
110-
switch (process.platform) {
111-
case "darwin":
112-
return findSvnDarwin();
113-
case "win32":
114-
return findSvnWin32();
115-
default:
116-
return findSpecificSvn("svn");
117-
}
118-
})
119-
.then(null, () => Promise.reject(new Error("Svn installation not found.")));
25+
export interface ISvnOptions {
26+
svnPath: string;
27+
version: string;
12028
}
12129

122-
function cpErrorHandler(cb: (reason?: any) => void): (reason?: any) => void {
30+
export function cpErrorHandler(
31+
cb: (reason?: any) => void
32+
): (reason?: any) => void {
12333
return err => {
12434
if (/ENOENT/.test(err.message)) {
12535
err = new SvnError({
@@ -133,16 +43,6 @@ function cpErrorHandler(cb: (reason?: any) => void): (reason?: any) => void {
13343
};
13444
}
13545

136-
export interface ISvnErrorData {
137-
error?: Error;
138-
message?: string;
139-
stdout?: string;
140-
stderr?: string;
141-
exitCode?: number;
142-
svnErrorCode?: string;
143-
svnCommand?: string;
144-
}
145-
14646
export class SvnError {
14747
error?: Error;
14848
message: string;
@@ -192,11 +92,6 @@ export class SvnError {
19292
}
19393
}
19494

195-
export interface ISvnOptions {
196-
svnPath: string;
197-
version: string;
198-
}
199-
20095
export class Svn {
20196
private svnPath: string;
20297
private version: string;
@@ -334,168 +229,3 @@ export class Svn {
334229
return this.exec("", args);
335230
}
336231
}
337-
338-
export class Repository {
339-
constructor(
340-
private svn: Svn,
341-
public root: string,
342-
public workspaceRoot: string
343-
) {}
344-
345-
async getStatus(): Promise<any[]> {
346-
const result = await this.svn.exec(this.workspaceRoot, ["stat"]);
347-
348-
let items = result.stdout.split("\n");
349-
let status = [];
350-
351-
for (let item of items) {
352-
let state = item.charAt(0);
353-
let path = item.substr(8).trim();
354-
355-
status.push([state, path]);
356-
}
357-
358-
return status;
359-
}
360-
361-
async show(path: string, options: CpOptions = {}): Promise<string> {
362-
const result = await this.svn.show(path, options);
363-
364-
if (result.exitCode !== 0) {
365-
throw new Error(result.stderr);
366-
}
367-
368-
return result.stdout;
369-
}
370-
371-
async commitFiles(message: string, files: any[]) {
372-
const result = await this.svn.commit(message, files);
373-
374-
if (result.exitCode !== 0) {
375-
throw new Error(result.stderr);
376-
}
377-
378-
return result.stdout;
379-
}
380-
381-
addFile(filePath: string) {
382-
return this.svn.add(filePath);
383-
}
384-
385-
async getCurrentBranch(): Promise<string> {
386-
try {
387-
const result = await this.svn.info(this.root);
388-
const currentBranch = result.stdout
389-
.match(/<url>(.*?)<\/url>/)[1]
390-
.split("/")
391-
.pop();
392-
return currentBranch;
393-
} catch (error) {
394-
console.error(error);
395-
return "";
396-
}
397-
}
398-
399-
async getRepoUrl() {
400-
const info = await this.svn.info(this.root);
401-
402-
if (info.exitCode !== 0) {
403-
throw new Error(info.stderr);
404-
}
405-
406-
let repoUrl = info.stdout.match(/<root>(.*?)<\/root>/)[1];
407-
const match = info.stdout.match(
408-
/<url>(.*?)\/(trunk|branches|tags).*?<\/url>/
409-
);
410-
411-
if (match && match[1]) {
412-
repoUrl = match[1];
413-
}
414-
415-
return repoUrl;
416-
}
417-
418-
async getBranches() {
419-
const repoUrl = await this.getRepoUrl();
420-
421-
const branches = [];
422-
423-
let trunkExists = await this.svn.exec("", [
424-
"ls",
425-
repoUrl + "/trunk",
426-
"--depth",
427-
"empty"
428-
]);
429-
430-
if (trunkExists.exitCode === 0) {
431-
branches.push("trunk");
432-
}
433-
434-
const trees = ["branches", "tags"];
435-
436-
for (let index in trees) {
437-
const tree = trees[index];
438-
const branchUrl = repoUrl + "/" + tree;
439-
440-
const result = await this.svn.list(branchUrl);
441-
442-
if (result.exitCode !== 0) {
443-
continue;
444-
}
445-
446-
const list = result.stdout
447-
.trim()
448-
.replace(/\/|\\/g, "")
449-
.split(/[\r\n]+/)
450-
.map((i: string) => tree + "/" + i);
451-
452-
branches.push(...list);
453-
}
454-
455-
return branches;
456-
}
457-
458-
async branch(name: string) {
459-
const repoUrl = await this.getRepoUrl();
460-
const newBranch = repoUrl + "/branches/" + name;
461-
const rootUrl = repoUrl + "/trunk";
462-
463-
const result = await this.svn.copy(rootUrl, newBranch, name);
464-
465-
if (result.exitCode !== 0) {
466-
throw new Error(result.stderr);
467-
}
468-
469-
const switchBranch = await this.svn.switchBranch(this.root, newBranch);
470-
471-
if (switchBranch.exitCode !== 0) {
472-
throw new Error(switchBranch.stderr);
473-
}
474-
475-
return true;
476-
}
477-
478-
async switchBranch(ref: string) {
479-
const repoUrl = await this.getRepoUrl();
480-
481-
var branchUrl = repoUrl + "/" + ref;
482-
483-
const switchBranch = await this.svn.switchBranch(this.root, branchUrl);
484-
485-
if (switchBranch.exitCode !== 0) {
486-
throw new Error(switchBranch.stderr);
487-
}
488-
489-
return true;
490-
}
491-
492-
async revert(files: any[]) {
493-
const result = await this.svn.revert(files);
494-
495-
if (result.exitCode !== 0) {
496-
throw new Error(result.stderr);
497-
}
498-
499-
return result.stdout;
500-
}
501-
}

0 commit comments

Comments
 (0)