2015-07-21 19:23:09 +03:00
extern crate rumblebars ;
extern crate rustc_serialize ;
use std ::env ;
use std ::path ::Path ;
use std ::fs ::{ self , File } ;
2015-07-22 13:32:06 +03:00
use std ::io ::{ Read , Write } ;
2015-07-21 19:23:09 +03:00
use std ::collections ::BTreeMap ;
use rumblebars ::{ Template , EvalContext } ;
use rustc_serialize ::json ::Json ;
static UNITS_DIR : & 'static str = " units " ;
2015-07-22 15:39:45 +03:00
static MAN_DIR : & 'static str = " man " ;
2015-07-21 19:23:09 +03:00
fn main ( ) {
let out_dir = env ::var ( " OUT_DIR " ) . unwrap ( ) ;
let output = Path ::new ( & * out_dir ) ;
2015-07-21 19:39:04 +03:00
let data = build_render_data ( ) ;
2015-07-21 19:23:09 +03:00
2015-07-22 13:42:17 +03:00
let mut config = File ::create ( out_dir . clone ( ) + " /config.rs " ) . unwrap ( ) ;
2015-07-22 15:18:41 +03:00
writeln! ( config , " pub static USERS_CRONTAB_DIR: &'static str = {:?}; " , data [ " statedir " ] . as_string ( ) . unwrap ( ) ) . unwrap ( ) ;
writeln! ( config , " pub static PACKAGE: &'static str = {:?}; " , data [ " package " ] . as_string ( ) . unwrap ( ) ) . unwrap ( ) ;
writeln! ( config , " pub static BIN_DIR: &'static str = {:?}; " , data [ " bindir " ] . as_string ( ) . unwrap ( ) ) . unwrap ( ) ;
writeln! ( config , " pub static LIB_DIR: &'static str = {:?}; " , data [ " libdir " ] . as_string ( ) . unwrap ( ) ) . unwrap ( ) ;
2015-07-21 19:39:04 +03:00
2015-09-26 17:46:57 +03:00
let mut data = Json ::Object ( data ) ;
for schedule in get_required_schedules ( ) {
data . as_object_mut ( ) . unwrap ( ) . insert ( " schedule " . to_owned ( ) , Json ::String ( schedule . clone ( ) ) ) ;
for schedule_unit in [ " target " , " timer " , " service " ] . iter ( ) {
compile_template (
format! ( " {} /cron-schedule. {} .in " , UNITS_DIR , schedule_unit ) ,
output . join ( format! ( " cron- {} . {} " , schedule , schedule_unit ) ) ,
& data ) ;
}
}
2015-07-21 19:39:04 +03:00
2015-07-22 15:39:45 +03:00
compile_templates ( UNITS_DIR , output , & data ) ;
compile_templates ( MAN_DIR , output , & data ) ;
}
2015-09-26 17:46:57 +03:00
fn compile_template < S : AsRef < Path > , T : AsRef < Path > > ( source_file : S , target_file : T , data : & Json ) {
println! ( " compiling from template: {:?} -> {:?} ... " , source_file . as_ref ( ) , target_file . as_ref ( ) ) ;
2015-07-22 15:39:45 +03:00
let ctx = EvalContext ::new ( ) ;
2015-09-26 17:46:57 +03:00
let tmpl = File ::open ( source_file ) . and_then ( | mut file | {
let mut buf = String ::new ( ) ;
file . read_to_string ( & mut buf ) . map ( | _ | Template ::new ( & * buf ) . unwrap ( ) )
} ) . unwrap ( ) ;
tmpl . eval ( data , & mut File ::create ( target_file ) . unwrap ( ) , & ctx ) . unwrap ( ) ;
}
fn compile_templates < P : AsRef < Path > > ( source_dir : & str , output_dir : P , data : & Json ) {
2015-07-22 15:39:45 +03:00
for entry in fs ::read_dir ( source_dir ) . unwrap ( ) {
2015-07-21 19:23:09 +03:00
let entry = entry . unwrap ( ) ;
let name = entry . file_name ( ) . into_string ( ) . unwrap ( ) ;
2015-09-26 17:48:34 +03:00
if name . ends_with ( " .in " ) & & ! name . starts_with ( " cron-schedule. " ) {
2015-07-22 15:39:45 +03:00
let target = output_dir . as_ref ( ) . join ( & name [ .. name . len ( ) - 3 ] ) ;
2015-09-26 17:46:57 +03:00
compile_template ( entry . path ( ) , target , data ) ;
2015-07-22 15:39:45 +03:00
}
2015-07-21 19:23:09 +03:00
}
}
fn build_render_data ( ) -> BTreeMap < String , Json > {
let mut ctx = BTreeMap ::new ( ) ;
let prefix = env ::var ( " PREFIX " ) . unwrap_or_else ( | _ | " /usr/local " . to_owned ( ) ) ;
let package = " systemd-cron " ;
ctx . insert ( " package " . to_owned ( ) , Json ::String ( package . to_owned ( ) ) ) ;
ctx . insert ( " bindir " . to_owned ( ) , Json ::String ( env ::var ( " BIN_DIR " ) . unwrap_or_else ( | _ | prefix . clone ( ) + " /bin " ) ) ) ;
ctx . insert ( " confdir " . to_owned ( ) , Json ::String ( env ::var ( " CONF_DIR " ) . unwrap_or_else ( | _ | prefix . clone ( ) + " /etc " ) ) ) ;
let datadir = env ::var ( " DATA_DIR " ) . unwrap_or_else ( | _ | prefix . clone ( ) + " /share " ) ;
let libdir = env ::var ( " LIB_DIR " ) . unwrap_or_else ( | _ | prefix . clone ( ) + " /lib " ) ;
ctx . insert ( " mandir " . to_owned ( ) , Json ::String ( env ::var ( " MAN_DIR " ) . unwrap_or_else ( | _ | datadir . clone ( ) + " /man " ) ) ) ;
ctx . insert ( " docdir " . to_owned ( ) , Json ::String ( env ::var ( " DOC_DIR " ) . unwrap_or_else ( | _ | datadir . clone ( ) + " /doc/ " + package ) ) ) ;
ctx . insert ( " unitdir " . to_owned ( ) , Json ::String ( env ::var ( " UNIT_DIR " ) . unwrap_or_else ( | _ | libdir . clone ( ) + " /systemd/system " ) ) ) ;
ctx . insert ( " libdir " . to_owned ( ) , Json ::String ( libdir ) ) ;
ctx . insert ( " datadir " . to_owned ( ) , Json ::String ( datadir ) ) ;
ctx . insert ( " prefix " . to_owned ( ) , Json ::String ( prefix ) ) ;
ctx . insert ( " statedir " . to_owned ( ) , Json ::String ( env ::var ( " STATE_DIR " ) . unwrap_or_else ( | _ | " /var/spool/cron " . to_owned ( ) ) ) ) ;
ctx . insert ( " runparts " . to_owned ( ) , Json ::String ( env ::var ( " RUN_PARTS " ) . unwrap_or_else ( | _ | " /usr/bin/run-parts " . to_owned ( ) ) ) ) ;
2015-09-26 17:46:57 +03:00
ctx . insert ( " persistent " . to_owned ( ) , Json ::Boolean ( env ::var ( " CARGO_FEATURE_PERSISTENT " ) . is_ok ( ) ) ) ;
ctx
}
fn get_required_schedules ( ) -> Vec < String > {
2015-07-21 19:23:09 +03:00
let mut schedules = Vec ::new ( ) ;
if env ::var ( " CARGO_FEATURE_SCHED_BOOT " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " boot " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_HOURLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " hourly " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_DAILY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " daily " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_WEEKLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " weekly " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_MONTHLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " monthly " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_YEARLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " yearly " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_MINUTELY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " minutely " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_QUARTERLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " quarterly " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
if env ::var ( " CARGO_FEATURE_SCHED_SEMI_ANNUALLY " ) . is_ok ( ) {
2015-09-26 17:46:57 +03:00
schedules . push ( " semi-annually " . to_owned ( ) ) ;
2015-07-21 19:23:09 +03:00
}
2015-09-26 17:46:57 +03:00
schedules
2015-07-21 19:23:09 +03:00
}