summaryrefslogtreecommitdiff
path: root/docs/archive/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/archive/index.html')
-rw-r--r--docs/archive/index.html1109
1 files changed, 1109 insertions, 0 deletions
diff --git a/docs/archive/index.html b/docs/archive/index.html
new file mode 100644
index 0000000..1345207
--- /dev/null
+++ b/docs/archive/index.html
@@ -0,0 +1,1109 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="generator" content="Docutils 0.22.4: https://docutils.sourceforge.io/">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta content="nixtamal, nix, nixos, reproducible builds, dependency pinning, source pinning, input pinning, dependency locking, dependency management, hermetic builds, build determinism, hash-based dependencies, functional package management, declarative builds, infrastructure as code, dev environment reproducibility, keep fetched dependency, darcs, pijul, fossil, blake3" name="keywords">
+ <meta content="Automate hashing and pinning of Nix source inputs with a declarative KDL manifest. Flake-compatible but not flake-bound, replacing or augmenting flake inputs with VCS-agnostic fetchers, mirrors, freshness commands, and BLAKE3." name="description">
+ <meta name="author" content="toastal">
+ <meta content="" name="robots">
+ <title>
+ Nixtamal | Nixtamal
+ </title>
+ <meta name="generator" content="soupault">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <meta http-equiv="X-XSS-Protection" content="1;mode=block">
+ <meta http-equiv="X-Content-Type-Options" content="nosniff">
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self';">
+ <meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
+ <meta name="theme" content="crimson">
+ <link rel="icon" type="image/svg+xml" href="/asset/_hashed/nixtamal/image/nixtamal-logo-gmxzsw8388sf9paq05xws7an4hnl4nx0.svg">
+ <link rel="stylesheet" href="/asset/_hashed/nixtamal/style/font-j47xx20z5d89qpsl95nnbipkg6d25m6y.css">
+ <link rel="stylesheet" href="/asset/_hashed/sugilite256/chroma-light-yfrfnk1zyqm9dc67gaa5y67s0a6x40ji.css">
+ <link rel="stylesheet" href="/asset/_hashed/sugilite256/chroma-dark-s4ssx3zwz2w418zx7pkrqlwqmywgvahl.css" media="(prefers-color-scheme: dark)">
+ <link rel="stylesheet" href="/asset/_hashed/nixtamal/style/main-lmdn1rci18371fnrcqrwga636ip08irz.css">
+ <link rel="author" href="/humans.txt">
+ </head>
+ <body class="with-toc">
+ <div id="DocWrapper" class="DocWrapper">
+ <div class="Banner-wrapper">
+ <header id="Banner" class="Banner">
+ <pre role="none" class="Banner-flair">┏┓╻+╻ ╱┏┳┓┏┓┏┳┓┏┓╻
+┃┃┃┃┗━┓╹┃╹┣┫┃┃┃┣┫┃
+╹┗┛╹╱ ╹ ╹ ╹╹╹ ╹╹╹┗┛</pre>
+ <a href="/" class="SiteLogo" title="Home">
+ <svg viewbox="0 0 79.375 27.099415" class="SiteLogo-image" role="img" aria-labelledby="SiteLogo-desc">
+ <use href="/asset/_hashed/nixtamal/image/nixtamal-logo-gmxzsw8388sf9paq05xws7an4hnl4nx0.svg#logo">
+ <desc id="SiteLogo-desc">
+ Home
+ </desc>
+ </use>
+ </svg>
+ </a>
+ <nav id="Navigation" class="Banner-navigation Navigation Navigation--banner" aria-expanded="true">
+ <a class="Navigation-item" href="/install/">Install</a>
+ <a class="Navigation-item" href="/manpage/">Manpage</a>
+ <a class="Navigation-item" href="/changelog/">Changelog</a>
+ <a class="Navigation-item" href="/roadmap/">Roadmap</a>
+ <a class="Navigation-item" href="/cookbook/">Cookbook</a>
+ <a class="Navigation-item" href="/real-world-showcase/">Real-world showcase</a>
+
+ <a class="Navigation-item" href="/community/">Community</a>
+ <a class="Navigation-item" href="/faqs/"><abbr title="frequently asked questions">FAQs</abbr></a>
+ <a class="Navigation-item" href="/funding/">Funding</a>
+ </nav>
+ </header>
+ <hr class="Banner-separator">
+ </div>
+ <main id="Main" class="Main">
+ <article id="Article" class="Article Stack">
+ <header class="Headline Article-headline">
+ <h1 itemprop="headline" class="title">
+ Nixtamal
+ </h1>
+ <p itemprop="alternativeHeadline" class="subtitle" id="fulfilling-input-pinning-for-nix-pinning-in-ways-flakes-never-can">
+ Fulfilling input pinning for Nix — pinning in ways flakes never can
+ </p>
+ </header>
+ <section itemprop="articleBody" id="Content" class="Content Article-body">
+ <nav class="contents" id="table-of-contents" role="doc-toc">
+ <p class="topic-title">
+ <a class="reference internal" href="#top">Table of Contents</a>
+ </p>
+ <ul class="simple">
+ <li>
+ <p>
+ <a class="reference internal" href="#keys-features" id="toc-entry-1">Keys features</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ <a class="reference internal" href="#showcase" id="toc-entry-2">Showcase</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ <a class="reference internal" href="#comparison" id="toc-entry-3">Comparison</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ <a class="reference internal" href="#design-constraints" id="toc-entry-4">Design constraints</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ <a class="reference internal" href="#technical-choices" id="toc-entry-5">Technical choices</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ <a class="reference internal" href="#ready-to-try-install" id="toc-entry-6">Ready to try &amp; install?</a>
+ </p>
+ </li>
+ </ul>
+ </nav>
+ <section id="keys-features">
+ <h2>
+ <a class="toc-backref" href="#toc-entry-1" role="doc-backlink">Keys features</a>
+ </h2>
+ <ul class="simple">
+ <li>
+ <p>
+ Automate the manual work of input pinning for dependency management
+ </p>
+ </li>
+ <li>
+ <p>
+ Allow easy ways to lock &amp; refresh those inputs
+ </p>
+ </li>
+ <li>
+ <p>
+ Declarative <abbr title="KDL Document language">KDL</abbr> manifest file over imperative <abbr title="command-line interface">CLI</abbr> flags
+ </p>
+ </li>
+ <li>
+ <p>
+ diff/grep-friendly lockfile
+ </p>
+ </li>
+ <li>
+ <p>
+ Host, forge, <abbr title="version control system">VCS</abbr>-agnostic
+ </p>
+ </li>
+ <li>
+ <p>
+ Choose eval time fetchers (builtins) or build time fetchers (Nixpkgs, default) — which opens up fetching now-supported <a class="reference external" href="https://darcs.net">Darcs</a>, <a class="reference external" href="https://pijul.org">Pijul</a>, &amp; <a class="reference external" href="https://fossil-scm.org">Fossil</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Supports mirrors
+ </p>
+ </li>
+ <li>
+ <p>
+ Override hash algorithm on a per-project &amp; per-input basis — including BLAKE3 support<a class="superscript" href="#footnote-1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>*<span class="fn-bracket">]</span></a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Custom freshness commands
+ </p>
+ </li>
+ <li>
+ <p>
+ No experimental Nix features required
+ </p>
+ </li>
+ </ul>
+ <aside class="footnote-list superscript">
+ <aside class="footnote superscript" id="footnote-1" role="doc-footnote">
+ <span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#footnote-reference-1">*</a><span class="fn-bracket">]</span></span>
+ <p>
+ Opting in requires enabling <code>blake3-hashes</code> <a class="reference external" href="https://nix.dev/manual/nix/2.31/development/experimental-features.html#xp-feature-blake3-hashes">experimental feature</a> which requires Nix 2.31+.
+ </p>
+ </aside>
+ </aside>
+ </section>
+ <section id="showcase">
+ <h2>
+ <a class="toc-backref" href="#toc-entry-2" role="doc-backlink">Showcase</a>
+ </h2>
+ <section id="set-up">
+ <h3>
+ Set up
+ </h3>
+ <pre class="code console literal-block"></pre>
+ </section>
+ <section id="tweak-the-manifest-with-your-editor">
+ <h3>
+ Tweak the manifest with your $EDITOR
+ </h3>
+ <pre class="code kdl literal-block"><span class="nl">version</span><span class="w"> </span><span class="s">"1.0.0"</span><span class="w">
+</span><span class="c1">// By default in this project, use experimental BLAKE3 algorithm for
+</span><span class="c1">// quicker, safer hashing
+</span><span class="nl">default-hash-algorithm</span><span class="w"> </span><span class="s">BLAKE3</span><span class="w">
+</span><span class="c1">// Define &amp; even reuse patches
+</span><span class="nl">patches</span><span class="w"> </span><span class="o">{</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Unique name for referencing in manifest inputs
+</span><span class="nl"> chroma-0.22.0</span><span class="w"> </span><span class="s">"https://patch-diff.githubusercontent.com/raw/NixOS/nixpkgs/pull/478519.patch"</span><span class="w"> </span><span class="o">{</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Override the project default hash algorithm
+</span><span class="nl"> hash</span><span class="w"> </span><span class="na">algorithm=</span><span class="s">SHA-512</span><span class="w"> </span><span class="na">expected=</span><span class="s">"1mdsfx204bgia572fydnmjy78dkybbcnjx20qn9l4q65r29ry28c"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="o">}</span><span class="w">
+</span><span class="c1">// Define inputs
+</span><span class="nl">inputs</span><span class="w"> </span><span class="o">{</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Unique name for referencing in Nix
+</span><span class="nl"> nixpkgs</span><span class="w"> </span><span class="o">{</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Fetch an archive with string templating support
+</span><span class="nl"> archive</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> url</span><span class="w"> </span><span class="s">"https://github.com/NixOS/nixpkgs/archive/{{fresh_value}}.tar.gz"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="nl"> hash</span><span class="w"> </span><span class="na">algorithm=</span><span class="s">SHA-256</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Apply patches to the source now while awaiting review
+</span><span class="nl"> patches</span><span class="w"> </span><span class="s">chroma-0.22.0</span><span class="w">
+</span><span class="w"> </span><span class="c1">// cURL an Atom feed for updates, stat a directory, whatever you
+</span><span class="w"> </span><span class="c1">// need so long as it returns a string, you can use it!
+</span><span class="w"> </span><span class="c1">// This also means you can prevent downloading massive files by
+</span><span class="w"> </span><span class="c1">// deciding yourself what “fresh” means to you.
+</span><span class="nl"> fresh-cmd</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> $</span><span class="w"> </span><span class="s">git</span><span class="w"> </span><span class="s">ls-remote</span><span class="w"> </span><span class="s">--branches</span><span class="w"> </span><span class="s">"https://github.com/NixOS/nixpkgs.git"</span><span class="w"> </span><span class="s">--refs</span><span class="w"> </span><span class="s">nixpkgs-unstable</span><span class="w">
+</span><span class="nl"> |</span><span class="w"> </span><span class="s">cut</span><span class="w"> </span><span class="s">-f1</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="nl"> nixtamal</span><span class="w"> </span><span class="o">{</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Use VCSs not supported by `builtins`
+</span><span class="nl"> darcs</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> repository</span><span class="w"> </span><span class="s">"https://darcs.toastal.in.th/nixtamal/stable"</span><span class="w">
+</span><span class="w"> </span><span class="c1">// fallback to mirrors when a host is down
+</span><span class="nl"> mirrors</span><span class="w"> </span><span class="s">"https://smeder.ee/~toastal/nixtamal.darcs"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="nl"> fresh-cmd</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> $</span><span class="w"> </span><span class="s">curl</span><span class="w"> </span><span class="s">-sL</span><span class="w"> </span><span class="s">"https://darcs.toastal.in.th/nixtamal/stable/_darcs/weak_hash"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Even static JSON files can be inputs
+</span><span class="nl"> mozilla-tls</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> file</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> url</span><span class="w"> </span><span class="s">"https://ssl-config.mozilla.org/guidelines/{{fresh_value}}.json"</span><span class="w">
+</span><span class="nl"> mirrors</span><span class="w"> </span><span class="s">"https://raw.githubusercontent.com/mozilla/ssl-config-generator/refs/tags/v{{fresh_value}}/src/static/guidelines/{{fresh_value}}.json"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Scrape a webpage for the latest version
+</span><span class="nl"> fresh-cmd</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> $</span><span class="w"> </span><span class="s">curl</span><span class="w"> </span><span class="s">-sL</span><span class="w"> </span><span class="s">"https://wiki.mozilla.org/Security/Server_Side_TLS"</span><span class="w">
+</span><span class="nl"> |</span><span class="w"> </span><span class="s">htmlq</span><span class="w"> </span><span class="s">-t</span><span class="w"> </span><span class="s">"table.wikitable:last-of-type &gt; tbody &gt; tr:nth-child(2) &gt; td:first-child"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="c1">// Download &amp; pin a model from Hugging Face, then can be used like with
+</span><span class="w"> </span><span class="c1">// `specialArgs = { inherit inputs; }`:
+</span><span class="w"> </span><span class="c1">//
+</span><span class="w"> </span><span class="c1">// services.llama-cpp = {
+</span><span class="w"> </span><span class="c1">// enable = true;
+</span><span class="w"> </span><span class="c1">// model = "${inputs.Qwen2_5-Coder-7B-Instruct}";
+</span><span class="w"> </span><span class="c1">// }
+</span><span class="nl"> Qwen2_5-Coder-7B-Instruct</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> file</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> url</span><span class="w"> </span><span class="s">"https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/resolve/{{fresh_value}}/qwen2.5-coder-7b-instruct-q5_k_m.gguf"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="nl"> fresh-cmd</span><span class="w"> </span><span class="o">{</span><span class="nl">
+</span><span class="nl"> $</span><span class="w"> </span><span class="s">curl</span><span class="w"> </span><span class="s">-fsL</span><span class="w"> </span><span class="s">"https://huggingface.co/api/models/Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/commits/main?path=qwen2.5-coder-7b-instruct-q5_k_m.gguf"</span><span class="w">
+</span><span class="nl"> |</span><span class="w"> </span><span class="s">jq</span><span class="w"> </span><span class="s">-r</span><span class="w"> </span><span class="s">".[0].id"</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="w"> </span><span class="o">}</span><span class="w">
+</span><span class="o">}</span></pre>
+ </section>
+ <section id="lock-or-refresh-your-new-inputs">
+ <h3>
+ Lock or refresh your new inputs
+ </h3>
+ <pre class="code console literal-block"></pre>
+ </section>
+ <section id="using-in-a-project">
+ <h3>
+ Using in a project
+ </h3>
+ <pre class="code nix literal-block"><span class="k">let</span>
+ <span class="c1"># Import the inputs attrset from the $NIXTAMAL_DIRECTORY (default:</span>
+ <span class="c1"># nix/tamal), which takes a configuration attrset:</span>
+ <span class="c1">#</span>
+ <span class="c1"># {</span>
+ <span class="c1"># system ? builtins.currentSystem,</span>
+ <span class="c1"># nixpkgs ? null,</span>
+ <span class="c1"># bootstrap-nixpkgs-lock-namee ? null,</span>
+ <span class="c1"># }:</span>
+ <span class="c1">#</span>
+ <span class="c1"># system : string</span>
+ <span class="c1"># The system architecture (useful for pure evaluation)</span>
+ <span class="c1"># bootstrap-nixpkgs : derivation</span>
+ <span class="c1"># A Nixpkgs source for bootstrapping. This is useful if using Nixtamal</span>
+ <span class="c1"># from inside another another pinning tool, OR, if you are willing to</span>
+ <span class="c1"># trade off a bit of purity at the fetcher level for better performance</span>
+ <span class="c1"># / saving data, you can pass { bootstrap-nixpkgs = ≮nixpkgs≯; } from the</span>
+ <span class="c1"># host system as the system’s Nixpkgs fetchers are likely stable enough</span>
+ <span class="c1"># for your bootstrapping needs (&amp; we feature check some of the API).</span>
+ <span class="c1"># bootstrap-nixpkgs-lock-name : string</span>
+ <span class="c1"># Key name from inputs to use as the bootstrapping Nixpkgs if you</span>
+ <span class="c1"># want/need inputs.nixpkgs to point to something else.</span>
+ <span class="n">inputs</span> <span class="o">=</span> <span class="kn">import</span> <span class="sr">./nix/tamal</span> <span class="p">{</span> <span class="p">};</span>
+
+ <span class="n">pkgs</span> <span class="o">=</span> <span class="kn">import</span> <span class="n">inputs</span><span class="o">.</span><span class="n">nixpkgs</span> <span class="p">{</span>
+ <span class="n">overlay</span> <span class="o">=</span> <span class="p">[</span>
+ <span class="c1"># exposes the “dag-yo” package</span>
+ <span class="p">(</span><span class="kn">import</span> <span class="s2">"</span><span class="si">${</span><span class="n">inputs</span><span class="o">.</span><span class="n">my-cool-package</span><span class="si">}</span><span class="s2">/nix/overlay"</span><span class="p">)</span>
+ <span class="p">];</span>
+ <span class="p">};</span>
+<span class="k">in</span>
+<span class="n">pkgs</span><span class="o">.</span><span class="n">dag-yo</span> <span class="c1"># punted‼</span></pre>
+ </section>
+ </section>
+ <section id="comparison">
+ <h2>
+ <a class="toc-backref" href="#toc-entry-3" role="doc-backlink">Comparison</a>
+ </h2>
+ <div class="table-wrapper docutils container">
+ <table class="comparison">
+ <caption>
+ Nix pinning tool comparisons
+ </caption>
+ <thead>
+ <tr>
+ <th class="head">
+ <p>
+ Pinning tool
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ Nixtamal
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ Nix channels
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ Nix flakes
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ npins
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ niv
+ </p>
+ </th>
+ <th class="head">
+ <p>
+ Yae
+ </p>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ Same state per machine
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="somewhat">
+ only if manually pinning
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Per-project support
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Versioned schemas
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="doesn’t-apply">
+ –
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Requires experimental Nix features
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="bad">
+ yes
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Splits lockfile vs. manifest duties
+ </td>
+ <td class="good">
+ yes (manifest.kdl)
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="good">
+ yes (flake.nix)
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Requires Nixpkgs
+ </td>
+ <td class="somewhat">
+ used for bootstrapping &amp; some features require it, but possible with <code>fetch-time=eval</code>
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch <abbr title="Concurrent Versions System">CVS</abbr>
+ </td>
+ <td class="bad">
+ no<a class="superscript" href="#footnote-3" id="footnote-reference-2" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a>
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch <abbr title="Darcs Advanced Revision Control System">Darcs</abbr>
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch Fossil
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch Git
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch <abbr title="GNU’s not Unix!">GNU</abbr> Bazaar
+ </td>
+ <td class="bad">
+ no<a class="superscript" href="#footnote-2" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch Mercurial
+ </td>
+ <td class="bad">
+ no<a class="superscript" href="#footnote-3" id="footnote-reference-4" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a>
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch Pijul
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch Subversion
+ </td>
+ <td class="bad">
+ no<a class="superscript" href="#footnote-3" id="footnote-reference-5" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a>
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch torrent
+ </td>
+ <td class="bad">
+ no<a class="superscript" href="#footnote-2" id="footnote-reference-6" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Fetch <abbr title="uniform resource locator">URL</abbr>s
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td class="good">
+ yes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ User-written freshness logic
+ </td>
+ <td class="good">
+ fresh-cmd
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Version constraints
+ </td>
+ <td class="somewhat">
+ Gate with <code>fresh-cmd</code> or Jingoo templating (<abbr title="do it yourself">DIY</abbr>)
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="somewhat">
+ Semver on some input kinds
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="somewhat">
+ Git tag predicate
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Configure hash algorithm
+ </td>
+ <td class="good">
+ yes, per-project + per-input &amp; BLAKE3 support
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Mirror support
+ </td>
+ <td class="good">
+ yes, on supported kinds
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="bad">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Patch support
+ </td>
+ <td class="good">
+ yes, declarative
+ </td>
+ <td class="bad">
+ no
+ </td>
+ <td class="somewhat">
+ must apply manually or pull in a dependency to handle
+ </td>
+ <td class="somewhat">
+ must apply manually
+ </td>
+ <td class="somewhat">
+ must apply manually
+ </td>
+ <td class="somewhat">
+ must apply manually
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Forge-specific <abbr title="uniform resource locator">URL</abbr> schemes or semantics
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="good">
+ no
+ </td>
+ <td class="bad">
+ yes
+ </td>
+ <td class="bad">
+ yes
+ </td>
+ <td class="bad">
+ yes, &amp; defaults to proprietary <abbr title="Microsoft">MS</abbr> GitHub
+ </td>
+ <td class="good">
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Freeze inputs for convenience
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td>
+ no
+ </td>
+ <td>
+ no
+ </td>
+ <td class="good">
+ yes
+ </td>
+ <td>
+ no
+ </td>
+ <td>
+ no
+ </td>
+ </tr>
+ <tr>
+ <td>