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 87 88 89 90 91 92 93 94 95 96
use crate::{ data::build_plan::BuildPlan, platform::{GenericPlatform, Platform}, shared::write_toml_file, }; use std::{ env, path::{Path, PathBuf}, process, }; pub fn cnb_runtime_detect< P: Platform, E: std::fmt::Display, F: FnOnce(DetectContext<P>) -> Result<DetectOutcome, E>, >( detect_fn: F, ) { let app_dir = env::current_dir().expect("Could not determine current working directory!"); let buildpack_dir = env::var("CNB_BUILDPACK_DIR") .expect("Could not determine buildpack directory!") .into(); let args: Vec<String> = env::args().collect(); if args.len() != 3 { eprintln!("Usage: detect <platform_dir> <buildplan>"); process::exit(1); } let platform = { let platform_dir = PathBuf::from(args.get(1).unwrap()); if !platform_dir.is_dir() { eprintln!("First argument must be a readable platform directory!"); process::exit(1); } match P::from_path(platform_dir.as_path()) { Ok(platform) => platform, Err(error) => { eprintln!( "Could not create platform from platform directory: {}", error ); process::exit(1); } } }; let build_plan_path: PathBuf = PathBuf::from(args.get(2).unwrap()); let detect_context = DetectContext { app_dir, buildpack_dir, platform, }; match detect_fn(detect_context) { Ok(DetectOutcome::Fail) | Err(_) => process::exit(100), Ok(DetectOutcome::Error(code)) => process::exit(code), Ok(DetectOutcome::Pass(build_plan)) => { if let Err(error) = write_toml_file(&build_plan, build_plan_path) { eprintln!("Could not write buildplan to disk: {}", error); process::exit(1); } process::exit(0) } }; } pub struct DetectContext<P: Platform> { app_dir: PathBuf, buildpack_dir: PathBuf, pub platform: P, } impl<P: Platform> DetectContext<P> { pub fn app_dir(&self) -> &Path { self.app_dir.as_path() } pub fn buildpack_dir(&self) -> &Path { self.buildpack_dir.as_path() } } pub type GenericDetectContext = DetectContext<GenericPlatform>; #[derive(Debug)] pub enum DetectOutcome { Pass(BuildPlan), Fail, Error(i32), }