closetodo.pp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. if ListFN<>'' then
  108. FIDS.SaveToFile(ListFN);
  109. end;
  110. For I:=0 to FIDS.Count-1 do
  111. CloseTodo(StrToInt64Def(FIDS[i],-1));
  112. Writeln(Format('Closed %d todos',[FIDS.Count]));
  113. // stop program loop
  114. Terminate;
  115. end;
  116. constructor TCloseTodoApplication.Create(TheOwner: TComponent);
  117. begin
  118. inherited Create(TheOwner);
  119. FConfig.Reset;
  120. FClient:=TGitLabClient.Create;
  121. FClient.OnLog:=@DoClientLog;
  122. StopOnException:=True;
  123. FIDS:=TStringList.Create;
  124. end;
  125. destructor TCloseTodoApplication.Destroy;
  126. begin
  127. FreeAndNil(FIDS);
  128. FreeAndNil(FClient);
  129. inherited Destroy;
  130. end;
  131. procedure TCloseTodoApplication.Usage(const aError: String);
  132. begin
  133. if (aError<>'') then
  134. Writeln('Error : ',aError);
  135. Writeln('Usage: ', ExeName, ' [options]');
  136. Writeln('Where [Options] is one or more of:');
  137. Writeln('-h --help This help');
  138. Writeln('-c --config=FILE Config file');
  139. Writeln('-l --list=FILE if file exists, read todo IDS from list. If file does not exist, write file after querying gitlab');
  140. Writeln('-q --quiet less messages');
  141. end;
  142. var
  143. Application: TCloseTodoApplication;
  144. begin
  145. Application:=TCloseTodoApplication.Create(nil);
  146. Application.Title:='Close Todos Application';
  147. Application.Run;
  148. Application.Free;
  149. end.