use emmylua_code_analysis::{
EmmyLuaAnalysis, WorkspaceFolder, build_workspace_folders, collect_workspace_files,
load_configs,
};
use fern::Dispatch;
use log::LevelFilter;
use std::{
path::{Path, PathBuf},
sync::Arc,
};
fn root_from_configs(config_paths: &[PathBuf], fallback: &Path) -> PathBuf {
if config_paths.len() != 1 {
fallback.to_path_buf()
} else {
let config_path = &config_paths[0];
match config_path.canonicalize() {
Ok(path) => path.parent().unwrap().to_path_buf(),
Err(err) => {
log::error!(
"Failed to canonicalize config path: \"{:?}\": {}",
config_path,
err
);
fallback.to_path_buf()
}
}
}
}
pub fn setup_logger(verbose: bool) {
let logger = Dispatch::new()
.format(move |out, message, record| {
let (color, reset) = match record.level() {
log::Level::Error => ("\x1b[31m", "\x1b[0m"), log::Level::Warn => ("\x1b[33m", "\x1b[0m"), log::Level::Info | log::Level::Debug | log::Level::Trace => ("", ""),
};
out.finish(format_args!(
"{}{}: {}{}",
color,
record.level(),
if verbose {
format!("({}) {}", record.target(), message)
} else {
message.to_string()
},
reset
))
})
.level(if verbose {
LevelFilter::Info
} else {
LevelFilter::Warn
})
.chain(std::io::stderr());
if let Err(e) = logger.apply() {
eprintln!("Failed to apply logger: {:?}", e);
}
}
pub fn load_workspace(
main_path: PathBuf,
cmd_workspace_folders: Vec<PathBuf>,
config_paths: Option<Vec<PathBuf>>,
exclude_pattern: Option<Vec<String>>,
include_pattern: Option<Vec<String>>,
) -> Option<EmmyLuaAnalysis> {
let (config_files, config_root): (Vec<PathBuf>, PathBuf) =
if let Some(config_paths) = config_paths {
(
config_paths.clone(),
root_from_configs(&config_paths, &main_path),
)
} else {
(
vec![
main_path.join(".luarc.json"),
main_path.join(".emmyrc.json"),
main_path.join(".emmyrc.lua"),
]
.into_iter()
.filter(|path| path.exists())
.collect(),
main_path.clone(),
)
};
let mut emmyrc = load_configs(config_files, None);
log::info!(
"Pre processing configurations using root: \"{}\"",
config_root.display()
);
emmyrc.pre_process_emmyrc(&config_root);
let workspace_folders = cmd_workspace_folders
.iter()
.map(|p| WorkspaceFolder::new(p.clone(), false))
.collect::<Vec<WorkspaceFolder>>();
let mut analysis = EmmyLuaAnalysis::new();
analysis.update_config(Arc::new(emmyrc));
analysis.init_std_lib(None);
let workspace_folders = build_workspace_folders(&workspace_folders, &analysis.emmyrc);
for workspace in &workspace_folders {
if workspace.is_library {
analysis.add_library_workspace(workspace);
} else {
analysis.add_main_workspace(workspace.root.clone());
}
}
let file_infos = collect_workspace_files(
&workspace_folders,
&analysis.emmyrc,
include_pattern,
exclude_pattern,
);
let files = file_infos
.into_iter()
.map(|file| file.into_tuple())
.collect();
analysis.update_files_by_path(files);
Some(analysis)
}