Skip to content

Commit 5eb8738

Browse files
committed
Merge branch 'main' into local-npm-registry
2 parents ad64586 + 4dfeb55 commit 5eb8738

File tree

20 files changed

+347
-119
lines changed

20 files changed

+347
-119
lines changed

examples/deploy/deploy.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def deploy_example_python(g: Graph):
8686
dir=None,
8787
prisma_migration=config_params,
8888
disable_artifact_resolution=None,
89+
codegen=None,
8990
)
9091

9192

meta-cli/src/cli/deploy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl Deploy {
146146
auth: node.auth.clone(),
147147
});
148148
ServerStore::set_prefix(node_config.prefix);
149+
ServerStore::set_codegen_flag(deploy.options.codegen);
149150

150151
Ok(Self {
151152
config,

meta-cli/src/cli/gen.rs

Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
22
// SPDX-License-Identifier: MPL-2.0
33

4+
use std::collections::HashMap;
45
use std::{path::PathBuf, sync::Arc};
56

6-
use super::{Action, ConfigArgs, NodeArgs};
7+
use crate::cli::{Action, ConfigArgs, NodeArgs};
78
use crate::{
89
com::store::ServerStore,
910
config::Config,
@@ -13,36 +14,68 @@ use actix::Actor;
1314
use actix_web::dev::ServerHandle;
1415
use anyhow::{bail, Context, Result};
1516
use async_trait::async_trait;
16-
use clap::Parser;
17+
use clap::{Parser, ValueEnum};
1718
use common::typegraph::Typegraph;
1819
use metagen::*;
20+
use serde_json::json;
21+
22+
#[derive(ValueEnum, Debug, Clone)]
23+
enum GeneratorOp {
24+
/// missing module dependencies
25+
Mod,
26+
/// mdk materializer
27+
Mdk,
28+
}
1929

20-
#[derive(Parser, Debug)]
30+
impl From<GeneratorOp> for String {
31+
fn from(op: GeneratorOp) -> String {
32+
match op {
33+
GeneratorOp::Mod => "codegen",
34+
GeneratorOp::Mdk => "mdk_rust",
35+
}
36+
.to_string()
37+
}
38+
}
39+
40+
#[derive(Parser, Debug, Clone)]
2141
pub struct Gen {
2242
#[command(flatten)]
2343
node: NodeArgs,
2444

45+
#[clap(value_enum, default_value_t=GeneratorOp::Mod)]
46+
generator: GeneratorOp,
47+
2548
/// Target typegate (cf config)
2649
#[clap(short, long)]
2750
pub target: Option<String>,
2851

2952
/// Metagen target to generate
3053
#[clap(default_value = "main")]
3154
gen_target: String,
55+
56+
/// Force load a typegraph file
57+
#[clap(short, long)]
58+
file: Option<PathBuf>,
3259
}
3360

3461
#[async_trait]
3562
impl Action for Gen {
3663
async fn run(&self, args: ConfigArgs, server_handle: Option<ServerHandle>) -> Result<()> {
3764
let dir = args.dir()?;
38-
let config = Config::load_or_find(args.config, &dir)?;
65+
let mut config = Config::load_or_find(args.config, &dir)?;
66+
67+
if let Some(file) = &self.file {
68+
config.metagen = Some(dummy_gen_cfg(&self.generator, file));
69+
}
70+
3971
let config = Arc::new(dbg!(config));
4072
let Some(mgen_conf) = &config.metagen else {
4173
anyhow::bail!(
4274
"no metagen section defined in config found at {:?}",
4375
config.path
4476
);
4577
};
78+
4679
let node_config = config.node(&self.node, self.target.as_deref().unwrap_or("dev"));
4780
let node = node_config
4881
.build(&dir)
@@ -55,18 +88,40 @@ impl Action for Gen {
5588
typegate: Arc::new(node),
5689
};
5790

58-
let files = metagen::generate_target(mgen_conf, &self.gen_target, resolver).await?;
59-
let mut set = tokio::task::JoinSet::new();
60-
for (path, file) in files {
61-
set.spawn(async move {
62-
tokio::fs::create_dir_all(path.parent().unwrap()).await?;
63-
tokio::fs::write(path, file).await?;
64-
Ok::<_, tokio::io::Error>(())
65-
});
66-
}
67-
while let Some(res) = set.join_next().await {
68-
res??;
69-
}
91+
match &self.generator {
92+
GeneratorOp::Mod => {
93+
let Some(file) = &self.file else {
94+
anyhow::bail!("no file provided");
95+
};
96+
97+
resolver
98+
.resolve(GeneratorInputOrder::TypegraphFromPath {
99+
path: file.to_owned(),
100+
name: None,
101+
})
102+
.await?;
103+
104+
let responses = ServerStore::get_responses(file)
105+
.context("invalid state, no response received")?;
106+
for (_, res) in responses.iter() {
107+
res.codegen()?
108+
}
109+
}
110+
GeneratorOp::Mdk => {
111+
let files = metagen::generate_target(mgen_conf, &self.gen_target, resolver).await?;
112+
let mut set = tokio::task::JoinSet::new();
113+
for (path, file) in files {
114+
set.spawn(async move {
115+
tokio::fs::create_dir_all(path.parent().unwrap()).await?;
116+
tokio::fs::write(path, file).await?;
117+
Ok::<_, tokio::io::Error>(())
118+
});
119+
}
120+
while let Some(res) = set.join_next().await {
121+
res??;
122+
}
123+
}
124+
};
70125

71126
server_handle.unwrap().stop(true).await;
72127

@@ -172,3 +227,21 @@ async fn load_tg_at(
172227

173228
Ok(tg)
174229
}
230+
231+
fn dummy_gen_cfg(generator: &GeneratorOp, file: &PathBuf) -> metagen::Config {
232+
let mut targets = HashMap::new();
233+
targets.insert(
234+
generator.clone().into(),
235+
json!({
236+
"typegraph_path": file,
237+
"path": "./mats/gen",
238+
"annotate_debug": false,
239+
}),
240+
);
241+
242+
let target = metagen::Target(targets);
243+
let mut targets = HashMap::new();
244+
targets.insert("main".to_string(), target);
245+
246+
metagen::Config { targets }
247+
}

meta-cli/src/codegen/deno.rs

Lines changed: 111 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub struct Codegen<'a> {
9191
}
9292

9393
impl<'a> Codegen<'a> {
94-
fn new<P>(tg: &'a Typegraph, path: P) -> Self
94+
pub fn new<P>(tg: &'a Typegraph, path: P) -> Self
9595
where
9696
P: AsRef<Path>,
9797
{
@@ -145,6 +145,18 @@ impl<'a> Codegen<'a> {
145145
}
146146
}
147147

148+
pub fn apply_codegen(self) -> Result<()> {
149+
let modules = self.codegen()?;
150+
for ModuleCode { path, code } in modules.iter() {
151+
if let Some(parent) = path.parent() {
152+
fs::create_dir_all(parent)
153+
.with_context(|| format!("Error creating directory {}", parent.display()))?;
154+
}
155+
fs::write(path, code).with_context(|| format!("Error generating {}", path.display()))?
156+
}
157+
Ok(())
158+
}
159+
148160
fn codegen(mut self) -> Result<Vec<ModuleCode>> {
149161
let mut gen_list = vec![];
150162

@@ -462,69 +474,101 @@ impl IntoJson for HashMap<String, Value> {
462474
}
463475
}
464476

465-
// #[cfg(test)]
466-
// mod tests {
467-
// use std::sync::Arc;
468-
469-
// use normpath::PathExt;
470-
// use pathdiff::diff_paths;
471-
// use tokio::sync::mpsc;
472-
473-
// use super::*;
474-
// use crate::config::Config;
475-
// use crate::deploy::actors::console::ConsoleActor;
476-
// use crate::deploy::actors::loader::{LoadModule, LoaderActor, LoaderEvent};
477-
// use crate::tests::utils::ensure_venv;
478-
// use actix::prelude::*;
479-
480-
// #[actix::test(flavor = "multi_thread")]
481-
// async fn codegen() -> Result<()> {
482-
// crate::logger::init();
483-
// ensure_venv()?;
484-
// let test_folder = Path::new("./src/tests/typegraphs").normalize()?;
485-
// std::env::set_current_dir(&test_folder)?;
486-
// let tests = fs::read_dir(&test_folder).unwrap();
487-
// let config = Config::default_in(".");
488-
// let config = Arc::new(config);
489-
490-
// for typegraph_test in tests {
491-
// let typegraph_test = typegraph_test.unwrap().path();
492-
// let typegraph_test = diff_paths(&typegraph_test, &test_folder).unwrap();
493-
494-
// let console = ConsoleActor::new(Arc::clone(&config)).start();
495-
// let (event_tx, event_rx) = mpsc::unbounded_channel();
496-
// let loader = LoaderActor::new(Arc::clone(&config), console, event_tx, 1)
497-
// .auto_stop()
498-
// .start();
499-
// loader.do_send(LoadModule(
500-
// test_folder
501-
// .join(&typegraph_test)
502-
// .as_path()
503-
// .to_owned()
504-
// .into(),
505-
// ));
506-
507-
// let mut event_rx = event_rx;
508-
// // let tg = match event_rx.recv().await.unwrap() {
509-
// // LoaderEvent::Typegraph(tg) => tg,
510-
// // evt => bail!("unexpected loader evt: {evt:?}"),
511-
// // };
512-
513-
// // TODO:
514-
// // run typegraph! thenget serialized version
515-
516-
// // let module_codes = Codegen::new(&tg, &typegraph_test).codegen()?;
517-
// // assert_eq!(module_codes.len(), 1);
518-
519-
// // let test_name = typegraph_test.to_string_lossy().to_string();
520-
// // insta::assert_snapshot!(test_name, &module_codes[0].code);
521-
522-
// assert!(matches!(
523-
// event_rx.recv().await,
524-
// Some(LoaderEvent::Stopped(_))
525-
// ));
526-
// }
527-
528-
// Ok(())
529-
// }
530-
// }
477+
#[cfg(test)]
478+
mod tests {
479+
use std::sync::Arc;
480+
481+
use futures::try_join;
482+
use futures::FutureExt;
483+
use normpath::PathExt;
484+
use pathdiff::diff_paths;
485+
use tokio::sync::mpsc;
486+
487+
use super::*;
488+
use crate::com::server::init_server;
489+
use crate::com::store::ServerStore;
490+
491+
use crate::com::store::Command;
492+
use crate::config::Config;
493+
use crate::deploy::actors::console::ConsoleActor;
494+
use crate::deploy::actors::loader::{LoadModule, LoaderActor, LoaderEvent};
495+
use crate::tests::utils::ensure_venv;
496+
use actix::prelude::*;
497+
498+
#[actix::test(flavor = "multi_thread")]
499+
async fn codegen() -> Result<()> {
500+
crate::logger::init();
501+
ensure_venv()?;
502+
let test_folder = Path::new("./src/tests/typegraphs").normalize()?;
503+
std::env::set_current_dir(&test_folder)?;
504+
let tests = fs::read_dir(&test_folder).unwrap();
505+
let config = Config::default_in(".");
506+
let config = Arc::new(config);
507+
508+
for typegraph_test in tests {
509+
let typegraph_test = typegraph_test.unwrap().path();
510+
let typegraph_test = diff_paths(&typegraph_test, &test_folder).unwrap();
511+
512+
let console = ConsoleActor::new(Arc::clone(&config)).start();
513+
let (event_tx, event_rx) = mpsc::unbounded_channel();
514+
let loader = LoaderActor::new(Arc::clone(&config), console, event_tx, 1)
515+
.auto_stop()
516+
.start();
517+
518+
let server = init_server()?;
519+
let server_handle = server.handle();
520+
521+
ServerStore::with(Some(Command::Serialize), Some(config.as_ref().clone()));
522+
ServerStore::set_codegen_flag(true); // !
523+
524+
let test_scope = async {
525+
loader.do_send(LoadModule(
526+
test_folder
527+
.join(&typegraph_test)
528+
.as_path()
529+
.to_owned()
530+
.into(),
531+
));
532+
533+
let mut event_rx = event_rx;
534+
let tg = match event_rx.recv().await.unwrap() {
535+
LoaderEvent::Typegraph(tg_infos) => {
536+
let (_name, res) = tg_infos
537+
.get_responses_or_fail()?
538+
.as_ref()
539+
.clone()
540+
.into_iter()
541+
.next()
542+
.unwrap();
543+
res.as_typegraph()? // !
544+
}
545+
evt => bail!("unexpected loader evt: {evt:?}"),
546+
};
547+
server_handle.stop(true).await;
548+
549+
let module_codes = Codegen::new(&tg, &typegraph_test).codegen()?;
550+
assert_eq!(module_codes.len(), 1);
551+
552+
let test_name = typegraph_test.to_string_lossy().to_string();
553+
insta::assert_snapshot!(test_name, &module_codes[0].code);
554+
555+
assert!(matches!(
556+
event_rx.recv().await,
557+
Some(LoaderEvent::Stopped(_))
558+
));
559+
560+
Ok(())
561+
};
562+
563+
match try_join!(server.map(|_| Ok(())), test_scope) {
564+
Ok(((), ())) => {}
565+
Err(e) => {
566+
server_handle.stop(true).await;
567+
panic!("{}", e)
568+
}
569+
};
570+
}
571+
572+
Ok(())
573+
}
574+
}

0 commit comments

Comments
 (0)