feat: add support for Mercurial (hg) source handling in mod.rs
- Implemented `split_hg_url` to parse Mercurial URLs and revisions. - Added `checkout_hg` function to clone Mercurial repositories. - Integrated Mercurial handling into the `prepare_one` function to support resuming builds. - Added tests for `split_hg_url` to ensure correct parsing of URLs and revisions. --- feat: introduce legacy STARBUILD conversion support in starbuild.rs - Created `ConvertedStarbuild` and `ParsedStarbuild` structs to manage conversion data. - Implemented `convert_starbuild_file` to parse STARBUILD files and generate package specifications. - Added functions to handle parsing of various STARBUILD constructs, including dependencies and build phases. - Developed a build script generator for STARBUILD, supporting custom install functions. - Included tests to validate conversion of single and multi-output STARBUILD files.
This commit is contained in:
Generated
+3
-3
@@ -418,7 +418,7 @@ checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "depot"
|
name = "depot"
|
||||||
version = "0.31.0"
|
version = "0.31.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
@@ -3090,9 +3090,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip"
|
name = "zip"
|
||||||
version = "8.3.1"
|
version = "8.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c546feb4481b0fbafb4ef0d79b6204fc41c6f9884b1b73b1d73f82442fc0845"
|
checksum = "7756d0206d058333667493c4014f545f4b9603c4330ccd6d9b3f86dcab59f7d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bzip2",
|
"bzip2",
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "depot"
|
name = "depot"
|
||||||
version = "0.31.0"
|
version = "0.31.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
@@ -27,7 +27,7 @@ toml = "1.0.6"
|
|||||||
url = "2.5.8"
|
url = "2.5.8"
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
xz2 = "0.1.7"
|
xz2 = "0.1.7"
|
||||||
zip = "8.3.1"
|
zip = "8.4.0"
|
||||||
zstd = { version = "0.13.3", features = ["zstdmt"] }
|
zstd = { version = "0.13.3", features = ["zstdmt"] }
|
||||||
inquire = "0.9.4"
|
inquire = "0.9.4"
|
||||||
md5 = "0.8.0"
|
md5 = "0.8.0"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
project(
|
project(
|
||||||
'depot',
|
'depot',
|
||||||
version: '0.31.0',
|
version: '0.31.1',
|
||||||
meson_version: '>=0.60.0',
|
meson_version: '>=0.60.0',
|
||||||
default_options: ['buildtype=release'],
|
default_options: ['buildtype=release'],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -117,6 +117,19 @@ pub fn build(
|
|||||||
"DEPOT_PRIMARY_DESTDIR",
|
"DEPOT_PRIMARY_DESTDIR",
|
||||||
install_destdir.to_string_lossy().into_owned(),
|
install_destdir.to_string_lossy().into_owned(),
|
||||||
);
|
);
|
||||||
|
let starbuild_workdir = if spec.sources().is_empty() {
|
||||||
|
src_dir.to_path_buf()
|
||||||
|
} else {
|
||||||
|
src_dir
|
||||||
|
.parent()
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or_else(|| src_dir.to_path_buf())
|
||||||
|
};
|
||||||
|
crate::builder::set_env_var(
|
||||||
|
&mut env_vars,
|
||||||
|
"DEPOT_STARBUILD_WORKDIR",
|
||||||
|
starbuild_workdir.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
add_output_destdir_envs(spec, &install_destdir, &mut env_vars);
|
add_output_destdir_envs(spec, &install_destdir, &mut env_vars);
|
||||||
|
|
||||||
// Ensure build script path is absolute for when we are in a sub-build-dir
|
// Ensure build script path is absolute for when we are in a sub-build-dir
|
||||||
|
|||||||
+40
-1
@@ -240,6 +240,17 @@ pub struct MakeSpecArgs {
|
|||||||
pub output: Option<PathBuf>,
|
pub output: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Args)]
|
||||||
|
pub struct ConvertArgs {
|
||||||
|
/// Path to the legacy STARBUILD file
|
||||||
|
#[arg(default_value = "STARBUILD")]
|
||||||
|
pub input: PathBuf,
|
||||||
|
|
||||||
|
/// Output TOML file path (defaults to <mainpkgname>.toml beside the STARBUILD)
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub output: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Args)]
|
#[derive(Debug, Clone, Args)]
|
||||||
pub struct InternalArgs {
|
pub struct InternalArgs {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
@@ -277,6 +288,8 @@ pub enum Commands {
|
|||||||
GenerateArtifacts(GenerateArtifactsArgs),
|
GenerateArtifacts(GenerateArtifactsArgs),
|
||||||
/// Create a new package specification interactively
|
/// Create a new package specification interactively
|
||||||
MakeSpec(MakeSpecArgs),
|
MakeSpec(MakeSpecArgs),
|
||||||
|
/// Convert a legacy STARBUILD into a Depot package spec
|
||||||
|
Convert(ConvertArgs),
|
||||||
#[command(hide = true)]
|
#[command(hide = true)]
|
||||||
Internal(InternalArgs),
|
Internal(InternalArgs),
|
||||||
}
|
}
|
||||||
@@ -430,7 +443,8 @@ pub enum RepoKindArg {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{
|
use super::{
|
||||||
BuildArgs, Cli, Commands, InstallArgs, RepoArgs, RepoCommands, SearchArgs, UpdateArgs,
|
BuildArgs, Cli, Commands, ConvertArgs, InstallArgs, RepoArgs, RepoCommands, SearchArgs,
|
||||||
|
UpdateArgs,
|
||||||
};
|
};
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -517,6 +531,31 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_accepts_default_input() {
|
||||||
|
let cli = Cli::try_parse_from(["depot", "convert"]).unwrap();
|
||||||
|
match cli.command {
|
||||||
|
Commands::Convert(ConvertArgs { input, output }) => {
|
||||||
|
assert_eq!(input, PathBuf::from("STARBUILD"));
|
||||||
|
assert!(output.is_none());
|
||||||
|
}
|
||||||
|
_ => panic!("expected convert command"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_accepts_custom_output() {
|
||||||
|
let cli = Cli::try_parse_from(["depot", "convert", "legacy/STARBUILD", "-o", "pkg.toml"])
|
||||||
|
.unwrap();
|
||||||
|
match cli.command {
|
||||||
|
Commands::Convert(ConvertArgs { input, output }) => {
|
||||||
|
assert_eq!(input, PathBuf::from("legacy/STARBUILD"));
|
||||||
|
assert_eq!(output, Some(PathBuf::from("pkg.toml")));
|
||||||
|
}
|
||||||
|
_ => panic!("expected convert command"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_cleanup_deps_flag_is_parsed() {
|
fn build_cleanup_deps_flag_is_parsed() {
|
||||||
let cli = Cli::try_parse_from(["depot", "build", "--cleanup-deps", "pkg.toml"]).unwrap();
|
let cli = Cli::try_parse_from(["depot", "build", "--cleanup-deps", "pkg.toml"]).unwrap();
|
||||||
|
|||||||
+58
-2
@@ -1,6 +1,7 @@
|
|||||||
use crate::cli::{
|
use crate::cli::{
|
||||||
BuildArgs, Cli, Commands, ConfigArgs, InfoArgs, InstallArgs, InternalCommands, ListArgs,
|
BuildArgs, Cli, Commands, ConfigArgs, ConvertArgs, InfoArgs, InstallArgs, InternalCommands,
|
||||||
OwnsArgs, RemoveArgs, RepoArgs, RepoCommands, RepoKindArg, SearchArgs, SignArgs, UpdateArgs,
|
ListArgs, OwnsArgs, RemoveArgs, RepoArgs, RepoCommands, RepoKindArg, SearchArgs, SignArgs,
|
||||||
|
UpdateArgs,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
builder, cli_assets, config, cross, db, deps, index, install, locking, package, planner,
|
builder, cli_assets, config, cross, db, deps, index, install, locking, package, planner,
|
||||||
@@ -63,6 +64,7 @@ fn command_rootfs(command: &Commands) -> Option<&Path> {
|
|||||||
Commands::Repo(args) => Some(repo_command_rootfs(&args.command)),
|
Commands::Repo(args) => Some(repo_command_rootfs(&args.command)),
|
||||||
Commands::Config(args) => Some(&args.rootfs_args.rootfs),
|
Commands::Config(args) => Some(&args.rootfs_args.rootfs),
|
||||||
Commands::Check(_)
|
Commands::Check(_)
|
||||||
|
| Commands::Convert(_)
|
||||||
| Commands::GenerateArtifacts(_)
|
| Commands::GenerateArtifacts(_)
|
||||||
| Commands::MakeSpec(_)
|
| Commands::MakeSpec(_)
|
||||||
| Commands::Internal(_) => None,
|
| Commands::Internal(_) => None,
|
||||||
@@ -76,6 +78,7 @@ fn command_assume_yes(command: &Commands) -> bool {
|
|||||||
Commands::Build(args) => args.prompt_args.yes,
|
Commands::Build(args) => args.prompt_args.yes,
|
||||||
Commands::Update(args) => args.prompt_args.yes,
|
Commands::Update(args) => args.prompt_args.yes,
|
||||||
Commands::Check(_)
|
Commands::Check(_)
|
||||||
|
| Commands::Convert(_)
|
||||||
| Commands::Info(_)
|
| Commands::Info(_)
|
||||||
| Commands::Search(_)
|
| Commands::Search(_)
|
||||||
| Commands::Owns(_)
|
| Commands::Owns(_)
|
||||||
@@ -4669,6 +4672,7 @@ pub fn run(cli: Cli) -> Result<()> {
|
|||||||
| Commands::Repo(_)
|
| Commands::Repo(_)
|
||||||
| Commands::Config(_)
|
| Commands::Config(_)
|
||||||
| Commands::GenerateArtifacts(_)
|
| Commands::GenerateArtifacts(_)
|
||||||
|
| Commands::Convert(_)
|
||||||
| Commands::MakeSpec(_)
|
| Commands::MakeSpec(_)
|
||||||
| Commands::Internal(_) => false,
|
| Commands::Internal(_) => false,
|
||||||
};
|
};
|
||||||
@@ -5901,6 +5905,58 @@ pub fn run(cli: Cli) -> Result<()> {
|
|||||||
output_path.display()
|
output_path.display()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Commands::Convert(ConvertArgs { input, output }) => {
|
||||||
|
let converted = package::convert_starbuild_file(&input, output.as_deref())?;
|
||||||
|
let mut outputs = vec![converted.output_path.clone()];
|
||||||
|
if let Some(build_script_path) = &converted.build_script_path {
|
||||||
|
outputs.push(build_script_path.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let existing: Vec<_> = outputs
|
||||||
|
.iter()
|
||||||
|
.filter(|path| path.exists())
|
||||||
|
.map(|path| path.display().to_string())
|
||||||
|
.collect();
|
||||||
|
if !existing.is_empty() {
|
||||||
|
ui::warn(format!(
|
||||||
|
"Generated files already exist: {}",
|
||||||
|
existing.join(", ")
|
||||||
|
));
|
||||||
|
if !ui::prompt_yes_no("Overwrite them?", false)? {
|
||||||
|
anyhow::bail!("Aborted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::write(&converted.output_path, converted.toml)
|
||||||
|
.with_context(|| format!("Failed to write {}", converted.output_path.display()))?;
|
||||||
|
if let (Some(build_script), Some(build_script_path)) =
|
||||||
|
(converted.build_script, converted.build_script_path)
|
||||||
|
{
|
||||||
|
fs::write(&build_script_path, build_script)
|
||||||
|
.with_context(|| format!("Failed to write {}", build_script_path.display()))?;
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
let mut perms = fs::metadata(&build_script_path)
|
||||||
|
.with_context(|| format!("Failed to stat {}", build_script_path.display()))?
|
||||||
|
.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
|
fs::set_permissions(&build_script_path, perms).with_context(|| {
|
||||||
|
format!("Failed to chmod {}", build_script_path.display())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
ui::success(format!(
|
||||||
|
"Converted STARBUILD into {} and {}",
|
||||||
|
converted.output_path.display(),
|
||||||
|
build_script_path.display()
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
ui::success(format!(
|
||||||
|
"Converted STARBUILD into {}",
|
||||||
|
converted.output_path.display()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
Commands::Internal(args) => {
|
Commands::Internal(args) => {
|
||||||
let command = args.command;
|
let command = args.command;
|
||||||
run_internal_command(command)?;
|
run_internal_command(command)?;
|
||||||
|
|||||||
@@ -1544,6 +1544,107 @@ pub fn spec_to_minimal_toml(spec: &PackageSpec) -> anyhow::Result<String> {
|
|||||||
root.insert("dependencies".into(), Value::Table(dep_tbl));
|
root.insert("dependencies".into(), Value::Table(dep_tbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !spec.package_dependencies.is_empty() {
|
||||||
|
let mut outputs_tbl = Table::new();
|
||||||
|
for (pkg_name, deps) in &spec.package_dependencies {
|
||||||
|
let mut dep_tbl = Table::new();
|
||||||
|
if !deps.build.is_empty() {
|
||||||
|
dep_tbl.insert(
|
||||||
|
"build".into(),
|
||||||
|
Value::Array(
|
||||||
|
deps.build
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !deps.runtime.is_empty() {
|
||||||
|
dep_tbl.insert(
|
||||||
|
"runtime".into(),
|
||||||
|
Value::Array(
|
||||||
|
deps.runtime
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !deps.test.is_empty() {
|
||||||
|
dep_tbl.insert(
|
||||||
|
"test".into(),
|
||||||
|
Value::Array(deps.test.iter().map(|s| Value::String(s.clone())).collect()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !deps.optional.is_empty() {
|
||||||
|
dep_tbl.insert(
|
||||||
|
"optional".into(),
|
||||||
|
Value::Array(
|
||||||
|
deps.optional
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !dep_tbl.is_empty() {
|
||||||
|
outputs_tbl.insert(pkg_name.clone(), Value::Table(dep_tbl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !outputs_tbl.is_empty() {
|
||||||
|
root.insert("package_dependencies".into(), Value::Table(outputs_tbl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !spec.package_alternatives.is_empty() {
|
||||||
|
let mut outputs_tbl = Table::new();
|
||||||
|
for (pkg_name, alternatives) in &spec.package_alternatives {
|
||||||
|
let mut alt_tbl = Table::new();
|
||||||
|
if !alternatives.provides.is_empty() {
|
||||||
|
alt_tbl.insert(
|
||||||
|
"provides".into(),
|
||||||
|
Value::Array(
|
||||||
|
alternatives
|
||||||
|
.provides
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !alternatives.conflicts.is_empty() {
|
||||||
|
alt_tbl.insert(
|
||||||
|
"conflicts".into(),
|
||||||
|
Value::Array(
|
||||||
|
alternatives
|
||||||
|
.conflicts
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !alternatives.replaces.is_empty() {
|
||||||
|
alt_tbl.insert(
|
||||||
|
"replaces".into(),
|
||||||
|
Value::Array(
|
||||||
|
alternatives
|
||||||
|
.replaces
|
||||||
|
.iter()
|
||||||
|
.map(|s| Value::String(s.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !alt_tbl.is_empty() {
|
||||||
|
outputs_tbl.insert(pkg_name.clone(), Value::Table(alt_tbl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !outputs_tbl.is_empty() {
|
||||||
|
root.insert("package_alternatives".into(), Value::Table(outputs_tbl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(toml::to_string_pretty(&Value::Table(root))?)
|
Ok(toml::to_string_pretty(&Value::Table(root))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
mod interactive;
|
mod interactive;
|
||||||
mod packager;
|
mod packager;
|
||||||
mod spec;
|
mod spec;
|
||||||
|
mod starbuild;
|
||||||
|
|
||||||
pub use interactive::*;
|
pub use interactive::*;
|
||||||
pub use packager::Packager;
|
pub use packager::Packager;
|
||||||
pub use spec::*;
|
pub use spec::*;
|
||||||
|
pub(crate) use starbuild::*;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ use sha2::{Digest, Sha256};
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::fs as unix_fs;
|
use std::os::unix::fs as unix_fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
@@ -418,6 +419,20 @@ fn prepare_one(
|
|||||||
|
|
||||||
// Treat `<url>#<rev>` and bare `*.git` sources as git before local file://
|
// Treat `<url>#<rev>` and bare `*.git` sources as git before local file://
|
||||||
// handling so `file://...repo.git#tag` resolves through the git checkout path.
|
// handling so `file://...repo.git#tag` resolves through the git checkout path.
|
||||||
|
if let Some((base, rev)) = split_hg_url(&url) {
|
||||||
|
let checkout_dir = build_dir.join(&extract_dir_name);
|
||||||
|
if checkout_dir.exists() && checkout_dir.join(".depot_state").exists() {
|
||||||
|
crate::log_info!(
|
||||||
|
"Resuming build in existing hg directory: {}",
|
||||||
|
checkout_dir.display()
|
||||||
|
);
|
||||||
|
return Ok(checkout_dir);
|
||||||
|
}
|
||||||
|
checkout_hg(&base, &rev, &checkout_dir)?;
|
||||||
|
hooks::post_extract(spec, source, &checkout_dir, cache_dir)?;
|
||||||
|
return Ok(checkout_dir);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((base, rev)) = split_git_url(&url) {
|
if let Some((base, rev)) = split_git_url(&url) {
|
||||||
let checkout_dir = build_dir.join(&extract_dir_name);
|
let checkout_dir = build_dir.join(&extract_dir_name);
|
||||||
if checkout_dir.exists() && checkout_dir.join(".depot_state").exists() {
|
if checkout_dir.exists() && checkout_dir.join(".depot_state").exists() {
|
||||||
@@ -556,6 +571,45 @@ fn split_git_url(url: &str) -> Option<(String, String)> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_hg_url(url: &str) -> Option<(String, String)> {
|
||||||
|
let rest = url.strip_prefix("hg+")?;
|
||||||
|
if let Some((base, rev)) = rest.split_once('#') {
|
||||||
|
let revision = if rev.trim().is_empty() {
|
||||||
|
"tip"
|
||||||
|
} else {
|
||||||
|
rev.trim()
|
||||||
|
};
|
||||||
|
return Some((base.to_string(), revision.to_string()));
|
||||||
|
}
|
||||||
|
Some((rest.to_string(), "tip".to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn checkout_hg(url: &str, rev: &str, checkout_dir: &Path) -> Result<()> {
|
||||||
|
if checkout_dir.exists() {
|
||||||
|
fs::remove_dir_all(checkout_dir).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to remove existing Mercurial checkout dir: {}",
|
||||||
|
checkout_dir.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::log_info!("Cloning Mercurial source {} @ {}...", url, rev);
|
||||||
|
let mut cmd = Command::new("hg");
|
||||||
|
cmd.arg("clone")
|
||||||
|
.arg("-u")
|
||||||
|
.arg(rev)
|
||||||
|
.arg(url)
|
||||||
|
.arg(checkout_dir);
|
||||||
|
cmd.env("PATH", crate::runtime_env::safe_script_path());
|
||||||
|
let status = crate::interrupts::command_status(&mut cmd)
|
||||||
|
.with_context(|| format!("Failed to run hg clone for {}", url))?;
|
||||||
|
if !status.success() {
|
||||||
|
bail!("Mercurial clone failed for {} @ {}", url, rev);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -755,6 +809,17 @@ mod tests {
|
|||||||
assert_eq!(rev, "0123456789abcdef");
|
assert_eq!(rev, "0123456789abcdef");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn split_hg_url_accepts_revision_and_default_tip() {
|
||||||
|
let (base, rev) = split_hg_url("hg+https://hg.example.test/repo#v1").unwrap();
|
||||||
|
assert_eq!(base, "https://hg.example.test/repo");
|
||||||
|
assert_eq!(rev, "v1");
|
||||||
|
|
||||||
|
let (base, rev) = split_hg_url("hg+https://hg.example.test/repo").unwrap();
|
||||||
|
assert_eq!(base, "https://hg.example.test/repo");
|
||||||
|
assert_eq!(rev, "tip");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prepare_one_rejects_cherry_pick_for_non_git_sources() {
|
fn prepare_one_rejects_cherry_pick_for_non_git_sources() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user