如何将DocFX API文档集成到您的GitHub仓库中





5.00/5 (5投票s)
有人声称使用 DocFX 生成 GitHub Pages 很难,但我发现一旦你标记了所有陷阱,它其实相当简单。
引言
在过去的几年里,我将为我的客户和我自己创建的 Microsoft .NET 应用程序所使用的许多底层工具都开源了。从一开始,我就想要并需要一种简单的方法来生成和维护超文本文档。本文将一步步展示我是如何实现这一目标的,并最终提出我将此过程整合到我现有 GitHub 仓库和其他尚为私有的库的开发工作流中的路线图。
背景
当我积极编写代码时,几乎总会有一个 Web 浏览器窗口在后台打开,通常指向 MSDN 库或 Stack Overflow 主题。在这两者中,MSDN 库与本主题最相关,因为它对 Microsoft .NET 基础类库和 Win32 API 的文档设定了标准,在很大程度上借鉴了 IBM,成为良好在线 API 文档的典范。
直接从 C# 应用程序的源代码自动生成 API 文档是我多年来一直想做的事情。这个概念当然不是什么新鲜事;万维网的开创性应用之一是 Netscape Navigator 中后期版本随附的早期 Javascript 版本的文档。一个更近的例子启发了我重新审视这个主题,那就是 Node 包管理器分发并托管在 GitHub 上的许多 Javascript 包的文档。
当我恢复这个项目时,我假设我会安装和使用 Sandcastle。然而,很快就显而易见的是,Microsoft 和其他人正在放弃它,转而使用 Microsoft 的一项名为 DocFX 的新产品。经过大约一周的密集学习和几次试错,我在生成 WizardWrx .NET API GitHub 仓库的完整文档方面取得了扎实的进展,并取得了成功。API 文档托管在一个 单独的 URL 上,我在仓库的 README.md
中嵌入了一个链接。
DocFX CLI(命令行界面)以 Chocolatey 包 的形式分发。虽然有一个 NuGet 包支持与项目构建集成,但我还没有研究过它。在文章的结尾,当讨论我的路线图时,我将对此做更多说明。
使用代码
本节所指的“代码”由六个主要组件组成。
- 适用于 Windows 的 Chocolatey 包管理器。
- DocFX CLI 包,通过公共 Chocolatey 存储库提供和安装。
- Windows PowerShell CLI,Chocolatey 和 DocFX 内部都使用它。PowerShell 已安装在所有受支持的 Microsoft Windows 版本上。
- Git CLI(命令行界面),我几年前与 Git for Windows 一起安装的。
- Microsoft Visual Studio 2017,它是其 MSBuild 引擎所必需的。任何版本都可以;我使用的是社区版,它能满足我所有的需求。
- 经典的 Windows CLI,以
cmd.exe
的形式,您需要用到其内部命令mklink
。
以下子章节涵盖了生成文档并将其集成到 GitHub 作为 Github Pages 的大部分步骤。如果您已阅读至此,我假设您已经安装了 PowerShell、Visual Studio 2017 和 Git CLI,因此我将不介绍它们的安装。由于 Chocolatey 相对较新,并且是后续所有步骤的先决条件,我将从安装它开始。
安装 Chocolatey
Chocolatey 的主网站上有 直接的安装说明。这些说明告知您需要 PowerShell 2 或更高版本以及 .NET Framework 4 或更高版本。如果您的操作系统是 Windows 7 或更高版本,您应该两者都有。
这些说明强烈建议您使用管理员(提升权限)的 shell 来运行安装。在稍微研究了一下之后,我没有理由不采纳这个建议。虽然这意味着您必须使用提升权限的 shell 来安装包,但结果是它们被正确安装并安全地 存放在受保护的系统目录中。
由于我不太喜欢 PowerShell,我遵循了针对老式命令行 shell cmd.exe
的说明。尽管如此,使用 PowerShell 还是不可避免的,因为您输入到 cmd.exe
的命令会调用 PowerShell 并将管道传递给它。
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
当命令在几秒钟后返回控制时,Cholcolatey 程序文件 choco.exe
已下载并安装到目录 C:\ProgramData\chocolatey\bin
,以及其支持的 DLL,并且 C:\ProgramData\chocolatey\bin
已被添加到您的 Windows 用户 PATH
列表中。
安装 DocFX
虽然有一个精美的 信息页,但您可以跳过它,因为您必须 知道的唯一命令是下面的命令,希望您一直保留着管理员权限的 shell。如果关闭了,请打开一个新的,然后输入以下命令。
choco install docfx
鉴于在 Microsoft .NET 生态系统中工作并发布 NuGet 包和 .NET 代码的开源 GitHub 仓库的人数众多,DocFX 在 Chocolaty 信息页上报告的下载量很小,这让我感到沮丧。也许是因为 DocFX 的用户文档还有很多不足之处。如果是这样,我希望这篇文章以及其他类似的将激励更多人开始使用它。
在关闭管理员命令提示符之前,还有最后一个命令,虽然是可选的,但我建议您运行它。
docfx template export default
上面的命令会在 DocFX 主程序目录 C:\ProgramData\chocolatey\lib\docfx
下创建一个名为 _exported_templates
的新目录,并用生成文档的模板和 CSS 文件填充它。此目录中唯一的一项是另一个子目录 default
,其中包含构成您生成的文档基础的模板、CSS 和 Javascript 文件。虽然您可以在不导出默认模板的情况下完成后续步骤,但检查它具有教育意义,对于像我这样对幕后发生的事情感到好奇的人来说是无法抗拒的。
包中还嵌入了其他几个模板,如下列表所示。
docfx template list
Existing embedded templates are:
common
default(zh-cn)
default
pdf.default
statictoc
虽然我简要检查了其他模板,它们以同样的方式导出,并在 _exported_templates
下占用同名的目录,但我只保留了默认模板。唯一看起来有用的模板是 pdf.default
,我目前不需要它,因为我想要 HTML 文档而不是 PDF。
由于 DocFX 安装程序将启动器存根放在 C:\ProgramData\chocolatey\bin
中,而其他所有内容都在您的解决方案目录中创建,因此您可以关闭管理员 shell,并在常规命令窗口中执行其余任务。(虽然您可以在管理员窗口中运行它们,但何必冒险呢?)
记录您的 API
- 该项目是用 DocFX 支持的编程语言实现的。由于我正在记录的 API 是用 C# 实现的,这是一种支持的语言,因此我轻松地扫清了第一个障碍。
- 公共类、接口、枚举、常量和方法都用“三斜杠” XML 注释块进行文档化。由于我开始使用 C# 13 年后就使用了这些来生成 IntelliSense 帮助,所以这个障碍也很容易。创建必要的注释超出了本文的范围。
我将首先介绍生成基本 API 文档所需的步骤,然后在展示我第一次尝试的结果后,解释我进行的一些改进。
文档集本质上是一个独立的网站,它可以独立存在,也可以通过驻留在某个目录中并像任何其他文档目录一样链接到它,从而成为更大网站的一部分。生成它是一个三步过程。
步骤 1:打开命令提示符,并将解决方案目录设为工作目录。
Microsoft Windows [Version 10.0.17134.285]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\DAG 2018/09/15 0:29:17.93>pushd F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx
上图假设您打开了命令提示符,然后更改了工作目录。
- 如果您在文件资源管理器窗口中看到了解决方案目录,则可以通过将光标(鼠标指针)放在地址栏中,输入
cmd
,然后按 **Return**(Enter)键来简化此操作。 - 在命令提示符中,使用
pushd
命令可以将更改日志驱动器和日志目录合并为一个命令。
步骤 2:输入命令 docfx init
来初始化 DocFX 项目,该命令会产生类似以下的输出。
F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx 2018/09/04 21:19:31.99>docfx init
Does the website contain API documentation from source code? (Default: Yes)
Choose Answer (Yes/No): Y
Where to save the generated documentation? (Default: _site)
Press ENTER to move to the next question.
What are the locations of your source code files? (Default: src/**.csproj)
Supported project files could be .sln, .csproj, .vbproj project files, or assembly files .dll, or .cs, .vb source files
You can use glob patterns, e.g. src/**
Press ENTER to move to the next question.
/**.csproj
What are the locations of your markdown files overwriting triple slash comments? (Default: apidoc/**.md)
You can specify markdown files with a YAML header to overwrite summary, remarks and description for parameters
You can use glob patterns, e.g. src/**
Press ENTER to move to the next question.
What are the locations of your conceptual files? (Default: articles/**.md,articles/**/toc.yml,toc.yml,*.md)
Supported conceptual files could be any text files. Markdown format is also supported.
You can use glob patterns, e.g. src/**
Press ENTER to move to the next question.
What are the locations of your resource files? (Default: images/**)
The resource files which conceptual files are referencing, e.g. images.
You can use glob patterns, e.g. src/**
Press ENTER to move to the next question.
Do you want to specify external API references?
Supported external API references can be in either JSON or YAML format.
Press ENTER to move to the next question.
What documentation templates do you want to use? (Default: default)
You can define multiple templates in order. The latter one will overwrite the former one if names collide
Predefined templates in docfx are now: default, statictoc
Press ENTER to move to the next question.
Created folder F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\src
Created folder F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\api
Created folder F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\apidoc
Created folder F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\articles
Created folder F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\images
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\toc.yml
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\index.md
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\api\toc.yml
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\api\index.md
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\articles\toc.yml
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\articles\intro.md
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\.gitignore
Created File F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\api\.gitignore
Created config file F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\docfx.json
Successfully generated default docfx project to F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project
Please run:
docfx "F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\docfx.json" --serve
To generate a default docfx website.
F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx 2018/09/04 21:30:36.66>
我覆盖了默认响应的唯一问题是“你的源代码文件在哪里?”虽然默认响应适用于您将源代码保留在名为 /src
的目录中,并将其他内容放在项目或解决方案目录中,但标准的 Visual Studio 项目通常不是这样组织的。用 /**.csproj
覆盖响应会指示 DocFX 扫描整个项目目录以查找用于指导文档过程的 .csproj
文件。请注意,我指示 DocFX 忽略解决方案文件,而只查找 .csproj
文件。对于大多数项目,告诉 DocFX 忽略解决方案文件并直接转到项目配置文件可能是安全的。
关于上述文件掩码,有两点需要注意。
- 注意 Unix 路径分隔符
/
的使用;您必须在整个过程中使用它来代替传统的 Windows 路径分隔符。 - 注意双星号,这是另一个常见的 Unix 惯用法。
步骤 3:生成 API 文档。
F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx 2018/09/10 15:23:35.39>docfx docfx_project\docfx.json --metadata
[18-09-10 08:26:29.494]Info:[MetadataCommand.ExtractMetadata]Using msbuild C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin as inner compiler.
[18-09-10 08:26:29.883]Info:[MetadataCommand.ExtractMetadata]Loading projects...
[18-09-10 08:26:34.027]Info:[MetadataCommand.ExtractMetadata]Cache for F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/ASCIIInfo/ASCIIInfo.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/AssemblyUtils/AssemblyUtils.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/Common/Common.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/ConsoleStreams/ConsoleStreams.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/Core/Core.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/DLLConfigurationManager/DLLConfigurationManager.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/DLLServices2TestStand/DLLServices2TestStand.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/EmbeddedTextFile/EmbeddedTextFile.csproj,F:/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx/FormatStringEngine/FormatStringEngine.csproj in F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\ASCIIInfo\obj\xdoc\cache\final\1607483063 is not valid: Could not find file 'F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\api\.manifest'., rebuild...
[18-09-10 08:26:34.029]Info:[MetadataCommand.ExtractMetadata]Generating metadata for each project...
[18-09-10 08:26:41.803]Info:[MetadataCommand]Completed Scope:MetadataCommand in 12334.6882 milliseconds.
[18-09-10 08:26:41.923]Info:[BuildCommand]6 plug-in(s) loaded.
[18-09-10 08:26:41.947]Info:[BuildCommand]No files are found with glob pattern apidoc/**.md, excluding obj/**,_site/**, under directory "F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project"
[18-09-10 08:26:41.948]Info:[BuildCommand]No files are found with glob pattern images/**, excluding <none>, under directory "F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project"
[18-09-10 08:26:41.965]Info:[BuildCommand]Markdown engine is markdig
[18-09-10 08:26:42.231]Info:[BuildCommand.BuildCore.Build Document]Max parallelism is 8.
[18-09-10 08:26:42.261]Info:[BuildCommand.BuildCore.Build Document.Prepare.CreateIncrementalBuildContext]Build strategy: IsFullBuild
[18-09-10 08:26:43.055]Info:[BuildCommand.BuildCore.Build Document.CompilePhaseHandlerWithIncremental.ConceptualDocumentProcessor]Building 3 file(s) in ConceptualDocumentProcessor(BuildConceptualDocument=>CountWord=>ValidateConceptualDocumentMetadata)...
[18-09-10 08:26:43.057]Info:[BuildCommand.BuildCore.Build Document.CompilePhaseHandlerWithIncremental.TocDocumentProcessor]Building 3 file(s) in TocDocumentProcessor(BuildTocDocument)...
[18-09-10 08:26:43.062]Info:[BuildCommand.BuildCore.Build Document.CompilePhaseHandlerWithIncremental.ManagedReferenceDocumentProcessor]Building 103 file(s) in ManagedReferenceDocumentProcessor(BuildManagedReferenceDocument=>ValidateManagedReferenceDocumentMetadata=>ApplyOverwriteDocumentForMref=>FillReferenceInformation)...
[18-09-10 08:27:03.599]Info:[BuildCommand.BuildCore.Build Document.LinkPhaseHandlerWithIncremental.UpdateContext]0 external references found in 1 xref maps.
[18-09-10 08:27:05.164]Info:[BuildCommand.BuildCore.Build Document.LinkPhaseHandlerWithIncremental.Apply Templates]Applying templates to 109 model(s)...
[18-09-10 08:27:07.463]Info:[BuildCommand.BuildCore.Build Document]XRef map exported.
[18-09-10 08:27:08.157]Info:[BuildCommand.Postprocess]Manifest file saved to manifest.json.
[18-09-10 08:27:08.237]Info:[BuildCommand]Completed building documents in 26309.0396 milliseconds.
[18-09-10 08:27:08.240]Info:[BuildCommand]Completed Scope:BuildCommand in 26434.8885 milliseconds.
[18-09-10 08:27:08.243]Info:Completed in 38776.6216 milliseconds
Build succeeded.
0 Warning(s)
0 Error(s)
F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx 2018/09/10 15:27:08.30>
上面的输出不是我第一次构建的。在最终弄清楚之前,我经历了多次试错,我将在下一节中讨论。另请注意,它不是程序建议的下一步命令。由于网站完全由静态页面组成,当您可以通过双击生成的 /docfx_project/_site
目录中的 index.html
来查看网站时,Web 服务器的开销没有任何好处。允许 DocFX 启动 Web 服务器会占用您的命令提示符,而您需要该命令提示符来准备网站发布。
发布为 GitHub Pages
- 发布整个仓库。虽然这适用于仓库完全由已在其他地方发布的代码文档组成(例如 NPM 包),但它会推送过多的内容,其中大部分内容无法很好地呈现到您的 GitHub Pages。
- 发布仓库
/docs
目录中的所有内容。此配置非常适合发布 API 文档,因为它隐藏了原始源代码。
您可能会说,这都很好,但是文档在 /docfx_project/_site
中;我如何将其放入 /docs
呢?这是一个公平的问题,至少有两个选择。
- 困难的方法是复制/docfx_project/_site中的内容到
/docs
目录。这是一个必须为每次更新重复的额外步骤,它会产生两份副本,两者都占用您备份集中的空间。(您除了 Git 和 GitHub 之外,还在使用其他方法备份您的仓库,对吗?) - 简单的方法是创建一个 Windows 卷影,将
/docs
链接到/docfx_project/_site,这样进入它的一切也会神奇地出现在/docs
中。创建卷影是一次性操作,并且消除了重复文件副本的缺点。
卷影并不是什么新鲜事物,Windows 的最近版本广泛使用它们来实现向后兼容的路径,例如以下五个文件名,它们都指向同一个实际文件。
"C:\Documents and Settings\All Users\Documents\H_DEASE\AI_PKG_400\WizardWrx.AssemblyPropertyViewer.dll" "C:\Documents and Settings\Public\Documents\H_DEASE\AI_PKG_400\WizardWrx.AssemblyPropertyViewer.dll" "C:\ProgramData\Documents\H_DEASE\AI_PKG_400\WizardWrx.AssemblyPropertyViewer.dll" "C:\Users\All Users\Documents\H_DEASE\AI_PKG_400\WizardWrx.AssemblyPropertyViewer.dll" "C:\Users\Public\Documents\H_DEASE\AI_PKG_400\WizardWrx.AssemblyPropertyViewer.dll"
虽然我多年前就了解了卷影,并且自上个世纪末开始使用 Windows NT Workstation 4.0 以来一直看到它们在起作用,但这是我第一次真正实用性地使用它们。
我创建所需卷影的一次性命令及其输出如下。
mklink /J F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docs F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\_site\ Junction created for F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docs <<===>> F:\Source_Code\Visual_Studio\Projects\WizardWrx_Libs\Wizardwrx\docfx_project\_site
该命令的通用形式如下。
mklink /J [AbsoluteProjectDirectoryName]docs [AbsoluteProjectDirectoryName]\docfx_project\_site
在上面的命令中,将项目目录的绝对(完整)名称替换为 [AbsoluteProjectDirectoryName]
。
关于 mklink
命令,有两个重要的事项需要记住。
- 由于
mklink
是一个内部命令(由cmd.exe
实现),所以没有名为mklink.exe
的程序文件。我花了十分钟搜索它,才意识到这一点。 - 您指定目标(在本例中是
/docs
),然后指定目标或源(在本例中是\docfx_project\_site
)。这与使用fsutil.exe
创建硬链接的参数顺序相同。如果顺序颠倒,您会收到以下有些含糊的错误消息:Cannot create a file when that file already exists。FSUtil.exe
的行为完全相同。
如果您按照给定的顺序执行这些说明,您的网站内容就会存在,并且如果您在 C# 项目的源代码树中选择 /docs
目录,您将看到与选择 /docfx_project/_site
目录时完全相同的文件。如果您不相信我,请清空 /docfx_project/_site
目录,然后将任意单个文件复制到其中。将活动文件浏览器视图切换到 /docs
,您将看到刚刚复制到 /docfx_project_site
的文件。(您可以通过从回收站恢复已删除的文件或重复上一个 DocFX 命令来重新生成网站来恢复所有内容。)
DocFX 命令初始化 /docfx_project
目录时会在此处放置一个 .gitignore
文件,您应该保持不变,因为它告诉 Git 保留更新 API 文档所需的模板文件,同时隐藏 /docfx_project/_site
目录。此操作可防止重复文件进入您的仓库,而 /docs
卷影确保包含 API 文档,并使其看起来像是来自 GitHub Pages 预期找到的位置。
第 1 步(共 3 步):更新本地 Git 仓库。根据需要重复此步骤。
假设您已安装 Git Bash 及其 Explorer 扩展,请滚动到项目的顶层目录,然后选择 **Git Bash here**。虽然有其他方法可以到达这里,但这是最简单的方法,因为它省去了将 Windows 路径转换为 Unix 路径的麻烦。无论您如何到达此处,接下来输入 Git 的三个命令中的第一个:git add *
。一些文本文件,例如 WizardWrx_NET_API_ABACUS_20180911_013037.LOG
,会引起一个警告,提示其行尾将被重写。此行为受初始化本地 Git 仓库时自动创建的 .gitattributes
文件控制。
DAG@ABACUS MINGW64 /f/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx (master) $ git add * warning: LF will be replaced by CRLF in docs/index.html. The file will have its original line endings in your working directory. The following paths are ignored by one of your .gitignore files: DLLServices2.suo DLLServices2.v12.suo README.HTML REFERENCE WizardWrx_NET_API_ABACUS_20180905_012540.LOG WizardWrx_NET_API_ABACUS_20180911_013037.LOG Use -f if you really want to add them. warning: LF will be replaced by CRLF in docs/api/DLLServices2TestStand.Properties.Resources.html. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in docs/api/DLLServices2TestStand.Properties.html. The file will have its original line endings in your working directory. ... warning: LF will be replaced by CRLF in docs/styles/docfx.vendor.js. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in docs/styles/lunr.js. The file will have its original line endings in your working directory. DAG@ABACUS MINGW64 /f/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx (master)
git add
命令生成了数十个此类警告,我只保留了前三个和最后两个。
第 2 步(共 3 步):提交更改到本地仓库。根据需要重复此步骤。在 Git Bash 提示符中输入以下命令:git commit -m "Amend the test script to output to a new reports directory, and replace the API documentation."
-m
开关将后面的引述字符串写入提交日志;此消息之后会显示在提交的每个文件旁边,直到后续提交更新它。
DAG@ABACUS MINGW64 /f/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx (master) $ git commit -m "Amend the test script to output to a new reports directory, and replace the API documentation ." [master afeb4b9] Amend the test script to output to a new reports directory, and replace the API documentation. 189 files changed, 48932 insertions(+), 1664 deletions(-) rewrite README.md (73%) create mode 100644 Test_Data/Application_ENIGMA_20171020_014625.TXT create mode 100644 Test_Data/Application_ENIGMA_20171020_015547.TXT create mode 100644 Test_Data/Application_ENIGMA_20171028_232630.TXT create mode 100644 Test_Data/DependentAssemblyInfoReport.TXT create mode 100644 Test_Data/DependentAssemblyInfoReport_20170917_234407.TXT create mode 100644 Test_Data/DependentAssemblyInfoReport_DEBUG_20170910_172816.TXT create mode 100644 Test_Data/DependentAssemblyInfoReport_RELEASE_20170910_180919.TXT create mode 100644 Test_Data/DigestMD5TestCases.TXT create mode 100644 Test_Data/MD5_File_Digests.DOCX create mode 100644 Test_Data/MaxStringLength.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_01.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_02.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_03.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_04.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_05.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_06.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_07.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_08.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_09.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Case_10.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Cases_20140218.ZIPX create mode 100644 Test_Data/MergeNewItemsIntoArray_Cases_20140628.ZIPX create mode 100644 Test_Data/MergeNewItemsIntoArray_Cases_20140629.ZIPX create mode 100644 Test_Data/MergeNewItemsIntoArray_Cases_20140630.ZIPX create mode 100644 Test_Data/MergeNewItemsIntoArray_Master.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_01.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_02.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_03.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_04.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_05.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_06.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_07.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_08.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_09.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Output_10.TXT create mode 100644 Test_Data/MergeNewItemsIntoArray_Summary.TXT create mode 100644 Test_Data/Plaintext_File_1_Block.TXT create mode 100644 Test_Data/Plaintext_File_2_Fractional_Block.TXT create mode 100644 Test_Data/Plaintext_File_3_1_Plus_Blocks.TXT create mode 100644 Test_Data/Plaintext_File_4_4_Plus_Blocks.TXT create mode 100644 Test_Data/Plaintext_File_4_Exactly_8_Blocks.TXT create mode 100644 Test_Data/TestCase_Inputs_and_Outputs_20170305_184427.ZIPX create mode 100644 Test_Reports/DLLServices2TestStand_Debug_ApplicationEvents_20180913_233040.TXT create mode 100644 Test_Reports/DLLServices2TestStand_Release_ApplicationEvents_20180913_233209.TXT create mode 100644 WizardWrx_NET_API_ABACUS_20180911_013037.7z.lnk create mode 100644 WizardWrx_NET_API_Binaries_Debug.7z create mode 100644 WizardWrx_NET_API_Binaries_Release.7z copy README.md => docfx_project/api/index.md (51%) rewrite docfx_project/index.md (100%) create mode 100644 docfx_project/templates/C#_Libraries/styles/main.css rename docs/{ => api}/DLLServices2TestStand.Properties.Resources.html (59%) rename docs/{ => api}/DLLServices2TestStand.Properties.html (100%) create mode 100644 docs/api/HelloDocfx.Class1.InnerClass.html create mode 100644 docs/api/HelloDocfx.Class1.html create mode 100644 docs/api/HelloDocfx.html rename docs/{ => api}/WizardWrx.ASCIICharacterDisplayInfo.html (100%) rename docs/{ => api}/WizardWrx.ASCII_Character_Display_Table.html (100%) rename docs/{ => api}/WizardWrx.ArrayInfo.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.AssemblyContainer.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.DependentAssemblies.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.DependentAssemblyInfo.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.PESubsystemInfo.PESubsystemID.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.PESubsystemInfo.SubsystemDescription.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.PESubsystemInfo.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.ReportGenerators.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.SortableManagedResourceItem.html (100%) rename docs/{ => api}/WizardWrx.AssemblyUtils.html (100%) rename docs/{ => api}/WizardWrx.CSVFileInfo.html (100%) rename docs/{ => api}/WizardWrx.Common.Properties.Resources.html (100%) rename docs/{ => api}/WizardWrx.Common.Properties.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.DefaultErrorMessageColors.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.ErrorMessagesInColor.ErrorSeverity.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.ErrorMessagesInColor.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.ErrorMessagesInColorConverter.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.MessageInColor.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.MessageInColorConverter.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.StandardHandleInfo.ConsoleModes.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.StandardHandleInfo.ConsoleOutputModes.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.StandardHandleInfo.StandardConsoleHandle.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.StandardHandleInfo.StandardHandleState.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.StandardHandleInfo.html (100%) rename docs/{ => api}/WizardWrx.ConsoleStreams.html (100%) rename docs/{ => api}/WizardWrx.Core.AgedFileInfo.html (100%) rename docs/{ => api}/WizardWrx.Core.AgedFileInfoCollection.html (100%) rename docs/{ => api}/WizardWrx.Core.AssemblyLocatorBase.html (100%) rename docs/{ => api}/WizardWrx.Core.BasicSystemInfoDisplayMessages.html (100%) rename docs/{ => api}/WizardWrx.Core.ByteArrayFormatters.html (100%) rename docs/{ => api}/WizardWrx.Core.CmdLneArgsBasic.ArgMatching.html (100%) rename docs/{ => api}/WizardWrx.Core.CmdLneArgsBasic.ArgType.html (100%) rename docs/{ => api}/WizardWrx.Core.CmdLneArgsBasic.html (100%) rename docs/{ => api}/WizardWrx.Core.PropertyDefaults.html (100%) rename docs/{ => api}/WizardWrx.Core.RegistryValues.html (100%) rename docs/{ => api}/WizardWrx.Core.TimeDisplayFormatter.DateFieldOrder.html (100%) rename docs/{ => api}/WizardWrx.Core.TimeDisplayFormatter.HoursFormatType.html (100%) rename docs/{ => api}/WizardWrx.Core.TimeDisplayFormatter.TimePrecisionType.html (100%) rename docs/{ => api}/WizardWrx.Core.TimeDisplayFormatter.html (100%) rename docs/{ => api}/WizardWrx.Core.TraceLogger.html (100%) rename docs/{ => api}/WizardWrx.Core.UnmanagedLibrary.html (99%) rename docs/{ => api}/WizardWrx.Core.html (100%) rename docs/{ => api}/WizardWrx.Cryptography.DigestFile.html (100%) rename docs/{ => api}/WizardWrx.Cryptography.DigestString.html (100%) rename docs/{ => api}/WizardWrx.Cryptography.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.ExceptionLogger.ErrorExitOptions.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.ExceptionLogger.OutputOptions.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.ExceptionLogger.ScrollUpResult.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.ExceptionLogger.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.IniFileReader.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.Properties.Resources.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.Properties.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.StateManager.AssemblyVersionRequest.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.StateManager.html (100%) rename docs/{ => api}/WizardWrx.DLLConfigurationManager.html (100%) rename docs/{ => api}/WizardWrx.DisplayFormats.html (100%) rename docs/{ => api}/WizardWrx.EmbeddedTextFile.ByteOrderMark.BOMType.html (100%) rename docs/{ => api}/WizardWrx.EmbeddedTextFile.ByteOrderMark.html (100%) rename docs/{ => api}/WizardWrx.EmbeddedTextFile.Readers.html (100%) rename docs/{ => api}/WizardWrx.EmbeddedTextFile.html (100%) rename docs/{ => api}/WizardWrx.FileIOFlags.html (100%) rename docs/{ => api}/WizardWrx.FileInfoExtension.enmInitialStatus.html (100%) rename docs/{ => api}/WizardWrx.FileInfoExtension.html (100%) rename docs/{ => api}/WizardWrx.FileInfoExtensionMethods.html (100%) rename docs/{ => api}/WizardWrx.FileNameTricks.TerminaBackslash.html (100%) rename docs/{ => api}/WizardWrx.FileNameTricks.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.FormatItem.Alignment.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.FormatItem.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.FormatItemsCollection.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.FormatStringError.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.FormatStringParser.html (100%) rename docs/{ => api}/WizardWrx.FormatStringEngine.html (100%) rename docs/{ => api}/WizardWrx.GenericSingletonBase-1.html (99%) rename docs/{ => api}/WizardWrx.ListHelpers.CompareResult.html (100%) rename docs/{ => api}/WizardWrx.ListHelpers.html (99%) rename docs/{ => api}/WizardWrx.ListInfo.html (100%) rename docs/{ => api}/WizardWrx.Logic.html (100%) rename docs/{ => api}/WizardWrx.MagicBooleans.html (100%) rename docs/{ => api}/WizardWrx.MagicNumbers.html (100%) rename docs/{ => api}/WizardWrx.NumberFormatters.html (100%) rename docs/{ => api}/WizardWrx.NumericFormats.HexFormatDecoration.html (100%) rename docs/{ => api}/WizardWrx.NumericFormats.html (100%) rename docs/{ => api}/WizardWrx.PathPositions.html (100%) rename docs/{ => api}/WizardWrx.RegExpSupport.html (100%) rename docs/{ => api}/WizardWrx.ReportDetail.ItemDisplayOrder.html (100%) rename docs/{ => api}/WizardWrx.ReportDetail.LabelChangedEventArgs.html (100%) rename docs/{ => api}/WizardWrx.ReportDetail.State.html (100%) rename docs/{ => api}/WizardWrx.ReportDetail.html (100%) rename docs/{ => api}/WizardWrx.ReportDetails.html (100%) rename docs/{ => api}/WizardWrx.ReportHelpers.Alignment.html (100%) rename docs/{ => api}/WizardWrx.ReportHelpers.html (100%) rename docs/{ => api}/WizardWrx.SpecialCharacters.html (100%) rename docs/{ => api}/WizardWrx.SpecialStrings.html (100%) rename docs/{ => api}/WizardWrx.StringExtensions.html (100%) rename docs/{ => api}/WizardWrx.StringTricks.html (100%) rename docs/{ => api}/WizardWrx.SyncRoot.html (100%) rename docs/{ => api}/WizardWrx.SysDateFormatters.html (100%) rename docs/{ => api}/WizardWrx.TextBlocks.html (100%) rename docs/{ => api}/WizardWrx.html (100%) create mode 100644 docs/api/index.html copy docs/{ => api}/toc.html (100%) create mode 100644 docs/articles/intro.html create mode 100644 docs/articles/toc.html create mode 100644 docs/favicon.ico create mode 100644 docs/fonts/glyphicons-halflings-regular.eot create mode 100644 docs/fonts/glyphicons-halflings-regular.svg create mode 100644 docs/fonts/glyphicons-halflings-regular.ttf create mode 100644 docs/fonts/glyphicons-halflings-regular.woff create mode 100644 docs/fonts/glyphicons-halflings-regular.woff2 rewrite docs/index.html (91%) create mode 100644 docs/logo.svg create mode 100644 docs/manifest.json create mode 100644 docs/search-stopwords.json create mode 100644 docs/styles/docfx.css create mode 100644 docs/styles/docfx.js create mode 100644 docs/styles/docfx.vendor.css create mode 100644 docs/styles/docfx.vendor.js create mode 100644 docs/styles/lunr.js create mode 100644 docs/styles/lunr.min.js create mode 100644 docs/styles/main.css create mode 100644 docs/styles/main.js create mode 100644 docs/styles/search-worker.js rewrite docs/toc.html (97%) create mode 100644 docs/xrefmap.yml DAG@ABACUS MINGW64 /f/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx (master)
为避免混乱的结果并防止丢失更改,请在发出另一个提交之前执行下一个命令。
第 3 步(共 3 步):将更改从本地 Git 仓库推送到 GitHub。完成此步骤后,您的 API 已发布,几乎可以供用户查看了。您可以通过输入以下 Git 命令来完成此操作:git push -u origin master
,该命令会产生类似以下的响应。
$ git push -u origin master Enumerating objects: 124, done. Counting objects: 100% (124/124), done. Delta compression using up to 8 threads. Compressing objects: 100% (102/102), done. Writing objects: 100% (105/105), 1.80 MiB | 1.02 MiB/s, done. Total 105 (delta 42), reused 0 (delta 0) remote: Resolving deltas: 100% (42/42), completed with 15 local objects. To https://github.com/txwizard/WizardWrx_NET_API.git 70e72c6..afeb4b9 master -> master Branch 'master' set up to track remote branch 'master' from 'origin'. DAG@ABACUS MINGW64 /f/Source_Code/Visual_Studio/Projects/WizardWrx_Libs/Wizardwrx (master)
虽然此命令的文本永远不会改变,但响应会根据远程仓库的位置和提交中的项目数量而有所不同。此处未显示的单次命令建立了此本地 Git 仓库与此远程 GitHub 仓库之间的连接。这些命令是在最初填充仓库的提交中发出的。
使文档可见
使所有内容可见的最后一步是在 GitHub 端完成的。虽然可能有一个 Git 命令可以做到这一点,但我没有深入研究,因为我在 Web 浏览器窗口中显示了该仓库,并且访问**设置**页面并进行更改很容易。使用**图 1** 帮助您找到它,它位于存储库名称正下方的链接列表的最右侧。
图 1:GitHub 仓库设置可在显示仓库名称的蓝色线条正下方的链接行最右侧找到。
显示设置页面时,您必须向下滚动,几乎到底部,才能找到控制您GitHub Pages 的组,它最初显示在图 2 中。

图 2:默认情况下,GitHub Pages 是禁用的。
出于显而易见的原因,GitHub Pages 默认对所有仓库都禁用。图 3 显示了我所做的唯一更改。我将在下一节解释为什么我将主题保持禁用(关闭)状态。

图 3:我将 GitHub Pages 设置为启用,但未启用主题。
我之所以保持主题禁用,是因为立即发现 DocFX 使用的 CSS 选择器和类与 Jekyll 主题使用的不同。没有它们,生成的显示效果勉强可以接受,如图 4 所示。
图 4:默认导航栏的对比度太低,不符合我的口味。
我无法继续而不提醒您,此屏幕是从正在进行的工作中捕获的。当我解决主题问题时,我已经在这个页面上填充了从其他页面移过来的内容。因此,下一个屏幕图 5 包含更多的文本,并且占位符已消失。
图 5:改进后的导航栏文本与背景色对比度大大提高。
掌控主题
将主题的控制权从 DocFX 模板所依赖的 Bootstrap CSS 中解放出来,比我预期的要容易得多,这要归功于我脑海中灵光一闪,导致我短暂地研究了同名样式和选择器的层叠顺序。
这是访问默认模板变得至关重要的点,因为它暴露了三个级联样式表文件(出现在 /docfx_project/_site/styles
中,但在 docfx init
命令生成的脚手架中其他地方找不到)的来源。
有三个这样的文件,如下所示。
docfx.css
是一个小型 CSS 文件,当我看到下一个文件时,我对此并未给予太多关注。docfx.vendor.css
仅仅是我们的朋友 Twitter, Inc. 提供的经典的 Bootstrap v3.3.7。main.css
最初是空的,旨在作为您覆盖一些 Bootstrap 样式的存根。
将 main.css
创建为一个空文件,可以使生成的文档 HTML 包含对它的引用,该引用在运行时解析,但什么也不做。更重要的是,生成器按正确的顺序设置它们,因此您在main.css中输入的任何内容都保证会覆盖它之上的任何内容,包括 docfx.css
,以及更重要的、在 docfx.vendor.css
中定义的、更全面和普遍的设置。
我通过覆盖少量选择器实现了我真正想要的一切,其中最关键的 .navbar-inverse
类定义在 docfx.vendor.css
中。
article h1 {
font-size : 24pt;
font-weight : 300;
margin-top : 1em;
margin-bottom : 0.5em;
color : #9932CC;
background-color : #ffffff;
}
article h2 {
font-size : 16pt;
font-weight : 300;
margin-top : 1em;
margin-bottom : 0.5em;
color : #000080;
background-color : #ffffff;
}
code {
color : #4B0082;
background-color : #ffffff;
border-radius : 4px
}
.navbar-inverse{background-color:#9932CC;border-color:#080808;font-size:24px;}
.navbar-inverse .navbar-brand{color:#9932CC}
.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#FFD700;background-color:transparent}
.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#fff}
.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#FFD700;background-color:transparent}
.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}
.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}
.navbar-inverse .navbar-toggle{border-color:#333}
.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}
.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}
.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}
.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}
最后一个棘手的部分是弄清楚如何让我的自定义 main.css
对 DocFX 可见。我最初阅读文档时,认为自定义模板目录应该放在 C:\ProgramData\chocolatey\lib\docfx\templates
中,但事实证明并非如此。模板的正确位置是 \docfx_project\templates
,它应该放在一个目录中,该目录的名称是它所代表的模板的名称,在我的情况下是 C#_Libraries
。由于C#_Libraries的结构必须与默认模板的结构相似,因此 CSS 文件放在 styles
目录中,所以相对于 DocFX 项目目录的路径是 \docfx_project\templates\C#_Libraries\styles
。
最后一块拼图是对位于根目录 \docfx_project
的 docfx.json
的一个小手动编辑。
"template": [ "default" , "templates/C#_Libraries" ],
键 template
是一个现有数组的名称,该数组最初包含一个项目,即 default
。添加 templates/C#_Libraries
会导致生成器导入我们的自定义 main.css
,从而替换了来自默认模板的同名空文件。请注意 Unix 风格的路径分隔符的使用以及缺失的开头和结尾分隔符。在docfx.json中指定的目录被假定为相对于\docfx_project,并且最后一个名称隐式地是一个目录,因为此条目根据定义是一个目录的名称。
路线图
- 最直接的下一步是在我几乎所有其他公共仓库中复制这项工作。
- 接下来是集成文档生成到项目构建中。这可能涉及实现上面提到的 NuGet 包,尽管我可能会选择使用一个独立的、使用我已有的 CLI 工具的后期构建步骤。
- 最后,我可能会尝试进一步改进模板以创建我自己的主题。其中最重要的是摆脱导航栏中那个丑陋的大 D。我不介意每个页面都宣传它是 DocFX 生成的;事实上,我为此感到高兴,但那个 D 在导航栏中看起来不合适。
关注点
除了实现一个长期的目标之外,我无法诚实地指出任何真正的“兴趣点”。唯一能想到的真正兴趣点是,这项应用是我第一个可以合法使用 NTFS 卷影的应用。到目前为止,卷影更多的是一种干扰而不是帮助,因为它们用几乎不可能安全根除的重复条目弄乱了目录列表,而且我不知道有什么方法可以告诉内部的 dir 命令跳过它们。
历史
2018 年 9 月 16 日星期日,第一次发布以供出版。
2018 年 9 月 17 日星期一,为了修复图像 URL 而进行的强制性更新。