feat: Implement build state tracking and interactive package specification creation
- Added StateTracker to manage build steps and allow resuming interrupted builds. - Updated post_extract function to utilize StateTracker for patch and command execution. - Introduced makefile.rs to handle building and installing packages via Makefile. - Created interactive.rs for an interactive package specification creator with SHA256 computation for source URLs. - Enhanced checksum verification to support multiple algorithms (SHA256, SHA512, MD5). - Added example configuration files in contrib for system-wide and user-level Depot configurations. - Updated tests to cover new functionality and ensure correctness of state tracking and interactive creation.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
//! Build state tracking to allow resuming interrupted builds.
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum BuildStep {
|
||||
PatchesApplied,
|
||||
PostExtractDone,
|
||||
Configured,
|
||||
PostCompileDone,
|
||||
PostInstallDone,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
struct State {
|
||||
completed_steps: HashSet<BuildStep>,
|
||||
}
|
||||
|
||||
pub struct StateTracker {
|
||||
state_file: PathBuf,
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl StateTracker {
|
||||
pub fn new(source_dir: &Path) -> Result<Self> {
|
||||
let state_file = source_dir.join(".depot_state");
|
||||
let state = if state_file.exists() {
|
||||
let content = fs::read_to_string(&state_file)?;
|
||||
toml::from_str(&content).unwrap_or_default()
|
||||
} else {
|
||||
State::default()
|
||||
};
|
||||
|
||||
Ok(Self { state_file, state })
|
||||
}
|
||||
|
||||
pub fn is_done(&self, step: BuildStep) -> bool {
|
||||
self.state.completed_steps.contains(&step)
|
||||
}
|
||||
|
||||
pub fn mark_done(&mut self, step: BuildStep) -> Result<()> {
|
||||
self.state.completed_steps.insert(step);
|
||||
self.save()
|
||||
}
|
||||
|
||||
fn save(&self) -> Result<()> {
|
||||
let content = toml::to_string_pretty(&self.state)?;
|
||||
fs::write(&self.state_file, content)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[test]
|
||||
fn test_state_tracker_init() -> Result<()> {
|
||||
let dir = tempdir()?;
|
||||
let tracker = StateTracker::new(dir.path())?;
|
||||
assert!(!tracker.state_file.exists());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mark_done_and_persistence() -> Result<()> {
|
||||
let dir = tempdir()?;
|
||||
let mut tracker = StateTracker::new(dir.path())?;
|
||||
|
||||
assert!(!tracker.is_done(BuildStep::Configured));
|
||||
tracker.mark_done(BuildStep::Configured)?;
|
||||
assert!(tracker.is_done(BuildStep::Configured));
|
||||
|
||||
// Check file exists
|
||||
assert!(tracker.state_file.exists());
|
||||
|
||||
// Reload
|
||||
let tracker2 = StateTracker::new(dir.path())?;
|
||||
assert!(tracker2.is_done(BuildStep::Configured));
|
||||
assert!(!tracker2.is_done(BuildStep::PostCompileDone));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user