From 6dedf8fe101e34fe98c6c3e41e7a041bbf65568d Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Mon, 31 Oct 2022 17:09:10 +0000 Subject: [PATCH] Allow additional files to be copied as part of template extraction --- standard/documentation-comments.md | 10 +++++----- tools/ExampleExtractor/ExampleMetadata.cs | 5 +++++ tools/ExampleExtractor/Program.cs | 2 +- tools/ExampleExtractor/Template.cs | 14 +++++++++++++- tools/example-templates/additional-files/Acme.cs | 7 +++++++ tools/example-templates/additional-files/README.md | 4 ++++ 6 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 tools/example-templates/additional-files/Acme.cs create mode 100644 tools/example-templates/additional-files/README.md diff --git a/standard/documentation-comments.md b/standard/documentation-comments.md index 5164b448a..b45752747 100644 --- a/standard/documentation-comments.md +++ b/standard/documentation-comments.md @@ -711,7 +711,7 @@ IDs: **Fields** are represented by their fully qualified name. - + ```csharp namespace Acme { @@ -756,7 +756,7 @@ IDs: **Constructors** - + ```csharp namespace Acme { @@ -779,7 +779,7 @@ IDs: **Finalizers** - + ```csharp namespace Acme { @@ -798,7 +798,7 @@ IDs: **Methods** - + ```csharp namespace Acme { @@ -878,7 +878,7 @@ IDs: **Events** - + ```csharp namespace Acme { diff --git a/tools/ExampleExtractor/ExampleMetadata.cs b/tools/ExampleExtractor/ExampleMetadata.cs index b24dcc897..ff0bfe40a 100644 --- a/tools/ExampleExtractor/ExampleMetadata.cs +++ b/tools/ExampleExtractor/ExampleMetadata.cs @@ -28,6 +28,11 @@ public class ExampleMetadata public bool InferOutput { get; set; } public string ExpectedException { get; set; } + /// + /// Additional files to copy from the special "additional-files" template directory. + /// + public List AdditionalFiles { get; set; } + // Information provided by the example extractor public string MarkdownFile { get; set; } public int StartLine { get; set; } diff --git a/tools/ExampleExtractor/Program.cs b/tools/ExampleExtractor/Program.cs index 75fff6e4d..896bf5916 100644 --- a/tools/ExampleExtractor/Program.cs +++ b/tools/ExampleExtractor/Program.cs @@ -68,7 +68,7 @@ anyErrors = true; continue; } - template.Apply(example, outputDirectory); + template.Apply(example, outputDirectory, templateDirectory); } } Console.WriteLine("Finished example extraction."); diff --git a/tools/ExampleExtractor/Template.cs b/tools/ExampleExtractor/Template.cs index 31786c43c..10cb3c0b0 100644 --- a/tools/ExampleExtractor/Template.cs +++ b/tools/ExampleExtractor/Template.cs @@ -4,6 +4,7 @@ namespace ExampleExtractor; internal class Template { + private const string AdditionalFilesDirectory = "additional-files"; private const string ExampleCodeSubstitution = "$example-code"; private const string ExampleNameSubstitution = "$example-name"; @@ -21,7 +22,8 @@ private Template(string name, Dictionary files) /// /// The example to apply. /// The root output directory. (A subdirectory for the example will be created within this.) - internal void Apply(Example example, string rootOutputDirectory) + /// The root template directory, used for finding additional files if necessary. + internal void Apply(Example example, string rootOutputDirectory, string rootTemplateDirectory) { var outputDirectory = Path.Combine(rootOutputDirectory, example.Name); Directory.CreateDirectory(outputDirectory); @@ -33,6 +35,15 @@ internal void Apply(Example example, string rootOutputDirectory) .Replace(ExampleNameSubstitution, example.Name); File.WriteAllText(file, code); } + if (example.Metadata.AdditionalFiles is List additionalFiles) + { + foreach (var additionalFile in additionalFiles) + { + string sourceFile = Path.Combine(rootTemplateDirectory, AdditionalFilesDirectory, additionalFile); + string destFile = Path.Combine(outputDirectory, additionalFile); + File.Copy(sourceFile, destFile); + } + } var metadataJson = JsonConvert.SerializeObject(example.Metadata); File.WriteAllText(Path.Combine(outputDirectory, ExampleMetadata.MetadataFile), metadataJson); } @@ -46,6 +57,7 @@ private static Template LoadTemplate(string directory) { var name = Path.GetFileName(directory); var files = Directory.GetFiles(directory) + .Where(file => Path.GetFileName(file) != AdditionalFilesDirectory) .ToDictionary(file => Path.GetFileName(file), file => File.ReadAllText(file)); return new Template(name, files); } diff --git a/tools/example-templates/additional-files/Acme.cs b/tools/example-templates/additional-files/Acme.cs new file mode 100644 index 000000000..8b936336d --- /dev/null +++ b/tools/example-templates/additional-files/Acme.cs @@ -0,0 +1,7 @@ +// Common types used in documentation-comments.md +namespace Acme +{ + enum Color { Red, Blue, Green } + public interface IProcess {} + public delegate void Del(); +} diff --git a/tools/example-templates/additional-files/README.md b/tools/example-templates/additional-files/README.md new file mode 100644 index 000000000..b8912876b --- /dev/null +++ b/tools/example-templates/additional-files/README.md @@ -0,0 +1,4 @@ +This directory is not a template in itself, but contains additional +files that can be copied into any example. This avoids having to +create separate templates for each file which is common across +multiple templates.