Changing the way docs are generated...

This commit is contained in:
Matthew Leibowitz 2018-04-20 17:46:44 +02:00
Родитель 5e6c998241
Коммит 1fb7af4322
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 3650EBE4AA155AF9
5 изменённых файлов: 219 добавлений и 122 удалений

Просмотреть файл

@ -6,6 +6,8 @@ harfbuzz release 1.4.6
skia release m60
xunit.runner.console release 2.3.1
Xamarin.Forms release 2.5.0.280555
Tizen.NET release 4.0.0
OpenTK.GLControl release 1.1.2349.61993
# native sonames
libSkiaSharp soname 60.1.0

Просмотреть файл

@ -3,13 +3,17 @@
#addin nuget:?package=Cake.FileHelpers&version=2.0.0
#reference "tools/SharpCompress/lib/net45/SharpCompress.dll"
#reference "tools/Newtonsoft.Json/lib/net45/SharpCompress.dll"
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using SharpCompress.Readers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#load "cake/Utils.cake"
@ -57,6 +61,7 @@ if (string.IsNullOrEmpty (BUILD_NUMBER)) {
#load "cake/UtilsManaged.cake"
#load "cake/BuildExternals.cake"
#load "cake/UpdateDocs.cake"
////////////////////////////////////////////////////////////////////////////////////////////////////
// EXTERNALS - the native C and C++ libraries
@ -265,128 +270,6 @@ Task ("samples")
}
});
////////////////////////////////////////////////////////////////////////////////////////////////////
// DOCS - building the API documentation
////////////////////////////////////////////////////////////////////////////////////////////////////
Task ("update-docs")
.Does (() =>
{
// the reference folders to locate assemblies
var refs = new List<DirectoryPath> ();
if (IsRunningOnWindows ()) {
var refAssemblies = "C:/Program Files (x86)/Microsoft Visual Studio/*/*/Common7/IDE/ReferenceAssemblies/Microsoft/Framework";
refs.AddRange (GetDirectories ($"{refAssemblies}/MonoAndroid/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/MonoAndroid/v4.0.3"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.iOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.TVOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.WatchOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.Mac/v2.0"));
refs.AddRange (GetDirectories ("C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"));
refs.AddRange (GetDirectories ($"{NUGET_PACKAGES}/xamarin.forms/{GetVersion ("Xamarin.Forms", "release")}/lib/*"));
}
// the assemblies to generate docs for
var assemblies = new FilePath [] {
// SkiaSharp
"./output/SkiaSharp/nuget/lib/netstandard1.3/SkiaSharp.dll",
// SkiaSharp.Views
"./output/SkiaSharp.Views/nuget/lib/MonoAndroid/SkiaSharp.Views.Android.dll",
"./output/SkiaSharp.Views/nuget/lib/net45/SkiaSharp.Views.Desktop.dll",
"./output/SkiaSharp.Views/nuget/lib/net45/SkiaSharp.Views.Gtk.dll",
"./output/SkiaSharp.Views/nuget/lib/net45/SkiaSharp.Views.WPF.dll",
"./output/SkiaSharp.Views/nuget/lib/Xamarin.iOS/SkiaSharp.Views.iOS.dll",
"./output/SkiaSharp.Views/nuget/lib/Xamarin.Mac20/SkiaSharp.Views.Mac.dll",
"./output/SkiaSharp.Views/nuget/lib/Xamarin.TVOS/SkiaSharp.Views.tvOS.dll",
"./output/SkiaSharp.Views/nuget/lib/uap10.0/SkiaSharp.Views.UWP.dll",
"./output/SkiaSharp.Views/nuget/lib/Xamarin.WatchOS/SkiaSharp.Views.watchOS.dll",
// SkiaSharp.Views.Forms
"./output/SkiaSharp.Views.Forms/nuget/lib/netstandard1.3/SkiaSharp.Views.Forms.dll",
// HarfBuzzSharp
"./output/HarfBuzzSharp/nuget/lib/netstandard1.3/HarfBuzzSharp.dll",
// SkiaSharp.HarfBuzz
"./output/SkiaSharp.HarfBuzz/nuget/lib/netstandard1.3/SkiaSharp.HarfBuzz.dll",
};
// print out the assemblies
foreach (var r in refs) {
Information ("Reference Directory: {0}", r);
}
foreach (var a in assemblies) {
Information ("Assemblies {0}...", a);
}
// generate doc files
var refArgs = string.Join (" ", refs.Select (r => $"--lib=\"{r}\""));
var assemblyArgs = string.Join (" ", assemblies.Select (a => $"\"{a}\""));
RunProcess (MDocPath, new ProcessSettings {
Arguments = $"update --preserve --out=\"{DOCS_PATH}\" {refArgs} {assemblyArgs}",
});
// process the generated docs
var docFiles = GetFiles ("./docs/**/*.xml");
float typeCount = 0;
float memberCount = 0;
float totalTypes = 0;
float totalMembers = 0;
foreach (var file in docFiles) {
var xdoc = XDocument.Load (file.ToString ());
// remove IComponent docs as this is just designer
xdoc.Root
.Elements ("Members")
.Elements ("Member")
.Where (e => e.Attribute ("MemberName")?.Value?.StartsWith ("System.ComponentModel.IComponent.") == true)
.Remove ();
// count the types without docs
var typesWithDocs = xdoc.Root
.Elements ("Docs");
totalTypes += typesWithDocs.Count ();
var currentTypeCount = typesWithDocs.Count (m => m.Value?.IndexOf ("To be added.") >= 0);
typeCount += currentTypeCount;
// count the members without docs
var membersWithDocs = xdoc.Root
.Elements ("Members")
.Elements ("Member")
.Where (m => m.Attribute ("MemberName")?.Value != "Dispose" && m.Attribute ("MemberName")?.Value != "Finalize")
.Elements ("Docs");
totalMembers += membersWithDocs.Count ();
var currentMemberCount = membersWithDocs.Count (m => m.Value?.IndexOf ("To be added.") >= 0);
memberCount += currentMemberCount;
// log if either type or member has missing docs
currentMemberCount += currentTypeCount;
if (currentMemberCount > 0) {
var fullName = xdoc.Root.Attribute ("FullName");
if (fullName != null)
Information ("Docs missing on {0} = {1}", fullName.Value, currentMemberCount);
}
// get the whitespaces right
var settings = new XmlWriterSettings {
Encoding = new UTF8Encoding (),
Indent = true,
NewLineChars = "\n",
OmitXmlDeclaration = true,
};
using (var writer = XmlWriter.Create (file.ToString (), settings)) {
xdoc.Save (writer);
writer.Flush ();
}
// empty line at the end
System.IO.File.AppendAllText (file.ToString (), "\n");
}
// log summary
Information (
"Documentation missing in {0}/{1} ({2:0.0%}) types and {3}/{4} ({5:0.0%}) members.",
typeCount, totalTypes, typeCount / totalTypes,
memberCount, totalMembers, memberCount / totalMembers);
});
////////////////////////////////////////////////////////////////////////////////////////////////////
// NUGET - building the package for NuGet.org
////////////////////////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -4,4 +4,5 @@
<package id="xunit.runner.console" version="2.3.1" />
<package id="mdoc" version="5.6.4" />
<package id="SharpCompress" version="0.18.1" />
<package id="Newtonsoft.Json" version="11.0.2" />
</packages>

210
cake/UpdateDocs.cake Normal file
Просмотреть файл

@ -0,0 +1,210 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// DOCS - building the API documentation
////////////////////////////////////////////////////////////////////////////////////////////////////
void CreateFrameworks (Version minVersion, DirectoryPath docsTempPath) {
// download all the versions from nuget so we can generate the docs
var ids = new [] {
"skiasharp",
"skiasharp.views",
"skiasharp.views.forms",
// "harfbuzzsharp",
// "skiasharp.harfbuzz",
};
var xplat = new [] {
"netstandard1.3",
"portable-net45%2Bwin8%2Bwpa81%2Bwp8",
"portable-net45%2Bxamarinmac%2Bxamarinios%2Bmonotouch%2Bmonoandroid%2Bwin8%2Bwpa81%2Bwp8%2Bxamarin.watchos%2Bxamarin.tvos",
};
var metadata = "https://api.nuget.org/v3/registration3/{0}/index.json";
var download = "https://api.nuget.org/v3-flatcontainer/{0}/{1}/{0}.{1}.nupkg";
var packagesPath = MakeAbsolute (ROOT_PATH.Combine ("externals/docs_packages"));
// prepare the temp folder
EnsureDirectoryExists (docsTempPath);
CleanDirectories (docsTempPath.FullPath);
var xFrameworks = new XElement ("Frameworks");
var xFrameworksDoc = new XDocument (xFrameworks);
foreach (var id in ids) {
// get the versions for each nuget
Information ($"Downloading information for ID: {id}...");
var md = string.Format (metadata, id);
var mdFile = DownloadFile (md);
var mdObj = JObject.Parse (FileReadText (mdFile));
var page = mdObj ["items"] [0];
foreach (var package in page ["items"]) {
var version = (string) package ["catalogEntry"] ["version"];
// skip pre-release versions
if (version.Contains("-") || Version.Parse (version) < minVersion)
continue;
// download the assemblies
Information ($"Downloading '{id}' version '{version}'...");
var dest = packagesPath.Combine (id).Combine (version);
var destFile = dest.CombineWithFilePath ($"{id}.{version}.nupkg");
if (!FileExists (destFile)) {
EnsureDirectoryExists (dest);
DownloadFile (string.Format (download, id, version), destFile);
Unzip (destFile, dest);
}
// copy the assemblies into the temp folder
if (id == "skiasharp.views") {
// copy platform-specific
foreach (var dir in GetDirectories ($"{dest}/lib/*")) {
var d = dir.GetDirectoryName ().ToLower ();
var platform = "";
if (d.StartsWith ("monoandroid")) {
platform = "android";
} else if (d.StartsWith ("net4")) {
platform = "net";
} else if (d.StartsWith ("uap")) {
platform = "uwp";
} else if (d.StartsWith ("xamarinios")) {
platform = "ios";
} else if (d.StartsWith ("xamarinmac")) {
platform = "macos";
} else if (d.StartsWith ("xamarintvos")) {
platform = "tvos";
} else if (d.StartsWith ("xamarinwatchos")) {
platform = "watchos";
} else {
throw new Exception ($"Unknown platform: {d}");
}
var moniker = $"{id.Replace (".", "-")}-{platform}-{version}";
var o = docsTempPath.Combine (moniker);
EnsureDirectoryExists (o);
foreach (var f in GetFiles ($"{dir}/*.dll")) {
CopyFileToDirectory (f, o);
}
xFrameworks.Add (
new XElement ("Framework",
new XAttribute ("Name", o.GetDirectoryName ()),
new XAttribute ("Source", o.GetDirectoryName ())));
}
} else {
// copy netstandard/portable
var moniker = $"{id.Replace (".", "-")}-{version}";
var o = docsTempPath.Combine (moniker);
EnsureDirectoryExists (o);
foreach (var x in xplat) {
if (DirectoryExists ($"{dest}/lib/{x}")) {
foreach (var f in GetFiles ($"{dest}/lib/{x}/*.dll")) {
CopyFileToDirectory (f, o);
}
break;
}
}
xFrameworks.Add (
new XElement ("Framework",
new XAttribute ("Name", o.GetDirectoryName ()),
new XAttribute ("Source", o.GetDirectoryName ())));
}
}
}
xFrameworksDoc.Save ($"{docsTempPath}/frameworks.xml");
}
Task ("update-docs")
.Does (() =>
{
var docsTempPath = MakeAbsolute (ROOT_PATH.Combine ("output/docs/temp"));
// create the frameworks folder from the released NuGets
CreateFrameworks (new Version (1, 0, 0), docsTempPath);
// the reference folders to locate assemblies
var refs = new List<DirectoryPath> ();
if (IsRunningOnWindows ()) {
var refAssemblies = "C:/Program Files (x86)/Microsoft Visual Studio/*/*/Common7/IDE/ReferenceAssemblies/Microsoft/Framework";
refs.AddRange (GetDirectories ($"{refAssemblies}/MonoAndroid/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/MonoAndroid/v4.0.3"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.iOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.TVOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.WatchOS/v1.0"));
refs.AddRange (GetDirectories ($"{refAssemblies}/Xamarin.Mac/v2.0"));
refs.AddRange (GetDirectories ("C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"));
refs.AddRange (GetDirectories ($"{NUGET_PACKAGES}/xamarin.forms/{GetVersion ("Xamarin.Forms", "release")}/lib/*"));
refs.AddRange (GetDirectories ($"{NUGET_PACKAGES}/tizen.net/{GetVersion ("Tizen.NET", "release")}/lib/*"));
refs.AddRange (GetDirectories ($"{NUGET_PACKAGES}/opentk.glcontrol/{GetVersion ("OpenTK.GLControl", "release")}/lib/*"));
}
// generate doc files
var refArgs = string.Join (" ", refs.Select (r => $"--lib=\"{r}\""));
var fw = MakeAbsolute (docsTempPath.CombineWithFilePath ("frameworks.xml"));
RunProcess (@"C:\Projects\api-doc-tools\bin\Debug\mdoc.exe", new ProcessSettings {
Arguments = $"update --preserve --out=\"{DOCS_PATH}\" -lang=DocId --frameworks={fw} {refArgs}",
WorkingDirectory = docsTempPath
});
// clean up after working
CleanDirectories (docsTempPath.FullPath);
// process the generated docs
var docFiles = GetFiles ("./docs/**/*.xml");
float typeCount = 0;
float memberCount = 0;
float totalTypes = 0;
float totalMembers = 0;
foreach (var file in docFiles) {
var xdoc = XDocument.Load (file.ToString ());
// remove IComponent docs as this is just designer
xdoc.Root
.Elements ("Members")
.Elements ("Member")
.Where (e => e.Attribute ("MemberName")?.Value?.StartsWith ("System.ComponentModel.IComponent.") == true)
.Remove ();
// count the types without docs
var typesWithDocs = xdoc.Root
.Elements ("Docs");
totalTypes += typesWithDocs.Count ();
var currentTypeCount = typesWithDocs.Count (m => m.Value?.IndexOf ("To be added.") >= 0);
typeCount += currentTypeCount;
// count the members without docs
var membersWithDocs = xdoc.Root
.Elements ("Members")
.Elements ("Member")
.Where (m => m.Attribute ("MemberName")?.Value != "Dispose" && m.Attribute ("MemberName")?.Value != "Finalize")
.Elements ("Docs");
totalMembers += membersWithDocs.Count ();
var currentMemberCount = membersWithDocs.Count (m => m.Value?.IndexOf ("To be added.") >= 0);
memberCount += currentMemberCount;
// log if either type or member has missing docs
currentMemberCount += currentTypeCount;
if (currentMemberCount > 0) {
var fullName = xdoc.Root.Attribute ("FullName");
if (fullName != null)
Information ("Docs missing on {0} = {1}", fullName.Value, currentMemberCount);
}
// get the whitespaces right
var settings = new XmlWriterSettings {
Encoding = new UTF8Encoding (),
Indent = true,
NewLineChars = "\n",
OmitXmlDeclaration = true,
};
using (var writer = XmlWriter.Create (file.ToString (), settings)) {
xdoc.Save (writer);
writer.Flush ();
}
// empty line at the end
System.IO.File.AppendAllText (file.ToString (), "\n");
}
// log summary
Information (
"Documentation missing in {0}/{1} ({2:0.0%}) types and {3}/{4} ({5:0.0%}) members.",
typeCount, totalTypes, typeCount / totalTypes,
memberCount, totalMembers, memberCount / totalMembers);
});

1
externals/.gitignore поставляемый
Просмотреть файл

@ -1,3 +1,4 @@
angle/
harfbuzz/
packages/
docs_packages/