Skip to content

Commit

Permalink
#47: added javascript based settings init
Browse files Browse the repository at this point in the history
  • Loading branch information
joshradin committed Oct 10, 2022
1 parent cb62033 commit 19c3f4e
Show file tree
Hide file tree
Showing 13 changed files with 326 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .idea/runConfigurations/Run_assemble.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions assemble.settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import("assemble/settings.js")

settings.root_project.name = "assemble";
6 changes: 4 additions & 2 deletions crates/assemble/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ name = "assemble"
path = "src/main.rs"

[features]
default = ["yaml"]
default = ["js"]
yaml = ["serde_yaml"]
js = ["rquickjs"]
dump_js = ["js", "rquickjs/dump-atoms", "rquickjs/dump-bytecode", "rquickjs/dump-objects"]

[dependencies]
assemble-core = { version = "0.2.0", path = "../assemble-core", features = ["derive", "text_factory"] }
Expand All @@ -41,6 +43,6 @@ tempfile = "3.3.0"
anyhow = "1.0.65"
libloading = "0.7.3"
parking_lot = "0.12.1"

rquickjs = { version = "0.1.7", optional=true, features=["macro", "rust-alloc"] }


20 changes: 20 additions & 0 deletions crates/assemble/src/build_logic/plugin/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ pub mod languages {
}
}

/// Configure a project using `yaml`
#[cfg(feature = "js")]
#[derive(Debug, Default)]
pub struct JavascriptLang;

#[cfg(feature = "js")]
impl ScriptingLang for JavascriptLang {
fn find_build_script(&self, in_dir: &Path) -> Option<PathBuf> {
None
}

fn build_script_name(&self) -> String {
String::from("assemble.build.js")
}

fn settings_script_name() -> String {
String::from("assemble.settings.js")
}
}

pub struct RustLang;
}

Expand Down
3 changes: 3 additions & 0 deletions crates/assemble/src/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub type ProjectProperties = HashMap<String, Option<String>>;

#[cfg(feature = "yaml")]
pub mod yaml;
#[cfg(feature = "js")]
pub mod js;

mod compile_project;
mod create_cargo_file;
Expand All @@ -43,6 +45,7 @@ mod patch_cargo;
pub const fn builder_type() -> &'static str {
match true {
cfg!(feature = "yaml") => "yaml",
cfg!(feature = "js") => "js",
_ => ""
}
}
Expand Down
114 changes: 114 additions & 0 deletions crates/assemble/src/builders/js.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//! The javascript based builder
use crate::build_logic::plugin::script::languages::JavascriptLang;
use crate::build_logic::plugin::script::ScriptingLang;
use crate::builders::js::error::JavascriptError;
use crate::builders::js::logging::Logger;
use crate::builders::js::types::Settings as JsSettings;
use crate::{BuildConfigurator, BuildLogic};
use assemble_core::prelude::{Assemble, ProjectDescriptor, ProjectError, Settings, SettingsAware};
use parking_lot::RwLock;
use rquickjs::{AsFunction, bind, Function};
use rquickjs::{Class, ClassDef, Context, ContextBuilder, FromJs, IntoJs, Object, Runtime, Value};
use std::path::Path;
use std::pin::Pin;
use std::sync::Arc;

pub mod error;
pub mod logging;
pub mod types;

pub struct JavascriptBuilder {
runtime: Pin<Box<Runtime>>,
context: Context,
}

impl JavascriptBuilder {
/// Creates a new java script builder
pub fn new() -> Self {
let runtime = Pin::new(Box::new(
Runtime::new().expect("couldn't create a js runtime."),
));
let ctxt = Context::full(&*runtime).expect("could not create context");
ctxt.with(|ctx| {
// bind_logging(ctx).expect("could not init logging");
ctx.globals().init_def::<logging::Logger>().unwrap();
ctx.eval::<(), _>(include_str!("js/settings.js")).unwrap();
});
ctxt.with(|ctx| {
// bind_logging(ctx).expect("could not init logging");
ctx.eval::<(), _>(
r"
const logger = new Logger();
",
)
.expect("couldn't init logger");
});
Self {
runtime,
context: ctxt,
}
}

pub fn configure_value<T: for<'js> IntoJs<'js> + for<'js> FromJs<'js> + Clone>(
&self,
var_name: &str,
js_type: &str,
value: &mut T,
path: &Path,
) -> Result<(), rquickjs::Error> {
self.context.with(|ctx| {
let mut as_js_value = value.clone().into_js(ctx)?;
ctx.globals().set("__temp", as_js_value)?;
ctx.eval(format!("const {} = new {}(__temp);", var_name, js_type))?;
ctx.eval_file(path)?;

let value_after = ctx.eval::<T, _>(var_name)?;
// let value_converted = T::from_js(ctx, value_after)?;
*value = value_after;

Ok(())
})
}
}

impl BuildConfigurator for JavascriptBuilder {
type Lang = JavascriptLang;
type Err = JavascriptError;

fn get_build_logic<S: SettingsAware>(&self, settings: &S) -> Result<BuildLogic, Self::Err> {
todo!()
}

fn configure_settings<S: SettingsAware>(&self, setting: &mut S) -> Result<(), Self::Err> {
let settings_file = setting.with_settings(|p| p.settings_file().to_path_buf());
let mut js_settings = JsSettings::default();

self.configure_value("settings", "Settings", &mut js_settings, &settings_file)?;

debug!("js settings: {:#?}", js_settings);
todo!("convert js settings to settings");
Ok(())
}

fn discover<P: AsRef<Path>>(
&self,
path: P,
assemble: &Arc<RwLock<Assemble>>,
) -> Result<Settings, Self::Err> {
let path = path.as_ref();

for path in path.ancestors() {
let script_path = path.join(Self::Lang::settings_script_name());
info!("searching for settings script at: {:?}", script_path);
if script_path.exists() && script_path.is_file() {
let mut settings = Settings::new(assemble, path.to_path_buf(), script_path);
settings.set_build_file_name(JavascriptLang.build_script_name());
info!("found: {:?}", settings.settings_file());
return Ok(settings);
}
}

return Err(JavascriptError::MissingSettingsFile);
}
}
7 changes: 7 additions & 0 deletions crates/assemble/src/builders/js/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[derive(Debug, thiserror::Error)]
pub enum JavascriptError {
#[error("No settings file could be found")]
MissingSettingsFile,
#[error(transparent)]
RQuickJsError(#[from] rquickjs::Error)
}
20 changes: 20 additions & 0 deletions crates/assemble/src/builders/js/logging.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// Create logging binding
use rquickjs::{bind, class_def};

#[bind(object, public)]
#[quickjs(bare)]
mod logger {
pub struct Logger { }

impl Logger {
pub fn new() -> Self {
Self { }
}

pub fn info(&self, string: String) {
info!("{}", string)
}
}
}

27 changes: 27 additions & 0 deletions crates/assemble/src/builders/js/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class ProjectDescriptor {
constructor() {
this.name = "";
}

toString() {
return "ProjectDescriptor"
}
}

class Settings {
constructor() {
this.root_project = new ProjectDescriptor();
}

toString() {
return "Settings"
}

include(path) {

}
}




Loading

0 comments on commit 19c3f4e

Please sign in to comment.