private void DeployWebResource(WebResourceFile webResourceFile, int current, int totalWebResources) { var len = totalWebResources.ToString().Length; if (webResourceFile.uniquename.StartsWith("/")) { webResourceFile.uniquename = webResourceFile.uniquename.Substring(1); } var fetchData = new { name = webResourceFile.uniquename, name2 = webResourceFile.uniquename.Substring(0, webResourceFile.uniquename.LastIndexOf('.')) }; var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='content' /> <attribute name='webresourceid' /> <attribute name='name' /> <attribute name='iscustomizable' /> <attribute name='ismanaged' /> <filter type='or'> <condition attribute='name' operator='eq' value='{fetchData.name}'/> <condition attribute='name' operator='eq' value='{fetchData.name2}'/> </filter> </entity> </fetch>"; var rows = crmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); var content = string.Empty; var webResourceId = Guid.Empty; if (rows.Entities.Count > 0) { if (rows.Entities.Count == 1) { var entity = rows.Entities[0]; var ismanaged = entity.GetAttributeValue <bool?>("ismanaged"); var iscustomizable = entity.GetAttributeValue <BooleanManagedProperty>("iscustomizable"); if (ismanaged.HasValue && ismanaged.Value == true) { if (iscustomizable?.Value == false) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + len + "}", "", current) + ": ", CliLog.ColorRed, "Update webresource failed because the setting webresource.iscustomizable = false - ", CliLog.ColorGreen, webResourceFile.uniquename); return; } } webResourceId = entity.Id; content = entity?["content"]?.ToString(); } else { foreach (var entity in rows.Entities) { if (entity.GetAttributeValue <string>("name") != fetchData.name) { continue; } var ismanaged = entity.GetAttributeValue <bool?>("ismanaged"); var iscustomizable = entity.GetAttributeValue <BooleanManagedProperty>("iscustomizable"); if (ismanaged.HasValue && ismanaged.Value == true) { if (iscustomizable?.Value == false) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + len + "}", "", current) + ": ", CliLog.ColorRed, "Update webresource failed because the setting webresource.iscustomizable = false - ", CliLog.ColorGreen, webResourceFile.uniquename); return; } } webResourceId = entity.Id; content = entity?["content"]?.ToString(); break; } } } var fileContent = Convert.ToBase64String(File.ReadAllBytes(webResourceFile.file)); if (fileContent == content) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorBlue, string.Format("{0,0}{1," + len + "}", "", current) + ": ", CliLog.ColorGreen, webResourceFile.file.Substring(currentDirectory.Length + 1)); AddWebResourceToSolution(new Entity("webresource") { ["name"] = webResourceFile.uniquename, ["webresourceid"] = webResourceId }); return; } var webResource = new Entity("webresource") { ["name"] = webResourceFile.uniquename, ["displayname"] = webResourceFile.displayname, ["description"] = webResourceFile.version, ["content"] = fileContent }; var webResourceFileInfo = new FileInfo(webResourceFile.file); var fileType = WebResourceWebResourceType.ScriptJScript; switch (webResourceFileInfo.Extension.ToLower().TrimStart('.')) { case "html": case "htm": fileType = WebResourceWebResourceType.WebpageHtml; break; case "js": fileType = WebResourceWebResourceType.ScriptJScript; break; case "png": fileType = WebResourceWebResourceType.PngFormat; break; case "gif": fileType = WebResourceWebResourceType.GifFormat; break; case "jpg": case "jpeg": fileType = WebResourceWebResourceType.JpgFormat; break; case "css": fileType = WebResourceWebResourceType.StyleSheetCss; break; case "ico": fileType = WebResourceWebResourceType.IcoFormat; break; case "xml": fileType = WebResourceWebResourceType.DataXml; break; case "xsl": case "xslt": fileType = WebResourceWebResourceType.StyleSheetXsl; break; case "xap": fileType = WebResourceWebResourceType.SilverlightXap; break; case "resx": fileType = WebResourceWebResourceType.StringResx; break; case "svg": fileType = WebResourceWebResourceType.SvgFormat; break; } webResource["webresourcetype"] = new OptionSetValue((int)fileType); if (fileType == WebResourceWebResourceType.StringResx) { var fileName = webResourceFileInfo.Name.Substring(0, webResourceFileInfo.Name.Length - webResourceFileInfo.Extension.Length); var arr = fileName.Split(".".ToCharArray()); if (int.TryParse(arr[arr.Length - 1], out var languagecode)) { var req = new RetrieveProvisionedLanguagesRequest(); var res = (RetrieveProvisionedLanguagesResponse)crmServiceClient.Execute(req); if (res.RetrieveProvisionedLanguages.Contains(languagecode)) { webResource["languagecode"] = languagecode; } else { throw new Exception($"Language code not found: {languagecode}"); } } } if (webResourceId == Guid.Empty) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorBlue, string.Format("{0,0}{1," + len + "}", "", current), ": ", CliLog.ColorMagenta, "Creating", CliLog.ColorGreen, " WebResource ", CliLog.ColorCyan, webResourceFile.file, CliLog.ColorGreen, " to ", CliLog.ColorCyan, webResourceFile.uniquename); webResourceId = crmServiceClient.Create(webResource); webResource["webresourceid"] = webResourceId; } else { webResource["webresourceid"] = webResourceId; CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorBlue, string.Format("{0,0}{1," + len + "}", "", current), ": ", CliLog.ColorMagenta, "Updating", CliLog.ColorGreen, " WebResource ", CliLog.ColorCyan, webResourceFile.file, CliLog.ColorGreen, " to ", CliLog.ColorCyan, webResourceFile.uniquename); crmServiceClient.Update(webResource); } WebResourcesToPublish.Add(webResourceId); AddWebResourceToSolution(webResource); }
private Entity RegisterAssembly(FileSystemInfo assemblyFilePath, Assembly assembly, IEnumerable <Type> workflowTypes) { var firstType = GetAttributes(workflowTypes, typeof(CrmPluginRegistrationAttribute).Name).FirstOrDefault(); if (firstType == null) { CliLog.WriteLine(); CliLog.WriteLine(); CliLog.WriteLine(ConsoleColor.Green, $"{LOG} Plugin Assembly don't have any type: CrmPluginRegistration Attribute"); CliLog.WriteLine(); CliLog.WriteLine(); CliLog.WriteLine(ConsoleColor.Red, "!!! DEPLOY PLUGIN FAILED !!!"); throw new Exception(); } var firstTypeAttribute = firstType.CreateFromData(); var assemblyProperties = assembly.GetName().FullName .Split(",= ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var fetchData = new { name = assemblyProperties[0] }; var fetchXml = $@" <fetch> <entity name='pluginassembly'> <attribute name='pluginassemblyid' /> <attribute name='content' /> <filter type='and'> <condition attribute='name' operator='eq' value='{fetchData.name}'/> </filter> </entity> </fetch>"; var rows = crmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); var pluginAssemblyId = Guid.Empty; var existingContent = string.Empty; if (rows.Entities.Count > 0) { var entity = rows.Entities[0]; pluginAssemblyId = entity.Id; existingContent = entity.GetAttributeValue <string>("content"); } var content = Convert.ToBase64String(File.ReadAllBytes(assemblyFilePath.FullName)); if (content == existingContent) { return(null); } var plugin = new Entity("pluginassembly") { ["content"] = content, ["name"] = assemblyProperties[0], ["culture"] = assemblyProperties[4], ["version"] = assemblyProperties[2], ["publickeytoken"] = assemblyProperties[6], ["sourcetype"] = new OptionSetValue(0), ["isolationmode"] = firstTypeAttribute.IsolationMode == IsolationModeEnum.Sandbox ? new OptionSetValue(2) : new OptionSetValue(1) }; if (pluginAssemblyId == Guid.Empty) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorRed, "Registering", CliLog.ColorGreen, " Assembly: ", CliLog.ColorCyan, $"{assemblyProperties[0]}"); pluginAssemblyId = crmServiceClient.Create(plugin); plugin["pluginassemblyid"] = pluginAssemblyId; } else { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorRed, "Updating", CliLog.ColorGreen, " Assembly: ", CliLog.ColorCyan, $"{assemblyProperties[0]}"); plugin["pluginassemblyid"] = pluginAssemblyId; try { crmServiceClient.Update(plugin); } catch (FaultException fe) { CliLog.WriteLine(); CliLog.WriteLine(); CliLog.WriteLine(ConsoleColor.White, fe.Message); CliLog.WriteLine(); CliLog.WriteLine(); CliLog.WriteLine(ConsoleColor.Red, "!!! DEPLOY WORKFLOW FAILED !!!"); throw; } } return(plugin); }
private void DownloadWebResources() { var fetchData = new { ismanaged = "0", iscustomizable = "1", uniquename = json.solution, name = json.prefix }; var fetchXml = string.Empty; if (json.solution.Length > 0) { fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <attribute name='webresourcetype' /> <attribute name='content' /> <filter type='and'> <condition attribute='iscustomizable' operator='eq' value='{fetchData.iscustomizable}'/> <condition attribute='ismanaged' operator='eq' value='{fetchData.ismanaged}'/> <condition attribute='name' operator='begins-with' value='{fetchData.name}'/> </filter> <order attribute='name' /> <link-entity name='solutioncomponent' from='objectid' to='webresourceid' link-type='inner' alias='sc'> <link-entity name='solution' from='solutionid' to='solutionid' link-type='inner' alias='s'> <filter type='and'> <condition attribute='uniquename' operator='eq' value='{fetchData.uniquename}'/> </filter> </link-entity> </link-entity> </entity> </fetch>"; } else { fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <attribute name='webresourcetype' /> <attribute name='content' /> <filter type='and'> <condition attribute='iscustomizable' operator='eq' value='{fetchData.iscustomizable}'/> <condition attribute='ismanaged' operator='eq' value='{fetchData.ismanaged}'/> </filter> <order attribute='name' /> </entity> </fetch>"; } var rows = crmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count == 0) { throw new Exception("Not found any webresources to download"); } var downloadFiles = DownloadFiles(rows.Entities); var totalDownloadWebResources = downloadFiles.Count; var len = totalDownloadWebResources.ToString().Length; CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, "Found: ", CliLog.ColorYellow, totalDownloadWebResources, CliLog.ColorGreen, " webresources"); foreach (var downloadFile in downloadFiles) { Utility.TryDeleteFile(downloadFile.FileName); } var i = 1; foreach (var downloadFile in downloadFiles) { var isOk = DownloadWebResourceFile(downloadFile, i, totalDownloadWebResources); if (isOk) { var shortFileName = downloadFile.FileName.Substring(currentDirectory.Length + 1); CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorCyan, string.Format("{0,0}{1," + len + "}", "", i) + ": ", CliLog.ColorWhite, "Downloaded ", CliLog.ColorGreen, downloadFile.Name, CliLog.ColorWhite, " to: ", CliLog.ColorGreen, shortFileName); } i++; } }
private static bool IsValid(CommandLineArgs arguments) { if (arguments.SdkLogin.Length > 0 && arguments.SdkLogin.ToLower() == "yes") { ; } else { if (arguments.Connection.Length == 0) { CliLog.WriteLine(CliLog.ColorError, $"/conn: missing"); return(false); } } if (arguments.Json.Length == 0) { CliLog.WriteLine(CliLog.ColorError, $"/json: missing"); return(false); } var jsonFile = Path.Combine(CurrentDirectory, arguments.Json); if (!File.Exists(jsonFile)) { CliLog.WriteLine(CliLog.ColorError, $"/json: DynamicsCrm.DevKit json missing [{jsonFile}]"); return(false); } if (arguments.Type.Length == 0) { CliLog.WriteLine(CliLog.ColorError, $"/type: missing"); return(false); } if (arguments.Profile.Length == 0) { CliLog.WriteLine(CliLog.ColorError, $"/profile: missing"); return(false); } if (arguments.SdkLogin.Length > 0 && arguments.SdkLogin.ToLower() == "yes") { if (arguments.Type.ToLower() != "proxytypes") { if (!IsConnectedDynamics365BySdkLogin()) { CliLog.WriteLine(CliLog.ColorError, $"SdkLogin failed !!!"); return(false); } } } else { if (!IsConnectedDynamics365(arguments.Connection)) { CliLog.WriteLine(CliLog.ColorError, $"/conn: Cannot connect to Dynamics 365 with your Connection String: {arguments.Connection}"); return(false); } } if (CrmServiceClient != null) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, "Connected: ", CliLog.ColorWhite, new Uri(CrmServiceClient.CrmConnectOrgUriActual.AbsoluteUri).GetLeftPart(UriPartial.Authority)); } CliLog.WriteLine(); return(true); }
private void GeneratorJsForm(string entity, int i, int count) { var forms = new List <string>(); var isDebugForm = true; var webApi = true; var isDebugWebApi = true; var fileTypeScriptDeclaration = $"{currentDirectory}\\{json.rootfolder}\\{entity}.d.ts"; if (File.Exists(fileTypeScriptDeclaration)) { var lines = File.ReadAllLines(fileTypeScriptDeclaration); if (lines.Count() != 0) { var json = lines[lines.Length - 1]; var comment = SimpleJson.DeserializeObject <CommentTypeScriptDeclaration>(json.Substring("//".Length).Replace("'", "\"")); forms = comment.JsForm; isDebugForm = comment.IsDebugForm; webApi = comment.JsWebApi; isDebugWebApi = comment.IsDebugWebApi; } } if (forms.Count == 0) { var parts2 = json.rootnamespace.Split(".".ToCharArray()); var projectName2 = parts2.Length > 1 ? parts2[1] : parts2[0]; var jsForm2 = new JsForm(crmServiceClient.OrganizationServiceProxy, projectName2, entity); forms = GetAllForms(entity, jsForm2); } if (forms.Count == 0) { return; } if (File.Exists($"{currentDirectory}\\{json.rootfolder}\\{entity}.js")) { var text = File.ReadAllText($"{currentDirectory}\\{json.rootfolder}\\{entity}.js"); text = text.Replace("\r\n", string.Empty); if (text.Length == 0 || text == $"//@ts-check///<reference path=\"{entity}.d.ts\" />") { Utility.TryDeleteFile($"{currentDirectory}\\{json.rootfolder}\\{entity}.js"); } } var parts = json.rootnamespace.Split(".".ToCharArray()); var projectName = parts.Length > 1 ? parts[1] : parts[0]; var jsForm = new JsForm(crmServiceClient.OrganizationServiceProxy, projectName, entity); if (json.debug.Length > 0) { isDebugForm = json.debug == "yes" ? true : false; } jsForm.GeneratorCode(forms, isDebugForm, webApi, isDebugWebApi); if (!File.Exists($"{currentDirectory}\\{json.rootfolder}\\{entity}.js")) { var text = jsForm.Form; text = text.Replace($"[[{entity}]]", $"{entity}.d.ts"); Utility.ForceWriteAllText($"{currentDirectory}\\{json.rootfolder}\\{entity}.js", text); } var old = string.Empty; if (File.Exists(fileTypeScriptDeclaration)) { old = File.ReadAllText(fileTypeScriptDeclaration).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); } var @new = jsForm.FormCodeTypeScriptDeclaration.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "Processing ", CliLog.ColorGreen, entity, ".d.ts"); Utility.ForceWriteAllText(fileTypeScriptDeclaration, jsForm.FormCodeTypeScriptDeclaration); } else { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "No change ", CliLog.ColorGreen, entity, ".d.ts"); } var fileForm = $"{currentDirectory}\\{json.rootfolder}\\{entity}.form.js"; old = string.Empty; if (File.Exists(fileForm)) { old = File.ReadAllText(fileForm).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); } @new = jsForm.FormCode.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "Processing ", CliLog.ColorGreen, entity, ".form.js"); Utility.ForceWriteAllText(fileForm, jsForm.FormCode); } else { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "No change ", CliLog.ColorGreen, entity, ".form.js"); } }
private void GeneratorJsWebApi(string entity, int i, int count) { var jsForm = new List <string>(); var isDebugForm = true; var isDebugWebApi = true; if (!File.Exists($"{currentDirectory}\\{json.rootfolder}\\{entity}.js")) { var text = string.Empty; text += "//@ts-check\r\n"; text += $"///<reference path=\"{entity}.d.ts\" />\r\n"; Utility.ForceWriteAllText($"{currentDirectory}\\{json.rootfolder}\\{entity}.js", text); } var fileTypeScriptDeclaration = $"{currentDirectory}\\{json.rootfolder}\\{entity}.d.ts"; if (File.Exists(fileTypeScriptDeclaration)) { var lines = File.ReadAllLines(fileTypeScriptDeclaration); if (lines.Count() != 0) { var json = lines[lines.Length - 1]; var comment = SimpleJson.DeserializeObject <CommentTypeScriptDeclaration>(json.Substring("//".Length).Replace("'", "\"")); isDebugWebApi = comment.IsDebugWebApi; jsForm = comment.JsForm; isDebugForm = comment.IsDebugForm; } } var parts = json.rootnamespace.Split(".".ToCharArray()); var projectName = parts.Length > 1 ? parts[1] : parts[0]; if (json.debug.Length > 0) { isDebugWebApi = json.debug == "yes" ? true : false; } var jsWebApi = new JsWebApi(crmServiceClient.OrganizationServiceProxy, projectName, entity, isDebugWebApi, jsForm, isDebugForm); jsWebApi.GeneratorCode(); var old = string.Empty; if (File.Exists(fileTypeScriptDeclaration)) { old = File.ReadAllText(fileTypeScriptDeclaration).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); } var @new = jsWebApi.WebApiCodeTypeScriptDeclaration.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "Processing ", CliLog.ColorGreen, entity, ".d.ts"); Utility.ForceWriteAllText(fileTypeScriptDeclaration, jsWebApi.WebApiCodeTypeScriptDeclaration); } else { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "No change ", CliLog.ColorGreen, entity, ".d.ts"); } var fileWebApi = $"{currentDirectory}\\{json.rootfolder}\\{entity}.webapi.js"; old = string.Empty; if (File.Exists(fileWebApi)) { old = File.ReadAllText(fileWebApi).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); } @new = jsWebApi.WebApiCode.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "Processing ", CliLog.ColorGreen, entity, ".webapi.js"); Utility.ForceWriteAllText(fileWebApi, jsWebApi.WebApiCode); } else { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, string.Format("{0,0}{1," + count.ToString().Length + "}", "", i) + ": ", CliLog.ColorMagenta, "No change ", CliLog.ColorGreen, entity, ".webapi.js"); } }
private List <Dependency> GetUpdateDependencies(List <Dependency> dependencies) { if (!IsSupportWebResourceDependency) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorCyan, "Your organization don't suport WebResource dependency"); return(dependencies); } var i = 1; var total = downloadedFiles.Count; var len = total.ToString().Length; CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, "Found: ", CliLog.ColorCyan, total, CliLog.ColorGreen, " webresources"); foreach (var downloadedFile in downloadedFiles) { var fetchData = new { webresourceid = downloadedFile.ObjectId }; var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <attribute name='dependencyxml' /> <filter type='and'> <condition attribute='webresourceid' operator='eq' value='{fetchData.webresourceid}'/> </filter> </entity> </fetch>"; var rows = crmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count != 1) { continue; } var name = rows.Entities[0].GetAttributeValue <string>("name"); var dependencyxml = rows.Entities[0].GetAttributeValue <string>("dependencyxml"); if (dependencyxml == null) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", i) + ": ", CliLog.ColorWhite, "Dependency: ", CliLog.ColorGreen, name, CliLog.ColorWhite, " not found"); i++; continue; } var xdoc = XDocument.Parse(dependencyxml); var webResources = (from x in xdoc.Descendants("Dependencies").Descendants("Dependency").Elements("Library") select new { name = x?.Attribute("name")?.Value }).ToList(); if (webResources.Count == 0) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", i) + ": ", CliLog.ColorWhite, "Dependency: ", CliLog.ColorGreen, name, CliLog.ColorWhite, " not found"); i++; continue; } var existing = dependencies.FirstOrDefault(d => d.webresources.Contains(name)); List <string> dependenciesLog; if (existing == null) { dependenciesLog = webResources.Select(w => w.name).ToList(); dependencies.Add(new Dependency { webresources = new List <string> { name }, dependencies = dependenciesLog }); } else { var update = existing.dependencies; update.AddRange(webResources.Select(w => w.name).ToList()); update = update.Distinct().ToList(); existing.dependencies = update; dependenciesLog = update; } CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", i) + ": ", CliLog.ColorWhite, "Dependency: ", CliLog.ColorGreen, name, CliLog.ColorWhite, " dependencies"); foreach (var dependency in dependenciesLog) { CliLog.WriteLine(CliLog.ColorWhite, "|", CliLog.ColorGreen, "\t", CliLog.ColorGreen, dependency); } i++; } return(dependencies); }