LoadFromFile() public static method

public static LoadFromFile ( string sergenJson ) : GeneratorConfig
sergenJson string
return GeneratorConfig
        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");
        }
Beispiel #2
0
        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();
Beispiel #4
0
        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();
            }
        }
Beispiel #5
0
        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");
        }
Beispiel #7
0
        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();
            }
        }
Beispiel #8
0
        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));
                        }
                    }
                }
            }
        }
Beispiel #10
0
        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");
        }
Beispiel #11
0
        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)..];
Beispiel #12
0
        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);
            }