From 4c1d9f5c704929949355ab2861500470bbff9fab Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Tue, 16 Aug 2022 21:02:53 +0100 Subject: [PATCH 1/5] Add run modes --- src/Compiler/Argument/CompilerArguments.cs | 11 +++-- src/Compiler/Argument/RunMode.cs | 13 ++++++ src/Compiler/SectorFileCompiler.cs | 51 +++++++++++++++------- 3 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 src/Compiler/Argument/RunMode.cs diff --git a/src/Compiler/Argument/CompilerArguments.cs b/src/Compiler/Argument/CompilerArguments.cs index 4ab64085..1a8f0377 100644 --- a/src/Compiler/Argument/CompilerArguments.cs +++ b/src/Compiler/Argument/CompilerArguments.cs @@ -10,7 +10,7 @@ public class CompilerArguments public const int EmptyFolderIgnore = 0; public const int EmptyFolderWarning = 1; public const int EmptyFolderError = 2; - + public const string DefaultBuildVersion = "BUILD_VERSION"; public List ConfigFiles { get; } = new(); @@ -34,7 +34,7 @@ public override bool Equals(Object obj) // Different length, so definitely not equal if (ConfigFiles.Count != compare.ConfigFiles.Count) { - return false ; + return false; } // Check every one is equal. @@ -48,7 +48,7 @@ public override bool Equals(Object obj) return true; } - + public override int GetHashCode() { return base.GetHashCode(); @@ -65,11 +65,14 @@ public override int GetHashCode() // Replace tokens in the output public List TokenReplacers { get; } = new(); - + // The version being built public string BuildVersion { get; set; } = DefaultBuildVersion; // What to do about empty folders public int EmptyFolderAction { get; set; } = EmptyFolderIgnore; + + // What mode should we run in. + public RunMode Mode { get; set; } = RunMode.COMPILE; } } diff --git a/src/Compiler/Argument/RunMode.cs b/src/Compiler/Argument/RunMode.cs new file mode 100644 index 00000000..f2dc18fc --- /dev/null +++ b/src/Compiler/Argument/RunMode.cs @@ -0,0 +1,13 @@ +using System; + +namespace Compiler.Argument +{ + [Flags] + public enum RunMode : ushort + { + CHECK_CONFIG = 1, + LINT = 2, + VALIDATE = 4, + COMPILE = 8 + } +} diff --git a/src/Compiler/SectorFileCompiler.cs b/src/Compiler/SectorFileCompiler.cs index 7d06bee7..ba0ffb2a 100644 --- a/src/Compiler/SectorFileCompiler.cs +++ b/src/Compiler/SectorFileCompiler.cs @@ -19,6 +19,8 @@ public class SectorFileCompiler { private readonly CompilerArguments arguments; private readonly EventTracker events; + private const int SUCESS_RETURN = 0; + private const int FAILURE_RETURN = 1; public SectorFileCompiler(CompilerArguments arguments, EventTracker events) { @@ -38,7 +40,7 @@ public int Compile() if (events.HasFatalError()) { events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; } // Parse all the config files @@ -49,11 +51,18 @@ public int Compile() { events.AddEvent(new CompilationMessage("Loading config files")); config = ConfigFileLoaderFactory.Make(arguments).LoadConfigFiles(arguments.ConfigFiles, arguments); - } catch (ConfigFileInvalidException e) + } + catch (ConfigFileInvalidException e) { events.AddEvent(new CompilationMessage(e.Message)); events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; + } + + events.AddEvent(new CompilationMessage("Config files loaded successfully")); + if (arguments.Mode == RunMode.CHECK_CONFIG) + { + return SUCESS_RETURN; } // Parse all the input files and create elements @@ -74,18 +83,18 @@ public int Compile() { events.AddEvent(new CompilationMessage(exception.Message)); events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; } - + if (events.HasFatalError()) { events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; } - + events.AddEvent(new CompilationMessage("Injecting pre-parse static data")); RunwayCentrelineInjector.InjectRunwayCentrelineData(sectorElements); - + events.AddEvent(new CompilationMessage("Parsing input files")); foreach (AbstractSectorDataFile dataFile in fileList) { @@ -95,13 +104,18 @@ public int Compile() if (events.HasFatalError()) { events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; } - + // There's some static data we need to inject to the collection for adjacent airports... events.AddEvent(new CompilationMessage("Injecting post-parse static data")); AdjacentAirportsInjector.InjectAdjacentAirportsData(sectorElements); - + + // We aren't going beyond linting, so stop. + if (arguments.Mode == RunMode.LINT) + { + return SUCESS_RETURN; + } // Now all the data is loaded, validate that there are no broken references etc. if (arguments.ValidateOutput) @@ -111,14 +125,20 @@ public int Compile() if (events.HasFatalError()) { events.AddEvent(new CompilationFinishedEvent(false)); - return 1; + return FAILURE_RETURN; } - } + } else { events.AddEvent(new CompilationMessage("Skipping output validation")); } + // We aren't going beyond post-validating, so don't compile. + if (arguments.Mode == RunMode.VALIDATE) + { + return SUCESS_RETURN; + } + // Generate the output - all at once OutputGenerator generator = new OutputGenerator( sectorElements, @@ -127,15 +147,16 @@ public int Compile() ); var outputTasks = new List(); - foreach(AbstractOutputFile output in arguments.OutputFiles) + foreach (AbstractOutputFile output in arguments.OutputFiles) { events.AddEvent(new CompilationMessage($"Generating {output.GetFileDescriptor()} output")); outputTasks.Add(generator.GenerateOutput(output)); } + Task.WaitAll(outputTasks.ToArray()); events.AddEvent(new CompilationFinishedEvent(true)); - return 0; + return SUCESS_RETURN; } } } From 8255272f2143d2dd967c3e119027033e36a7e6e3 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Tue, 16 Aug 2022 21:20:57 +0100 Subject: [PATCH 2/5] fix: properly check for argument presence --- src/CompilerCli/Argument/ArgumentParser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CompilerCli/Argument/ArgumentParser.cs b/src/CompilerCli/Argument/ArgumentParser.cs index 861dbb16..6778560d 100644 --- a/src/CompilerCli/Argument/ArgumentParser.cs +++ b/src/CompilerCli/Argument/ArgumentParser.cs @@ -53,12 +53,12 @@ string[] args public bool HasCompilerArgument(Type type) { - return availableCompilerArguments.Select(arg => arg.GetType() == type).Count() != 0; + return availableCompilerArguments.Any(arg => arg.GetType() == type); } public bool HasCliArgument(Type type) { - return availableCompilerArguments.Select(arg => arg.GetType() == type).Count() != 0; + return availableCliArguments.Any(arg => arg.GetType() == type); } private int ProcessArguments(string[] args, int startIndex, Action> process) From f2c4d0ea1945a5e052f1b74b9c9d8f57d763d476 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Tue, 16 Aug 2022 21:21:22 +0100 Subject: [PATCH 3/5] Add tests for running mode options --- .../Compiler/CheckConfigCompilerArgument.cs | 18 ++++++++ .../Compiler/LintCompilerArgument.cs | 18 ++++++++ .../Compiler/ValidateCompilerArgument.cs | 18 ++++++++ .../Argument/ArgumentParserFactoryTest.cs | 5 ++- .../CheckConfigCompilerArgumentTest.cs | 41 +++++++++++++++++++ .../Compiler/LintCompilerArgumentTest.cs | 41 +++++++++++++++++++ .../Compiler/ValidateCompilerArgumentTest.cs | 41 +++++++++++++++++++ 7 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs create mode 100644 src/CompilerCli/Compiler/LintCompilerArgument.cs create mode 100644 src/CompilerCli/Compiler/ValidateCompilerArgument.cs create mode 100644 tests/CompilerCliTest/Compiler/CheckConfigCompilerArgumentTest.cs create mode 100644 tests/CompilerCliTest/Compiler/LintCompilerArgumentTest.cs create mode 100644 tests/CompilerCliTest/Compiler/ValidateCompilerArgumentTest.cs diff --git a/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs b/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs new file mode 100644 index 00000000..86a8659e --- /dev/null +++ b/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Compiler.Argument; + +namespace CompilerCli.Compiler +{ + public class CheckConfigCompilerArgument: AbstractCompilerArgument + { + public override void Parse(List values, CompilerArguments compilerSettings) + { + throw new System.NotImplementedException(); + } + + public override string GetSpecifier() + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/CompilerCli/Compiler/LintCompilerArgument.cs b/src/CompilerCli/Compiler/LintCompilerArgument.cs new file mode 100644 index 00000000..1de0d9e8 --- /dev/null +++ b/src/CompilerCli/Compiler/LintCompilerArgument.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Compiler.Argument; + +namespace CompilerCli.Compiler +{ + public class LintCompilerArgument: AbstractCompilerArgument + { + public override void Parse(List values, CompilerArguments compilerSettings) + { + throw new System.NotImplementedException(); + } + + public override string GetSpecifier() + { + throw new System.NotImplementedException(); + } + } +} diff --git a/src/CompilerCli/Compiler/ValidateCompilerArgument.cs b/src/CompilerCli/Compiler/ValidateCompilerArgument.cs new file mode 100644 index 00000000..8e77d9de --- /dev/null +++ b/src/CompilerCli/Compiler/ValidateCompilerArgument.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Compiler.Argument; + +namespace CompilerCli.Compiler +{ + public class ValidateCompilerArgument: AbstractCompilerArgument + { + public override void Parse(List values, CompilerArguments compilerSettings) + { + throw new System.NotImplementedException(); + } + + public override string GetSpecifier() + { + throw new System.NotImplementedException(); + } + } +} diff --git a/tests/CompilerCliTest/Argument/ArgumentParserFactoryTest.cs b/tests/CompilerCliTest/Argument/ArgumentParserFactoryTest.cs index 1cdbf9f0..ee8e21ae 100644 --- a/tests/CompilerCliTest/Argument/ArgumentParserFactoryTest.cs +++ b/tests/CompilerCliTest/Argument/ArgumentParserFactoryTest.cs @@ -14,6 +14,9 @@ public class ArgumentParserFactoryTest [InlineData(typeof(StripCommentsCompilerArgument))] [InlineData(typeof(ConfigFileCompilerArgument))] [InlineData(typeof(BuildVersionCompilerArgument))] + [InlineData(typeof(CheckConfigCompilerArgument))] + [InlineData(typeof(LintCompilerArgument))] + [InlineData(typeof(ValidateCompilerArgument))] public void TestItAddsCompilerArguments(Type type) { Assert.True(ArgumentParserFactory.Make().HasCompilerArgument(type)); @@ -27,4 +30,4 @@ public void TestItAddsCliArguments(Type type) Assert.True(ArgumentParserFactory.Make().HasCliArgument(type)); } } -} \ No newline at end of file +} diff --git a/tests/CompilerCliTest/Compiler/CheckConfigCompilerArgumentTest.cs b/tests/CompilerCliTest/Compiler/CheckConfigCompilerArgumentTest.cs new file mode 100644 index 00000000..5d1c6323 --- /dev/null +++ b/tests/CompilerCliTest/Compiler/CheckConfigCompilerArgumentTest.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using Compiler.Argument; +using CompilerCli.Compiler; +using Xunit; + +namespace CompilerCliTest.Compiler +{ + public class CheckConfigCompilerArgumentTest + { + private CompilerArguments arguments; + private CheckConfigCompilerArgument checkConfigCompilerArgument; + + public CheckConfigCompilerArgumentTest() + { + arguments = new CompilerArguments(); + checkConfigCompilerArgument = new CheckConfigCompilerArgument(); + } + + [Fact] + public void TestItSetsCompileOnlyAsMode() + { + checkConfigCompilerArgument.Parse(new List(), arguments); + Assert.Equal(RunMode.CHECK_CONFIG, arguments.Mode); + } + + [Fact] + public void TestItThrowsExceptionOnValues() + { + Assert.Throws( + () => checkConfigCompilerArgument.Parse(new List(new[] { "a"}), arguments) + ); + } + + [Fact] + public void TestItReturnsASpecifier() + { + Assert.Equal("--check-config", checkConfigCompilerArgument.GetSpecifier()); + } + } +} diff --git a/tests/CompilerCliTest/Compiler/LintCompilerArgumentTest.cs b/tests/CompilerCliTest/Compiler/LintCompilerArgumentTest.cs new file mode 100644 index 00000000..69706e67 --- /dev/null +++ b/tests/CompilerCliTest/Compiler/LintCompilerArgumentTest.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using Compiler.Argument; +using CompilerCli.Compiler; +using Xunit; + +namespace CompilerCliTest.Compiler +{ + public class LintCompilerArgumentTest + { + private CompilerArguments arguments; + private LintCompilerArgument lintCompilerArgument; + + public LintCompilerArgumentTest() + { + arguments = new CompilerArguments(); + lintCompilerArgument = new LintCompilerArgument(); + } + + [Fact] + public void TestItSetsCompileOnlyAsMode() + { + lintCompilerArgument.Parse(new List(), arguments); + Assert.Equal(RunMode.LINT, arguments.Mode); + } + + [Fact] + public void TestItThrowsExceptionOnValues() + { + Assert.Throws( + () => lintCompilerArgument.Parse(new List(new[] { "a"}), arguments) + ); + } + + [Fact] + public void TestItReturnsASpecifier() + { + Assert.Equal("--lint", lintCompilerArgument.GetSpecifier()); + } + } +} diff --git a/tests/CompilerCliTest/Compiler/ValidateCompilerArgumentTest.cs b/tests/CompilerCliTest/Compiler/ValidateCompilerArgumentTest.cs new file mode 100644 index 00000000..a313e3f5 --- /dev/null +++ b/tests/CompilerCliTest/Compiler/ValidateCompilerArgumentTest.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using Compiler.Argument; +using CompilerCli.Compiler; +using Xunit; + +namespace CompilerCliTest.Compiler +{ + public class ValidateCompilerArgumentTest + { + private CompilerArguments arguments; + private ValidateCompilerArgument validateCompilerArgument; + + public ValidateCompilerArgumentTest() + { + arguments = new CompilerArguments(); + validateCompilerArgument = new ValidateCompilerArgument(); + } + + [Fact] + public void TestItSetsCompileOnlyAsMode() + { + validateCompilerArgument.Parse(new List(), arguments); + Assert.Equal(RunMode.VALIDATE, arguments.Mode); + } + + [Fact] + public void TestItThrowsExceptionOnValues() + { + Assert.Throws( + () => validateCompilerArgument.Parse(new List(new[] { "a"}), arguments) + ); + } + + [Fact] + public void TestItReturnsASpecifier() + { + Assert.Equal("--validate", validateCompilerArgument.GetSpecifier()); + } + } +} From ceaa5f813296df38f9e0eaab52f2d95cf9f6d885 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Wed, 17 Aug 2022 19:57:10 +0100 Subject: [PATCH 4/5] feat: add config check, lint and validate runtime options --- README.md | 6 ++++++ src/CompilerCli/Argument/ArgumentParserFactory.cs | 7 +++++-- .../Compiler/CheckConfigCompilerArgument.cs | 14 ++++++++++---- src/CompilerCli/Compiler/LintCompilerArgument.cs | 14 ++++++++++---- .../Compiler/ValidateCompilerArgument.cs | 14 ++++++++++---- 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e88e3dac..e5483784 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ times, then the compiler will attempt to merge the configs together. ### Optional +`--check-config` - If set, only runs the configuration checking step to ensure that the compiler config is correct. + +`--lint` - If set, only runs the configuration check and linting steps. + +`--validate` - If set, only runs the configuration check, linting and post-validation steps. Does not output files. + `--skip-validation` - If set, the compiler will skip the post-parse validation phase of compilation, `--strip-comments` - If set, any comments in the input will be removed. If an empty line is leftover, it will be discarded. diff --git a/src/CompilerCli/Argument/ArgumentParserFactory.cs b/src/CompilerCli/Argument/ArgumentParserFactory.cs index 2c750ddc..7054beaf 100644 --- a/src/CompilerCli/Argument/ArgumentParserFactory.cs +++ b/src/CompilerCli/Argument/ArgumentParserFactory.cs @@ -15,7 +15,10 @@ public static ArgumentParser Make() new SkipValidationCompilerArgument(), new StripCommentsCompilerArgument(), new ConfigFileCompilerArgument(), - new BuildVersionCompilerArgument() + new BuildVersionCompilerArgument(), + new CheckConfigCompilerArgument(), + new LintCompilerArgument(), + new ValidateCompilerArgument(), }, new SortedSet { @@ -25,4 +28,4 @@ public static ArgumentParser Make() ); } } -} \ No newline at end of file +} diff --git a/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs b/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs index 86a8659e..27060379 100644 --- a/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs +++ b/src/CompilerCli/Compiler/CheckConfigCompilerArgument.cs @@ -1,18 +1,24 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Compiler.Argument; namespace CompilerCli.Compiler { - public class CheckConfigCompilerArgument: AbstractCompilerArgument + public class CheckConfigCompilerArgument : AbstractCompilerArgument { public override void Parse(List values, CompilerArguments compilerSettings) { - throw new System.NotImplementedException(); + if (values.Count != 0) + { + throw new ArgumentException("Check config argument does not take any options"); + } + + compilerSettings.Mode = RunMode.CHECK_CONFIG; } public override string GetSpecifier() { - throw new System.NotImplementedException(); + return "--check-config"; } } } diff --git a/src/CompilerCli/Compiler/LintCompilerArgument.cs b/src/CompilerCli/Compiler/LintCompilerArgument.cs index 1de0d9e8..ac729b9b 100644 --- a/src/CompilerCli/Compiler/LintCompilerArgument.cs +++ b/src/CompilerCli/Compiler/LintCompilerArgument.cs @@ -1,18 +1,24 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Compiler.Argument; namespace CompilerCli.Compiler { - public class LintCompilerArgument: AbstractCompilerArgument + public class LintCompilerArgument : AbstractCompilerArgument { public override void Parse(List values, CompilerArguments compilerSettings) { - throw new System.NotImplementedException(); + if (values.Count != 0) + { + throw new ArgumentException("Lint argument does not take any options"); + } + + compilerSettings.Mode = RunMode.LINT; } public override string GetSpecifier() { - throw new System.NotImplementedException(); + return "--lint"; } } } diff --git a/src/CompilerCli/Compiler/ValidateCompilerArgument.cs b/src/CompilerCli/Compiler/ValidateCompilerArgument.cs index 8e77d9de..a17eb580 100644 --- a/src/CompilerCli/Compiler/ValidateCompilerArgument.cs +++ b/src/CompilerCli/Compiler/ValidateCompilerArgument.cs @@ -1,18 +1,24 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Compiler.Argument; namespace CompilerCli.Compiler { - public class ValidateCompilerArgument: AbstractCompilerArgument + public class ValidateCompilerArgument : AbstractCompilerArgument { public override void Parse(List values, CompilerArguments compilerSettings) { - throw new System.NotImplementedException(); + if (values.Count != 0) + { + throw new ArgumentException("Validate argument does not take any options"); + } + + compilerSettings.Mode = RunMode.VALIDATE; } public override string GetSpecifier() { - throw new System.NotImplementedException(); + return "--validate"; } } } From 09ed5f51178f4a3db63d7de41219c6bf7b4bf670 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Wed, 17 Aug 2022 19:58:53 +0100 Subject: [PATCH 5/5] docs: update documentation for skip validation option --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e5483784..ecd241ed 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ times, then the compiler will attempt to merge the configs together. `--validate` - If set, only runs the configuration check, linting and post-validation steps. Does not output files. -`--skip-validation` - If set, the compiler will skip the post-parse validation phase of compilation, +`--skip-validation` - If set, the compiler will skip the post-parse validation phase of compilation. +If running in full compilation mode, will still produce output. `--strip-comments` - If set, any comments in the input will be removed. If an empty line is leftover, it will be discarded.