// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Data; namespace Spludlow { public class Code { public static void CheckDevelopSources(string[] solutionDirectories) { DataTable table = Spludlow.Config.DevelopSources().Tables[0]; List projectDirs = new List(ListProjects(solutionDirectories)); List developSources = new List(); foreach (DataRow row in table.Rows) developSources.Add((string)row["DevelopSourceId"]); List notInDevSource = new List(); List notProjectDir = new List(); foreach (string id in projectDirs) if (developSources.Contains(id) == false) notInDevSource.Add(id); foreach (string id in developSources) if (projectDirs.Contains(id) == false) notProjectDir.Add(id); Spludlow.Log.Report("CheckDevelopSources; Project not in DevelopSources.txt: " + notInDevSource.Count, notInDevSource.ToArray()); Spludlow.Log.Report("CheckDevelopSources; Enrty in DevelopSources.txt with no Project: " + notProjectDir.Count, notProjectDir.ToArray()); } public static string[] ListProjects(string[] solutionDirectories) { List reportList = new List(); List projectList = new List(); foreach (string solutionDirectory in solutionDirectories) { string solutionName = Path.GetFileName(solutionDirectory); reportList.Add(solutionDirectory); foreach (string projectDirectory in Directory.GetDirectories(solutionDirectory)) { string projectName = Path.GetFileName(projectDirectory); if (projectName == ".vs") continue; reportList.Add(projectName + "@" + projectDirectory); projectList.Add(projectName); } } Spludlow.Log.Report("ListProjects", reportList.ToArray()); return projectList.ToArray(); } public static void RemoveUnwanted(string[] solutionDirectories) // No longer needed, figured it out { string[] unWanted = new string[] { "Microsoft.Web.Administration.dll", }; DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "ProjectName BinDirectory Filename", "String String String", }); foreach (string solutionDirectory in solutionDirectories) { foreach (string projectDirectory in Directory.GetDirectories(solutionDirectory)) { string projectName = Path.GetFileName(projectDirectory); if (File.Exists(projectDirectory + @"\Web.config") == true) { string webBinDirectory = projectDirectory + @"\Bin"; if (Directory.Exists(webBinDirectory) == false) continue; foreach (string filename in unWanted) { string path = webBinDirectory + @"\" + filename; if (File.Exists(path) == true) { //File.Delete(path); table.Rows.Add(projectName, webBinDirectory, filename); } } continue; } string binDirectory = projectDirectory + @"\bin\Release"; if (Directory.Exists(binDirectory) == false) continue; foreach (string filename in unWanted) { string path = binDirectory + @"\" + filename; if (File.Exists(path) == true) { //File.Delete(path); table.Rows.Add(projectName, binDirectory, filename); } } } } Spludlow.Log.Report("RemoveUnwanted", table); } public static void CopyReferencedLibraries(string[] solutionDirectories, bool liveMode) { Dictionary> websExistingLibraries = new Dictionary>(); Dictionary> librariesReferenced = new Dictionary>(); Dictionary webBinDirs = new Dictionary(); Dictionary libBinDirs = new Dictionary(); foreach (string solutionDirectory in solutionDirectories) { foreach (string projectDirectory in Directory.GetDirectories(solutionDirectory)) { string projectName = Path.GetFileName(projectDirectory); if (File.Exists(projectDirectory + @"\Web.config") == true) { string webBinDirectory = projectDirectory + @"\Bin"; if (Directory.Exists(webBinDirectory) == false) continue; websExistingLibraries.Add(projectName, new List()); webBinDirs.Add(projectName, webBinDirectory); foreach (string filename in Directory.GetFiles(webBinDirectory, "*.dll")) { string name = Path.GetFileNameWithoutExtension(filename); websExistingLibraries[projectName].Add(name); } continue; } string libraryBinDirectory = projectDirectory + @"\bin\Release"; if (Directory.Exists(libraryBinDirectory) == false) continue; if (Directory.GetFiles(libraryBinDirectory, "*.exe").Length > 0) { // And exe projects (not just webs) websExistingLibraries.Add(projectName, new List()); webBinDirs.Add(projectName, libraryBinDirectory); foreach (string filename in Directory.GetFiles(libraryBinDirectory, "*.dll")) { string name = Path.GetFileNameWithoutExtension(filename); websExistingLibraries[projectName].Add(name); } continue; } librariesReferenced.Add(projectName, new List()); libBinDirs.Add(projectName, libraryBinDirectory); foreach (string filename in Directory.GetFiles(libraryBinDirectory, "*.dll")) { string name = Path.GetFileNameWithoutExtension(filename); librariesReferenced[projectName].Add(name); } if (librariesReferenced[projectName].Count == 0) librariesReferenced.Remove(projectName); } } DataSet dataSet = new DataSet(); DataTable completeTable = Spludlow.Data.TextTable.ReadText(new string[] { "WebProject ParentLibrary ReferencedLibrary Status SourceFilename TargetFilename SourceTime TargetTime SourceSize TargetSize", "String String String String String String DateTime DateTime Int64 Int64", }); completeTable.TableName = "Complete"; foreach (string webProjectName in websExistingLibraries.Keys) { foreach (string existingWebLibraryName in websExistingLibraries[webProjectName]) { if (librariesReferenced.ContainsKey(existingWebLibraryName) == false) continue; foreach (string referencedLibrary in librariesReferenced[existingWebLibraryName]) { string sourceFilename = libBinDirs[existingWebLibraryName] + @"\" + referencedLibrary + ".dll"; string targetFilename = webBinDirs[webProjectName] + @"\" + referencedLibrary + ".dll"; DataRow row = completeTable.Rows.Add(new object[] { webProjectName, existingWebLibraryName, referencedLibrary, "", sourceFilename, targetFilename, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value }); DateTime sourceTime = File.GetLastWriteTime(sourceFilename); Int64 sourceSize = Spludlow.Io.Files.FileLength(sourceFilename); row["SourceTime"] = sourceTime; row["SourceSize"] = sourceSize; if (File.Exists(targetFilename) == true) { DateTime targetTime = File.GetLastWriteTime(targetFilename); Int64 targetSize = Spludlow.Io.Files.FileLength(targetFilename); row["TargetTime"] = targetTime; row["TargetSize"] = targetSize; String status = ""; if (sourceTime != targetTime) status += "Time,"; if (sourceSize != targetSize) status += "Size,"; row["Status"] = status; } else { row["Status"] = "Missing"; } } } } DataTable updateTable = completeTable.Clone(); updateTable.TableName = "Update"; foreach (DataRow row in completeTable.Select("TargetTime IS NULL")) updateTable.ImportRow(row); foreach (DataRow row in updateTable.Rows) { string targetFilename = (string)row["TargetFilename"]; if (File.Exists(targetFilename) == true) { row["Status"] = "Exists"; continue; } string sourceFilename = (string)row["SourceFilename"]; row["Status"] = "Copy"; try { if (liveMode == true) File.Copy(sourceFilename, targetFilename); } catch (Exception ee) { row["Status"] = ee.Message; } } dataSet.Tables.Add(updateTable); dataSet.Tables.Add(completeTable); DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "ProjectName Reference", "String String", }); table = table.Clone(); table.TableName = "Web Existing Libraries"; foreach (string key in websExistingLibraries.Keys) foreach (string value in websExistingLibraries[key]) table.Rows.Add(new object[] { key, value }); dataSet.Tables.Add(table); table = table.Clone(); table.TableName = "Libraries Referenced"; foreach (string key in librariesReferenced.Keys) foreach (string value in librariesReferenced[key]) table.Rows.Add(new object[] { key, value }); dataSet.Tables.Add(table); Spludlow.Log.Report("CopyReferencedLibrariesForWebs", new object[] { dataSet }); } public static string[] CSharpFilenames(string solutionDirectory) { DataSet dataSet = Spludlow.Io.DirectoryList.List(solutionDirectory, true, false); SysTables.FileSystemInfosDataTable table = (SysTables.FileSystemInfosDataTable)dataSet.Tables["FileSystemInfos"]; List results = new List(); foreach (SysTables.FileSystemInfosRow row in table.Rows) { if (row.Directory == false) { if (ValidCSharpFilename(row.Path) == true) results.Add(row.Path); } } return results.ToArray(); } public static bool ValidCSharpFilename(string path) { path = path.ToLower(); if (path.EndsWith(".cs") == false) return false; if (path.EndsWith(".designer.cs") == true) return false; if (path.EndsWith(@"\assemblyinfo.cs") == true) return false; if (path.Contains(@"\connected services\") == true) return false; if (path.Contains(@"\properties\") == true) return false; if (path.Contains(@"\obj\") == true) return false; return true; } public static void CodeHeaderComments(string solutionDirectory, string[] copyrightLines) { DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "Filename Reached CreationTime LastAccessTime LastWriteTime LineCount", "String Boolean DateTime DateTime DateTime Int32", }); foreach (string filename in CSharpFilenames(solutionDirectory)) { FileInfo fileInfo = new FileInfo(filename); DateTime creationTime = fileInfo.CreationTime; DateTime lastAccessTime = fileInfo.LastAccessTime; DateTime lastWriteTime = fileInfo.LastWriteTime; StringBuilder result = new StringBuilder(); foreach (string copyrightLine in copyrightLines) { result.Append("// "); result.AppendLine(copyrightLine); } result.AppendLine(""); string text = File.ReadAllText(filename, Encoding.UTF8); int lineCount = 0; bool reached = false; using (StringReader reader = new StringReader(text)) { string line; while ((line = reader.ReadLine()) != null) { if (line == "using System;") reached = true; if (reached == true) { result.AppendLine(line); line = line.Trim(); if (line.Length > 1 && line.StartsWith("using ") == false) ++lineCount; } } } if (reached == true) { File.WriteAllText(filename, result.ToString(), Encoding.UTF8); File.SetCreationTime(filename, creationTime); File.SetLastAccessTime(filename, lastAccessTime); File.SetLastWriteTime(filename, lastWriteTime); } table.Rows.Add(filename, reached, creationTime, lastAccessTime, lastWriteTime, lineCount); } Spludlow.Log.Report("CodeHeaderComments", new object[] { table }); } public static string DataRow(DataSet schema, string tableName, string varibleName) { StringBuilder text = new StringBuilder(); DataTable table = schema.Tables[tableName + "_Columns"]; foreach (DataRow row in table.Rows) { text.Append("\t\t\t"); text.Append(varibleName); text.Append("."); text.Append((string)row["ColumnName"]); text.Append(" = null;"); text.Append("\t\t//\t"); text.Append((string)row["DataTypeId"]); if ((bool)row["PrimaryKey"] == true) text.Append("\tPrimaryKey"); if ((bool)row["AutoIncrement"] == true) text.Append("\tAutoIncrement"); if ((bool)row["AllowDBNull"] == true) text.Append("\tAllowNull"); text.AppendLine(); } return text.ToString(); } public static void SetAssemblyInfos(string[] solutionDirectories, string version, string name) { string[] infoLines = new string[] { "AssemblyTitle Spludlow", "AssemblyDescription", "AssemblyConfiguration", "AssemblyCompany Spludlow", "AssemblyProduct Spludlow Framework", "AssemblyCopyright Copyright © " + DateTime.Now.Year + " " + name, "AssemblyTrademark Registered Trademark ® " + DateTime.Now.Year + " " + name, "AssemblyCulture", "AssemblyVersion " + version, "AssemblyFileVersion " + version, }; Dictionary info = new Dictionary(); foreach (string line in infoLines) { string[] parts = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); string data = ""; if (parts.Length > 1) data = parts[1]; info.Add(parts[0], data); } List filenames = new List(); foreach (string solutionDirectory in solutionDirectories) { string solutionName = Path.GetFileName(solutionDirectory); foreach (string projectDirectory in Directory.GetDirectories(solutionDirectory)) { string projectName = Path.GetFileName(projectDirectory); if (projectName == ".vs") continue; string[] assInfos = Directory.GetFiles(projectDirectory, "AssemblyInfo.cs", SearchOption.AllDirectories); if (assInfos.Length > 1) throw new ApplicationException("Code SetAssemblyInfos; Too many AssemblyInfo.cs files in project: " + projectDirectory); if (assInfos.Length == 0) continue; SetAssemblyInfo(assInfos[0], projectName, info); filenames.Add(projectName + ": " + assInfos[0]); } } Spludlow.Log.Finish("Set AssemblyInfos: " + filenames.Count, filenames.ToArray()); } private static void SetAssemblyInfo(string filename, string projectName, Dictionary info) { string assemblyTitle = info["AssemblyTitle"]; info["AssemblyTitle"] = projectName; StringBuilder result = new StringBuilder(); using (StreamReader reader = new StreamReader(filename, Encoding.UTF8)) { string line; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("[assembly: Assembly") == true) { string key = Spludlow.Text.ChopBetween(line, ":", "(", false).Trim(); if (info.ContainsKey(key) == true) { StringBuilder newLine = new StringBuilder("[assembly: @KEY(\"@DATA\")]"); newLine.Replace("@KEY", key); newLine.Replace("@DATA", info[key]); line = newLine.ToString(); } } result.AppendLine(line); } } File.WriteAllText(filename, result.ToString(), Encoding.UTF8); info["AssemblyTitle"] = assemblyTitle; } private static string VersionKey = "SpludlowReleaseVersion"; public static string BumpVersionNumber() { using (Spludlow.Variables variables = new Spludlow.Variables()) { string value = variables.Get(VersionKey); if (value == null) value = "0.0"; int index = value.IndexOf("."); int major = Int32.Parse(value.Substring(0, index)); int minor = Int32.Parse(value.Substring(index + 1)); ++minor; value = major + "." + minor; variables.Set(VersionKey, value); return value; } } public static void SetVersionNumber(string value) { Spludlow.Variables.SetValue(VersionKey, value); } public static string GetVersionNumber() { return Spludlow.Variables.GetValue(VersionKey); } private static string FrameworkVersionKey = "SpludlowTargetFrameworkVersion"; public static void SetFrameworkVersion(string value) { Spludlow.Variables.SetValue(FrameworkVersionKey, value); } public static string GetFrameworkVersion() { return Spludlow.Variables.GetValue(FrameworkVersionKey); } public static void FixEnableViewState(string webDirectory) { DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "Filename Update CreationTime LastAccessTime LastWriteTime LineCount", "String Boolean DateTime DateTime DateTime Int32", }); foreach (string filename in Directory.GetFiles(webDirectory, "*.aspx", SearchOption.AllDirectories)) { FileInfo fileInfo = new FileInfo(filename); DateTime creationTime = fileInfo.CreationTime; DateTime lastAccessTime = fileInfo.LastAccessTime; DateTime lastWriteTime = fileInfo.LastWriteTime; string text = File.ReadAllText(filename, Encoding.UTF8); StringBuilder result = new StringBuilder(); int lineCount = 0; bool update = false; using (StringReader reader = new StringReader(text)) { string line; while ((line = reader.ReadLine()) != null) { if (result.Length == 0 && line.StartsWith("<%@ Page") == true && line.EndsWith(" %>") == true && line.Contains("EnableViewState") == false) { update = true; line = line.Replace(" %>", " EnableViewState=\"false\" %>"); } result.AppendLine(line); ++lineCount; } } if (update == true) { File.WriteAllText(filename, result.ToString(), Encoding.UTF8); File.SetCreationTime(filename, creationTime); File.SetLastAccessTime(filename, lastAccessTime); File.SetLastWriteTime(filename, lastWriteTime); } table.Rows.Add(filename, update, creationTime, lastAccessTime, lastWriteTime, lineCount); } Spludlow.Log.Report("FixEnableViewState", table); } public static void EnableOutputCaching(string webDirectory, string[] skipPages) { DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "Filename Update CreationTime LastAccessTime LastWriteTime LineCount", "String Boolean DateTime DateTime DateTime Int32", }); foreach (string filename in Directory.GetFiles(webDirectory, "*.aspx", SearchOption.AllDirectories)) { bool skip = false; foreach (string skipPage in skipPages) { if (filename.EndsWith(skipPage) == true) { skip = true; break; } } FileInfo fileInfo = new FileInfo(filename); DateTime creationTime = fileInfo.CreationTime; DateTime lastAccessTime = fileInfo.LastAccessTime; DateTime lastWriteTime = fileInfo.LastWriteTime; string text = File.ReadAllText(filename, Encoding.UTF8); StringBuilder result = new StringBuilder(); bool update = ! skip; int lineCount = 0; using (StringReader reader = new StringReader(text)) { string line; while ((line = reader.ReadLine()) != null) { if (result.Length == 0) // First Line { result.AppendLine(line); result.AppendLine("<%@ OutputCache Duration=\"3600\" VaryByParam=\"*\" %>"); } else { if (line.StartsWith("<%@ OutputCache") == false) result.AppendLine(line); } ++lineCount; } } if (update == true) { File.WriteAllText(filename, result.ToString(), Encoding.UTF8); File.SetCreationTime(filename, creationTime); File.SetLastAccessTime(filename, lastAccessTime); File.SetLastWriteTime(filename, lastWriteTime); } table.Rows.Add(filename, update, creationTime, lastAccessTime, lastWriteTime, lineCount); } Spludlow.Log.Report("EnableOutputCaching", table); } public static void CleanBinAndObj(string solutionDirectory, bool deleteDotVs) { string[] subDirs = new string[] { "bin", "obj" }; List deleteDirs = new List(); if (deleteDotVs == true) { string directory = solutionDirectory + @"\.vs"; if (Directory.Exists(directory) == true) deleteDirs.Add(directory); } foreach (string projectDirectory in Directory.GetDirectories(solutionDirectory)) { foreach (string subDir in subDirs) { string directory = projectDirectory + @"\" + subDir; if (Directory.Exists(directory) == true) deleteDirs.Add(directory); } } Spludlow.Log.Report("CleanBinAndObj", deleteDirs.ToArray()); foreach (string dir in deleteDirs) Directory.Delete(dir, true); } } }