{"id":13585423,"url":"https://github.com/repology/repology-rules","last_synced_at":"2025-04-07T09:34:43.976Z","repository":{"id":30804458,"uuid":"126047919","full_name":"repology/repology-rules","owner":"repology","description":"Package normalization ruleset for Repology","archived":false,"fork":false,"pushed_at":"2024-04-10T19:23:09.000Z","size":12049,"stargazers_count":101,"open_issues_count":30,"forks_count":111,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-04-10T21:59:27.044Z","etag":null,"topics":["package","packages","repository","version"],"latest_commit_sha":null,"homepage":"https://repology.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/repology.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-03-20T16:26:03.000Z","updated_at":"2024-04-15T14:59:36.100Z","dependencies_parsed_at":"2023-02-19T11:01:15.839Z","dependency_job_id":"4cc938c7-0430-4f13-a768-1042e0bcf1c2","html_url":"https://github.com/repology/repology-rules","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repology%2Frepology-rules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repology%2Frepology-rules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repology%2Frepology-rules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repology%2Frepology-rules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/repology","download_url":"https://codeload.github.com/repology/repology-rules/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223277862,"owners_count":17118660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["package","packages","repository","version"],"created_at":"2024-08-01T15:04:56.065Z","updated_at":"2024-11-06T03:31:05.311Z","avatar_url":"https://github.com/repology.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Repology ruleset\n\n![CI](https://github.com/repology/repology-rules/workflows/CI/badge.svg)\n\nThere can be a huge discrepancy in how packages for a single project\nare named and versioned in different repositories, so Repology\nneeds a flexible ruleset in order to overcome the differences,\nmatch packages, and make versions comparable.\n\n## TL;DR\n\nYou are welcome to submit pull requests with the rules you need.\nHere's a quick pointer of how to add specific rules:\n\n### You want to **merge** differently named packages into a single entry?\n\n- Choose a target name (prefer the least ambiguous and/or most widely used name)\n- Open the corresponding yaml file under [`800.renames-and-merges/`](./800.renames-and-merges/)\n  (if there's no existing yaml file relevant to your package,\n  use the file named with the first letter of your target name, like `a.yaml`)\n- Add a rule like `- { setname: \u003ctarget name\u003e, name: \u003coriginal name\u003e }`\n\n### You want to mark incorrect versions of a specific package?\n\n- Open the corresponding yaml file under [`900.version-fixes/`](./900.version-fixes/)\n- Add a rule like: `- { name: \u003cpackage name\u003e, ver: \u003cbad version\u003e, ignore: true }`\n- Consider using a `verpat` with a regular expression to match similar\n  bad versions which may appear in the future. Examples:\n  - `verpat: \"20[0-9]{6}\"` to match dates (`20110323`)\n  - `verpat: \"20[0-9]{2}\\\\.[0-9]{2}\\\\.[0-9]{2}\"` same, but for delimited date, (`2010.03.23`)\n  - `verpat: \".*20[0-9]{6}.*\"` to match dates anywhere in the version (`1.0.20110323`)\n  - `verpat: \"[0-9a-f]{7}\"` match something resembling a git commit (`a7b823f`)\n  - `verpat: \"[0-9]{4,}\"` match something resembling a build or revision number (`12345`)\n\n### You want to split different projects with the same name\n\n- Open the corresponding yaml file under [`850.split-ambiguities/`](./850.split-ambiguities/)\n- Add a group of rules to distinguish packages by upstream URL\n  ([wwwpart](#wwwpart), [wwwpat](#wwwpat) and [sourceforge](#sourceforge)\n  conditions are allowed). Such group must end with a\n  catch-all rule for packages not matched by specific\n  rules. Example:\n  ```yaml\n  - { name: \u003cambiguous name\u003e, wwwpart: \u003curl part for project A\u003e, setname: \u003cname A\u003e }`\n  - { name: \u003cambiguous name\u003e, wwwpart: \u003curl part for project B\u003e, setname: \u003cname B\u003e }`\n  - { name: \u003cambiguous name\u003e, addflag: unclassified }\n  ```\n\n## Contributing\n\nThings to know if you're submitting a pull request or have push access\nto this repository.\n\n- Repology is currently set up to automatically pull the latest ruleset\n  from the `master` branch in this repository on each update, so everything\n  committed here will be automatically applied to Repology in several\n  hours.\n- Repology runs `make check` after updating the repository, and if it\n  fails, rolls back to the latest good commit, so it's somewhat\n  protected from a broken ruleset.\n- In the worst case, a broken ruleset will prevent Repology from\n  updating until the problem is resolved.\n- Still, please run `make check` before committing, and/or install\n  the git hook in [`scripts/pre-push`](./scripts/pre-push),\n  which runs it for you (you can copy it into `.git/hooks`\n  or just run `make install-hook`).\n- The checker script requires the Python modules `voluptuous` and `PyYAML`.\n  `pip install PyYAML voluptuous` should install them for you.\n- In general, stay close to the style already used in the ruleset,\n  use existing rules as examples, keep it simple and have fun!\n- If in doubt, you can always just submit a report from the package's page\n  on the website and avoid all the work!\n\n## Rule basics\n\nRules are stored in a set of files in [YAML](http://yaml.org/) format,\na flexible human-friendly markup format for structured data.\nEach rule is a single item of a big array, and may be written in a single or\nmultiple lines (depending on what's more convenient for the particular\ncase). For example, the following rule renames `etracer` into `extreme-tuxracer`:\n\n```yaml\n- { name: etracer, setname: extreme-tuxracer }\n```\n\nwhich is the same as:\n\n```yaml\n- name: etracer\n  setname: extreme-tuxracer\n```\n\nEach rule has a set of keywords which specify how a package is matched\n(by name, version, repository, category etc.) and how it is modified\n(package is renamed, version scheme is changed, flags are applied, etc.).\n\nRule order matters, as multiple rules may match a single package, and\nthey are applied in order. Furthermore, changes applied by earlier\nrules affect further matches: for instance, if a package is renamed,\nthe new name will be matched for the following rules.\n\nWhile rules are basically arbitrary, it's practical though to attribute\neach rule to a specific class of action, the most distinctive of which are:\n\n- **Rename or merge rules.** Match a name, and set another name. The main purpose\n  is to merge differently-named packages into the same project. For example,\n  `etracer`, `extremetuxracer`, `extreme-tuxracer` → `extreme-tuxracer`.\n- **Split rules.** Match a name and some additional property (version, homepage\n  or repository), and set another name. Used to split similarly-named\n  packages of different projects. For example, `clementine` → `clementine-wm`,\n  `clementine-player`.\n- **Version fixes.** Match a name but do not change it; instead, change versions\n  or set some version-related flags. Used to fix incorrect versioning scheme\n  (`v1.0` → `1.0`), mark some versions as devel (such as beta versions),\n  or ignore some versions (e.g. snapshots like `20130523` when there are\n  official versions like `1.0`).\n\n## Ruleset structure\n\nThe ruleset is split into several distinctive parts,\nmostly based on the functional class of rules described above.\nThey are arranged in such a way that when adding a rule into a specific part\nyou don't need to be aware of the rest of the ruleset.\n\n- **100.prefix-suffix** - normalization of repository specific prefixes and\n  suffixes which are not part of the meaningful package name. Such as removal\n  of `lib32-` prefixes.\n\n- **2xx.handpicked** - a block where access to unmodified package names is\n  needed, such as manual whitelists or blacklists.\n\n- **[45]xx.wildcard** - wildcard rules which affect a lot of packages. These\n  mostly handle modules for specific languages such as Perl (which may be\n  named like `p5-Foo-Bar` or `libfoo-bar-perl` in different repositories)\n  by adding distinctive prefix (`perl:` in this case) to them,\n  so they do not conflict with modules for other languages and other software.\n\n  There are three subsets here:\n  - **pure** rules which are known to not have any false positives\n  (e.g. packages from `CPAN` are always perl modules).\n  - **exceptions** for the wildcard rules\n  - **wildcard** rules themselves\n\n- **750.exceptions** - the small set of remaining exceptions.\n  If a package needs a rule here, it's most positively incorrectly named.\n\n- **800.renames-and-merges** - pure merge rules\n\n- **850.split-ambiguities** - pure split rules\n\n- **900.version-fixes** - pure version fixes\n\n- **950.split-branches** - additional split section for projects which\n  have multiple development branches which are incompatible and may\n  present in a single repository at the same time for compatibility\n  purposes. For example, `gtk2` and `gtk3`.\n\n- There are also some **fixme** subsets which are remainings of the previous\n  generation of the ruleset. These files will eventually be refactored\n  and removed.\n\nThis may seem complex, but in practice the mostly used rulesets are\n**800**, **850** and **900**, which cleanly correspond to three functional\nclasses of rules described in the [previous section](#tldr).\n\nOther parts of the ruleset may need attention when new repositories are\nintroduced.\n\n## Rule syntax\n\nAs already mentioned, the keywords that comprise rules are related to either\nmatching packages, or modifying them. Below are detailed descriptions for all\nof them.\n\n### Conditions\n\n#### ruleset\n\nEach repository that Repology supports has a set of *rulesets* associated with\nit. For instance, all Debian-based distros have the ruleset `debuntu`. This may\nbe used to only match packages in specific repositories, but without the need\nto chase a specific repository version. You may look up repositories and their\ndetails in the [repos.d](https://github.com/repology/repology-updater/tree/master/repos.d)\ndirectory of the main Repology repository.\n\nYou may specify a list of rulesets to match any of them.\n\n```yaml\n- { ruleset: freebsd, ... }\n\n- { ruleset: [ arch, openbsd ], ... }\n```\n\n#### noruleset\n\nDisable rule matching for specified ruleset(s).\n\n```yaml\n# applies to all Debian derivatives, but not Deepin\n- { ruleset: debuntu, noruleset: deepin, ... }\n```\n\n#### family\n\nDeprecated. Same as **ruleset**, and may be just changed into it.\n\n#### category\n\nMatches package category(ies). Note that category information is not\navailable for all repositories, and each repository may have its\nown set of categories.\n\n```yaml\n- { category: games, ... }\n\n- { category: [ mail-client, mail-filter, mail-mta ], ... }\n```\n\n#### categorypat\n\nMatches package category(ies) against a regular expression.\nThe whole category is matched, match is case insensitive.\n\n```yaml\n- { categorypat: \"emacs[0-9]+Packages\" }\n```\n\n#### maintainer\n\nMatches package maintainer(s). The matching is case-insensitive.\n\n```yaml\n- { maintainer: \"nobody@nowhere.com\" }\n```\n\n#### name\n\nMatch exact package name(s).\n\n```yaml\n- { name: firefox, ... }\n\n- { name: [postgresql-client, postgresql-server, postgresql-contrib], ... }\n```\n\n#### namepat\n\nMatches package name against a regular expression.\nThe whole name is matched. May contain captures.\n\n```yaml\n- { namepat: \"swig[0-9]+\", ... }\n```\n\n#### ver\n\nMatches exact package version(s).\n\n```yaml\n- { name: firefox, ver: \"50.0.1\", ... }\n```\n\n#### notver\n\nThe opposite of **ver**: matches if the package version is none of specified\nversion(s).\n\n```yaml\n- { name: firefox, notver: [\"50.0.1\", \"50.0.2\"] }\n```\n\n#### verpat\n\nMatches a package version name against a regular expression.\nThe whole version is matched. Note that you need to escape periods,\nwhich mean \"any symbol\" in regular expressions. Matching is case-insensitive.\n\n```yaml\n- { name: firefox, verpat: \"50\\\\.[0-9]+\", ... }\n\n- { name: firefox, verpat: \"50\\\\..*\", ... }\n```\n\n#### vercomps\n\nMatches the number of components (dot-separated parts) of a version.\n\n```yaml\n- { name: gimp, vercomps: 3, ...} # matches 1.2.3, but not 1.2 or 1.2.3.4\n```\n\n#### verlonger\n\nMatches versions longer than a given number of components (dot-separated parts).\n\nMostly useful to match broken version schemes that add extra version components.\n\n```yaml\n- { name: gimp, verlonger: 3, ...} # 2.9.8.12345 is something unofficial\n```\n\n#### vergt, verge, verlt, verle, vereq, verne\n\nCompares version to a given one and matches if it is:\n\n- **vergt**: greater (\u003e)\n- **verge**: greater or equal (≥)\n- **verlt**: lesser (\u003c)\n- **verle**: lesser or equal (≤)\n- **vereq**: equal\n- **verne**: not equal\n\n```yaml\n# match git \u003e= 2.16\n- { name: git, verge: \"2.16\", ...}\n```\n\nBe careful when using this with regard to pre-release versions:\n`1.0beta1` is lesser than `1.0`, so it won't match `verge: 1.0`.\nYou may use **verpat** instead.\n\n#### relgt, relge, rellt, relle, releq, relne\n\nSimilar to the **verXX** family, but checks how a package version relates\nto a specified release. A release includes all pre-releases and\npost-releases with a given prefix; e.g. `releq: \"1.0\"` would match\n`1.0alpha1`, `1.0`, `1.0patch`, `1.0.1`, but not `0.99` and `1.1`.\n\n#### wwwpat\n\nMatches the package homepage against a regular expression. Note that\nunlike namepat and verpat, a partial match is allowed here.\nAlso note that dots should be escaped with double slash,\nas `.` means \"any character\" in regular expressions.\n\n```yaml\n- { name: firefox, wwwpat: \"mozilla\\\\.org\", ... }\n```\n\n#### wwwpart\n\nMatches when a package homepage contains given substring. This\nis usually more practical than **wwwpat** as in most cases you\njust need to match an URL part and don't need complex patterns,\nand you don't need to worry about escaping here. Matching is\ncase-insensitive.\n\n```yaml\n- { name: firefox, wwwpart: \"mozilla.org\", ... }\n```\n\n#### sourceforge\n\nMatches when a package homepage is a sourceforge page for a given\nproject name (`https://\u003cproject\u003e.sourceforge.net`,\n`https://sourceforge.net/project/\u003cproject\u003e` etc.):\n\n```yaml\n- { name: aterm, sourceforge: aterm, ... }\n```\n\n#### summpart\n\nMatches when a package summary contains a given substring. Useful\nas an alternative to **wwwpart** for cases where the package\nhomepage is not available. Matching is case-insensitive.\n\n```yaml\n- { name: firefox, summpart: \"browser\", ... }\n```\n\n#### is_p_is_patch\n\nMatches when a package has the `p_is_patch` flag set\n(see the [`p_is_patch`](#p_is_patch) action below).\n\n### Actions\n\n#### setname\n\nEffectively rename the package. You may use the `$0` placeholder to\nsubstitute original name, or `$1`, `$2` etc. to substitute the contents\nof the corresponding captures of the regular expression used in **namepat**.\nNote that you don't need to use neither **name** nor **namepat** for\n`$0` to work, but you must have **namepat** with corresponding\ncaptures to use `$1` and so on.\n\n```yaml\n# etracer→extreme-tuxracer\n- { name: etracer, setname: extreme-tuxracer }\n\n# aspell-dict-en→aspell-ru, aspell-dict-ru→aspell-ru etc.\n- { namepat: \"aspell-dict-(.*)\", setname: \"aspell-$1\" }\n\n# all packages in dev-perl Gentoo category are prepended `perl:`\n# Locale-Msgfmt→perl:Locale-Msgfmt\n- { ruleset: gentoo, category: dev-perl, setname: \"perl:$0\" }\n```\n\n#### setver\n\nChanges the version of the package. As with **setname**, you may\nuse the placeholders `$0`, `$1`, etc.\n\n```yaml\n# remove bogus leading version component\n- { verpat: \"0\\\\.(.*)\", setver: $1 }\n```\n\n#### remove\n\nSet to `true` to completely remove a package. It will not appear\nanywhere in Repology. Set to `false` to undo.\n\n```yaml\n# a metapackage which does not refer to any real project, we don't need it\n- { name: \"x11-fonts\", remove: true }\n```\n\n#### devel\n\nSet to `true` to mark the version of a matched package as a development or\nunstable version, so it does not make the latest stable version be marked\nas outdated. Set to `false` to undo.\n\n```yaml\n# mark versions with odd second component as devel\n- { name: gnome-terminal, verpat: \"[0-9]+\\\\.[0-9]*[13579]\\\\..*\", devel: true }\n```\n\n#### altver\n\nA project may use two parallel versioning schemes, one of which contains\nadditional version components, such as a build number:\n\n`0.17`, `0.17.13509`, `0.17.13541`, `0.18`, `0.18.16131`\n\nNormally, `0.18.16131` would be considered more recent than `0.18`,\nbut if these refer to the same version, this is not desired behavior.\nIn such case, a version scheme containing extra components\n(e.g. one which compares greater) may be marked as **altver**,\nwhich would allow both `0.18` and `0.18.16131` to be considered the latest,\nand both to be marked as outdated by the presence of either `0.19` or `0.19.x`.\n\n```yaml\n- { name: freecad, verlonger: 3, altver: true }\n```\n\n#### altscheme\n\nSimilar to **altver**, but for the case where versioning schemes\ndo not have a common prefix and are totally incompatible:\n\n`3.2.1`, `3207`, `3.2.2`, `3211`\n\nMarking either of the schemes with this flag results in completely independent processing,\nwhich would allow both `3.2.2` and `3211` to be treated as the newest version.\n\n```yaml\n- { name: sublime-text, verpat: \"[0-9]+\", altscheme: true }\n```\n\n#### ignore, incorrect, untrusted, noscheme, snapshot, successor, debianism, rolling\n\nSet to `true` to ignore specific package versions. This is meant for the\ncases where comparison is not possible - ignored versions are excluded from\ncomparison and do not affect the status of other versions. There are multiple\nignore flavors:\n\n- `rolling` - the package is always fetched from the latest snapshot or VCS\n  master/trunk. Its version has no meaning (like Gentoo's `9999`),\n  and may contain repository-specific formats such as a commit hash,\n  revision or date.\n- `noscheme` - there's no official versioning scheme. Repositories may\n  use random versions or dates, there's no point comparing them.\n- `incorrect` - known incorrect version (e.g. version which was not\n  released yet)\n- `untrusted` - used for repositories which are known for providing\n  incorrect versions, to ignore them proactively. It's a common pattern\n  to create a pair of `incorrect` rules matching specific versions, and an\n  `untrusted` rule for the following versions in a given repository.\n- `ignored` - general ignore action\n- `successor` - currently an alias for `devel`, used to convey the additional\n  meaning of this being a fork of an unmaintained original project\n- `debianism` - currently an alias for `devel`, used to convey the additional\n  meaning of this package using a distribution maintained at Debian (probably\n  with version addendum)\n- `snapshot` - currently alias for `ignored`\n\n```yaml\n# Fedora was known to use \"6.0.0\" version before it was actually released\n# mark as incorrect and prevent future problems\n- { name: llvm, ver: \"6.0.0\", ruleset: fedora, incorrect: true }\n- { name: llvm, ruleset: fedora, untrusted: true }\n```\n\n#### p_is_patch\n\nSet to `true` to indicate that this project uses `p` letter in the version\nto indicate post- or patch releases. This fixes version comparison, as\nby default `p` is treated as pre-release.\n\n```yaml\n# sudo 1.8.21p2 \u003e 1.8.21\n- { name: sudo, p_is_patch: true }\n```\n\n#### any_is_patch\n\nSet to `true` to indicate that this project uses any letter in the version\nto indicate post- releases.\n\n```yaml\n# rb here denotes a patchset, treat is as such\n- { name: webalizer, verpat: \".*rb.*\", any_is_patch: true }\n```\n\n#### sink\n\nSet to `true` to force the package version to compare lower than\nany other package version. Useful to handle upstream versioning\nschema change when new versions compare lower than legacy ones.\nSet to `false` to undo.\n\n```yaml\n# when 0.20 follows 0.193:\n- { version: \"0.193\", sink: true }\n```\n\nResult: `0.20 (newest)` \u003e `0.193 (outdated)`\n\n#### outdated\n\nSet to `true` to force the package to be outdated, even if it\nclassifies as the most recent. Note that this does not lead to\nanother version being selected as newest. Useful to convey that\na version is outdated even when there are no newer versions (for\ninstance, when a project is superceded by another project).\nSet to `false` to undo.\n\n```yaml\n# when 0.20 follows 0.193:\n- { version: \"0.193\", outdated: true }\n```\n\nResult: `0.193 (outdated)` \u003e `0.20 (outdated)`\n\n#### legacy\n\nSet to `true` to force the package to be legacy instead of outdated.\nSet to `false` to undo. Useful when a specific repository purposely contains\nan outdated version of a specific project for compatibility purposes.\n\n```yaml\n- { name: ruby-slack-notifier-1, ruleset: aur, legacy: true }\n```\n\n#### nolegacy\n\nSet to `true` to prevent the package from ever having legacy status.\nThis is useful for marking packages which declare to be of development\nversion, but are nevertheless outdated.\n\n```yaml\n- { name: ffmpeg-git, nolegacy: true }\n```\n\n#### warning\n\nOutput a given warning when matched.\n\n```yaml\n# will catch unexpected versions\n- { name: gtk, verpat: \"1\\\\..*\", setname: gtk1 }\n- { name: gtk, verpat: \"2\\\\..*\", setname: gtk2 }\n- { name: gtk, verpat: \"3\\\\..*\", setname: gtk3 }\n- { name: gtk, verpat: \"4\\\\..*\", setname: gtk4 }\n- { name: gtk, warning: \"Neither of gtk1,2,3,4 - need a new rule or some weirdness is going on\" }\n\n# will trigger a warning if new project called \"tesseract\" appears\n# ...or website changes, or just a package without website defined appears,\n# so it'll require another condition\n- { name: tesseract, setname: tesseract-game, wwwpart: tesseract.gg }\n- { name: tesseract, setname: tesseract-ocr, wwwpart: tesseract-ocr }\n- { name: tesseract, warning: \"Please add rule for tesseract\" }\n```\n\n#### addflavor\n\nFlavors are used to distinguish a set of packages denoting multiple\nversions of a project and a set of packages denoting a multiple parts\nor variants of a project. Consider an example:\n\n- `foo1 1.0` and `foo2 2.0` merged into `foo`. In this case they denote\n  multiple versions of the same project, flavors are not needed here\n  and `foo1` will have `legacy` status.\n- `foo-client 1.0` and `foo-server 1.1` merged into `foo`. In this case\n  they denote parts of the same project, which are expected to be of\n  the same version. Flavors should be used in this case, so `foo-client`\n  will have the `outdated` status.\n\nFlavors are plain strings and may be arbitrary, for example `client`\nand `server` in the last example. You may specify a flavor explicitly,\nor use the `true` value to make the flavor be taken from the package name.\n\n```yaml\n- { name: postgresql-client, setname: postgresql, addflavor: client }\n- { name: postgresql-server, setname: postgresql, addflavor: server }\n\n# This works too\n- { name: [postgresql-client, postgresql-server], setname: postgresql, addflavor: true }\n```\n\n#### setflavor\n\nSame as addflavor, but replaces flavor instead to appending to\nflavors list.\n\n#### resetflavors\n\nSet to `true` to remove all previously added flavors.\n\n#### last\n\nSet to `true` to stop ruleset processing right after the current rule.\n\nConsider this a legacy feature; it should not be needed.\n\n#### replaceinname\n\nTakes a pattern and replacement strings, and applies them to the package\nname. Used for low-level normalization.\n\n```yaml\n# slashes in package names are not allowed\n- { replaceinname: { \"/\": \"-\" } }\n\n# also useful for some repositories\n- { replaceinname: { \" \": \"-\" } }\n```\n\n#### tolowername\n\nConverts a package name to lowercase. This is called once in the\nvery beginning of the ruleset. The purpose of having this as a rule\naction is to be able to have exceptions, e.g. packages which should\nbe distinguished solely by the case of their names.\n\n```yaml\n- { tolowername: true }\n```\n\n#### setsubrepo\n\nChanges the subrepo property of the package. As with **setname**,\nyou may use the placeholders `$0`, `$1`, etc.\n\n```yaml\n# split subrepo name from package name\n- { namepat: \"([^-]+)-(.*)\", setsubrepo: $1, setname: $2 }\n```\n\n### Conditional rules\n\nFor additional flexibility, a mechanism exists to toggle some rules\nbased on the previous rules.\n\n#### addflag\n\nSets a virtual flag (arbitrary string) which only exists for the duration\nof rule processing, and may be checked in the following rules.\n\n```yaml\n- { name: python, addflag: not_python_module }\n```\n\n#### flag, noflag\n\nOnly matches if the specified flag is (or is not) set.\n\n```yaml\n- { name: python, addflag: not_python_module }\n...\n# will add \"python:\" prefix to all packages in category \"python\",\n# but not for \"python\" package\n- { category: python, noflag: not_python_module, setname: \"python:$0\" }\n```\n\n### Annotations\n\nThese annotations do not affect package processing, but are related\nto ruleset maintenance.\n\n#### maintenance\n\nIndicates that a rule needs manual maintenance. For example, when\na development version cannot be determined from the version schema,\none would need to revisit and update the version occasionally.\n\n```yaml\n- { name: tor, verge: \"0.3.4\", devel: true, maintenance: true }\n```\n\n#### precious\n\nIndicates that a rule should not be removed even if it doesn't\nmatch any packages. That is, a rule is likely to be useful sometime\nin the future.\n\n#### disposable\n\nIndicates that a rule may be removed if it doesn't match any packages.\n\n## Author\n\n- [Dmitry Marakasov](https://github.com/AMDmi3) \u003camdmi3@amdmi3.ru\u003e\n\n## License\n\nGPLv3 or later, see [COPYING](COPYING).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepology%2Frepology-rules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frepology%2Frepology-rules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepology%2Frepology-rules/lists"}