-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SchemaValidator to validate WiX authoring.
SchemaValidator is a quick-n-dirty tool to let you validate a set of WiX source files against the WiX schemas. This is mostly useful to highlight incomplete/inaccurate schemas.
- Loading branch information
Showing
4 changed files
with
189 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
|
||
namespace WixBuildTools.SchemaValidator; | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
/// <summary> | ||
/// Command-line parsing. | ||
/// </summary> | ||
public class CommandLine | ||
{ | ||
private CommandLine() | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// List of schema files to process. | ||
/// </summary> | ||
public List<string> Schemas { get; private set; } = new List<string>(); | ||
|
||
/// <summary> | ||
/// List of source files to process. | ||
/// </summary> | ||
public List<string> Sources { get; private set; } = new List<string>(); | ||
|
||
/// <summary> | ||
/// Show the help text. | ||
/// </summary> | ||
public static void ShowHelp() | ||
{ | ||
Console.WriteLine("SchemaValidator.exe [-?] path/to/*.xsd path/to/*.wx?"); | ||
} | ||
|
||
/// <summary> | ||
/// Parses the command-line. | ||
/// </summary> | ||
/// <param name="args">Arguments from command-line.</param> | ||
/// <param name="commandLine">Command line object created from command-line arguments</param> | ||
/// <returns>True if command-line is parsed, false if a failure was occurred.</returns> | ||
public static bool TryParseArguments(string[] args, out CommandLine commandLine) | ||
{ | ||
var success = true; | ||
|
||
commandLine = new CommandLine(); | ||
|
||
for (var i = 0; i < args.Length; ++i) | ||
{ | ||
if ('-' == args[i][0] || '/' == args[i][0]) | ||
{ | ||
var arg = args[i].Substring(1).ToLowerInvariant(); | ||
if ("?" == arg || "help" == arg) | ||
{ | ||
return false; | ||
} | ||
} | ||
else | ||
{ | ||
var paths = args[i].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||
|
||
foreach (var path in paths) | ||
{ | ||
var sourcePath = Path.GetFullPath(path); | ||
var sourceDir = Path.GetDirectoryName(sourcePath); | ||
var wildcard = sourcePath.Substring(sourceDir!.Length + 1); | ||
var files = Directory.EnumerateFiles(sourceDir, wildcard, SearchOption.AllDirectories); | ||
if (files.Any()) | ||
{ | ||
commandLine.Schemas.AddRange(files.Where(f => Path.GetExtension(f).Equals(".xsd", StringComparison.OrdinalIgnoreCase))); | ||
commandLine.Sources.AddRange(files.Where(f => Path.GetExtension(f).StartsWith(".wx", StringComparison.OrdinalIgnoreCase))); | ||
} | ||
else | ||
{ | ||
Console.Error.WriteLine($"Source file '{sourcePath}' could not be found."); | ||
success = false; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (0 == commandLine.Schemas.Count) | ||
{ | ||
Console.Error.WriteLine("No schema files specified. Specify at least one file."); | ||
success = false; | ||
} | ||
|
||
if (0 == commandLine.Sources.Count) | ||
{ | ||
Console.Error.WriteLine("No source files specified. Specify at least one file."); | ||
success = false; | ||
} | ||
|
||
return success; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
|
||
namespace WixBuildTools.SchemaValidator; | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Xml; | ||
using System.Xml.Linq; | ||
using System.Xml.Schema; | ||
|
||
public sealed class Program | ||
{ | ||
public static int Main(string[] args) | ||
{ | ||
if (!CommandLine.TryParseArguments(args, out var commandLine)) | ||
{ | ||
CommandLine.ShowHelp(); | ||
return 1; | ||
} | ||
|
||
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Start run. Validating {commandLine.Sources.Count} source files against {commandLine.Schemas.Count} schemas."); | ||
|
||
var settings = GetReaderSettings(commandLine); | ||
|
||
var errors = 0; | ||
|
||
foreach (var source in commandLine.Sources) | ||
{ | ||
try | ||
{ | ||
Validate(source, settings); | ||
} | ||
catch (XmlSchemaException xse) | ||
{ | ||
++errors; | ||
Console.WriteLine($"Encountered validation error in {source}({xse.LineNumber},{xse.LinePosition}): {xse.Message}"); | ||
} | ||
} | ||
|
||
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Run complete. Encountered {errors} validation errors from {commandLine.Sources.Count} source files against {commandLine.Schemas.Count} schemas."); | ||
|
||
return 0; | ||
} | ||
|
||
private static XmlReaderSettings GetReaderSettings(CommandLine commandLine) | ||
{ | ||
var settings = new XmlReaderSettings | ||
{ | ||
ValidationType = ValidationType.Schema, | ||
ValidationFlags = | ||
XmlSchemaValidationFlags.ReportValidationWarnings | | ||
XmlSchemaValidationFlags.ProcessIdentityConstraints | | ||
XmlSchemaValidationFlags.ProcessInlineSchema | | ||
XmlSchemaValidationFlags.ProcessSchemaLocation | ||
}; | ||
|
||
foreach (var schema in commandLine.Schemas) | ||
{ | ||
settings.Schemas.Add(null, schema); | ||
} | ||
|
||
return settings; | ||
} | ||
|
||
static void Validate(string xmlFile, XmlReaderSettings settings) | ||
{ | ||
var document = new XmlDocument(); | ||
var reader = XmlReader.Create(xmlFile, settings); | ||
document.Load(reader); | ||
document.Validate(null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |