View a markdown version of this page

程序包组定义语法和匹配行为 - CodeArtifact

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

程序包组定义语法和匹配行为

本主题包含有关定义程序包组、模式匹配行为、程序包关联强度和程序包组层次结构的信息。

程序包组定义语法和示例

定义程序包组的模式语法严格遵循程序包路径的格式。程序包路径是根据程序包的坐标组件(格式、命名空间和名称)创建的,方法是在开头添加正斜杠,然后用正斜杠分隔每个组件。例如,命名空间中名为 anycompany-ui-components 的 npm 包的包路径是 //anycompany-ui-co mponents。npm/space

程序包组模式遵循与程序包路径相同的结构,不同之处在于省略了未指定为组定义一部分的组件,并且该模式以一个后缀结尾。包含的后缀决定了模式的匹配行为,如下所示:

  • $ 后缀将与完整的程序包坐标匹配。

  • ~ 后缀将与一个前缀匹配。

  • * 后缀将与先前定义的组件的所有值匹配。

以下是每种允许组合的示例模式:

  1. 所有程序包格式:/*

  2. 特定程序包格式:/npm/*

  3. 程序包格式和命名空间前缀:/maven/com.anycompany~

  4. 程序包格式和命名空间:/npm/space/*

  5. 程序包格式、命名空间和名称前缀:/npm/space/anycompany-ui~

  6. 程序包格式、命名空间和名称:/maven/org.apache.logging.log4j/log4j-core$

如以上示例所示,~ 后缀添加到命名空间或名称的末尾以表示前缀匹配,当用于匹配路径中下一个组件的所有值(所有格式、所有命名空间或所有名称)时,* 位于正斜杠之后。

程序包组定义和规范化

CodeArtifact 对 NuGet Python 和 Swift 包名进行标准化,并在存储 Swift 包命名空间之前对其进行标准化处理。 CodeArtifact 在将包与包组定义进行匹配时,使用这些标准化名称。因此,包含采用这些格式的命名空间或名称的程序包组必须使用规范化的命名空间和名称。有关如何规范包名称和命名空间的更多信息,请参阅、P NuGetyth onSwift 名称标准化文档。

程序包组定义中的命名空间

对于没有命名空间的包或包格式(Python 和 NuGet),包组不得包含命名空间。这些程序包组的程序包组定义包含一个空白的命名空间部分。例如,名为 requests 的 Python 程序包的路径为 /python//requests

对于带有命名空间的程序包或程序包格式(Maven、通用和 Swift),如果包含程序包名称,则必须包含命名空间。对于 Swift 程序包格式,将使用规范化的程序包命名空间。有关如何规范 Swift 程序包命名空间的更多信息,请参阅 Swift 程序包名称和命名空间规范化

程序包组层次结构和模式特异性

“在” 或 “与包组相关联” 的软件包是指其包路径与该组的模式相匹配但与更具体的组的模式不匹配的软件包。例如,给定包组/npm/*/npm/space/*,包路径 /npm//react 与第一组 (/npm/*) 关联,而/npm/spaceaui.compon ents 和 npm/space/amplif y-ui-core 与第二组 () 关联。/npm/space/*尽管一个包可能匹配多个组,但每个包仅与一个组相关联,即最具体的匹配项,并且只有该组的配置适用于该软件包。

当一个包路径与多个模式匹配时,可以将 “更具体” 的模式视为最长的匹配模式。或者,更具体的模式是与程序包(该程序包与不太具体的模式匹配)的适当子集匹配的模式。在之前的示例中,每个与 /npm/space/* 匹配的程序包也都与 /npm/* 匹配,但反之则不成立,这使得 /npm/space/* 模式更具体,因为它是 /npm/* 的一个适当子集。由于一个组是另一个组的子集,因此它会创建一个层次结构,其中 /npm/space/* 是父组 /npm/* 的子组。

尽管只有最具体的软件包组的配置适用于软件包,但可以将该组配置为继承其父组的配置。

单词、单词边界和前缀匹配

讨论前缀匹配之前,我们先定义一些关键术语:

  • 单词是一个字母或数字,后跟零个或多个字母、数字或标记字符(例如重音符号、变音符号等)。

  • 当到达非单词字符时,单词边界位于单词的末尾。 Non-word 字符是标点符号.,例如-、和_

具体而言,单词的正则表达式模式是 [\p{L}\p{N}][\p{L}\p{N}\p{M}]*,可以分解如下:

  • \p{L} 代表任何字母。

  • \p{N} 代表任意数字。

  • \p{M} 代表任何标记字符,例如重音符号、变音符号等。

因此,[\p{L}\p{N}] 代表一个数字或字母,[\p{L}\p{N}\p{M}]* 代表零个或多个字母、数字或标记字符,而单词边界位于此正则表达式模式的每个匹配项的末尾。

注意

单词边界匹配基于 “单词” 的定义。它不是基于字典中定义的单词,或 CamelCase。例如,onewordOneWord 中没有单词边界。

现在定义了单词和单词边界,我们可以用它们来描述中的前缀匹配 CodeArtifact。为了表示单词边界上的前缀匹配,在单词字符后面使用匹配字符(~)。例如,模式 /npm/space/foo~ 与程序包路径 /npm/space/foo/npm/space/foo-bar 匹配,但与 /npm/space/food/npm/space/foot 不匹配。

非单词字符后面需要使用通配符(*),而不是 ~,例如在模式 /npm/* 中。

区分大小写

程序包组定义区分大小写,这意味着仅在大小写方面有所不同的模式可作为单独的程序包组存在。例如,用户可以使用 npm Public Registry 中存在的三个单独的软件包创建单独的软件包组:/npm//AsyncStorage$/npm//asyncStorage$、、、、和,它们仅/npm//asyncstorage$因大小写而有所不同:AsyncStorageasyncStorag e、asyncStorag e。

尽管大小写很重要, CodeArtifact 但如果包裹的模式变体因大小写而异,则仍会将包裹与包裹组关联起来。如果用户在创建/npm//AsyncStorage$软件包组时没有创建上面显示的其他两个组,则名称AsyncStorage的所有大小写变体,包括 AsyncStorage 和 as yncStorag e,都将与该软件包组相关联。但是,如下一节所述强匹配和弱匹配,这些变体的处理方式将与模式完全匹配。AsyncStorage

强匹配和弱匹配

上一节区分大小写中的信息说明程序包组区分大小写,接着又解释它们不区分大小写。这是因为中的软件包组定义 CodeArtifact 具有强匹配(或完全匹配)和弱匹配(或变体匹配)的概念。强匹配是指程序包与模式完全匹配,无任何变体。弱匹配是指程序包与模式的变体(例如不同的字母大小写)匹配。弱匹配行为可防止包组模式变体的软件包汇总到更通用的包组。当软件包是最具体的匹配组模式的变体(弱匹配)时,该包与该组关联,但该包会被屏蔽,而不是应用该组的源控制配置,从而阻止该包的任何新版本从上游提取或发布。这种行为降低了由于名称几乎相同的程序包的依赖项混淆而导致供应链攻击的风险。

为了说明弱匹配行为,假设程序包组 /npm/* 允许摄取但阻止发布。更具体的程序包组 /npm//anycompany-spicy-client$ 被配置为阻止摄取但允许发布。名为 anycompany-spicy-client 的程序包是程序包组的强匹配,允许发布程序包版本但阻止摄取程序包版本。允许发布的程序包名称的唯一大小写格式为 anycompany-spicy-client,因为它是程序包定义模式的强匹配。另一种大小写变体,例如由于匹配AnyCompany-spicy-client度较弱,因此无法发布。更重要的是,程序包组会阻止摄取所有大小写变体,而不仅仅是模式中使用的小写名称,从而降低了依赖项混淆攻击的风险。

其他变体

除了大小写差异外,弱匹配还会忽略破折号 -、点 .、下划线 _ 和易混淆字符(例如来自不同字母表的外观相似的字符)序列方面的差异。在用于弱匹配的标准化过程中, CodeArtifact 执行大小写折叠(类似于转换为小写字母),用单个点替换短划线、点和下划线字符序列,并对可混淆的字符进行标准化。

弱匹配将破折号、点和下划线视为等效,但不会完全忽略它们。这意味着 foo-barfoo.barfoo..barfoo_bar 都是弱匹配的等效形式,但 foobar 不是。尽管一些公共存储库实施了防止此类变体的措施,但公共存储库提供的保护并未使包组的此功能变得不必要。例如,诸如 npm Public Registry 之类的公共存储库只有在 my-package 已经发布到名为 my-package 的包时才会阻止其出现新的变体。如果 my-package 是内部程序包,并且您已创建允许发布但阻止摄取的程序包组 /npm//my-package$,那么您可能不想将 my-package 发布到 npm 公有注册表,以防止允许诸如 my.package 之类的变体。

虽然某些程序包格式(例如 Maven)对这些字符的处理方式不同(Maven 将 . 而不是 -_ 视为命名空间层次结构分隔符),但像 com.act-on 这样的程序包仍可能与 com.act.on 发生混淆。

注意

请注意,每当有多个变体与一个程序包组关联时,管理员都可以为特定变体创建一个新的程序包组,以便为该变体配置不同的行为。