internal static StObjMapInfo?Create(IActivityMonitor m, Assembly a, CustomAttributeData attr) { try { object?v = attr.AttributeType.GetField("V", BindingFlags.Public | BindingFlags.Static)?.GetValue(null); if (v == null) { m.Error($"Unable to retrieve the CK.StObj.Signature assembly attribute from '{a.FullName}'."); } else { (SHA1Value, IReadOnlyList <string>)s = ((SHA1Value, IReadOnlyList <string>))v; Type?t = a.GetType(StObjContextRoot.RootContextTypeFullName, false, false); if (t == null) { m.Error($"Unable to retrieve the generated {StObjContextRoot.RootContextTypeFullName} type from '{a.FullName}'."); } else { var r = new StObjMapInfo(s.Item1, s.Item2, t); m.Info($"Found StObjMap: {r}."); return(r); } } } catch (Exception ex) { m.Error("Unable to read StObjMap information.", ex); } return(null); }
/// <summary> /// Pushes a version lightweight tag to the 'origin' remote. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="v">The version to push.</param> /// <returns>True on success, false on error.</returns> public bool PushVersionTag(IActivityMonitor m, SVersion v) { var sv = 'v' + v.ToString(); using (m.OpenInfo($"Pushing tag {sv} to remote for {SubPath}.")) { try { Remote remote = Git.Network.Remotes["origin"]; var options = new PushOptions() { CredentialsProvider = (url, user, cred) => ProtoGitFolder.PATCredentialsHandler(m) }; var exists = Git.Tags[sv]; if (exists == null) { m.Error($"Version Tag {sv} does not exist in {SubPath}."); return(false); } Git.Network.Push(remote, exists.CanonicalName, options); return(true); } catch (Exception ex) { m.Error($"PushVersionTags failed ({sv} on {SubPath}).", ex); return(false); } } }
IFileInfo GetWritableDestination(IActivityMonitor m, ref NormalizedPath destination) { destination = destination.ResolveDots(); if (destination.IsEmptyPath) { throw new ArgumentNullException(nameof(destination)); } var fDest = GetFileInfo(destination); if (fDest.Exists && fDest.IsDirectory) { m.Error($"Cannot replace a folder '{destination}' by a file content."); fDest = null; } if (fDest.PhysicalPath == null) { m.Error($"Destination file '{destination}' is not writable."); fDest = null; } if (fDest != null) { string dir = Path.GetDirectoryName(fDest.PhysicalPath); if (!Directory.Exists(dir)) { m.Trace($"Creating directory '{dir}'."); Directory.CreateDirectory(dir); } } return(fDest); }
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."); } } } }
/// <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); }
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> /// Initializes the Git folders: this instanciates the <see cref="GitFolder"/> from the /// <see cref="XGitFolder.ProtoGitFolder"/>. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <returns>The world on success, null on error.</returns> World IXTypedObjectProvider <World> .GetObject(IActivityMonitor m) { var proto = Parent.Descendants <XGitFolder>().Select(g => g.ProtoGitFolder).ToList(); List <GitFolder> gitFolders = new List <GitFolder>(); using (m.OpenInfo($"Initializing {proto.Count} Git folders.")) { try { foreach (var p in proto) { var g = _fileSystem.EnsureGitFolder(m, p); if (g != null) { gitFolders.Add(g); } else { m.Error($"GitFolder creation failed for {p.FolderPath}."); return(null); } } DumpGitFolders(m, gitFolders); return(_world); } catch (Exception ex) { m.Error(ex); return(null); } } }
public bool SetWorldMapping(IActivityMonitor m, string worldFullName, NormalizedPath mappedPath) { var worlds = ReadWorlds(m); if (worlds == null) { return(false); } var w = worlds.FirstOrDefault(x => x.FullName.Equals(worldFullName, StringComparison.OrdinalIgnoreCase)); if (w == null) { m.Error($"World '{worldFullName}' not found."); return(false); } if (w.Root == mappedPath) { m.Trace($"World '{w.FullName}' is already mapped to '{w.Root}'."); return(true); } if (!mappedPath.IsRooted) { m.Error($"Invalid '{mappedPath}'. It must be rooted."); return(false); } if (!WorldLocalMapping.SetMap(m, w.FullName, mappedPath)) { return(true); } m.Info($"World '{w.FullName}' is now mapped to '{mappedPath}'."); ReadWorlds(m, false); 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); }
/// <summary> /// Tries to parse a xml World definition file name. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="path">The file path.</param> /// <param name="localMap">The mapper to use.</param> /// <returns>The name or null on error.</returns> public static LocalWorldName TryParse(IActivityMonitor m, NormalizedPath path, IWorldLocalMapping localMap) { if (path.IsEmptyPath || !path.LastPart.EndsWith(".World.xml", StringComparison.OrdinalIgnoreCase)) { m.Error($"Path must end with '.World.xml': '{path}'"); return(null); } try { var fName = path.LastPart; Debug.Assert(".World.xml".Length == 10); fName = fName.Substring(0, fName.Length - 10); int idx = fName.IndexOf('['); if (idx < 0) { return(new LocalWorldName(path, fName, null, localMap)); } int paraLength = fName.IndexOf(']') - idx - 1; return(new LocalWorldName(path, fName.Substring(0, idx), fName.Substring(idx + 1, paraLength), localMap)); } catch (Exception ex) { m.Error($"While parsing file path: {path}.", ex); return(null); } }
/// <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); } }
public bool Execute(IActivityMonitor m, Func <bool> onError) { bool trampolineSuccess = true; int i = 0; using (m.OpenInfo($"Executing initial {_postActions.Count} deferred actions.") .ConcludeWith(() => $"Executed {i} actions.")) { while (i < _postActions.Count) { var a = _postActions[i]; Debug.Assert(a != null); _postActions[i++] = null; try { if (!a(m, _holder)) { m.Error("A deferred action failed."); trampolineSuccess = onError(); } } catch (Exception ex) { m.Error(ex); trampolineSuccess = onError(); } } _postActions.Clear(); } return(trampolineSuccess); }
/// <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.Error("The configured path is empty."); } else if (FileUtil.IndexOfInvalidPathChars(_configPath) >= 0) { m.Error($"The configured path '{_configPath}' is invalid."); } else { rootPath = _configPath; if (!Path.IsPathRooted(rootPath)) { string?rootLogPath = LogFile.RootLogPath; if (String.IsNullOrWhiteSpace(rootLogPath)) { m.Error($"The relative path '{_configPath}' requires that LogFile.RootLogPath be specified."); } else { rootPath = Path.Combine(rootLogPath, _configPath); } } } return(rootPath != null?FileUtil.NormalizePathSeparator(rootPath, true) : null); }
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; }
/// <summary> /// Ensures that a path is a directory, creating it as necessary (if /// the path is writable). /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="dir">The target path in this file system.</param> /// <returns>True on success, false on error.</returns> public bool EnsureDirectory(IActivityMonitor m, NormalizedPath dir) { dir = dir.ResolveDots(); if (dir.IsEmptyPath) { throw new ArgumentNullException(nameof(dir)); } var p = GetFileInfo(dir); if (!p.Exists) { if (p.PhysicalPath == null) { m.Error($"Directory path '{dir}' is not writable."); return(false); } if (!Directory.Exists(p.PhysicalPath)) { m.Trace($"Creating directory '{p.PhysicalPath}'."); Directory.CreateDirectory(p.PhysicalPath); } } else if (!p.IsDirectory) { m.Error($"Path '{dir}' is a file. Cannot transform it into a directory."); return(false); } return(true); }
void CheckStObjProperties(IActivityMonitor monitor, BuildValueCollector valueCollector) { if (_stObjProperties == null) { return; } foreach (StObjProperty p in _stObjProperties) { if (p.InfoOnType == null || p.InfoOnType.ResolutionSource == PropertyResolutionSource.FromContainerAndThenGeneralization) { // Check the Type constraint that could potentially hurt one day. bool containerHasSetOrMerged = IsOwnContainer && HandleStObjPropertySource(monitor, p, _dContainer !, "Container", true); if (Generalization != null) { HandleStObjPropertySource(monitor, p, Generalization, "Generalization", !containerHasSetOrMerged); } } else if (p.InfoOnType.ResolutionSource == PropertyResolutionSource.FromGeneralizationAndThenContainer) { // Check the Type constraint that could potentially hurt one day. bool generalizationHasSetOrMerged = Generalization != null && HandleStObjPropertySource(monitor, p, Generalization, "Generalization", true); if (IsOwnContainer) { HandleStObjPropertySource(monitor, p, _dContainer !, "Container", !generalizationHasSetOrMerged); } } // If the value is missing (it has never been set or has been explicitly "removed"), we have nothing to do. // If the type is not constrained, we have nothing to do. object v = p.Value; if (v != System.Type.Missing) { bool setIt = p.HasStructuredObjectProperty; if (p.Type != typeof(object)) { if (v == null) { if (p.Type.IsValueType && !(p.Type.IsGenericType && p.Type.GetGenericTypeDefinition() == typeof(Nullable <>))) { monitor.Error($"StObjProperty '{ToString()}.{p.Name}' has been set to null but its type '{p.Type.Name}' is not nullable."); setIt = false; } } else { if (!p.Type.IsAssignableFrom(v.GetType())) { monitor.Error($"StObjProperty '{ToString()}.{p.Name}' is of type '{p.Type.Name}', but a value of type '{v.GetType()}' has been set."); setIt = false; } } } if (setIt) { Debug.Assert(p.InfoOnType != null); AddPreConstructProperty(p.InfoOnType.PropertyInfo, v, valueCollector); } } } }
/// <summary> /// Merges the types. Returns false if and only if CanBeExtended conflicts. /// </summary> public bool AddUnionPropertyTypes(IActivityMonitor monitor, List <NullableTypeTree> types, bool typesCanBeExtended) { Debug.Assert(types.Count > 0); if (_unionTypes == null) { _unionTypes = types; _unionTypesCanBeExtended = typesCanBeExtended; return(true); } bool success = true; List <NullableTypeTree>?extended = null; foreach (var t in types) { if (!_unionTypes.Contains(t)) { if (!_unionTypesCanBeExtended) { monitor.Error($"Existing union type cannot be extended. Type '{t}' is a new one (existing types are: '{_unionTypes.Select( t => t.ToString() ).Concatenate( "', '" )}')."); success = false; } else { if (extended == null) { extended = _unionTypes as List <NullableTypeTree> ?? new List <NullableTypeTree>(_unionTypes); } extended.Add(t); } } } if (success) { if (!typesCanBeExtended) { _unionTypesCanBeExtended = false; foreach (var t in _unionTypes) { if (!types.Contains(t)) { monitor.Error($"Current union type definition cannot be extended. Existing union type defines type '{t}' that is not defined by these union types '{types.Select( t => t.ToString() ).Concatenate( "', '" )}')."); success = false; } } } if (success && extended != null) { _unionTypes = extended; } } return(success); }
/// <summary> /// Logs potential errors. Returns true if no error occured, false on error. /// </summary> /// <param name="m"></param> /// <param name="res"></param> /// <returns>True on success, false on error.</returns> async Task <bool> LogErrors(IActivityMonitor m, HttpResponseMessage res) { if (res.StatusCode == HttpStatusCode.Unauthorized) { using (m.OpenError("Unauthorized Status Code")) { if (res.Headers.Contains("www-authenticate")) { List <string> auth = res.Headers.GetValues("www-authenticate").ToList(); if (auth.Contains("ipaddress")) { m.Error("Login is not allowed from your IP address"); } else if (auth.Contains("otp")) { m.Error("OTP required for authentication"); } else { m.Error("Unable to authenticate, need: " + string.Join(", ", auth)); } } else { if ((await res.Content.ReadAsStringAsync()).Contains("one-time pass")) { m.Error("OTP required for authentication."); } else { m.Error("Unknown error."); } } } return(false); } if (!res.IsSuccessStatusCode) { using (m.OpenError($"Response status code is not a success code: '{res.ReasonPhrase}'.")) { m.Trace(await res.Content.ReadAsStringAsync()); } return(false); } else { m.Debug("Response status code is a success status code."); } return(true); }
static SVersion SafeParse(IActivityMonitor m, string path) { SVersion v = null; int idx = path.LastIndexOf(System.IO.Path.DirectorySeparatorChar); if (idx < 0) { m.Error($"Invalid path '{path}' for package."); } else if (!(v = SVersion.TryParse(path.Substring(idx))).IsValid) { m.Error($"Invalid SemVer in '{path}' for package."); } return(v); }
/// <summary> /// Appends an enum definition. The underlying type should be safely convertible into Int32. /// </summary> /// <typeparam name="T">Actual type of the code writer.</typeparam> /// <param name="this">This code writer.</param> /// <param name="monitor">The monitor to use.</param> /// <param name="enumType">The enum type.</param> /// <param name="typeName">Teh TypeScript type name.</param> /// <returns>This code writer to enable fluent syntax.</returns> static public T AppendEnumDefinition <T>(this T @this, IActivityMonitor monitor, Type enumType, string typeName) where T : ITSCodeWriter { if (!enumType.IsEnum) { throw new ArgumentException($"Must be an enum: {enumType.Name}.", nameof(enumType)); } var uT = enumType.GetEnumUnderlyingType(); if (uT == typeof(UInt32) || uT == typeof(Int64) || uT == typeof(UInt64)) { monitor.Error($"Enum: {enumType.Name} cannot be generated as TypeScript since it is based on {uT.Name} type. Only types that can be safely converted into Int32 should be used."); return(@this); } return(@this.Append("enum ").Append(typeName) .OpenBlock() .Append(b => { string[] names = Enum.GetNames(enumType); int[] values = Enum.GetValues(enumType).Cast <object>().Select(x => Convert.ToInt32(x)).ToArray(); for (int i = 0; i < names.Length; ++i) { if (i > 0) { b.Append(",").NewLine(); } b.Append(names[i]).Append(" = ").Append(values[i]); } }) .CloseBlock()); }
private static bool DoBuild( IActivityMonitor m, ISolutionDriver driver, CSVersion targetVersion, out bool tagCreated) { tagCreated = false; try { var git = driver.GitRepository; if (targetVersion.PackageQuality == PackageQuality.Release) { if (!git.SwitchDevelopToMaster(m)) { return(false); } driver = driver.GetCurrentBranchDriver(); } if (!git.SetVersionTag(m, targetVersion)) { return(false); } tagCreated = true; if (!driver.Build(m, withUnitTest: true, withZeroBuilder: true, withPushToRemote: false)) { return(false); } return(true); } catch (Exception ex) { m.Error("Build failed.", ex); return(false); } }
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); }
/// <summary> /// Creates a ZeroBuilder. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="feeds">The local feeds.</param> /// <param name="depContext">The dependency context to consider.</param> /// <param name="driverFinder">The driver finder by solution name.</param> /// <param name="solutionReloader">Optional solutions reloader.</param> /// <returns>The ZeroBuilder on success, null on error.</returns> static ZeroBuilder Create( IActivityMonitor m, IEnvLocalFeedProvider feeds, IWorldSolutionContext context) { if (context.DependencyContext.BuildProjectsInfo.HasError) { using (m.OpenError("Build Projects dependencies failed to be computed.")) { context.DependencyContext.BuildProjectsInfo.RawBuildProjectsInfoSorterResult.LogError(m); } return(null); } var zeroProjects = context.DependencyContext.BuildProjectsInfo.ZeroBuildProjects; if (zeroProjects.Count == 0) { m.Error(context.DependencyContext.HasError ? "Invalid dependency analysis." : "No Build Project exist."); return(null); } var mustBuild = new HashSet <string>(zeroProjects.Select(p => p.Project.FullFolderPath.Path)); var memPath = feeds.ZeroBuild.PhysicalPath.AppendPart("CacheZeroVersion.txt"); var sha1Cache = System.IO.File.Exists(memPath) ? System.IO.File.ReadAllLines(memPath) .Select(l => l.Split()) .Where(l => mustBuild.Contains(l[0])) .ToDictionary(l => l[0], l => new HashSet <string>(l[1].Split('|'))) : new Dictionary <string, HashSet <string> >(); m.Info($"File '{memPath}' contains {sha1Cache.Count} entries."); var currentShas = new string[zeroProjects.Count]; return(new ZeroBuilder(feeds, memPath, sha1Cache, mustBuild, context)); }
/// <summary> /// Synchronizes these <see cref="PackageJsonFile.Dependencies"/> that are <see cref="NPMVersionDependencyType.LocalPath"/> /// to the associated <see cref="DependencyModel.Project"/> instance's <see cref="IProject.ProjectReferences"/>. /// </summary> /// <param name="m">The monitor to use.</param> internal bool SynchronizeProjectReferences(IActivityMonitor m) { var toRemove = new HashSet <IProject>(_project.ProjectReferences.Select(r => r.Target)); foreach (var dep in PackageJson.Dependencies) { if (dep.Type == NPMVersionDependencyType.LocalPath) { var path = _project.SolutionRelativeFolderPath.Combine(dep.RawDep.Substring("file:".Length)); var mapped = _project.Solution.Projects.FirstOrDefault(d => d.SolutionRelativeFolderPath == path.ResolveDots() && d.Type == "js"); if (mapped == null) { m.Error($"Unable to resolve local reference to project '{dep.RawDep}' in {PackageJson}."); return(false); } _project.EnsureProjectReference(mapped, dep.Kind); toRemove.Remove(mapped); } } foreach (var noMore in toRemove) { _project.RemoveProjectReference(noMore); } return(true); }
MSProjFile ReloadProjectFile(FileSystem fs, IActivityMonitor m, Dictionary <NormalizedPath, MSProjFile> cache) { _file = MSProjFile.FindOrLoadProjectFile(fs, m, Path, cache); if (_file != null) { XElement f = _file.Document.Root .Elements("PropertyGroup") .Elements() .Where(x => x.Name.LocalName == "TargetFramework" || x.Name.LocalName == "TargetFrameworks") .SingleOrDefault(); if (f == null) { m.Error($"There must be one and only one TargetFramework or TargetFrameworks element in {Path}."); _file = null; } else { TargetFrameworks = Savors.FindOrCreate(f.Value); LangVersion = _file.Document.Root.Elements("PropertyGroup").Elements("LangVersion").LastOrDefault()?.Value; OutputType = _file.Document.Root.Elements("PropertyGroup").Elements("OutputType").LastOrDefault()?.Value; IsPackable = (bool?)_file.Document.Root.Elements("PropertyGroup").Elements("IsPackable").LastOrDefault(); DoInitializeDependencies(m); if (!_dependencies.IsInitialized) { _file = null; } } } if (_file == null) { TargetFrameworks = Savors.EmptyTrait; } return(_file); }
public void Execute(IActivityMonitor m, object payload) { using (m.OpenTrace($"Executing {UniqueName}.")) { try { if (PayloadSignature != null) { if (!(payload is SimplePayload simple) || simple.Fields.Count != _parameters.Length - 1) { throw new ArgumentException(nameof(payload)); } var p = new object[_parameters.Length]; p[0] = m; for (int i = 0; i < simple.Fields.Count; ++i) { p[i + 1] = simple.Fields[i].GetValue(); } _method.Invoke(_instance, p); } else { _method.Invoke(_instance, new[] { m }); } } catch (Exception ex) { m.Error(ex); } } }
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> /// Deletes a file or folder. It must be physically accessible /// (<see cref="IFileInfo.PhysicalPath"/> must not be null): if inside a <see cref="GitFolder"/>, it must /// be a in the current head (ie. corresponds to a file in the current working directory). /// </summary> /// <param name="m">The monitor.</param> /// <param name="subPath">The item path to delete.</param> /// <returns>True on success, false on error (error is logged into the monitor).</returns> public bool Delete(IActivityMonitor m, NormalizedPath subPath) { IFileInfo info = GetFileInfo(subPath); if (info.Exists) { if (info.PhysicalPath == null) { m.Error($"'{subPath}' to delete is not physically available."); return(false); } try { if (info.IsDirectory) { m.Info($"Deleting folder '{subPath}'."); FileHelper.RawDeleteLocalDirectory(m, info.PhysicalPath); } else { m.Info($"Deleting file '{subPath}'."); File.Delete(info.PhysicalPath); } } catch (Exception ex) { m.Fatal(ex); return(false); } } return(true); }
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); }
/// <summary> /// Copy a text content to a <paramref name="destination"/> path in this /// file system. /// The destination must not be an existing folder and must be physically accessible /// (<see cref="IFileInfo.PhysicalPath"/> must not be null): if inside a <see cref="GitFolder"/>, it must /// be a in the current head (ie. corresponds to a file in the current working directory). /// </summary> /// <param name="m">The activity monitor.</param> /// <param name="content">The content text.</param> /// <param name="destination">The target path in this file system.</param> /// <returns>True on success, false on error.</returns> public bool CopyTo(IActivityMonitor m, string content, NormalizedPath destination, Encoding encoding = null) { if (content == null) { throw new ArgumentNullException(nameof(content)); } var fDest = GetWritableDestination(m, ref destination); if (fDest == null) { return(false); } using (m.OpenInfo($"{(fDest.Exists ? "Replacing" : "Creating")} {destination}.")) { try { if (encoding == null) { File.WriteAllText(fDest.PhysicalPath, content); } else { File.WriteAllText(fDest.PhysicalPath, content, encoding); } return(true); } catch (Exception ex) { m.Error(ex); return(false); } } }
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." ); }
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; } }
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 ); } } } }