void DumpWarnings(IActivityMonitor m, HttpResponseHeaders responseHeaders) { if (responseHeaders.Contains("warning")) { foreach (string warning in responseHeaders.GetValues("warning")) { m.Warn($"NPM warning: {warning}"); var match = Regex.Match(warning, @"/^\s*(\d{3})\s+(\S+)\s+""(.*)""\s+""([^""]+)""/"); if (!int.TryParse(match.Groups[1].Value, out int code)) { m.Error("Incorrect warning header format."); continue; } string host = match.Groups[2].Value; string message = match.Groups[3].Value; DateTime date = JsonConvert.DeserializeObject <DateTime>(match.Groups[4].Value); if (code == 199) { if (message.Contains("ENOTFOUND")) { m.Warn($"registry: Using stale data from {RegistryUri.ToString()} because the host is inaccessible -- are you offline?"); m.Error("Npm.Net is not using any caches, so you should not see the previous warning."); } else { m.Warn($"Unexpected warning for {RegistryUri.ToString()}: {message}"); } } else if (code == 111) { m.Warn($"Using stale data from {RegistryUri.ToString()} due to a request error during revalidation."); } } } }
public void Add(string name, List <XNode> e, bool replace, bool @override) { Monitor.Trace($"Registering {name} reusable for {Element.ToStringPath()}."); if (_map == null) { _map = new Dictionary <string, List <XNode> >(); } bool existsAbove = Parent?.Find(name, clone: false) != null; bool existsHere = _map.ContainsKey(name); if (replace && !existsHere) { Monitor.Warn($"{Element.ToStringPath()}: Reusable '{name}' does not replace any previously registered item. Replace=\"True\" attribute should be removed."); } if (!replace && existsHere) { Monitor.Error($"{Element.ToStringPath()}: Reusable '{name}' is already registered at this level. Use Replace=\"True\" attribute if replacement is intentional."); } if (@override && !existsAbove) { Monitor.Warn($"{Element.ToStringPath()}: Reusable '{name}' does not override any registered item above. Override=\"True\" attribute should be removed."); } if (!@override && existsAbove) { Monitor.Error($"{Element.ToStringPath()}: Reusable '{name}' is already registered above. Use Override=\"True\" attribute if redefinition is intentional."); } _map[name] = e; }
public bool OptimizeUnionTypes(IActivityMonitor monitor) { Debug.Assert(_unionTypes != null && _unionTypes.Any() && _unionTypes.All(t => !t.Kind.IsNullable())); for (int i = 0; i < _unionTypes.Count; ++i) { var tN = _unionTypes[i]; var t = tN.Type; for (int j = i + 1; j < _unionTypes.Count; ++j) { var tJN = _unionTypes[j]; var tJ = tJN.Type; if (tJ == t) { monitor.Warn($"{ToString()} UnionType '{t.ToCSharpName()}' duplicated. Removing one."); _unionTypes.RemoveAt(j--); } else if (tJ.IsAssignableFrom(t)) { monitor.Warn($"{ToString()} UnionType '{tJ.ToCSharpName()}' is assignable from (is more general than) '{t.ToCSharpName()}'. Removing the second one."); _unionTypes.RemoveAt(i--); break; } else if (t.IsAssignableFrom(tJ)) { monitor.Warn($"{ToString()} UnionType '{t.ToCSharpName()}' is assignable from (is more general than) '{tJ.ToCSharpName()}'. Removing the second one."); _unionTypes.RemoveAt(j--); } } } if (_unionTypes.Count == 1) { monitor.Warn($"{ToString()}: UnionType contains only one type. This is weird (but ignored)."); } return(true); }
/// <summary> /// Ensures that the the Git Repository is opened and updates the <see cref="Worlds"/>. /// Returns true on success, false on error. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="force">True to refresh the <see cref="Worlds"/> even if <see cref="IsOpen"/> is already true.</param> /// <returns>Whether this repository has been successfully opened.</returns> internal bool Refresh(IActivityMonitor m, bool force = true) { bool isOpened = false; if (!IsOpen) { _git = GitRepository.Create(m, this, Root, Root.LastPart, false, BranchName, checkOutBranchName: true); if (_git == null) { return(false); } isOpened = true; } if (force || isOpened) { if (_git.Pull(m, MergeFileFavor.Theirs).ReloadNeeded || isOpened) { var worldNames = Directory.GetFiles(Root, "*.World.xml") .Select(p => LocalWorldName.TryParse(p, _store.WorldLocalMapping)) .Where(w => w != null) .ToDictionary(w => w.FullName); var invalidParallels = worldNames.Values.Where(p => p.ParallelName != null && !worldNames.ContainsKey(p.Name)).ToList(); foreach (var orphan in invalidParallels) { m.Warn($"Invalid Parallel World '{orphan.FullName}': unable to find the default stack definition '{orphan.Name}' in the repository. It is ignored."); worldNames.Remove(orphan.FullName); } foreach (var exists in _worlds) { if (!worldNames.Remove(exists.WorldName.FullName)) { if (exists.WorldName.HasDefinitionFile) { m.Warn($"Unable to find World definition file for '{exists.WorldName}'. File '{exists.WorldName.XmlDescriptionFilePath}' not found."); exists.WorldName.HasDefinitionFile = false; } } else { if (!exists.WorldName.HasDefinitionFile) { m.Trace($"Found World definition file for '{exists.WorldName}'."); exists.WorldName.HasDefinitionFile = true; } } } foreach (var newWorld in worldNames.Values) { m.Info($"Found a new World definition: creating '{newWorld.FullName}' entry."); newWorld.HasDefinitionFile = true; _worlds.Add(new WorldInfo(this, newWorld)); } } } return(IsOpen); }
/// <summary> /// Emits a warning for each <see cref="Element"/>'s attribute that has not been <see cref="Handle"/>d. /// </summary> /// <returns>The number of emitted warnings.</returns> public int WarnUnhandledAttributes() { int warned = 0; foreach (var a in Element.Attributes()) { if (!_handled.Contains(a)) { warned++; Monitor.Warn($"Unhandled attribute '{a.Name}'{a.GetLineColumnString()}."); } } return(warned); }
internal bool Validate(IActivityMonitor monitor, string name) { bool success = true; if (MinKeyDuration < TimeSpan.FromSeconds(1)) { monitor.Error($"{name}.MinKeyDuration must not be less than 00:00:01 (1 second)."); success = false; } if (MaxUseCount < 1) { monitor.Error($"{name}.MaxUseCount must be at least 1."); success = false; } else if (DefaultUseCount < 1) { monitor.Error($"{name}.DefaultUseCount must be between 1 and MaxUseCount ({MaxUseCount}) included."); success = false; } else if (DefaultUseCount > MaxUseCount) { monitor.Warn($"{name}.DefaultUseCount must not be greater than MaxUseCount ({MaxUseCount}). It has been set to MaxUseCount."); DefaultUseCount = MaxUseCount; } return(success); }
/// <summary> /// Reads the Stacks.xml file and instanciates the <see cref="StackRepo"/> objects and /// their <see cref="WorldInfo"/>: creating the StackRepo registers the required secrets /// in the key store. /// </summary> /// <param name="m">The monitor to use.</param> internal void ReadStacksFromLocalStacksFilePath(IActivityMonitor m) { if (!File.Exists(StacksFilePath)) { m.Warn($"File '{StacksFilePath}' not found."); } else { using (m.OpenInfo($"Reading '{StacksFilePath}'.")) { try { _stackRepos.Clear(); _stackRepos.AddRange(XDocument.Load(StacksFilePath).Root.Elements().Select(e => StackRepo.Parse(this, e))); } catch (Exception ex) { m.Error($"Unable to read '{StacksFilePath}' file.", ex); } } } if (_stackRepos.Count == 0) { using (m.OpenInfo("Since there is no Stack defined, we initialize CK and CK-Build mapped to '/Dev/CK' by default.")) { m.Info($"Use 'run World/{nameof( SetWorldMapping )}' command to update the mapping."); _stackRepos.Add(new StackRepo(this, new Uri("https://github.com/signature-opensource/CK-Stack.git"), true)); _stackRepos.Add(new StackRepo(this, new Uri("https://github.com/CK-Build/CK-Build-Stack.git"), true)); WorldLocalMapping.SetMap(m, "CK-Build", "/Dev/CK"); WorldLocalMapping.SetMap(m, "CK", "/Dev/CK"); WriteStacksToLocalStacksFilePath(m); } } }
internal CKTypeInfo(IActivityMonitor monitor, CKTypeInfo?parent, Type t, IServiceProvider services, bool isExcluded, AutoServiceClassInfo?serviceClass) { Debug.Assert((serviceClass == null) == (this is RealObjectClassInfo)); ServiceClass = serviceClass; Generalization = parent; Type = t; _interfacesCache = System.Type.EmptyTypes; if ((parent?.IsExcluded ?? false)) { monitor.Warn($"Type {t.FullName} is excluded since its parent is excluded."); IsExcluded = true; } else if (IsExcluded = isExcluded) { monitor.Info($"Type {t.FullName} is excluded."); } else { _attributes = new TypeAttributesCache(monitor, t, services, parent == null); _interfacesCache = t.GetInterfaces(); if (parent != null) { _nextSibling = parent._firstChild; parent._firstChild = this; ++parent._specializationCount; } } }
/// <summary> /// Helper that copies a file with retries. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="source">The source file path.</param> /// <param name="target">The target file path.</param> /// <returns>True on success, false on error.</returns> public static bool SafeCopy(IActivityMonitor monitor, NormalizedPath source, NormalizedPath target) { int tryCount = 0; retry: try { File.Copy(source, target, true); } catch (FileNotFoundException ex) { monitor.Error($"Unable to copy file: source '{source}' not found.", ex); return(false); } catch (Exception ex) { if (++tryCount > 5) { monitor.Error($"Unable to copy file: '{source}' to '{target}' after 5 tries.", ex); return(false); } monitor.Warn($"Unable to copy file: '{source}' to '{target}'. Retrying in {tryCount * 50} ms.", ex); System.Threading.Thread.Sleep(tryCount * 50); goto retry; } monitor.Info($"Copied file '{source}' to '{target}'."); return(true); }
static void ConfigureByStObjConstruct(IActivityMonitor monitor, IStObjMutableItem o, SqlDatabase db) { var fromAbove = o.ConstructParametersAboveRoot; Debug.Assert(fromAbove != null, "Since we are on the root of the specializations path."); fromAbove.Should().NotBeEmpty().And.HaveCount(1, "We have only one base class with a StObjConstruct method."); var(t, parameters) = fromAbove.Single(); t.Should().Be(typeof(SqlDatabase)); if (parameters.Count != 3 || parameters[0].Name != "connectionString" || parameters[0].Type != typeof(string) || parameters[1].Name != "hasCKCore" || parameters[1].Type != typeof(bool) || parameters[2].Name != "useSnapshotIsolation" || parameters[2].Type != typeof(bool)) { throw new CKException("Expected SqlDatabase.StObjContruct(string connectionString, bool hasCKCore, bool useSnapshotIsolation)"); } if (db.IsDefaultDatabase) { parameters[0].SetParameterValue("The default connection string."); } else if (db.Name == "histo") { parameters[0].SetParameterValue("The histo connection string."); parameters[1].SetParameterValue(true); parameters[2].SetParameterValue(true); } else { monitor.Warn($"Unable to find configuration for Database named '{db.Name}' of type {db.GetType()}. Its ConnectionString will be null."); } }
bool DoSomething(IActivityMonitor m, FileInfo file) { using (m.OpenInfo().Send("Do something important on file '{0}'.", file.Name)) { if (!file.Exists) { m.Warn().Send("File does not exist."); } else { m.Trace().Send("File last modified at {1:T}. {0} Kb to process.", file.Length, file.LastWriteTimeUtc); try { // ... Process file ... } catch (Exception ex) { m.Error().Send(ex, "While processing."); return(false); } } m.SetTopic("Changing my mind. Keeping it as-is."); return(true); } }
/// <summary> /// Gets the <see cref="ExternalNameAttribute"/> names or this <see cref="Type.FullName"/>. /// Emits a warning if the full name is used, and errors if the name exists and is invalid. /// </summary> /// <param name="t">This type.</param> /// <param name="monitor">The monitor to use.</param> /// <param name="name">The name to use to identify the type.</param> /// <param name="previousNames">Optional previous names.</param> /// <returns>True on success, false on error.</returns> public static bool GetExternalNames(this Type t, IActivityMonitor monitor, out string name, out string[] previousNames) { CustomAttributeData?attr = GetAttributeData(t); if (attr != null) { var args = attr.ConstructorArguments; name = (string)args[0].Value !; previousNames = ((IEnumerable <CustomAttributeTypedArgument>)args[1].Value !).Select(a => (string)a.Value !).ToArray(); if (String.IsNullOrWhiteSpace(name)) { monitor.Error($"Empty name in ExternalName attribute on '{t.FullName}'."); return(false); } if (previousNames.Any(n => String.IsNullOrWhiteSpace(n))) { monitor.Error($"Empty previous name in ExternalName attribute on '{t.FullName}'."); return(false); } if (previousNames.Contains(name) || previousNames.GroupBy(Util.FuncIdentity).Any(g => g.Count() > 1)) { monitor.Error($"Duplicate ExternalName in attribute on '{t.FullName}'."); return(false); } } else { name = t.FullName !; previousNames = Array.Empty <string>(); monitor.Warn($"Type '{name}' use its full name as its name since no [ExternalName] attribute is defined."); } return(true); }
internal AutoServiceKind ComputeFinalTypeKind(IActivityMonitor m, IAutoServiceKindComputeFacade kindComputeFacade, ref bool success) { if (!_isComputed) { if (_isComputing) { m.Warn($"Automatic DI type of 'IEnumerable<{EnumeratedType.FullName}> is not decidable: a dependency cycle has been found. It will be considered as the \"worst case\": a non marshallable IsFrontService|IsScoped."); _finalKind = AutoServiceKind.IsFrontService | AutoServiceKind.IsFrontProcessService | AutoServiceKind.IsScoped; } else { // Check that the potential registered IEnumerable AutoServiceKind is compatible with the one of the enumerated interface. var combined = (_itemKind | _enumerabledKind) & ~CKTypeKind.IsMultipleService; var conflict = combined.GetCombinationError(false); if (conflict != null) { m.Error($"Invalid configuration for 'IEnumerable<{EnumeratedType.FullName}>' ({_enumerabledKind}) that contradicts the {EnumeratedType.Name} interface ({_itemKind}): {conflict}."); success = false; } else { _isComputing = true; DoComputeFinalTypeKind(m, kindComputeFacade, combined.ToAutoServiceKind(), ref success); _isComputing = false; } } _isComputed = true; } return(_finalKind); }
public async Task <ArtifactAvailableInstances> GetVersionsAsync(IActivityMonitor m, string artifactName) { if (_registry == null) { _registry = _registryFactory(); } var v = new ArtifactAvailableInstances(this, artifactName); var result = await _registry.View(m, artifactName); if (result.exist) { JObject body = JObject.Parse(result.viewJson); var versions = (JObject)body["versions"]; foreach (var vK in versions) { var sV = SVersion.TryParse(vK.Key); if (!sV.IsValid) { m.Warn($"Unable to parse version '{vK.Key}' for '{artifactName}': {sV.ErrorMessage}"); } else { v = v.WithVersion(sV); } } } return(v); }
internal static void CommonLogAndWarings(IActivityMonitor monitor, IReadOnlyList <Type> abstractTails) { if (abstractTails.Count > 0) { monitor.Warn($"Abstract classes without specialization are ignored: {abstractTails.Select( t => t.ToCSharpName() ).Concatenate()}."); } }
/// <summary> /// Reads or creates a new <see cref="SolutionFile"/>. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="ctx">The project file context.</param> /// <param name="solutionPath">The path to the .sln file relative to the <see cref="MSProjContext.FileSystem"/>.</param> /// <param name="mustExist">False to allow the file to not exist.</param> /// <returns> /// The solution file or null on error (for example when not found and <paramref name="mustExist"/> is true). /// </returns> public static SolutionFile Read(FileSystem fs, IActivityMonitor m, NormalizedPath solutionPath, bool mustExist = true) { using (m.OpenInfo($"Reading '{solutionPath}'.")) { var file = fs.GetFileInfo(solutionPath); if (!file.Exists && mustExist) { m.Error($"File '{solutionPath}' not found. Unable to read the solution."); return(null); } var s = new SolutionFile(fs, solutionPath); if (file.Exists) { using (var r = new Reader(m, file.CreateReadStream())) { if (!s.Read(r)) { m.Error("Unable to read the Solution."); return(null); } } } else { m.Warn($"File '{solutionPath}' not found. Creating an empty solution."); } return(s); } }
static Branch DoGetBranch(IActivityMonitor m, Repository r, string branchName, bool logErrorMissingLocalAndRemote, string repoDisplayName) { var b = r.Branches[branchName]; if (b == null) { string remoteName = "origin/" + branchName; var remote = r.Branches[remoteName]; if (remote == null) { var msg = $"Repository '{repoDisplayName}': Both local '{branchName}' and remote '{remoteName}' not found."; if (logErrorMissingLocalAndRemote) { m.Error(msg); } else { m.Warn(msg); } return(null); } m.Info($"Creating local branch on remote '{remoteName}' in repository '{repoDisplayName}'."); b = r.Branches.Add(branchName, remote.Tip); b = r.Branches.Update(b, u => u.TrackedBranch = remote.CanonicalName); } return(b); }
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); } }
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."); }
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." ); }
/// <summary> /// May be modified to enforce constraints on the passphrase. /// Currently only requires it to be not null nor empty. /// </summary> static bool CheckPassPhraseConstraints(IActivityMonitor m, string passPhrase) { if (String.IsNullOrEmpty(passPhrase)) { m.Warn("Invalid pass phrase."); return(false); } return(true); }
internal void ReadWorlds(IActivityMonitor m, StackInitializeOption option, Action <LocalWorldName> addWorld) { if (option == StackInitializeOption.OpenRepository) { EnsureOpen(m); } else if (option == StackInitializeOption.OpenAndPullRepository) { Pull(m); } if (!IsOpen) { m.Warn($"Repository '{OriginUrl}' for stacks '{_stacks.Select( s => s.StackName ).Concatenate("', '")}' is not opened. Skipping Worlds reading from them."); return; } var worldNames = Directory.GetFiles(Root, "*.World.xml") .Select(p => LocalWorldName.TryParse(m, p, _store.WorldLocalMapping)) .Where(w => w != null) .ToList(); var missing = _stacks .Where(s => !worldNames.Any(w => w.FullName.Equals(s.StackName, StringComparison.OrdinalIgnoreCase))); foreach (var s in missing) { m.Warn($"Unable to find xml file definition for '{s.StackName}'."); } for (int i = 0; i < worldNames.Count; ++i) { var w = worldNames[i]; if (w.ParallelName == null && !_stacks.Any(s => s.StackName.Equals(w.FullName, StringComparison.OrdinalIgnoreCase))) { m.Warn($"Unexpected '{w.FullName}' stack found. It is ignored."); worldNames.RemoveAt(i--); } else { addWorld(w); } } }
public void ApplySettings(IActivityMonitor m) { if (!_f.EnsureDirectory(m)) { return; } var s = _driver.GetSolution(m, allowInvalidSolution: true); if (s == null) { return; } if (_driver.BuildRequiredSecrets.Count == 0) { m.Warn("No build secrets collected for this solution. Skipping KeyVault configuration."); return; } var passPhrase = _secretStore.GetSecretKey(m, SolutionDriver.CODECAKEBUILDER_SECRET_KEY, true); // Opens the actual current vault: if more secrets are defined we keep them. Dictionary <string, string> current = KeyVault.DecryptValues(TextContent, passPhrase); current.Clear(); // The central CICDKeyVault is protected with the same CODECAKEBUILDER_SECRET_KEY secret. Dictionary <string, string> centralized = KeyVault.DecryptValues(_sharedState.CICDKeyVault, passPhrase); bool complete = true; foreach (var name in _driver.BuildRequiredSecrets.Select(x => x.SecretKeyName)) { if (!centralized.TryGetValue(name, out var secret)) { m.Error($"Missing required build secret '{name}' in central CICDKeyVault. It must be added."); complete = false; } else { current[name] = secret; } } if (complete) { Updating?.Invoke(this, new CodeCakeBuilderKeyVaultUpdatingArgs(m, _solutionSpec, s, current)); string result = KeyVault.EncryptValuesToString(current, passPhrase); CreateOrUpdate(m, result); } }
public void Setup(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); var variables = currentVariables?.Select(v => (v.Name, Environment.ExpandEnvironmentVariables(v.Value))).ToList() ?? new List <(string Name, string)>(); variables.Add(("CKLI_WORLD_MAPPING", _fileSystem.Root)); System.IO.File.WriteAllText(tempPS1.Path, script.Script); if (!ProcessRunner.RunPowerShell( monitor, script.WorkingDir, tempPS1.Path, new[] { script.Arguments }, stdErrorLevel: LogLevel.Warn, variables)) { hasError |= !script.ContinueOnNonZeroExitCode; if (!hasError) { monitor.Warn("ContinueOnNonZeroExitCode is true: error is ignored."); } } } break; } } } } }
/// <summary> /// Overridden to match [assembly: CK.StObj.Signature( "..." )] SHA1 attribute in the first line. /// </summary> /// <param name="monitor"></param> /// <returns></returns> protected override SHA1Value DoGetSignature(IActivityMonitor monitor) { var firstLine = SafeReadFirstLine(monitor, Path); if (firstLine != null) { var m = Regex.Match(firstLine, @"\s*\[\s*assembly\s*:\s*CK.StObj.Signature\s*\(\s*@?""(?<1>.*?)"""); if (m.Success && SHA1Value.TryParse(m.Groups[1].Value, out var signature)) { return(signature); } } monitor.Warn($"Unable to read [assembly: CK.StObj.Signature( \"...\" )] attribute from '{Path}'."); return(SHA1Value.Zero); }
protected virtual void SetGeneralizationInfo(IActivityMonitor monitor, CovariantPropertyInfo gen) { // Covariance ? if (PropertyType != gen.PropertyType && !gen.PropertyType.IsAssignableFrom(PropertyType)) { monitor.Error($"Property '{DeclaringType.FullName}.{Name}' type is not compatible with base property '{gen.DeclaringType.FullName}.{Name}'."); } else if (_p.GetSetMethod(true) != null) { monitor.Warn($"Property '{DeclaringType.FullName}.{Name}' should not have a setter (there should only be a getter that casts the base property)."); } // Propagates the top first definer level. _definerSpecializationDepth = gen.DefinerSpecializationDepth; _settablePropertyInfo = gen._settablePropertyInfo; }
public void DeleteStackDefinition(IActivityMonitor m, string stackName) { int idx = _stacks.IndexOf(d => d.StackName.Equals(stackName, StringComparison.OrdinalIgnoreCase)); if (idx < 0) { m.Warn($"Stack named '{stackName}' not found."); } else { m.Info($"Removing: '{_stacks[idx]}'."); _stacks.RemoveAt(idx); UpdateReposFromDefinitions(m, StackInitializeOption.None); } }
/// <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> /// Helper that reads the first line of a text file. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="path">The file path.</param> /// <returns>The first line or null on error.</returns> public static string?SafeReadFirstLine(IActivityMonitor monitor, NormalizedPath path) { try { using (var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var r = new StreamReader(s)) { return(r.ReadLine()); } } catch (Exception ex) { monitor.Warn($"Unable to read the first line from '{path}'.", ex); } 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); }
// 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."); } }
static void DumpMonitorOutput( IActivityMonitor monitor ) { Exception exception1; Exception exception2; try { throw new InvalidOperationException( "Exception!" ); } catch( Exception e ) { exception1 = e; } try { throw new InvalidOperationException( "Inception!", exception1 ); } catch( Exception e ) { exception2 = e; } for( int i = 0; i < 5; i++ ) { using( monitor.OpenTrace().Send( "Dump output loop {0}", i ) ) { for( int j = 0; j < 1000; j++ ) { monitor.Trace().Send( "Trace log! {0}", j ); monitor.Info().Send( "Info log! {0}", j ); monitor.Warn().Send( "Warn log! {0}", j ); monitor.Error().Send( "Error log! {0}", j ); monitor.Error().Send( "Fatal log! {0}", j ); monitor.Error().Send( exception2, "Exception log! {0}", j ); } } } }
public static void ReplayLogs( DirectoryInfo directory, bool recurse, Func<MultiLogReader.Monitor, ActivityMonitor> monitorProvider, IActivityMonitor m = null ) { var reader = new MultiLogReader(); using( m != null ? m.OpenTrace().Send( "Reading files from '{0}' {1}.", directory.FullName, recurse ? "(recursive)" : null ) : null ) { var files = reader.Add( directory.EnumerateFiles( "*.ckmon", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly ).Select( f => f.FullName ) ); if( files.Count == 0 ) { if( m != null ) m.Warn().Send( "No *.ckmon files found!" ); } else { var monitors = reader.GetActivityMap().Monitors; if( m != null ) { m.Trace().Send( String.Join( Environment.NewLine, files ) ); m.CloseGroup( String.Format( "Found {0} file(s) containing {1} monitor(s).", files.Count, monitors.Count ) ); m.OpenTrace().Send( "Extracting entries." ); } foreach( var mon in monitors ) { var replay = monitorProvider( mon ); if( replay == null ) { if( m != null ) m.Info().Send( "Skipping activity from '{0}'.", mon.MonitorId ); } else { mon.Replay( replay, m ); } } } } }
/// <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; }
bool DoSomething( IActivityMonitor m, FileInfo file ) { using( m.OpenInfo().Send( "Do something important on file '{0}'.", file.Name ) ) { if( !file.Exists ) { m.Warn().Send( "File does not exist." ); } else { m.Trace().Send( "File last modified at {1:T}. {0} Kb to process.", file.Length, file.LastWriteTimeUtc ); try { // ... Process file ... } catch( Exception ex ) { m.Error().Send( ex, "While processing." ); return false; } } m.SetTopic( "Changing my mind. Keeping it as-is." ); return true; } }