Skip to content

Commit

Permalink
Merge pull request #269 from 0xced/command-comment
Browse files Browse the repository at this point in the history
Add the actual command that generated the .cs file in the comments
  • Loading branch information
mganss authored May 31, 2021
2 parents fd88711 + 62681c0 commit 85ead03
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 7 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ Options:
(default is true)
--nc, --netCore generate .NET Core specific code that might not
work with .NET Framework (default is false)
--ca, --commandArgs generate a comment with the exact command line
arguments that were used to generate the source
code (default is true)
```

For use from code use the [library NuGet package](https://www.nuget.org/packages/XmlSchemaClassGenerator-beta/):
Expand Down Expand Up @@ -362,4 +365,4 @@ Contrbutions are welcome. Here are some guidelines:

- If it's not a trivial fix, please submit an issue first
- Try and blend new code with the existing code's style
- Add unit tests
- Add unit tests
5 changes: 4 additions & 1 deletion XmlSchemaClassGenerator.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static void Main(string[] args)
var uniqueTypeNamesAcrossNamespaces = false;
var createGeneratedCodeAttributeVersion = true;
var netCoreSpecificCode = false;
var generateCommandLineArgs = true;

var options = new OptionSet {
{ "h|help", "show this message and exit", v => showHelp = v != null },
Expand Down Expand Up @@ -126,6 +127,7 @@ A file name may be given by appending a pipe sign (|) followed by a file name (l
{ "un|uniqueTypeNames", "generate type names that are unique across namespaces (default is false)", v => uniqueTypeNamesAcrossNamespaces = v != null },
{ "gc|generatedCodeAttribute", "add version information to GeneratedCodeAttribute (default is true)", v => createGeneratedCodeAttributeVersion = v != null },
{ "nc|netCore", "generate .NET Core specific code that might not work with .NET Framework (default is false)", v => netCoreSpecificCode = v != null },
{ "ca|commandArgs", "generate a comment with the exact command line arguments that were used to generate the source code (default is true)", v => generateCommandLineArgs = v != null },
};

var globsAndUris = options.Parse(args);
Expand Down Expand Up @@ -200,7 +202,8 @@ A file name may be given by appending a pipe sign (|) followed by a file name (l
CompactTypeNames = compactTypeNames,
UniqueTypeNamesAcrossNamespaces = uniqueTypeNamesAcrossNamespaces,
CreateGeneratedCodeAttributeVersion = createGeneratedCodeAttributeVersion,
NetCoreSpecificCode = netCoreSpecificCode
NetCoreSpecificCode = netCoreSpecificCode,
GenerateCommandLineArgumentsComment = generateCommandLineArgs,
};

generator.CommentLanguages.AddRange(commentLanguages);
Expand Down
17 changes: 17 additions & 0 deletions XmlSchemaClassGenerator.Tests/ExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Xunit;

namespace XmlSchemaClassGenerator.Tests
{
public class ExtensionsTests
{
[Theory]
[InlineData(null, null)]
[InlineData("", "")]
[InlineData("MyText", "MyText")]
[InlineData("My Text", "\"My Text\"")]
public void QuoteEmptyOrNull(string input, string expected)
{
Assert.Equal(expected, input.QuoteIfNeeded());
}
}
}
65 changes: 63 additions & 2 deletions XmlSchemaClassGenerator.Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ private static IEnumerable<string> ConvertXml(string name, IEnumerable<string> x
CodeTypeReferenceOptions = generatorPrototype.CodeTypeReferenceOptions,
DoNotForceIsNullable = generatorPrototype.DoNotForceIsNullable,
CreateGeneratedCodeAttributeVersion = generatorPrototype.CreateGeneratedCodeAttributeVersion,
NetCoreSpecificCode = generatorPrototype.NetCoreSpecificCode
NetCoreSpecificCode = generatorPrototype.NetCoreSpecificCode,
GenerateCommandLineArgumentsComment = generatorPrototype.GenerateCommandLineArgumentsComment,
CommandLineArgumentsProvider = generatorPrototype.CommandLineArgumentsProvider,
};

gen.CommentLanguages.Clear();
Expand Down Expand Up @@ -1058,7 +1060,7 @@ public void ComplexTypeWithAttributeGroupExtension()
// </auto-generated>
//------------------------------------------------------------------------------
// This code was generated by Tests.
// This code was generated by Tests
namespace Test
{
Expand Down Expand Up @@ -2388,5 +2390,64 @@ void UnknownAttributeHandler(object sender, XmlAttributeEventArgs e)
AssertEx.Equal(deserializedObject, deserializedXml);
}
}

[Theory]
[InlineData("fake command line arguments", "fake command line arguments")]
[InlineData(null, "N/A")]
public void IncludeCommandLineArguments(string commandLineArguments, string expectedCommandLineArguments)
{
const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema elementFormDefault=""qualified"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" targetNamespace=""http://local.none"" xmlns:l=""http://local.none"">
<xs:element name=""document"" type=""l:elem"" />
<xs:complexType name=""elem"">
<xs:attribute name=""Text"" type=""xs:string""/>
</xs:complexType>
</xs:schema>";

var generator = new Generator
{
GenerateInterfaces = false,
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test"
},
GenerateCommandLineArgumentsComment = true,
CommandLineArgumentsProvider = new CommandLineArgumentsProvider(commandLineArguments)
};

var contents = ConvertXml(nameof(IncludeCommandLineArguments), xsd, generator);

var csharp = Assert.Single(contents);

CompareOutput(
$@"//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// This code was generated by Tests version 1.0.0.1 using the following command:
// {expectedCommandLineArguments}
namespace Test
{{
[System.CodeDom.Compiler.GeneratedCodeAttribute(""Tests"", ""1.0.0.1"")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(""elem"", Namespace=""http://local.none"")]
[System.ComponentModel.DesignerCategoryAttribute(""code"")]
[System.Xml.Serialization.XmlRootAttribute(""document"", Namespace=""http://local.none"")]
public partial class Elem
{{
[System.Xml.Serialization.XmlAttributeAttribute(""Text"")]
public string Text {{ get; set; }}
}}
}}
", csharp);
}
}
}
24 changes: 24 additions & 0 deletions XmlSchemaClassGenerator/CommandLineArgumentsProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;

namespace XmlSchemaClassGenerator
{
public class CommandLineArgumentsProvider
{
public CommandLineArgumentsProvider(string commandLineArguments)
{
CommandLineArguments = commandLineArguments;
}

public string CommandLineArguments { get; }

public static CommandLineArgumentsProvider CreateFromEnvironment()
{
var args = Environment.GetCommandLineArgs();
var commandLineArguments = string.Join(" ", args.Take(1).Select(Path.GetFileNameWithoutExtension).Concat(args.Skip(1)).Select(Extensions.QuoteIfNeeded));
return new CommandLineArgumentsProvider(commandLineArguments);
}
}
}
16 changes: 16 additions & 0 deletions XmlSchemaClassGenerator/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -41,5 +42,20 @@ public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TS
{
return source.GroupBy(propertySelector).Select(x => x.First());
}

public static string QuoteIfNeeded(this string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}

if (text.Contains(" "))
{
return "\"" + text + "\"";
}

return text;
}
}
}
29 changes: 26 additions & 3 deletions XmlSchemaClassGenerator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,18 @@ public bool NetCoreSpecificCode
set { _configuration.NetCoreSpecificCode = value; }
}

public bool GenerateCommandLineArgumentsComment
{
get { return _configuration.GenerateCommandLineArgumentsComment; }
set { _configuration.GenerateCommandLineArgumentsComment = value; }
}

public CommandLineArgumentsProvider CommandLineArgumentsProvider
{
get { return _configuration.CommandLineArgumentsProvider; }
set { _configuration.CommandLineArgumentsProvider = value; }
}

static Generator()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Expand Down Expand Up @@ -329,9 +341,20 @@ public void Generate(XmlSchemaSet set)
{
if (Version != null)
{
var comment = $"This code was generated by {Version.Title}"
+ (CreateGeneratedCodeAttributeVersion ? $" version {Version.Version}." : ".");
ns.Comments.Add(new CodeCommentStatement(comment));
var comment = new StringBuilder($"This code was generated by {Version.Title}");
if (CreateGeneratedCodeAttributeVersion)
{
comment.Append($" version {Version.Version}");
}
if (GenerateCommandLineArgumentsComment)
{
comment.Append(" using the following command:");
}
ns.Comments.Add(new CodeCommentStatement(comment.ToString()));
if (GenerateCommandLineArgumentsComment)
{
ns.Comments.Add(new CodeCommentStatement(CommandLineArgumentsProvider?.CommandLineArguments ?? "N/A"));
}
}

writer.Write(ns);
Expand Down
12 changes: 12 additions & 0 deletions XmlSchemaClassGenerator/GeneratorConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public GeneratorConfiguration()
NamingProvider = new NamingProvider(NamingScheme);
Version = VersionProvider.CreateFromAssembly();
EnableUpaCheck = true;
CommandLineArgumentsProvider = CommandLineArgumentsProvider.CreateFromEnvironment();
}

/// <summary>
Expand Down Expand Up @@ -304,5 +305,16 @@ public void WriteLog(string message)
/// </list>
/// </summary>
public bool NetCoreSpecificCode { get; set; }

/// <summary>
/// Adds a comment with the exact command line arguments that were used to generate the
/// source code using the <see cref="CommandLineArgumentsProvider"/>. Default is false.
/// </summary>
public bool GenerateCommandLineArgumentsComment { get; set; }

/// <summary>
/// A provider to obtain the command line arguments of the tool.
/// </summary>
public CommandLineArgumentsProvider CommandLineArgumentsProvider { get; set; }
}
}

0 comments on commit 85ead03

Please sign in to comment.