From 850e80b26c4a2d07e98eb1e73de74ae9b2bdd17f Mon Sep 17 00:00:00 2001 From: Able <abl3theabove@gmail.com> Date: Wed, 19 Mar 2025 17:18:05 -0500 Subject: [PATCH] rlbuild --- rlbuild/src/environ/old.rs | 70 ++++++- rlbuild/src/environ/pkg_environ.rs | 173 ++++++++++++++++++ rlbuild/src/packages.rs | 34 ++-- .../horizon_testing_program/src/main.hb | 2 +- sysdata/programs/render_example/src/main.hb | 2 +- sysdata/programs/rlbuild_test/README.md | 1 + sysdata/programs/rlbuild_test/meta.rl | 9 + sysdata/programs/rlbuild_test/src/main.hb | 3 + sysdata/system.rl | 5 + sysdata/system_config.toml | 4 +- 10 files changed, 283 insertions(+), 20 deletions(-) create mode 100644 rlbuild/src/environ/pkg_environ.rs create mode 100644 sysdata/programs/rlbuild_test/README.md create mode 100644 sysdata/programs/rlbuild_test/meta.rl create mode 100644 sysdata/programs/rlbuild_test/src/main.hb diff --git a/rlbuild/src/environ/old.rs b/rlbuild/src/environ/old.rs index b76948c..74a5337 100644 --- a/rlbuild/src/environ/old.rs +++ b/rlbuild/src/environ/old.rs @@ -163,14 +163,76 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { let path = format!("out/programs/{}/src", pkg_name_str); fs::create_dir_all(path).unwrap(); + // If package is from :src repo, copy source files + if repo_name.to_string() == ":src" { + // Try original name first + let src_path = format!("sysdata/programs/{}", pkg_name_str); + println!("Checking source path: {}", src_path); + + // If not found, try with dashes converted to underscores + let underscored_name = pkg_name_str.replace('-', "_"); + let src_path_alt = format!("sysdata/programs/{}", underscored_name); + + let (found_path, found_name) = if fs::metadata(&src_path).is_ok() { + (src_path, pkg_name_str.clone()) + } else if fs::metadata(&src_path_alt).is_ok() { + println!("Found source directory with underscored name at {}", src_path_alt); + (src_path_alt, underscored_name) + } else { + return Err(RispError::Reason(format!( + "Source directory not found for package {} at {} or {}", + pkg_name_str, src_path, src_path_alt + ))); + }; + + println!("Found source directory at {}", found_path); + // Copy all files from src directory + for entry in fs::read_dir(&found_path).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_file() { + let file_name = path.file_name().unwrap().to_str().unwrap(); + let dest_path = format!("out/programs/{}/{}", pkg_name_str, file_name); + println!("Copying {} to {}", path.display(), dest_path); + fs::copy(&path, &dest_path).unwrap(); + } + } + // Copy contents of src directory if it exists + let src_src_path = format!("sysdata/programs/{}/src", found_name); + println!("Checking src directory at {}", src_src_path); + if fs::metadata(&src_src_path).is_ok() { + println!("Found src directory at {}", src_src_path); + for entry in fs::read_dir(&src_src_path).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_file() { + let file_name = path.file_name().unwrap().to_str().unwrap(); + let dest_path = format!("out/programs/{}/src/{}", pkg_name_str, file_name); + println!("Copying {} to {}", path.display(), dest_path); + fs::copy(&path, &dest_path).unwrap(); + } + } + } + + // Check if meta.rl exists in source, if not generate one + let meta_src_path = format!("sysdata/programs/{}/meta.rl", found_name); + let meta_dest_path = format!("out/programs/{}/meta.rl", pkg_name_str); + + if !fs::metadata(&meta_src_path).is_ok() { + println!("Generating meta.rl for {}", pkg_name_str); + let mut file = File::create(&meta_dest_path).unwrap(); + let meta_content = format!( + "(package \"{}\"\n (version 1 0 0)\n :authors (\"\")\n :tags ()\n (deps))\n", + pkg_name_str + ); + file.write_all(meta_content.as_bytes()).unwrap(); + } + } + let path = format!("out/programs/{}/app.axe", pkg_name_str); let mut file = File::create(path).unwrap(); - let _ = file.write_all(b""); - // TODO: build the code with the hblang compiler. - - Ok(Expr::Bool(true)) }), ); diff --git a/rlbuild/src/environ/pkg_environ.rs b/rlbuild/src/environ/pkg_environ.rs new file mode 100644 index 0000000..86a482a --- /dev/null +++ b/rlbuild/src/environ/pkg_environ.rs @@ -0,0 +1,173 @@ +use std::{fs, File}; +use rlisp_library::{Environ, Expr, RispError, parse_eval}; +use crate::packages::{Package, Dependency}; + +pub fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { + // Function to create a package + env.data.insert( + "package".to_string(), + Expr::Func(|args: &[Expr]| -> Result<Expr, RispError> { + if args.len() < 5 { + return Err(RispError::Reason("package requires name, authors, version, dependencies, and build command".to_string())); + } + + let name = match &args[0] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("package name must be a string".to_string())), + }; + + let authors = match &args[1] { + Expr::List(l) => l.iter() + .map(|a| match a { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("authors must be strings".to_string())), + }) + .collect(), + _ => return Err(RispError::Reason("authors must be a list".to_string())), + }; + + let version = match &args[2] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("version must be a string".to_string())), + }; + + let dependencies = match &args[3] { + Expr::List(l) => l.iter() + .map(|d| match d { + Expr::List(dep_list) => { + if dep_list.len() != 2 { + return Err(RispError::Reason("dependency must have source".to_string())); + } + let source = match &dep_list[1] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("dependency source must be a string".to_string())), + }; + Ok(Dependency { source }) + } + _ => Err(RispError::Reason("dependency must be a list".to_string())), + }) + .collect::<Result<Vec<Dependency>, RispError>>()?, + _ => return Err(RispError::Reason("dependencies must be a list".to_string())), + }; + + let build_command = match &args[4] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("build command must be a string".to_string())), + }; + + let package = Package::new(name, authors, version, dependencies, build_command); + + // Store the package in the environment + env.data.insert( + "current_package".to_string(), + Expr::Custom(Box::new(package)) + ); + + Ok(Expr::Bool(true)) + }), + ); + + // Function to get the current package + env.data.insert( + "get-package".to_string(), + Expr::Func(|_args: &[Expr]| -> Result<Expr, RispError> { + match env.data.get("current_package") { + Some(pkg) => Ok(pkg.clone()), + None => Err(RispError::Reason("No package is currently defined".to_string())), + } + }), + ); + + // Package installation function + env.data.insert( + "pkg-install".to_string(), + Expr::Func(|args: &[Expr]| -> Result<Expr, RispError> { + if args.len() != 2 { + return Err(RispError::Reason("pkg-install requires repo name and package name".to_string())); + } + + let repo_name = match &args[0] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("repo name must be a string".to_string())), + }; + + let pkg_name = match &args[1] { + Expr::Str(s) => s.clone(), + _ => return Err(RispError::Reason("package name must be a string".to_string())), + }; + + println!("Installing package {} from repo {}", pkg_name, repo_name); + + // Create package directory structure + let pkg_dir = format!("out/programs/{}", pkg_name); + fs::create_dir_all(&pkg_dir).unwrap(); + fs::create_dir_all(format!("{}/src", pkg_dir)).unwrap(); + + // If package is from :src repo, copy source files + if repo_name == ":src" { + // Try original name first + let src_path = format!("sysdata/programs/{}", pkg_name); + let underscored_name = pkg_name.replace('-', "_"); + let src_path_alt = format!("sysdata/programs/{}", underscored_name); + + let (found_path, found_name) = if fs::metadata(&src_path).is_ok() { + (src_path, pkg_name.clone()) + } else if fs::metadata(&src_path_alt).is_ok() { + println!("Found source directory with underscored name at {}", src_path_alt); + (src_path_alt, underscored_name) + } else { + return Err(RispError::Reason(format!( + "Source directory not found for package {} at {} or {}", + pkg_name, src_path, src_path_alt + ))); + }; + + // Copy all files from source directory + for entry in fs::read_dir(&found_path).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_file() { + let file_name = path.file_name().unwrap().to_str().unwrap(); + let dest_path = format!("{}/{}", pkg_dir, file_name); + println!("Copying {} to {}", path.display(), dest_path); + fs::copy(&path, &dest_path).unwrap(); + } + } + + // Copy contents of src directory if it exists + let src_src_path = format!("sysdata/programs/{}/src", found_name); + if fs::metadata(&src_src_path).is_ok() { + for entry in fs::read_dir(&src_src_path).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_file() { + let file_name = path.file_name().unwrap().to_str().unwrap(); + let dest_path = format!("{}/src/{}", pkg_dir, file_name); + println!("Copying {} to {}", path.display(), dest_path); + fs::copy(&path, &dest_path).unwrap(); + } + } + } + + // Read and evaluate meta.rl directly + let meta_path = format!("sysdata/programs/{}/meta.rl", found_name); + if let Ok(meta_content) = fs::read_to_string(&meta_path) { + println!("Evaluating meta.rl for package {}", pkg_name); + if let Err(e) = parse_eval(&meta_content, &mut env.clone()) { + println!("Warning: Failed to evaluate meta.rl: {}", e); + } + } else { + println!("Warning: No meta.rl found for package {}", pkg_name); + } + + // Create empty app.axe file + let app_path = format!("{}/app.axe", pkg_dir); + File::create(app_path).unwrap(); + } + + Ok(Expr::Bool(true)) + }), + ); + + env +} diff --git a/rlbuild/src/packages.rs b/rlbuild/src/packages.rs index f4e279f..4d7c2e1 100644 --- a/rlbuild/src/packages.rs +++ b/rlbuild/src/packages.rs @@ -1,15 +1,25 @@ -pub enum Origin { - GitRepo(String), - Path(String), - Repo() +#[derive(Debug, Clone)] +pub struct Package { + pub name: String, + pub authors: Vec<String>, + pub version: String, + pub dependencies: Vec<Dependency>, + pub build_command: String, } -pub struct Package { - name: String, - authors: Vec<String>, - tags: Vec<String>, - version: u8, - depends: Vec<(String, String)>, - origin: Origin, +#[derive(Debug, Clone)] +pub struct Dependency { + pub source: String, +} + +impl Package { + pub fn new(name: String, authors: Vec<String>, version: String, dependencies: Vec<Dependency>, build_command: String) -> Self { + Self { + name, + authors, + version, + dependencies, + build_command, + } + } } -impl Package {} diff --git a/sysdata/programs/horizon_testing_program/src/main.hb b/sysdata/programs/horizon_testing_program/src/main.hb index b3a13de..63be2b6 100644 --- a/sysdata/programs/horizon_testing_program/src/main.hb +++ b/sysdata/programs/horizon_testing_program/src/main.hb @@ -29,7 +29,7 @@ main := fn(): int { instance := ignim.instance.void_instance() - // // TODO: recursively follow this https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Instance + // TODO: recursively follow this https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Instance ret := ignim.instance.create_instance(&create_info, 0, &instance) if ret == errors.IncompatibleDriver { log.error("Driver Incompatible with Vulkan") diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb index c3e299f..651f2de 100644 --- a/sysdata/programs/render_example/src/main.hb +++ b/sysdata/programs/render_example/src/main.hb @@ -1 +1 @@ -.{example: main} := @use("./examples/intouch.hb") \ No newline at end of file +.{example: main} := @use("./examples/drag-and-drop.hb") \ No newline at end of file diff --git a/sysdata/programs/rlbuild_test/README.md b/sysdata/programs/rlbuild_test/README.md new file mode 100644 index 0000000..7422ed9 --- /dev/null +++ b/sysdata/programs/rlbuild_test/README.md @@ -0,0 +1 @@ +# rlbuild_test \ No newline at end of file diff --git a/sysdata/programs/rlbuild_test/meta.rl b/sysdata/programs/rlbuild_test/meta.rl new file mode 100644 index 0000000..ad68fa2 --- /dev/null +++ b/sysdata/programs/rlbuild_test/meta.rl @@ -0,0 +1,9 @@ +(package "name" + :authors ("able") + :version "0.1.0" + (depends + (repo-lookup :src "rlbuild-test") + (repo-lookup :src "hblang") + ) + (build "hblang src/main.hb") +) \ No newline at end of file diff --git a/sysdata/programs/rlbuild_test/src/main.hb b/sysdata/programs/rlbuild_test/src/main.hb new file mode 100644 index 0000000..38df4bf --- /dev/null +++ b/sysdata/programs/rlbuild_test/src/main.hb @@ -0,0 +1,3 @@ +main := fn(): int { + return 0 +} \ No newline at end of file diff --git a/sysdata/system.rl b/sysdata/system.rl index 8e5eb7a..051b4e3 100644 --- a/sysdata/system.rl +++ b/sysdata/system.rl @@ -41,6 +41,11 @@ (pkg-install :core :ps2-driver) (pkg-install :core :ata-pio) +(pkg-install :src :rlbuild-test) + + + + ;;;;;;;;;;;;;; ;; SERVICES ;; ;;;;;;;;;;;;;; diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index fd9919f..7cea078 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -44,8 +44,8 @@ path = "boot:///sunset_server.hbf" [boot.limine.ableos.modules.adit] path = "boot:///adit.hbf" -# [boot.limine.ableos.modules.ablefetch] -# path = "boot:///ablefetch.hbf" +[boot.limine.ableos.modules.ablefetch] +path = "boot:///ablefetch.hbf" # [boot.limine.ableos.modules.sketchpad] # path = "boot:///sketchpad.hbf"