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
#[macro_use] extern crate lazy_static; extern crate ansi_term; mod engine; mod id; mod parse_args; mod prop; mod recur; mod render; mod tag; mod task; use crate::id::Id; use crate::parse_args::parse_cli_args; use crate::render::render_table; use crate::task::Task; use chrono::prelude::*; use serde_json; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::path::Path; use std::process::Command; use std::{env, fs}; const ENV_VAR_SHELL: &str = "SHELL"; const ENV_VAR_DIR_NAME: &str = "HYPERTASK_DIR"; const ENV_VAR_AFTER_HOOK: &str = "HYPERTASK_AFTER"; fn get_tasks() -> impl Iterator<Item = Result<Task, String>> { let hyper_cortex_dir = env::var(ENV_VAR_DIR_NAME) .expect(format!("environment variable {} is unset", ENV_VAR_DIR_NAME).as_str()); let paths = fs::read_dir(&hyper_cortex_dir) .expect(format!("folder {} could not be found", hyper_cortex_dir.to_string()).as_str()); paths.map(|path| { path.map_err(|_| "Failed to open task".to_string()) .and_then(|file_path| { File::open(file_path.path()) .map_err(|_| format!("failed to open task `{:?}`", file_path)) .and_then(|file| { serde_json::from_reader(BufReader::new(file)) .map_err(|_| format!("failed to parse task `{:?}`", file_path)) }) }) }) } fn put_task(task: &Task) -> Result<(), String> { let Id(task_id) = task.get_id(); let hyper_cortex_dir = env::var(ENV_VAR_DIR_NAME) .expect(format!("environment variable {} is unset", ENV_VAR_DIR_NAME).as_str()); let file_path = Path::new(&hyper_cortex_dir).join(task_id); let file = File::create(file_path).expect("Unable to create file"); let buf_writer = BufWriter::new(file); serde_json::to_writer_pretty(buf_writer, &task) .expect(format!("could not output task {:?}", &task).as_str()); if let (Ok(shell), Ok(after_cmd)) = (env::var(ENV_VAR_SHELL), env::var(ENV_VAR_AFTER_HOOK)) { Command::new(shell) .arg("-c") .arg(after_cmd) .output() .expect("Failed to execute command"); } Ok(()) } pub fn run_cli(_get_now: &Fn() -> DateTime<Utc>, args: &Vec<String>) -> Result<(), String> { let tasks_iterator = get_tasks(); let engine = parse_cli_args(args.iter().skip(1))?; let tasks_to_display = engine.run(tasks_iterator, &put_task); render_table(&tasks_to_display); Ok(()) }