Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added scaffolding for VCS client interface. |
---|---|
Timelines: | family | ancestors | descendants | both | feature/rewrite-multi-async |
Files: | files | file ages | folders |
SHA1: |
083aa4a1658418563c46936ed6c0f2b9 |
User & Date: | tinus 2016-02-21 15:22:31.513 |
Context
2016-02-22
| ||
18:34 | Added console running code to TVCSClient. check-in: 20d7dd8edd user: tinus tags: feature/rewrite-multi-async | |
2016-02-21
| ||
15:22 | Added scaffolding for VCS client interface. check-in: 083aa4a165 user: tinus tags: feature/rewrite-multi-async | |
13:00 | Register a module notifier for each file opened, and unregister it on destruction. check-in: 9368ecb481 user: tinus tags: feature/rewrite-multi-async | |
Changes
Changes to src/Delphi10/VCSInfo_XSeattle.dpr.
︙ | ︙ | |||
11 12 13 14 15 16 17 | using PChar or ShortString parameters. } {$R *.dres} uses System.SysUtils, System.Classes, | | > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using PChar or ShortString parameters. } {$R *.dres} uses System.SysUtils, System.Classes, vcsinfo.InfoWzrd in '..\vcsinfo.InfoWzrd.pas', vcsinfo.VCSClient in '..\vcsinfo.VCSClient.pas', vcsinfo.Fossil in '..\vcsinfo.Fossil.pas'; {$R *.res} begin end. |
Changes to src/Delphi10/VCSInfo_XSeattle.dproj.
︙ | ︙ | |||
96 97 98 99 100 101 102 | <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> <DCC_DebugInformation>0</DCC_DebugInformation> </PropertyGroup> <ItemGroup> <DelphiCompile Include="$(MainSource)"> <MainSource>MainSource</MainSource> </DelphiCompile> | > > | > | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> <DCC_DebugInformation>0</DCC_DebugInformation> </PropertyGroup> <ItemGroup> <DelphiCompile Include="$(MainSource)"> <MainSource>MainSource</MainSource> </DelphiCompile> <DCCReference Include="..\vcsinfo.InfoWzrd.pas"/> <DCCReference Include="..\vcsinfo.VCSClient.pas"/> <DCCReference Include="..\vcsinfo.Fossil.pas"/> <RcItem Include="..\Res\logo.bmp"> <ResourceType>BITMAP</ResourceType> <ResourceId>BMP_LOGO</ResourceId> </RcItem> <None Include="..\..\todo.md"/> <BuildConfiguration Include="Release"> <Key>Cfg_2</Key> <CfgParent>Base</CfgParent> </BuildConfiguration> <BuildConfiguration Include="Base"> <Key>Base</Key> </BuildConfiguration> |
︙ | ︙ | |||
148 149 150 151 152 153 154 | </DeployFile> <DeployFile LocalName="..\..\out\Win32\Debug\VCSInfo_XSeattle.dll" Configuration="Debug" Class="ProjectOutput"> <Platform Name="Win32"> <RemoteName>VCSInfo_XSeattle.dll</RemoteName> <Overwrite>true</Overwrite> </Platform> </DeployFile> | | > > > > > > > > > > > > > > > | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | </DeployFile> <DeployFile LocalName="..\..\out\Win32\Debug\VCSInfo_XSeattle.dll" Configuration="Debug" Class="ProjectOutput"> <Platform Name="Win32"> <RemoteName>VCSInfo_XSeattle.dll</RemoteName> <Overwrite>true</Overwrite> </Platform> </DeployFile> <DeployClass Name="DependencyModule"> <Platform Name="Win32"> <Operation>0</Operation> <Extensions>.dll;.bpl</Extensions> </Platform> <Platform Name="iOSDevice64"> <Operation>1</Operation> <Extensions>.dylib</Extensions> </Platform> <Platform Name="OSX32"> <RemoteDir>Contents\MacOS</RemoteDir> <Operation>1</Operation> <Extensions>.dylib</Extensions> </Platform> <Platform Name="iOSDevice32"> <Operation>1</Operation> <Extensions>.dylib</Extensions> </Platform> <Platform Name="iOSSimulator"> <Operation>1</Operation> <Extensions>.dylib</Extensions> </Platform> </DeployClass> <DeployClass Name="ProjectOSXResource"> <Platform Name="OSX32"> <RemoteDir>Contents\Resources</RemoteDir> <Operation>1</Operation> </Platform> |
︙ | ︙ | |||
507 508 509 510 511 512 513 | </DeployClass> <DeployClass Name="Android_LauncherIcon36"> <Platform Name="Android"> <RemoteDir>res\drawable-ldpi</RemoteDir> <Operation>1</Operation> </Platform> </DeployClass> | | < < < < < < < < < < < < < < < | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | </DeployClass> <DeployClass Name="Android_LauncherIcon36"> <Platform Name="Android"> <RemoteDir>res\drawable-ldpi</RemoteDir> <Operation>1</Operation> </Platform> </DeployClass> <DeployClass Name="ProjectiOSDeviceResourceRules"> <Platform Name="iOSDevice64"> <Operation>1</Operation> </Platform> <Platform Name="iOSDevice32"> <Operation>1</Operation> </Platform> </DeployClass> <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/> <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/> <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/> <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/> <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/> |
︙ | ︙ |
Added src/vcsinfo.Fossil.pas.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | unit vcsinfo.Fossil; interface uses vcsinfo.VCSClient; type TVCSFossil = class(TVCSClient) strict protected class function IsRepo(const APath: string; out ARootPath: string): boolean; override; strict protected function GetExecutable: string; override; function GetUIExecutable: string; override; function GetTitle: string; override; public constructor Create(const APath: string); destructor Destroy; override; function GetBranches: TArray<string>; override; function GetIncoming: integer; override; function GetOutgoing: integer; override; function GetPendingFiles: integer; override; function GetUntrackedFiles: Integer; override; function GetStatus: TArray<string>; override; procedure ShowRepositoryUI; override; procedure ShowRemoteUI; override; procedure ShowStatusUI; override; function SwitchToBranchUI(const BranchName: string): boolean; override; procedure ProcessRename(const OldName, NewName: string); override; end; implementation { TVCSFossil } constructor TVCSFossil.Create(const APath: string); begin inherited; end; destructor TVCSFossil.Destroy; begin inherited; end; function TVCSFossil.GetBranches: TArray<string>; begin {$MESSAGE WARN 'TODO: fossil branch list; put the current one first'} end; function TVCSFossil.GetExecutable: string; begin Result := 'fossil.exe'; end; function TVCSFossil.GetIncoming: integer; begin {$MESSAGE WARN 'TODO: if remote-url is off, then 0; otherwise -1'} Result := -1; end; function TVCSFossil.GetOutgoing: integer; begin {$MESSAGE WARN 'TODO: if remote-url is off, or autosync is on, then 0; otherwise -1'} Result := -1; end; function TVCSFossil.GetPendingFiles: integer; begin {$MESSAGE WARN 'TODO: fossil changes'} end; function TVCSFossil.GetStatus: TArray<string>; begin {$MESSAGE WARN 'TODO: fossil status'} end; function TVCSFossil.GetTitle: string; begin {$MESSAGE WARN 'TODO: fossil sqlite3 "SELECT value FROM config WHERE name=‘project-name’"'} end; function TVCSFossil.GetUIExecutable: string; begin Result := ''; end; function TVCSFossil.GetUntrackedFiles: Integer; begin {$MESSAGE WARN 'TODO: fossil extras'} end; procedure TVCSFossil.ShowRemoteUI; begin {$MESSAGE WARN 'TODO: fossil sync -autourl; show results'} end; procedure TVCSFossil.ShowRepositoryUI; begin {$MESSAGE WARN 'TODO: fossil ui'} end; procedure TVCSFossil.ProcessRename(const OldName, NewName: string); begin {$MESSAGE WARN 'TODO: fossil rename --soft "OldName" "NewName"'} end; procedure TVCSFossil.ShowStatusUI; begin {$MESSAGE WARN 'TODO: fossil gdiff'} end; function TVCSFossil.SwitchToBranchUI(const BranchName: string): boolean; begin // TODO: see old VCSInfoMenuWzrd: try fossil checkout first, then dialog with // discard (fossil checkout --force), shelve (fossil stash), merge (fossil update), or cancel {$MESSAGE WARN 'TODO: see old VCSInfoMenuWzrd'} end; class function TVCSFossil.IsRepo(const APath: string; out ARootPath: string): boolean; begin {$MESSAGE WARN 'TODO: fossil info; extract line for local-root'} end; end. |
Name change from src/VCSInfoWzrd.pas to src/vcsinfo.InfoWzrd.pas.
|
| | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | unit vcsinfo.InfoWzrd; interface uses Vcl.Graphics, ToolsAPI, vcsinfo.View; type TVCSInfoStatusWizard = class(TNotifierObject, IOTAWizard) private FLogo: TBitmap; FView: TNotifiers; public constructor Create; destructor Destroy; override; { IOTAWizard } function GetIDString: string; function GetName: string; |
︙ | ︙ | |||
40 41 42 43 44 45 46 | FLogo.LoadFromResourceName(HInstance, 'BMP_LOGO'); SplashScreenServices.AddPluginBitmap(rsWizardName, FLogo.Handle, False, 'Freeware'); (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(rsWizardName, rsWizardName, FLogo.Handle, False, 'Freeware'); // TODO: set up cache (Model) // TODO: set up UI, including timer and notifiers (View) | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | FLogo.LoadFromResourceName(HInstance, 'BMP_LOGO'); SplashScreenServices.AddPluginBitmap(rsWizardName, FLogo.Handle, False, 'Freeware'); (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(rsWizardName, rsWizardName, FLogo.Handle, False, 'Freeware'); // TODO: set up cache (Model) // TODO: set up UI, including timer and notifiers (View) FView := TNotifiers.Create; (BorlandIDEServices as IOTAServices).AddNotifier(FView); // TODO: set up thread queue (Controller) end; destructor TVCSInfoStatusWizard.Destroy; begin // TODO: destroy all the objects we own |
︙ | ︙ |
Name change from src/RepoCache.pas to src/vcsinfo.RepoCache.pas.
1 2 3 4 | unit RepoCache; interface uses | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | unit RepoCache; interface uses System.Generics.Collections, vcsinfo.VCSClient; type TRepoInfo = class private FVCSClient: TVCSClient; FRoot: string; FLastCheckRepo: TDateTime; |
︙ | ︙ |
Added src/vcsinfo.VCSClient.pas.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | unit vcsinfo.VCSClient; interface uses System.SysUtils, System.Generics.Collections; type EVCSException = class(Exception); type TVCSClient = class; TVCSClientClass = class of TVCSClient; TVCSClient = class public class function CreateForPath(const APath: string): TVCSClient; class function IsRepo(const APath: string; out ARootPath: string): boolean; virtual; abstract; class procedure RegisterVCSClass(const VCSClass: TVCSClientClass); strict private class var FRegisteredVCSes: TList<TVCSClientClass>; strict protected FRoot: string; function GetExecutable: string; virtual; abstract; function GetUIExecutable: string; virtual; abstract; function GetTitle: string; virtual; function GetCurrentBranch: string; virtual; public constructor Create(const APath: string); destructor Destroy; override; function GetBranches: TArray<string>; virtual; abstract; function GetIncoming: integer; virtual; abstract; function GetOutgoing: integer; virtual; abstract; function GetPendingFiles: integer; virtual; abstract; function GetUntrackedFiles: Integer; virtual; abstract; function GetStatus: TArray<string>; virtual; abstract; procedure ShowRepositoryUI; virtual; abstract; procedure ShowRemoteUI; virtual; abstract; procedure ShowStatusUI; virtual; abstract; function SwitchToBranchUI(const BranchName: string): boolean; virtual; abstract; procedure ProcessRename(const OldName, NewName: string); virtual; abstract; property Executable: string read GetExecutable; property UIExecutable: string read GetUIExecutable; property Root: string read FRoot; property Title: string read GetTitle; property CurrentBranch: string read GetCurrentBranch; end; implementation { TVCSClient } constructor TVCSClient.Create(const APath: string); begin end; destructor TVCSClient.Destroy; begin inherited; end; function TVCSClient.GetCurrentBranch: string; var Branches: TArray<string>; begin // ASSUMPTION: the first branch is the current one Branches := GetBranches; if Length(Branches) > 0 then Result := Branches[0] else Result := ''; end; function TVCSClient.GetTitle: string; begin Result := ExtractFileName(ExcludeTrailingPathDelimiter(FRoot)); end; class function TVCSClient.CreateForPath(const APath: string): TVCSClient; var VCSClass: TVCSClientClass; RootPath: string; begin for VCSClass in FRegisteredVCSes do begin if VCSClass.IsRepo(APath, RootPath) then begin Result := VCSClass.Create(APath); Exit; end; end; Result := nil; end; class procedure TVCSClient.RegisterVCSClass(const VCSClass: TVCSClientClass); begin FRegisteredVCSes.Add(VCSClass); end; end. |
Name change from src/VCSInfoView.pas to src/vcsinfo.View.pas.
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | unit vcsinfo.View; interface uses ToolsAPI, System.Classes, System.Generics.Collections; type TNotifiers = class(TNotifierObject, IOTAIDENotifier, IOTAIDENotifier50, IOTAIDENotifier80, IOTAModuleNotifier, IOTAModuleNotifier80, IOTAModuleNotifier90) private FModules: TDictionary<IOTAModule,Integer>; public constructor Create; destructor Destroy; override; |
︙ | ︙ | |||
92 93 94 95 96 97 98 | implementation uses System.SysUtils; { TVCSInfoView } | | | | | | 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 | implementation uses System.SysUtils; { TVCSInfoView } constructor TNotifiers.Create; begin inherited; FModules := TDictionary<IOTAModule,Integer>.Create; end; destructor TNotifiers.Destroy; var Module: IOTAModule; begin for Module in FModules.Keys do begin Module.RemoveNotifier(FModules.Items[Module]); end; FModules.Free; inherited; end; procedure TNotifiers.LogMessage(const Text: string; const Args: array of const); begin LogMessage(Format(Text, Args)); end; procedure TNotifiers.LogMessage(const Text: string); const RFC3339: TFormatSettings = (DateSeparator: '-'; TimeSeparator: ':'; ShortDateFormat: 'yyyy-MM-dd'; LongDateFormat: 'yyyy-MM-dd'; ShortTimeFormat: 'hh:nn:ss'; LongTimeFormat: 'hh:nn:ss.zzz'); var Messages: IOTAMessageServices; Group: IOTAMessageGroup; |
︙ | ︙ | |||
139 140 141 142 143 144 145 | for Line in Text.Replace(#13#10, #10).Split([#10, #13]) do begin Messages.AddTitleMessage(TimeStamp + #9 + Line, Group); if TimeStamp[1] <> #9 then TimeStamp := StringOfChar(#9, 2); end; end {TVCSInfoView.LogMessage}; | | | | | | | > | | | | | | 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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | for Line in Text.Replace(#13#10, #10).Split([#10, #13]) do begin Messages.AddTitleMessage(TimeStamp + #9 + Line, Group); if TimeStamp[1] <> #9 then TimeStamp := StringOfChar(#9, 2); end; end {TVCSInfoView.LogMessage}; procedure TNotifiers.AfterCompile(Succeeded, IsCodeInsight: Boolean); begin end; procedure TNotifiers.AfterCompile(const Project: IOTAProject; Succeeded, IsCodeInsight: Boolean); begin if not IsCodeInsight then begin {$MESSAGE WARN 'TODO: update project’s workdir status'} end; end; procedure TNotifiers.AfterCompile(Succeeded: Boolean); begin end; procedure TNotifiers.AfterRename(const OldFileName, NewFileName: string); begin {$MESSAGE HINT 'TODO: rename in VCS as well'} LogMessage('Renamed "%s" to "%s"', [OldFilename, NewFileName]); end; function TNotifiers.AllowSave: Boolean; begin Result := True; {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in two seconds'} LogMessage('AllowSave: %d', [Ord(Result)]); (BorlandIDEServices as IOTAModuleServices).CurrentModule.FileName; end; procedure TNotifiers.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); begin end; procedure TNotifiers.BeforeCompile(const Project: IOTAProject; IsCodeInsight: Boolean; var Cancel: Boolean); begin end; procedure TNotifiers.BeforeRename(const OldFileName, NewFileName: string); begin end; function TNotifiers.CheckOverwrite: Boolean; begin Result := True; end; procedure TNotifiers.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean); var NewModule: IOTAModule; Index: Integer; begin case NotifyCode of ofnFileOpened: begin |
︙ | ︙ | |||
208 209 210 211 212 213 214 | ofnActiveProjectChanged: begin {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in a second'} LogMessage('Active project changed: "%s"', [FileName]); end; end; end; | | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | ofnActiveProjectChanged: begin {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in a second'} LogMessage('Active project changed: "%s"', [FileName]); end; end; end; function TNotifiers.GetOverwriteFileName(Index: Integer): string; begin Result := ''; end; function TNotifiers.GetOverwriteFileNameCount: Integer; begin Result := 0; end; procedure TNotifiers.ModuleRenamed(const NewName: string); begin end; procedure TNotifiers.SetSaveFileName(const FileName: string); begin end; end. |
Changes to todo.md.
︙ | ︙ | |||
106 107 108 109 110 111 112 113 114 115 116 117 118 119 | * Overview of current status _(nice to have)_ - `hg -y --summary --remote` - `fossil info` or `fossil status` * Repo title _(nice to have)_ - `hg -yq root` - `fossil sqlite3 "SELECT value FROM config WHERE name='project-name'"` (or `fossil info`, then extract the line starting with `project-name:`) ____________________________________________________________________________________________________ TRepoInfo = class private FVCSClient: TVCSClient; FRoot: string; | > > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | * Overview of current status _(nice to have)_ - `hg -y --summary --remote` - `fossil info` or `fossil status` * Repo title _(nice to have)_ - `hg -yq root` - `fossil sqlite3 "SELECT value FROM config WHERE name='project-name'"` (or `fossil info`, then extract the line starting with `project-name:`) * Process rename - `hg -yq rename --after SOURCE DEST` - `fossil rename --soft OLDNAME NEWNAME` ____________________________________________________________________________________________________ TRepoInfo = class private FVCSClient: TVCSClient; FRoot: string; |
︙ | ︙ |