Skip to content

Commit 630cf77

Browse files
authored
Merge pull request #60 from edgardmessias/multiple_svn_folders
Added support to multiple svn folders (Close #30)
2 parents 9b8df50 + 1b76e81 commit 630cf77

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
* @JohnstonCode Commit info message now shows what revision it was
1818
* @JohnstonCode Added svn update to scm title commands
1919
* @JohnstonCode Added confirmation message to revert command
20+
* @edgardmessias Added support for multiple svn folders. To configure,
21+
edit the options:
22+
* "svn.multipleFolders.enabled" : Allow to find subfolders using SVN
23+
* "svn.layout.depth" : Maximum depth to find subfolders using SVN
24+
* "svn.multipleFolders.ignore" : Folders to ignore using SVN
25+
(Ex.: '\*\*/vendor', '\*\*/node_modules')
2026

2127
## Bug Fixes
2228

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,23 @@
163163
"description":
164164
"Relative path for 'tags' in SVN URL, 'null' to disable. (Ex.: 'tags', 'stamps')",
165165
"default": "tags"
166+
},
167+
"svn.multipleFolders.enabled": {
168+
"type": "boolean",
169+
"description": "Allow to find subfolders using SVN",
170+
"default": false
171+
},
172+
"svn.multipleFolders.depth": {
173+
"type": "number",
174+
"minimum": 0,
175+
"description": "Maximum depth to find subfolders using SVN",
176+
"default": 4
177+
},
178+
"svn.multipleFolders.ignore": {
179+
"type": "array",
180+
"minimum": 4,
181+
"description": "Folders to ignore using SVN",
182+
"default": ["**/vendor", "**/node_modules"]
166183
}
167184
}
168185
}

src/model.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export class Model {
2020
private disposables: Disposable[] = [];
2121
private enabled = false;
2222
private possibleSvnRepositoryPaths = new Set<string>();
23+
private ignorePattern: RegExp = /^$/;
24+
private maxDepth: number = 0;
2325

2426
get repositories(): Repository[] {
2527
return this.openRepositories.map(r => r.repository);
@@ -31,6 +33,31 @@ export class Model {
3133

3234
if (this.enabled) {
3335
this.init();
36+
37+
const multipleFolders = config.get<boolean>(
38+
"multipleFolders.enabled",
39+
false
40+
);
41+
42+
if (multipleFolders) {
43+
this.maxDepth = config.get<number>("multipleFolders.depth", 0);
44+
45+
const ignoreList = config.get("multipleFolders.ignore", []);
46+
47+
// Base on https://github.com/aleclarson/glob-regex/blob/master/index.js
48+
const pattern = ignoreList
49+
.join("|")
50+
.replace(/\./g, "\\.")
51+
.replace(/\*\*\//g, "(.+[\\\\\/])?")
52+
.replace(/\*\*/g, "(.+[\\\\\/])?*")
53+
.replace(/\*/g, "[^\\\\\/]+");
54+
55+
try {
56+
this.ignorePattern = new RegExp("^(" + pattern + ")$");
57+
} catch (error) {
58+
window.showErrorMessage("Invalid pattern for: " + pattern);
59+
}
60+
}
3461
} else {
3562
this.disable();
3663
}
@@ -119,7 +146,7 @@ export class Model {
119146
}
120147
}
121148

122-
async tryOpenRepository(path: string): Promise<void> {
149+
async tryOpenRepository(path: string, level = 0): Promise<void> {
123150
if (this.getRepository(path)) {
124151
return;
125152
}
@@ -135,7 +162,17 @@ export class Model {
135162

136163
this.open(repository);
137164
} catch (err) {
138-
console.error(err);
165+
const newLevel = level + 1;
166+
167+
if (newLevel <= this.maxDepth) {
168+
fs.readdirSync(path).forEach(file => {
169+
const dir = path + "/" + file;
170+
if (fs.statSync(dir).isDirectory() && !this.ignorePattern.test(dir)) {
171+
this.tryOpenRepository(dir, newLevel);
172+
}
173+
});
174+
}
175+
139176
return;
140177
}
141178
}

src/svn.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ export class SvnError {
9595
export class Svn {
9696
private svnPath: string;
9797
private version: string;
98-
98+
private lastCwd: string = "";
99+
99100
private _onOutput = new EventEmitter();
100101
get onOutput(): EventEmitter {
101102
return this._onOutput;
@@ -112,11 +113,12 @@ export class Svn {
112113

113114
async exec(cwd: string, args: any[], options: CpOptions = {}) {
114115
if (cwd) {
116+
this.lastCwd = cwd;
115117
options.cwd = cwd;
116118
}
117119

118120
if (options.log !== false) {
119-
this.log(`svn ${args.join(" ")}\n`);
121+
this.log(`[${this.lastCwd.split(/[\\\/]+/).pop()}]$ svn ${args.join(" ")}\n`);
120122
}
121123

122124
let process = cp.spawn(this.svnPath, args, options);
@@ -222,7 +224,7 @@ export class Svn {
222224
}
223225

224226
switchBranch(root: string, path: string) {
225-
return this.exec(root, ["switch", path]);
227+
return this.exec(root, ["switch", path, "--ignore-ancestry"]);
226228
}
227229

228230
revert(files: any[]) {

0 commit comments

Comments
 (0)