]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-installer/src/combiner.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / src / tools / rust-installer / src / combiner.rs
CommitLineData
22607d1e
XL
1use super::Scripter;
2use super::Tarballer;
9fa01778 3use crate::util::*;
f035d41b 4use anyhow::{bail, Context, Result};
416331ca
XL
5use flate2::read::GzDecoder;
6use std::io::{Read, Write};
7use std::path::Path;
8use tar::Archive;
22607d1e 9
416331ca 10actor! {
22607d1e
XL
11 #[derive(Debug)]
12 pub struct Combiner {
416331ca 13 /// The name of the product, for display.
22607d1e
XL
14 product_name: String = "Product",
15
416331ca 16 /// The name of the package tarball.
22607d1e
XL
17 package_name: String = "package",
18
416331ca 19 /// The directory under lib/ where the manifest lives.
22607d1e
XL
20 rel_manifest_dir: String = "packagelib",
21
416331ca 22 /// The string to print after successful installation.
22607d1e
XL
23 success_message: String = "Installed.",
24
416331ca 25 /// Places to look for legacy manifests to uninstall.
22607d1e
XL
26 legacy_manifest_dirs: String = "",
27
416331ca 28 /// Installers to combine.
22607d1e
XL
29 input_tarballs: String = "",
30
416331ca 31 /// Directory containing files that should not be installed.
22607d1e
XL
32 non_installed_overlay: String = "",
33
416331ca 34 /// The directory to do temporary work.
22607d1e
XL
35 work_dir: String = "./workdir",
36
416331ca 37 /// The location to put the final image and tarball.
22607d1e
XL
38 output_dir: String = "./dist",
39 }
40}
41
42impl Combiner {
416331ca 43 /// Combines the installer tarballs.
22607d1e
XL
44 pub fn run(self) -> Result<()> {
45 create_dir_all(&self.work_dir)?;
46
47 let package_dir = Path::new(&self.work_dir).join(&self.package_name);
48 if package_dir.exists() {
49 remove_dir_all(&package_dir)?;
50 }
51 create_dir_all(&package_dir)?;
52
416331ca 53 // Merge each installer into the work directory of the new installer.
22607d1e 54 let components = create_new_file(package_dir.join("components"))?;
416331ca
XL
55 for input_tarball in self
56 .input_tarballs
57 .split(',')
58 .map(str::trim)
59 .filter(|s| !s.is_empty())
60 {
22607d1e 61 // Extract the input tarballs
ff7c6d11 62 let tar = GzDecoder::new(open_file(&input_tarball)?);
f035d41b 63 Archive::new(tar).unpack(&self.work_dir).with_context(|| {
416331ca
XL
64 format!(
65 "unable to extract '{}' into '{}'",
66 &input_tarball, self.work_dir
67 )
68 })?;
22607d1e 69
9fa01778 70 let pkg_name = input_tarball.trim_end_matches(".tar.gz");
22607d1e
XL
71 let pkg_name = Path::new(pkg_name).file_name().unwrap();
72 let pkg_dir = Path::new(&self.work_dir).join(&pkg_name);
73
416331ca 74 // Verify the version number.
22607d1e
XL
75 let mut version = String::new();
76 open_file(pkg_dir.join("rust-installer-version"))
416331ca 77 .and_then(|mut file| Ok(file.read_to_string(&mut version)?))
f035d41b 78 .with_context(|| format!("failed to read version in '{}'", input_tarball))?;
9fa01778 79 if version.trim().parse() != Ok(crate::RUST_INSTALLER_VERSION) {
22607d1e
XL
80 bail!("incorrect installer version in {}", input_tarball);
81 }
82
416331ca 83 // Copy components to the new combined installer.
22607d1e
XL
84 let mut pkg_components = String::new();
85 open_file(pkg_dir.join("components"))
416331ca 86 .and_then(|mut file| Ok(file.read_to_string(&mut pkg_components)?))
f035d41b 87 .with_context(|| format!("failed to read components in '{}'", input_tarball))?;
22607d1e 88 for component in pkg_components.split_whitespace() {
416331ca 89 // All we need to do is copy the component directory. We could
22607d1e
XL
90 // move it, but rustbuild wants to reuse the unpacked package
91 // dir for OS-specific installers on macOS and Windows.
92 let component_dir = package_dir.join(&component);
93 create_dir(&component_dir)?;
94 copy_recursive(&pkg_dir.join(&component), &component_dir)?;
95
416331ca 96 // Merge the component name.
f035d41b 97 writeln!(&components, "{}", component).context("failed to write new components")?;
22607d1e
XL
98 }
99 }
100 drop(components);
101
416331ca 102 // Write the installer version.
22607d1e 103 let version = package_dir.join("rust-installer-version");
416331ca
XL
104 writeln!(
105 create_new_file(version)?,
106 "{}",
107 crate::RUST_INSTALLER_VERSION
108 )
f035d41b 109 .context("failed to write new installer version")?;
416331ca
XL
110
111 // Copy the overlay.
22607d1e
XL
112 if !self.non_installed_overlay.is_empty() {
113 copy_recursive(self.non_installed_overlay.as_ref(), &package_dir)?;
114 }
115
416331ca 116 // Generate the install script.
22607d1e
XL
117 let output_script = package_dir.join("install.sh");
118 let mut scripter = Scripter::default();
416331ca
XL
119 scripter
120 .product_name(self.product_name)
22607d1e
XL
121 .rel_manifest_dir(self.rel_manifest_dir)
122 .success_message(self.success_message)
123 .legacy_manifest_dirs(self.legacy_manifest_dirs)
124 .output_script(path_to_str(&output_script)?);
125 scripter.run()?;
126
416331ca 127 // Make the tarballs.
22607d1e
XL
128 create_dir_all(&self.output_dir)?;
129 let output = Path::new(&self.output_dir).join(&self.package_name);
130 let mut tarballer = Tarballer::default();
416331ca
XL
131 tarballer
132 .work_dir(self.work_dir)
22607d1e
XL
133 .input(self.package_name)
134 .output(path_to_str(&output)?);
135 tarballer.run()?;
136
137 Ok(())
138 }
139}