符号链接

虽然Antora要求文件遵循标准层次结构,但可以使用符号链接将现有位置的文件重新映射到此层次结构中。本页介绍了符号链接并解释了它们如何在Antora中用于帮助构建内容层次结构。

符号链接,简称为符号链接,是一个指向文件的快捷方式,本身就像一个文件。换句话说,它是一个指向另一个文件的文件。符号链接的目的是为文件提供第二个位置,而无需复制它。符号链接还可以指向目录,从而有效地将该目录下的所有文件链接到新位置。符号链接甚至可以指向另一个符号链接,从而使文件或目录具有更多位置成为可能。

符号链接的行为就像普通文件或目录一样,尽管具有一些额外的元数据。像Antora这样的应用程序遇到符号链接时会将其视为任何其他文件或目录。这种属性使符号链接成为重新映射文件(例如示例和局部文件)到Antora层次结构的理想工具。在深入讨论之前,让我们看看符号链接在哪些地方受支持以及如何创建它们。

尽管符号链接曾经只在Unix和类Unix(*nix)操作系统中常见,在现代计算中,对符号链接的支持是普遍的。符号链接可以在本地文件系统和git存储库中使用,并且它们之间可以透明地转换。

如果你在想,是的,符号链接在Windows上也可以工作。自Windows 10以来,符号链接(而不是某种模拟)在Windows上得到了完全支持。请参阅Windows 10中的符号链接以了解此功能的推出。

在git中,符号链接实际上与操作系统文件系统上的符号链接不同。在git中,符号链接是一个数据文件(具有特殊的文件模式),它存储对存储库中相对路径的引用。当你将包含符号链接的分支检出到工作树(例如,git clonegit checkout)时,该引用会转换为本地文件系统上的符号链接。但即使这种情况没有发生(core.symlinks未启用),符号链接也会被创建为包含路径引用的常规文件(就像在git存储库中一样)。

符号链接可以指向文件、目录,甚至另一个符号链接。

创建符号链接时,关系应始终表示为相对路径。如果使用绝对路径,它将绑定符号链接到本地文件系统的布局,并且不会转换为git。

创建符号链接的命令取决于您是使用类Unix操作系统还是Windows。但是,它产生的结果是相同的。

*nix

要在类Unix操作系统(也称为*nix)上创建符号链接,您可以使用带有-s标志的ln命令。以下是如何创建指向同级文件的符号链接的示例:

$ ln -s target.adoc link.adoc

在这种情况下,link.adoc是一个符号链接,指向文件target.adoc

这也适用于目录:

$ ln -s target link

在这种情况下,link是一个符号链接,指向目录target。符号链接充当目录。

更常见的情况是,您希望将其映射到当前目录之外的位置。这意味着在符号链接目标的路径中包括一个或多个目录段。

要创建指向目录中文件的符号链接,请首先导航到要创建符号链接的目录。然后,将目标指定为相对于该目录的路径。这看起来有点反向,但它将创建一个从link开始指向target的指针。

$ ln -s ../../path/to/target.adoc link.adoc

在这种情况下,link.adoc是一个符号链接,指向文件../../path/to/target.adoc,相对于包含符号链接的目录。目标可能位于嵌套目录中,而不是父目录中。

对于目录,您也可以执行相同的操作:

$ ln -s ../../path/to/target link

在这种情况下,link是一个符号链接,指向目录../../path/to/target,相对于包含符号链接的目录。符号链接充当目录。

Windows

要在Windows上创建符号链接,您可以使用mklink命令。此命令可用于创建指向文件或目录的符号链接。(与硬链接或目录链接相比,最好使用符号链接)。

要创建指向文件的符号链接,语法如下:

mklink <link> <target>

要创建指向目录的符号链接,语法如下:

mklink /d <link> <target>
在Windows中,与*nix的ln命令相比,链接和目标的顺序是相反的。

以下是使用mklink创建指向同级文件的符号链接的示例:

$ mklink link.adoc target.adoc

在这种情况下,link.adoc是一个符号链接,指向文件target.adoc

现在让我们创建一个指向同级文件夹的符号链接。

mklink /d link target

在这种情况下,link是一个符号链接,指向目录target。符号链接充当目录。

更常见的情况是,您希望链接到当前目录之外的位置。这意味着在符号链接目标的路径中包括一个或多个目录段。

要创建指向目录中文件的符号链接,请首先导航到要创建符号链接的目录。然后,将目标指定为相对于该目录的路径。这将创建一个从link开始指向target的指针。

$ mklink link.adoc ..\..\path\to\target.adoc

在这种情况下,link.adoc是一个符号链接,指向文件..\..\path\to\target.adoc,相对于包含符号链接的目录。目标可能位于嵌套目录中,而不是父目录中。

对于目录,您也可以执行相同的操作:

$ mklink /d link ..\..\path\to\target

在这种情况下,link是一个符号链接,指向目录..\..\path\to\target,相对于包含符号链接的目录。符号链接充当目录。

Antora完全支持符号链接。这意味着您可以在工作树中使用符号链接,也可以在git树中使用符号链接(是的,git也支持符号链接)。

它是如何工作的?

当Antora遇到指向文件的符号链接时,它不会尝试将其保留为符号链接。相反,它会像对待任何其他文件一样创建一个常规虚拟文件。我们可以说,在Antora的虚拟文件系统中,该文件被复制了,尽管如果它是符号链接在Antora层次结构下的唯一部分,它最终可能是唯一的实例。

当Antora遇到指向目录的符号链接时,它会读取目标目录下的所有文件,并为每个文件创建一个常规虚拟文件。在这种情况下,Antora会保留符号链接的路径,然后从那一点开始将路径附加到文件。就Antora而言,该文件位于由符号链接表示的目录内,就好像符号链接是一个真实的目录一样。我们可以说,在Antora的虚拟文件系统中,该目录下的所有文件都被复制了,尽管如果目标目录不是Antora层次结构的一部分,它们最终可能是这些文件的唯一实例。

这里的要点是,通过使用符号链接,您可以说服Antora文件或目录位于实际位置之外。如果它是指向文件的符号链接,Antora会将其视为您将文件复制到那里,尽管实际上并没有。如果它是指向目录的符号链接,Antora会将其视为您递归地将目录复制到那里,尽管实际上并没有。

让我们学习如何利用这一功能。

让我们考虑Antora中符号链接功能最常见的用法之一。您有一些示例文件想要包含在文档中,但这些文件不在标准的Antora目录结构内。为了使它们对Antora可用,您需要将它们重新映射到Antora层次结构中。

让我们看看该布局:

📒 docs
  📄 antora.yml
  📂 modules
    📂 ROOT
      📂 pages
        📄 index.adoc
      📄 nav.adoc
📒 src
  📒 main
    📒 java
      📒 org
        📒 example
          📄 MyClass.java

我们想要的是将源文件 MyClass.java(或其中的某部分)包含在页面 index.adoc 中。但是,由于源文件不在Antora层次结构下,目前无法实现。符号链接来拯救!

首先,在符号链接将位于的ROOT模块下创建 examples 文件夹。

📒 docs
  📄 antora.yml
  📂 modules
    📂 ROOT
      📂 examples
      📂 pages
        📄 index.adoc
      📄 nav.adoc
📒 src
  📒 main
    📒 java
      📒 org
        📒 example
          📄 MyClass.java

接下来,让我们在终端中切换到该目录,并从 examples 文件夹创建指向 MyClass.java 的符号链接,以将其引入Antora层次结构。

$ cd docs/modules/ROOT/examples

然后,使用适合您操作系统的命令创建符号链接。

*nix
$ ln -s ../../../src/main/java/org/example/MyClass.java MyClass.java
Windows
$ mklink MyClass.java ..\..\..\src\main\java\org\example\MyClass.java

这是结果。

📒 docs
  📄 antora.yml
  📂 modules
    📂 ROOT
      📂 examples
        🔗 MyClass.java (1)
      📂 pages
        📄 index.adoc
      📄 nav.adoc
📒 src
  📒 main
    📒 java
      📒 org
        📒 example
          📄 MyClass.java
1 MyClass.java 是指向存储库根目录下 src/main/java/org/example/MyClass.java 文件的符号链接
如果您的文档内容来自git引用,请像对待任何其他文件一样将符号链接提交到git存储库。

现在,您可以使用以下包含指令在 index.adoc 页面中包含源文件:

include::example$MyClass.java[]

您可能会觉得为要包含的每个文件创建符号链接很繁琐。这就是目录符号链接发挥作用的地方。您可以创建一个指向目录的符号链接,这实际上将该层次结构嫁接到Antora层次结构中。

与其创建指向源文件的符号链接,不如创建一个指向 src 文件夹的符号链接。同样,首先切换到 examples 目录。

$ cd docs/modules/ROOT/examples

然后,使用适合您操作系统的命令创建符号链接。

*nix
$ ln -s ../../../src src
Windows
$ mklink src ..\..\..\src

这是结果:

📒 docs
  📄 antora.yml
  📂 modules
    📂 ROOT
      📂 examples
        🔗 src (1)
      📂 pages
        📄 index.adoc
      📄 nav.adoc
📒 src
  📒 main
    📒 java
      📒 org
        📒 example
          📄 MyClass.java
1 src 是指向存储库根目录下 src 文件夹的符号链接
如果您的文档内容来自git引用,请像对待任何其他文件一样将符号链接提交到git存储库。即使符号链接指向一个目录,在git中,它仍然被视为文件。

现在,您可以使用以下包含指令在 index.adoc 页面中包含源文件:

include::example$src/main/java/org/example/MyClass.java[]

您可以为任何类型的资源创建符号链接,包括示例、部分、页面、图像等。尽管符号链接的目标通常位于Antora层次结构之外,但如果意图是复制文件或目录,则符号链接可以指向Antora层次结构内的位置。

限制

在Antora中使用符号链接时需要注意一些限制。

  • 符号链接的目标必须存在。如果Antora无法解析符号链接,将会抛出错误。

  • 符号链接不能指向自身。如果Antora检测到这种情况,将会抛出错误。

  • git存储库中的符号链接不能指向git存储库之外的位置。

  • git存储库中的符号链接不能指向git存储库中另一个引用的位置。

  • 符号链接的目标应该是相对的。创建指向绝对路径的符号链接具有未定义或不可移植的行为。

不要将许多未在文档站点中使用的文件映射到Antora层次结构中。这样做会为Antora增加额外的处理,可能会减慢构建速度。尽量精确地选择要映射到Antora层次结构中的文件。