File: find_merged_revisions.pas

package info (click to toggle)
lazarus 2.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 214,460 kB
  • sloc: pascal: 1,862,622; xml: 265,709; cpp: 56,595; sh: 3,008; java: 609; makefile: 535; perl: 297; sql: 222; ansic: 137
file content (154 lines) | stat: -rwxr-xr-x 4,291 bytes parent folder | download | duplicates (6)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/instantfpc
// Author: Mattias Gaertner 2016

{$mode objfpc}{$H+}

uses Classes, SysUtils;

procedure WriteUsage;
begin
  writeln('Reads svn logs from trunk and fixes. Writes commits found in both.');
  writeln;
  writeln('Usage:');
  writeln('  ./find_merged_revisions.pas <trunk.log> <fixes.log> <merged.txt>');
  writeln;
  writeln('Create trunk.log and fixes.log from svn with:');
  writeln('  svn log --limit=1000 /path/lazarus/trunk > trunk.log ');
  writeln('  svn log --limit=1000 /path/lazarus/fixes > fixes.log ');
  writeln;
  writeln('merged.txt are the already listed entries on');
  writeln('  http://wiki.lazarus.freepascal.org/Lazarus_1.6_fixes_branch like this:');
  writeln('    r51389 fpvectorial: Fix compilation error with fpc 2.6.4');
  Halt(1);
end;

type
  TLogEntry = class
  public
    Revision: string;
    Message: string;
  end;

function ReadLog(aFilename: string): TFPList; // list of TLogEntry
{ Entries have the format:
------------------------------------------------------------------------
r51652 ...
some text...
}
const
  Separator = '------------------------------';
var
  sl: TStringList;
  i, j: Integer;
  Line: String;
  LogEntry: TLogEntry;
begin
  Result:=TFPList.Create;
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(aFilename);
    i:=0;
    while i<sl.Count do begin
      Line:=sl[i];
      inc(i);
      if LeftStr(Line,length(Separator))=Separator then begin
        if i=sl.Count then break;
        Line:=sl[i];
        inc(i);
        if (length(Line)>=2) and (Line[1]='r') and (Line[2] in ['0'..'9']) then begin
          // read revsion, e.g.  r51234 |...
          j:=2;
          while (j<=length(Line)) and (Line[j] in ['0'..'9']) do inc(j);
          LogEntry:=TLogEntry.Create;
          Result.Add(LogEntry);
          LogEntry.Revision:=LeftStr(Line,j-1);
          LogEntry.Message:='';
          while i<sl.Count do begin
            Line:=sl[i];
            inc(i);
            if LeftStr(Line,length(Separator))=Separator then break;
            Line:=Trim(Line);
            if Line<>'' then begin
              if LogEntry.Message<>'' then
                LogEntry.Message+=' ';
              LogEntry.Message+=Line;
            end;
          end;
          LogEntry.Message:=Trim(LogEntry.Message);
          //writeln('GetLog Rev="',LogEntry.Revision,'" Msg="',LogEntry.Message,'"');
        end;
      end;
    end;
  finally
    sl.Free;
  end;
end;

function ReadOldMerged(aFilename: string): TFPList;
{ One entry per line like this:
   r51379 Converter: Change global procedures into methods of TConvertSettings.
}
var
  sl: TStringList;
  i, j: Integer;
  Line: String;
  LogEntry: TLogEntry;
begin
  Result:=TFPList.Create;
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(aFilename);
    for i:=0 to sl.Count-1 do begin
      Line:=Trim(sl[i]);
      if (length(Line)>=2) and (Line[1]='r') and (Line[2] in ['0'..'9']) then begin
        j:=2;
        while (j<=length(Line)) and (Line[j] in ['0'..'9']) do inc(j);
        LogEntry:=TLogEntry.Create;
        Result.Add(LogEntry);
        LogEntry.Revision:=LeftStr(Line,j-1);
        LogEntry.Message:=Trim(copy(Line,j,length(Line)));
      end;
    end;
  finally
    sl.Free;
  end;
end;

function FindMsg(aMessage: string; Entries: TFPList): TLogEntry;
var
  i: Integer;
begin
  for i:=0 to Entries.Count-1 do begin
    Result:=TLogEntry(Entries[i]);
    if Result.Message=aMessage then exit;
  end;
  Result:=nil;
end;

function ExpandFile(aFilename: string): string;
begin
  if aFilename='' then
    WriteUsage;
  Result:=ExpandFilename(aFilename);
end;

var
  TrunkLog, FixesLog, OldMerged: TFPList;
  TrunkID: Integer;
  FixesEntry, TrunkEntry: TLogEntry;
begin
  if ParamCount<3 then WriteUsage;
  TrunkLog:=ReadLog(ExpandFile(ParamStr(1)));
  FixesLog:=ReadLog(ExpandFile(ParamStr(2)));
  OldMerged:=ReadOldMerged(ExpandFile(ParamStr(3)));

  TrunkID:=0;
  writeln('Merged revisions:');
  for TrunkID:=TrunkLog.Count-1 downto 0 do begin
    TrunkEntry:=TLogEntry(TrunkLog[TrunkID]);
    FixesEntry:=FindMsg(TrunkEntry.Message,FixesLog);
    if FixesEntry=nil then continue;
    if FindMsg(FixesEntry.Message,OldMerged)<>nil then continue;
    writeln(TrunkEntry.Revision,' (',FixesEntry.Revision,') ',TrunkEntry.Message);
  end;
end.