731 lines
52 KiB
HTML
731 lines
52 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||
<head>
|
||
<!-- Book generated using mdBook -->
|
||
<meta charset="UTF-8">
|
||
<title>The Rustup developer guide</title>
|
||
<meta name="robots" content="noindex">
|
||
|
||
|
||
<!-- Custom HTML head -->
|
||
|
||
<meta name="description" content="">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#ffffff">
|
||
|
||
<link rel="icon" href="favicon-de23e50b.svg">
|
||
<link rel="shortcut icon" href="favicon-8114d1fc.png">
|
||
<link rel="stylesheet" href="css/variables-8adf115d.css">
|
||
<link rel="stylesheet" href="css/general-2459343d.css">
|
||
<link rel="stylesheet" href="css/chrome-ae938929.css">
|
||
<link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
|
||
|
||
<!-- Fonts -->
|
||
<link rel="stylesheet" href="fonts/fonts-9644e21d.css">
|
||
|
||
<!-- Highlight.js Stylesheets -->
|
||
<link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css">
|
||
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css">
|
||
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.css">
|
||
|
||
<!-- Custom theme stylesheets -->
|
||
|
||
|
||
<!-- Provide site root and default themes to javascript -->
|
||
<script>
|
||
const path_to_root = "";
|
||
const default_light_theme = "light";
|
||
const default_dark_theme = "navy";
|
||
window.path_to_searchindex_js = "searchindex-ee054dd1.js";
|
||
</script>
|
||
<!-- Start loading toc.js asap -->
|
||
<script src="toc-e709a72b.js"></script>
|
||
</head>
|
||
<body>
|
||
<div id="mdbook-help-container">
|
||
<div id="mdbook-help-popup">
|
||
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
|
||
<div>
|
||
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
|
||
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
|
||
<p>Press <kbd>?</kbd> to show this help</p>
|
||
<p>Press <kbd>Esc</kbd> to hide this help</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="mdbook-body-container">
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script>
|
||
try {
|
||
let theme = localStorage.getItem('mdbook-theme');
|
||
let sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script>
|
||
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
||
let theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
const html = document.documentElement;
|
||
html.classList.remove('light')
|
||
html.classList.add(theme);
|
||
html.classList.add("js");
|
||
</script>
|
||
|
||
<input type="checkbox" id="mdbook-sidebar-toggle-anchor" class="hidden">
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script>
|
||
let sidebar = null;
|
||
const sidebar_toggle = document.getElementById("mdbook-sidebar-toggle-anchor");
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
} else {
|
||
sidebar = 'hidden';
|
||
sidebar_toggle.checked = false;
|
||
}
|
||
if (sidebar === 'visible') {
|
||
sidebar_toggle.checked = true;
|
||
} else {
|
||
html.classList.remove('sidebar-visible');
|
||
}
|
||
</script>
|
||
|
||
<nav id="mdbook-sidebar" class="sidebar" aria-label="Table of contents">
|
||
<!-- populated by js -->
|
||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||
<noscript>
|
||
<iframe class="sidebar-iframe-outer" src="toc.html"></iframe>
|
||
</noscript>
|
||
<div id="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
|
||
<div class="sidebar-resize-indicator"></div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div id="mdbook-page-wrapper" class="page-wrapper">
|
||
|
||
<div class="page">
|
||
<div id="mdbook-menu-bar-hover-placeholder"></div>
|
||
<div id="mdbook-menu-bar" class="menu-bar sticky">
|
||
<div class="left-buttons">
|
||
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
|
||
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span>
|
||
</label>
|
||
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
|
||
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span>
|
||
</button>
|
||
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
|
||
</ul>
|
||
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
|
||
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span>
|
||
</button>
|
||
</div>
|
||
|
||
<h1 class="menu-title">The Rustup developer guide</h1>
|
||
|
||
<div class="right-buttons">
|
||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span>
|
||
</a>
|
||
<a href="https://github.com/rust-lang/rustup/tree/HEAD/doc/dev-guide" title="Git repository" aria-label="Git repository">
|
||
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></span>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div id="mdbook-search-wrapper" class="hidden">
|
||
<form id="mdbook-searchbar-outer" class="searchbar-outer">
|
||
<div class="search-wrapper">
|
||
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
|
||
<div class="spinner-wrapper">
|
||
<span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
|
||
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
|
||
<ul id="mdbook-searchresults">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
<script>
|
||
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
|
||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
});
|
||
</script>
|
||
|
||
<div id="mdbook-content" class="content">
|
||
<main>
|
||
<h1 id="contributing-to-rustup"><a class="header" href="#contributing-to-rustup">Contributing to rustup</a></h1>
|
||
<ol>
|
||
<li>Fork it!</li>
|
||
<li>Create your feature branch: <code>git checkout -b my-new-feature</code></li>
|
||
<li>Test it: <code>cargo test --features=test</code></li>
|
||
<li><a href="#linting">Lint it!</a></li>
|
||
<li>Commit your changes: <code>git commit -am 'Add some feature'</code></li>
|
||
<li>Push to the branch: <code>git push origin my-new-feature</code></li>
|
||
<li>Submit a pull request :D</li>
|
||
</ol>
|
||
<p>For developing on <code>rustup</code> itself, the easiest way is to run the development
|
||
build on your current installation. This approach is best used for minor fixes
|
||
or improvements. See the documentation for <a href="#rustup_force_arg0"><code>RUSTUP_FORCE_ARG0</code></a> for more info.</p>
|
||
<p>A more formal solution involves installing rustup into a temporary directory as
|
||
your dedicated test environment.
|
||
To do so, you can run a series of commands similar to this:</p>
|
||
<pre><code class="language-bash">cargo build
|
||
mkdir home
|
||
RUSTUP_HOME=home CARGO_HOME=home target/debug/rustup-init --no-modify-path -y
|
||
</code></pre>
|
||
<p>You can then try out <code>rustup</code> with your changes by running <code>home/bin/rustup</code>, without
|
||
affecting any existing installation. Remember to keep those two environment variables
|
||
set when running your compiled <code>rustup-init</code> or the toolchains it installs, but <em>unset</em>
|
||
when rebuilding <code>rustup</code> itself.</p>
|
||
<p>If you wish to install your new build to try out longer term in your home directory
|
||
then you can run <code>cargo dev-install</code> which is an alias in <code>.cargo/config</code> which
|
||
runs <code>cargo run -- --no-modify-path -y</code> to install your build into your homedir.</p>
|
||
<p>We use <code>rustfmt</code> to keep our codebase consistently formatted. Please ensure that
|
||
you have correctly formatted your code (most editors will do this automatically
|
||
when saving) or it may not pass the CI tests.</p>
|
||
<p>If you are moving, renaming or removing an existing mdBook page, please use mdBook’s
|
||
<a href="https://rust-lang.github.io/mdBook/format/configuration/renderers.html#outputhtmlredirect"><code>output.html.redirect</code></a> feature to ensure that the old URL gets redirected.</p>
|
||
<p>Unless you explicitly state otherwise, any contribution intentionally
|
||
submitted for inclusion in the work by you, as defined in the
|
||
Apache-2.0 license, shall be dual licensed as in the README, without any
|
||
additional terms or conditions.</p>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="linting"><a class="header" href="#linting">Linting</a></h1>
|
||
<p>We use <code>cargo clippy</code> to ensure high-quality code and to enforce a set of best practices for Rust programming.
|
||
However, not all lints provided by <code>cargo clippy</code> are relevant or applicable to our project.
|
||
We may choose to ignore some lints if they are unstable, experimental, or specific to our project.
|
||
If you are unsure about a lint, please ask us in the
|
||
<a href="https://rust-lang.zulipchat.com/#narrow/channel/490103-t-rustup">rustup Zulip channel</a>.</p>
|
||
<h2 id="manual-linting"><a class="header" href="#manual-linting">Manual linting</a></h2>
|
||
<p>When checking the codebase with <a href="https://doc.rust-lang.org/stable/clippy/index.html"><code>clippy</code></a>,
|
||
it is recommended to use the following command:</p>
|
||
<pre><code class="language-console">$ cargo clippy --all --all-targets --all-features -- -D warnings
|
||
</code></pre>
|
||
<p>Please note the <code>--all-features</code> flag: it is used because we need to enable the <code>test</code> feature
|
||
to make lints fully work, for which <code>--all-features</code> happens to be a convenient shortcut.</p>
|
||
<p>The <code>test</code> feature is required because <code>rustup</code> uses
|
||
<a href="https://doc.rust-lang.org/cargo/reference/features.html">cargo features</a> to
|
||
<a href="https://doc.rust-lang.org/reference/conditional-compilation.html">conditionally compile</a>
|
||
support code for integration tests, as <code>#[cfg(test)]</code> is only available for unit tests.</p>
|
||
<p>If you encounter an issue or wish to speed up the initial analysis, you could also try
|
||
activating only the <code>test</code> feature by replacing <code>--all-features</code> with <code>--features=test</code>.</p>
|
||
<h2 id="rust-analyzer"><a class="header" href="#rust-analyzer">Rust-Analyzer</a></h2>
|
||
<p>When checking the codebase using <code>rust-analyzer</code>, the first thing to do remains unchanged:
|
||
enabling the features.</p>
|
||
<p>This is done by setting the <code>rust-analyzer.cargo.features</code> property to <code>"all"</code>.</p>
|
||
<p>For example, if you are using <code>rust-analyzer</code> within VSCode, you would want to
|
||
add the following to your project’s <code>.vscode/settings.json</code><sup class="footnote-reference" id="fr-vscode-global-cfg-1"><a href="#footnote-vscode-global-cfg">1</a></sup>:</p>
|
||
<pre><code class="language-jsonc">"rust-analyzer.cargo.features": "all",
|
||
</code></pre>
|
||
<p>Alternatively, if you want to enable the <code>test</code> feature only, you should set the
|
||
following instead:</p>
|
||
<pre><code class="language-jsonc">"rust-analyzer.cargo.features": ["test"]
|
||
</code></pre>
|
||
<p>Next, as <code>rust-analyzer</code> depends on <code>cargo check</code> by default, it is also recommended to
|
||
enable the <code>cargo clippy</code> integration by adding the following:</p>
|
||
<pre><code class="language-jsonc">"rust-analyzer.check.command": "clippy",
|
||
</code></pre>
|
||
<p>You might also want to refer to the
|
||
<a href="https://rust-analyzer.github.io/manual.html#configuration"><code>rust-analyzer</code> manual</a>
|
||
for more details on properly setting up <code>rust-analyzer</code> in your IDE of choice.</p>
|
||
<hr>
|
||
<ol class="footnote-definition">
|
||
<li id="footnote-vscode-global-cfg">
|
||
<p>Alternatively, if you want to apply the configuration to all your Rust projects,
|
||
you can add it to your global configuration at <code>~/.config/Code/User/settings.json</code> instead. <a href="#fr-vscode-global-cfg-1">↩</a></p>
|
||
</li>
|
||
</ol>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="coding-standards"><a class="header" href="#coding-standards">Coding standards</a></h1>
|
||
<p>Generally we just follow good sensible Rust practices, clippy and so forth.
|
||
However there are some practices we’ve agreed on that are not machine-enforced;
|
||
meeting those requirements in a PR will make it easier to merge.</p>
|
||
<h2 id="atomic-commits"><a class="header" href="#atomic-commits">Atomic commits</a></h2>
|
||
<p>We use atomic commits across the repo. Each commit should represent a single unit of change.
|
||
You can read more about atomic commits <a href="https://www.aleksandrhovhannisyan.com/blog/atomic-git-commits">here</a>.</p>
|
||
<h2 id="import-grouping"><a class="header" href="#import-grouping">Import grouping</a></h2>
|
||
<p>In each file the imports should be grouped into at most 4 groups in the
|
||
following order:</p>
|
||
<ol>
|
||
<li>stdlib</li>
|
||
<li>non-repository local crates</li>
|
||
<li>repository local other crates</li>
|
||
<li>this crate</li>
|
||
</ol>
|
||
<p>Separate each group with a blank line, and rustfmt will sort into a canonical
|
||
order. Any file that is not grouped like this can be rearranged whenever the
|
||
file is touched - we’re not precious about having it done in a separate commit,
|
||
though that is helpful.</p>
|
||
<h2 id="no-direct-use-of-process-state-outside-rustupprocess"><a class="header" href="#no-direct-use-of-process-state-outside-rustupprocess">No direct use of process state outside rustup::process</a></h2>
|
||
<p>The <code>rustup::process</code> module abstracts the global state that is
|
||
<code>std::env::args</code>, <code>std::env::vars</code>, <code>std::io::std*</code> and <code>std::env::current_dir</code>
|
||
permitting threaded tests of the CLI logic; use the relevant methods of the
|
||
<code>rustup::process::Process</code> type rather than those APIs directly.
|
||
Usually, a <code>process: &Process</code> variable will be available to you in the current context.
|
||
For example, it could be in the form of a parameter of the current function,
|
||
or a field of a <code>Cfg</code> instance, etc.</p>
|
||
<h2 id="writing-tests"><a class="header" href="#writing-tests">Writing tests</a></h2>
|
||
<p>Rustup provides a number of test helpers in the <code>rustup::test</code> module
|
||
which is conditionally enabled with the <code>test</code> feature.</p>
|
||
<p>The existing tests under <code>tests/suite</code> provide good examples of how to use these
|
||
helpers, but you might also find it useful to look at the documentation for
|
||
particular APIs in the <code>rustup::test</code> module.</p>
|
||
<p>For example, for more information regarding end-to-end tests with the <code>.expect()</code>
|
||
APIs, you can refer to the documentation of the <a href="https://github.com/search?q=repo%3Arust-lang%2Frustup+symbol%3A%2F%28%3F-i%29Assert%2F&type=code"><code>Assert</code></a> type.</p>
|
||
<h2 id="clippy-lints"><a class="header" href="#clippy-lints">Clippy lints</a></h2>
|
||
<p>At the time of writing, rustup’s CI pipeline runs clippy on both Windows and
|
||
Linux, but contributors to particularly OS-specific code should also make
|
||
sure that their clippy checking is done on that particular platform, as
|
||
OS-conditional code is a common source of unused imports and other small lints,
|
||
which can build up over time.</p>
|
||
<h2 id="writing-platform-specific-code"><a class="header" href="#writing-platform-specific-code">Writing platform-specific code</a></h2>
|
||
<p>For developers using BSD/Linux/Mac OS, there are Windows VM’s suitable for such
|
||
development tasks for use with virtualbox and other hypervisors are downloadable
|
||
from
|
||
<a href="https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/">Microsoft</a>.
|
||
Similarly, there are many Linux and Unix operating systems images available for
|
||
developers whose usual operating system is Windows. Currently Rustup has no Mac
|
||
OS specific code, so there should be no need to worry about Mac VM images.</p>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="version-numbers"><a class="header" href="#version-numbers">Version numbers</a></h1>
|
||
<p>If you ever see a released version of rustup which has <code>::</code> in its version string
|
||
then something went wrong with the CI and that needs to be addressed.</p>
|
||
<p>We use <code>git-testament</code> to construct our version strings. This records, as a
|
||
struct, details of the git commit, tag description, and also an indication
|
||
of modifications to the working tree present when the binary was compiled.</p>
|
||
<p>During normal development you may get information from invoking <code>rustup --version</code>
|
||
which looks like <code>rustup-init 1.18.3+15 (a54051502 2019-05-26)</code> or even
|
||
<code>rustup-init 1.18.3+15 (a54051502 2019-05-26) dirty 1 modification</code>.</p>
|
||
<p>The first part is always the binary name as per <code>clap</code>’s normal operation. The
|
||
version number is a combination of the most recent tag in the git repo, and the
|
||
number of commits since that tag. The parenthesised information is, naturally,
|
||
the SHA of the most recent commit and the date of that commit. If the indication
|
||
of a dirty tree is present, the number of changes is indicated. This combines
|
||
adds, deletes, modifies, and unknown entries.</p>
|
||
<p>You can request further information of a <code>rustup</code> binary with the
|
||
<code>rustup dump-testament</code> hidden command. It produces output of the form:</p>
|
||
<pre><code class="language-shell">$ rustup dump-testament
|
||
Rustup version renders as: 1.18.3+15 (a54051502 2019-05-26) dirty 1 modification
|
||
Current crate version: 1.18.3
|
||
Built from branch: kinnison/version-strings
|
||
Commit info: 1.18.3+15 (a54051502 2019-05-26)
|
||
Modified: CONTRIBUTING.md
|
||
</code></pre>
|
||
<p>This can be handy when you are testing development versions on your PC
|
||
and cannot remember exactly which version you had installed, or if you have given
|
||
a development copy (or instruction to build such) to a user, and wish to have them
|
||
confirm <em>exactly</em> what they are using.</p>
|
||
<p>Finally, we tell <code>git-testament</code> that we trust the <code>stable</code> branch to carry
|
||
releases. If the build is being performed when not on the <code>stable</code> branch, and
|
||
the tag and <code>CARGO_PKG_VERSION</code> differ, then the short version string will include
|
||
both, in the form <code>rustup-init 1.18.3 :: 1.18.2+99 (a54051502 2019-05-26)</code> which
|
||
indicates the crate version before the rest of the commit.
|
||
On the other hand, if the build was on the <code>stable</code> branch then regardless
|
||
of the tag information, providing the commit was clean, the version is
|
||
always replaced by the crate version. The <code>dump-testament</code> hidden command can
|
||
reveal the truth however.</p>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="making-a-release"><a class="header" href="#making-a-release">Making a release</a></h1>
|
||
<p>In rustup, there are two possible release “modes”: the beta release and the
|
||
official release. The main difference between the two is that they use
|
||
different values for the <code>RUSTUP_UPDATE_ROOT</code> environment variable:</p>
|
||
<ul>
|
||
<li>A beta release is deployed on <code>https://dev-static.rust-lang.org/rustup</code>.</li>
|
||
<li>An official release is deployed on <code>https://static.rust-lang.org/rustup</code>.</li>
|
||
</ul>
|
||
<p>By switching between those two values, rustup effectively provides two “self
|
||
update channels”, making beta testing possible with <code>rustup self update</code>.</p>
|
||
<p>Currently, rustup does one beta release followed by one official release for
|
||
each version number in the increasing order. In other words, we don’t release
|
||
any <code>1.28.x</code> once the <code>1.29.0</code> beta release is out, and the latter is followed
|
||
by the <code>1.29.0</code> stable release, and so on.</p>
|
||
<h2 id="bumping-the-version-number"><a class="header" href="#bumping-the-version-number">Bumping the version number</a></h2>
|
||
<p>The version number is registered in the <code>Cargo.toml</code> file of the project.</p>
|
||
<p>The general principle for version numbers is that we always increment the
|
||
<em>minor</em> number unless:</p>
|
||
<ul>
|
||
<li>A major incompatibility has been introduced in this release:
|
||
increment the <em>major</em> number instead.</li>
|
||
<li>This release is a hotfix because the last one had a defect:
|
||
increment the <em>patch</em> number instead.</li>
|
||
</ul>
|
||
<h3 id="minor-version-bumps"><a class="header" href="#minor-version-bumps">Minor version bumps</a></h3>
|
||
<blockquote>
|
||
<p>NOTE: Rustup hasn’t been doing major version bumps since a long time ago, but
|
||
if we ever do, the procedure for it should be similar to that of a minor one.</p>
|
||
</blockquote>
|
||
<p>A minor version bump should be performed immediately after the latest <code>X.Y.0</code>
|
||
(e.g. <code>1.29.0</code>) beta release, and to do so, the following steps should be
|
||
taken:</p>
|
||
<ul>
|
||
<li>In the <code>main</code> branch, note the current minor version number <code>X.Y</code> (e.g.
|
||
<code>1.29</code>) and create a new branch from <code>main</code> named <code>release/X.Y</code> (e.g.
|
||
<code>release/1.29</code>). This will be the active backport branch from now on.</li>
|
||
<li>In a separate PR targeting <code>main</code>:
|
||
<ul>
|
||
<li>Bump the minor version number in <code>Cargo.toml</code> (e.g. to <code>1.30.0</code>).</li>
|
||
<li>Run <code>cargo build</code> and review <code>Cargo.lock</code> changes.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="patch-version-bumps"><a class="header" href="#patch-version-bumps">Patch version bumps</a></h3>
|
||
<p>A patch version bump should be performed immediately after any latest release
|
||
other than <code>X.Y.0</code> betas if the backport branch <code>release/X.Y</code> is still
|
||
considered active (i.e. it is expected to cut new patch releases from the
|
||
branch):</p>
|
||
<ul>
|
||
<li>In a separate PR targeting that backport branch:
|
||
<ul>
|
||
<li>Bump the patch version number in <code>Cargo.toml</code> (e.g. to <code>1.29.1</code>).</li>
|
||
<li>Run <code>cargo build</code> and review <code>Cargo.lock</code> changes.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2 id="maintaining-the-backport-branch"><a class="header" href="#maintaining-the-backport-branch">Maintaining the backport branch</a></h2>
|
||
<p>When the backport branch <code>release/X.Y</code> is active, you are expected to backport
|
||
to it any relevant non-breaking changes one would like to see in new patch
|
||
releases. This includes, but is not limited to:</p>
|
||
<ul>
|
||
<li>Bug fixes.</li>
|
||
<li>Patch-compatible documentation improvements.</li>
|
||
<li>Minor features if they are not expected to cause any breakage.</li>
|
||
<li>CI adjustments if relevant to the active backport branch.</li>
|
||
</ul>
|
||
<p>The backport PRs should bear the <code>backport</code> label and target the active
|
||
backport branch in a rebased, commit-preserving manner.</p>
|
||
<p>It is OK to backport multiple original PRs at once as long as the conflict
|
||
resolution is straightforward (we would expect this to be the case for the most
|
||
part otherwise it would be against the point of patch releases in the first
|
||
place).</p>
|
||
<p>The backport branches already have similar CI setup like that of <code>main</code>, but
|
||
the full CI must be manually triggered rather than scheduled. To do so, you can
|
||
use the <a href="https://cli.github.com">GitHub CLI</a> under the project directory:</p>
|
||
<pre><code class="language-console">$ gh workflow run ci.yaml --ref release/X.Y
|
||
</code></pre>
|
||
<h2 id="cutting-a-new-release"><a class="header" href="#cutting-a-new-release">Cutting a new release</a></h2>
|
||
<p>Before making a release, ensure that <code>rustup-init.sh</code> is behaving correctly,
|
||
and that you’re satisfied that nothing in the ecosystem is breaking because
|
||
of the update. A useful set of things to check includes verifying that
|
||
real-world toolchains install okay, and that <code>rust-analyzer</code> isn’t broken by
|
||
the release. While it’s not our responsibility if they depend on non-stable
|
||
APIs, we should behave well if we can.</p>
|
||
<p>The next step is to check whether you are cutting a beta or an official release,
|
||
and determine which <code>$BRANCH</code> you should be working on:</p>
|
||
<ul>
|
||
<li><code>main</code> for <code>X.Y.0</code> beta releases.</li>
|
||
<li><code>release/X.Y</code> for any other <code>X.Y.*</code> release.</li>
|
||
</ul>
|
||
<p>Producing the final release artifacts is a bit involved because of the way
|
||
rustup is distributed. Below is a list of things to be done in order to cut a
|
||
new [b]eta release or an official [r]elease:</p>
|
||
<ol>
|
||
<li>[b/r] Make sure that the desired version number for the new release
|
||
<code>$VER_NUM</code> already exists in <code>$BRANCH</code>’s <code>Cargo.toml</code> file. Then in a new PR
|
||
targeting <code>$BRANCH</code>:
|
||
<ol>
|
||
<li>Update <code>CHANGELOG.md</code> accordingly if necessary.</li>
|
||
<li>Update <code>rustup-init.sh</code> so that:
|
||
<ul>
|
||
<li>The version number matches <code>$VER_NUM</code>.</li>
|
||
<li>The commit shasum matches the latest commit on <code>$BRANCH</code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Update the test snapshot of <code>rustup-init.sh --help</code>.
|
||
At the moment of writing, this is done by running:
|
||
<pre><code class="language-console">$ SNAPSHOTS=overwrite cargo test --features=test -- cli_rustup_init_ui
|
||
</code></pre>
|
||
</li>
|
||
</ol>
|
||
</li>
|
||
<li>[b/r] After merging the PR made in the previous step:
|
||
<ol>
|
||
<li>Pull the latest remote <code>$BRANCH</code> changes to the local <code>$BRANCH</code>.</li>
|
||
<li>Hard-reset the local <code>stable</code> to <code>$BRANCH</code>’s tip.</li>
|
||
<li>Double-check that the current local <code>stable</code> is indeed what is expected
|
||
for the next release (version number, commit history, etc.).</li>
|
||
<li>Force-push the local <code>stable</code> to the remote <code>stable</code>.</li>
|
||
</ol>
|
||
</li>
|
||
<li>[b/r] While you wait for green CI on <code>stable</code>, double-check the
|
||
functionality of <code>rustup-init.sh</code> and <code>rustup-init</code> just in case.</li>
|
||
<li>[b/r] Ensure all of CI is green on the <code>stable</code> branch.
|
||
Once it is, check through a representative proportion of the builds looking
|
||
for the reported version statements to ensure that we definitely built
|
||
something cleanly which reports as the right version number when run
|
||
<code>--version</code>.</li>
|
||
<li>[b] Make a new PR to the <a href="https://github.com/rust-lang/blog.rust-lang.org/tree/main/content/inside-rust">Inside Rust Blog</a> adding a new “Call for Testing”
|
||
announcement post.</li>
|
||
<li>[r] Make a new PR to the <a href="https://github.com/rust-lang/blog.rust-lang.org">Rust Blog</a> adding a new release announcement post.</li>
|
||
<li>[b/r] Ping someone in the release team to perform the actual release.
|
||
They can find instructions in <code>ci/sync-dist.py</code>.
|
||
<blockquote>
|
||
<p><strong>Note:</strong> Some manual testing occurs here, so hopefully they’ll catch
|
||
anything egregious in which case abort the change and roll back.</p>
|
||
</blockquote>
|
||
</li>
|
||
<li>[b] Once the beta release has happened, post a new topic named “Seeking beta
|
||
testers for rustup $VER_NUM” on the <a href="https://internals.rust-lang.org">Internals Forum</a> to point to the blog
|
||
post made previously.</li>
|
||
<li>[r] Once the official release has happened, prepare and push a tag on the
|
||
latest <code>stable</code> commit.
|
||
<ul>
|
||
<li><code>git tag -as $VER_NUM -m $VER_NUM</code> (optionally without <code>-s</code> if not GPG
|
||
signing the tag)</li>
|
||
<li><code>git push origin $VER_NUM</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>[b/r] Immediately perform the corresponding version bump for the next
|
||
release as described in the previous sections.</li>
|
||
</ol>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="developer-tips-and-tricks"><a class="header" href="#developer-tips-and-tricks">Developer tips and tricks</a></h1>
|
||
<h2 id="rustup_force_arg0"><a class="header" href="#rustup_force_arg0"><code>RUSTUP_FORCE_ARG0</code></a></h2>
|
||
<p>The environment variable <code>RUSTUP_FORCE_ARG0</code> can be used to get rustup to think
|
||
it’s a particular binary, rather than e.g. copying it, symlinking it or other
|
||
tricks with exec. This is handy when testing particular code paths from cargo
|
||
run.</p>
|
||
<p>For example, if you want to run <code>rustup show</code> with <code>cargo run</code>, you may execute:</p>
|
||
<pre><code class="language-console">> cargo run --config env.RUSTUP_FORCE_ARG0=\'rustup\' -- show
|
||
</code></pre>
|
||
<p>This command passes the <code>RUSTUP_FORCE_ARG0</code> environment variable to the
|
||
<code>rustup-init</code> binary without influencing the <code>cargo run</code> command itself,
|
||
which is very important since <code>cargo</code> could also be a rustup proxy.</p>
|
||
<h2 id="rustup_backtrack_limit"><a class="header" href="#rustup_backtrack_limit"><code>RUSTUP_BACKTRACK_LIMIT</code></a></h2>
|
||
<p>If it’s necessary to alter the backtracking limit from the default of half
|
||
a release cycle for some reason, you can set the <code>RUSTUP_BACKTRACK_LIMIT</code>
|
||
environment variable. If this is unparsable as an <code>i32</code> or if it’s absent
|
||
then the default of 21 days (half a cycle) is used. If it parses and is less
|
||
than 1, it is clamped to 1 at minimum.</p>
|
||
<p>This is not meant for use by users, but can be suggested in diagnosing an issue
|
||
should one arise with the backtrack limits.</p>
|
||
<h2 id="rustup_max_retries"><a class="header" href="#rustup_max_retries"><code>RUSTUP_MAX_RETRIES</code></a></h2>
|
||
<p>When downloading a file, rustup will retry the download a number of times. The
|
||
default is 3 times, but if this variable is set to a valid usize then it is the
|
||
max retry count. A value of <code>0</code> means no retries, thus the default of <code>3</code> will
|
||
mean a download is tried a total of four times before failing out.</p>
|
||
<h2 id="rustup_backtrace"><a class="header" href="#rustup_backtrace"><code>RUSTUP_BACKTRACE</code></a></h2>
|
||
<p>By default while running tests, we unset some environment variables that will
|
||
break our testing (like <code>RUSTUP_TOOLCHAIN</code>, <code>SHELL</code>, <code>ZDOTDIR</code>, <code>RUST_BACKTRACE</code>).
|
||
But if you want to debug locally, you may need backtrace. <code>RUSTUP_BACKTRACE</code>
|
||
is used like <code>RUST_BACKTRACE</code> to enable backtraces of failed tests.</p>
|
||
<p><strong>NOTE</strong>: This is a backtrace for the test, not for any subprocess invocation of
|
||
rustup process running in the test</p>
|
||
<pre><code class="language-bash">$ RUSTUP_BACKTRACE=1 cargo test --release --test cli-v1 -- remove_toolchain_then_add_again
|
||
Finished release [optimized] target(s) in 0.38s
|
||
Running target\release\deps\cli_v1-1f29f824792f6dc1.exe
|
||
|
||
running 1 test
|
||
test remove_toolchain_then_add_again ... FAILED
|
||
|
||
failures:
|
||
|
||
---- remove_toolchain_then_add_again stdout ----
|
||
thread 'remove_toolchain_then_add_again' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 1142, kind: Other, message: "An attempt was made to create more links on a file than the file system supports." }', src\libcore\result.rs:999:5
|
||
stack backtrace:
|
||
0: backtrace::backtrace::trace_unsynchronized
|
||
at C:\Users\appveyor\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.29\src\backtrace\mod.rs:66
|
||
1: std::sys_common::backtrace::_print
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\sys_common\backtrace.rs:47
|
||
2: std::sys_common::backtrace::print
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\sys_common\backtrace.rs:36
|
||
3: std::panicking::default_hook::{{closure}}
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\panicking.rs:198
|
||
4: std::panicking::default_hook
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\panicking.rs:209
|
||
5: std::panicking::rust_panic_with_hook
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\panicking.rs:475
|
||
6: std::panicking::continue_panic_fmt
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\panicking.rs:382
|
||
7: std::panicking::rust_begin_panic
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libstd\panicking.rs:309
|
||
8: core::panicking::panic_fmt
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libcore\panicking.rs:85
|
||
9: core::result::unwrap_failed
|
||
10: cli_v1::mock::clitools::test
|
||
11: alloc::boxed::{{impl}}::call_once<(),FnOnce<()>>
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\src\liballoc\boxed.rs:746
|
||
12: panic_unwind::__rust_maybe_catch_panic
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libpanic_unwind\lib.rs:82
|
||
13: std::panicking::try
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\src\libstd\panicking.rs:273
|
||
14: std::panic::catch_unwind
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\src\libstd\panic.rs:388
|
||
15: test::run_test::run_test_inner::{{closure}}
|
||
at /rustc/de02101e6d949c4a9040211e9ce8c488a997497e\/src\libtest\lib.rs:1466
|
||
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
||
|
||
|
||
failures:
|
||
remove_toolchain_then_add_again
|
||
|
||
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 26 filtered out
|
||
|
||
error: test failed, to rerun pass '--test cli-v1'
|
||
</code></pre>
|
||
<div style="break-before: page; page-break-before: always;"></div>
|
||
<h1 id="tracing"><a class="header" href="#tracing">Tracing</a></h1>
|
||
<p>Similar to other tools in the Rust ecosystem like rustc and cargo,
|
||
rustup also provides observability/logging features via the <code>tracing</code> crate.</p>
|
||
<p>The verbosity of logs is controlled via the <code>RUSTUP_LOG</code> environment
|
||
variable using <code>tracing_subscriber</code>’s <a href="https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives">directive syntax</a>.</p>
|
||
<h2 id="console-based-tracing"><a class="header" href="#console-based-tracing">Console-based tracing</a></h2>
|
||
<p>A <code>tracing_subscriber</code> that prints log lines directly to <code>stderr</code> is directly
|
||
available in the prebuilt version of rustup since v1.28.0.</p>
|
||
<p>For historical reasons, if <code>RUSTUP_LOG</code> is not set, this subscriber will print
|
||
the log lines in a format that mimics the “legacy” <code>stderr</code> output in older
|
||
versions of rustup:</p>
|
||
<pre><code class="language-console">> rustup default stable
|
||
info: using existing install for 'stable-aarch64-apple-darwin'
|
||
info: default toolchain set to 'stable-aarch64-apple-darwin'
|
||
|
||
stable-aarch64-apple-darwin unchanged - rustc 1.79.0 (129f3b996 2024-06-10)
|
||
</code></pre>
|
||
<p>However, once <code>RUSTUP_LOG</code> is set to any value, rustup’s “custom logging mode” will
|
||
be activated, and <code>tracing_subscriber</code>’s builtin output format will be used instead:</p>
|
||
<pre><code class="language-console">> RUSTUP_LOG=trace rustup default stable
|
||
2024-06-16T12:08:48.732894Z INFO rustup::cli::common: using existing install for 'stable-aarch64-apple-darwin'
|
||
2024-06-16T12:08:48.739232Z INFO rustup::cli::common: default toolchain set to 'stable-aarch64-apple-darwin'
|
||
|
||
stable-aarch64-apple-darwin unchanged - rustc 1.79.0 (129f3b996 2024-06-10)
|
||
</code></pre>
|
||
<p>Please note that since <code>RUSTUP_LOG=trace</code> essentially accepts log lines from
|
||
all possible sources, you might sometimes see log lines coming from rustup’s
|
||
dependencies, such as <code>hyper_util</code> in the following example:</p>
|
||
<pre><code class="language-console">> RUSTUP_LOG=trace rustup update
|
||
[..]
|
||
2024-06-16T12:12:45.569428Z TRACE hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task
|
||
2024-06-16T12:12:45.648682Z TRACE hyper_util::client::legacy::pool: pool dropped, dropping pooled (("https", static.rust-lang.org))
|
||
|
||
stable-aarch64-apple-darwin unchanged - rustc 1.79.0 (129f3b996 2024-06-10)
|
||
nightly-aarch64-apple-darwin unchanged - rustc 1.81.0-nightly (3cf924b93 2024-06-15)
|
||
|
||
2024-06-16T12:12:45.693350Z INFO rustup::cli::rustup_mode: cleaning up downloads & tmp directories
|
||
</code></pre>
|
||
<p>It is also possible to limit the sources of the log lines and the desired
|
||
max level for each source. For example, set <code>RUSTUP_LOG=rustup=DEBUG</code> to
|
||
receive log lines only from <code>rustup</code> itself with a max verbosity of <code>DEBUG</code>.</p>
|
||
<h2 id="opentelemetry-tracing"><a class="header" href="#opentelemetry-tracing">Opentelemetry tracing</a></h2>
|
||
<p>The feature <code>otel</code> can be used when building rustup to turn on Opentelemetry
|
||
tracing with an OLTP GRPC exporter.</p>
|
||
<p>This can be very useful for diagnosing performance or correctness issues in more
|
||
complicated scenarios.</p>
|
||
<p>The normal <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md">OTLP environment
|
||
variables</a>
|
||
can be used to customise its behaviour, but often the simplest thing is to just
|
||
run a Jaeger docker container on the same host:</p>
|
||
<pre><code class="language-sh">docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 -e COLLECTOR_OTLP_ENABLED=true -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 4317:4317 -p 4318:4318 -p 14250:14250 -p 14268:14268 -p 14269:14269 -p 9411:9411 jaegertracing/all-in-one:latest
|
||
</code></pre>
|
||
<p>Then build <code>rustup-init</code> with tracing:</p>
|
||
<pre><code class="language-sh">cargo build --features=otel
|
||
</code></pre>
|
||
<p>Run the operation you want to analyze. For example, we can now run <code>rustup show</code> with tracing:</p>
|
||
<pre><code class="language-sh">RUSTUP_FORCE_ARG0="rustup" ./target/debug/rustup-init show
|
||
</code></pre>
|
||
<p>And <a href="http://localhost:16686/search?service=rustup">look in Jaeger for a trace</a>.</p>
|
||
<p>Tracing can also be used in tests to get a trace of the operations taken during the test.
|
||
To use this feature, build the project with <code>--features=otel,test</code>.</p>
|
||
<h2 id="adding-instrumentation"><a class="header" href="#adding-instrumentation">Adding instrumentation</a></h2>
|
||
<p>Instrumenting a currently uninstrumented function is mostly simply done like so:</p>
|
||
<pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>#[tracing::instrument(level = "trace", err(level = "trace"), skip_all)]
|
||
<span class="boring">}</span></code></pre>
|
||
<p>Sometimes you might want to instrument a function only when the <code>otel</code> feature is enabled.
|
||
In this case, you will need to use conditional compilation with <code>cfg_attr</code>:</p>
|
||
<pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||
</span><span class="boring">fn main() {
|
||
</span>#[cfg_attr(feature="otel", tracing::instrument(level = "trace", err(level = "trace"), skip_all))]
|
||
<span class="boring">}</span></code></pre>
|
||
<p><code>skip_all</code> is not required, but some core structs don’t implement <code>Debug</code> yet, and
|
||
others have a lot of output in <code>Debug</code>: tracing adds some overheads, so keeping
|
||
spans lightweight can help avoid frequency bias in the results - where
|
||
parameters with large debug in frequently called functions show up as much
|
||
slower than they are.</p>
|
||
<p>Some good general heuristics:</p>
|
||
<ul>
|
||
<li>Do instrument slow blocking functions</li>
|
||
<li>Do instrument functions with many callers or that call many different things,
|
||
as these tend to help figure the puzzle of what-is-happening</li>
|
||
<li>Default to not instrumenting thin shim functions (or at least, only instrument
|
||
them temporarily while figuring out the shape of a problem)</li>
|
||
<li>Be way of debug build timing - release optimisations make a huge difference,
|
||
though debug is a lot faster to iterate on. If something isn’t a problem in
|
||
release don’t pay it too much heed in debug.</li>
|
||
</ul>
|
||
|
||
</main>
|
||
|
||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
<!-- Mobile navigation buttons -->
|
||
|
||
|
||
<div style="clear: both"></div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
|
||
</nav>
|
||
|
||
</div>
|
||
|
||
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template>
|
||
<template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template>
|
||
<template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template>
|
||
<template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template>
|
||
<template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
|
||
|
||
|
||
|
||
<script>
|
||
window.playground_copyable = true;
|
||
</script>
|
||
|
||
|
||
<script src="elasticlunr-ef4e11c1.min.js"></script>
|
||
<script src="mark-09e88c2c.min.js"></script>
|
||
<script src="searcher-c2a407aa.js"></script>
|
||
|
||
<script src="clipboard-1626706a.min.js"></script>
|
||
<script src="highlight-abc7f01d.js"></script>
|
||
<script src="book-a0b12cfe.js"></script>
|
||
|
||
<!-- Custom JS scripts -->
|
||
|
||
<script>
|
||
window.addEventListener('load', function() {
|
||
window.setTimeout(window.print, 100);
|
||
});
|
||
</script>
|
||
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|