public void Build(List<FileRevision> versions, Action<float> progress = null) { var sw = Stopwatch.StartNew(); _tempDir = Path.Combine(Environment.CurrentDirectory, "vss-temp"); Directory.CreateDirectory(_tempDir); _db = _options.DB.Value; var originalVersions = versions.ToList(); using(_cache = new VssFileCache(_options.CacheDir, _db.SrcSafeIni)) { // filterout cached versions if (!_options.Force) { Console.WriteLine("Skip already cached versions..."); var cached = 0; var notRetained = 0; var errors = 0; versions.Clear(); foreach (var file in originalVersions) { if (_cache.GetFilePath(file.FileSpec, file.VssVersion) != null) { cached++; continue; } if (!string.IsNullOrWhiteSpace(_cache.GetFileError(file.FileSpec, file.VssVersion))) { var err = _cache.GetFileError(file.FileSpec, file.VssVersion); if (err == "not-retained") notRetained++; else errors++; continue; } versions.Add(file); } Console.WriteLine("Cached(good): {0}", cached); Console.WriteLine("Cached(errors): {0}", errors); Console.WriteLine("Cached(not retained version): {0}", notRetained); Console.WriteLine("Not Cached: {0}", versions.Count); } Console.WriteLine(); // sort versions versions = versions .GroupBy(f => f.FileSpec) // order by versions count. posible you do not want to convert all versions for some autogenerated files .OrderBy(g => g.Count()) // start retrieveing from recent (high versions) to ancient (version 1) .SelectMany(g => g.OrderByDescending(v => v.VssVersion)) .ToList() ; using(_log = File.CreateText(LogFileName)) { _log.AutoFlush = true; // cache var fileGroups = versions.GroupBy(v => v.FileSpec).ToList(); for (var j = 0; j < fileGroups.Count; j++) { var fileGroup = fileGroups[j]; Console.Write("[{0}/{1}] Get: {3,5} x {2}", j, fileGroups.Count, fileGroup.Key, fileGroup.Count()); if (progress != null) progress((float)j / fileGroups.Count); foreach (var fg in fileGroup) { Process(fg); } Console.WriteLine(); } } // build cached versions list BuildCachedVersionsList(originalVersions); } sw.Stop(); Console.WriteLine(); Console.WriteLine("Building cache complete. Take {0}", sw.Elapsed); }
public void BuildStats(List<FileRevision> list) { // dump info about versions count per file using (var versionsCountLog = File.CreateText(VersionsCountFileName)) { var listG = list .GroupBy(f => f.FileSpec) .Select(g => new { Count = g.Count(), Spec = g.Key }) .OrderByDescending(x => x.Count) .ToList() ; listG.ForEach(g => versionsCountLog.WriteLine("{0,6} {1}", g.Count, g.Spec)); } // reduce pinned files to single revision list = list .GroupBy(f => f.FileSpec) .Select(g => { if (IsShouldBePinned(g.Key)) return g.Take(1).ToArray(); return g.ToArray(); }) .SelectMany(x => x) .ToList() ; using (var cache = new VssFileCache(_options.CacheDir, _options.SourceSafeIni)) using (var errLog = File.CreateText(ErrorsFileName)) using (var onlyLastVersionsLog = File.CreateText(OnlyLastVersionFileName)) { errLog.AutoFlush = true; onlyLastVersionsLog.AutoFlush = true; // undone list using (var log = File.CreateText(UndoneVersionsCountFileName)) { var listG = list .Where(v => cache.GetFileInfo(v.FileSpec, v.VssVersion) == null) .GroupBy(f => f.FileSpec) .Select(g => new { Count = g.Count(), Spec = g.Key }) .OrderByDescending(x => x.Count) .ToList() ; listG.ForEach(g => log.WriteLine("{0,6} {1}", g.Count, g.Spec)); } var cached = 0; var errors = 0; var onlyLastVersions = 0; var notCached = 0; var onlyLastVersionSpecs = new HashSet<string>(); foreach (var file in list) { if (cache.GetFilePath(file.FileSpec, file.VssVersion) != null) { cached++; } else { var err = cache.GetFileError(file.FileSpec, file.VssVersion); if (!string.IsNullOrWhiteSpace(err)) { if (err == "not-retained") { if (!onlyLastVersionSpecs.Contains(file.FileSpec)) { onlyLastVersions++; onlyLastVersionsLog.WriteLine("{0}", file.FileSpec); onlyLastVersionSpecs.Add(file.FileSpec); } } else { errors++; errLog.WriteLine("{0}@{1}\n\t{2}", file.FileSpec, file.VssVersion, err); } cached++; } else { notCached++; } } } Console.WriteLine("Cached: {0} (Errors: {1}) Not Cached: {2}", cached, errors, notCached); Console.WriteLine("Only Last Version: {0}", onlyLastVersions); Console.WriteLine("Not Cached: {0:0.00}%", 100.0 * notCached / list.Count); Console.WriteLine(); } }
public void Build(Options opts, IList<Tuple<string, int>> files, Action<float> progress = null) { var stopWatch = new Stopwatch(); stopWatch.Start(); using (var cache = new VssFileCache(opts.CacheDir + "-revs", opts.SourceSafeIni)) using(var wr = File.CreateText(DataFileName)) using(var log = File.CreateText(LogFileName)) { wr.AutoFlush = log.AutoFlush = true; var db = opts.DB.Value; var findex = 0; foreach (var spec in files.Select(t => t.Item1)) { findex++; try{ IVSSItem item = db.VSSItem[spec]; var head = item.VersionNumber; var timestamp = item.VSSVersion.Date.Ticks; var cachedData = cache.GetFilePath(spec, head, timestamp); if (cachedData != null) { Console.Write("c"); Save(wr, Load(cachedData)); // next file continue; } Console.Write("[{0,5}/{1,5}] {2} ", findex, files.Count, item.Spec); if (progress != null) progress((float)findex / files.Count); var rotationIndex = 0; var rotationArray = @"|/-\|/-\".ToCharArray(); var latestOnly = IsLatestOnly(opts, spec); var itemRevisions = new List<FileRevision>(); foreach (IVSSVersion ver in item.Versions) { Console.Write("{0}\b", rotationArray[rotationIndex++ % rotationArray.Length]); if (ver.Action.StartsWith("Labeled ") || ver.Action.StartsWith("Branched ")) continue; if (!ver.Action.StartsWith("Checked in ") && !ver.Action.StartsWith("Created ") && !ver.Action.StartsWith("Archived ") && !ver.Action.StartsWith("Rollback to")) { log.WriteLine("Unknown action: " + ver.Action); } var user = ver.Username.ToLowerInvariant(); var fileVersionInfo = new FileRevision { FileSpec = item.Spec, At = ver.Date.ToUniversalTime(), Comment = ver.Comment, VssVersion = ver.VersionNumber, User = user }; try { // can throw exception, but it is not critical fileVersionInfo.Physical = ver.VSSItem.Physical; } catch (Exception ex) { Console.WriteLine("ERROR: Get Physical: " + ex.Message); log.WriteLine("ERROR: Get Physical: {0}", spec); log.WriteLine(ex.ToString()); fileVersionInfo.Physical = "_UNKNOWN_"; } itemRevisions.Add(fileVersionInfo); if (latestOnly) break; Console.Write('.'); } Console.WriteLine(" "); if (itemRevisions.Count > 0) { // some time date of items wrong, but versions - correct. // sort items in correct order and fix dates itemRevisions = itemRevisions.OrderBy(i => i.VssVersion).ToList(); // fix time. make time of each next item greater than all previous var notEarlierThan = itemRevisions[0].At; for (int i = 1; i < itemRevisions.Count; i++) { if (itemRevisions[i].At < notEarlierThan) { itemRevisions[i].At = notEarlierThan + TimeSpan.FromMilliseconds(1); itemRevisions[i].Comment += "\n! Time was fixed during VSS -> SVN conversion. Time can be incorrect !\n"; itemRevisions[i].Comment = itemRevisions[i].Comment.Trim(); } notEarlierThan = itemRevisions[i].At; } } Save(wr, itemRevisions); var tempFile = Path.GetTempFileName(); try { using (var sw = new StreamWriter(tempFile, false, Encoding.UTF8)) Save(sw, itemRevisions); cache.AddFile(spec, head, timestamp, tempFile, false); } finally { if (File.Exists(tempFile)) File.Delete(tempFile); } } catch(Exception ex) { Console.WriteLine("ERROR: {0}", spec); log.WriteLine("ERROR: {0}", spec); log.WriteLine(ex.ToString()); } } } stopWatch.Stop(); Console.WriteLine("Build files versions list complete. Take: {0}", stopWatch.Elapsed); }