Changes On Branch feature/multi-vcs

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch feature/multi-vcs Excluding Merge-Ins

This is equivalent to a diff from 1386e67547 to 022c6433c4

2015-11-18
12:19
Added plans and ideas for further development. check-in: a006fff05f user: tinus tags: trunk
2015-11-17
21:44
Added some implementation details. Leaf check-in: 022c6433c4 user: tinus tags: feature/multi-vcs
21:29
Started branch to support multiple, unit-pluggable, version control systems. check-in: c618ca4b81 user: tinus tags: feature/multi-vcs
21:17
Added project files for Delphi 10 Seattle. check-in: 1386e67547 user: tinus tags: trunk
16:54
Keep original root path (only use final path for lookup). Show the root path along with the summary. check-in: f6e4f59d52 user: tinus tags: trunk

Changes to src/VCSInfoMenuWzrd.pas.

1
2
3
4
5
6
7
8
9



10
11
12

13
14
15




































16
17
18
19
20
21
22
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







-

+
+
+


-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







unit VCSInfoMenuWzrd;

interface
uses
  System.Generics.Collections,
  ToolsAPI;


type
  TRepoClient = class;
  TRepoClientClass = class of TRepoClient;

  TRepoInfo = record
    Root: string;
    IsRepo: Boolean;
    Client: TRepoClient;
    Incoming: Cardinal;
    Outgoing: Cardinal;
    LastUpdated: TDateTime;
    function IsRepo: Boolean;
  end;

  TRepoClient = class abstract
  private
    FRootPath: string;
  public
    constructor Create(const Path: string);
    property Root: string read FRootPath;
  public
    class function IsRepo(const Path: string): boolean; virtual;
    class function GetRoot(const Path: string): string; virtual;
    class function GetIncoming(const Path: string): Cardinal; virtual;
    class function GetOutgoing(const Path: string): Cardinal; virtual;
    class function GetSummary(const Path: string): Cardinal; virtual;
  private
    class var FClients: TList<TRepoClientClass>;
  public
    class procedure RegisterClient(const RepoClientClass: TRepoClientClass);
    class function CreateClient(const Path: string): TRepoClient;
  end;

  THgClient = class(TRepoClient)
    class function IsRepo(const Path: string): boolean; override;
    class function GetRoot(const Path: string): string; override;
    class function GetIncoming(const Path: string): Cardinal; override;
    class function GetOutgoing(const Path: string): Cardinal; override;
    class function GetSummary(const Path: string): Cardinal; override;
  end;

  TFossilClient = class(TRepoClient)
    class function IsRepo(const Path: string): boolean; override;
    class function GetRoot(const Path: string): string; override;
    class function GetIncoming(const Path: string): Cardinal; override;
    class function GetOutgoing(const Path: string): Cardinal; override;
    class function GetSummary(const Path: string): Cardinal; override;
  end;

  // TODO: implement IOTAEditorNotifier and/or IOTAIDENotifier so we know which file is active
  TVCSInfoWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
    private
      FRepos: TDictionary<string,TRepoInfo>;

423
424
425
426
427
428
429

430
431
432
433
434
435
436
437
438
439




440
441
442
443
444
445
446
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489







+










+
+
+
+







  Result := scMenuIDString;
end;

{ ------------------------------------------------------------------------------------------------ }
function TVCSInfoWizard.GetRepoInfo(const AFileName: string; const AForceUpdate: Boolean): TRepoInfo;
var
  FilePath, FinalFilePath, RootPath, FinalRootPath: string;
  Client: TRepoClient;
  Lines: TStringList;
  iRes: Cardinal;
begin
  Result := Default(TRepoInfo);
  if not Assigned(FRepos) then
    FRepos := TDictionary<string,TRepoInfo>.Create;

  FilePath := ExtractFileDir(AFileName);
  FinalFilePath := GetFinalPathName(FilePath);
  if AForceUpdate or (not FRepos.TryGetValue(FinalFilePath, Result)) or (Now - Result.LastUpdated > 5 / SecsPerDay) then begin

    // TODO: try all registered repo clients to identify whether FilePath is a repo, and get its root
    Client := TRepoClient.CreateClient(FilePath);

    iRes := ExecuteCmd('hg -yq root', RootPath, False, nil, FilePath);
    if iRes >= 255 then begin
      Result.Root := FilePath;
      Result.LastUpdated := Now;
      FinalRootPath := FinalFilePath;
    end else begin
      RootPath := RootPath.Trim;