Skip to content

Commit 65f755e

Browse files
committed
support out of source
1 parent 464dff4 commit 65f755e

File tree

5 files changed

+124
-19
lines changed

5 files changed

+124
-19
lines changed

src/build/compile.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -453,23 +453,43 @@ pub fn compiler_args(
453453
false => vec![],
454454
};
455455

456+
let package_name_arg = vec!["-bs-package-name".to_string(), config.name.to_owned()];
457+
456458
let implementation_args = if is_interface {
457459
debug!("Compiling interface file: {}", &module_name);
458460
vec![]
459461
} else {
460462
debug!("Compiling file: {}", &module_name);
461-
462-
vec![
463-
"-bs-package-name".to_string(),
464-
config.name.to_owned(),
465-
"-bs-package-output".to_string(),
466-
format!(
467-
"{}:{}:{}",
468-
root_config.get_module(),
469-
Path::new(file_path).parent().unwrap().to_str().unwrap(),
470-
root_config.get_suffix()
471-
),
472-
]
463+
let specs = config.get_package_specs();
464+
465+
specs
466+
.iter()
467+
.map(|spec| {
468+
return vec![
469+
"-bs-package-output".to_string(),
470+
format!(
471+
"{}:{}:{}",
472+
root_config.get_module(),
473+
if spec.in_source {
474+
Path::new(file_path)
475+
.parent()
476+
.unwrap()
477+
.to_str()
478+
.unwrap()
479+
.to_string()
480+
} else {
481+
format!(
482+
"lib/{}/{}",
483+
spec.get_out_of_source_dir(),
484+
Path::new(file_path).parent().unwrap().to_str().unwrap()
485+
)
486+
},
487+
root_config.get_suffix()
488+
),
489+
];
490+
})
491+
.flatten()
492+
.collect()
473493
};
474494

475495
vec![
@@ -486,6 +506,7 @@ pub fn compiler_args(
486506
// this is the default
487507
// we should probably parse the right ones from the package config
488508
// vec!["-w".to_string(), "a".to_string()],
509+
package_name_arg,
489510
implementation_args,
490511
// vec![
491512
// "-I".to_string(),
@@ -534,6 +555,7 @@ fn compile_file(
534555
&Some(packages),
535556
build_dev_deps,
536557
);
558+
537559
let to_mjs = Command::new(bsc_path)
538560
.current_dir(helpers::canonicalize_string_path(&build_path_abs.to_owned()).unwrap())
539561
.args(to_mjs_args)

src/build/packages.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ pub fn get_build_path(canonical_path: &str) -> String {
6767
format!("{}/lib/bs", canonical_path)
6868
}
6969

70+
pub fn get_js_path(canonical_path: &str) -> String {
71+
format!("{}/lib/js", canonical_path)
72+
}
73+
74+
pub fn get_es6_path(canonical_path: &str) -> String {
75+
format!("{}/lib/es6", canonical_path)
76+
}
77+
7078
pub fn get_ocaml_build_path(canonical_path: &str) -> String {
7179
format!("{}/lib/ocaml", canonical_path)
7280
}
@@ -80,6 +88,14 @@ impl Package {
8088
get_build_path(&self.path)
8189
}
8290

91+
pub fn get_js_path(&self) -> String {
92+
get_js_path(&self.path)
93+
}
94+
95+
pub fn get_es6_path(&self) -> String {
96+
get_es6_path(&self.path)
97+
}
98+
8399
pub fn get_mlmap_path(&self) -> String {
84100
self.get_build_path()
85101
+ "/"
@@ -590,8 +606,48 @@ pub fn parse_packages(build_state: &mut BuildState) {
590606
}
591607
let build_path_abs = package.get_build_path();
592608
let bs_build_path = package.get_ocaml_build_path();
593-
helpers::create_build_path(&build_path_abs);
594-
helpers::create_build_path(&bs_build_path);
609+
helpers::create_path(&build_path_abs);
610+
helpers::create_path(&bs_build_path);
611+
let root_config = build_state
612+
.get_package(&build_state.root_config_name)
613+
.expect("cannot find root config");
614+
615+
root_config.config.get_package_specs().iter().for_each(|spec| {
616+
if !spec.in_source {
617+
// we don't want to calculate this if we don't have out of source specs
618+
// we do this twice, but we almost never have multiple package specs
619+
// so this optimization is less important
620+
let relative_dirs: AHashSet<PathBuf> = match &package.source_files {
621+
Some(source_files) => source_files
622+
.keys()
623+
.map(|source_file| {
624+
Path::new(source_file)
625+
.parent()
626+
.expect("parent dir not found")
627+
.to_owned()
628+
})
629+
.collect(),
630+
_ => AHashSet::new(),
631+
};
632+
if spec.is_common_js() {
633+
helpers::create_path(&package.get_js_path());
634+
relative_dirs.iter().for_each(|path_buf| {
635+
helpers::create_path_for_path(&Path::join(
636+
&PathBuf::from(package.get_js_path()),
637+
path_buf,
638+
))
639+
})
640+
} else {
641+
helpers::create_path(&package.get_es6_path());
642+
relative_dirs.iter().for_each(|path_buf| {
643+
helpers::create_path_for_path(&Path::join(
644+
&PathBuf::from(package.get_es6_path()),
645+
path_buf,
646+
))
647+
})
648+
}
649+
}
650+
});
595651

596652
package.namespace.to_suffix().iter().for_each(|namespace| {
597653
// generate the mlmap "AST" file for modules that have a namespace configured

src/build/parse.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,7 @@ fn generate_ast(
325325
);
326326

327327
// generate the dir of the ast_path (it mirrors the source file dir)
328-
helpers::create_build_path(
329-
&(package.get_build_path() + "/" + &ast_path.parent().unwrap().to_string_lossy()),
330-
);
328+
helpers::create_path(&(package.get_build_path() + "/" + &ast_path.parent().unwrap().to_string_lossy()));
331329

332330
/* Create .ast */
333331
let result = if let Some(res_to_ast) = Some(

src/config.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,23 @@ pub struct PackageSpec {
111111
pub suffix: Option<String>,
112112
}
113113

114+
impl PackageSpec {
115+
pub fn get_out_of_source_dir(&self) -> String {
116+
match self.module.as_str() {
117+
"commonjs" => "js",
118+
_ => "es6",
119+
}
120+
.to_string()
121+
}
122+
123+
pub fn is_common_js(&self) -> bool {
124+
match self.module.as_str() {
125+
"commonjs" => true,
126+
_ => false,
127+
}
128+
}
129+
}
130+
114131
#[derive(Deserialize, Debug, Clone)]
115132
#[serde(untagged)]
116133
pub enum Error {
@@ -427,6 +444,14 @@ impl Config {
427444
None => vec![],
428445
}
429446
}
447+
448+
pub fn get_package_specs(&self) -> Vec<PackageSpec> {
449+
match self.package_specs.clone() {
450+
None => vec![],
451+
Some(OneOrMore::Single(spec)) => vec![spec],
452+
Some(OneOrMore::Multiple(vec)) => vec,
453+
}
454+
}
430455
}
431456

432457
#[cfg(test)]

src/helpers.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,17 @@ pub fn contains_ascii_characters(str: &str) -> bool {
139139
false
140140
}
141141

142-
pub fn create_build_path(build_path: &str) {
142+
pub fn create_path(path: &str) {
143143
fs::DirBuilder::new()
144144
.recursive(true)
145-
.create(PathBuf::from(build_path.to_string()))
145+
.create(PathBuf::from(path.to_string()))
146146
.unwrap();
147147
}
148148

149+
pub fn create_path_for_path(path: &Path) {
150+
fs::DirBuilder::new().recursive(true).create(path).unwrap();
151+
}
152+
149153
pub fn get_bsc(root_path: &str, workspace_root: Option<String>) -> String {
150154
let subfolder = match (std::env::consts::OS, std::env::consts::ARCH) {
151155
("macos", "aarch64") => "darwinarm64",

0 commit comments

Comments
 (0)