Skip to content

Commit 58459d0

Browse files
committed
Extract cargo-markers main.rs into separate modules
1 parent 873ba6e commit 58459d0

File tree

5 files changed

+172
-137
lines changed

5 files changed

+172
-137
lines changed

cargo-marker/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ once_cell = "1.16.0"
1010

1111
[features]
1212
default = []
13-
# Indicates that development features like auto driver building etc should be enabled.
14-
# This option assumes that it's being executed at the project root.
13+
# This enables developer features used to automatically build the local version
14+
# assuming, that it's being executed at the root of the repo.
1515
dev-build = []

cargo-marker/src/cli.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use clap::{Arg, ArgAction, Command};
2+
3+
use crate::VERSION;
4+
5+
const AFTER_HELP_MSG: &str = r#"CARGO ARGS
6+
All arguments after double dashes(`--`) will be passed to cargo.
7+
These options are the same as for `cargo check`.
8+
9+
EXAMPLES:
10+
* `cargo marker -l ./marker_lints`
11+
"#;
12+
13+
pub fn get_clap_config() -> Command {
14+
Command::new(VERSION)
15+
.arg(
16+
Arg::new("version")
17+
.short('V')
18+
.long("version")
19+
.action(ArgAction::SetTrue)
20+
.help("Print version info and exit"),
21+
)
22+
.arg(
23+
Arg::new("verbose")
24+
.short('v')
25+
.long("verbose")
26+
.action(ArgAction::SetTrue)
27+
.help("Print additional debug information to the console"),
28+
)
29+
.arg(
30+
Arg::new("test-setup")
31+
.long("test-setup")
32+
.action(ArgAction::SetTrue)
33+
.help("This flag will compile the lint crate and print all relevant environment values"),
34+
)
35+
.subcommand(setup_command())
36+
.subcommand(check_command())
37+
.args(check_command_args())
38+
.after_help(AFTER_HELP_MSG)
39+
.override_usage("cargo-marker [OPTIONS] -- <CARGO ARGS>")
40+
}
41+
42+
fn setup_command() -> Command {
43+
Command::new("setup")
44+
.about("A collection of commands to setup marker")
45+
.after_help("By default this will install the driver for rustc.")
46+
}
47+
48+
fn check_command() -> Command {
49+
Command::new("check")
50+
.about("Run marker on a local package")
51+
.args(check_command_args())
52+
}
53+
54+
fn check_command_args() -> impl IntoIterator<Item = impl Into<Arg>> {
55+
vec![
56+
Arg::new("lints")
57+
.short('l')
58+
.long("lints")
59+
.num_args(1..)
60+
.help("Defines a set of lints crates that should be used"),
61+
]
62+
}

cargo-marker/src/driver.rs

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,8 @@
1111
//! That command will first ensure that the required toolchain is installed and then
1212
//! run `cargo install` for the driver with a specific toolchain. The version and
1313
//! toolchain are hardcoded in this crate.
14-
//!
15-
//! If a driver is already installed. We'll first run the driver to request the
16-
//! required toolchain and then run the driver using that toolchain. Requesting
17-
//! the toolchain works, since the argument will be processed before rustc is run.
18-
//! At least, that's the idea.
1914
20-
use std::process::Command;
15+
use std::{path::PathBuf, process::Command};
2116

2217
use once_cell::sync::Lazy;
2318

@@ -28,11 +23,35 @@ use crate::ExitStatus;
2823
static DEFAULT_DRIVER_INFO: Lazy<RustcDriverInfo> = Lazy::new(|| RustcDriverInfo {
2924
toolchain: "nightly-2022-11-03".to_string(),
3025
version: "0.1.0".to_string(),
26+
api_version: "0.1.0".to_string(),
3127
});
3228

3329
struct RustcDriverInfo {
3430
toolchain: String,
3531
version: String,
32+
#[allow(unused)]
33+
api_version: String,
34+
}
35+
36+
/// This tries to install the rustc driver specified in [`DEFAULT_DRIVER_INFO`].
37+
pub fn install_driver(verbose: bool) -> Result<(), ExitStatus> {
38+
// The toolchain, driver version and api version should ideally be configurable.
39+
// However, that will require more prototyping and has a low priority rn.
40+
// See #60
41+
42+
// Prerequisites
43+
let toolchain = &DEFAULT_DRIVER_INFO.toolchain;
44+
check_toolchain(toolchain)?;
45+
46+
build_driver(
47+
toolchain,
48+
&DEFAULT_DRIVER_INFO.version,
49+
verbose,
50+
cfg!(feature = "dev-build"),
51+
)?;
52+
53+
// We don't want to advice the user, to install the driver again.
54+
check_driver(verbose, false)
3655
}
3756

3857
/// This function checks if the specified toolchain is installed. This requires
@@ -41,7 +60,7 @@ fn check_toolchain(toolchain: &str) -> Result<(), ExitStatus> {
4160
let mut cmd = Command::new("cargo");
4261
cmd.args([&format!("+{toolchain}"), "-V"]);
4362
if cmd.output().is_err() {
44-
eprintln!("error: the required toolchain `{toolchain}` can't be found");
63+
eprintln!("Error: The required toolchain `{toolchain}` can't be found");
4564
eprintln!();
4665
eprintln!("You can install the toolchain by running: rustup toolchain install {toolchain}");
4766
Err(ExitStatus::InvalidToolchain)
@@ -50,29 +69,32 @@ fn check_toolchain(toolchain: &str) -> Result<(), ExitStatus> {
5069
}
5170
}
5271

53-
/// This tries to install the rustc driver specified in [`DEFAULT_DRIVER_INFO`].
54-
pub fn install_driver(verbose: bool) -> Result<(), ExitStatus> {
55-
// Prerequisites
56-
let toolchain = &DEFAULT_DRIVER_INFO.toolchain;
57-
check_toolchain(&toolchain)?;
72+
/// This tries to compile the driver. If successful the driver binary will
73+
/// be places next to the executable of `cargo-linter`.
74+
fn build_driver(toolchain: &str, version: &str, verbose: bool, dev_build: bool) -> Result<(), ExitStatus> {
75+
if dev_build {
76+
println!("Compiling rustc driver");
77+
} else {
78+
println!("Compiling rustc driver v{version} with {toolchain}");
79+
}
5880

5981
// Build driver
6082
let mut cmd = Command::new("cargo");
61-
cmd.arg(&format!("+{toolchain}"));
83+
84+
if !dev_build {
85+
cmd.arg(&format!("+{toolchain}"));
86+
}
6287

6388
if verbose {
6489
cmd.arg("--verbose");
6590
}
6691

67-
#[cfg(feature = "dev-build")]
68-
cmd.args(["build", "--bin", "linter_driver_rustc"]);
69-
#[cfg(not(feature = "dev-build"))]
70-
cmd.args([
71-
"install",
72-
"marker_rustc_driver",
73-
"--version",
74-
&DEFAULT_DRIVER_INFO.version,
75-
]);
92+
if dev_build {
93+
cmd.args(["build", "--bin", "marker_driver_rustc"]);
94+
} else {
95+
// TODO Set output path to the local branch thingy
96+
cmd.args(["install", "marker_rustc_driver", "--version", version]);
97+
}
7698

7799
let status = cmd
78100
.spawn()
@@ -87,3 +109,34 @@ pub fn install_driver(verbose: bool) -> Result<(), ExitStatus> {
87109
Err(ExitStatus::DriverInstallationFailed)
88110
}
89111
}
112+
113+
fn check_driver(verbose: bool, print_advice: bool) -> Result<(), ExitStatus> {
114+
let path = get_driver_path();
115+
if verbose {
116+
println!("Searching for driver at: {}", path.display());
117+
}
118+
119+
if !path.exists() || !path.is_file() {
120+
if print_advice {
121+
eprintln!("Error: The driver binary could not be found.");
122+
eprintln!();
123+
eprintln!("Try installing it via `cargo marker setup`");
124+
}
125+
126+
Err(ExitStatus::MissingDriver)
127+
} else {
128+
Ok(())
129+
}
130+
}
131+
132+
pub fn get_driver_path() -> PathBuf {
133+
#[allow(unused_mut)]
134+
let mut path = std::env::current_exe()
135+
.expect("unable to retrieve the path of the current executable")
136+
.with_file_name("marker_driver_rustc");
137+
138+
#[cfg(target_os = "windows")]
139+
path.set_extension("exe");
140+
141+
path
142+
}

cargo-marker/src/lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)