public static LoadFromFile ( string sergenJson ) : |
||
sergenJson | string | |
return |
public void Run(string csproj, List <ExternalType> tsTypes) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); config.ClientTypes = config.ClientTypes ?? new GeneratorConfig.ClientTypesConfig(); if (config.RootNamespace.IsEmptyOrNull()) { config.RootNamespace = config.GetRootNamespaceFor(csproj); } var outDir = Path.Combine(projectDir, (config.ClientTypes.OutDir.TrimToNull() ?? "Imports/ClientTypes") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming ClientTypes at: "); Console.ResetColor(); Console.WriteLine(outDir); var generator = new ClientTypesGenerator(); generator.RootNamespaces.Add(config.RootNamespace); foreach (var type in tsTypes) { generator.AddTSType(type); } var codeByFilename = generator.Run(); new MultipleOutputHelper().WriteFiles(outDir, codeByFilename, "*.ts"); }
public static void Run(string csproj) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); config.MVC ??= new GeneratorConfig.MVCConfig(); var outDir = Path.Combine(projectDir, (config.MVC.OutDir.TrimToNull() ?? "Imports/MVC") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming MVC at: "); Console.ResetColor(); Console.WriteLine(outDir); string[] stripViewPaths = config.MVC.StripViewPaths ?? new string[] { "Modules/", "Views/", Path.GetFileNameWithoutExtension(csproj) + "/" }; var rootDir = projectDir + Path.DirectorySeparatorChar; var searchViewPaths = (config.MVC.SearchViewPaths ?? new string[] { "Modules/", "Views/", Path.GetFileNameWithoutExtension(csproj) + "/" }) .Select(x => Path.Combine(rootDir, x.Replace('/', Path.DirectorySeparatorChar))); IEnumerable <string> files = new List <string>(); foreach (var path in searchViewPaths) { if (Directory.Exists(path)) { files = files.Concat(Directory.GetFiles(path, "*.cshtml", SearchOption.AllDirectories)); } } string getName(string s) { var path = s[rootDir.Length..]; var name = Path.ChangeExtension(path, null).Replace('\\', '/'); foreach (var strip in stripViewPaths) { if (name.StartsWith(strip, StringComparison.OrdinalIgnoreCase)) { name = name[strip.Length..];
public ExitCodes Run(string csproj) { if (csproj == null) { throw new ArgumentNullException(nameof(csproj)); } if (!File.Exists(csproj)) { Console.Error.WriteLine($"Project file {csproj} is not found!"); return(ExitCodes.ProjectNotFound); } var visited = new HashSet <string>(StringComparer.OrdinalIgnoreCase); Func <string, bool> skipPackage = id => { if (visited.Contains(id)) { return(true); } if (CodeGeneration.SkipPackages.ForRestore(id)) { return(true); } visited.Add(id); return(false); }; var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); GlobFilter include = null; if (config.Restore?.Include.IsEmptyOrNull() == false) { include = new GlobFilter(config.Restore.Include); } GlobFilter exclude = null; if (config.Restore?.Exclude.IsEmptyOrNull() == false) { exclude = new GlobFilter(config.Restore.Exclude); } var targetRoot = Path.GetDirectoryName(csproj); var restoredFromProjectReference = new HashSet <string>(StringComparer.OrdinalIgnoreCase); void restoreFile(string file, string relative) { relative = PathHelper.ToPath(relative); if (include != null && !include.IsMatch(relative)) { return; } if (exclude != null && exclude.IsMatch(relative)) { return; } if (restoredFromProjectReference.Contains(relative)) { return; } var target = Path.Combine(targetRoot, relative); if (File.Exists(target)) { if (!File.ReadAllBytes(target) .SequenceEqual(File.ReadAllBytes(file))) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, true); } } else { if (!Directory.Exists(target)) { Directory.CreateDirectory(Path.GetDirectoryName(target)); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, false); } } try { foreach (var reference in EnumerateProjectReferences(csproj, new HashSet <string>(StringComparer.OrdinalIgnoreCase))) { IBuildProject project; try { project = ProjectSystem.LoadProject(reference); } catch { continue; } foreach (var item in project.AllEvaluatedItems .Where(x => string.Equals(x.ItemType, "TypingsToPackage", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "Content", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "None", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "TypeScriptCompile", StringComparison.OrdinalIgnoreCase)) .Where(x => x.EvaluatedInclude?.EndsWith(".d.ts", StringComparison.OrdinalIgnoreCase) == true)) { var sourceFile = Path.Combine(Path.GetDirectoryName(reference), item.EvaluatedInclude); if (!File.Exists(sourceFile)) { continue; } if (!string.Equals(item.ItemType, "TypingsToPackage", StringComparison.OrdinalIgnoreCase) && item.GetMetadataValue("Pack") != "true") { continue; } var packagePath = item.GetMetadataValue("PackagePath")?.Trim(); if (!string.IsNullOrEmpty(packagePath)) { foreach (var path in packagePath.Split(';', StringSplitOptions.RemoveEmptyEntries)) { if (!PathHelper.ToUrl(path).StartsWith("typings/", StringComparison.OrdinalIgnoreCase)) { continue; } restoreFile(sourceFile, path); restoredFromProjectReference.Add(path); } } } } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } var packagesDir = PackageHelper.DeterminePackagesPath(FileSystem); if (packagesDir == null) { Console.Error.WriteLine("Can't determine NuGet packages directory!"); return(ExitCodes.CantDeterminePackagesDir); } var queue = new Queue <(string ID, string Version)>(); foreach (var x in EnumeratePackageReferences(csproj)) { if (!skipPackage(x.Id) && !string.IsNullOrEmpty(x.Version)) { queue.Enqueue(x); } } ; while (queue.Count > 0) { var dep = queue.Dequeue(); var id = dep.ID; var ver = dep.Version.Trim(); if (ver.EndsWith("-*", StringComparison.Ordinal)) { ver = ver.Substring(0, ver.Length - 2); } else if (ver.StartsWith("[", StringComparison.Ordinal) && ver.EndsWith("]", StringComparison.Ordinal)) { ver = ver[1..^ 1].Trim();
public void Run(string projectJson, string[] args) { var projectDir = Path.GetDirectoryName(projectJson); var outFile = args.FirstOrDefault(x => x.StartsWith("-o:"))?.Substring(3).TrimToNull(); var connectionKey = args.FirstOrDefault(x => x.StartsWith("-c:"))?.Substring(3).TrimToNull(); var table = args.FirstOrDefault(x => x.StartsWith("-t:"))?.Substring(3).TrimToNull(); var what = args.FirstOrDefault(x => x.StartsWith("-w:"))?.Substring(3).TrimToNull(); var module = args.FirstOrDefault(x => x.StartsWith("-m:"))?.Substring(3).TrimToNull(); var identifier = args.FirstOrDefault(x => x.StartsWith("-i:"))?.Substring(3).TrimToNull(); var permissionKey = args.FirstOrDefault(x => x.StartsWith("-p:"))?.Substring(3).TrimToNull(); if (identifier != null) { CodeFileHelper.Overwrite = true; } var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); var connectionKeys = config.Connections .Where(x => !x.ConnectionString.IsEmptyOrNull()) .Select(x => x.Key).ToList(); var appSettingsFile = Path.Combine(projectDir, "appsettings.json"); AppSettingsFormat appSettings; if (File.Exists(appSettingsFile)) { appSettings = JSON.ParseTolerant <AppSettingsFormat>(File.ReadAllText(appSettingsFile).TrimToNull() ?? "{}"); } else { appSettings = new AppSettingsFormat(); } connectionKeys.AddRange(appSettings.Data.Keys); var appSettingsFile2 = Path.Combine(projectDir, "appsettings.machine.json"); if (File.Exists(appSettingsFile2)) { var appSettings2 = JSON.ParseTolerant <AppSettingsFormat>(File.ReadAllText(appSettingsFile2).TrimToNull() ?? "{}"); foreach (var pair in appSettings2.Data) { appSettings.Data[pair.Key] = pair.Value; } } connectionKeys.AddRange(appSettings.Data.Keys); connectionKeys = connectionKeys.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(x => x).ToList(); if (connectionKeys.Count == 0) { Console.Error.WriteLine("No connections in appsettings.json or sergen.json!"); Environment.Exit(1); } if (outFile == null && connectionKey == null) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("=== Table Code Generation ==="); Console.WriteLine(""); Console.ResetColor(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Available Connections:"); Console.ResetColor(); foreach (var x in connectionKeys) { Console.WriteLine(x); } Console.ResetColor(); Console.WriteLine(); } else if (connectionKey == null) { File.WriteAllText(outFile, JSON.Stringify(connectionKeys)); Environment.Exit(0); } string userInput = null; if (outFile == null && connectionKey == null) { userInput = connectionKeys.Count == 1 ? connectionKeys[0] : null; while (connectionKey == null || !connectionKeys.Contains(connectionKey, StringComparer.OrdinalIgnoreCase)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Connection: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; connectionKey = Hinter.ReadHintedLine(connectionKeys, userInput: userInput); userInput = connectionKey; if (connectionKey == "!") { Console.ResetColor(); return; } } } userInput = connectionKey; connectionKey = connectionKeys.Find(x => string.Compare(x, userInput, StringComparison.OrdinalIgnoreCase) == 0); if (connectionKey == null) { Console.Error.WriteLine("Can't find connection with key: " + userInput + "!"); Environment.Exit(1); } if (outFile == null) { Console.ResetColor(); Console.WriteLine(); } var dataConnection = appSettings.Data.ContainsKey(connectionKey) ? appSettings.Data[connectionKey] : null; var confConnection = config.Connections.FirstOrDefault(x => string.Compare(x.Key, connectionKey, StringComparison.OrdinalIgnoreCase) == 0); var connectionString = dataConnection != null?dataConnection.ConnectionString.TrimToNull() : null; if (connectionString == null && confConnection != null) { connectionString = confConnection.ConnectionString.TrimToNull(); } var providerName = dataConnection != null?dataConnection.ProviderName.TrimToNull() : null; if (providerName == null && confConnection != null) { providerName = confConnection.ProviderName.TrimToNull(); } providerName = providerName ?? "System.Data.SqlClient"; DbProviderFactories.RegisterFactory("System.Data.SqlClient", SqlClientFactory.Instance); DbProviderFactories.RegisterFactory("Microsoft.Data.Sqlite", Microsoft.Data.Sqlite.SqliteFactory.Instance); DbProviderFactories.RegisterFactory("Npgsql", Npgsql.NpgsqlFactory.Instance); DbProviderFactories.RegisterFactory("FirebirdSql.Data.FirebirdClient", FirebirdSql.Data.FirebirdClient.FirebirdClientFactory.Instance); DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySql.Data.MySqlClient.MySqlClientFactory.Instance); if (connectionString.IndexOf("../../..") >= 0) { connectionString = connectionString.Replace("../../..", Path.GetDirectoryName(projectJson)); } else if (connectionString.IndexOf(@"..\..\..\") >= 0) { connectionString = connectionString.Replace(@"..\..\..\", Path.GetDirectoryName(projectJson)); } ISchemaProvider schemaProvider; List <TableName> tableNames; using (var connection = SqlConnections.New(connectionString, providerName)) { schemaProvider = SchemaHelper.GetSchemaProvider(connection.GetDialect().ServerType); tableNames = schemaProvider.GetTableNames(connection).ToList(); } var tables = tableNames.Select(x => x.Tablename).ToList(); if (outFile == null && table == null) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Available Tables:"); Console.ResetColor(); foreach (var x in tables) { Console.WriteLine(x); } } else if (table == null) { File.WriteAllText(outFile, JSON.Stringify(tableNames.Select(x => { var xct = confConnection == null ? null : confConnection.Tables.FirstOrDefault(z => string.Compare(z.Tablename, table, StringComparison.OrdinalIgnoreCase) == 0); return(new { name = x.Tablename, module = xct == null || xct.Module.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(connectionKey) : xct.Module, permission = xct == null || xct.PermissionKey.IsTrimmedEmpty() ? "Administration:General" : xct.PermissionKey, identifier = xct == null || xct.Identifier.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(x.Table) : xct.Identifier, }); }))); Environment.Exit(0); } userInput = tables.Count == 1 ? tables[0] : null; if (userInput == null && schemaProvider.DefaultSchema != null && tables.Any(x => x.StartsWith(schemaProvider.DefaultSchema + "."))) { userInput = schemaProvider.DefaultSchema + "."; } if (outFile == null) { Console.WriteLine(); while (table == null || !tables.Contains(table, StringComparer.OrdinalIgnoreCase)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; table = Hinter.ReadHintedLine(tables, userInput: userInput); userInput = table; if (table == "!") { Console.ResetColor(); return; } } } userInput = table; var tableName = tableNames.First(x => string.Compare(x.Tablename, userInput, StringComparison.OrdinalIgnoreCase) == 0); if (tableName == null) { Console.Error.WriteLine("Can't find table with name: " + userInput + "!"); Environment.Exit(1); } var confTable = confConnection == null ? null : confConnection.Tables.FirstOrDefault(x => string.Compare(x.Tablename, table, StringComparison.OrdinalIgnoreCase) == 0); if (module == null) { userInput = confTable == null || confTable.Module.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(connectionKey) : confTable.Module; Console.WriteLine(); while (module.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Module name for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; module = Hinter.ReadHintedLine(new string[0], userInput: userInput); userInput = module; if (module == "!") { Console.ResetColor(); return; } } } if (identifier == null) { userInput = confTable == null || confTable.Identifier.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(tableName.Table) : confTable.Identifier; Console.WriteLine(); while (identifier.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a class Identifier for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; identifier = Hinter.ReadHintedLine(new string[0], userInput: userInput); userInput = identifier; if (identifier == "!") { Console.ResetColor(); return; } } } if (permissionKey == null) { userInput = confTable == null || confTable.PermissionKey.IsTrimmedEmpty() ? "Administration:General" : confTable.PermissionKey; Console.WriteLine(); while (permissionKey.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Permission Key for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; permissionKey = Hinter.ReadHintedLine(new string[0], userInput: userInput); userInput = permissionKey; if (permissionKey == "!") { Console.ResetColor(); return; } } } if (what == null) { Console.WriteLine(); userInput = "RSU"; while (what.IsEmptyOrNull()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Choose What to Generate (R:Row, S:Repo+Svc, U=Cols+Form+Page+Grid+Dlg+Css)"); Console.ForegroundColor = ConsoleColor.Yellow; what = Hinter.ReadHintedLine(new string[0], userInput: userInput); userInput = what; if (what == "!") { Console.ResetColor(); return; } } } config.GenerateRow = what.IndexOf("R", StringComparison.OrdinalIgnoreCase) >= 0; config.GenerateService = what.IndexOf("S", StringComparison.OrdinalIgnoreCase) >= 0; config.GenerateUI = what.IndexOf("U", StringComparison.OrdinalIgnoreCase) >= 0; Console.ResetColor(); Console.WriteLine(); if (confConnection == null) { confConnection = new GeneratorConfig.Connection { Key = connectionKey }; config.Connections.Add(confConnection); } if (confTable == null) { confTable = new GeneratorConfig.Table { Identifier = identifier, Module = module, PermissionKey = permissionKey, Tablename = tableName.Tablename }; confConnection.Tables.Add(confTable); } else { confTable.Identifier = identifier; confTable.Module = module; confTable.PermissionKey = permissionKey; } File.WriteAllText(Path.Combine(projectDir, "sergen.json"), config.SaveToJson()); using (var connection = SqlConnections.New(connectionString, providerName)) { connection.Open(); var rowModel = RowGenerator.GenerateModel(connection, tableName.Schema, tableName.Table, module, connectionKey, identifier, permissionKey, config); new EntityCodeGenerator(rowModel, config, projectJson).Run(); } }
public void Run(string csproj, List <ExternalType> tsTypes) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); string[] assemblyFiles = null; if (config.ServerTypings == null || config.ServerTypings.Assemblies.IsEmptyOrNull()) { var xe = XElement.Parse(File.ReadAllText(csproj)); var xtarget = xe.Descendants("TargetFramework").FirstOrDefault(); if (xtarget == null || string.IsNullOrEmpty(xtarget.Value)) { System.Console.Error.WriteLine("Couldn't read TargetFramework from project file for server typings generation!"); Environment.Exit(1); } string outputName; var xasm = xe.Descendants("AssemblyName").FirstOrDefault(); if (xasm == null || string.IsNullOrEmpty(xasm.Value)) { outputName = Path.ChangeExtension(Path.GetFileName(csproj), null); } else { outputName = xasm.Value; } var outputExtension = ".dll"; var targetFramework = xtarget.Value; if (targetFramework.StartsWith("net") && !targetFramework.StartsWith("netcoreapp")) { outputExtension = ".exe"; } var outputPath1 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Debug/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); var outputPath2 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Release/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); if (File.Exists(outputPath1)) { if (File.Exists(outputPath2) && File.GetLastWriteTime(outputPath1) < File.GetLastWriteTime(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { assemblyFiles = new[] { outputPath1 } }; } else if (File.Exists(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { System.Console.Error.WriteLine(String.Format("Couldn't find output file for server typings generation at {0}!" + Environment.NewLine + "Make sure project is built successfully before running Sergen", outputPath1)); Environment.Exit(1); } } if (assemblyFiles == null) { if (config.ServerTypings == null) { System.Console.Error.WriteLine("ServerTypings is not configured in sergen.json file!"); Environment.Exit(1); } if (config.ServerTypings.Assemblies.IsEmptyOrNull()) { System.Console.Error.WriteLine("ServerTypings has no assemblies configured in sergen.json file!"); Environment.Exit(1); } assemblyFiles = config.ServerTypings.Assemblies; for (var i = 0; i < assemblyFiles.Length; i++) { var assemblyFile1 = Path.GetFullPath(assemblyFiles[i].Replace('/', Path.DirectorySeparatorChar)); var binDebugIdx = assemblyFile1.IndexOf("/bin/Debug/", StringComparison.OrdinalIgnoreCase); string assemblyFile2 = assemblyFile1; if (binDebugIdx >= 0) { assemblyFile2 = assemblyFile1.Substring(0, binDebugIdx) + "/bin/Release/" + assemblyFile1.Substring(binDebugIdx + "/bin/Release".Length); } assemblyFiles[i] = assemblyFile1; if (File.Exists(assemblyFile1)) { if (File.Exists(assemblyFile2) && File.GetLastWriteTime(assemblyFile1) < File.GetLastWriteTime(assemblyFile2)) { assemblyFiles[i] = assemblyFile2; } } else if (File.Exists(assemblyFile2)) { assemblyFiles[i] = assemblyFile2; } else { System.Console.Error.WriteLine(String.Format(String.Format("Assembly file '{0}' specified in sergen.json is not found! " + "This might happen when project is not successfully built or file name doesn't match the output DLL." + "Please check path in sergen.json and try again.", assemblyFile1))); Environment.Exit(1); } } } if (config.RootNamespace.IsEmptyOrNull()) { System.Console.Error.WriteLine("Please set RootNamespace option in sergen.json file!"); Environment.Exit(1); } var outDir = Path.Combine(projectDir, (config.ServerTypings.OutDir.TrimToNull() ?? "Imports/ServerTypings") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming ServerTypings at: "); Console.ResetColor(); Console.WriteLine(outDir); List <Assembly> assemblies = new List <Assembly>(); foreach (var assemblyFile in assemblyFiles) { #if COREFX using (var dynamicContext = new AssemblyResolver(assemblyFile)) { var asm = dynamicContext.Assembly; #else { var asm = Assembly.LoadFrom(assemblyFile); #endif try { asm.GetTypes(); assemblies.Add(asm); } catch (ReflectionTypeLoadException ex1) { System.Console.Error.WriteLine(String.Format("Couldn't list types in project assembly: '{0}'!", assemblyFile) + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, ex1.LoaderExceptions.Select(x => x.Message).Distinct())); Environment.Exit(1); } catch (Exception ex) { System.Console.Error.WriteLine(String.Format("Couldn't list types in project assembly: '{0}'! ", assemblyFile) + Environment.NewLine + Environment.NewLine + ex.ToString()); Environment.Exit(1); } } } Extensibility.ExtensibilityHelper.SelfAssemblies = new Assembly[] { typeof(LocalTextRegistry).Assembly, typeof(SqlConnections).Assembly, typeof(Row).Assembly, typeof(SaveRequestHandler <>).Assembly, typeof(WebSecurityHelper).Assembly }.Concat(assemblies).Distinct().ToArray(); var generator = new ServerTypingsGenerator(assemblies.ToArray()); generator.RootNamespaces.Add(config.RootNamespace); foreach (var type in tsTypes) { generator.AddTSType(type); } var codeByFilename = generator.Run(); new MultipleOutputHelper().WriteFiles(outDir, codeByFilename, "*.ts"); } }
public void Run(string csproj, List <ExternalType> tsTypes) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); if (config.ServerTypings == null) { System.Console.Error.WriteLine("ServerTypings is not configured in sergen.json file!"); Environment.Exit(1); } if (config.ServerTypings.Assemblies.IsEmptyOrNull()) { System.Console.Error.WriteLine("ServerTypings has no assemblies configured in sergen.json file!"); Environment.Exit(1); } if (config.RootNamespace.IsEmptyOrNull()) { System.Console.Error.WriteLine("Please set RootNamespace option in sergen.json file!"); Environment.Exit(1); } var outDir = Path.Combine(projectDir, (config.ServerTypings.OutDir.TrimToNull() ?? "Imports/ServerTypings") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming ServerTypings at: "); Console.ResetColor(); Console.WriteLine(outDir); var rootPath = Path.GetFullPath(config.ServerTypings.Assemblies[0].Replace('/', Path.DirectorySeparatorChar)); var loadContext = new ProjectLoadContext(csproj, Path.GetDirectoryName(rootPath)); List <Assembly> assemblies = new List <Assembly>(); foreach (var assembly in config.ServerTypings.Assemblies) { var fullName = Path.GetFullPath(assembly.Replace('/', Path.DirectorySeparatorChar)); assemblies.Add(loadContext.LoadFromAssemblyPath(fullName)); } Extensibility.ExtensibilityHelper.SelfAssemblies = new Assembly[] { typeof(LocalTextRegistry).GetAssembly(), typeof(SqlConnections).GetAssembly(), typeof(Row).GetAssembly(), typeof(SaveRequestHandler <>).GetAssembly(), typeof(WebSecurityHelper).GetAssembly() }.Concat(assemblies).Distinct().ToArray(); var generator = new ServerTypingsGenerator(assemblies.ToArray()); generator.RootNamespaces.Add(config.RootNamespace); foreach (var type in tsTypes) { generator.AddTSType(type); } var codeByFilename = generator.Run(); new MultipleOutputHelper().WriteFiles(outDir, codeByFilename, "*.ts"); }
public void Run(string csproj, string[] args) { var projectDir = Path.GetDirectoryName(csproj); var outFile = GetOption(args, "o").TrimToNull(); var connectionKey = GetOption(args, "c").TrimToNull(); var table = GetOption(args, "t").TrimToNull(); var what = GetOption(args, "w").TrimToNull(); var module = GetOption(args, "m").TrimToNull(); var identifier = GetOption(args, "i").TrimToNull(); var permissionKey = GetOption(args, "p").TrimToNull(); if (identifier != null) { CodeFileHelper.Overwrite = true; } var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); var connectionStringOptions = new ConnectionStringOptions(); if (!string.IsNullOrEmpty(config.CustomTemplates)) { Templates.TemplatePath = Path.Combine(projectDir, config.CustomTemplates); } foreach (var x in config.Connections.Where(x => !x.ConnectionString.IsEmptyOrNull())) { connectionStringOptions[x.Key] = new ConnectionStringEntry { ConnectionString = x.ConnectionString, ProviderName = x.ProviderName, Dialect = x.Dialect }; } foreach (var name in config.GetAppSettingsFiles()) { var path = Path.Combine(projectDir, name); if (File.Exists(name)) { var appSettings = JSON.ParseTolerant <AppSettingsFormat>(File.ReadAllText(path).TrimToNull() ?? "{}"); if (appSettings.Data != null) { foreach (var data in appSettings.Data) { // not so nice fix for relative paths, e.g. sqlite etc. if (data.Value.ConnectionString.Contains("../../..", StringComparison.Ordinal)) { data.Value.ConnectionString = data.Value .ConnectionString.Replace("../../..", Path.GetDirectoryName(csproj), StringComparison.Ordinal); } else if (data.Value.ConnectionString.Contains(@"..\..\..\", StringComparison.Ordinal)) { data.Value.ConnectionString = data.Value.ConnectionString.Replace(@"..\..\..\", Path.GetDirectoryName(csproj), StringComparison.Ordinal); } connectionStringOptions[data.Key] = data.Value; } } } } if (connectionStringOptions.Count == 0) { Console.Error.WriteLine("No connections in appsettings files or sergen.json!"); Environment.Exit(1); } var connectionKeys = connectionStringOptions.Keys.OrderBy(x => x).ToArray(); if (outFile == null && connectionKey == null) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("=== Table Code Generation ==="); Console.WriteLine(""); Console.ResetColor(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Available Connections:"); Console.ResetColor(); foreach (var x in connectionKeys) { Console.WriteLine(x); } Console.ResetColor(); Console.WriteLine(); } else if (connectionKey == null) { File.WriteAllText(outFile, JSON.Stringify(connectionStringOptions.Keys.OrderBy(x => x))); Environment.Exit(0); } string userInput = null; if (outFile == null && connectionKey == null) { userInput = connectionKeys.Length == 1 ? connectionKeys[0] : null; while (connectionKey == null || !connectionKeys.Contains(connectionKey, StringComparer.OrdinalIgnoreCase)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Connection: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; connectionKey = Hinter.ReadHintedLine(connectionKeys, userInput: userInput); userInput = connectionKey; if (connectionKey == "!") { Console.ResetColor(); return; } } } userInput = connectionKey; if (!connectionStringOptions.ContainsKey(userInput)) { Console.Error.WriteLine("Can't find connection with key: " + userInput + "!"); Environment.Exit(1); } if (outFile == null) { Console.ResetColor(); Console.WriteLine(); } DbProviderFactories.RegisterFactory("Microsoft.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance); DbProviderFactories.RegisterFactory("System.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance); DbProviderFactories.RegisterFactory("Microsoft.Data.Sqlite", Microsoft.Data.Sqlite.SqliteFactory.Instance); DbProviderFactories.RegisterFactory("Npgsql", Npgsql.NpgsqlFactory.Instance); DbProviderFactories.RegisterFactory("FirebirdSql.Data.FirebirdClient", FirebirdSql.Data.FirebirdClient.FirebirdClientFactory.Instance); DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySqlConnector.MySqlConnectorFactory.Instance); var sqlConnections = new DefaultSqlConnections( new DefaultConnectionStrings(connectionStringOptions)); ISchemaProvider schemaProvider; List <TableName> tableNames; using (var connection = sqlConnections.NewByKey(connectionKey)) { schemaProvider = SchemaHelper.GetSchemaProvider(connection.GetDialect().ServerType); tableNames = schemaProvider.GetTableNames(connection).ToList(); } var tables = tableNames.Select(x => x.Tablename).ToList(); var confConnection = config.Connections.FirstOrDefault(x => string.Compare(x.Key, connectionKey, StringComparison.OrdinalIgnoreCase) == 0); if (outFile == null && table == null) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Available Tables:"); Console.ResetColor(); foreach (var x in tables) { Console.WriteLine(x); } } else if (table == null) { File.WriteAllText(outFile, JSON.Stringify(tableNames.Select(x => { var xct = confConnection == null ? null : confConnection.Tables.FirstOrDefault(z => string.Compare(z.Tablename, table, StringComparison.OrdinalIgnoreCase) == 0); return(new { name = x.Tablename, module = xct == null || xct.Module.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(connectionKey) : xct.Module, permission = xct == null || xct.PermissionKey.IsTrimmedEmpty() ? "Administration:General" : xct.PermissionKey, identifier = xct == null || xct.Identifier.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(x.Table) : xct.Identifier, }); }))); Environment.Exit(0); } userInput = tables.Count == 1 ? tables[0] : null; if (userInput == null && schemaProvider.DefaultSchema != null && tables.Any(x => x.StartsWith(schemaProvider.DefaultSchema + ".", StringComparison.Ordinal))) { userInput = schemaProvider.DefaultSchema + "."; } if (outFile == null) { Console.WriteLine(); while (table == null || !tables.Contains(table, StringComparer.OrdinalIgnoreCase)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; table = Hinter.ReadHintedLine(tables, userInput: userInput); userInput = table; if (table == "!") { Console.ResetColor(); return; } } } userInput = table; var tableName = tableNames.First(x => string.Compare(x.Tablename, userInput, StringComparison.OrdinalIgnoreCase) == 0); if (tableName == null) { Console.Error.WriteLine("Can't find table with name: " + userInput + "!"); Environment.Exit(1); } var confTable = confConnection == null ? null : confConnection.Tables.FirstOrDefault(x => string.Compare(x.Tablename, table, StringComparison.OrdinalIgnoreCase) == 0); if (module == null) { userInput = confTable == null || confTable.Module.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(connectionKey) : confTable.Module; Console.WriteLine(); while (module.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Module name for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; module = Hinter.ReadHintedLine(Array.Empty <string>(), userInput: userInput); userInput = module; if (module == "!") { Console.ResetColor(); return; } } } if (identifier == null) { userInput = confTable == null || confTable.Identifier.IsEmptyOrNull() ? RowGenerator.ClassNameFromTableName(tableName.Table) : confTable.Identifier; Console.WriteLine(); while (identifier.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a class Identifier for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; identifier = Hinter.ReadHintedLine(Array.Empty <string>(), userInput: userInput); userInput = identifier; if (identifier == "!") { Console.ResetColor(); return; } } } if (permissionKey == null) { userInput = confTable == null || confTable.PermissionKey.IsTrimmedEmpty() ? "Administration:General" : confTable.PermissionKey; Console.WriteLine(); while (permissionKey.IsTrimmedEmpty()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Enter a Permission Key for table: ('!' to abort)"); Console.ForegroundColor = ConsoleColor.Yellow; permissionKey = Hinter.ReadHintedLine(Array.Empty <string>(), userInput: userInput); userInput = permissionKey; if (permissionKey == "!") { Console.ResetColor(); return; } } } if (what == null) { Console.WriteLine(); userInput = "RSUC"; while (what.IsEmptyOrNull()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Choose What to Generate (R:Row, S:Repo+Svc, U=UI, C=Custom)"); Console.ForegroundColor = ConsoleColor.Yellow; what = Hinter.ReadHintedLine(Array.Empty <string>(), userInput: userInput); userInput = what; if (what == "!") { Console.ResetColor(); return; } } } config.GenerateRow = what.IndexOf("R", StringComparison.OrdinalIgnoreCase) >= 0; config.GenerateService = what.IndexOf("S", StringComparison.OrdinalIgnoreCase) >= 0; config.GenerateUI = what.IndexOf("U", StringComparison.OrdinalIgnoreCase) >= 0; config.GenerateCustom = what.IndexOf("C", StringComparison.OrdinalIgnoreCase) >= 0; Console.ResetColor(); Console.WriteLine(); if (confConnection == null) { confConnection = new GeneratorConfig.Connection { Key = connectionKey }; config.Connections.Add(confConnection); } if (confTable == null) { confTable = new GeneratorConfig.Table { Identifier = identifier, Module = module, PermissionKey = permissionKey, Tablename = tableName.Tablename }; confConnection.Tables.Add(confTable); } else { confTable.Identifier = identifier; confTable.Module = module; confTable.PermissionKey = permissionKey; } File.WriteAllText(Path.Combine(projectDir, "sergen.json"), config.SaveToJson()); using (var connection = sqlConnections.NewByKey(connectionKey)) { connection.Open(); var csprojContent = File.ReadAllText(csproj); var net5Plus = !new Regex(@"\<TargetFramework\>.*netcoreapp.*\<\/TargetFramework\>", RegexOptions.Multiline | RegexOptions.Compiled) .IsMatch(csprojContent); var rowModel = RowGenerator.GenerateModel(connection, tableName.Schema, tableName.Table, module, connectionKey, identifier, permissionKey, config, net5Plus); rowModel.AspNetCore = true; rowModel.NET5Plus = net5Plus; var kdiff3Paths = new[] { config.KDiff3Path }; CodeFileHelper.Kdiff3Path = kdiff3Paths.FirstOrDefault(File.Exists); CodeFileHelper.TSCPath = config.TSCPath ?? "tsc"; new EntityCodeGenerator(rowModel, config, csproj).Run(); } }
public void Run(string csproj) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); config.MVC = config.MVC ?? new GeneratorConfig.MVCConfig(); var outDir = Path.Combine(projectDir, (config.MVC.OutDir.TrimToNull() ?? "Imports/MVC") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming MVC at: "); Console.ResetColor(); Console.WriteLine(outDir); string[] stripViewPaths = config.MVC.StripViewPaths ?? new string[] { "Modules/", "Views/" }; var rootDir = projectDir + Path.DirectorySeparatorChar; var searchViewPaths = (config.MVC.SearchViewPaths ?? new string[] { "Modules/", "Views/" }) .Select(x => Path.Combine(rootDir, x.Replace('/', Path.DirectorySeparatorChar))); IEnumerable <string> files = new List <string>(); foreach (var path in searchViewPaths) { files = files.Concat(Directory.GetFiles(path, "*.cshtml", SearchOption.AllDirectories)); } Func <string, string> getName = s => { var path = s.Substring(rootDir.Length); var name = Path.ChangeExtension(path, null).Replace('\\', '/'); foreach (var strip in stripViewPaths) { if (name.StartsWith(strip, StringComparison.OrdinalIgnoreCase)) { name = name.Substring(strip.Length); } } return(name); }; files = files.OrderBy(x => getName(x)); StringBuilder sb = new StringBuilder(); sb.AppendLine("using System;"); sb.AppendLine(""); sb.AppendLine("namespace MVC"); sb.AppendLine("{"); sb.AppendLine(" public static class Views"); sb.AppendLine(" {"); var last = new string[0]; var processed = new HashSet <string>(); foreach (var file in files) { var path = file.Substring(rootDir.Length); var name = getName(file); if (name.StartsWith("App_Code/", StringComparison.OrdinalIgnoreCase) || name.EndsWith("_ViewStart", StringComparison.OrdinalIgnoreCase) || name.EndsWith("_ViewImports", StringComparison.OrdinalIgnoreCase) || processed.Contains(name)) { continue; } processed.Add(name); var parts = name.Split(new char[] { '/' }); if (parts.Length <= 1) { continue; } for (var i = last.Length; i > parts.Length; i--) { var close = (new String(' ', (i * 4)) + "}"); sb.AppendLine(close); } var x = Math.Min(last.Length, parts.Length) - 2; while (x >= 0 && last[x] != parts[x]) { var close = (new String(' ', ((x + 2) * 4)) + "}"); x--; sb.AppendLine(close); sb.AppendLine(); } for (var i = Math.Max(x + 1, 0); i < parts.Length - 1; i++) { var indent = new String(' ', (i + 2) * 4); var u = parts[i]; if (i > 0 && parts[i - 1] == u) { u = u + "_"; } sb.AppendLine(indent + "public static class " + u); sb.AppendLine(indent + "{"); } var n = parts[parts.Length - 1].Replace(".", "_"); if (parts.Length - 1 > 0 && parts[parts.Length - 2] == n) { n += "_"; } sb.Append(new String(' ', (parts.Length + 1) * 4)); sb.AppendLine("public const string " + n + " = \"~/" + path.Replace(@"\", "/") + "\";"); last = parts; } for (var i = last.Length - 1; i > 0; i--) { sb.AppendLine(new String(' ', ((i + 1) * 4)) + "}" + Environment.NewLine); } sb.AppendLine(" }"); sb.AppendLine("}"); new MultipleOutputHelper().WriteFiles(outDir, new SortedDictionary <string, string> { { "MVC.cs", sb.ToString() } }); }
public void Run(string csproj) { var process = Process.Start(new ProcessStartInfo { FileName = "dotnet", WorkingDirectory = Path.GetDirectoryName(csproj), CreateNoWindow = true, Arguments = "restore \"" + csproj + "\"" }); process.WaitForExit(); if (process.ExitCode > 0) { Console.Error.WriteLine("Error executing dotnet restore!"); Environment.Exit(process.ExitCode); } var packagesDir = new PackageHelper().DeterminePackagesPath(); var visited = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var queue = new Queue <Tuple <string, string, string> >(); Func <string, bool> skipPackage = id => { if (visited.Contains(id)) { return(true); } foreach (var skip in skipPackages) { if (id.StartsWith(skip, StringComparison.OrdinalIgnoreCase)) { return(true); } } visited.Add(id); return(false); }; var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); EnumerateProjectDeps(csproj, (fw, id, ver) => { if (!skipPackage(id) && !string.IsNullOrEmpty(ver)) { queue.Enqueue(new Tuple <string, string, string>(fw, id, ver)); } }); GlobFilter include = null; if (config.Restore?.Include.IsEmptyOrNull() == false) { include = new GlobFilter(config.Restore.Include); } GlobFilter exclude = null; if (config.Restore?.Exclude.IsEmptyOrNull() == false) { exclude = new GlobFilter(config.Restore.Exclude); } while (queue.Count > 0) { var dep = queue.Dequeue(); var id = dep.Item2; var ver = dep.Item3.Trim(); if (ver.EndsWith("-*", StringComparison.Ordinal)) { ver = ver.Substring(0, ver.Length - 2); } else if (ver.StartsWith("[", StringComparison.Ordinal) && ver.EndsWith("]", StringComparison.Ordinal)) { ver = ver.Substring(1, ver.Length - 2).Trim(); } var packageFolder = Path.Combine(Path.Combine(packagesDir, id), ver); if (!Directory.Exists(packageFolder)) { packageFolder = Path.Combine(Path.Combine(packagesDir, id.ToLowerInvariant()), ver); if (!Directory.Exists(packageFolder)) { var myPackagesDir = Path.Combine(packagesDir, "..", "my-packages"); packageFolder = Path.Combine(myPackagesDir, id, ver); if (!Directory.Exists(packageFolder)) { packageFolder = Path.Combine(myPackagesDir, id.ToLowerInvariant(), ver); } } } var nuspecFile = Path.Combine(packageFolder, id + ".nuspec"); if (!File.Exists(nuspecFile)) { nuspecFile = Path.Combine(packageFolder, id.ToLowerInvariant() + ".nuspec"); if (!File.Exists(nuspecFile)) { continue; } } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Processing: " + id); Console.ResetColor(); var contentRoot = Path.Combine(packageFolder, "Content/".Replace('/', Path.DirectorySeparatorChar)); if (!Directory.Exists(contentRoot)) { contentRoot = Path.Combine(packageFolder, "content/".Replace('/', Path.DirectorySeparatorChar)); } if (Directory.Exists(contentRoot)) { var targetRoot = Path.GetDirectoryName(csproj); foreach (var file in Directory.GetFiles(contentRoot, "*.*", SearchOption.AllDirectories)) { var extension = Path.GetExtension(file); if (string.Compare(extension, ".transform", StringComparison.OrdinalIgnoreCase) == 0) { continue; } var relative = file.Substring(contentRoot.Length); // toastr! if (relative.StartsWith("content/".Replace('/', Path.DirectorySeparatorChar), StringComparison.Ordinal)) { relative = "Content/".Replace('/', Path.DirectorySeparatorChar) + relative.Substring("content/".Length); } else if (relative.StartsWith("scripts/", StringComparison.Ordinal)) { relative = "Scripts/".Replace('/', Path.DirectorySeparatorChar) + relative.Substring("content/".Length); } else if (relative.StartsWith("Fonts/", StringComparison.Ordinal)) { relative = "fonts/".Replace('/', Path.DirectorySeparatorChar) + relative.Substring("fonts/".Length); } if (relative.StartsWith("scripts/typings/".Replace('/', Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase)) { relative = relative.Substring("scripts/".Length); } else { relative = Path.Combine("wwwroot", relative); } if (include != null && !include.IsMatch(relative)) { continue; } if (exclude != null && exclude.IsMatch(relative)) { continue; } var target = Path.Combine(targetRoot, relative); if (File.Exists(target)) { if (!File.ReadAllBytes(target) .SequenceEqual(File.ReadAllBytes(file))) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, true); } } else { if (!Directory.Exists(target)) { Directory.CreateDirectory(Path.GetDirectoryName(target)); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, false); } } } var nuspecContent = File.ReadAllText(nuspecFile); var nuspec = XElement.Parse(nuspecContent); var meta = nuspec.Elements().Where(x => x.Name?.LocalName == "metadata").FirstOrDefault(); if (meta == null) { continue; } var deps = meta.Elements().Where(x => x.Name?.LocalName == "dependencies").FirstOrDefault();; if (deps == null) { continue; } var fw = dep.Item1; var groups = deps.Elements().Where(x => x.Name?.LocalName == "group"); if (groups.Any()) { foreach (var group in groups) { var target = group.Attribute("targetFramework").Value; if (string.IsNullOrEmpty(target) || string.Compare(target, fw, StringComparison.OrdinalIgnoreCase) == 0 || target.StartsWith(".NETStandard", StringComparison.OrdinalIgnoreCase) || target.StartsWith("netstandard", StringComparison.OrdinalIgnoreCase) || target.StartsWith("netcore", StringComparison.OrdinalIgnoreCase) || target.StartsWith("net", StringComparison.OrdinalIgnoreCase)) { foreach (var dep2 in group.Elements().Where(x => x.Name?.LocalName == "dependency")) { var id2 = dep2.Attribute("id").Value; if (!skipPackage(id2)) { queue.Enqueue(new Tuple <string, string, string>(fw, id2, dep2.Attribute("version").Value)); } } } } } else { foreach (var dep2 in deps.Elements().Where(x => x.Name?.LocalName == "dependency")) { var id2 = dep2.Attribute("id").Value; if (!skipPackage(id2)) { queue.Enqueue(new Tuple <string, string, string>(fw, id2, dep2.Attribute("version").Value)); } } } } }
public void Run(string csproj, List <ExternalType> tsTypes) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); string[] assemblyFiles = null; if (config.ServerTypings == null || config.ServerTypings.Assemblies.IsEmptyOrNull()) { var xe = XElement.Parse(File.ReadAllText(csproj)); var xtarget = xe.Descendants("TargetFramework").FirstOrDefault(); if (xtarget == null || string.IsNullOrEmpty(xtarget.Value)) { System.Console.Error.WriteLine("Couldn't read TargetFramework from project file for server typings generation!"); Environment.Exit(1); } string outputName; var xasm = xe.Descendants("AssemblyName").FirstOrDefault(); if (xasm == null || string.IsNullOrEmpty(xasm.Value)) { outputName = Path.ChangeExtension(Path.GetFileName(csproj), null); } else { outputName = xasm.Value; } var outputExtension = ".dll"; var targetFramework = xtarget.Value; if (targetFramework.StartsWith("net") && !targetFramework.StartsWith("netcoreapp")) { outputExtension = ".exe"; } var outputPath1 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Debug/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); var outputPath2 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Release/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); if (File.Exists(outputPath1)) { if (File.Exists(outputPath2) && File.GetLastWriteTime(outputPath1) < File.GetLastWriteTime(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { assemblyFiles = new[] { outputPath1 } }; } else if (File.Exists(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { System.Console.Error.WriteLine(String.Format("Couldn't find output file for server typings generation at {0}!" + Environment.NewLine + "Make sure project is built successfully before running Sergen", outputPath1)); Environment.Exit(1); } } if (assemblyFiles == null) { if (config.ServerTypings == null) { System.Console.Error.WriteLine("ServerTypings is not configured in sergen.json file!"); Environment.Exit(1); } if (config.ServerTypings.Assemblies.IsEmptyOrNull()) { System.Console.Error.WriteLine("ServerTypings has no assemblies configured in sergen.json file!"); Environment.Exit(1); } assemblyFiles = config.ServerTypings.Assemblies; for (var i = 0; i < assemblyFiles.Length; i++) { var assemblyFile1 = Path.GetFullPath(assemblyFiles[i].Replace('/', Path.DirectorySeparatorChar)); var binDebugIdx = assemblyFile1.IndexOf("/bin/Debug/", StringComparison.OrdinalIgnoreCase); string assemblyFile2 = assemblyFile1; if (binDebugIdx >= 0) { assemblyFile2 = assemblyFile1.Substring(0, binDebugIdx) + "/bin/Release/" + assemblyFile1.Substring(binDebugIdx + "/bin/Release".Length); } assemblyFiles[i] = assemblyFile1; if (File.Exists(assemblyFile1)) { if (File.Exists(assemblyFile2) && File.GetLastWriteTime(assemblyFile1) < File.GetLastWriteTime(assemblyFile2)) { assemblyFiles[i] = assemblyFile2; } } else if (File.Exists(assemblyFile2)) { assemblyFiles[i] = assemblyFile2; } else { System.Console.Error.WriteLine(String.Format(String.Format("Assembly file '{0}' specified in sergen.json is not found! " + "This might happen when project is not successfully built or file name doesn't match the output DLL." + "Please check path in sergen.json and try again.", assemblyFile1))); Environment.Exit(1); } } } if (config.RootNamespace.IsEmptyOrNull()) { System.Console.Error.WriteLine("Please set RootNamespace option in sergen.json file!"); Environment.Exit(1); } var generator = new ServerTypingsGenerator(assemblyFiles.ToArray()); generator.LocalTexts = config.ServerTypings != null && config.ServerTypings.LocalTexts; var appSettings = Path.Combine(projectDir, "appsettings.json"); if (generator.LocalTexts && File.Exists(appSettings)) { try { var obj = JObject.Parse(File.ReadAllText(appSettings)); var packages = ((obj["AppSettings"] as JObject)?["LocalTextPackages"] as JObject); if (packages != null) { foreach (var p in packages.PropertyValues()) { foreach (var x in p.Values <string>()) { generator.LocalTextFilters.Add(x); } } } } catch (Exception ex) { System.Console.WriteLine("Error occured while parsing appsettings.json!" + Environment.NewLine + ex.ToString()); } } var outDir = Path.Combine(projectDir, (config.ServerTypings.OutDir.TrimToNull() ?? "Imports/ServerTypings") .Replace('/', Path.DirectorySeparatorChar)); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("Transforming ServerTypings at: "); Console.ResetColor(); Console.WriteLine(outDir); generator.RootNamespaces.Add(config.RootNamespace); foreach (var type in tsTypes) { generator.AddTSType(type); } var codeByFilename = generator.Run(); new MultipleOutputHelper().WriteFiles(outDir, codeByFilename, "*.ts"); }
public static void Run(string csproj, List <ExternalType> tsTypes) { var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); string[] assemblyFiles = null; if (config.ServerTypings == null || config.ServerTypings.Assemblies.IsEmptyOrNull()) { var targetFramework = ProjectFileHelper.ExtractTargetFrameworkFrom(csproj); if (string.IsNullOrEmpty(targetFramework)) { Console.Error.WriteLine("Couldn't read TargetFramework from " + "project file for server typings generation!"); Environment.Exit(1); } string outputName = ProjectFileHelper.ExtractAssemblyNameFrom(csproj) ?? Path.ChangeExtension(Path.GetFileName(csproj), null); var outputExtension = ".dll"; if (targetFramework.StartsWith("net", StringComparison.OrdinalIgnoreCase) && !targetFramework.StartsWith("netcoreapp", StringComparison.Ordinal) && targetFramework.IndexOf('.', StringComparison.Ordinal) < 0) { outputExtension = ".exe"; } var outputPath1 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Debug/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); var outputPath2 = Path.Combine(Path.GetDirectoryName(csproj), "bin/Release/" + targetFramework + "/" + outputName + outputExtension) .Replace('/', Path.DirectorySeparatorChar); if (File.Exists(outputPath1)) { if (File.Exists(outputPath2) && File.GetLastWriteTime(outputPath1) < File.GetLastWriteTime(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { assemblyFiles = new[] { outputPath1 } }; } else if (File.Exists(outputPath2)) { assemblyFiles = new[] { outputPath2 } } ; else { Console.Error.WriteLine(string.Format(CultureInfo.CurrentCulture, "Couldn't find output file for server typings generation at {0}!" + Environment.NewLine + "Make sure project is built successfully before running Sergen", outputPath1)); Environment.Exit(1); } } if (assemblyFiles == null) { if (config.ServerTypings == null) { Console.Error.WriteLine("ServerTypings is not configured in sergen.json file!"); Environment.Exit(1); } if (config.ServerTypings.Assemblies.IsEmptyOrNull()) { Console.Error.WriteLine("ServerTypings has no assemblies configured in sergen.json file!"); Environment.Exit(1); } assemblyFiles = config.ServerTypings.Assemblies; for (var i = 0; i < assemblyFiles.Length; i++) { var assemblyFile1 = Path.GetFullPath(assemblyFiles[i].Replace('/', Path.DirectorySeparatorChar)); var binDebugIdx = assemblyFile1.IndexOf("/bin/Debug/", StringComparison.OrdinalIgnoreCase); string assemblyFile2 = assemblyFile1; if (binDebugIdx >= 0) { assemblyFile2 = assemblyFile1.Substring(0, binDebugIdx) + "/bin/Release/" + assemblyFile1[(binDebugIdx + "/bin/Release".Length)..];
public void Run(string csproj) { var packagesDir = new PackageHelper().DeterminePackagesPath(); var visited = new HashSet <string>(StringComparer.OrdinalIgnoreCase); Func <string, bool> skipPackage = id => { if (visited.Contains(id)) { return(true); } foreach (var skip in skipPackages) { if (id.StartsWith(skip, StringComparison.OrdinalIgnoreCase)) { return(true); } } visited.Add(id); return(false); }; var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); GlobFilter include = null; if (config.Restore?.Include.IsEmptyOrNull() == false) { include = new GlobFilter(config.Restore.Include); } GlobFilter exclude = null; if (config.Restore?.Exclude.IsEmptyOrNull() == false) { exclude = new GlobFilter(config.Restore.Exclude); } var targetRoot = Path.GetDirectoryName(csproj); var restoredFromProjectReference = new HashSet <string>(StringComparer.OrdinalIgnoreCase); void restoreFile(string file, string relative) { relative = PathHelper.ToPath(relative); if (include != null && !include.IsMatch(relative)) { return; } if (exclude != null && exclude.IsMatch(relative)) { return; } if (restoredFromProjectReference.Contains(relative)) { return; } var target = Path.Combine(targetRoot, relative); if (File.Exists(target)) { if (!File.ReadAllBytes(target) .SequenceEqual(File.ReadAllBytes(file))) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, true); } } else { if (!Directory.Exists(target)) { Directory.CreateDirectory(Path.GetDirectoryName(target)); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Restoring: " + relative); Console.ResetColor(); File.Copy(file, target, false); } } try { foreach (var reference in EnumerateProjectReferences(csproj, new HashSet <string>(StringComparer.OrdinalIgnoreCase))) { var project = new Project(reference); try { foreach (var item in project.AllEvaluatedItems .Where(x => string.Equals(x.ItemType, "TypingsToPackage", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "Content", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "None", StringComparison.OrdinalIgnoreCase) || string.Equals(x.ItemType, "TypeScriptCompile", StringComparison.OrdinalIgnoreCase)) .Where(x => x.EvaluatedInclude?.EndsWith(".d.ts", StringComparison.OrdinalIgnoreCase) == true)) { var sourceFile = Path.Combine(Path.GetDirectoryName(reference), item.EvaluatedInclude); if (!File.Exists(sourceFile)) { continue; } if (!string.Equals(item.ItemType, "TypingsToPackage", StringComparison.OrdinalIgnoreCase) && item.GetMetadataValue("Pack") != "true") { continue; } var packagePath = item.GetMetadataValue("PackagePath")?.Trim(); if (!string.IsNullOrEmpty(packagePath)) { foreach (var path in packagePath.Split(';', StringSplitOptions.RemoveEmptyEntries)) { if (!PathHelper.ToUrl(path).StartsWith("typings/", StringComparison.OrdinalIgnoreCase)) { continue; } restoreFile(sourceFile, path); restoredFromProjectReference.Add(path); } } } } finally { ProjectCollection.GlobalProjectCollection.UnloadAllProjects(); } } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } var queue = new Queue <(string ID, string Version)>(); foreach (var x in EnumeratePackageReferences(csproj)) { if (!skipPackage(x.Id) && !string.IsNullOrEmpty(x.Version)) { queue.Enqueue(x); } } ; while (queue.Count > 0) { var dep = queue.Dequeue(); var id = dep.ID; var ver = dep.Version.Trim(); if (ver.EndsWith("-*", StringComparison.Ordinal)) { ver = ver.Substring(0, ver.Length - 2); } else if (ver.StartsWith("[", StringComparison.Ordinal) && ver.EndsWith("]", StringComparison.Ordinal)) { ver = ver.Substring(1, ver.Length - 2).Trim(); } var packageFolder = Path.Combine(Path.Combine(packagesDir, id), ver); if (!Directory.Exists(packageFolder)) { packageFolder = Path.Combine(Path.Combine(packagesDir, id.ToLowerInvariant()), ver); if (!Directory.Exists(packageFolder)) { var myPackagesDir = Path.Combine(packagesDir, "..", "my-packages"); packageFolder = Path.Combine(myPackagesDir, id, ver); if (!Directory.Exists(packageFolder)) { packageFolder = Path.Combine(myPackagesDir, id.ToLowerInvariant(), ver); } } } var nuspecFile = Path.Combine(packageFolder, id + ".nuspec"); if (!File.Exists(nuspecFile)) { nuspecFile = Path.Combine(packageFolder, id.ToLowerInvariant() + ".nuspec"); if (!File.Exists(nuspecFile)) { continue; } } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("Processing: " + id); Console.ResetColor(); var contentRoot = Path.Combine(packageFolder, "content"); if (!Directory.Exists(contentRoot)) { contentRoot = Path.Combine(packageFolder, "Content"); } if (Directory.Exists(contentRoot)) { foreach (var file in Directory.GetFiles(contentRoot, "*.*", SearchOption.AllDirectories)) { var extension = Path.GetExtension(file); if (string.Compare(extension, ".transform", StringComparison.OrdinalIgnoreCase) == 0) { continue; } var relative = PathHelper.ToUrl(file.Substring(contentRoot.Length + 1)); // normalize paths as Content, Scripts, fonts and typings (these are exact cases expected) if (relative.StartsWith("content/", StringComparison.OrdinalIgnoreCase)) { relative = "Content/" + relative["content/".Length..];
public ExitCodes Run() { AnsiConsole.WriteLine(); AnsiConsole.Write(new Spectre.Console.Rule($"[bold springgreen3_1]Table Code Generation[/]") { Alignment = Justify.Left }); var csproj = SelectCsProj(); if (csproj is null) { return(ExitCodes.NoProjectFiles); } var projectDir = Path.GetDirectoryName(csproj); var config = GeneratorConfig.LoadFromFile(Path.Combine(projectDir, "sergen.json")); if (!string.IsNullOrEmpty(config.CustomTemplates)) { Templates.TemplatePath = Path.Combine(projectDir, config.CustomTemplates); } var connectionString = SelectConnectionString(config, projectDir); if (connectionString.connectionKey is null) { return(ExitCodes.NoConnectionString); } var confConnection = config.Connections?.FirstOrDefault(x => string.Compare(x.Key, connectionString.connectionKey, StringComparison.OrdinalIgnoreCase) == 0); var tables = SelectedTables(connectionString.sqlConnections, connectionString.connectionKey); var module = string.Empty; var permissionKey = "Administration:General"; var generateData = new Dictionary <string, (string module, string identifier, string permissionKey, TableName table)>(); foreach (var table in tables.selectedTables) { var confTable = confConnection?.Tables.FirstOrDefault(x => string.Compare(x.Tablename, table.Tablename, StringComparison.OrdinalIgnoreCase) == 0); if (string.IsNullOrEmpty(module)) { module = confTable?.Module?.TrimToNull() is null? RowGenerator.ClassNameFromTableName(connectionString.connectionKey) : confTable.Module; } module = SelectModule(table.Tablename, module); var defaultIdentifier = confTable?.Identifier?.TrimToNull() is null? RowGenerator.ClassNameFromTableName(table.Table) : confTable.Identifier; var identifier = SelectIdentifier(table.Tablename, defaultIdentifier); permissionKey = SelectPermissionKey(table.Tablename, confTable?.PermissionKey?.TrimToNull() ?? permissionKey); generateData.Add(table.Tablename, (module, identifier, permissionKey, table)); } var whatToGenerate = SelectWhatToGenerate(); config.GenerateRow = whatToGenerate.Contains("Row"); config.GenerateService = whatToGenerate.Contains("Repository & Service"); config.GenerateUI = whatToGenerate.Contains("User Interface"); config.GenerateCustom = whatToGenerate.Contains("Custom"); foreach (var data in generateData) { var confTable = confConnection?.Tables.FirstOrDefault(x => string.Compare(x.Tablename, data.Key, StringComparison.OrdinalIgnoreCase) == 0); if (confConnection == null) { confConnection = new GeneratorConfig.Connection { Key = connectionString.connectionKey }; config.Connections.Add(confConnection); } if (confTable == null) { confTable = new GeneratorConfig.Table { Identifier = data.Value.identifier, Module = data.Value.module, PermissionKey = data.Value.permissionKey, Tablename = data.Key }; confConnection.Tables.Add(confTable); } else { confTable.Identifier = data.Value.identifier; confTable.Module = data.Value.module; confTable.PermissionKey = data.Value.permissionKey; } File.WriteAllText(Path.Combine(projectDir, "sergen.json"), config.SaveToJson()); using var connection = connectionString.sqlConnections.NewByKey(connectionString.connectionKey); connection.Open(); var csprojContent = File.ReadAllText(csproj); var net5Plus = !new Regex(@"\<TargetFramework\>.*netcoreapp.*\<\/TargetFramework\>", RegexOptions.Multiline | RegexOptions.Compiled) .IsMatch(csprojContent); var rowModel = RowGenerator.GenerateModel(connection, data.Value.table.Schema, data.Value.table.Table, data.Value.module, connectionString.connectionKey, data.Value.identifier, data.Value.permissionKey, config, net5Plus); rowModel.AspNetCore = true; rowModel.NET5Plus = net5Plus; var kdiff3Paths = new[] { config.KDiff3Path }; CodeFileHelper.Kdiff3Path = kdiff3Paths.FirstOrDefault(File.Exists); CodeFileHelper.TSCPath = config.TSCPath ?? "tsc"; new EntityCodeGenerator(rowModel, config, csproj).Run(); } return(ExitCodes.Success); }