Skip to content

Commit 0c56f81

Browse files
authored
Merge pull request #139 from edgardmessias/news_commits_statusbar
Added in StatusBar notification of news commits (Close #135)
2 parents 1999488 + 5a03f06 commit 0c56f81

File tree

6 files changed

+116
-21
lines changed

6 files changed

+116
-21
lines changed

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,13 @@
360360
"How frequently (in minutes) to check branch changes. Set to `0` to avoid periodic checks.",
361361
"default": 5
362362
},
363+
"svn.newsCommits.update": {
364+
"type": "number",
365+
"minimum": 0,
366+
"description":
367+
"How frequently (in minutes) to check news commits. Set to `0` to avoid periodic checks.",
368+
"default": 5
369+
},
363370
"svn.multipleFolders.enabled": {
364371
"type": "boolean",
365372
"description": "Allow to find subfolders using SVN",

src/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ export class SvnCommands {
702702
@command("svn.update", { repository: true })
703703
async update(repository: Repository) {
704704
try {
705-
const result = await repository.repository.update();
705+
const result = await repository.updateRevision();
706706
window.showInformationMessage(result);
707707
} catch (error) {
708708
console.error(error);

src/repository.ts

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { IFileStatus } from "./statusParser";
2626
export class Repository {
2727
public watcher: FileSystemWatcher;
2828
public sourceControl: SourceControl;
29+
public statusBar: SvnStatusBar;
2930
public changes: SvnResourceGroup;
3031
public unversioned: SvnResourceGroup;
3132
public external: SvnResourceGroup;
@@ -36,8 +37,10 @@ export class Repository {
3637
private disposables: Disposable[] = [];
3738
public currentBranch = "";
3839
public isSwitchingBranch: boolean = false;
40+
public isUpdatingRevision: boolean = false;
3941
public branches: any[] = [];
4042
public branchesTimer: NodeJS.Timer;
43+
public newsCommit: number = 0;
4144

4245
private _onDidChangeRepository = new EventEmitter<Uri>();
4346
readonly onDidChangeRepository: Event<Uri> = this._onDidChangeRepository
@@ -49,6 +52,10 @@ export class Repository {
4952
private _onDidChangeBranch = new EventEmitter<void>();
5053
readonly onDidChangeBranch: Event<void> = this._onDidChangeBranch.event;
5154

55+
private _onDidChangeNewsCommit = new EventEmitter<void>();
56+
readonly onDidChangeNewsCommit: Event<void> = this._onDidChangeNewsCommit
57+
.event;
58+
5259
get root(): string {
5360
return this.repository.root;
5461
}
@@ -114,19 +121,20 @@ export class Repository {
114121
this.sourceControl.quickDiffProvider = this;
115122
this.disposables.push(this.sourceControl);
116123

117-
const statusBar = new SvnStatusBar(this);
118-
this.disposables.push(statusBar);
119-
statusBar.onDidChange(
120-
() => (this.sourceControl.statusBarCommands = statusBar.commands),
124+
this.statusBar = new SvnStatusBar(this);
125+
this.disposables.push(this.statusBar);
126+
this.statusBar.onDidChange(
127+
() => (this.sourceControl.statusBarCommands = this.statusBar.commands),
121128
null,
122129
this.disposables
123130
);
124131

125-
const updateBranchName = async () => {
132+
const updateBranchInfo = async () => {
126133
this.currentBranch = await this.getCurrentBranch();
127-
this.sourceControl.statusBarCommands = statusBar.commands;
134+
this.sourceControl.statusBarCommands = this.statusBar.commands;
128135
};
129-
updateBranchName();
136+
this.onDidChangeStatus(updateBranchInfo);
137+
updateBranchInfo();
130138

131139
this.changes = this.sourceControl.createResourceGroup(
132140
"changes",
@@ -163,7 +171,15 @@ export class Repository {
163171
}, 1000 * 60 * updateFreq);
164172
}
165173

174+
const updateFreqNews = svnConfig.get<number>("svn.newsCommits.update");
175+
if (updateFreqNews) {
176+
setInterval(() => {
177+
this.updateNewsCommits();
178+
}, 1000 * 60 * updateFreqNews);
179+
}
180+
166181
this.updateBranches();
182+
this.updateNewsCommits();
167183
this.update();
168184
}
169185

@@ -176,6 +192,15 @@ export class Repository {
176192
}
177193
}
178194

195+
@debounce(1000)
196+
async updateNewsCommits() {
197+
const newsCommit = await this.repository.countNewsCommit();
198+
if (newsCommit !== this.newsCommit) {
199+
this.newsCommit = newsCommit;
200+
this._onDidChangeNewsCommit.fire();
201+
}
202+
}
203+
179204
@debounce(1000)
180205
async update() {
181206
let changes: any[] = [];
@@ -286,8 +311,6 @@ export class Repository {
286311
this.external.resourceStates = [];
287312
}
288313

289-
this.currentBranch = await this.getCurrentBranch();
290-
291314
this._onDidChangeStatus.fire();
292315

293316
return Promise.resolve();
@@ -362,6 +385,7 @@ export class Repository {
362385
this.isSwitchingBranch = false;
363386
this.updateBranches();
364387
this._onDidChangeBranch.fire();
388+
this.updateNewsCommits()
365389
return response;
366390
}
367391

@@ -386,9 +410,18 @@ export class Repository {
386410
this.isSwitchingBranch = false;
387411
this.updateBranches();
388412
this._onDidChangeBranch.fire();
413+
this.updateNewsCommits()
389414
}
390415
}
391416

417+
async updateRevision() {
418+
this.isUpdatingRevision = true;
419+
const response = await this.repository.update();
420+
this.isUpdatingRevision = false;
421+
this.updateNewsCommits();
422+
return response;
423+
}
424+
392425
async resolve(file: string, action: string) {
393426
try {
394427
const response = await this.repository.resolve(file, action);

src/statusBar.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { window, StatusBarItem, Disposable, EventEmitter, Event } from "vscode";
1+
import {
2+
window,
3+
StatusBarItem,
4+
Disposable,
5+
EventEmitter,
6+
Event,
7+
Command
8+
} from "vscode";
29
import { Repository } from "./repository";
310

411
export class SvnStatusBar {
@@ -24,20 +31,41 @@ export class SvnStatusBar {
2431
null,
2532
this.disposables
2633
);
34+
repository.onDidChangeNewsCommit(
35+
this._onDidChange.fire,
36+
this._onDidChange,
37+
this.disposables
38+
);
2739
}
2840

29-
get commands() {
30-
const icon = this.repository.isSwitchingBranch ? "sync~spin" : "git-branch";
31-
const title = `$(${icon}) ${this.repository.currentBranch}`;
41+
get commands(): Command[] {
42+
const result: Command[] = [];
3243

33-
return [
34-
{
44+
if (this.repository.currentBranch) {
45+
const icon = this.repository.isSwitchingBranch
46+
? "sync~spin"
47+
: "git-branch";
48+
result.push({
3549
command: "svn.switchBranch",
3650
tooltip: "switch branch",
37-
title,
51+
title: `$(${icon}) ${this.repository.currentBranch}`,
3852
arguments: [this.repository]
39-
}
40-
];
53+
});
54+
}
55+
56+
const icon = this.repository.isUpdatingRevision ? "sync~spin" : "sync";
57+
const title =
58+
this.repository.newsCommit > 0
59+
? `${this.repository.newsCommit} news commits`
60+
: "Updated";
61+
62+
result.push({
63+
command: "svn.update",
64+
tooltip: "Update Revision",
65+
title: `$(${icon}) ${title}`,
66+
arguments: [this.repository]
67+
});
68+
return result;
4169
}
4270

4371
dispose(): void {

src/svn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ export class Svn {
254254
return this.exec("", ["ls", "--xml", filePath]);
255255
}
256256

257-
info(path: string) {
258-
return this.exec(path, ["info", "--xml"]);
257+
info(path: string, revision: string = "BASE") {
258+
return this.exec(path, ["info", "--xml", "-r", revision]);
259259
}
260260

261261
copy(rootPath: string, branchPath: string, name: string) {

src/svnRepository.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { workspace } from "vscode";
22
import { Svn, CpOptions } from "./svn";
33
import { IFileStatus, parseStatusXml } from "./statusParser";
44
import { parseInfoXml, ISvnInfo } from "./infoParser";
5+
import { sequentialize } from "./decorators";
56

67
export class Repository {
78
private _info?: ISvnInfo;
@@ -28,6 +29,7 @@ export class Repository {
2829
this._info = undefined;
2930
}
3031

32+
@sequentialize
3133
async getInfo(): Promise<ISvnInfo> {
3234
if (this._info) {
3335
return this._info;
@@ -269,6 +271,8 @@ export class Repository {
269271
throw new Error(result.stderr);
270272
}
271273

274+
this.resetInfo();
275+
272276
const message = result.stdout
273277
.trim()
274278
.split(/\r?\n/)
@@ -318,4 +322,27 @@ export class Repository {
318322

319323
return result.stdout;
320324
}
325+
326+
async countNewsCommit(revision: string = "BASE:HEAD") {
327+
const result = await this.svn.exec(this.workspaceRoot, [
328+
"log",
329+
"-r",
330+
revision,
331+
"-q",
332+
"--xml"
333+
]);
334+
335+
if (result.exitCode !== 0) {
336+
return 0;
337+
}
338+
339+
const matches = result.stdout.match(/<logentry/g);
340+
341+
if (matches && matches.length > 0) {
342+
// Every return current commit
343+
return matches.length - 1;
344+
}
345+
346+
return 0;
347+
}
321348
}

0 commit comments

Comments
 (0)