android_tools/bundletool/
build_bundle.rs

1use super::bundletool;
2use crate::error::*;
3use std::path::{Path, PathBuf};
4
5/// ## Build your app bundle using bundletool
6/// To build your app bundle, you use the `bundletool build-bundle` command, as shown
7/// below:
8///
9/// ```sh
10/// `bundletool build-bundle --modules=base.zip --output=mybundle.aab`
11/// ```
12///
13/// ## Note
14/// If you plan to publish the app bundle, you need to sign it using [`jarsigner`]. You
15/// can not use apksigner to sign your app bundle.
16///
17/// [jarsigner]: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jarsigner.html
18#[derive(Debug)]
19pub struct BuildBundle {
20    modules: Vec<PathBuf>,
21    output: PathBuf,
22    config: Option<PathBuf>,
23    metadata_file: Option<PathBuf>,
24}
25
26impl BuildBundle {
27    /// Specifies the list of module ZIP files `bundletool` should use to build your app
28    /// bundle.
29    ///
30    /// Specifies the path and filename for the output `.aab` file
31    pub fn new(modules: &[PathBuf], output: &Path) -> Self {
32        Self {
33            modules: modules.to_vec(),
34            output: output.to_owned(),
35            config: None,
36            metadata_file: None,
37        }
38    }
39
40    /// Specifies the path to an optional configuration file you can use to customize the
41    /// build process. To learn more, see the section about
42    /// [`customizing downstream APK generation`](https://developer.android.com/studio/build/building-cmdline#bundleconfig)
43    pub fn config(&mut self, config: &Path) -> &mut Self {
44        self.config = Some(config.to_owned());
45        self
46    }
47
48    /// Instructs bundletool to package an optional metadata file inside your app bundle.
49    /// You can use this file to include data, such as ProGuard mappings or the complete
50    /// list of your app's DEX files, that may be useful to other steps in your toolchain
51    /// or an app store.
52    ///
53    /// `target-bundle-path` specifies a path relative to the root of the app bundle where
54    /// you would like the metadata file to be packaged, and `local-file-path` specifies
55    /// the path to the local metadata file itself
56    pub fn metadata_file(&mut self, metadata_file: &Path) -> &mut Self {
57        self.metadata_file = Some(metadata_file.to_owned());
58        self
59    }
60
61    /// Runs `bundletool` commands to build AAB
62    pub fn run(&self) -> Result<()> {
63        let mut build_bundle = bundletool()?;
64        build_bundle.arg("build-bundle");
65        build_bundle.arg("--modules");
66        build_bundle.arg(
67            self.modules
68                .iter()
69                .map(|v| v.to_string_lossy().to_string())
70                .collect::<Vec<String>>()
71                .join(","),
72        );
73        build_bundle.arg("--output").arg(&self.output);
74        if let Some(config) = &self.config {
75            build_bundle.arg("--config").arg(config);
76        }
77        if let Some(metadata_file) = &self.metadata_file {
78            build_bundle.arg("--metadata-file").arg(metadata_file);
79        }
80        build_bundle.output_err(true)?;
81        Ok(())
82    }
83}