/// <summary> /// Implements standard name checking for <see cref="ActionConfiguration.Name"/>. /// The provided <paramref name="nameToCheck"/> must not be null or empty or contains only whitespaces nor '/' character. /// The '/' is reserved to structure the namespace. /// </summary> /// <param name="routeName">The name of the route that contains the action.</param> /// <param name="monitor">The monitor that will receive error descriptions.</param> /// <param name="nameToCheck">The name to check.</param> /// <returns>True if the name is valid. False otherwise.</returns> static public bool CheckActionNameValidity( string routeName, IActivityMonitor monitor, string nameToCheck ) { if( String.IsNullOrWhiteSpace( nameToCheck ) ) monitor.SendLine( LogLevel.Error, string.Format( "Invalid name '{0}' in route '{1}'. Name must not be empty or contains only white space.", nameToCheck, routeName ), null ); else if( nameToCheck.Contains( '/' ) ) monitor.SendLine( LogLevel.Error, string.Format( "Invalid name '{0}' in route '{1}'. Name must not contain '/'.", nameToCheck, routeName ), null ); else return true; return false; }
internal ActionCompositeConfigurationResolved( IActivityMonitor monitor, int index, IReadOnlyList<string> path, ActionCompositeConfiguration a, bool flattenUselessComposite ) : base( index, path, a ) { _isParallel = a.IsParallel; _children = new List<ActionConfigurationResolved>(); AppendChildren( monitor, a, path.Append( a.Name ).ToArray(), flattenUselessComposite ); }
static TestHelper() { _monitor = new ActivityMonitor(); _monitor.Output.BridgeTarget.HonorMonitorFilter = false; _console = new ActivityMonitorConsoleClient(); _monitor.Output.RegisterClients( _console ); }
/// <summary> /// Checks the validity: name and <see cref="DeclaredName"/> must be valid. /// </summary> /// <param name="routeName">Name of the route that contains this configuration.</param> /// <param name="monitor">Monitor to use to explain errors.</param> /// <returns>True if valid, false otherwise.</returns> protected internal override bool CheckValidity( string routeName, IActivityMonitor monitor ) { // If we support insertion in a composite we will allow name with / inside/ // If we allow / in DeclaredName, it means that an action inside a Composite can be inserted // somewhere else... This is possible technically, but does it make sense? return CheckActionNameValidity( routeName, monitor, _name ) && CheckActionNameValidity( routeName, monitor, _declaredName ); }
/// <summary> /// Initialization of the handler: computes the path. /// </summary> /// <param name="m"></param> public override void Initialize( IActivityMonitor m ) { using( m.OpenGroup( LogLevel.Trace, string.Format( "Initializing BinaryFile handler '{0}' (MaxCountPerFile = {1}).", Name, _file.MaxCountPerFile ), null ) ) { _file.Initialize( m ); } }
internal bool Override( IActivityMonitor monitor, IReadOnlyList<string> fullPath, ActionConfiguration a ) { var e = fullPath.GetEnumerator(); if( !e.MoveNext() ) throw new ArgumentException( "Must not be empty.", "fullPath" ); if( e.Current != _action.Name ) throw new ArgumentException( "Must start with the action name.", "fullPath" ); if( !e.MoveNext() ) { _action = a; _isCloned = false; monitor.SendLine( LogLevel.Info, string.Format( "Action '{0}' has been overridden.", a.Name ), null ); return true; } ActionCompositeConfiguration parent; int idx = FindInComposite( e, out parent ); if( idx >= 0 ) { Debug.Assert( _action is ActionCompositeConfiguration, "It is a composite." ); Debug.Assert( _action.IsCloneable, "A composite is cloneable." ); if( !_isCloned ) { _action = ((ActionCompositeConfiguration)_action).CloneComposite( true ); monitor.SendLine( LogLevel.Info, string.Format( "Action '{0}' has been cloned in order to override an inner action.", string.Join( "/", fullPath ) ), null ); _isCloned = true; idx = FindInComposite( e, out parent ); } Debug.Assert( parent.Children[idx].Name == fullPath.Last() ); parent.Override( idx, a ); monitor.SendLine( LogLevel.Info, string.Format( "Inner action '{0}' has been overridden.", string.Join( "/", fullPath ) ), null ); return true; } monitor.SendLine( LogLevel.Error, string.Format( "Action '{0}' not found. Unable to override it.", string.Join( "/", fullPath ) ), null ); return false; }
void DemoOpenGroupBetter( IActivityMonitor m ) { using( m.OpenInfo().Send( "Doing things..." ) ) { // ... } }
static TestHelper() { _monitor = new ActivityMonitor(); // Do not pollute the console by default... // ... but this may be useful sometimes: LogsToConsole does the job. _console = new ActivityMonitorConsoleClient(); }
/// <summary> /// Internal factory for ActionConfigurationResolved avoids externally visible virtual protected method on ActionConfiguration. /// This prevents any other composite implementations than our. /// </summary> internal static ActionConfigurationResolved Create( IActivityMonitor monitor, ActionConfiguration a, bool flattenUselessComposite, int index = 0, IReadOnlyList<string> path = null ) { if( path == null ) path = Util.Array.Empty<string>(); Impl.ActionCompositeConfiguration c = a as Impl.ActionCompositeConfiguration; if( c != null ) return new Impl.ActionCompositeConfigurationResolved( monitor, index, path, c, flattenUselessComposite ); return new ActionConfigurationResolved( index, path, a ); }
/// <summary> /// Used only by filtering extension methods (level is filtered and not None) or by static FakeLineSender (level is None). /// </summary> internal ActivityMonitorLineSender( IActivityMonitor monitor, LogLevel level, string fileName, int lineNumber ) : base( level, fileName, lineNumber ) { Debug.Assert( FakeLineSender == null || ((level & LogLevel.IsFiltered) != 0 && MaskedLevel != LogLevel.None), "The level is already filtered and not None or we are initializing the static FakeLineSender." ); _monitor = monitor; }
void DemoOpenGroupThisWorksFine( IActivityMonitor m ) { using( m.OpenInfo().Send( "Doing things..." ) ) { // ... m.CloseGroup( "Success." ); } }
void DemoLogs( IActivityMonitor m, FileInfo f, Exception ex ) { m.Trace().Send( "Data from '{0}' processed.", f.Name ); m.Info().Send( ex, "An error occurred while processing '{0}'. Process will be retried later.", f.Name ); m.Warn().Send( "File '{0}' is too big ({1} Kb). It must be less than 50Kb.", f.Name, f.Length / 1024 ); m.Error().Send( ex, "File '{0}' can not be processed.", f.Name ); m.Fatal().Send( ex, "This will cancel the whole operation." ); }
internal PreRoute( IActivityMonitor monitor, IProtoRoute protoRoute ) { _monitor = monitor; _protoRoute = protoRoute; _actionsByName = new Dictionary<string,ActionConfigurationResolved>(); _actions = new List<ActionConfigurationResolved>(); foreach( var meta in _protoRoute.MetaConfigurations ) meta.Apply( this ); }
/// <summary> /// Private method used by OpenXXX (Trace, Info,..., Fatal) extension methods. /// </summary> static IActivityMonitorGroupSender FilteredGroup( IActivityMonitor @this, LogLevel level, string fileName, int lineNumber ) { Debug.Assert( (level & LogLevel.IsFiltered) == 0 ); if( @this.ShouldLogGroup( level, fileName, lineNumber ) ) { return new ActivityMonitorGroupSender( @this, level | LogLevel.IsFiltered, fileName, lineNumber ); } return new ActivityMonitorGroupSender( @this ); }
public override void Initialize(IActivityMonitor monitor) { base.Initialize(monitor); if (monitor == null) { return; } this.bridgeEventWriter = new BridgeEventTraceWriter(); this.messageBusEventWriter = new MessageBusEventTraceWriter(); this.publisherEventWriter = new PublisherEventTraceWriter(); this.subscriberEventWriter = new SubscriberEventTraceWriter(); this.workerEventWriter = new WorkerEventTraceWriter(); monitor.BridgeClosed += this.OnBridgeClosed; monitor.BridgeClosing += this.OnBridgeClosing; monitor.BridgeInitialized += this.OnBridgeInitialized; monitor.BridgeInitializing += this.OnBridgeInitializing; monitor.BridgeTransferred += this.OnBridgeTransferred; monitor.BridgeTransferring += this.OnBridgeTransferring; monitor.BridgeException += this.OnBridgeException; monitor.BridgeWarning += this.OnBridgeWarning; monitor.MessageBusWarning += this.OnMessageBusWarning; monitor.MessageBusException += this.OnMessageBusException; monitor.MessageBusClosed += this.OnMessageBusClosed; monitor.MessageBusClosing += this.OnMessageBusClosing; monitor.MessageBusRegisteredHandler += this.OnMessageBusHandlerRegistered; monitor.MessageBusRegisteringHandler += this.OnMessageBusHandlerRegistering; monitor.MessageBusSending += this.OnMessageBusMessageSending; monitor.MessageBusSent += this.OnMessageBusMessageSent; monitor.PublisherWarning += this.OnPublisherWarning; monitor.PublisherException += this.OnPublisherException; monitor.PublisherClosed += this.OnPublisherClosed; monitor.PublisherClosing += this.OnPublisherClosing; monitor.PublisherInitializing += this.OnPublisherInitializing; monitor.PublisherInitialized += this.OnPublisherInitialized; monitor.PublisherSending += this.OnPublisherSending; monitor.PublisherSent += this.OnPublisherSent; monitor.SubscriberWarning += this.OnSubscriberWarning; monitor.SubscriberException += this.OnSubscriberException; monitor.SubscriberClosed += this.OnSubscriberClosed; monitor.SubscriberClosing += this.OnSubscriberClosing; monitor.SubscriberInitialized += this.OnSubscriberInitialized; monitor.SubscriberInitializing += this.OnSubscriberInitializing; monitor.SubscriberReceived += this.OnSubscriberReceived; monitor.SubscriberReceiving += this.OnSubscriberReceiving; monitor.WorkerRunning += this.OnWorkerRunning; monitor.WorkerStarted += this.OnWorkerStarted; monitor.WorkerStarting += this.OnWorkerStarting; monitor.WorkerStopped += this.OnWorkerStopped; monitor.WorkerStopping += this.OnWorkerStopping; monitor.WorkerCompleted += this.OnWorkerCompleted; monitor.WorkerException += this.OnWorkerException; monitor.WorkerWarning += this.OnWorkerWarning; }
/// <summary> /// Initialize a new <see cref="ActivityMonitorBridge"/> bound to an existing <see cref="ActivityMonitorBridgeTarget"/> /// This Client should be registered in the <see cref="IActivityMonitor.Output"/> of a local monitor. /// </summary> /// <param name="bridge">The target bridge.</param> /// <param name="pullTargetTopicAndAutoTagsFromTarget"> /// When true, the <see cref="IActivityMonitor.Topic"/> and <see cref="IActivityMonitor.AutoTags"/> are automaticaly updated whenever they change on the target monitor. /// </param> /// <param name="pushTopicAndAutoTagsToTarget"> /// When true, any change to <see cref="IActivityMonitor.Topic"/> or <see cref="IActivityMonitor.AutoTags"/> are applied to the target monitor. /// </param> /// <param name="applyTargetFilterToUnfilteredLogs"> /// True to avoid sending logs with level below the target <see cref="IActivityMonitor.MinimalFilter"/> (when <see cref="ActivityMonitorBridgeTarget.HonorMonitorFilter"/> is true /// and it is an unfiltered line or group log). /// This is an optimization that can be used to send less data to the target monitor but breaks the UnfilteredLog/UnfilteredOpenGroup contract. /// </param> public ActivityMonitorBridge( ActivityMonitorBridgeTarget bridge, bool pullTargetTopicAndAutoTagsFromTarget, bool pushTopicAndAutoTagsToTarget, bool applyTargetFilterToUnfilteredLogs = false ) { if( bridge == null ) throw new ArgumentNullException( "bridge" ); _bridgeTarget = bridge; _pullTargetTopicAndAutoTagsFromTarget = pullTargetTopicAndAutoTagsFromTarget; _pushTopicAndAutoTagsToTarget = pushTopicAndAutoTagsToTarget; _applyTargetFilterToUnfilteredLogs = applyTargetFilterToUnfilteredLogs; _targetMonitor = _bridgeTarget.TargetMonitor; _openedGroups = new List<bool>(); }
private static void PrintAll(IActivityMonitor monitor, string key, DateTime time) { Console.WriteLine("Users for {0}", key); foreach (var user in monitor.GetAll(key, time)) { Console.WriteLine("* {0}-{1}", user.Id, user.Name); } Console.WriteLine(); }
public ActivityInfoProcessor() { this.monitor = new WindowsActivityMonitor(); this.watcher = new WindowsProcessWatcher(monitor, queue); myTimer = new Timer {Interval = 1000}; myTimer.Tick += watcher.Handle; consumeTimer = new Timer {Interval = 100}; consumeTimer.Tick += consume; }
void DemoOpenGroupWithDynamicConclusion( IActivityMonitor m ) { int nbProcessed = 0; using( m.OpenInfo().Send( "Doing things..." ) .ConcludeWith( () => String.Format( "{0} files.", nbProcessed ) ) ) { // ... nbProcessed += 21; m.CloseGroup( "Success." ); // The user Group conclusion is: "Success. - 21 files." (the two conclusions are concatenated). } }
void AppendChildren( IActivityMonitor monitor, ActionCompositeConfiguration a, IReadOnlyList<string> childPath, bool flattenUselessComposite ) { foreach( var child in a.Children ) { ActionCompositeConfiguration composite = child as ActionCompositeConfiguration; if( flattenUselessComposite && composite != null && composite.IsParallel == a.IsParallel ) { AppendChildren( monitor, composite, childPath = childPath.Append( composite.Name ).ToArray(), true ); } else _children.Add( ActionConfigurationResolved.Create( monitor, child, flattenUselessComposite, _children.Count, childPath ) ); } }
/// <summary> /// Loads this configuration from a <see cref="XElement"/>. /// </summary> /// <param name="path">Path to the configuration xml file.</param> /// <param name="monitor">Monitor that will be used.</param> /// <returns>True on success, false if the configuration can not be read.</returns> public bool LoadFromFile( string path, IActivityMonitor monitor ) { if( path == null ) throw new ArgumentNullException( "path" ); if( monitor == null ) throw new ArgumentNullException( "monitor" ); try { var doc = XDocument.Load( path, LoadOptions.SetBaseUri|LoadOptions.SetLineInfo ); return Load( doc.Root, monitor ); } catch( Exception ex ) { monitor.SendLine( LogLevel.Error, null, ex ); return false; } }
static void CleanupTimedFolders(IActivityMonitor m, IBasicTestHelper basic, string basePath, int maxCurrentLogFolderCount, int maxArchivedLogFolderCount) { Debug.Assert(basePath.EndsWith(FileUtil.DirectorySeparatorString)); // Note: The comparer is a reverse comparer. The most RECENT timed folder is the FIRST. GetTimedFolders(basePath, out SortedDictionary <DateTime, string> timedFolders, out string archivePath, false); if (timedFolders.Count > maxCurrentLogFolderCount) { int retryCount = 5; retry: try { if (archivePath == null) { m.Trace("Creating Archive folder."); Directory.CreateDirectory(archivePath = basePath + "Archive"); } foreach (var old in timedFolders.Values.Skip(maxCurrentLogFolderCount)) { var fName = Path.GetFileName(old); m.Trace($"Moving '{fName}' folder into Archive folder."); var target = Path.Combine(archivePath, fName); if (Directory.Exists(target)) { target += '-' + Guid.NewGuid().ToString(); } Directory.Move(old, target); } GetTimedFolders(archivePath, out timedFolders, out _, true); foreach (var tooOld in timedFolders.Values.Skip(maxArchivedLogFolderCount)) { basic.CleanupFolder(tooOld, false); } } catch (Exception ex) { if (--retryCount < 0) { m.Error($"Aborting Log's cleanup of timed folders in '{basePath}' after 5 retries.", ex); return; } m.Warn($"Log's cleanup of timed folders in '{basePath}' failed. Retrying.", ex); Thread.Sleep(retryCount * 100); goto retry; } } }
/// <summary> /// Overridden to ensure that the target folder exists and, if the target folder is "$StObjGen" that /// a .gitignore file exists in it. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <returns>Always true.</returns> protected override bool PrepareWrite(IActivityMonitor monitor) { var folder = Path.RemoveLastPart(); Directory.CreateDirectory(Path.RemoveLastPart()); // For '$StObjGen' folders, ensures that a .gitignore file exists. if (Path.LastPart == "$StObjGen") { var gitIgnore = folder.AppendPart(".gitignore"); if (!File.Exists(gitIgnore)) { // Ignores error. SafeWrite(monitor, gitIgnore, "*"); } } return(true); }
TypeAttributesCache(IActivityMonitor monitor, Type type, IAttributeContextBound[] typeAttributes, IServiceProvider services, bool includeBaseClasses) { if (type == null) { throw new ArgumentNullException(nameof(type)); } // This is ready to be injected in the delegated attribute constructor: no other attributes are visible. // If other attributes must be accessed, then the IAttributeContextBoundInitializer interface must be used. Type = type; _all = Array.Empty <Entry>(); var all = new List <Entry>(); int initializerCount = Register(monitor, services, all, type, includeBaseClasses, typeAttributes); BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (includeBaseClasses) { flags &= ~BindingFlags.DeclaredOnly; } _typeMembers = type.GetMembers(flags); foreach (var m in _typeMembers) { initializerCount += Register(monitor, services, all, m, false); } _all = all.ToArray(); _includeBaseClasses = includeBaseClasses; if (initializerCount > 0) { foreach (Entry e in _all) { if (e.Attr is IAttributeContextBoundInitializer aM) { aM.Initialize(monitor, this, e.M); if (--initializerCount == 0) { break; } } } } }
/// <summary> /// Tries to set the <see cref="CKTypeKind.IsPocoClass"/> flag for a type (that must be a class). /// This fails if the type is already registered as another kind of type. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="t">The type to configure.</param> /// <returns>True on success, false on error.</returns> internal bool SetPocoClass(IActivityMonitor m, Type t) { Debug.Assert(t.IsClass); var exist = RawGet(m, t); if (exist == CKTypeKind.None) { m.Trace($"Type '{t}' is now defined as a PocoClass."); _cache[t] = CKTypeKind.IsPocoClass; } else if (exist != CKTypeKind.IsPocoClass) { m.Error($"Type '{t}' is already registered as a '{ToStringFull( exist )}'. It can not be defined as a PocoClass."); return(false); } return(true); }
public bool PushLocalArtifacts(IActivityMonitor m, IArtifactRepository target, IEnumerable <ArtifactInstance> artifacts, bool arePublicArtifacts) { bool success = true; foreach (var h in _provider._handlers) { using (m.OpenTrace($"Pushing for type handler '{h}'.")) { if (!h.PushLocalArtifacts(this, m, target, artifacts, arePublicArtifacts)) { m.CloseGroup("Failed."); success = false; } } } return(success); }
// This is NOT how it works in CK.SqlServer.Setup.Engine: StObjConstruct is used. static void ConfigureByDirectSetProperties(IActivityMonitor monitor, IStObjMutableItem o, SqlDatabase db) { if (db.IsDefaultDatabase) { o.SetDirectPropertyValue(monitor, nameof(SqlDatabase.ConnectionString), "The default connection string.", sourceDescription: "By configurator."); } else if (db.Name == "histo") { o.SetDirectPropertyValue(monitor, nameof(SqlDatabase.ConnectionString), "The histo connection string.", sourceDescription: "By configurator."); o.SetDirectPropertyValue(monitor, nameof(SqlDatabase.HasCKCore), true, sourceDescription: "By configurator."); o.SetDirectPropertyValue(monitor, nameof(SqlDatabase.UseSnapshotIsolation), true, sourceDescription: "By configurator."); } else { monitor.Warn($"Unable to find configuration for Database named '{db.Name}' of type {db.GetType()}. Its ConnectionString will be null."); } }
public IStObjServiceFinalManualMapping?GetFinalMapping( IActivityMonitor m, StObjObjectEngineMap engineMap, IAutoServiceKindComputeFacade kindComputeFacade, ref bool success) { if (!_finalMappingDone) { _finalMappingDone = true; Class.ComputeFinalTypeKind(m, kindComputeFacade, new Stack <AutoServiceClassInfo>(), ref success); if (Assignments.Any()) { _finalMapping = engineMap.CreateServiceFinalManualMapping(this); } } return(_finalMapping); }
TSTypeFile DoGetTSTypeFile(IActivityMonitor monitor, Type t, ref HashSet <Type>?cycleDetector) { TSTypeFile?f = _typeMappings.GetValueOrDefault(t); if (f == null) { Debug.Assert(!_attributeCache.ContainsKey(t)); f = new TSTypeFile(this, t, Array.Empty <ITSCodeGeneratorType>(), null); _typeMappings.Add(t, f); _typeFiles.Add(f); } if (!f.IsInitialized) { EnsureInitialized(monitor, f, ref cycleDetector); } return(f); }
private bool HandleStObjPropertySource(IActivityMonitor monitor, StObjProperty p, MutableItem source, string sourceName, bool doSetOrMerge) { StObjProperty?c = source.GetStObjProperty(p.Name); // Source property is defined somewhere in the source. if (c != null) { // If the property is explicitly defined (Info != null) and its type is not // compatible with our, there is a problem. if (c.InfoOnType != null && !p.Type.IsAssignableFrom(c.Type)) { // It is a warning because if actual values work, everything is okay... but one day, it should fail. var msg = String.Format("StObjProperty '{0}.{1}' of type '{2}' is not compatible with the one of its {6} ('{3}.{4}' of type '{5}'). Type should be compatible since {6}'s property value will be propagated if no explicit value is set for '{7}.{1}' or if '{3}.{4}' is set with an incompatible value.", ToString(), p.Name, p.Type.Name, source.RealObjectType.Type.Name, c.Name, c.Type.Name, sourceName, RealObjectType.Type.Name); monitor.Warn(msg); } if (doSetOrMerge) { // The source value must have been set and not explicitly "removed" with a System.Type.Missing value. if (c.Value != System.Type.Missing) { // We "Set" the value from this source. if (!p.ValueHasBeenSet) { p.Value = c.Value; } else if (p.Value is IMergeable) { using (var services = new SimpleServiceContainer()) { services.Add(monitor); if (!((IMergeable)p.Value).Merge(c.Value, services)) { monitor.Error($"Unable to merge StObjProperty '{ToString()}.{p.Value}' with value from {sourceName}."); } } } return(true); } } } return(false); }
internal T FindProjectByGuid <T>(IActivityMonitor m, string guid, int lineNumber = 0) where T : ProjectBase { var project = FindProjectByGuid(m, guid); if (project == null) { return(null); } if (project is T typed) { return(typed); } m.Error(lineNumber == 0 ? $"Project '{guid}' must be a {typeof( T ).GetType().Name}." : $"Guid '{guid}' defined on line #{lineNumber} references must be a {typeof( T ).GetType().Name}."); return(null); }
/// <summary> /// Opens the key vault. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="passPhrase">The key vault pass phrase.</param> /// <returns>True on success.</returns> public bool OpenKeyVault(IActivityMonitor m, string passPhrase) { if (!CheckPassPhraseConstraints(m, passPhrase)) { return(false); } if (_passPhrase != null) { m.Info($"Key Vault is already opened."); return(true); } if (KeyVaultFileExists) { try { var keys = KeyVault.DecryptValues(File.ReadAllText(KeyVaultPath), passPhrase); m.OpenInfo($"Opening existing Key Vault with keys: {keys.Keys.Concatenate()}."); _store.ImportSecretKeys(m, keys); _passPhrase = passPhrase; _vaultContent.Clear(); _vaultContent.AddRange(keys); } catch (Exception ex) { m.Error("Unable to open the key vault.", ex); return(false); } } else { _passPhrase = passPhrase; m.OpenInfo($"New Key Vault opened."); } if (_store.Infos.Any(s => !s.IsSecretAvailable)) { using (m.OpenWarn($"Missing secrets:")) { foreach (var s in _store.Infos.Where(s => !s.IsSecretAvailable)) { m.Warn(s.ToString()); } } } m.CloseGroup(); return(true); }
/// <summary> /// Initialization of this handler always returns true. /// </summary> /// <param name="m">The monitor to use.</param> /// <returns>Always true.</returns> public ValueTask <bool> ActivateAsync(IActivityMonitor m) { // Ensure the System.Console colors are actually valid when starting. // Linux consoles may start with an invalid and undocumented value (-1). // In System.Console's source code, -1 is internally referenced as "UnknownColor". if (!Enum.IsDefined(typeof(ConsoleColor), System.Console.BackgroundColor)) { System.Console.BackgroundColor = ConsoleColor.Black; } if (!Enum.IsDefined(typeof(ConsoleColor), System.Console.ForegroundColor)) { System.Console.ForegroundColor = ConsoleColor.White; } return(ValueTask.FromResult(true)); }
public CSCodeGenerationResult Implement(IActivityMonitor monitor, MethodInfo m, ICSCodeGenerationContext c, ITypeScope b) { IFunctionScope mB = b.CreateOverride(m); mB.Parent.Should().BeSameAs(b, "The function is ready to be implemented."); if (IsLambda) { mB.Append("=> ").Append(ActualCode).Append(';').NewLine(); } else { mB.Append(ActualCode); } return(CSCodeGenerationResult.Success); }
/// <summary> /// Gets the simple git version <see cref="RepositoryInfo"/> from a branch. /// Returns null if an error occurred or if RepositoryInfo.xml has not been successfully read. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="branchName">Defaults to <see cref="CurrentBranchName"/>.</param> /// <returns>The RepositoryInfo or null if it it cannot be obtained.</returns> public RepositoryInfo ReadRepositoryVersionInfo(IActivityMonitor m, string branchName = null) { if (branchName == null) { branchName = CurrentBranchName; } try { Branch b = Git.Branches[branchName]; if (b == null) { m.Error($"Unknown branch {branchName}."); return(null); } var pathOpt = b.IsRemote ? SubPath.AppendPart("remotes").Combine(b.FriendlyName) : SubPath.AppendPart("branches").AppendPart(branchName); pathOpt = pathOpt.AppendPart("RepositoryInfo.xml"); var fOpt = FileSystem.GetFileInfo(pathOpt); if (!fOpt.Exists) { m.Error($"Missing required {pathOpt} file."); return(null); } var opt = RepositoryInfoOptions.Read(fOpt.ReadAsXDocument().Root); opt.StartingBranchName = branchName; var result = new RepositoryInfo(Git, opt); if (result.RepositoryError != null) { m.Error($"Unable to read RepositoryInfo. RepositoryError: {result.RepositoryError}."); return(null); } if (result.Error != null) { m.Error(result.ReleaseTagError); return(null); } return(result); } catch (Exception ex) { m.Fatal($"While reading version info for branch '{branchName}'.", ex); return(null); } }
void OnWorkingFolderChanged(IActivityMonitor m, LocalWorldName local) { var repo = _repos.FirstOrDefault(r => local.XmlDescriptionFilePath.StartsWith(r.Root)); if (repo == null) { m.Warn($"Unable to find the local repository for {local.FullName}."); } else if (!repo.IsOpen) { m.Warn($"Local repository {local.FullName} ({repo.Root}) is not opened."); } else { repo.PushChanges(m); } }
protected override BuildResult CreateBuildResult(IActivityMonitor m) { foreach (var(s, driver) in DependentSolutionContext.Solutions) { var buildProjectUpgrades = GetBuildProjectUpgrades(s); if (!driver.UpdatePackageDependencies(m, buildProjectUpgrades)) { return(null); } if (!driver.GitRepository.Commit(m, "Updated Build project dependencies.", CommitBehavior.AmendIfPossibleAndOverwritePreviousMessage)) { return(null); } _commits[s.Index] = driver.GitRepository.Head.CommitSha; } return(base.CreateBuildResult(m)); }
/// <summary> /// Reads this cache from a serialized data. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="reader">The deserializer to use.</param> /// <returns>True on success, false on error.</returns> public bool Read(IActivityMonitor monitor, ICKBinaryReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } try { _db = new PackageDB(reader); return(true); } catch (Exception ex) { monitor.Error("Unable to read package database.", ex); return(false); } }
protected override void DoApplySettings(IActivityMonitor m) { var solution = _driver.GetSolution(m, allowInvalidSolution: true); if (solution == null) { return; } var projects = _npmDriver.GetNPMProjects(m); if (projects == null) { return; } bool useNpm = projects.Any(); if (useNpm) { //CakeExtensions SetTextResource(m, "CakeExtensions/NpmDistTagRunner.cs"); SetTextResource(m, "CakeExtensions/NpmView.cs"); SetTextResource(m, "CakeExtensions/NpmGetNpmVersion.cs"); //npm itself SetTextResource(m, "npm/Build.NPMArtifactType.cs", text => AdaptBuildNPMArtifactForPushFeeds(text, solution)); SetTextResource(m, "npm/Build.NPMFeed.cs"); SetTextResource(m, "npm/NPMProject.cs"); SetTextResource(m, "npm/NPMPublishedProject.cs"); SetTextResource(m, "npm/NPMSolution.cs"); SetTextResource(m, "npm/NPMProjectContainer.cs"); SetTextResource(m, "npm/TempFileTextModification.cs"); SetTextResource(m, "npm/SimplePackageJsonFile.cs"); SetTextResource(m, "npm/AngularWorkspace.cs"); } else { DeleteFile(m, "CakeExtensions/NpmDistTagRunner.cs"); DeleteFile(m, "CakeExtensions/NpmView.cs"); DeleteFile(m, "CakeExtensions/NpmGetNpmVersion.cs"); DeleteFile(m, "npm/Build.NPMArtifactType.cs"); DeleteFile(m, "npm/Build.NPMFeed.cs"); DeleteFile(m, "npm/NPMProject.cs"); DeleteFile(m, "npm/NPMPublishedProject.cs"); DeleteFile(m, "npm/NPMSolution.cs"); } }
/// <summary> /// Computes the root path. /// </summary> /// <param name="m">A monitor (must not be null).</param> /// <returns>The final path to use (ends with '\'). Null if unable to compute the path.</returns> string ComputeBasePath( IActivityMonitor m ) { string rootPath = null; if( String.IsNullOrWhiteSpace( _configPath ) ) m.SendLine( LogLevel.Error, "The configured path is empty.", null ); else if( FileUtil.IndexOfInvalidPathChars( _configPath ) >= 0 ) m.SendLine( LogLevel.Error, string.Format( "The configured path '{0}' is invalid.", _configPath ), null ); else { rootPath = _configPath; if( !Path.IsPathRooted( rootPath ) ) { string rootLogPath = SystemActivityMonitor.RootLogPath; if( String.IsNullOrWhiteSpace( rootLogPath ) ) m.SendLine( LogLevel.Error, string.Format( "The relative path '{0}' requires that {1} be specified (typically in the AppSettings).", _configPath, SystemActivityMonitor.AppSettingsKey ), null ); else rootPath = Path.Combine( rootLogPath, _configPath ); } } return rootPath != null ? FileUtil.NormalizePathSeparator( rootPath, true ) : null; }
public void ApplySettings(IActivityMonitor m) { if (!this.CheckCurrentBranch(m)) { return; } if (PluginBranch == StandardGitStatus.Local && _solutionSpec.UseCKSetup && !_solutionSpec.NoDotNetUnitTests) { EnsureStorePath(m, _localFeedProvider.Local.GetCKSetupStorePath()); } else { Delete(m); } }
public void ApplySettings(IActivityMonitor monitor) { using (monitor.OpenInfo($"Executing {_scripts.Count} script(s) on this Workstation.")) using (var tempPS1 = new TemporaryFile("ps1")) { bool hasError = false; HashSet <EnvVar> currentVariables = null; foreach (var o in _scripts) { if (hasError) { break; } switch (o) { case HashSet <EnvVar> v: currentVariables = v; break; case ScriptLine script: { using (monitor.OpenTrace($"Executing script Type='{script.Type}', WorkingDir='{script.WorkingDir}', Arguments='{script.Arguments}', ContinueOnNonZeroExitCode='{script.ContinueOnNonZeroExitCode}'.")) { monitor.Debug($"With EnvironmentVariables: {currentVariables?.Select( v => v.ToString() ).Concatenate()}."); monitor.Debug(script.Script); System.IO.File.WriteAllText(tempPS1.Path, script.Script); if (!ProcessRunner.RunPowerShell( monitor, script.WorkingDir, tempPS1.Path, new[] { script.Arguments }, stdErrorLevel: LogLevel.Warn, currentVariables?.Select(v => (v.Name, Environment.ExpandEnvironmentVariables(v.Value))))) { hasError |= !script.ContinueOnNonZeroExitCode; if (!hasError) { monitor.Warn("ContinueOnNonZeroExitCode is true: error is ignored."); } } } break; } } } } }
public void ApplySettings(IActivityMonitor m) { if (!this.CheckCurrentBranch(m)) { return; } YamlMapping firstMapping = GetFirstMapping(m, true); if (firstMapping == null) { m.Error("First mapping should not return null !"); return; } // We don't use GitLab for public repositories if (GitFolder.IsPublic || GitFolder.KnownGitProvider != KnownGitProvider.GitLab) { if (TextContent != null) { m.Log(LogLevel.Info, "The project is public or the repository is not on GitLab, so we don't use GitLab and the .gitlab-ci.yml is not needed."); Delete(m); } return; } // We use GitLab when the repository is private. YamlMapping codeCakeJob = FindOrCreateYamlElement(m, firstMapping, "codecakebuilder"); SetSequence(codeCakeJob, "tags", new YamlValue("windows")); SetSequence(codeCakeJob, "script", new YamlValue("dotnet run --project CodeCakeBuilder -nointeraction") ); codeCakeJob["artifacts"] = new YamlMapping() { ["paths"] = new YamlSequence() { new YamlValue(@"'**\*.log'"), new YamlValue(@"'**\*.trx'"), new YamlValue(@"'**\Tests\**\TestResult*.xml'"), new YamlValue(@"'**Tests\**\Logs\**\*'"), }, ["when"] = new YamlValue("always"), ["expire_in"] = new YamlValue("6 month") }; CreateOrUpdate(m, YamlMappingToString(m)); }
public void ApplySettings(IActivityMonitor m) { if (_solutionSpec.NoSharedPropsFile) { Delete(m); return; } if (!_commonFolder.EnsureDirectory(m)) { return; } var s = _driver.GetSolution(m, false); if (s == null) { return; } bool useCentralPackage = s.Projects.Select(p => p.Tag <MSBuildSln.MSProject>()) .Where(p => p != null) .Any(p => p.UseMicrosoftBuildCentralPackageVersions); // If Shared.props exists, we make sure there is no xml namespace defined. if (Document == null) { Document = new XDocument(new XElement("Project")); } else { Document.Root.RemoveAllNamespaces(); } HandleBasicDefinitions(m, useCentralPackage); HandleStandardProperties(m); XCommentSection.FindOrCreate(Document.Root, "ReproducibleBuilds", false)?.Remove(); HandleZeroVersion(m); HandleGenerateDocumentation(m); HandleSourceLink(m, useCentralPackage); Document.Root.Elements("PropertyGroup") .Where(e => !e.HasElements) .Select(e => e.ClearCommentsBeforeAndNewLineAfter()) .Remove(); Save(m); }
bool IStObjTypeFilter.TypeFilter(IActivityMonitor monitor, Type t) { // Type.FullName is null if the current instance represents a generic type parameter, an array // type, pointer type, or byref type based on a type parameter, or a generic type // that is not a generic type definition but contains unresolved type parameters. // This FullName is also null for (at least) classes nested into nested generic classes. // In all cases, we emit a warn and filters this beast out. if (t.FullName == null) { monitor.Warn($"Type has no FullName: '{t.Name}'. It is excluded."); return(false); } Debug.Assert(t.AssemblyQualifiedName != null, "Since FullName is defined."); if (_excludedTypes.Contains(t.Name)) { monitor.Info($"Type {t.AssemblyQualifiedName} is filtered out by its Type Name."); return(false); } if (_excludedTypes.Contains(t.FullName)) { monitor.Info($"Type {t.AssemblyQualifiedName} is filtered out by its Type FullName."); return(false); } if (_excludedTypes.Contains(t.AssemblyQualifiedName)) { monitor.Info($"Type {t.AssemblyQualifiedName} is filtered out by its Type AssemblyQualifiedName."); return(false); } if (SimpleTypeFinder.WeakenAssemblyQualifiedName(t.AssemblyQualifiedName, out var weaken) && _excludedTypes.Contains(weaken)) { monitor.Info($"Type {t.AssemblyQualifiedName} is filtered out by its weak type name ({weaken})."); return(false); } // We only care about IPoco and IRealObject. Nothing more. if (_isUnifiedPure) { if (!typeof(IPoco).IsAssignableFrom(t) && !typeof(IRealObject).IsAssignableFrom(t)) { return(false); } } return(_firstLayer?.TypeFilter(monitor, t) ?? true); }
StackRepo FindRepo(IActivityMonitor m, string stackName) { int idx = _stacks.IndexOf(d => d.StackName == stackName); if (idx < 0) { m.Error($"Stack named '{stackName}' not found."); return(null); } var home = _repos.FirstOrDefault(r => r.OriginUrl == _stacks[idx].OriginUrl); if (home == null) { m.Error($"Repository initialization error for stack '{_stacks[idx]}'."); return(null); } return(home); }
public async ValueTask <ISender> CreateSenderAsync(IActivityMonitor monitor, TrustedParty audience, ISignAlgorithm algorithm, TimeSpan validity, bool encrypt = false, uint maxUseCount = 0) { Throw.CheckNotNullArgument(monitor); Throw.CheckNotNullArgument(audience); Throw.CheckNotNullArgument(algorithm); Throw.CheckArgument(validity >= Configuration.MinSignatureLifetime && validity <= Configuration.MaxSignatureLifetime); var bestBefore = _appClock.Clock.UtcNow + validity; var key = algorithm.KeyRequirement != null ? await ResolveOutgoingKeyAsync(monitor, audience, algorithm.KeyRequirement, bestBefore, maxUseCount) : null; return(new Sender(this, audience, algorithm, key, bestBefore)); }
public CSCodeGenerationResult Implement(IActivityMonitor monitor, MethodInfo m, ICSCodeGenerationContext codeGenContext, ITypeScope typeBuilder) { IFunctionScope mB = typeBuilder.CreateOverride(m); Debug.Assert(mB.Parent == typeBuilder, "The function is ready to be implemented."); if (_attr.IsLambda) { mB.Append("=> ").Append(_attr.ActualCode).Append(';').NewLine(); } else { mB.Append(_attr.ActualCode).NewLine(); } return(CSCodeGenerationResult.Success); }
/// <summary> /// Computes the road map for all the solutions. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="versionSelector">The version selector to use.</param> /// <param name="forgetAllExistingRoadmapVersions"> /// True to automatically skip any previously reolved versions. /// <paramref name="versionSelector"/> will not see them. /// </param> /// <returns>True on success, false on error or cancellation..</returns> public bool UpdateRoadmap(IActivityMonitor m, IReleaseVersionSelector versionSelector, bool forgetAllExistingRoadmapVersions) { if (!forgetAllExistingRoadmapVersions) { foreach (var info in _infos) { info.ClearReleaseInfo(); } } foreach (var info in _infos) { if (!info.EnsureReleaseInfo(m, versionSelector).IsValid) { return(false); } } return(true); }
/// <summary> /// Common validator function for names. /// </summary> /// <param name="monitor">The monitor.</param> /// <param name="propertyName">The property name.</param> /// <param name="value">The value.</param> /// <param name="isRequired">Whether it is required or can be let to null.</param> /// <returns>True on success, false otherwise.</returns> public static bool ValidateName(IActivityMonitor monitor, string propertyName, string?value, bool isRequired) { if (string.IsNullOrWhiteSpace(value)) { if (isRequired) { monitor.Error($"{propertyName} is required and {_nameSuffix}"); return(false); } return(true); } if (value.Any(c => !IsValidNameChar(c)) || Char.IsDigit(value[0]) || value[0] == '_') { monitor.Error($"{propertyName} {_nameSuffix} {propertyName} = '{value}'."); return(false); } return(true); }
public void ShowLogsBetweenDates( IActivityMonitor m, DateTimeOffset beginning, DateTimeOffset ending, IEnumerable <DiffRoot> diffRoot) { List <Commit> commits = GetCommitsBetweenDates(beginning, ending).ToList(); if (commits.Count == 0) { m.Info("No commits between the given dates."); } else { IDiffResult diffResult = GetReleaseDiff(m, diffRoot, commits); Console.WriteLine(diffResult.ToString()); } }
/// <summary> /// Reads the solution level dependencies. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="dep">The action per dependent project.</param> /// <returns>True on success, false on error.</returns> protected bool EnumerateSolutionLevelProjectDependencies(IActivityMonitor m, Action <Project> dep) { var deps = FindSection("ProjectDependencies"); if (deps != null) { foreach (var line in deps.PropertyLines) { var p = Solution.FindProjectByGuid <Project>(m, line.Name, line.LineNumber); if (p == null) { return(false); } dep(p); } } return(true); }
/// <summary> /// The initialize. /// </summary> /// <param name="monitor"> /// The monitor. /// </param> public override void Initialize(IActivityMonitor monitor) { monitor.BridgeClosed += this.OnBridgeClosed; monitor.BridgeClosing += this.OnBridgeClosing; monitor.BridgeInitialized += this.OnBridgeInitialized; monitor.BridgeInitializing += this.OnBridgeInitializing; monitor.BridgeTransferred += this.OnBridgeTransferred; monitor.BridgeTransferring += this.OnBridgeTransferring; monitor.BridgeException += this.OnBridgeException; monitor.BridgeWarning += this.OnBridgeWarning; monitor.MessageBusWarning += this.OnMessageBusWarning; monitor.MessageBusException += this.OnMessageBusException; monitor.MessageBusClosed += this.OnMessageBusClosed; monitor.MessageBusClosing += this.OnMessageBusClosing; monitor.MessageBusRegisteredHandler += this.OnMessageBusHandlerRegistered; monitor.MessageBusRegisteringHandler += this.OnMessageBusHandlerRegistering; monitor.MessageBusSending += this.OnMessageBusMessageSending; monitor.MessageBusSent += this.OnMessageBusMessageSent; monitor.PublisherWarning += this.OnPublisherWarning; monitor.PublisherException += this.OnPublisherException; monitor.PublisherClosed += this.OnPublisherClosed; monitor.PublisherClosing += this.OnPublisherClosing; monitor.PublisherInitializing += this.OnPublisherInitializing; monitor.PublisherInitialized += this.OnPublisherInitialized; monitor.PublisherSending += this.OnPublisherSending; monitor.PublisherSent += this.OnPublisherSent; monitor.SubscriberWarning += this.OnSubscriberWarning; monitor.SubscriberException += this.OnSubscriberException; monitor.SubscriberClosed += this.OnSubscriberClosed; monitor.SubscriberClosing += this.OnSubscriberClosing; monitor.SubscriberInitialized += this.OnSubscriberInitialized; monitor.SubscriberInitializing += this.OnSubscriberInitializing; monitor.SubscriberReceived += this.OnSubscriberReceived; monitor.SubscriberReceiving += this.OnSubscriberReceiving; monitor.WorkerRunning += this.OnWorkerRunning; monitor.WorkerStarted += this.OnWorkerStarted; monitor.WorkerStarting += this.OnWorkerStarting; monitor.WorkerStopped += this.OnWorkerStopped; monitor.WorkerStopping += this.OnWorkerStopping; monitor.WorkerCompleted += this.OnWorkerCompleted; monitor.WorkerException += this.OnWorkerException; monitor.WorkerWarning += this.OnWorkerWarning; base.Initialize(monitor); }
/// <summary> /// The initialize method. /// </summary> /// <param name="monitor"> /// The monitor. /// </param> public virtual void Initialize(IActivityMonitor monitor) { this.MachineName = Environment.MachineName; this.DeploymentId = string.Empty; this.RoleInstanceName = string.Empty; this.RoleInstanceId = string.Empty; if (RoleEnvironment.CurrentRoleInstance == null) { return; } this.DeploymentId = RoleEnvironment.DeploymentId; this.RoleInstanceId = RoleEnvironment.CurrentRoleInstance.Id; if (RoleEnvironment.CurrentRoleInstance.Role != null) { this.RoleInstanceName = RoleEnvironment.CurrentRoleInstance.Role.Name; } }
/// <summary> /// Ensures that the <see cref="Default"/> GrandOutput is created (see <see cref="EnsureActiveDefault"/>) and configured with default settings: /// only one one channel with its minimal filter sets to Debug with one text file handler that writes .txt files in "<see cref="SystemActivityMonitor.RootLogPath"/>\GrandOutputDefault" directory. /// The <see cref="SystemActivityMonitor.RootLogPath"/> must be valid and if a GrandOutput.config file exists inside, it is loaded as the configuration. /// If it exists, it must be valid (otherwise an exception is thrown). /// Once loaded, the file is monitored and any change that occurs to it dynamically triggers a <see cref="SetConfiguration"/> with the new file. /// </summary> /// <param name="monitor">An optional monitor.</param> static public GrandOutput EnsureActiveDefaultWithDefaultSettings( IActivityMonitor monitor = null ) { lock( _defaultLock ) { if( _default == null ) { if( monitor == null ) monitor = new SystemActivityMonitor( true, "GrandOutput" ) { MinimalFilter = GrandOutputMinimalFilter }; using( monitor.OpenGroup( LogLevel.Info, "Attempting Default GrandOutput configuration.", null ) ) { try { SystemActivityMonitor.AssertRootLogPathIsSet(); _configPath = SystemActivityMonitor.RootLogPath + "GrandOutput.config"; GrandOutputConfiguration def = CreateDefaultConfig(); if( !File.Exists( _configPath ) ) { File.WriteAllText( _configPath, _defaultConfig ); } if( !def.LoadFromFile( _configPath, monitor ) ) { throw new CKException( "Unable to load Configuration file: '{0}'.", _configPath ); } GrandOutput output = new GrandOutput(); if( !output.SetConfiguration( def, monitor ) ) { throw new CKException( "Failed to set Configuration." ); } StartMonitoring( monitor ); _default = output; ActivityMonitor.AutoConfiguration += m => _default.Register( m ); } catch( Exception ex ) { monitor.SendLine( LogLevel.Fatal, null, ex ); throw; } } } } return _default; }
/// <summary> /// Loads this configuration from a <see cref="XElement"/>. /// </summary> /// <param name="e">The xml element: its name must be GrandOutputConfiguration.</param> /// <param name="monitor">Monitor that will be used.</param> /// <returns>True on success, false if the configuration can not be read.</returns> public bool Load( XElement e, IActivityMonitor monitor ) { if( e == null ) throw new ArgumentNullException( "e" ); if( monitor == null ) throw new ArgumentNullException( "monitor" ); try { if( e.Name != "GrandOutputConfiguration" ) throw new XmlException( "Element name must be <GrandOutputConfiguration>." + e.GetLineColumnString() ); // AppDomainDefaultFilter was the name before. LogFilter? globalDefaultFilter = e.GetAttributeLogFilter( "GlobalDefaultFilter", false ) ?? e.GetAttributeLogFilter( "AppDomainDefaultFilter", false ); SourceFilterApplyMode applyMode; Dictionary<string, LogFilter> sourceFilter = ReadSourceOverrideFilter( e, out applyMode, monitor ); if( sourceFilter == null ) return false; RouteConfiguration routeConfig; using( monitor.OpenGroup( LogLevel.Trace, "Reading root Channel.", null ) ) { XElement channelElement = e.Element( "Channel" ); if( channelElement == null ) { monitor.SendLine( LogLevel.Error, "Missing <Channel /> element." + e.GetLineColumnString(), null ); return false; } routeConfig = FillRoute( monitor, channelElement, new RouteConfiguration() ); } // No error: set the new values. _routeConfig = routeConfig; _sourceFilter = sourceFilter; _sourceFilterApplyMode = applyMode; _globalDefaultFilter = globalDefaultFilter; return true; } catch( Exception ex ) { monitor.SendLine( LogLevel.Error, null, ex ); } return false; }
/// <summary> /// Tries to parse a recent file name entry. /// </summary> /// <param name="monitor">Monitor that may receive errors.</param> /// <param name="s">String to parse.</param> /// <returns>A recent file or null if parsing failed.</returns> public static RecentFile TryParse( IActivityMonitor monitor, string s ) { if( monitor == null ) throw new ArgumentNullException( "monitor" ); if( s == null ) throw new ArgumentNullException( "s" ); int pipeIdx = s.IndexOf( '|' ); if( pipeIdx > 0 ) { string fName = s.Substring( 0, pipeIdx ); if( System.IO.File.Exists( fName ) ) { DateTime accessTime; if( !FileUtil.TryParseFileNameUniqueTimeUtcFormat( s.Substring( pipeIdx + 1 ), out accessTime ) ) { monitor.Warn().Send( "Invalid recent file access time for '{0}'. It is set to now.", fName ); accessTime = DateTime.UtcNow; } return new RecentFile( new FileInfo( fName ), accessTime ); } else monitor.Warn().Send( "Recent file '{0}' does not exist. It is ignored.", fName ); } else monitor.Warn().Send( "Invalid recent file entry '{0}'. It is ignored.", s ); return null; }
/// <summary> /// Checks that children are valid (action's name must be unique). /// </summary> /// <param name="routeName">Name of the route that references this action.</param> /// <param name="monitor">Monitor to report errors.</param> /// <returns>True if valid, false otherwise.</returns> public override bool CheckValidity( string routeName, IActivityMonitor monitor ) { if( monitor == null ) throw new ArgumentNullException( "monitor" ); bool result = true; for( int i = 0; i < _children.Count; ++i ) { var child = _children[i]; bool validChild = true; for( int j = ++i; j < _children.Count; ++j ) { if( _children[j].Name == child.Name ) { monitor.SendLine( LogLevel.Error, string.Format( "Duplicate action name '{0}' in {1} '{2}', route '{3}'.", child.Name, TypeDisplayName, Name, routeName ), null ); validChild = false; } } validChild &= child.CheckValidity( routeName, monitor ); // Remove child to continue the process but avoid cascading errors. if( !validChild ) _children.RemoveAt( i-- ); result &= validChild; } return result; }
void DoSequenceOrParallelOrAdd( IActivityMonitor monitor, Action<ActionConfiguration> collector, XElement xml ) { if( xml.Name == "Parallel" || xml.Name == "Sequence" ) { Action<ActionConfiguration> elementCollector; if( xml.Name == "Parallel" ) { var p = new ActionParallelConfiguration( xml.AttributeRequired( "Name" ).Value ); elementCollector = a => p.AddAction( a ); collector( p ); } else { var s = new ActionSequenceConfiguration( xml.AttributeRequired( "Name" ).Value ); elementCollector = a => s.AddAction( a ); collector( s ); } foreach( var action in xml.Elements() ) DoSequenceOrParallelOrAdd( monitor, collector, action ); } else { if( xml.Name != "Add" ) throw new XmlException( String.Format( "Unknown element '{0}': only <Add>, <Parallel> or <Sequence>.", xml.Name ) ); string type = xml.AttributeRequired( "Type" ).Value; Type t = FindConfigurationType( type ); HandlerConfiguration hC = (HandlerConfiguration)Activator.CreateInstance( t, xml.AttributeRequired( "Name" ).Value ); hC.DoInitialize( monitor, xml ); collector( hC ); } }
SubRouteConfiguration FillSubRoute( IActivityMonitor monitor, XElement xml, SubRouteConfiguration sub ) { using( monitor.OpenGroup( LogLevel.Trace, string.Format( "Reading subordinated channel '{0}'.", sub.Name ), null ) ) { var matchOptions = (string)xml.Attribute( "MatchOptions" ); var filter = (string)xml.Attribute( "TopicFilter" ); var regex = (string)xml.Attribute( "TopicRegex" ); if( (filter == null) == (regex == null) ) { throw new XmlException( "Subordinated Channel must define one TopicFilter or TopicRegex attribute (and not both)." + xml.GetLineColumnString() ); } RegexOptions opt = RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline | RegexOptions.ExplicitCapture; if( !String.IsNullOrWhiteSpace( matchOptions ) ) { if( !Enum.TryParse( matchOptions, true, out opt ) ) { var expected = String.Join( ", ", Enum.GetNames( typeof( RegexOptions ) ).Where( n => n != "None" ) ); throw new XmlException( "MatchOptions value must be a subset of: " + expected + xml.GetLineColumnString() ); } monitor.SendLine( LogLevel.Trace, string.Format( "MatchOptions for Channel '{0}' is: {1}.", sub.Name, opt ), null ); } else monitor.SendLine( LogLevel.Trace, string.Format( "MatchOptions for Channel '{0}' defaults to: IgnoreCase, CultureInvariant, Multiline, ExplicitCapture.", sub.Name ), null ); sub.RoutePredicate = filter != null ? CreatePredicateFromWildcards( filter, opt ) : CreatePredicateRegex( regex, opt ); FillRoute( monitor, xml, sub ); return sub; } }