public static UserControl GetSubscriptionSettingsUiForPlugin(string pluginName) { var pluginDirectory = PluginsDirectory.GetDirectories().Where(d => d.Name == pluginName).FirstOrDefault(); if (pluginDirectory != null) { foreach (FileInfo fileInfo in pluginDirectory.GetFiles("*.dll")) { try { Assembly assembly = Assembly.LoadFile(fileInfo.FullName); var type = assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ISubscriptionSettings))).FirstOrDefault(); if (type != null) { return(Activator.CreateInstance(type) as UserControl); } } catch (Exception ex) { SourceLogLogger.LogError("Exception in GetSubscriptionSettingsUiForPlugin: " + Environment.NewLine + " " + ex + Environment.NewLine + "\tpluginDirectory: " + pluginDirectory + Environment.NewLine + "\tfileInfo.FullName: " + fileInfo.FullName + Environment.NewLine); } } } return(null); }
public virtual void Initialise() { SourceLogLogger.LogInformation("Plugin initialising", "Plugin." + GetType().Name); Timer = new Timer(CheckForNewLogEntries); Timer.Change(0, 15000); }
private static Dictionary <string, Type> LoadPluginTypeList() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve; var pluginTypeList = new Dictionary <string, Type>(); foreach (var pluginDirectory in PluginsDirectory.GetDirectories()) { foreach (FileInfo fileInfo in pluginDirectory.GetFiles("*.dll")) { try { Assembly assembly = Assembly.LoadFile(fileInfo.FullName); foreach (Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IPlugin)))) { pluginTypeList.Add(assembly.GetName().Name, type); } } //catch (BadImageFormatException) //{ } //catch (FileLoadException) //{ } catch (Exception ex) { SourceLogLogger.LogError("Exception in " + typeof(PluginManager).Name + ": " + Environment.NewLine + " " + ex + Environment.NewLine + "\tpluginDirectory: " + pluginDirectory + Environment.NewLine + "\tfileInfo.FullName: " + fileInfo.FullName + Environment.NewLine); } } } return(pluginTypeList); }
private void CheckForNewLogEntries(object state) { if (Monitor.TryEnter(LockObject)) { try { SourceLogLogger.LogInformation("Checking for new entries", "Plugin." + GetType().Name); CheckForNewLogEntriesImpl(); } catch (Exception ex) { var args = new PluginExceptionEventArgs { Exception = ex }; if (PluginException != null) { PluginException(this, args); } } finally { Monitor.Exit(LockObject); } } }
internal static LogEntryDto Parse(string changesetString) { SourceLogLogger.LogInformation("Parsing changeset: " + changesetString, "Plugin.Perforce"); var logEntry = new LogEntryDto(); const string pattern = @"Change\s(?<revision>\d+)\son\s(?<datetime>\d{4}/\d{2}/\d{2}\s\d{2}:\d{2}:\d{2})\sby\s(?<author>[^@]+)@\w+\n\n(?<message>.*?(?=\n([^\s]|$)))"; var r = new Regex(pattern, RegexOptions.Singleline); var match = r.Match(changesetString); if (match.Success) { int revision; if (Int32.TryParse(match.Groups["revision"].Value, out revision)) { logEntry.Revision = revision.ToString(CultureInfo.InvariantCulture); } DateTime datetime; if (DateTime.TryParse(match.Groups["datetime"].Value, out datetime)) { logEntry.CommittedDate = datetime; } logEntry.Author = match.Groups["author"].Value; var message = match.Groups["message"].Value; logEntry.Message = message.Trim().Replace("\n\t", "\n"); } else { SourceLogLogger.LogError("Parsing changeset: " + changesetString, "Plugin.Perforce"); } return(logEntry); }
static byte[] GitHubApiGetBinary(string uri) { SourceLogLogger.LogInformation($"GitHubApiGet: {uri}", "Plugin.GitHub"); var request = WebRequest.Create(uri); ((HttpWebRequest)request).UserAgent = "SourceLog"; try { using (var response = request.GetResponse()) { using (var memoryStream = new MemoryStream()) { var responseStream = response.GetResponseStream(); if (responseStream != null) { responseStream.CopyTo(memoryStream); } return(memoryStream.ToArray()); } } } catch (WebException ex) { if (ex.Response.Headers["X-RateLimit-Remaining"] == "0") { SourceLogLogger.LogInformation($"GitHub API rate limit met - sleeping for 1 hr", "Plugin.GitHub"); Thread.Sleep(TimeSpan.FromHours(1)); return(GitHubApiGetBinary(uri)); } // Getting a 404 from the raw_url on a changed subproject. // E.g. filename "libgit2" on this commit: // https://github.com/libgit2/libgit2sharp/commit/39c2ed2233b3d99e33c031183e26996d1210c329 // https://api.github.com/repos/libgit2/libgit2sharp/commits/39c2ed2233b3d99e33c031183e26996d1210c329 if (ex.Response.Headers["status"] == "404 Not Found") { return(System.Text.Encoding.UTF8.GetBytes( ex.Response.Headers["status"] + Environment.NewLine + "URI: " + uri + Environment.NewLine + Environment.NewLine + "Subproject link?" )); } // ReSharper disable AssignNullToNotNullAttribute var response = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd(); // ReSharper restore AssignNullToNotNullAttribute if (response == "Error: blob is too big") { return(System.Text.Encoding.UTF8.GetBytes(response + Environment.NewLine + "URI: " + uri)); } throw new Exception(response, ex); } }
public void GenerateFlowDocuments() { ChangedFiles.AsParallel().ForAll(changedFile => { SourceLogLogger.LogInformation("GeneratingFlowDocuments - File: " + changedFile.FileName); var diff = new SideBySideFlowDocumentDiffGenerator(changedFile.OldVersion, changedFile.NewVersion); changedFile.LeftFlowDocument = diff.LeftDocument; changedFile.RightFlowDocument = diff.RightDocument; changedFile.FirstModifiedLineVerticalOffset = diff.FirstModifiedLineVerticalOffset; }); }
protected override void CheckForNewLogEntriesImpl() { if (!Monitor.TryEnter(LockObject)) { return; } try { using (var svnClient = new SvnClient()) { var uri = new Uri(SettingsXml); Collection <SvnLogEventArgs> svnLogEntries; if (svnClient.GetLog(uri, new SvnLogArgs { Limit = 30 }, out svnLogEntries)) { var q = svnLogEntries .Where(e => e.Time.PrecisionFix() > MaxDateTimeRetrieved) .OrderBy(e => e.Time); foreach (var svnLogEntry in q) { var revision = svnLogEntry.Revision; SourceLogLogger.LogInformation($"Creating LogEntryDto for revision {revision}", $"Plugin.{GetType().Name}"); var logEntry = new LogEntryDto { Author = svnLogEntry.Author, CommittedDate = svnLogEntry.Time, Message = svnLogEntry.LogMessage, Revision = revision.ToString(CultureInfo.InvariantCulture), ChangedFiles = new List <ChangedFileDto>() }; ProcessChangedPaths(svnLogEntry, revision, logEntry); var args = new NewLogEntryEventArgs { LogEntry = logEntry }; OnNewLogEntry(args); } MaxDateTimeRetrieved = svnLogEntries.Max(x => x.Time).PrecisionFix(); } } } finally { Monitor.Exit(LockObject); } }
internal static ChangedFileDto ParseP4File(string file) { SourceLogLogger.LogInformation("Parsing file: " + file, "Plugin.Perforce"); var changedFile = new ChangedFileDto(); const string pattern = @"(?<filename>[^#]*)#(?<revision>\d+)\s-\s(?<action>\w+)\schange\s(?<changeNumber>\d+)\s\((?<filetype>\w+(\+\w+)?)\)"; var r = new Regex(pattern); var match = r.Match(file); if (match.Success) { changedFile.FileName = match.Groups["filename"].Value; switch (match.Groups["action"].Value) { case "add": changedFile.ChangeType = ChangeType.Added; break; case "edit": changedFile.ChangeType = ChangeType.Modified; break; case "delete": changedFile.ChangeType = ChangeType.Deleted; break; case "branch": changedFile.ChangeType = ChangeType.Copied; break; case "integrate": changedFile.ChangeType = ChangeType.Modified; break; } } else { SourceLogLogger.LogError("Parsing file failed: " + file, "Plugin.Perforce"); } return(changedFile); }
private static FlowDocument GetFlowDocument(byte[] flowDocumentData) { FlowDocument flowDocument; try { using (var compressedStream = new MemoryStream(flowDocumentData)) using (var uncompressedStream = new MemoryStream()) { using (var gZipDecompressor = new GZipStream(compressedStream, CompressionMode.Decompress)) { gZipDecompressor.CopyTo(uncompressedStream); } uncompressedStream.Position = 0; flowDocument = (FlowDocument)XamlReader.Load(uncompressedStream); } } catch (Exception exception) { SourceLogLogger.LogError("Error deserialising FlowDocument: " + exception); flowDocument = new FlowDocument(); } return(flowDocument); }
public void AddNewLogEntry(object sender, NewLogEntryEventArgs e) { var logEntry = new LogEntry(e.LogEntry); if (Log.Count(l => l.Revision == logEntry.Revision) > 0) { SourceLogLogger.LogError($"Subscription \"{Name}\" already contains revision {logEntry.Revision}, date (ticks) {logEntry.CommittedDate.Ticks}"); } logEntry.GenerateFlowDocuments(); using (var db = SourceLogContextProvider()) { logEntry.LogSubscription = db.LogSubscriptions.Find(LogSubscriptionId); db.LogEntries.Add(logEntry); db.SaveChanges(); } logEntry.UnloadChangedFiles(); if (_uiThread != null) { _uiThread.Post(entry => { Log.Add((LogEntry)entry); NotifyPropertyChanged("Log"); var logEntryInfo = new NewLogEntryInfoEventHandlerArgs { LogSubscriptionName = Name, Author = ((LogEntry)entry).Author, Message = ((LogEntry)entry).Message }; NewLogEntry(this, logEntryInfo); }, logEntry); } }
static void LogProviderLogProviderException(object sender, PluginExceptionEventArgs args) { SourceLogLogger.LogError(args.Exception.ToString()); }
protected override void CheckForNewLogEntriesImpl() { string collectionUrl; string sourceLocation; GetTfsSettings(out collectionUrl, out sourceLocation); var tfsUri = new Uri(collectionUrl); var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri); var vcs = projectCollection.GetService <VersionControlServer>(); var history = vcs.QueryHistory( path: sourceLocation, version: VersionSpec.Latest, deletionId: 0, recursion: RecursionType.Full, user: null, versionFrom: null, versionTo: null, maxCount: 30, includeChanges: true, slotMode: false ) .Cast <Changeset>() .ToList(); foreach (var changeset in history.Where(c => c.CreationDate > MaxDateTimeRetrieved).OrderBy(c => c.CreationDate)) { var changesetId = changeset.ChangesetId; SourceLogLogger.LogInformation("Creating LogEntry for Changeset " + changesetId, "Plugin.TFS2010"); var logEntry = new LogEntryDto { Author = changeset.Committer, CommittedDate = changeset.CreationDate, Message = changeset.Comment, Revision = changesetId.ToString(CultureInfo.InvariantCulture), ChangedFiles = new List <ChangedFileDto>() }; foreach (var change in changeset.Changes) { var changedFile = new ChangedFileDto { FileName = change.Item.ServerItem }; switch (change.Item.ItemType) { case ItemType.Folder: // XamlReader.Load seems to require UTF8 var folderStringBytes = System.Text.Encoding.UTF8.GetBytes("[Folder]"); if (change.ChangeType.HasFlag(TFS.ChangeType.Add)) { changedFile.OldVersion = new byte[0]; } else { changedFile.OldVersion = folderStringBytes; } if (change.ChangeType.HasFlag(TFS.ChangeType.Delete)) { changedFile.NewVersion = new byte[0]; } else { changedFile.NewVersion = folderStringBytes; } break; case ItemType.File: if (change.ChangeType.HasFlag(TFS.ChangeType.Delete)) { changedFile.NewVersion = new byte[0]; } else { using (var memoryStream = new MemoryStream()) { change.Item.DownloadFile().CopyTo(memoryStream); changedFile.NewVersion = memoryStream.ToArray(); } } var previousVersion = vcs.GetItem(change.Item.ItemId, changesetId - 1, true); if (previousVersion != null) { using (var previousVersionMemoryStream = new MemoryStream()) { previousVersion.DownloadFile().CopyTo(previousVersionMemoryStream); changedFile.OldVersion = previousVersionMemoryStream.ToArray(); } } else { changedFile.OldVersion = new byte[0]; } break; default: continue; } SetChangeType(changedFile, change); logEntry.ChangedFiles.Add(changedFile); } var args = new NewLogEntryEventArgs { LogEntry = logEntry }; OnNewLogEntry(args); } MaxDateTimeRetrieved = history.Max(c => c.CreationDate); }
private void ProcessChangedPaths(SvnLoggingEventArgs svnLogEntry, long revision, LogEntryDto logEntry) { svnLogEntry.ChangedPaths.AsParallel().WithDegreeOfParallelism(1).ForAll(changedPath => { SourceLogLogger.LogInformation($"Processing path {changedPath.Path}", $"Plugin.Subversion"); using (var parallelSvnClient = new SvnClient()) { var changedFile = new ChangedFileDto { FileName = changedPath.Path }; var nodeKind = changedPath.NodeKind; if (nodeKind == SvnNodeKind.Unknown) { // Use GetInfo to get the NodeKind SvnInfoEventArgs svnInfo; try { parallelSvnClient.GetInfo( new SvnUriTarget( SettingsXml + changedPath.Path, // If the file is deleted then using revision causes an exception (changedPath.Action == SvnChangeAction.Delete ? revision - 1 : revision) ), out svnInfo); nodeKind = svnInfo.NodeKind; } catch (SvnRepositoryIOException svnRepositoryIoException) { SourceLogLogger.LogWarning(svnRepositoryIoException.ToString(), "Plugin.Subversion"); } } if (nodeKind != SvnNodeKind.File) { changedFile.OldVersion = new byte[0]; changedFile.NewVersion = new byte[0]; } else { if (changedPath.Action == SvnChangeAction.Modify || changedPath.Action == SvnChangeAction.Delete) { // Use GetInfo to get the last change revision var previousRevisionUri = new SvnUriTarget(SettingsXml + changedPath.Path, revision - 1); try { // For some reason we seem to get an exception with a message stating that // a previous version doesn't exist for a Modify action. I'm not sure how // you can have a modify without a previous version (surely everything // starts with an add..? SvnInfoEventArgs previousRevisionInfo; parallelSvnClient.GetInfo(previousRevisionUri, out previousRevisionInfo); changedFile.OldVersion = ReadFileVersion( parallelSvnClient, SettingsXml + changedPath.Path, previousRevisionInfo.LastChangeRevision); } catch (SvnRepositoryIOException e) { SourceLogLogger.LogError("SvnRepositoryIOException: " + e, "Plugin.Subversion"); changedFile.OldVersion = new byte[0]; } catch (SvnFileSystemException ex) { // http://stackoverflow.com/questions/12939642/sharpsvn-getinfo-lastchangerevision-is-wrong SourceLogLogger.LogWarning("SvnFileSystemException: " + ex, "Plugin.Subversion"); changedFile.OldVersion = new byte[0]; } } else { changedFile.OldVersion = new byte[0]; } if (changedPath.Action == SvnChangeAction.Modify || changedPath.Action == SvnChangeAction.Add) { changedFile.NewVersion = ReadFileVersion(parallelSvnClient, SettingsXml + changedPath.Path, revision); } else { changedFile.NewVersion = new byte[0]; } } switch (changedPath.Action) { case SvnChangeAction.Add: changedFile.ChangeType = ChangeType.Added; break; case SvnChangeAction.Delete: changedFile.ChangeType = ChangeType.Deleted; break; default: changedFile.ChangeType = ChangeType.Modified; break; } logEntry.ChangedFiles.Add(changedFile); } }); }