Add --main flag to specify app/package to resolve deps from

This commit is contained in:
Agus Zubiaga 2024-06-07 17:09:44 -03:00
parent 75fe98cbaf
commit 2da7ea394b
No known key found for this signature in database
15 changed files with 89 additions and 19 deletions

View File

@ -72,6 +72,7 @@ pub const FLAG_STDOUT: &str = "stdout";
pub const FLAG_WASM_STACK_SIZE_KB: &str = "wasm-stack-size-kb";
pub const FLAG_OUTPUT: &str = "output";
pub const FLAG_FUZZ: &str = "fuzz";
pub const FLAG_MAIN: &str = "main";
pub const ROC_FILE: &str = "ROC_FILE";
pub const ROC_DIR: &str = "ROC_DIR";
pub const GLUE_DIR: &str = "GLUE_DIR";
@ -149,6 +150,12 @@ pub fn build_app() -> Command {
.action(ArgAction::SetTrue)
.required(false);
let flag_main = Arg::new(FLAG_MAIN)
.long(FLAG_MAIN)
.help("The .roc file of the main app/package module to resolve dependencies from")
.value_parser(value_parser!(PathBuf))
.required(false);
let roc_file_to_run = Arg::new(ROC_FILE)
.help("The .roc file of an app to run")
.value_parser(value_parser!(PathBuf))
@ -227,6 +234,7 @@ pub fn build_app() -> Command {
)
.subcommand(Command::new(CMD_TEST)
.about("Run all top-level `expect`s in a main module and any modules it imports")
.arg(flag_main.clone())
.arg(flag_optimize.clone())
.arg(flag_max_threads.clone())
.arg(flag_opt_size.clone())
@ -246,7 +254,7 @@ pub fn build_app() -> Command {
)
.arg(
Arg::new(ROC_FILE)
.help("The .roc file for the main module")
.help("The .roc file to test")
.value_parser(value_parser!(PathBuf))
.required(false)
.default_value(DEFAULT_ROC_FILENAME)
@ -321,11 +329,12 @@ pub fn build_app() -> Command {
.about(concatcp!("Print the Roc compilers version, which is currently ", VERSION)))
.subcommand(Command::new(CMD_CHECK)
.about("Check the code for problems, but dont build or run it")
.arg(flag_main.clone())
.arg(flag_time.clone())
.arg(flag_max_threads.clone())
.arg(
Arg::new(ROC_FILE)
.help("The .roc file of an app to check")
.help("The .roc file to check")
.value_parser(value_parser!(PathBuf))
.required(false)
.default_value(DEFAULT_ROC_FILENAME),
@ -496,6 +505,8 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
// TODO may need to determine this dynamically based on dev builds.
let function_kind = FunctionKind::LambdaSet;
let opt_main_path = matches.get_one::<PathBuf>(FLAG_MAIN);
// Step 1: compile the app and generate the .o file
let load_config = LoadConfig {
target,
@ -509,6 +520,7 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
let load_result = roc_load::load_and_monomorphize(
arena,
path.to_path_buf(),
opt_main_path.cloned(),
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
load_config,
);

View File

@ -5,7 +5,7 @@ use roc_build::program::{check_file, CodeGenBackend};
use roc_cli::{
build_app, format_files, format_src, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK,
CMD_DEV, CMD_DOCS, CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_PREPROCESS_HOST, CMD_REPL,
CMD_RUN, CMD_TEST, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB,
CMD_RUN, CMD_TEST, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_MAIN,
FLAG_NO_LINK, FLAG_OUTPUT, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, GLUE_DIR,
GLUE_SPEC, ROC_FILE,
};
@ -200,9 +200,12 @@ fn main() -> io::Result<()> {
Some(n) => Threading::AtMost(*n),
};
let opt_main_path = matches.get_one::<PathBuf>(FLAG_MAIN);
match check_file(
&arena,
roc_file_path.to_owned(),
opt_main_path.cloned(),
emit_timings,
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
threading,

View File

@ -647,6 +647,21 @@ mod cli_run {
);
}
#[test]
#[cfg_attr(windows, ignore)]
fn roc_test_main_flag() {
test_roc_expect(
"crates/cli/tests/module_imports_pkg",
"Module.roc",
&["--main", "tests/module_imports_pkg/app.roc"],
indoc!(
r#"
0 failed and 1 passed in <ignored for test> ms.
"#
),
)
}
#[test]
#[cfg_attr(windows, ignore)]
fn transitive_expects() {

View File

@ -0,0 +1,7 @@
module [valueFromPkg]
import pkg.Foo
valueFromPkg = Foo.foo
expect valueFromPkg == "Foo"

View File

@ -0,0 +1,8 @@
app [main] {
pkg: "./pkg/main.roc"
}
import Module
main =
Module.valueFromPkg

View File

@ -0,0 +1,3 @@
module [foo]
foo = "Foo"

View File

@ -0,0 +1 @@
package [Foo] {}

View File

@ -735,9 +735,14 @@ pub fn build_file<'a>(
let compilation_start = Instant::now();
// Step 1: compile the app and generate the .o file
let loaded =
roc_load::load_and_monomorphize(arena, app_module_path.clone(), roc_cache_dir, load_config)
.map_err(|e| BuildFileError::from_mono_error(e, compilation_start))?;
let loaded = roc_load::load_and_monomorphize(
arena,
app_module_path.clone(),
None,
roc_cache_dir,
load_config,
)
.map_err(|e| BuildFileError::from_mono_error(e, compilation_start))?;
build_loaded_file(
arena,
@ -1187,6 +1192,7 @@ fn build_and_preprocess_host_lowlevel(
pub fn check_file<'a>(
arena: &'a Bump,
roc_file_path: PathBuf,
opt_main_path: Option<PathBuf>,
emit_timings: bool,
roc_cache_dir: RocCacheDir<'_>,
threading: Threading,
@ -1209,8 +1215,13 @@ pub fn check_file<'a>(
threading,
exec_mode: ExecutionMode::Check,
};
let mut loaded =
roc_load::load_and_typecheck(arena, roc_file_path, roc_cache_dir, load_config)?;
let mut loaded = roc_load::load_and_typecheck(
arena,
roc_file_path,
opt_main_path,
roc_cache_dir,
load_config,
)?;
let buf = &mut String::with_capacity(1024);

View File

@ -121,6 +121,7 @@ pub fn load_and_monomorphize_from_str<'a>(
pub fn load_and_monomorphize<'a>(
arena: &'a Bump,
filename: PathBuf,
opt_main_path: Option<PathBuf>,
roc_cache_dir: RocCacheDir<'_>,
load_config: LoadConfig,
) -> Result<MonomorphizedModule<'a>, LoadMonomorphizedError<'a>> {
@ -129,6 +130,7 @@ pub fn load_and_monomorphize<'a>(
let load_start = LoadStart::from_path(
arena,
filename,
opt_main_path,
load_config.render,
roc_cache_dir,
load_config.palette,
@ -145,6 +147,7 @@ pub fn load_and_monomorphize<'a>(
pub fn load_and_typecheck<'a>(
arena: &'a Bump,
filename: PathBuf,
opt_main_path: Option<PathBuf>,
roc_cache_dir: RocCacheDir<'_>,
load_config: LoadConfig,
) -> Result<LoadedModule, LoadingProblem<'a>> {
@ -153,6 +156,7 @@ pub fn load_and_typecheck<'a>(
let load_start = LoadStart::from_path(
arena,
filename,
opt_main_path,
load_config.render,
roc_cache_dir,
load_config.palette,

View File

@ -134,6 +134,7 @@ mod test_reporting {
let result = roc_load::load_and_typecheck(
arena,
full_file_path,
None,
RocCacheDir::Disallowed,
load_config,
);

View File

@ -1105,6 +1105,7 @@ impl<'a> LoadStart<'a> {
pub fn from_path(
arena: &'a Bump,
filename: PathBuf,
opt_main_path: Option<PathBuf>,
render: RenderTarget,
roc_cache_dir: RocCacheDir<'_>,
palette: Palette,
@ -1144,23 +1145,23 @@ impl<'a> LoadStart<'a> {
match header_type {
Module { .. } | Builtin { .. } | Hosted { .. } => {
let main_path = loop {
let main_path = opt_main_path.or_else(|| loop {
match src_dir.join("main.roc").canonicalize() {
Ok(path) => break path,
Ok(path) => break Some(path),
Err(_) => {
if !src_dir.pop() {
return Err(LoadingProblem::FormattedReport(
"todo(agus): good error".to_string(),
));
break None;
}
}
}
};
});
let mut messages = Vec::with_capacity(4);
messages.push(header_output.msg);
let cache_dir = roc_cache_dir.as_persistent_path();
if let (Some(main_path), Some(cache_dir)) = (main_path, cache_dir) {
let mut messages = Vec::with_capacity(4);
messages.push(header_output.msg);
if let Some(cache_dir) = roc_cache_dir.as_persistent_path() {
load_packages_from_main(
arena,
src_dir.clone(),
@ -1171,9 +1172,9 @@ impl<'a> LoadStart<'a> {
Arc::clone(&arc_shorthands),
cache_dir,
)?;
}
header_output.msg = Msg::Many(messages);
header_output.msg = Msg::Many(messages);
}
}
App { .. } | Package { .. } | Platform { .. } => {}
}

View File

@ -50,6 +50,7 @@ fn load_and_typecheck(
let load_start = LoadStart::from_path(
arena,
filename,
None,
RenderTarget::Generic,
RocCacheDir::Disallowed,
DEFAULT_PALETTE,

View File

@ -482,6 +482,7 @@ pub fn load_module_for_docs(filename: PathBuf) -> LoadedModule {
match roc_load::load_and_typecheck(
&arena,
filename,
None,
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
load_config,
) {

View File

@ -414,6 +414,7 @@ pub fn load_types(
} = roc_load::load_and_typecheck(
arena,
full_file_path,
None,
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
LoadConfig {
target,

View File

@ -79,6 +79,7 @@ pub fn generate_stub_lib(
let loaded = roc_load::load_and_monomorphize(
arena,
input_path.to_path_buf(),
None,
roc_cache_dir,
LoadConfig {
target,