1extern crate proc_macro;
2
3use proc_macro2::Span;
4use proc_macro_hack::proc_macro_hack;
5use quote::quote;
6use syn::{parse_macro_input, Error, LitStr, Result};
7
8use crate::dir::Dir;
9use std::path::PathBuf;
10
11mod command;
12mod dir;
13mod file;
14
15fn do_it(path: PathBuf) -> Result<Dir> {
16 let parent = path
17 .parent()
18 .ok_or_else(|| Error::new(Span::call_site(), "No Parent Dir"))?;
19
20 if !parent.exists() {
21 return Err(Error::new(
22 Span::call_site(),
23 format!("Folder {} doesnot exist", parent.display()),
24 ));
25 }
26
27 #[cfg(any(not(debug_assertions), feature = "embed"))]
28 {
29 let parent = parent
30 .canonicalize()
31 .map_err(|e| Error::new(Span::call_site(), format!("{}", e)))?;
32 if !parent.join("package.json").exists() {
33 return Err(Error::new(
34 Span::call_site(),
35 format!("Folder {} doenot contain package.json", parent.display()),
36 ));
37 }
38 command::run_command(
39 vec!["npm", "install", "--no-package-lock", "--no-audit"],
40 &parent,
41 )?;
42 command::run_command(vec!["npm", "run", "build"], &parent)?;
43 if !path.exists() {
44 return Err(Error::new(
45 Span::call_site(),
46 format!("Folder {} doesnot exist after build", path.display()),
47 ));
48 }
49 }
50
51 #[cfg(any(not(debug_assertions), feature = "embed"))]
52 let path = path
53 .canonicalize()
54 .map_err(|e| Error::new(Span::call_site(), format!("{}", e)))?;
55
56 Dir::from_disk(path)
57}
58
59#[proc_macro_hack]
60pub fn include_package(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
61 let path = PathBuf::from(parse_macro_input!(input as LitStr).value());
62
63 do_it(path)
64 .map(|dir| {
65 quote! {
66 #dir
67 }
68 })
69 .unwrap_or_else(|error| error.to_compile_error())
70 .into()
71}