1

Is there a tool for Windows that can read the Delphi history files.
and extract the lines-of-code written per session along with the timestamps of the sessions.

What info do I want

session_id   date+time             filename      lines_of_code changed
1            1-1-2011 - 13:14:36   unit1.pas     100
....

What info do I have to extract this from
I'm using Delphi 2007.
And every change a in source file gets written to a subdir called history that looks like:

name                date_changed    type     size
project1.dpr.~1~    date-time       ~1~      1  kb
project1.dpr.~2~    date-time       ~2~      1  kb
unit1.pas.~1~       date-time       ~1~      83 kb
...

Every history file includes the full source code, not just the differences.
(so if you would like to revert back to a source file you can just code that file over the old)

Not subversion
For the future I'm going to use a subversion program to keep track of this stuff, but for the past stuff I want to have some record as well.
So unless a subversion clone can index the old source file backups in the history folder I'm not looking for that now.

durron597
  • 31,968
  • 17
  • 99
  • 158
Johan
  • 74,508
  • 24
  • 191
  • 319
  • 2
    I have never seen an automated tool that can deal accurately with what happens in a programming session. This is going to be even more so when you try to infer time spent from time stamps of the history files. What about looking at but not changing a file? That is time spent on a problem but not on changing. What about changing a whole lot, and then not saving but reloading. That's editing time that won't be recorded. And the other way round: you have a file open for x hours, but only look at it at the end of a programming session, when you change a single character in a user message... – Marjan Venema Apr 20 '11 at 12:36
  • The diff tool needs to extract the lines of code changed between the 2 stored versions of a file. – Johan Apr 20 '11 at 12:38
  • So what about the "time spend" in the title of your question? – Marjan Venema Apr 20 '11 at 12:43
  • That would be a nice bonus, but you can deduce a lot from #of lines and timestamps. – Johan Apr 20 '11 at 12:59
  • You should try Windiff, it has a very good GUI and it is open source. – yms Apr 20 '11 at 13:21
  • You could try Beyond Compare and use the "show diffs only" view. It is the best difference app I know and it has a command line interface, so you could probably write some code around it fairly easily. – Marjan Venema Apr 20 '11 at 13:39
  • @yms.cu: You're thinking of WinMerge. WinDiff is the closed-source viewer included with the Windows Platform SDK. Neither of them can be automated to generate output from the command line. – Zoë Peterson Apr 20 '11 at 14:35
  • @Craig Yes, you are right, I was thinking of WinMerge. But I cannot see the requirement for "command line automation" in the question though... – yms Apr 20 '11 at 15:11
  • @yms Command line automation would be cool. – Johan Apr 20 '11 at 15:15
  • I agree with Craig Young below: it looks as though you're trying to do something stupid, so telling you how to do that won't help. What problem are you actually trying to solve (and perhaps it might go on programmers.SE instead?) –  Apr 21 '11 at 01:42
  • I want to get a diff between each of the stored versions ~1~ -> ~2~ -> ~3~ – Johan Apr 21 '11 at 01:50

3 Answers3

4

I'm going to be blunt.

It sounds to me as if you're a project manager treading in extremely dangerous territory. Johan (vehemently) denies being a project manager. :D
Notwithstanding the fact that apart from the desire to specifically check the Delphi history, this sounds far more like a super-user question than a programming question.

Please refer to the following links for the dangers to such approaches:
-2000 Lines of code
Measuring Knowledge Workers
Productivity 2.0

Whenever you try to correlate lines of code and time, you do so at the expense of many other considerations. The following list is certainly not exhaustive!

  • A particular developer's familiarity with a section of code.
  • Fragility of a section of code.
  • Complexity of a bug or feature.... Which has nothing to do with lines of code.
  • Existing redundancies.
  • Introduced redundancies.
  • Accuracy of work undertaken.
  • Thoroughness of work undertaken.
  • Nature of the work undertaken at a particular time.
  • Hand-written vs. generateed code (dprs are generated, dfms are partially generate - setting properties is like writing code).
  • Readability of existing code.
  • Flexibiliy of existing code.

EDIT
I know that I haven't really answered your question, but I implore you to give it due consideration. Please think carefully about what you're trying to achieve.


EDIT2
Even for non project managers, this advice stands. You cannot draw a meaningful conclusion from the correlation between time & lines of code. From a scientific perspective, there is too much 'interference'.

I repeat: Please think carefully about what you're trying to achieve.
Your comment says "when you worked in what for how long". That sounds like timesheet information to me, in which case simply which files are affected should suffice.

As a result, you may be able to get away with a combination of the following DOS commands: dir, findstr, sort.

Disillusioned
  • 14,635
  • 3
  • 43
  • 77
  • @craig sorry im not a project manager sorry bout getting you all worked up i need the tool to work out when i worked ln what for how long for me – Johan Apr 20 '11 at 22:54
  • @Johan: Don't worry, I didn't get worked up. My humble apologies for accusing you of being a project manager. Sorry to have offended you. :) However, I still stand by my answer. You cannot draw a meaningful correlation between time & lines of code. – Disillusioned Apr 20 '11 at 23:23
  • BTW how did you do the strikethrough effect in markdown? – Johan Apr 21 '11 at 01:17
  • +1, good list. I knew about the -2000 article, wanted to put a link in my answer, but google failed me. – Cosmin Prund Apr 21 '11 at 04:45
  • The markdown supports limited html, strike and /strike is one of them. – Disillusioned Apr 21 '11 at 16:20
3

Virtually any Diff tool that generates so-called "diff compatible" diff files or "patches" can be used for the job. For example, I'm sure you can use this: http://gnuwin32.sourceforge.net/packages/diffutils.htm

Simply invoke the command line tool giving as parameters the new and the old versions of the file and Annalise it's output: You basically care about lines that start with a single - or +. This would give you a rough estimate of number of lines changed. If you want to get fancy you'll need to modify your algorithm to properly detect changed blocks, but that's a lot more difficult, because diff's job is to generate output that's used to transform the "old" file into a "new" files, not count changes. Line edits are usually shown as a deletion followed by an addition.

Here are the problems you'll face using diff:

  • Moved lines are shown as both DELETIONS and ADDITIONS and will likely be counted twice, even those all the programmer did was restructure the code a bit.
  • Edited lines might be counted more then once.

Since you don't care about the actual diff, and you want a rough estimate of changed lines of code, here's an other very simple idea that provides you with a number. Not very accurate, but then again LOC counting is not exactly an accurate measure of programmer performance any way! This code looks at both OLD and NEW files and gives the number of lines found in OLD but not found in NEW plus the number of lines found in NEW but not found in OLD

function CountLineChanges(const OldFile, NewFile:string):Integer;
var OldL: TStringList;
    NewL: TStringList;
    i: Integer;

  procedure FillListWithStringsFromFile(const FileName: string; const L:TStringList);
  var F: TStringList;
      i,n: Integer;
      s: string;
  begin
    F := TStringList.Create;
    try
      F.LoadFromFile(FileName);
      for i:=0 to F.Count-1 do
      begin
        s := F[i];
        if L.IndexOf(s) = -1 then
          L.Add(s)
        else
          begin
            // Seeing this line again!
            n := 1;
            while L.IndexOf(s + '#' + IntToStr(n)) <> -1 do
              Inc(n);
            L.Add(s + '#' + IntToStr(n));
          end;
      end;
    finally F.Free;
    end;
  end;

begin
  OldL := TStringList.Create;
  try
    OldL.Sorted := True;
    NewL := TStringList.Create;
    try
      NewL.Sorted := True;

      FillListWithStringsFromFile(OldFile, OldL);
      FillListWithStringsFromFile(NewFile, NewL);

      Result := 0;
      for i:=0 to OldL.Count-1 do
        if NewL.IndexOf(OldL[i]) = -1 then
          Inc(Result);
      for i:=0 to NewL.Count-1 do
        if OldL.IndexOf(NewL[i]) = -1 then
          Inc(Result);

    finally NewL.Free;
    end;
  finally OldL.Free;
  end;
end;

Issues with this code:

  • Blocks of code moved from one place to the other give 0 as a result.
  • All edited lines are counted precisely twice.
Cosmin Prund
  • 25,498
  • 2
  • 60
  • 104
0

IMO, you should use your source repository history instead. i.e. subversion. It will show you a log of all checkins, for all users, with timestamps. forever.

Chris Thornton
  • 15,620
  • 5
  • 37
  • 62
  • Thanks Chris but I want to extract this info after the fact, not keep this data for the future. – Johan Apr 20 '11 at 12:25