Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check command #15692

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions crates/red_knot/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::logging::Verbosity;
use crate::python_version::PythonVersion;
use crate::Command;
use clap::{ArgAction, ArgMatches, Error, Parser};
use red_knot_project::metadata::options::{EnvironmentOptions, Options};
use red_knot_project::metadata::value::{RangedValue, RelativePathBuf};
Expand All @@ -16,8 +15,20 @@ use ruff_db::system::SystemPathBuf;
#[command(version)]
pub(crate) struct Args {
#[command(subcommand)]
pub(crate) command: Option<Command>,
pub(crate) command: Command,
}

#[derive(Debug, clap::Subcommand)]
pub(crate) enum Command {
/// Check a project for type errors.
Check(CheckCommand),

/// Start the language server
Server,
}

#[derive(Debug, Parser)]
pub(crate) struct CheckCommand {
/// Run the command within the given project directory.
///
/// All `pyproject.toml` files will be discovered by walking up the directory tree from the given project directory,
Expand Down Expand Up @@ -57,17 +68,15 @@ pub(crate) struct Args {
pub(crate) watch: bool,
}

impl Args {
pub(crate) fn to_options(&self) -> Options {
impl CheckCommand {
pub(crate) fn into_options(self) -> Options {
let rules = if self.rules.is_empty() {
None
} else {
Some(
self.rules
.iter()
.map(|(rule, level)| {
(RangedValue::cli(rule.to_string()), RangedValue::cli(level))
})
.into_iter()
.map(|(rule, level)| (RangedValue::cli(rule), RangedValue::cli(level)))
.collect(),
)
};
Expand All @@ -77,11 +86,11 @@ impl Args {
python_version: self
.python_version
.map(|version| RangedValue::cli(version.into())),
venv_path: self.venv_path.as_ref().map(RelativePathBuf::cli),
typeshed: self.typeshed.as_ref().map(RelativePathBuf::cli),
extra_paths: self.extra_search_path.as_ref().map(|extra_search_paths| {
venv_path: self.venv_path.map(RelativePathBuf::cli),
typeshed: self.typeshed.map(RelativePathBuf::cli),
extra_paths: self.extra_search_path.map(|extra_search_paths| {
extra_search_paths
.iter()
.into_iter()
.map(RelativePathBuf::cli)
.collect()
}),
Expand All @@ -105,8 +114,8 @@ impl RulesArg {
self.0.is_empty()
}

fn iter(&self) -> impl Iterator<Item = (&str, lint::Level)> {
self.0.iter().map(|(rule, level)| (rule.as_str(), *level))
fn into_iter(self) -> impl Iterator<Item = (String, lint::Level)> {
self.0.into_iter()
}
}

Expand Down
20 changes: 9 additions & 11 deletions crates/red_knot/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::process::{ExitCode, Termination};
use std::sync::Mutex;

use crate::args::Args;
use crate::args::{Args, CheckCommand, Command};
use crate::logging::setup_tracing;
use anyhow::{anyhow, Context};
use clap::Parser;
Expand All @@ -21,12 +21,6 @@ mod logging;
mod python_version;
mod verbosity;

#[derive(Debug, clap::Subcommand)]
pub enum Command {
/// Start the language server
Server,
}

#[allow(clippy::print_stdout, clippy::unnecessary_wraps, clippy::print_stderr)]
pub fn main() -> ExitStatus {
run().unwrap_or_else(|error| {
Expand All @@ -52,10 +46,13 @@ pub fn main() -> ExitStatus {
fn run() -> anyhow::Result<ExitStatus> {
let args = Args::parse_from(std::env::args());

if matches!(args.command, Some(Command::Server)) {
return run_server().map(|()| ExitStatus::Success);
match args.command {
Command::Server => run_server().map(|()| ExitStatus::Success),
Command::Check(check_args) => run_check(check_args),
}
}

fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
let verbosity = args.verbosity.level();
countme::enable(verbosity.is_trace());
let _guard = setup_tracing(verbosity)?;
Expand Down Expand Up @@ -86,7 +83,8 @@ fn run() -> anyhow::Result<ExitStatus> {
.unwrap_or_else(|| cli_base_path.clone());

let system = OsSystem::new(cwd);
let cli_options = args.to_options();
let watch = args.watch;
let cli_options = args.into_options();
let mut workspace_metadata = ProjectMetadata::discover(system.current_directory(), &system)?;
workspace_metadata.apply_cli_options(cli_options.clone());

Expand All @@ -104,7 +102,7 @@ fn run() -> anyhow::Result<ExitStatus> {
}
})?;

let exit_status = if args.watch {
let exit_status = if watch {
main_loop.watch(&mut db)?
} else {
main_loop.run(&mut db)
Expand Down
Loading
Loading