Parsing VSS History Files

Parse those nasty VSS history files. Put them in a format more suitable for Gource.

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
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
           
            try
            {
                //List<HistoryItem> items = new List<HistoryItem>();

                using (StreamReader sr = new StreamReader("C:\\Users\\Torrance\\Desktop\\vss.txt"))
                {
                   
                    // first line of the file is the project name
                    string projectName = sr.ReadLine();

                    // create an object that we will reuse to combine data
                    HistoryItem current = new HistoryItem(projectName);

                    string line = string.Empty;
                    while ((line = sr.ReadLine()) != null)
                    {
                        // just skip over blank lines
                        if (string.IsNullOrEmpty(line)) { continue; }

                        // if the line has a single space at the start, the line is a continuation of
                        // the previous record, append to the current working item
                        if (line.Substring(0, 1) == " ")
                        {
                            current.Append(line);
                            continue;
                        }

                        // we are at the next item, add what we were working on and start the next
                        if (!current.IsEmpty)
                        {
                            // write new output
                            string s = current.ToString();
                            if (!string.IsNullOrEmpty(s))
                            {
                                File.AppendAllText(@"C:\Users\Torrance\Desktop\vss.out", s + Environment.NewLine);
                            }
                            Console.WriteLine(s);

                            current.Reset();
                        }

                        current.Init(line);
                    }

                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }

        public class HistoryItem
        {
            public string project;

            public string user;
            public string time;
            public string item;
            public string parent;

            public HistoryItem(string project)
            {
                this.project = project;
            }

            public bool IsEmpty
            {
                get
                {
                    if (string.IsNullOrEmpty(this.item)) { return true; } else { return false; }
                }
            }
            public void Reset()
            {
                this.item = string.Empty;
                this.user = string.Empty;
                this.time = string.Empty;
                this.parent = string.Empty;
            }
            public void Init(string line)
            {
                this.item = line.Substring(0, 21).Trim();
                this.user = line.Substring(21, 11).Trim();
                this.time = line.Substring(32, 19).Trim();
                this.parent = line.Substring(51, 38).Trim();
            }
            public void Append(string line)
            {
                this.item += line.Substring(0, 21).Trim();
                this.user += line.Substring(21, 11).Trim();
                this.time += line.Substring(32, 19).Trim();
                this.parent += line.Substring(51, 38).Trim();
            }

            public override string ToString()
            {
                // get the user
                string username = this.user;

                #region parse out the date
                string dt = this.time;
                string d = dt.Substring(0, 8).Trim();
                //string t = dt.Substring(10, 6).Trim();
                string[] a = d.Split('/');
                string month = a[0];
                string day = a[1];
                string year = a[2];

                if (month.Length == 1) { month = "0" + month; }
                if (day.Length == 1) { day = "0" + day; }
                if ((year == "99") || (year == "98") || (year == "97"))
                {
                    year = "19" + year;
                }
                else
                {
                    year = "20" + year;
                }
                string datetime = year + "/" + month + "/" + day + " 00:00:00.000";
                #endregion

                #region name the item
                string f = this.item;
                string label = this.parent;
                string historyType = "M";
                string filename = string.Empty;

                if (label.StartsWith("Checked in") ||
                    label.StartsWith("Renamed") ||
                    label.StartsWith("Recovered") ||
                    label.StartsWith("Moved") ||
                    label.StartsWith("Branched") ||
                    label.StartsWith("Rollback")
                    )
                {
                    label = this.project;
                    historyType = "M";
                    filename = label + "/" + f;
                }
                else if (label.StartsWith("Added"))
                {
                    label = this.project;
                    historyType = "A";
                    filename = label + "/" + f;
                }
                else if (label.StartsWith("Deleted") || label.StartsWith("Destroyed"))
                {
                    label = this.project;
                    historyType = "D";
                    filename = label + "/" + f;
                }
                else if (label.StartsWith("Shared"))
                {
                    label = label.Substring(7);
                    historyType = "S";
                    filename = label;

                    return string.Empty;

                    //
                    // looks like this
                    //$/Aims66/AimsClient68/AdmTicketerPrivateComments.frx
                    // doesnt match up with the path of all the other types of entries
                }
                else if (label.StartsWith("Purged") || label.StartsWith("Pinned") || label.StartsWith("Unpinned"))
                {
                    return string.Empty;
                }
                else
                {
                    return string.Empty;
                }
                #endregion


                string s = datetime + "\t" + username + "\t" + historyType + "\t" + filename;
                return s;
            }
        }
    }
}
//