closetodo.lpr 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. program closetodo;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}
  5. cthreads,
  6. {$ENDIF}
  7. Classes, SysUtils, CustApp, fpjson, gitlabclient,opensslsockets, jsonparser ;
  8. type
  9. { TCloseTodoApplication }
  10. TCloseTodoApplication = class(TCustomApplication)
  11. private
  12. FConfig : TGitlabConfig;
  13. FClient : TGitLabClient;
  14. FIDS : TStrings;
  15. FQuiet : Boolean;
  16. procedure CloseTodo(aID: int64);
  17. procedure DoClientLog(Sender: TObject; const aMessage: string);
  18. procedure DoResource(Sender: TObject; aPage, aIndex, aCount: Integer; aObject: TJSONObject; aContinue: Boolean);
  19. protected
  20. procedure DoRun; override;
  21. public
  22. constructor Create(TheOwner: TComponent); override;
  23. destructor Destroy; override;
  24. procedure Usage(const aError : String); virtual;
  25. end;
  26. { TCloseTodoApplication }
  27. procedure TCloseTodoApplication.DoResource(Sender: TObject; aPage, aIndex,
  28. aCount: Integer; aObject: TJSONObject; aContinue: Boolean);
  29. Var
  30. aData : TJSONData;
  31. Msg,aState : String;
  32. aBugID,aBugIID,aProjectID : Int64;
  33. begin
  34. Msg:=Format('[Page %d [%d/%d]: ',[aPage,aIndex,aCount]);
  35. aProjectID:=0;
  36. aBugID:=0;
  37. aBugIID:=0;
  38. aState:='';
  39. aData:=aObject.FindPath('target.state');
  40. if Assigned(aData) then
  41. aState:=aData.AsString;
  42. aData:=aObject.FindPath('project.id');
  43. if Assigned(aData) then
  44. aProjectID:=aData.AsInt64;
  45. aData:=aObject.FindPath('target.id');
  46. if Assigned(aData) then
  47. aBugID:=aData.AsInt64;
  48. aData:=aObject.FindPath('target.iid');
  49. if Assigned(aData) then
  50. aBugIID:=aData.Asint64;
  51. DoClientLog(Self,Msg+Format('Project: %d, bug: %d, bug iid: %d, state : %s',[aProjectID,aBugID,aBugIID,aState]));
  52. if SameText(aState,'closed') then
  53. begin
  54. if (FConfig.ProjectID=0) or (aProjectID=FConfig.ProjectID) then
  55. FIDS.Add(IntToStr(aObject.Get('id',Int64(0))));
  56. end
  57. end;
  58. procedure TCloseTodoApplication.CloseTodo(aID : int64);
  59. Var
  60. aResource : String;
  61. begin
  62. if (aID=-1) then
  63. exit;
  64. aResource:=Format('todos/%d/mark_as_done',[aID]);
  65. Writeln('Posting ',aResource);
  66. FClient.CreateResource(aResource,Nil);
  67. end;
  68. procedure TCloseTodoApplication.DoClientLog(Sender: TObject;
  69. const aMessage: string);
  70. begin
  71. if not FQuiet then
  72. Writeln(aMessage);
  73. end;
  74. procedure TCloseTodoApplication.DoRun;
  75. var
  76. ErrorMsg: String;
  77. ListFN,ConfigFN : String;
  78. I : Integer;
  79. begin
  80. Terminate;
  81. ErrorMsg:=CheckOptions('hc:l:q', ['help','config:','list:','quiet']);
  82. if (ErrorMsg<>'') or HasOption('h','help') then
  83. begin
  84. Usage(ErrorMsg);
  85. Exit;
  86. end;
  87. FQuiet:=HasOption('q','quiet');
  88. ConfigFN:=GetOptionValue('c','config');
  89. if ConfigFN='' then
  90. begin
  91. Usage('Need gitlab config file');
  92. Exit;
  93. end;
  94. if not FileExists(ConfigFN)then
  95. begin
  96. Usage('Gitlab config file "'+ConfigFN+'" does not exist');
  97. Exit;
  98. end;
  99. FConfig.LoadFromFile(ConfigFN,'');
  100. FClient.Config:=FConfig;
  101. ListFN:=GetOptionValue('l','list');
  102. if FileExists(ListFN)then
  103. FIDS.LoadFromFile(ListFN)
  104. else
  105. begin
  106. FClient.ForEachResource('todos',['action','assigned','state','pending'],@DoResource);
  107. FIDS.SaveToFile(ListFN);
  108. end;
  109. For I:=0 to FIDS.Count-1 do
  110. CloseTodo(StrToInt64Def(FIDS[i],-1));
  111. Writeln(Format('Closed %d todos',[FIDS.Count]));
  112. // stop program loop
  113. Terminate;
  114. end;
  115. constructor TCloseTodoApplication.Create(TheOwner: TComponent);
  116. begin
  117. inherited Create(TheOwner);
  118. FConfig.Reset;
  119. FClient:=TGitLabClient.Create;
  120. FClient.OnLog:=@DoClientLog;
  121. StopOnException:=True;
  122. FIDS:=TStringList.Create;
  123. end;
  124. destructor TCloseTodoApplication.Destroy;
  125. begin
  126. FreeAndNil(FIDS);
  127. FreeAndNil(FClient);
  128. inherited Destroy;
  129. end;
  130. procedure TCloseTodoApplication.Usage(const aError: String);
  131. begin
  132. if (aError<>'') then
  133. Writeln('Error : ',aError);
  134. Writeln('Usage: ', ExeName, ' [options]');
  135. Writeln('Where [Options] is one or more of:');
  136. Writeln('-h --help This help');
  137. Writeln('-c --config=FILE Config file');
  138. Writeln('-l --list=FILE if file exists, read todo IDS from list. If file does not exist, write file after querying gitlab');
  139. Writeln('-q --quiet less messages');
  140. end;
  141. var
  142. Application: TCloseTodoApplication;
  143. begin
  144. Application:=TCloseTodoApplication.Create(nil);
  145. Application.Title:='Close Todos Application';
  146. Application.Run;
  147. Application.Free;
  148. end.