Skip to content

Commit

Permalink
sbuild: support custom outdir, timeout and debug mode
Browse files Browse the repository at this point in the history
  • Loading branch information
QaidVoid committed Jan 9, 2025
1 parent ffe3ea9 commit 0fd4e14
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 35 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,17 @@ Arguments:

## sbuilder

TODO
```sh
Usage: sbuild [OPTIONS] [FILES]

A builder for SBUILD package files.

Options:
--help, -h Show this help message
--debug, -d Execute build scripts in debug mode
--outdir, -o <PATH> Directory to store the build files in
--timeout <DURATION> Timeout duration after which the pkgver check exits

Arguments:
FILE... One or more package files to build
```
16 changes: 15 additions & 1 deletion sbuild-linter/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
io::Write,
path::{Path, PathBuf},
sync::{mpsc::Sender, Arc, Mutex},
time::Instant,
};

pub enum LogMessage {
Expand Down Expand Up @@ -46,6 +47,7 @@ impl LogManager {
TaskLogger {
sender: self.sender.clone(),
file,
start_time: Instant::now(),
}
}
}
Expand All @@ -54,6 +56,7 @@ impl LogManager {
pub struct TaskLogger {
sender: Sender<LogMessage>,
file: Option<Arc<Mutex<LogFile>>>,
start_time: Instant,
}

struct LogFile {
Expand All @@ -62,9 +65,20 @@ struct LogFile {
}

impl TaskLogger {
fn write_to_file(&self, msg: &str) {
pub fn write_to_file(&self, msg: impl Into<String>) {
let msg = msg.into();
if let Some(file) = &self.file {
if let Ok(mut file_guard) = file.lock() {
let elapsed = self.start_time.elapsed();

let total_seconds = elapsed.as_secs();
let minutes = total_seconds / 60;
let seconds = total_seconds % 60;
let milliseconds = (elapsed.subsec_millis()) as u64;

let timestamp = format!("[{:02}:{:02}.{:03}]", minutes, seconds, milliseconds);

let msg = format!("{} {}", timestamp, msg);
let _ = writeln!(file_guard.file, "{}", msg);
}
}
Expand Down
1 change: 1 addition & 0 deletions sbuild/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ keywords.workspace = true

[dependencies]
blake3 = "1.5.5"
chrono = { version = "0.4.39", default-features = false, features = ["now"] }
colored = "2.1.0"
futures = "0.3.31"
goblin = { version = "0.9.2", features = ["elf64", "elf32", "endian_fd", "std"] }
Expand Down
94 changes: 66 additions & 28 deletions sbuild/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
},
fs::{self, File},
io::{BufRead, BufReader},
path::Path,
path::{Path, PathBuf},
process::{Child, Command, Stdio},
sync::{self, Arc},
thread,
Expand Down Expand Up @@ -35,13 +35,18 @@ pub struct BuildContext {
pkg_type: Option<String>,
sbuild_pkg: String,
entrypoint: String,
outdir: String,
tmpdir: String,
outdir: PathBuf,
tmpdir: PathBuf,
version: String,
}

impl BuildContext {
fn new<P: AsRef<Path>>(build_config: &BuildConfig, cache_path: P, version: String) -> Self {
fn new<P: AsRef<Path>>(
build_config: &BuildConfig,
cache_path: P,
version: String,
outdir: Option<String>,
) -> Self {
let sbuild_pkg = build_config.pkg.clone();
let entrypoint = build_config
.x_exec
Expand All @@ -50,12 +55,23 @@ impl BuildContext {
.map(|e| e.trim_start_matches('/').to_string())
.unwrap_or_else(|| sbuild_pkg.clone());

let outdir = format!(
"{}/sbuild/{}",
cache_path.as_ref().display(),
build_config.pkg_id
);
let tmpdir = format!("{}/SBUILD_TEMP", outdir);
let outdir = outdir
.map(|dir| {
let path = Path::new(&dir);
if path.is_absolute() {
path.to_owned()
} else {
let current_dir = env::current_dir().expect("Failed to get current directory");
current_dir.join(dir).join(&build_config.pkg_id)
}
})
.unwrap_or_else(|| {
cache_path
.as_ref()
.join("sbuild")
.join(&build_config.pkg_id)
});
let tmpdir = outdir.join("SBUILD_TEMP");

Self {
pkg: build_config.pkg.clone(),
Expand Down Expand Up @@ -87,8 +103,8 @@ impl BuildContext {
("pkg_id", self.pkg_id.clone()),
("pkg_type", self.pkg_type.clone().unwrap_or_default()),
("sbuild_pkg", self.sbuild_pkg.clone()),
("sbuild_outdir", self.outdir.clone()),
("sbuild_tmpdir", self.tmpdir.clone()),
("sbuild_outdir", self.outdir.to_string_lossy().to_string()),
("sbuild_tmpdir", self.tmpdir.to_string_lossy().to_string()),
("pkg_ver", self.version.clone()),
]
.into_iter()
Expand Down Expand Up @@ -118,10 +134,11 @@ pub struct Builder {
icon: bool,
appstream: bool,
pkg_type: PackageType,
debug: bool,
}

impl Builder {
pub fn new(logger: TaskLogger, soar_env: SoarEnv, external: bool) -> Self {
pub fn new(logger: TaskLogger, soar_env: SoarEnv, external: bool, debug: bool) -> Self {
Builder {
logger,
soar_env,
Expand All @@ -130,6 +147,7 @@ impl Builder {
icon: false,
appstream: false,
pkg_type: PackageType::Unknown,
debug,
}
}

Expand Down Expand Up @@ -277,10 +295,12 @@ impl Builder {
self.logger.info(&format!("Renamed icon to {}", final_path));
fs::rename(out_path, final_path).unwrap();
} else {
let tmp_path = format!("{}/{}", context.tmpdir, out_path.display());
let tmp_path = context.tmpdir.join(out_path);
fs::rename(&out_path, &tmp_path).unwrap();
self.logger
.warn(&format!("Unsupported icon. Moved to {}", tmp_path));
self.logger.warn(&format!(
"Unsupported icon. Moved to {}",
tmp_path.display()
));
}
} else {
self.logger.warn(&format!(
Expand Down Expand Up @@ -408,7 +428,8 @@ impl Builder {
if !bin_path.exists() {
self.logger.error(format!(
"{} should exist in {} but doesn't.",
context.entrypoint, context.outdir
context.entrypoint,
context.outdir.display()
));
return false;
}
Expand Down Expand Up @@ -452,9 +473,14 @@ impl Builder {
}
}

pub async fn build(&mut self, file_path: &str) -> bool {
pub async fn build(
&mut self,
file_path: &str,
outdir: Option<String>,
timeout: Duration,
) -> bool {
let logger = self.logger.clone();
let linter = Linter::new(logger.clone(), Duration::from_secs(120));
let linter = Linter::new(logger.clone(), timeout);

let pwd = env::current_dir().unwrap();
let mut success = false;
Expand All @@ -478,20 +504,32 @@ impl Builder {
let version = version.unwrap();
let x_exec = &build_config.x_exec;
let pkg_id = &build_config.pkg_id;
let script = format!("#!/usr/bin/env {}\n{}", x_exec.shell, x_exec.run);
let script = format!(
"#!/usr/bin/env {}\n{}\n{}",
x_exec.shell,
if self.debug { "set -x" } else { "" },
x_exec.run
);
let tmp = temp_file(pkg_id, &script);

let context = BuildContext::new(&build_config, &self.soar_env.cache_path, version);
let context =
BuildContext::new(&build_config, &self.soar_env.cache_path, version, outdir);
let _ = fs::remove_dir_all(&context.outdir);
fs::create_dir_all(&context.outdir).unwrap();
let final_version_file =
format!("{}/{}.version", context.outdir, context.sbuild_pkg);
let final_validated_file =
format!("{}/{}.validated", context.outdir, context.sbuild_pkg);
let final_version_file = format!(
"{}/{}.version",
context.outdir.display(),
context.sbuild_pkg
);
let final_validated_file = format!(
"{}/{}.validated",
context.outdir.display(),
context.sbuild_pkg
);
fs::copy(&version_file, &final_version_file).unwrap();
fs::copy(&version_file, &final_validated_file).unwrap();

let log_path = format!("{}/build.log", context.outdir);
let log_path = context.outdir.join("build.log");
logger.move_log_file(log_path).unwrap();

if let Some(ref arch) = x_exec.arch {
Expand Down Expand Up @@ -520,9 +558,9 @@ impl Builder {
.exec(&context, build_config, tmp.to_string_lossy().to_string())
.await;
if success {
logger.success(&format!(
logger.success(format!(
"Successfully built the package at {}",
context.outdir
context.outdir.display()
));
} else {
logger.success(&format!(
Expand Down
60 changes: 55 additions & 5 deletions sbuild/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
Arc, LazyLock,
},
thread,
time::Instant,
time::{Duration, Instant},
};

use colored::Colorize;
Expand All @@ -25,6 +25,9 @@ A builder for SBUILD package files.
Options:
--help, -h Show this help message
--debug, -d Execute build scripts in debug mode
--outdir, -o <PATH> Directory to store the build files in
--timeout <DURATION> Timeout duration after which the pkgver check exits
Arguments:
FILE... One or more package files to build"#
Expand Down Expand Up @@ -68,14 +71,45 @@ async fn main() {
let args: Vec<String> = env::args().collect();

let mut files = Vec::new();
let mut timeout = 120;
let mut outdir = None;
let mut debug = false;

let iter = args.iter().skip(1);
for arg in iter {
let mut iter = args.iter().skip(1);
while let Some(arg) = iter.next() {
match arg.as_str() {
"--debug" | "-d" => {
debug = true;
}
"--help" | "-h" => {
println!("{}", usage());
return;
}
"--outdir" | "-o" => {
if let Some(next) = iter.next() {
if next.starts_with("-") {
eprintln!("Expected dir path. Got flag instead.");
std::process::exit(1);
}
outdir = Some(next);
} else {
eprintln!("outdir path is not provided.");
eprintln!("{}", usage());
std::process::exit(1);
}
}
"--timeout" => {
if let Some(next) = iter.next() {
match next.parse::<usize>() {
Ok(duration) => timeout = duration,
Err(_) => {
eprintln!("Invalid duration: '{}'", next);
eprintln!("{}", usage());
std::process::exit(1);
}
};
}
}
arg => {
if arg.starts_with("--") {
eprintln!("Unknown argument '{}'", arg);
Expand Down Expand Up @@ -140,8 +174,24 @@ async fn main() {
.expect("Failed to create temp file");
let tmp_file_path = named_temp_file.path().to_path_buf();
let logger = log_manager.create_logger(Some(tmp_file_path));
let mut builder = Builder::new(logger.clone(), soar_env.clone(), true);
if builder.build(file_path).await {

let now = chrono::Utc::now();
logger.write_to_file(format!(
"sbuild v{} [{}]",
env!("CARGO_PKG_VERSION"),
now.format("%A, %B %d, %Y %H:%M:%S")
));

let mut builder = Builder::new(logger.clone(), soar_env.clone(), true, debug);

if builder
.build(
file_path,
outdir.cloned(),
Duration::from_secs(timeout as u64),
)
.await
{
success.fetch_add(1, Ordering::SeqCst);
} else {
fail.fetch_add(1, Ordering::SeqCst);
Expand Down

0 comments on commit 0fd4e14

Please sign in to comment.