diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 3ae0dbd5819..3b2fdb7c89a 100644 Binary files a/ql/Cargo.lock and b/ql/Cargo.lock differ diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index b316e6bc05c..cb2070417ac 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ql-extractor" +name = "codeql-ql-extractor" version = "0.1.0" authors = ["GitHub"] edition = "2018" diff --git a/ql/extractor/src/bin/autobuilder.rs b/ql/extractor/src/autobuilder.rs similarity index 88% rename from ql/extractor/src/bin/autobuilder.rs rename to ql/extractor/src/autobuilder.rs index 0d9605c4c1d..a17a4916239 100644 --- a/ql/extractor/src/bin/autobuilder.rs +++ b/ql/extractor/src/autobuilder.rs @@ -1,8 +1,13 @@ +use clap::Args; use std::env; use std::path::PathBuf; use std::process::Command; -fn main() -> std::io::Result<()> { +#[derive(Args)] +// The autobuilder takes no command-line options, but this may change in the future. +pub struct Options {} + +pub fn run(_: Options) -> std::io::Result<()> { let dist = env::var("CODEQL_DIST").expect("CODEQL_DIST not set"); let db = env::var("CODEQL_EXTRACTOR_QL_WIP_DATABASE") .expect("CODEQL_EXTRACTOR_QL_WIP_DATABASE not set"); diff --git a/ql/extractor/src/bin/extractor.rs b/ql/extractor/src/extractor.rs similarity index 88% rename from ql/extractor/src/bin/extractor.rs rename to ql/extractor/src/extractor.rs index 592c98b1b15..ca616b482c3 100644 --- a/ql/extractor/src/bin/extractor.rs +++ b/ql/extractor/src/extractor.rs @@ -1,3 +1,4 @@ +use clap::Args; use rayon::prelude::*; use std::fs; use std::io::BufRead; @@ -5,7 +6,22 @@ use std::path::{Path, PathBuf}; use codeql_extractor::{diagnostics, extractor, node_types, trap}; -fn main() -> std::io::Result<()> { +#[derive(Args)] +pub struct Options { + /// Sets a custom source achive folder + #[arg(long)] + source_archive_dir: PathBuf, + + /// Sets a custom trap folder + #[arg(long)] + output_dir: PathBuf, + + /// A text file containing the paths of the files to extract + #[arg(long)] + file_list: PathBuf, +} + +pub fn run(options: Options) -> std::io::Result<()> { tracing_subscriber::fmt() .with_target(false) .without_time() @@ -58,30 +74,9 @@ fn main() -> std::io::Result<()> { .build_global() .unwrap(); - let matches = clap::Command::new("QL extractor") - .version("1.0") - .author("GitHub") - .about("CodeQL QL extractor") - .args(&[ - clap::arg!(--"source-archive-dir" "Sets a custom source archive folder"), - clap::arg!(--"output-dir" "Sets a custom trap folder"), - clap::arg!(--"file-list" "A text file containing the paths of the files to extract"), - ]) - .get_matches(); - let src_archive_dir = matches - .get_one::("source-archive-dir") - .expect("missing --source-archive-dir"); - let src_archive_dir = PathBuf::from(src_archive_dir); - - let trap_dir = matches - .get_one::("output-dir") - .expect("missing --output-dir"); - let trap_dir = PathBuf::from(trap_dir); - - let file_list = matches - .get_one::("file-list") - .expect("missing --file-list"); - let file_list = fs::File::open(file_list)?; + let trap_dir = options.output_dir; + let file_list = fs::File::open(options.file_list)?; + let source_archive_dir = options.source_archive_dir; let language = tree_sitter_ql::language(); let dbscheme = tree_sitter_ql_dbscheme::language(); @@ -114,7 +109,7 @@ fn main() -> std::io::Result<()> { return Ok(()); } let path = PathBuf::from(line).canonicalize()?; - let src_archive_file = path_for(&src_archive_dir, &path, ""); + let src_archive_file = path_for(&source_archive_dir, &path, ""); let source = std::fs::read(&path)?; let code_ranges = vec![]; let mut trap_writer = trap::Writer::new(); diff --git a/ql/extractor/src/bin/generator.rs b/ql/extractor/src/generator.rs similarity index 54% rename from ql/extractor/src/bin/generator.rs rename to ql/extractor/src/generator.rs index 45a13f6a18d..cdfdd17df4d 100644 --- a/ql/extractor/src/bin/generator.rs +++ b/ql/extractor/src/generator.rs @@ -1,8 +1,20 @@ +use clap::Args; use std::path::PathBuf; use codeql_extractor::generator::{generate, language::Language}; -fn main() -> std::io::Result<()> { +#[derive(Args)] +pub struct Options { + /// Path of the generated dbscheme file + #[arg(long)] + dbscheme: PathBuf, + + /// Path of the generated QLL file + #[arg(long)] + library: PathBuf, +} + +pub fn run(options: Options) -> std::io::Result<()> { tracing_subscriber::fmt() .with_target(false) .without_time() @@ -10,25 +22,6 @@ fn main() -> std::io::Result<()> { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .init(); - let matches = clap::Command::new("QL dbscheme generator") - .version("1.0") - .author("GitHub") - .about("CodeQL QL dbscheme generator") - .args(&[ - clap::arg!(--dbscheme "Path of the generated dbscheme file"), - clap::arg!(--library "Path of the generated QLL file"), - ]) - .get_matches(); - let dbscheme_path = matches - .get_one::("dbscheme") - .expect("missing --dbscheme"); - let dbscheme_path = PathBuf::from(dbscheme_path); - - let ql_library_path = matches - .get_one::("library") - .expect("missing --library"); - let ql_library_path = PathBuf::from(ql_library_path); - let languages = vec![ Language { name: "QL".to_owned(), @@ -52,5 +45,5 @@ fn main() -> std::io::Result<()> { }, ]; - generate(languages, dbscheme_path, ql_library_path) + generate(languages, options.dbscheme, options.library) } diff --git a/ql/extractor/src/main.rs b/ql/extractor/src/main.rs new file mode 100644 index 00000000000..0287a20c184 --- /dev/null +++ b/ql/extractor/src/main.rs @@ -0,0 +1,23 @@ +use clap::Parser; + +mod autobuilder; +mod extractor; +mod generator; + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +enum Cli { + Extract(extractor::Options), + Generate(generator::Options), + Autobuild(autobuilder::Options), +} + +fn main() -> std::io::Result<()> { + let cli = Cli::parse(); + + match cli { + Cli::Extract(options) => extractor::run(options), + Cli::Generate(options) => generator::run(options), + Cli::Autobuild(options) => autobuilder::run(options), + } +}