1 use std
::path
::PathBuf
;
2 use std
::process
::Command
;
4 use clap_complete
::shells
;
6 use crate::builder
::{Builder, RunConfig, ShouldRun, Step}
;
7 use crate::config
::TargetSelection
;
8 use crate::dist
::distdir
;
9 use crate::flags
::get_completion
;
11 use crate::tool
::{self, SourceType, Tool}
;
12 use crate::util
::output
;
15 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
16 pub struct ExpandYamlAnchors
;
18 impl Step
for ExpandYamlAnchors
{
21 /// Runs the `expand-yaml_anchors` tool.
23 /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the
24 /// anchors in them, since GitHub Actions doesn't support them.
25 fn run(self, builder
: &Builder
<'_
>) {
26 builder
.info("Expanding YAML anchors in the GitHub Actions configuration");
27 builder
.run_delaying_failure(
28 &mut builder
.tool_cmd(Tool
::ExpandYamlAnchors
).arg("generate").arg(&builder
.src
),
32 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
33 run
.path("src/tools/expand-yaml-anchors")
36 fn make_run(run
: RunConfig
<'_
>) {
37 run
.builder
.ensure(ExpandYamlAnchors
);
41 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
42 pub struct BuildManifest
;
44 impl Step
for BuildManifest
{
46 const ONLY_HOSTS
: bool
= true;
48 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
49 run
.path("src/tools/build-manifest")
52 fn make_run(run
: RunConfig
<'_
>) {
53 run
.builder
.ensure(BuildManifest
);
56 fn run(self, builder
: &Builder
<'_
>) {
57 // This gets called by `promote-release`
58 // (https://github.com/rust-lang/promote-release).
59 let mut cmd
= builder
.tool_cmd(Tool
::BuildManifest
);
60 let sign
= builder
.config
.dist_sign_folder
.as_ref().unwrap_or_else(|| {
61 panic
!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
63 let addr
= builder
.config
.dist_upload_addr
.as_ref().unwrap_or_else(|| {
64 panic
!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
67 let today
= output(Command
::new("date").arg("+%Y-%m-%d"));
70 cmd
.arg(distdir(builder
));
71 cmd
.arg(today
.trim());
73 cmd
.arg(&builder
.config
.channel
);
75 builder
.create_dir(&distdir(builder
));
76 builder
.run(&mut cmd
);
80 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
81 pub struct BumpStage0
;
83 impl Step
for BumpStage0
{
85 const ONLY_HOSTS
: bool
= true;
87 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
88 run
.path("src/tools/bump-stage0")
91 fn make_run(run
: RunConfig
<'_
>) {
92 run
.builder
.ensure(BumpStage0
);
95 fn run(self, builder
: &Builder
<'_
>) -> Self::Output
{
96 let mut cmd
= builder
.tool_cmd(Tool
::BumpStage0
);
97 cmd
.args(builder
.config
.args());
98 builder
.run(&mut cmd
);
102 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
103 pub struct ReplaceVersionPlaceholder
;
105 impl Step
for ReplaceVersionPlaceholder
{
107 const ONLY_HOSTS
: bool
= true;
109 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
110 run
.path("src/tools/replace-version-placeholder")
113 fn make_run(run
: RunConfig
<'_
>) {
114 run
.builder
.ensure(ReplaceVersionPlaceholder
);
117 fn run(self, builder
: &Builder
<'_
>) -> Self::Output
{
118 let mut cmd
= builder
.tool_cmd(Tool
::ReplaceVersionPlaceholder
);
119 cmd
.arg(&builder
.src
);
120 builder
.run(&mut cmd
);
124 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
127 host
: TargetSelection
,
128 target
: TargetSelection
,
133 const ONLY_HOSTS
: bool
= false;
135 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
136 run
.path("src/tools/miri")
139 fn make_run(run
: RunConfig
<'_
>) {
140 run
.builder
.ensure(Miri
{
141 stage
: run
.builder
.top_stage
,
142 host
: run
.build_triple(),
147 fn run(self, builder
: &Builder
<'_
>) {
148 let stage
= self.stage
;
149 let host
= self.host
;
150 let target
= self.target
;
151 let compiler
= builder
.compiler(stage
, host
);
154 .ensure(tool
::Miri { compiler, target: self.host, extra_features: Vec::new() }
)
155 .expect("in-tree tool");
156 let miri_sysroot
= test
::Miri
::build_miri_sysroot(builder
, compiler
, &miri
, target
);
159 // Running it via `cargo run` as that figures out the right dylib path.
160 // add_rustc_lib_path does not add the path that contains librustc_driver-<...>.so.
161 let mut miri
= tool
::prepare_tool_cargo(
171 miri
.add_rustc_lib_path(builder
, compiler
);
172 // Forward arguments.
173 miri
.arg("--").arg("--target").arg(target
.rustc_target_arg());
174 miri
.args(builder
.config
.args());
176 // miri tests need to know about the stage sysroot
177 miri
.env("MIRI_SYSROOT", &miri_sysroot
);
179 let mut miri
= Command
::from(miri
);
180 builder
.run(&mut miri
);
184 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
185 pub struct CollectLicenseMetadata
;
187 impl Step
for CollectLicenseMetadata
{
188 type Output
= PathBuf
;
189 const ONLY_HOSTS
: bool
= true;
191 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
192 run
.path("src/tools/collect-license-metadata")
195 fn make_run(run
: RunConfig
<'_
>) {
196 run
.builder
.ensure(CollectLicenseMetadata
);
199 fn run(self, builder
: &Builder
<'_
>) -> Self::Output
{
200 let Some(reuse
) = &builder
.config
.reuse
else {
201 panic
!("REUSE is required to collect the license metadata");
204 // Temporary location, it will be moved to src/etc once it's accurate.
205 let dest
= builder
.out
.join("license-metadata.json");
207 let mut cmd
= builder
.tool_cmd(Tool
::CollectLicenseMetadata
);
208 cmd
.env("REUSE_EXE", reuse
);
209 cmd
.env("DEST", &dest
);
210 builder
.run(&mut cmd
);
216 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
217 pub struct GenerateCopyright
;
219 impl Step
for GenerateCopyright
{
220 type Output
= PathBuf
;
221 const ONLY_HOSTS
: bool
= true;
223 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
224 run
.path("src/tools/generate-copyright")
227 fn make_run(run
: RunConfig
<'_
>) {
228 run
.builder
.ensure(GenerateCopyright
);
231 fn run(self, builder
: &Builder
<'_
>) -> Self::Output
{
232 let license_metadata
= builder
.ensure(CollectLicenseMetadata
);
234 // Temporary location, it will be moved to the proper one once it's accurate.
235 let dest
= builder
.out
.join("COPYRIGHT.md");
237 let mut cmd
= builder
.tool_cmd(Tool
::GenerateCopyright
);
238 cmd
.env("LICENSE_METADATA", &license_metadata
);
239 cmd
.env("DEST", &dest
);
240 builder
.run(&mut cmd
);
246 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
247 pub struct GenerateWindowsSys
;
249 impl Step
for GenerateWindowsSys
{
251 const ONLY_HOSTS
: bool
= true;
253 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
254 run
.path("src/tools/generate-windows-sys")
257 fn make_run(run
: RunConfig
<'_
>) {
258 run
.builder
.ensure(GenerateWindowsSys
);
261 fn run(self, builder
: &Builder
<'_
>) {
262 let mut cmd
= builder
.tool_cmd(Tool
::GenerateWindowsSys
);
263 cmd
.arg(&builder
.src
);
264 builder
.run(&mut cmd
);
268 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
269 pub struct GenerateCompletions
;
271 impl Step
for GenerateCompletions
{
274 /// Uses `clap_complete` to generate shell completions.
275 fn run(self, builder
: &Builder
<'_
>) {
276 // FIXME(clubby789): enable zsh when clap#4898 is fixed
277 let [bash
, fish
, powershell
] = ["x.py.sh", "x.py.fish", "x.py.ps1"]
278 .map(|filename
| builder
.src
.join("src/etc/completions").join(filename
));
279 if let Some(comp
) = get_completion(shells
::Bash
, &bash
) {
280 std
::fs
::write(&bash
, comp
).expect("writing bash completion");
282 if let Some(comp
) = get_completion(shells
::Fish
, &fish
) {
283 std
::fs
::write(&fish
, comp
).expect("writing fish completion");
285 if let Some(comp
) = get_completion(shells
::PowerShell
, &powershell
) {
286 std
::fs
::write(&powershell
, comp
).expect("writing powershell completion");
290 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
291 run
.alias("generate-completions")
294 fn make_run(run
: RunConfig
<'_
>) {
295 run
.builder
.ensure(GenerateCompletions
);