Exemplo n.º 1
0
		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);
		}
Exemplo n.º 2
0
		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);
		}