Load tasks from URLs
This commit is contained in:
parent
70f476dcc9
commit
bd6e1d67f9
61
src/task.rs
61
src/task.rs
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use crate::db::{is_executable, read_extension};
|
use crate::db::{is_executable, read_extension, read_or_none};
|
||||||
use crate::dvcs::{Backend, Repo};
|
use crate::dvcs::{Backend, Repo};
|
||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
|
@ -177,16 +177,69 @@ pub fn from_dir(basedir: &Path) -> Result<Vec<Task>, std::io::Error> {
|
||||||
|
|
||||||
pub struct MissingTask(pub String);
|
pub struct MissingTask(pub String);
|
||||||
|
|
||||||
|
/// Contains a mapping of sources to their corresponding tasks
|
||||||
|
pub struct SourceSet {
|
||||||
|
mapping: HashMap<String, Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SourceSet {
|
||||||
|
|
||||||
|
/// Loads a SourceSet from a basedir
|
||||||
|
pub fn from(basedir: &Path) -> Result<SourceSet, std::io::Error> {
|
||||||
|
let source_urls = basedir.read_dir()?.filter_map(|p| {
|
||||||
|
if p.is_err() { return None; } // Skip individual errors
|
||||||
|
let p = p.unwrap().path();
|
||||||
|
let path_str = p.to_str().unwrap();
|
||||||
|
if !path_str.ends_with(".source") {
|
||||||
|
// Filter out non-source files
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
return Some((
|
||||||
|
path_str.trim_end_matches(".source").to_string(), // Task name
|
||||||
|
read_or_none(&p).unwrap() // Source URL
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut sources_map: HashMap<String, Vec<String>> = HashMap::new();
|
||||||
|
for (task, source) in source_urls {
|
||||||
|
if let Some(list) = sources_map.get_mut(&source) {
|
||||||
|
list.push(task.to_string());
|
||||||
|
} else {
|
||||||
|
sources_map.insert(source.clone(), vec!(task.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(SourceSet {
|
||||||
|
mapping: sources_map
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the task names associated with a given source
|
||||||
|
pub fn tasks_for(&self, source: &str) -> Option<Vec<String>> {
|
||||||
|
self.mapping.get(source).map(|x| x.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads a task list from a given base directory, taking only tasks that are in requested list.
|
/// Loads a task list from a given base directory, taking only tasks that are in requested list.
|
||||||
/// Fails if the directory is not readable with std::io::Error, or if a requested task does
|
/// Given tasks can be either a task name or a task URL. This function will panic if the basedir
|
||||||
/// not exist.
|
/// does not exist, or error if a requested task/source does not exist.
|
||||||
pub fn from_dir_and_list(basedir: &Path, list: Vec<String>) -> Result<Vec<Task>, MissingTask> {
|
pub fn from_dir_and_list(basedir: &Path, list: Vec<String>) -> Result<Vec<Task>, MissingTask> {
|
||||||
|
// Safe unwrap because we checked that basedir existed before
|
||||||
|
// or maybe can crash for permission problem? TODO: write tests
|
||||||
|
let sourceset = SourceSet::from(basedir).unwrap();
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = Vec::new();
|
||||||
for t in list {
|
for t in list {
|
||||||
if let Some(task) = Task::from_path(&basedir.join(&t)) {
|
if let Some(task) = Task::from_path(&basedir.join(&t)) {
|
||||||
tasks.push(task);
|
tasks.push(task);
|
||||||
} else {
|
} else {
|
||||||
return Err(MissingTask(t));
|
// Maybe it's not a task name, but a task URL?
|
||||||
|
if let Some(list) = sourceset.tasks_for(&t) {
|
||||||
|
// Hopefully safe unwrap (unless there's a source without a corresponding task?)
|
||||||
|
let task_list = list.iter().map(|t_name| Task::from_path(&basedir.join(&t_name)).unwrap());
|
||||||
|
tasks.extend(task_list);
|
||||||
|
} else {
|
||||||
|
return Err(MissingTask(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(tasks)
|
Ok(tasks)
|
||||||
|
|
Loading…
Reference in New Issue