Пример #1
0
        public static RootConfig CreateFromAssembly(AssemblyCache cache, string assembly, GenerateContractMode mode, bool internalVisibility)
        {
            RootConfig root = new RootConfig(cache)
            {
                Contracts = new List<ProxyConfig>()
            };

            Assembly loadedAssembly = null;
            if (!string.IsNullOrEmpty(assembly) && File.Exists(assembly))
            {
                root.Assemblies = new List<string> { Path.GetFullPath(assembly) };
                loadedAssembly = cache.Loader.Load(assembly);
            }
            else
            {
                loadedAssembly = cache.HostedAssembly;
            }

            if (loadedAssembly != null)
            {
                foreach (var type in root.AssemblyCache.GetTypes(loadedAssembly))
                {
                    root.AddContract(type.GetTypeInfo(), mode, internalVisibility);
                };
            }

            return root;
        }
Пример #2
0
        private int AddContracts(RootConfig rootConfig, List<string> contracts, GenerateContractMode mode, bool internalVisibility)
        {
            if (!contracts.Any() || contracts.Any(c => c.EndsWith(".*", StringComparison.OrdinalIgnoreCase)))
            {
                try
                {
                    rootConfig.AddAllContracts(mode, internalVisibility);
                }
                catch (Exception e)
                {
                    return HandleError($"Failed to resolve contracts", e);
                }

                return 0;
            }

            foreach (var contract in contracts)
            {
                if (contract.EndsWith(".*", StringComparison.OrdinalIgnoreCase))
                {
                    var ns = contract.TrimEnd('*', '.');
                    try
                    {
                        rootConfig.AddContractsFromNamespace(ns, mode, internalVisibility);
                    }
                    catch (Exception e)
                    {
                        return HandleError($"Failed to resolve contracts: {contract.White().Bold()}", e);
                    }
                }
                else
                {
                    try
                    {
                        rootConfig.AddContract(contract, mode, internalVisibility);
                    }
                    catch (Exception e)
                    {
                        return HandleError($"Failed to resolve contract: {contract.White().Bold()}", e);
                    }
                }
            }

            return 0;
        }
Пример #3
0
        private static RootConfig CreateSampleConfiguration(AssemblyCache cache)
        {
            RootConfig rootConfig = new RootConfig(cache);
            rootConfig.Modifier = "<public|internal>";
            rootConfig.Assemblies = new List<string> { "<AssemblyPath>", "<AssemblyPath>", "<AssemblyPath>" };
            rootConfig.Generators = new List<GeneratorConfig>
                                        {
                                            new GeneratorConfig
                                                {
                                                    Name = "<GeneratorName>",
                                                    Type = "<FullTypeName>",
                                                    Properties =
                                                        new Dictionary<string, string>
                                                            {
                                                                {
                                                                    "<Name>",
                                                                    "<Value>"
                                                                }
                                                            }
                                                }
                                        };

            rootConfig.Contracts = new List<ProxyConfig>();
            rootConfig.Contracts.Add(
                new ProxyConfig
                    {
                        Contract = "<Type>",
                        Modifier = "<public|internal>",
                        Context = "<Context> // passed to user code generators",
                        Excluded = new List<string> { "<FullTypeName>", "<FullTypeName>" },
                        ForceAsync = true,
                        Generator = "<GeneratorName>",
                        Output = "<Path>",
                        Suffix = "<Suffix> // suffix for generated client proxy, defaults to 'Proxy'",
                        Namespace = "<Namespace> // namespace of generated proxy, defaults to contract namespace if null",
                        Name = "<ProxyName> // name of generated proxy, defaults to 'ContractName + Suffix' if null",
                        ExcludedInterfaces = new List<string> { "<FullTypeName>", "<FullTypeName>" }
                    });

            return rootConfig;
        }
Пример #4
0
        public int Main(string[] args)
        {
            var app = new CommandLineApplication();
            app.Name = "bolt";
            app.VersionOption("--version", GetVersion());
            app.OnExecute(() =>
            {
                app.ShowHelp();
                return 2;
            });

            app.Command("example", c =>
            {
                c.Description = "Generates configuration file example.";
                var argRoot = c.Argument("[output]", "The output configuration file path. If no value is specified then 'bolt.example.json' file will be generated in current directory.");
                c.HelpOption("-?|-h|--help");

                c.OnExecute(() =>
                {
                    try
                    {
                        string result = CreateSampleConfiguration(_cache).Serialize();
                        string outputFile = PathHelpers.GetOutput(Directory.GetCurrentDirectory(), argRoot.Value, "bolt.example.json");
                        bool exist = File.Exists(outputFile);
                        File.WriteAllText(outputFile, result);
                        if (exist)
                        {
                            Console.WriteLine($"Examle overwritten: {outputFile.White().Bold()}".Green().Bold());
                        }
                        else
                        {
                            Console.WriteLine($"Example created: {outputFile.White().Bold()}".Green());
                        }
                    }
                    catch(Exception e)
                    {
                        return HandleError("Failed to generate example configuration file.", e);
                    }

                    return 0;
                });
            });

            app.Command("config", c =>
            {
                c.Description = "Generates configuration file for all interfaces in assembly.";
                var input = c.Argument("[input]", "Assembly used to generate configuration file.");
                var output = c.Option("--output <PATH>", "Directory or configuration file path. If no path is specified then the 'bolt.configuration.json' configuration file will be generated in current directory.", CommandOptionType.SingleValue);

                c.HelpOption("-?|-h|--help");

                c.OnExecute(() =>
                {
                    if (string.IsNullOrEmpty(input.Value) && !_cache.IsHosted())
                    {
                        Console.WriteLine("Assembly must be specified.".Yellow());
                        return 1;
                    }

                    if (!_cache.IsHosted() && !File.Exists(input.Value))
                    {
                        Console.WriteLine($"Assembly not found: {input.Value.White()}".Yellow());
                        return 1;
                    }

                    try
                    {
                        string json = RootConfig.CreateFromAssembly(_cache, input.Value, GenerateContractMode.All, false).Serialize();
                        var outputFile = PathHelpers.GetOutput(Path.GetDirectoryName(input.Value), output.Value(), "bolt.configuration.json");
                        bool exist = File.Exists(outputFile);
                        File.WriteAllText(outputFile, json);
                        if (exist)
                        {
                            Console.WriteLine($"Configuration overwritten: {outputFile.White().Bold()}".Green().Bold());
                        }
                        else
                        {
                            Console.WriteLine($"Configuration created: {outputFile.White().Bold()}".Green());
                        }
                    }
                    catch (Exception e)
                    {
                        return HandleError("Failed to generate Bolt configuration file.", e);
                    }

                    return 0;
                });
            });

            app.Command("code", c =>
            {
                var values = Enum.GetValues(typeof(GenerateContractMode)).OfType<GenerateContractMode>().Select(v => v.ToString());
                var rawModeValues = string.Join(",", values);

                c.Description = "Generates code from assembly or from configuration file.";
                var input = c.Argument("[input]", "Path to the assembly or configuration file.");
                var output = c.Option("--output <DIRECTORY>", "Directory where the Bolt code will be generated. If directory is not specified then the input path directory will be used instead.", CommandOptionType.SingleValue);
                var dirOption = c.Option("--dir <PATH>", "Directories where contract assemblies are located.", CommandOptionType.MultipleValue);
                var contractOption = c.Option("--contract <NAME>", "Additional contracts to generate, if not included in config file or assembly.", CommandOptionType.MultipleValue);
                var modeOption = c.Option($"--mode <{rawModeValues}>", "Specifies what parts of contracts should be generated. ", CommandOptionType.SingleValue);
                var internalSwitch = c.Option("--internal", "Generates the contracts with internal visibility.", CommandOptionType.NoValue);

                c.HelpOption("-?|-h|--help");

                c.OnExecute(() =>
                {
                    bool inputMustExist = !_cache.IsHosted();
                    bool inputExists = !string.IsNullOrEmpty(input.Value);

                    if (inputMustExist && !inputExists)
                    {
                        Console.WriteLine("Input path must be specified.".Yellow());
                        return 1;
                    }

                    var extension = inputExists ? Path.GetExtension(input.Value) : null;

                    if (inputMustExist && !File.Exists(input.Value))
                    {
                        Console.WriteLine($"File not found: {input.Value.White().Bold()}".Yellow());
                        return 1;
                    }

                    if (inputExists)
                    {
                        _cache.Loader.AddDirectory(Path.GetDirectoryName(Path.GetFullPath(input.Value)));
                    }

                    foreach (var dir in dirOption.Values)
                    {
                        if (Directory.Exists(dir))
                        {
                            _cache.Loader.AddDirectory(dir);
                        }
                    }

                    GenerateContractMode mode;
                    try
                    {
                        mode = modeOption.HasValue() ? (GenerateContractMode)Enum.Parse(typeof(GenerateContractMode), modeOption.Value(), true) : GenerateContractMode.All;
                    }
                    catch (Exception)
                    {
                        Console.WriteLine($"Invalid mode option specified: {modeOption.Value().White().Bold()}, Available options: {rawModeValues.Bold()}".Yellow());
                        return 1;
                    }

                    bool asInternal = internalSwitch.HasValue();

                    RootConfig rootConfig;
                    if ( inputExists)
                    {
                        if (extension == ".exe" || extension == ".dll")
                        {
                            rootConfig = new RootConfig(_cache);
                            try
                            {
                                Console.WriteLine($"Loading all contracts from assembly: ${input.Value}");
                                _cache.Loader.Load(input.Value);
                                rootConfig.Assemblies.Add(input.Value);
                            }
                            catch (Exception e)
                            {
                                return HandleError($"Failed to read assembly: {input.Value.White().Bold()}", e);
                            }

                            if (AddContracts(rootConfig, contractOption.Values, mode, asInternal) != 0)
                            {
                                return 1;
                            }
                        }
                        else
                        {
                            try
                            {
                                rootConfig = RootConfig.CreateFromConfig(_cache, input.Value);
                            }
                            catch (Exception e)
                            {
                                return HandleError($"Failed to read Bolt configuration: {input.Value.White().Bold()}", e);
                            }
                        }
                    }
                    else
                    {
                        rootConfig = new RootConfig(_cache);
                        if (AddContracts(rootConfig, contractOption.Values, mode, asInternal) != 0)
                        {
                            return 1;
                        }
                    }

                    if (output.HasValue())
                    {
                        rootConfig.OutputDirectory = output.Value();
                    }
                    else
                    {
                        rootConfig.OutputDirectory = Path.GetDirectoryName(input.Value);
                    }

                    return rootConfig.Generate();
                });
            });


            try
            {
                var code = app.Execute(args);
                return code;
            }
            finally
            {
                _cache.Dispose();
            }
        }