/// <summary> Source <c>Proj</c> is specified in the destination <c>Proj</c> XML comment placeholder. </summary> /// <param name="destProj"> Absolute path of destination <c>Proj</c>. </param> internal DestinationProjLinker(string destProj) { DestProjAbsolutePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, destProj); DestProjDirectory = Path.GetDirectoryName(DestProjAbsolutePath) ?? ""; if (string.IsNullOrEmpty(DestProjAbsolutePath)) { App.Crash("ERROR: No destProjFileAbsolutePath. That's a bug."); } try { destProjXml = new DestinationProjXml(DestProjAbsolutePath); } catch (Exception e) { App.Crash(e, "DestinationProjLinker CTOR (1 param) loading destination XML from " + DestProjAbsolutePath); } if (destProjXml.RootXelement == null || !destProjXml.RootXelement.Elements().Any()) { App.Crash("ERROR: Bad Destination Proj file at " + DestProjAbsolutePath); } SourceProjList = new List<string>(); ExclusionsList = new List<string>(); InclusionsList = new List<string>(); foreach (string line in destProjXml.StartPlaceHolder.Value.Split(new[] {"\r\n", "\n", Environment.NewLine}, StringSplitOptions.None).ToList()) { if (line.ToLower().Trim().StartsWith(Settings.SourcePlaceholderLowerCase)) { string sourceInXml = line.ToLower().Replace(Settings.SourcePlaceholderLowerCase, "").Replace("-->", "").Trim(); string absoluteSource = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(DestProjDirectory, sourceInXml); SourceProjList.Add(absoluteSource); } if (line.ToLower().Trim().StartsWith(Settings.ExcludePlaceholderLowerCase)) { ExclusionsList.Add(line.ToLower().Replace(Settings.ExcludePlaceholderLowerCase, "").Trim().ToLower()); } if (line.ToLower().Trim().StartsWith(Settings.IncludePlaceholderLowerCase)) { InclusionsList.Add(line.ToLower().Replace(Settings.IncludePlaceholderLowerCase, "").Trim().ToLower()); } } if (InclusionsList == null || !InclusionsList.Any()) { InclusionsList.Add("*"); // default wildcard match will include everything. } }
/// <summary> Source <c>Proj</c> is specified in the destination <c>Proj</c> XML comment placeholder. </summary> /// <param name="destProj"> Absolute path of destination <c>Proj</c>. </param> internal DestinationProjLinker(string destProj) { DestProjAbsolutePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, destProj); DestProjDirectory = Path.GetDirectoryName(DestProjAbsolutePath) ?? ""; if (string.IsNullOrEmpty(DestProjAbsolutePath)) { App.Crash("ERROR: No destProjFileAbsolutePath. That's a bug."); } try { destProjXml = new DestinationProjXml(DestProjAbsolutePath); } catch (Exception e) { App.Crash(e, "DestinationProjLinker CTOR (1 param) loading destination XML from " + DestProjAbsolutePath); } if (destProjXml.RootXelement == null || !destProjXml.RootXelement.Elements().Any()) { App.Crash("ERROR: Bad Destination Proj file at " + DestProjAbsolutePath); } SourceProjList = new List <string>(); ExclusionsList = new List <string>(); InclusionsList = new List <string>(); foreach (string line in destProjXml.StartPlaceHolder.Value.Split(new[] { "\r\n", "\n", Environment.NewLine }, StringSplitOptions.None).ToList()) { if (line.ToLower().Trim().StartsWith(Settings.SourcePlaceholderLowerCase)) { string sourceInXml = line.ToLower().Replace(Settings.SourcePlaceholderLowerCase, "").Replace("-->", "").Trim(); string absoluteSource = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(DestProjDirectory, sourceInXml); SourceProjList.Add(absoluteSource); } if (line.ToLower().Trim().StartsWith(Settings.ExcludePlaceholderLowerCase)) { ExclusionsList.Add(line.ToLower().Replace(Settings.ExcludePlaceholderLowerCase, "").Trim().ToLower()); } if (line.ToLower().Trim().StartsWith(Settings.IncludePlaceholderLowerCase)) { InclusionsList.Add(line.ToLower().Replace(Settings.IncludePlaceholderLowerCase, "").Trim().ToLower()); } } if (InclusionsList == null || !InclusionsList.Any()) { InclusionsList.Add("*"); // default wildcard match will include everything. } }
/// <summary> Copies and links a List of Projects into the <c> destinationFolder </c>. /// <para> File is Linked from the first <c> projectsToLink </c> for each if there is more than 1 source. </para> </summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null or empty. </exception> /// <param name="projectsToLink"> a List of projects to Link. </param> /// <param name="destinationFolder"> Pathname of the destination folder. Empty string throws <c>ArgumentNullException</c></param> /// <param name="createSubFolders"> True (default) if you want each now project in its own subfolder. </param> internal static void NewProject(List<ProjectToLink> projectsToLink, string destinationFolder, bool createSubFolders = true) { if (projectsToLink == null) throw new ArgumentNullException(nameof(projectsToLink)); if (string.IsNullOrEmpty(destinationFolder)) throw new ArgumentNullException(nameof(destinationFolder)); var destinationProjects = new HashSet<string>(projectsToLink.Select(p => p.DestinationProjectName)); Log.WriteLine("Recycling " + destinationProjects.Count + " Project(s) to " + destinationFolder); foreach (string destinationProject in destinationProjects) { string destinationProjPath = createSubFolders ? Path.Combine(destinationFolder + "\\" + Path.GetFileNameWithoutExtension(destinationProject), destinationProject) : Path.Combine(destinationFolder, destinationProject); if (File.Exists(destinationProjPath)) { bool overwriteExisting = YesOrNo.Ask(destinationProjPath + Environment.NewLine + "already exists!" + Environment.NewLine + "Overwrite it ?"); if (!overwriteExisting) continue; } List<string> sources = projectsToLink .Where(d => d.DestinationProjectName == destinationProject) .Select(s => s.SourceProject).ToList(); if (sources.Count != 1) { string message = destinationProject + "has " + sources.Count + " source Projects." + Environment.NewLine; for (var index = 0; index < sources.Count; index++) { string source = sources[index]; message += index + 1 + ". " + source + Environment.NewLine; } message += "Continue (Y) or skip (N) " + destinationProject + " or Cancel Everything?"; bool? carryOn = YesOrNo.OrCancel(message); if (carryOn == null) { Log.WriteLine("User aborted All Recycling. " + message); return; // bail out of everything } if (carryOn == false) { Log.WriteLine("User skipped one Linked Project. " + message); continue; // skip just this Destination Project } } if (sources.Any()) { Log.WriteLine("Recycling to :" + destinationProjPath); Directory.CreateDirectory(Path.GetDirectoryName(destinationProjPath)); // safe. Doesn't care if it already exists. File.Copy(sources[0], destinationProjPath, true); var destinationProjXml = new DestinationProjXml(destinationProjPath); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.ClearStartPlaceholderContent(); destinationProjXml.AddExclusion("app.config"); Log.WriteLine("...because a linked App.config will cause problems when you change build settings."); destinationProjXml.AddExclusion("packages.config"); Log.WriteLine("...because nuget's packages.config will cause problems when you change build settings."); destinationProjXml.ClearAllExistingCodeExceptExplicitlyLinked(); foreach (string source in sources) { if (File.Exists(source)) destinationProjXml.AddSource(PathMaker.MakeRelativePath(destinationProjPath, source)); else Log.WriteLine("Bad Source in: " + destinationProjPath + Environment.NewLine + " Source: " + source + Environment.NewLine); } destinationProjXml.Save(); App.ParseCommands(new[] {destinationProjPath}); } } }
/// <summary> Source <c> Proj </c> is specified in the destination <c> Proj </c> XML comment placeholder. </summary> /// <param name="destProj"> Absolute path of destination <c> Proj </c>. </param> internal DestinationProjLinker(string destProj) { DestProjAbsolutePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, destProj); DestProjDirectory = Path.GetDirectoryName(DestProjAbsolutePath) ?? ""; if (string.IsNullOrEmpty(DestProjAbsolutePath)) { App.Crash("ERROR: No destProjFileAbsolutePath. That's a bug."); } try { destProjXml = new DestinationProjXml(DestProjAbsolutePath); if (destProjXml.RootXelement == null || !destProjXml.RootXelement.Elements().Any()) { App.Crash($"ERROR: Bad Destination Proj file at {DestProjAbsolutePath}. Root elemental null?: {destProjXml?.RootXelement == null}" + $", Root elements count: {destProjXml.RootXelement?.Elements()?.Count()}"); } } catch (Exception e) { App.Crash(e, "DestinationProjLinker CTOR (1 param) loading destination XML from " + DestProjAbsolutePath); } SourceProjList = new List <string>(); ExclusionsList = new List <string>(); InclusionsList = new List <string>(); foreach (string line in destProjXml.StartPlaceHolder.Value.Split(new[] { "\r\n", "\n", Environment.NewLine }, StringSplitOptions.None).ToList()) { try { if (line.ToLower().Trim().StartsWith(Settings.SourcePlaceholderLowerCase, StringComparison.Ordinal)) { string sourceInXml = line.Replace(Settings.SourcePlaceholderLowerCase, "") .Replace(Settings.SourcePlaceholder, "") .Replace("-->", "").Replace("\"", "").Trim(); string absoluteSource = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(DestProjDirectory, sourceInXml); SourceProjList.Add(absoluteSource); } else if (line.ToLower().Trim().StartsWith(Settings.ExcludePlaceholderLowerCase, StringComparison.Ordinal)) { ExclusionsList.Add(line.ToLower().Replace(Settings.ExcludePlaceholderLowerCase, "").Trim()); } else if (line.ToLower().Trim().StartsWith(Settings.IncludePlaceholderLowerCase, StringComparison.Ordinal)) { InclusionsList.Add(line.ToLower().Replace(Settings.IncludePlaceholderLowerCase, "").Trim()); } } catch (Exception e) { App.Crash(e, $"broke parsing the Code Linker placeholder at: {line}"); } } foreach (string exclusion in ExclusionsList) { Log.WriteLine("exclusion: " + exclusion, ConsoleColor.DarkYellow); } foreach (string inclusion in InclusionsList) { Log.WriteLine("inclusion: " + inclusion, ConsoleColor.White, ConsoleColor.DarkGreen); } if (!InclusionsList.Any()) { InclusionsList.Add("*"); // default wildcard match will include everything. } }
public static void ParseCommands(string[] args) { linkers.Clear(); // System.Diagnostics.Debugger.Launch(); // to find teh bugs load this in Visual Studio and uncomment the start of this line. int argsCount = args.Length; if (argsCount == 0) { Log.WriteLine("No Args given so Help Text Displayed."); Log.WriteLine(); Help.Write(); Finish(); } List<string> argsList = args.Select(a => a.Replace(@"""", "")).ToList(); if (argsList.Contains("/?")) { Help.Write(); Log.WriteLine("User asked For Help. Hope I helped."); Finish(); } bool doSubDirectories = argsList.Contains("/s", StringComparer.CurrentCultureIgnoreCase); bool createSubDirectories = !argsList.Contains("/nosub", StringComparer.CurrentCultureIgnoreCase); Log.WriteToConsole = !argsList.Contains("/stfu", StringComparer.CurrentCultureIgnoreCase); NoConfirm = argsList.Contains("/noconfirm", StringComparer.CurrentCultureIgnoreCase); if (!string.IsNullOrEmpty(argsList[0])) { if (argsList[0].IsaCsOrVbProjFile()) { if (argsCount > 1 && args[1].IsaCsOrVbProjFile()) { Log.WriteLine("Queueing Code Link from: " + argsList[0] + " to " + argsList[1]); linkers.Add(new DestinationProjLinker(argsList[0], argsList[1])); } else { Log.WriteLine("Queueing Code Link to: " + argsList[0] + ". Source TBA."); linkers.Add(new DestinationProjLinker(argsList[0])); } } else if (argsList[0].ToLower() == "strip") { if (argsCount > 1) { if (args[1].IsaCsOrVbProjFile()) { var destinationProjXml = new DestinationProjXml(args[1]); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.Save(); Finish("Stripped all code from " + args[1]); } else { try { List<string> destProjFiles = GetProjectsFromFolders(argsList[1], doSubDirectories); foreach (string destProjFile in destProjFiles) { Log.WriteLine("Stripping Code from: " + destProjFile + ". "); var destinationProjXml = new DestinationProjXml(destProjFile); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.Save(); } } catch (Exception e) { Crash(e, "Stripping Code from Folder: " + args[1] + " didn't work. Bad name?"); } Finish("Stripped all code"); } } } else if (argsList[0].ToLower() == "new") { if (argsCount > 2) { if (args[1].IsaCsOrVbProjFile()) { string sourcePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, args[1]); try { ProjectMaker.NewProject(sourcePath, args[2], createSubDirectories); } catch (Exception e) { Crash(e, "Linking " + args[1] + " to " + args[2] + " didn't work. Bad name?"); } Finish("Linked " + " from " + args[1] + " to " + args[2]); } else { try { List<string> sourceProjFiles = GetProjectsFromFolders(argsList[1], doSubDirectories); foreach (string sourceProjFile in sourceProjFiles) { if (sourceProjFile.IsaCsOrVbProjFile()) { string sourcePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, sourceProjFile); try { ProjectMaker.NewProject(sourcePath, args[2], createSubDirectories); } catch (Exception e) { Crash(e, "Linking " + sourceProjFile + " to " + args[2] + " didn't work. Bad name?"); } Log.WriteLine("Linked " + " from " + sourceProjFile + " to " + args[2]); } else Log.WriteLine("ERROR: " + sourceProjFile + " is not a project file. Cannot Link it."); } } catch (Exception e) { Crash(e, "Linking Projects from Folder: " + args[1] + " didn't work. Bad name?"); } Finish("Linked Projects"); } } } // /NewProject else // vanilla Link command with a folder { try { List<string> destProjFiles = GetProjectsFromFolders(argsList[0], doSubDirectories); foreach (string destProjFile in destProjFiles) { Log.WriteLine("Queueing Code Link to: " + destProjFile + ". Source TBA."); linkers.Add(new DestinationProjLinker(destProjFile)); } } catch (Exception e) { Crash(e, "Queueing Code Link didn't work. Bad file name?"); } } if (!linkers.Any()) { string errorMessage = "I got nuthin. Your Args made no sense to me." + Environment.NewLine; foreach (string arg in args) { errorMessage += arg + Environment.NewLine; } Crash(errorMessage); } foreach (DestinationProjLinker destinationProjLinker in linkers) { destinationProjLinker.LinkCode(); } } }
/// <summary> Copies and links a List of Projects into the <c>destinationFolder</c>. /// <para> File is Linked from the first <c>projectsToLink</c> for each if there is more than 1 source.</para></summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null or empty. </exception> /// <param name="projectsToLink"> The projects to Link. </param> /// <param name="destinationFolder"> Pathname of the destination folder. Empty string throws <c>ArgumentNullException</c></param> internal static void NewProject(List <ProjectToLink> projectsToLink, string destinationFolder) { if (projectsToLink == null) { throw new ArgumentNullException(nameof(projectsToLink)); } if (string.IsNullOrEmpty(destinationFolder)) { throw new ArgumentNullException(nameof(destinationFolder)); } HashSet <string> destinationProjects = new HashSet <string>(projectsToLink.Select(p => p.DestinationProjectName)); Log.WriteLine("Recycling " + destinationProjects.Count + " Project(s) to " + destinationFolder); foreach (string destinationProject in destinationProjects) { string destinationProjPath = Path.Combine(destinationFolder, destinationProject); if (File.Exists(destinationProjPath)) { bool overwriteExisting = YesOrNo.Ask(destinationProjPath + Environment.NewLine + "already exists!" + Environment.NewLine + "Overwrite it ?"); if (!overwriteExisting) { continue; } } List <string> sources = projectsToLink.Where(d => d.DestinationProjectName == destinationProject).Select(s => s.SourceProject).ToList(); if (sources.Count != 1) { string message = destinationProject + "has " + sources.Count + " source Projects." + Environment.NewLine; for (int index = 0; index < sources.Count; index++) { string source = sources[index]; message += (index + 1).ToString() + ". " + source + Environment.NewLine; } message += "Continue (Y) or skip (N) " + destinationProject + " or Cancel Everything?"; bool?carryOn = YesOrNo.OrCancel(message); if (carryOn == null) { Log.WriteLine("User aborted All Recycling. " + message); return; // bail out of everything } if (carryOn == false) { Log.WriteLine("User skipped one Linked Project. " + message); continue; // skip just this Destination Project } } if (sources.Any()) { Log.WriteLine("Recycling to :" + destinationProjPath); File.Copy(sources[0], destinationProjPath, overwrite: true); DestinationProjXml destinationProjXml = new DestinationProjXml(destinationProjPath); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.ClearStartPlaceholderContent(); destinationProjXml.AddExclusion("app.config"); Log.WriteLine("...because a linked App.config will cause problems when you change build settings."); destinationProjXml.ClearAllExistingCodeExceptExplicitlyLinked(); foreach (string source in sources) { if (File.Exists(source)) { destinationProjXml.AddSource(PathMaker.MakeRelativePath(destinationProjPath, source)); } else { Log.WriteLine("Bad Source in: " + destinationProjPath + Environment.NewLine + " Source: " + source + Environment.NewLine); } } destinationProjXml.Save(); App.ParseCommands(new[] { destinationProjPath }); } } }
public static void ParseCommands(string[] args) { linkers.Clear(); // System.Diagnostics.Debugger.Launch(); // to find teh bugs load this in Visual Studio and uncomment the start of this line. int argsCount = args.Length; if (argsCount == 0) { Log.WriteLine("No Args given so Help Text Displayed.", ConsoleColor.Red); Log.WriteLine(); Help.Write(); Finish(); } List <string> argsList = args.Select(a => a.Replace(@"""", "")).ToList(); if (argsList.Contains("/?")) { Help.Write(); Log.WriteLine("User asked For Help. Hope I helped.", ConsoleColor.Green); Finish(); } bool doSubDirectories = argsList.Contains("/s", StringComparer.CurrentCultureIgnoreCase); bool createSubDirectories = !argsList.Contains("/nosub", StringComparer.CurrentCultureIgnoreCase); Log.WriteToConsole = !argsList.Contains("/stfu", StringComparer.CurrentCultureIgnoreCase); NoConfirm = argsList.Contains("/noconfirm", StringComparer.CurrentCultureIgnoreCase); if (argsList.Contains("/abs", StringComparer.CurrentCultureIgnoreCase)) { PathMaker.UseRelativePaths = false; } string prefixArg = args.FirstOrDefault(arg => arg.StartsWith("/prefix:", StringComparison.OrdinalIgnoreCase)); if (prefixArg?.Any() ?? false) { string prefix = prefixArg.Substring(8).Replace("\"", ""); DestinationProjLinker.LinkPrefix = prefix; } if (!string.IsNullOrEmpty(argsList[0])) { if (argsList[0].IsaCsOrVbProjFile()) { if (argsCount > 1 && args[1].IsaCsOrVbProjFile()) { Log.WriteLine("Queueing Code Link from: " + argsList[0], ConsoleColor.Cyan); Log.WriteLine(" to: " + argsList[1], ConsoleColor.Cyan); Log.WriteLine(); linkers.Add(new DestinationProjLinker(argsList[0], argsList[1])); } else { Log.WriteLine("Queueing Code Link to: " + argsList[0] + ". Source TBA.", ConsoleColor.Cyan); linkers.Add(new DestinationProjLinker(argsList[0])); } } else if (argsList[0].ToLower() == "strip") { if (argsCount > 1) { if (args[1].IsaCsOrVbProjFile()) { var destinationProjXml = new DestinationProjXml(args[1]); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.Save(); Finish("Stripped all code from " + args[1]); } else { try { List <string> destProjFiles = GetProjectsFromFolders(argsList[1], doSubDirectories); foreach (string destProjFile in destProjFiles) { Log.WriteLine("Stripping Code from: " + destProjFile + ". ", ConsoleColor.Yellow); var destinationProjXml = new DestinationProjXml(destProjFile); destinationProjXml.ClearOldLinkedCode(); destinationProjXml.Save(); } } catch (Exception e) { Crash(e, "Stripping Code from Folder: " + args[1] + " didn't work. Bad name?"); } Finish("Stripped all code"); } } } else if (argsList[0].ToLower() == "new") { if (argsCount > 2) { if (args[1].IsaCsOrVbProjFile()) { string sourcePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, args[1]); try { ProjectMaker.NewProject(sourcePath, args[2], createSubDirectories); } catch (Exception e) { Crash(e, "Linking " + args[1] + " to " + args[2] + " didn't work. Bad name?"); } Finish("Linked " + " from " + args[1] + " to " + args[2]); } else { try { List <string> sourceProjFiles = GetProjectsFromFolders(argsList[1], doSubDirectories); foreach (string sourceProjFile in sourceProjFiles) { if (sourceProjFile.IsaCsOrVbProjFile()) { string sourcePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, sourceProjFile); try { ProjectMaker.NewProject(sourcePath, args[2], createSubDirectories); } catch (Exception e) { Crash(e, "Linking " + sourceProjFile + " to " + args[2] + " didn't work. Bad name?"); } Log.WriteLine("Linked " + " from " + sourceProjFile + " to " + args[2], ConsoleColor.Green); } else { Log.WriteLine("ERROR: " + sourceProjFile + " is not a project file. Cannot Link it.", ConsoleColor.Green); } } } catch (Exception e) { Crash(e, "Linking Projects from Folder: " + args[1] + " didn't work. Bad name?"); } Finish("Linked Projects"); } } } // /NewProject else // vanilla Link command with a folder { try { List <string> destProjFiles = GetProjectsFromFolders(argsList[0], doSubDirectories); foreach (string destProjFile in destProjFiles) { Log.WriteLine("Queueing Code Link to: " + destProjFile + ". Source TBA.", ConsoleColor.Cyan); linkers.Add(new DestinationProjLinker(destProjFile)); } } catch (Exception e) { Crash(e, "Queueing Code Link didn't work. Bad file name?"); } } if (!linkers.Any()) { string errorMessage = "I got nuthin. Your Args made no sense to me." + Environment.NewLine; foreach (string arg in args) { errorMessage += arg + Environment.NewLine; } Crash(errorMessage); } foreach (DestinationProjLinker destinationProjLinker in linkers) { destinationProjLinker.LinkCode(); } } }