Skip to content

Commit afde99e

Browse files
committed
🥅 - Don't panic when failing to parse bsconfig
1 parent 87c275a commit afde99e

File tree

5 files changed

+78
-78
lines changed

5 files changed

+78
-78
lines changed

src/build.rs

+19-50
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::helpers::emojis::*;
1313
use crate::helpers::{self, get_workspace_root};
1414
use crate::sourcedirs;
1515
use ahash::AHashSet;
16+
use anyhow::{anyhow, Result};
1617
use build_types::*;
1718
use console::style;
1819
use indicatif::{ProgressBar, ProgressStyle};
@@ -54,15 +55,19 @@ pub struct CompilerArgs {
5455
pub parser_args: Vec<String>,
5556
}
5657

57-
pub fn get_compiler_args(path: &str, rescript_version: Option<String>, bsc_path: Option<String>) -> String {
58+
pub fn get_compiler_args(
59+
path: &str,
60+
rescript_version: Option<String>,
61+
bsc_path: Option<String>,
62+
) -> Result<String> {
5863
let filename = &helpers::get_abs_path(path);
5964
let package_root = helpers::get_abs_path(
6065
&helpers::get_nearest_config(&std::path::PathBuf::from(path)).expect("Couldn't find package root"),
6166
);
6267
let workspace_root = get_workspace_root(&package_root).map(|p| helpers::get_abs_path(&p));
6368
let root_rescript_config =
64-
packages::read_config(&workspace_root.to_owned().unwrap_or(package_root.to_owned()));
65-
let rescript_config = packages::read_config(&package_root);
69+
packages::read_config(&workspace_root.to_owned().unwrap_or(package_root.to_owned()))?;
70+
let rescript_config = packages::read_config(&package_root)?;
6671
let rescript_version = if let Some(rescript_version) = rescript_version {
6772
rescript_version
6873
} else {
@@ -111,28 +116,13 @@ pub fn get_compiler_args(path: &str, rescript_version: Option<String>, bsc_path:
111116
&workspace_root,
112117
&None,
113118
);
114-
serde_json::to_string_pretty(&CompilerArgs {
119+
120+
let result = serde_json::to_string_pretty(&CompilerArgs {
115121
compiler_args,
116122
parser_args,
117-
})
118-
.unwrap()
119-
}
123+
})?;
120124

121-
#[derive(Debug, Clone)]
122-
pub enum InitializeBuildError {
123-
PackageDependencyValidation,
124-
}
125-
126-
impl fmt::Display for InitializeBuildError {
127-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128-
match self {
129-
Self::PackageDependencyValidation => write!(
130-
f,
131-
"{} {}Could not Validate Package Dependencies",
132-
LINE_CLEAR, CROSS,
133-
),
134-
}
135-
}
125+
Ok(result)
136126
}
137127

138128
pub fn initialize_build(
@@ -141,14 +131,14 @@ pub fn initialize_build(
141131
show_progress: bool,
142132
path: &str,
143133
bsc_path: Option<String>,
144-
) -> Result<BuildState, InitializeBuildError> {
134+
) -> Result<BuildState> {
145135
let project_root = helpers::get_abs_path(path);
146136
let workspace_root = helpers::get_workspace_root(&project_root);
147137
let bsc_path = match bsc_path {
148138
Some(bsc_path) => bsc_path,
149139
None => helpers::get_bsc(&project_root, workspace_root.to_owned()),
150140
};
151-
let root_config_name = packages::get_package_name(&project_root);
141+
let root_config_name = packages::get_package_name(&project_root)?;
152142
let rescript_version = helpers::get_rescript_version(&bsc_path);
153143

154144
if show_progress {
@@ -157,7 +147,7 @@ pub fn initialize_build(
157147
}
158148

159149
let timing_package_tree = Instant::now();
160-
let packages = packages::make(filter, &project_root, &workspace_root);
150+
let packages = packages::make(filter, &project_root, &workspace_root, show_progress)?;
161151
let timing_package_tree_elapsed = timing_package_tree.elapsed();
162152

163153
if show_progress {
@@ -173,7 +163,7 @@ pub fn initialize_build(
173163
}
174164

175165
if !packages::validate_packages_dependencies(&packages) {
176-
return Err(InitializeBuildError::PackageDependencyValidation);
166+
return Err(anyhow!("Failed to validate package dependencies"));
177167
}
178168

179169
let timing_source_files = Instant::now();
@@ -435,27 +425,6 @@ pub fn incremental_build(
435425
}
436426
}
437427

438-
#[derive(Debug, Clone)]
439-
pub enum BuildError {
440-
InitializeBuild(InitializeBuildError),
441-
IncrementalBuild(IncrementalBuildError),
442-
}
443-
444-
impl fmt::Display for BuildError {
445-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446-
match self {
447-
Self::InitializeBuild(e) => {
448-
write!(f, "{} {}Error Initializing Build: {}", LINE_CLEAR, CROSS, e)
449-
}
450-
Self::IncrementalBuild(e) => write!(
451-
f,
452-
"{} {}Error Running Incremental Build: {}",
453-
LINE_CLEAR, CROSS, e
454-
),
455-
}
456-
}
457-
}
458-
459428
// write build.ninja files in the packages after a non-incremental build
460429
// this is necessary to bust the editor tooling cache. The editor tooling
461430
// is watching this file.
@@ -477,15 +446,15 @@ pub fn build(
477446
no_timing: bool,
478447
create_sourcedirs: bool,
479448
bsc_path: Option<String>,
480-
) -> Result<BuildState, BuildError> {
449+
) -> Result<BuildState> {
481450
let default_timing: Option<std::time::Duration> = if no_timing {
482451
Some(std::time::Duration::new(0.0 as u64, 0.0 as u32))
483452
} else {
484453
None
485454
};
486455
let timing_total = Instant::now();
487456
let mut build_state = initialize_build(default_timing, filter, show_progress, path, bsc_path)
488-
.map_err(BuildError::InitializeBuild)?;
457+
.map_err(|e| anyhow!("Could not initialize build. Error: {e}"))?;
489458

490459
match incremental_build(
491460
&mut build_state,
@@ -512,7 +481,7 @@ pub fn build(
512481
Err(e) => {
513482
clean::cleanup_after_build(&build_state);
514483
write_build_ninja(&build_state);
515-
Err(BuildError::IncrementalBuild(e))
484+
Err(anyhow!("Incremental build failed. Error: {e}"))
516485
}
517486
}
518487
}

src/build/clean.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::packages;
33
use crate::helpers;
44
use crate::helpers::emojis::*;
55
use ahash::AHashSet;
6+
use anyhow::Result;
67
use console::style;
78
use rayon::prelude::*;
89
use std::io::Write;
@@ -318,11 +319,11 @@ pub fn cleanup_after_build(build_state: &BuildState) {
318319
});
319320
}
320321

321-
pub fn clean(path: &str, show_progress: bool, bsc_path: Option<String>) {
322+
pub fn clean(path: &str, show_progress: bool, bsc_path: Option<String>) -> Result<()> {
322323
let project_root = helpers::get_abs_path(path);
323324
let workspace_root = helpers::get_workspace_root(&project_root);
324-
let packages = packages::make(&None, &project_root, &workspace_root);
325-
let root_config_name = packages::get_package_name(&project_root);
325+
let packages = packages::make(&None, &project_root, &workspace_root, show_progress)?;
326+
let root_config_name = packages::get_package_name(&project_root)?;
326327
let bsc_path = match bsc_path {
327328
Some(bsc_path) => bsc_path,
328329
None => helpers::get_bsc(&project_root, workspace_root.to_owned()),
@@ -399,4 +400,6 @@ pub fn clean(path: &str, show_progress: bool, bsc_path: Option<String>) {
399400
);
400401
let _ = std::io::stdout().flush();
401402
}
403+
404+
Ok(())
402405
}

src/build/packages.rs

+42-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::config;
55
use crate::helpers;
66
use crate::helpers::emojis::*;
77
use ahash::{AHashMap, AHashSet};
8+
use anyhow::Result;
89
use console::style;
910
use log::{debug, error};
1011
use rayon::prelude::*;
@@ -216,7 +217,7 @@ fn get_source_dirs(source: config::Source, sub_path: Option<PathBuf>) -> AHashSe
216217
source_folders
217218
}
218219

219-
pub fn read_config(package_dir: &str) -> config::Config {
220+
pub fn read_config(package_dir: &str) -> Result<config::Config> {
220221
let prefix = if package_dir.is_empty() {
221222
"".to_string()
222223
} else {
@@ -290,6 +291,7 @@ fn read_dependencies(
290291
parent_path: &str,
291292
project_root: &str,
292293
workspace_root: Option<String>,
294+
show_progress: bool,
293295
) -> Vec<Dependency> {
294296
return parent_config
295297
.bs_dependencies
@@ -311,16 +313,34 @@ fn read_dependencies(
311313
let (config, canonical_path) =
312314
match read_dependency(package_name, parent_path, project_root, &workspace_root) {
313315
Err(error) => {
314-
log::error!(
316+
if show_progress {
317+
println!(
315318
"{} {} Error building package tree. {}",
316319
style("[1/2]").bold().dim(),
317320
CROSS,
318321
error
319322
);
323+
}
324+
325+
log::error!(
326+
"We could not build package tree reading depencency '{package_name}', at path '{parent_path}'. Error: {error}",
327+
);
328+
320329
std::process::exit(2)
321330
}
322-
Ok(canonical_path) => (read_config(&canonical_path), canonical_path),
331+
Ok(canonical_path) => {
332+
match read_config(&canonical_path) {
333+
Ok(config) => (config, canonical_path),
334+
Err(error) => {
335+
log::error!(
336+
"We could not build package tree '{package_name}', at path '{parent_path}', Error: {error}",
337+
);
338+
std::process::exit(2)
339+
}
340+
}
341+
}
323342
};
343+
324344
let is_pinned = parent_config
325345
.pinned_dependencies
326346
.as_ref()
@@ -333,6 +353,7 @@ fn read_dependencies(
333353
&canonical_path,
334354
project_root,
335355
workspace_root.to_owned(),
356+
show_progress
336357
);
337358

338359
Dependency {
@@ -397,8 +418,12 @@ fn make_package(config: config::Config, package_path: &str, is_pinned_dep: bool,
397418
}
398419
}
399420

400-
fn read_packages(project_root: &str, workspace_root: Option<String>) -> AHashMap<String, Package> {
401-
let root_config = read_config(project_root);
421+
fn read_packages(
422+
project_root: &str,
423+
workspace_root: Option<String>,
424+
show_progress: bool,
425+
) -> Result<AHashMap<String, Package>> {
426+
let root_config = read_config(project_root)?;
402427

403428
// Store all packages and completely deduplicate them
404429
let mut map: AHashMap<String, Package> = AHashMap::new();
@@ -414,6 +439,7 @@ fn read_packages(project_root: &str, workspace_root: Option<String>) -> AHashMap
414439
project_root,
415440
project_root,
416441
workspace_root,
442+
show_progress,
417443
));
418444
dependencies.iter().for_each(|d| {
419445
if !map.contains_key(&d.name) {
@@ -424,7 +450,7 @@ fn read_packages(project_root: &str, workspace_root: Option<String>) -> AHashMap
424450
}
425451
});
426452

427-
map
453+
Ok(map)
428454
}
429455

430456
/// `get_source_files` is essentially a wrapper around `read_structure`, which read a
@@ -527,25 +553,29 @@ pub fn make(
527553
filter: &Option<regex::Regex>,
528554
root_folder: &str,
529555
workspace_root: &Option<String>,
530-
) -> AHashMap<String, Package> {
531-
let map = read_packages(root_folder, workspace_root.to_owned());
556+
show_progress: bool,
557+
) -> Result<AHashMap<String, Package>> {
558+
let map = read_packages(root_folder, workspace_root.to_owned(), show_progress)?;
532559

533560
/* Once we have the deduplicated packages, we can add the source files for each - to minimize
534561
* the IO */
535562
let result = extend_with_children(filter, map);
563+
536564
result.values().for_each(|package| {
537565
if let Some(dirs) = &package.dirs {
538566
dirs.iter().for_each(|dir| {
539567
let _ = std::fs::create_dir_all(std::path::Path::new(&package.get_bs_build_path()).join(dir));
540568
})
541569
}
542570
});
543-
result
571+
572+
Ok(result)
544573
}
545574

546-
pub fn get_package_name(path: &str) -> String {
547-
let config = read_config(path);
548-
config.name
575+
pub fn get_package_name(path: &str) -> Result<String> {
576+
let config = read_config(path)?;
577+
578+
Ok(config.name)
549579
}
550580

551581
pub fn parse_packages(build_state: &mut BuildState) {

src/config.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::build::packages;
22
use crate::helpers::deserialize::*;
3+
use anyhow::Result;
34
use convert_case::{Case, Casing};
45
use serde::Deserialize;
56
use std::fs;
@@ -267,17 +268,11 @@ pub fn flatten_ppx_flags(
267268
}
268269

269270
/// Try to convert a bsconfig from a certain path to a bsconfig struct
270-
pub fn read(path: String) -> Config {
271-
fs::read_to_string(path.clone())
272-
.map_err(|e| format!("Could not read bsconfig. {path} - {e}"))
273-
// .and_then(|x| {
274-
// dbg!(&x);
275-
// repair(x).map_err(|e| format!("Json was invalid and could not be repaired. {path} - {e}"))
276-
// })
277-
.and_then(|x| {
278-
serde_json::from_str::<Config>(&x).map_err(|e| format!("Could not parse bsconfig. {path} - {e}"))
279-
})
280-
.expect("Errors reading bsconfig")
271+
pub fn read(path: String) -> Result<Config> {
272+
let read = fs::read_to_string(path.clone())?;
273+
let parse = serde_json::from_str::<Config>(&read)?;
274+
275+
Ok(parse)
281276
}
282277

283278
fn check_if_rescript11_or_higher(version: &str) -> Result<bool, String> {

src/main.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::Result;
12
use clap::{Parser, ValueEnum};
23
use clap_verbosity_flag::InfoLevel;
34
use log::LevelFilter;
@@ -72,7 +73,7 @@ struct Args {
7273
bsc_path: Option<String>,
7374
}
7475

75-
fn main() {
76+
fn main() -> Result<()> {
7677
let args = Args::parse();
7778
let log_level_filter = args.verbose.log_level_filter();
7879

@@ -93,7 +94,7 @@ fn main() {
9394
Some(path) => {
9495
println!(
9596
"{}",
96-
build::get_compiler_args(&path, args.rescript_version, args.bsc_path)
97+
build::get_compiler_args(&path, args.rescript_version, args.bsc_path)?
9798
);
9899
std::process::exit(0);
99100
}
@@ -139,6 +140,8 @@ fn main() {
139140
args.after_build,
140141
args.create_sourcedirs.unwrap_or(false),
141142
);
143+
144+
Ok(())
142145
}
143146
},
144147
}

0 commit comments

Comments
 (0)