diff --git a/build.zig b/build.zig index 657a891aca..e3c6d0441d 100644 --- a/build.zig +++ b/build.zig @@ -81,6 +81,7 @@ pub fn build(b: *std.Build) void { .link_libc = true, }); all_tests.root_module.addOptions("build_options", build_options); + all_tests.root_module.addAnonymousImport("legal_details", .{ .root_source_file = b.path("legal_details") }); if (!no_bin) { const run_tests = b.addRunArtifact(all_tests); @@ -173,6 +174,7 @@ fn add_fuzz_target( .link_libc = true, }); repro_exe.root_module.addImport("fuzz_test", fuzz_obj.root_module); + install_and_run(b, no_bin, repro_exe, repro_step, repro_step); if (fuzz and build_afl and !no_bin) { @@ -210,6 +212,7 @@ fn addMainExe( const config = b.addOptions(); config.addOption(bool, "llvm", enable_llvm); exe.root_module.addOptions("config", config); + exe.root_module.addAnonymousImport("legal_details", .{ .root_source_file = b.path("legal_details") }); if (enable_llvm) { const llvm_paths = llvmPaths(b, target, use_system_llvm, user_llvm_path) orelse return null; diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 500c8db5f2..d4502f03c4 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -59,6 +59,7 @@ pub const CMD_FORMAT_ANNOTATE: &str = "annotate"; pub const CMD_TEST: &str = "test"; pub const CMD_GLUE: &str = "glue"; pub const CMD_PREPROCESS_HOST: &str = "preprocess-host"; +pub const CMD_LICENSES: &str = "licenses"; pub const FLAG_EMIT_LLVM_IR: &str = "emit-llvm-ir"; pub const FLAG_PROFILING: &str = "profiling"; @@ -397,6 +398,8 @@ pub fn build_app() -> Command { ) .subcommand(Command::new(CMD_VERSION) .about(concatcp!("Print the Roc compiler’s version, which is currently ", VERSION))) + .subcommand(Command::new(CMD_LICENSES) + .about("Prints license info for Roc as well as attributions to other projects used by Roc.")) .subcommand(Command::new(CMD_CHECK) .about("Check the code for problems, but don’t build or run it") .arg(flag_main.clone()) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index d38876e220..5c768a8a80 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -5,11 +5,11 @@ use roc_build::program::{check_file, CodeGenBackend}; use roc_cli::{ annotate_file, build_app, default_linking_strategy, format_files, format_src, test, AnnotationProblem, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK, CMD_DEV, CMD_DOCS, - CMD_FORMAT, CMD_FORMAT_ANNOTATE, CMD_GLUE, CMD_PREPROCESS_HOST, CMD_REPL, CMD_RUN, CMD_TEST, - CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_DOCS_ROOT, FLAG_LIB, FLAG_MAIN, - FLAG_MIGRATE, FLAG_NO_COLOR, FLAG_NO_HEADER, FLAG_NO_LINK, FLAG_OUTPUT, FLAG_PP_DYLIB, - FLAG_PP_HOST, FLAG_PP_PLATFORM, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, FLAG_VERBOSE, - GLUE_DIR, GLUE_SPEC, ROC_FILE, VERSION, + CMD_FORMAT, CMD_FORMAT_ANNOTATE, CMD_GLUE, CMD_LICENSES, CMD_PREPROCESS_HOST, CMD_REPL, + CMD_RUN, CMD_TEST, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_DOCS_ROOT, + FLAG_LIB, FLAG_MAIN, FLAG_MIGRATE, FLAG_NO_COLOR, FLAG_NO_HEADER, FLAG_NO_LINK, FLAG_OUTPUT, + FLAG_PP_DYLIB, FLAG_PP_HOST, FLAG_PP_PLATFORM, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, + FLAG_VERBOSE, GLUE_DIR, GLUE_SPEC, ROC_FILE, VERSION, }; use roc_docs::generate_docs_html; use roc_error_macros::{internal_error, user_error}; @@ -33,6 +33,8 @@ use std::ffi::{OsStr, OsString}; use roc_cli::build; +const LEGAL_DETAILS_TEXT: &str = include_str!("../../../legal_details"); + fn main() -> io::Result<()> { let _tracing_guards = roc_tracing::setup_tracing!(); @@ -493,6 +495,10 @@ fn main() -> io::Result<()> { println!("roc {}", VERSION); Ok(0) } + Some((CMD_LICENSES, _)) => { + println!("{LEGAL_DETAILS_TEXT}"); + Ok(0) + } _ => unreachable!(), }?; diff --git a/nix/fileFilter.nix b/nix/fileFilter.nix index 3564ea15ce..4b057e43ab 100644 --- a/nix/fileFilter.nix +++ b/nix/fileFilter.nix @@ -37,6 +37,7 @@ let ../Cargo.toml ../Cargo.lock ../version.txt + ../legal_details ../rust-toolchain.toml ../.cargo/config.toml onlyCratesFolder diff --git a/src/cli.zig b/src/cli.zig index 56a3905d3b..aa7d7f18ec 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -14,6 +14,7 @@ pub const RocCmd = enum { roc_docs, roc_glue, roc_help, + roc_licenses, pub fn parse(arg_str: []const u8) ?RocCmd { const map = std.static_string_map.StaticStringMap(RocCmd).initComptime(.{ @@ -27,6 +28,7 @@ pub const RocCmd = enum { .{ "docs", .roc_docs }, .{ "glue", .roc_glue }, .{ "help", .roc_help }, + .{ "licenses", .roc_licenses }, }); if (map.get(arg_str)) |cmd| { diff --git a/src/main.zig b/src/main.zig index d9d3802e1a..1f4c50f80d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,3 +1,7 @@ +//! Roc command line interface for the new compiler. Entrypoint of the Roc binary. +//! Build with `zig build -Dllvm -Dfuzz -Dsystem-afl=false`. +//! Result is at `./zig-out/bin/roc` + const std = @import("std"); const fmt = @import("fmt.zig"); const base = @import("base.zig"); @@ -15,6 +19,8 @@ const Allocator = std.mem.Allocator; const exitOnOom = collections.utils.exitOnOom; const fatal = collections.utils.fatal; +const legalDetailsFileContent = @embedFile("legal_details"); + const usage = \\Usage: \\ @@ -31,6 +37,7 @@ const usage = \\ check Check the code for problems, but don’t build or run it \\ docs Generate documentation for a Roc package \\ glue Generate glue code between a platform's Roc API and its host language + \\ licenses Prints license info for Roc as well as attributions to other projects used by Roc. \\ \\General Options: \\ @@ -88,6 +95,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { .roc_docs => try rocDocs(gpa, opt, cmd_args), .roc_glue => try rocGlue(gpa, opt, cmd_args), .roc_help => try rocHelp(), + .roc_licenses => try rocLicenses(), } } else if (std.mem.eql(u8, cmd, "-h") or std.mem.eql(u8, cmd, "--help")) { try rocHelp(); @@ -97,11 +105,6 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { } } -fn printHelp() !void { - try std.io.getStdOut().writeAll(usage); - std.process.exit(0); -} - fn rocRun(gpa: Allocator, opt: RocOpt, args: []const []const u8) !void { _ = gpa; @@ -210,6 +213,12 @@ fn rocGlue(allocator: Allocator, opt: RocOpt, args: []const []const u8) !void { fatal("not implemented", .{}); } +fn rocLicenses() !void { + try std.io.getStdOut().writeAll(legalDetailsFileContent); + std.process.exit(0); +} + fn rocHelp() !void { try std.io.getStdOut().writeAll(usage); + std.process.exit(0); }