private void GetAttachment(Uri uri, string attachmentName, string rootDownloadPath, int workItemId) { Log("Downloading attachment '{0}' of work item {1}", attachmentName, workItemId); var downloadPath = DirUtility.EnsureDir(rootDownloadPath, "TFS-" + workItemId.ToString()); using (var webClient = new WebClient()) { webClient.UseDefaultCredentials = true; webClient.DownloadFileCompleted += (s, e) => { Action <string, object> logAction = (msg, f) => Log(msg, f); if (e.Error == null) { logAction.BeginInvoke("File {0} downloaded.", e.UserState.ToString(), CallBack, logAction); } else { logAction.BeginInvoke("Error: {0}", e.Error.ToString(), CallBack, logAction); } }; webClient.DownloadProgressChanged += (s, e) => Log("{0} Progress Percentage: {1}", e.UserState, e.ProgressPercentage); var fileName = Path.Combine(downloadPath, attachmentName); OutstandingOperations++; webClient.DownloadFileAsync(uri, fileName, fileName); } }
private void WriteActiveTasksFile() { var activeTasks = this.TaskChanges.GroupBy(x => x.Task.Id).Select(x => x.First()).Where( x => x.Task.State != "Closed").OrderBy(x => x.Task.Title).ToList(); if (!activeTasks.Any()) { return; } var sb = new StringBuilder(); sb.AppendFormat("{0} Task(s) Not Closed{1}{1}", activeTasks.Count, Environment.NewLine); activeTasks.ForEach(x => { var t = x.Task; sb.AppendFormat("{0}{1}", t.Title, Environment.NewLine); sb.AppendFormat("TFS #{0} [{1}] by {2}{3}{3}", t.Id, t.State, x.Task.GetAssignedTo(), Environment.NewLine); }); var filename = Path.Combine(DirUtility.EnsureDir(this.RootDownloadPath, "Tasks"), "Task List (Not Closed).txt"); File.WriteAllText(filename, sb.ToString()); }
public void DownloadChanges(MassDownloadConfig configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } if (null == configuration.KnownFileTypes) { throw new NullReferenceException("Config KnownFileTypes must be set"); } if (string.IsNullOrWhiteSpace(configuration.TfsServer)) { throw new NullReferenceException("TfsServer must be set in configuration"); } this.Stage = "Initializing"; this.StartTime = DateTime.Now; this.Config = configuration; this.Config.DownloadPath = DirUtility.EnsureDir(@configuration.BaseDownloadDirectory, string.Format(@"{0}\{1}\WI {2}\{3}", DateTime.Now.ToString("yyyy"), DateTime.Now.ToString("MM"), this.Config.ProjectId, DateTime.Now.ToString("dd ddd HH-mm-ss"))); this.Config.AttachmentPath = DirUtility.EnsureDir(this.DownloadPath, "Attachments"); var changesetList = GetChangeSetListAndAttachments(); if (!PendingCancellation()) { this.Stage = "Analyzing, downloading, organizing changesets"; var index = 0; var csList = changesetList.OrderBy(cs => cs.CreationDate).ToList(); csList.ForEach(cs => ProcessChangeSet(cs, ++index, csList.Count())); } if (!PendingCancellation()) { this.Stage = "Post-processing"; DatabasePostProcess(); OutputTaskInfo(); } this.Stage = "Cleaning up"; ReportProgress("Tearing down"); MassDownloadCleanup(); this.EndTime = DateTime.Now; var ts = this.EndTime.Value - this.StartTime.Value; Log("Mass download complete in {0}", ts); SaveLog(); if (!PendingCancellation()) { Process.Start(this.DownloadPath); } this.CancelPending = false; }
private string GetWorkItemDir() { var dir = Path.Combine(this.BaseOutputDirectory, string.Format(@"{0}\{0}-{1}\WI {2}", DateTime.Now.Year, DateTime.Now.Month.ToString("00"), this.WorkItem.Id)); // we might pickup something leftover from a previous run that is no longer valid if (Directory.Exists(dir)) { DirUtility.DeleteDirectory(dir); } DirUtility.EnsureDir(dir); return(dir); }
private void HandleDatabaseTaskAttachments() { var attachDir = new DirectoryInfo(this.MassDownload.Config.AttachmentPath); var files = attachDir.GetFiles("*.sql", SearchOption.AllDirectories).ToList(); if (!files.Any() || string.IsNullOrEmpty(this.RootDatabaseFolder)) { return; } var attachSqlDir = DirUtility.EnsureDir(this.RootDatabaseFolder, "_Attachments"); files.ForEach(f => HandleDatabaseTaskAttachment(f, attachSqlDir)); }
private MassDownloadChangeInfo GetChangeInfo(Changeset changeset, Change change) { var ci = new MassDownloadChangeInfo { Change = change, Changeset = changeset, File = change.Item.ServerItem.Split('/').Last() }; ci.FileTypeInfo = this.Config.KnownFileTypes.GetTypeForFilenameExt(ci.File); ci.TaskChanges = _taskChanges.Where(x => x.TaskChangeSets.Contains(changeset)).ToList(); // i.e. DownloadPath\Database or DownloadPath\Reports ci.TargetDirectory = Path.Combine(this.DownloadPath, ci.FileTypeInfo.TypeName); var extText = ci.File.Substring(ci.File.LastIndexOf(".")); ci.Extension = ci.FileTypeInfo.GetFileExtension(extText); if (ci.IsDatabase) { // i.e. DownloadPath\Database if (string.IsNullOrEmpty(this.Config.RootDatabasePath)) { this.Config.RootDatabasePath = ci.TargetDirectory; } ci.DatabaseSchema = ci.File.Substring(0, ci.File.IndexOf(".") - 0); // i.e. DownloadPath\Database\Schema\VIEWS ci.TargetDirectory = Path.Combine(ci.TargetDirectory, ci.DatabaseSchema, ci.Extension.Category); } if (ci.HasIncompleteTask) { ci.TargetDirectory = Path.Combine(ci.TargetDirectory, "_Incomplete"); } if (ci.IsDeleted) { ci.TargetFilenameDeleted = Path.Combine(ci.TargetDirectory, ci.File); ci.TargetDirectory = Path.Combine(ci.TargetDirectory, Constants.DELETED_SUB_DIR_NAME); } DirUtility.EnsureDir(ci.TargetDirectory); ci.TargetFilename = Path.Combine(ci.TargetDirectory, ci.File); return(ci); }
private void SetBaseDirectory(string baseOutputDirectory) { var currentDirectory = Environment.CurrentDirectory; #if DEBUG if (Debugger.IsAttached) { currentDirectory = AppDomain.CurrentDomain.BaseDirectory; } #endif var baseDir = string.IsNullOrWhiteSpace(baseOutputDirectory) ? currentDirectory : baseOutputDirectory; DirUtility.EnsureDir(baseDir); this.BaseOutputDirectory = baseDir; }
private void DownloadWorkItemAttachments() { if (null == this.WorkItem) { throw new NullReferenceException("WorkItem must be set"); } if (this.WorkItem.AttachedFileCount <= 0) { return; } var attachDir = DirUtility.EnsureDir(this.WorkItemDirectory, "Attachments"); using (var webClient = new WebClient()) { webClient.UseDefaultCredentials = true; foreach (Attachment attach in this.WorkItem.Attachments) { webClient.DownloadFile(attach.Uri, Path.Combine(attachDir, attach.Name)); } } }
private void Package() { this.Save(); if (this.Changes.IncludedChanges.Any(x => string.IsNullOrWhiteSpace(x.Schema))) { IoC.Get <IMessageBoxService>().ShowOKDispatch("One or more database objects are missing required Schema values.", "Required Data Missing"); return; } var packageDir = Path.Combine(this.Changes.RootDatabaseFolder, "_Package"); var di = new DirectoryInfo(packageDir); if (di.Exists) { DirUtility.DeleteDirectory(di.FullName); } di.Create(); var schemaCounts = new Dictionary <string, int>(); // this should be a user configurable setting. this allows gaps between changes should others need to be inserted const int skipBetween = 5; var warnings = new List <string>(); this.Changes.IncludedChanges.OrderBy(x => x.Index).ToList().ForEach(x => { var sourceFilename = Path.Combine(Changes.RootDatabaseFolder, x.FilePath); var delim = !x.File.StartsWith("_") ? "_" : string.Empty; var schemaDir = string.Empty; if (!schemaCounts.ContainsKey(x.Schema)) { schemaCounts.Add(x.Schema, 0); schemaDir = Path.Combine(packageDir, schemaCounts.Count.ToString("00") + "_" + x.Schema); DirUtility.EnsureDir(schemaDir); } else { var keys = schemaCounts.Keys.ToList(); var index = keys.IndexOf(x.Schema) + 1; schemaDir = Path.Combine(packageDir, index.ToString("00") + "_" + x.Schema); } if (!File.Exists(sourceFilename)) { warnings.Add(string.Format("The following file does not exist. Perhaps it was deleted and should not have been included: {0}", sourceFilename)); } else { var schemaIndex = schemaCounts[x.Schema] * skipBetween; schemaCounts[x.Schema] += 1; var targetFilename = Path.Combine(schemaDir, string.Format("{0:000}{1}{2}", schemaIndex, delim, x.File)); File.Copy(sourceFilename, targetFilename); } }); Process.Start(packageDir); if (warnings.Any()) { var warningsFile = Path.Combine(packageDir, "PackageWarnings.txt"); File.WriteAllText(warningsFile, string.Join(Environment.NewLine, warnings)); Process.Start(warningsFile); } }
private void DownloadChange(Change change, Changeset cs) { try { if (change.Item.ItemType == ItemType.File) { var file = change.Item.ServerItem.Split('/').Last(); var masterFilename = Path.Combine(this.ChangesDirectory, file); var fileType = this.KnownFileTypes.GetTypeForFilenameExt(masterFilename); var masterDir = Path.Combine(this.ChangesDirectory, fileType.TypeName); masterFilename = Path.Combine(masterDir, file); if (change.ChangeType != ChangeType.Delete) { change.Item.DownloadFile(masterFilename); this.DeployInfo.AddChange(change, cs, masterFilename, fileType); if (fileType.FileType == KnownFileType.Database) { if (!this.DbFileOrderGuess.ContainsKey(masterFilename)) { this.DbFileOrderGuess.Add(masterFilename, this.DbFileOrderGuess.Count + 1); } } } else { if (File.Exists(masterFilename)) { var newMasterFilename = masterFilename + ".deleted"; File.Move(masterFilename, newMasterFilename); this.DeployInfo.AddChange(change, cs, newMasterFilename, fileType); } } } } catch (Exception exception) { const string errorDirName = "wacko"; var errorDirLocation = string.Format( @"{0}\{1}", this.WorkItemDirectory, errorDirName); DirUtility.EnsureDir(errorDirLocation); var fs = File.Create( string.Format( @"{0}\error_{1}_{2}.txt", errorDirLocation, cs.ChangesetId, DateTime.Now.ToString("yyyyMMddHHmmssfff"))); var text = Encoding.UTF8.GetBytes( string.Format( "Message: {0}\r\nStack Trace: {1}", exception.Message, exception.StackTrace) ); fs.Write(text, 0, text.Length); fs.Close(); } }
private void OutputTaskInfo() { var sbSummary = new StringBuilder(); var sbCompleteSummary = new StringBuilder(); var lineDivider = new string('=', 90); var closedCount = 0; var activeCount = 0; var tasksWithArtifactsCount = 0; var closedWithArtifactsCount = 0; var artifactCountClosed = 0; var taskDir = DirUtility.EnsureDir(this.RootDownloadPath, "Tasks"); var deployDir = DirUtility.EnsureDir(taskDir, "Deploy"); this.TaskChanges.OrderBy(x => x.Task.Title).ToList().ForEach(tc => { var t = tc.Task; var assignedTo = t.GetAssignedTo(); sbSummary.AppendFormat("{0}{1}", t.Title, Environment.NewLine); sbSummary.AppendFormat("TFS #{0} [{1}] by {2}{3}", t.Id, t.State, assignedTo, Environment.NewLine); var closedTask = t.State == "Closed"; var taskDeployDir = string.Empty; if (closedTask) { closedCount++; if (tc.TaskFiles.Any()) { sbCompleteSummary.AppendFormat("{0}{1}", t.Title, Environment.NewLine); sbCompleteSummary.AppendFormat("TFS #{0} [{1}] by {2}{3}", t.Id, t.State, assignedTo, Environment.NewLine); taskDeployDir = DirUtility.EnsureDir(deployDir, WorkItemPath(t)); } } else { activeCount++; } foreach (var de in tc.TaskFiles.OrderBy(x => x.Value.File)) { var cfi = de.Value; var serverPath = cfi.ServerItem; var pos = cfi.ServerItem.LastIndexOf("/"); if (pos > -1) { serverPath = serverPath.Substring(0, pos); } var msg = string.Format("\t{0}{1}\t{2}{1}{1}", cfi.File, Environment.NewLine, serverPath); if (cfi.IsDelete) { msg = "\t[DELETED] => " + msg; } sbSummary.Append(msg); if (closedTask) { sbCompleteSummary.Append(msg); var fi = new FileInfo(cfi.Filename); // deleted files if (fi.Exists) { var newTaskFilename = Path.Combine(taskDeployDir, fi.Name); File.Copy(cfi.Filename, newTaskFilename); } artifactCountClosed++; } } if (!tc.TaskFiles.Any()) { sbSummary.AppendLine("\t No artifacts found (code changes only or otherwise excluded)"); } else { tasksWithArtifactsCount++; if (closedTask) { closedWithArtifactsCount++; } } sbSummary.AppendLine(lineDivider); sbSummary.AppendLine(); if (closedTask && tc.TaskFiles.Any()) { sbCompleteSummary.AppendLine(lineDivider); sbCompleteSummary.AppendLine(); } }); var sbTaskList = new StringBuilder(); var sbTaskListClosed = new StringBuilder(); this.TaskChanges.Select(x => x.Task).OrderBy(x => x.Title).ToList().ForEach(t => { var assignedTo = t.GetAssignedTo(); sbTaskList.AppendFormat("{0}{1}", t.Title, Environment.NewLine); sbTaskList.AppendFormat("TFS #{0} [{1}] by {2}{3}{3}", t.Id, t.State, assignedTo, Environment.NewLine); if (t.State == "Closed") { sbTaskListClosed.AppendFormat("{0}{1}", t.Title, Environment.NewLine); sbTaskListClosed.AppendFormat("TFS #{0} [{1}] by {2}{3}{3}", t.Id, t.State, assignedTo, Environment.NewLine); } }); var taskCountHeader = string.Format( "{0} Tasks. {1} Closed, {2} Incomplete", activeCount + closedCount, closedCount, activeCount); var summary = string.Format( "{0}. {1} Tasks with artifacts{2}{2}{3}", taskCountHeader, tasksWithArtifactsCount, Environment.NewLine, sbSummary); sbTaskList.Insert(0, taskCountHeader + Environment.NewLine + Environment.NewLine); sbTaskListClosed.Insert(0, string.Format("{0} Closed Tasks{1}{1}", closedCount, Environment.NewLine)); sbCompleteSummary.Insert(0, string.Format("{0} Closed Tasks with Artifacts{1}{2} Artifact Changes{1}{1}", closedWithArtifactsCount, Environment.NewLine, artifactCountClosed)); OutputTaskHyperlinks(taskDir); var taskSummaryFile = Path.Combine(taskDir, "Artifacts by Task (All).txt"); var closedWithArtifactsFile = Path.Combine(taskDir, "Artifacts by Task (Closed with Artifacts).txt"); var taskListFile = Path.Combine(taskDir, "Task List (All).txt"); var taskListClosedFile = Path.Combine(taskDir, "Task List (Closed).txt"); File.WriteAllText(taskSummaryFile, summary); File.WriteAllText(closedWithArtifactsFile, sbCompleteSummary.ToString()); File.WriteAllText(taskListFile, sbTaskList.ToString()); File.WriteAllText(taskListClosedFile, sbTaskListClosed.ToString()); WriteActiveTasksFile(); }