1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
use crate::buildsystem::{detect_buildsystems, Error};
use crate::fix_build::{iterate_with_build_fixers, BuildFixer, InterimError};
use crate::fixers::*;
use crate::installer::{
auto_installation_scope, auto_installer, Error as InstallerError, InstallationScope,
};
use crate::logs::{wrap, LogManager};
use crate::session::Session;
use std::ffi::OsString;
use std::path::Path;
/// Create a distribution package using the detected build system.
///
/// # Arguments
/// * `session` - The session to run commands in
/// * `export_directory` - Directory to search for build systems
/// * `reldir` - Relative directory to change to before building
/// * `target_dir` - Directory to write distribution package to
/// * `log_manager` - Log manager for capturing output
/// * `version` - Optional version to use for the package
/// * `quiet` - Whether to suppress output
///
/// # Returns
/// The filename of the created distribution package
pub fn dist(
session: &mut dyn Session,
export_directory: &Path,
reldir: &Path,
target_dir: &Path,
log_manager: &mut dyn LogManager,
version: Option<&str>,
quiet: bool,
) -> Result<OsString, Error> {
session.chdir(reldir)?;
if let Some(version) = version {
// TODO(jelmer): Shouldn't include backend-specific code here
std::env::set_var("SETUPTOOLS_SCM_PRETEND_VERSION", version);
}
// TODO(jelmer): use scan_buildsystems to also look in subdirectories
let buildsystems = detect_buildsystems(export_directory);
let scope = auto_installation_scope(session);
let installer = auto_installer(session, scope, None);
let mut fixers: Vec<Box<dyn BuildFixer<InstallerError>>> = vec![
Box::new(UnexpandedAutoconfMacroFixer::new(
session,
installer.as_ref(),
)),
Box::new(GnulibDirectoryFixer::new(session)),
Box::new(MinimumAutoconfFixer::new(session)),
Box::new(MissingGoSumEntryFixer::new(session)),
Box::new(InstallFixer::new(
installer.as_ref(),
InstallationScope::User,
)),
];
if session.is_temporary() {
// Only muck about with temporary sessions
fixers.extend([
Box::new(GitIdentityFixer::new(session)) as Box<dyn BuildFixer<InstallerError>>,
Box::new(SecretGpgKeyFixer::new(session)) as Box<dyn BuildFixer<InstallerError>>,
]);
}
// Some things want to write to the user's home directory, e.g. pip caches in ~/.cache
session.create_home()?;
if let Some(buildsystem) = buildsystems.into_iter().next() {
return Ok(iterate_with_build_fixers(
fixers
.iter()
.map(|x| x.as_ref())
.collect::<Vec<_>>()
.as_slice(),
|| -> Result<_, InterimError<Error>> {
Ok(wrap(log_manager, || -> Result<_, Error> {
buildsystem.dist(session, installer.as_ref(), target_dir, quiet)
})?)
},
None,
)?);
}
Err(Error::NoBuildSystemDetected)
}
#[cfg(feature = "breezy")]
// This is the function used by debianize()
/// Create a dist tarball for a tree.
///
/// # Arguments
/// * `session` - session to run it
/// * `tree` - Tree object to work in
/// * `target_dir` - Directory to write tarball into
/// * `include_controldir` - Whether to include the version control directory
/// * `temp_subdir` - name of subdirectory in which to check out the source code;
/// defaults to "package"
pub fn create_dist<T: crate::vcs::DupableTree>(
session: &mut dyn Session,
tree: &T,
target_dir: &Path,
include_controldir: Option<bool>,
log_manager: &mut dyn LogManager,
version: Option<&str>,
_subpath: &Path,
temp_subdir: Option<&str>,
) -> Result<OsString, Error> {
let temp_subdir = temp_subdir.unwrap_or("package");
let project = session.project_from_vcs(tree, include_controldir, Some(temp_subdir))?;
dist(
session,
project.external_path(),
project.internal_path(),
target_dir,
log_manager,
version,
false,
)
}
#[cfg(feature = "breezy")]
#[cfg(target_os = "linux")]
/// Create a dist tarball for a tree.
///
/// # Arguments
/// * `session` - session to run it
/// * `tree` - Tree object to work in
/// * `target_dir` - Directory to write tarball into
/// * `include_controldir` - Whether to include the version control directory
/// * `temp_subdir` - name of subdirectory in which to check out the source code;
/// defaults to "package"
pub fn create_dist_schroot<T: crate::vcs::DupableTree>(
tree: &T,
target_dir: &Path,
chroot: &str,
packaging_tree: Option<&dyn breezyshim::tree::Tree>,
packaging_subpath: Option<&Path>,
include_controldir: Option<bool>,
subpath: &Path,
log_manager: &mut dyn LogManager,
version: Option<&str>,
temp_subdir: Option<&str>,
) -> Result<OsString, Error> {
// TODO(jelmer): pass in package name as part of session prefix
let mut session = crate::session::schroot::SchrootSession::new(chroot, Some("ognibuild-dist"))?;
#[cfg(feature = "debian")]
if let (Some(packaging_tree), Some(packaging_subpath)) = (packaging_tree, packaging_subpath) {
crate::debian::satisfy_build_deps(&session, packaging_tree, packaging_subpath)
.map_err(|e| Error::Other(format!("Failed to satisfy build dependencies: {:?}", e)))?;
}
#[cfg(not(feature = "debian"))]
if packaging_tree.is_some() || packaging_subpath.is_some() {
log::warn!("Ignoring packaging tree and subpath as debian feature is not enabled");
}
create_dist(
&mut session,
tree,
target_dir,
include_controldir,
log_manager,
version,
subpath,
temp_subdir,
)
}
|