예제 #1
0
        /// <summary>
        /// Called to execute the code generator application.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        /// <returns>The exit code.</returns>
        public int Run(IReadOnlyList <string> args)
        {
            try
            {
                var argsReader = new ArgsReader(args);
                if (argsReader.ReadHelpFlag())
                {
                    foreach (string line in Description)
                    {
                        System.Console.WriteLine(line);
                    }
                    System.Console.WriteLine();
                    WriteUsage();
                    return(0);
                }

                var generator = CreateGenerator(argsReader);
                generator.GeneratorName = s_assemblyName;
                if (SupportsCustomIndent)
                {
                    string indentText = argsReader.ReadIndentOption();
                    if (indentText != null)
                    {
                        generator.IndentText = indentText;
                    }
                }
                if (SupportsCustomNewLine)
                {
                    string newLine = argsReader.ReadNewLineOption();
                    if (newLine != null)
                    {
                        generator.NewLine = newLine;
                    }
                }

                string serviceName = argsReader.ReadServiceNameOption();
                bool   shouldClean = SupportsClean && argsReader.ReadCleanFlag();
                bool   isQuiet     = argsReader.ReadQuietFlag();
                bool   isVerify    = argsReader.ReadVerifyFlag();
                bool   isDryRun    = argsReader.ReadDryRunFlag();

                string inputPath = argsReader.ReadArgument();
                if (inputPath == null)
                {
                    throw new ArgsReaderException("Missing input path.");
                }

                string outputPath = argsReader.ReadArgument();
                if (outputPath == null)
                {
                    throw new ArgsReaderException("Missing output path.");
                }

                argsReader.VerifyComplete();

                NamedText input;
                if (inputPath == "-")
                {
                    input = new NamedText("", System.Console.In.ReadToEnd());
                }
                else
                {
                    if (!File.Exists(inputPath))
                    {
                        throw new ApplicationException("Input file does not exist: " + inputPath);
                    }
                    input = new NamedText(Path.GetFileName(inputPath), File.ReadAllText(inputPath));
                }

                ServiceInfo service;
                if (ServiceDefinitionUtility.DetectFormat(input) == ServiceDefinitionFormat.Swagger)
                {
                    service = new SwaggerParser {
                        ServiceName = serviceName
                    }.ParseDefinition(input);
                }
                else
                {
                    if (serviceName != null)
                    {
                        throw new ArgsReaderException("--serviceName not supported for FSD input.");
                    }
                    service = new FsdParser().ParseDefinition(input);
                }

                PrepareGenerator(generator, service, outputPath);
                var output = generator.GenerateOutput(service);

                if (SupportsSingleOutput &&
                    !outputPath.EndsWith("/", StringComparison.Ordinal) &&
                    !outputPath.EndsWith("\\", StringComparison.Ordinal) &&
                    !Directory.Exists(outputPath))
                {
                    if (output.NamedTexts.Count > 1)
                    {
                        throw new InvalidOperationException("Multiple outputs not expected.");
                    }

                    if (output.NamedTexts.Count == 1)
                    {
                        var namedText = output.NamedTexts[0];

                        if (outputPath == "-")
                        {
                            System.Console.Write(namedText.Text);
                        }
                        else if (ShouldWriteByteOrderMark(namedText.Name))
                        {
                            File.WriteAllText(outputPath, namedText.Text, s_utf8WithBom);
                        }
                        else
                        {
                            File.WriteAllText(outputPath, namedText.Text);
                        }
                    }
                }
                else
                {
                    var namedTextsToWrite = new List <NamedText>();
                    foreach (var namedText in output.NamedTexts)
                    {
                        string existingFilePath = Path.Combine(outputPath, namedText.Name);
                        if (File.Exists(existingFilePath))
                        {
                            // ignore CR when comparing files
                            if (namedText.Text.Replace("\r", "") != File.ReadAllText(existingFilePath).Replace("\r", ""))
                            {
                                namedTextsToWrite.Add(namedText);
                                if (!isQuiet)
                                {
                                    System.Console.WriteLine("changed " + namedText.Name);
                                }
                            }
                        }
                        else
                        {
                            namedTextsToWrite.Add(namedText);
                            if (!isQuiet)
                            {
                                System.Console.WriteLine("added " + namedText.Name);
                            }
                        }
                    }

                    var namesToDelete = new List <string>();
                    if (shouldClean && output.PatternsToClean.Count != 0)
                    {
                        var directoryInfo = new DirectoryInfo(outputPath);
                        if (directoryInfo.Exists)
                        {
                            foreach (string nameMatchingPattern in FindNamesMatchingPatterns(directoryInfo, output.PatternsToClean))
                            {
                                if (output.NamedTexts.All(x => x.Name != nameMatchingPattern))
                                {
                                    namesToDelete.Add(nameMatchingPattern);
                                    if (!isQuiet)
                                    {
                                        System.Console.WriteLine("removed " + nameMatchingPattern);
                                    }
                                }
                            }
                        }
                    }

                    if (isVerify)
                    {
                        return(namedTextsToWrite.Count != 0 || namesToDelete.Count != 0 ? 1 : 0);
                    }

                    if (!isDryRun)
                    {
                        if (!Directory.Exists(outputPath))
                        {
                            Directory.CreateDirectory(outputPath);
                        }

                        foreach (var namedText in namedTextsToWrite)
                        {
                            string outputFilePath = Path.Combine(outputPath, namedText.Name);

                            string outputFileDirectoryPath = Path.GetDirectoryName(outputFilePath);
                            if (outputFileDirectoryPath != null && outputFileDirectoryPath != outputPath && !Directory.Exists(outputFileDirectoryPath))
                            {
                                Directory.CreateDirectory(outputFileDirectoryPath);
                            }

                            if (ShouldWriteByteOrderMark(namedText.Name))
                            {
                                File.WriteAllText(outputFilePath, namedText.Text, s_utf8WithBom);
                            }
                            else
                            {
                                File.WriteAllText(outputFilePath, namedText.Text);
                            }
                        }

                        foreach (string nameToDelete in namesToDelete)
                        {
                            File.Delete(Path.Combine(outputPath, nameToDelete));
                        }
                    }
                }

                return(0);
            }
            catch (Exception exception)
            {
                if (exception is ApplicationException || exception is ArgsReaderException || exception is ServiceDefinitionException)
                {
                    System.Console.Error.WriteLine(exception.Message);
                    if (exception is ArgsReaderException)
                    {
                        System.Console.Error.WriteLine();
                        WriteUsage();
                    }
                    return(2);
                }
                else
                {
                    System.Console.Error.WriteLine(exception.ToString());
                    return(3);
                }
            }
        }
        public async Task <ServiceResult <GenerateResponseDto> > GenerateAsync(GenerateRequestDto request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            try
            {
                var  input     = new NamedText(request.Definition?.Name ?? "", request.Definition?.Text ?? "");
                bool isSwagger = ServiceDefinitionUtility.DetectFormat(input) == ServiceDefinitionFormat.Swagger;
                var  service   = isSwagger ? new SwaggerParser().ParseDefinition(input) : new FsdParser().ParseDefinition(input);

                var generatorName = request.Generator?.Name;
                switch (generatorName)
                {
                case "csharp":
                    return(ServiceResult.Success(GenerateCode(() => new CSharpGenerator(), g => g.GenerateOutput(service))));

                case "javascript":
                    return(ServiceResult.Success(GenerateCode(() => new JavaScriptGenerator(), g => g.GenerateOutput(service))));

                case "typescript":
                    return(ServiceResult.Success(GenerateCode(() => new JavaScriptGenerator {
                        TypeScript = true
                    }, g => g.GenerateOutput(service))));

                case "markdown":
                    return(ServiceResult.Success(GenerateCode(() => new MarkdownGenerator(), g => g.GenerateOutput(service))));

                case "fsd":
                    return(ServiceResult.Success(GenerateCode(() => new FsdGenerator(), g => g.GenerateOutput(service))));

                case "swagger-json":
                    return(ServiceResult.Success(GenerateCode(() => new SwaggerGenerator(), g => g.GenerateOutput(service))));

                case "swagger-yaml":
                    return(ServiceResult.Success(GenerateCode(() => new SwaggerGenerator {
                        Yaml = true
                    }, g => g.GenerateOutput(service))));

                case "asp-net-web-api":
                    return(ServiceResult.Success(GenerateCode(() => new AspNetGenerator(), g => g.GenerateOutput(service))));

                case "crash":
                    throw new InvalidOperationException("Intentional exception for diagnostic purposes.");

                default:
                    return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Unrecognized generator '{generatorName}'.")));
                }
            }
            catch (ServiceDefinitionException exception)
            {
                return(ServiceResult.Success(new GenerateResponseDto
                {
                    Failure = new FailureDto
                    {
                        Message = exception.Error,
                        Line = exception.Position.LineNumber,
                        Column = exception.Position.ColumnNumber,
                    },
                }));
            }
        }