Skip to content

Commit 3544636

Browse files
authored
Add automatic tool installation via cargo. (#28)
Tools are installed in the per-user data directory with manifest tracking.
1 parent bb4d769 commit 3544636

18 files changed

Lines changed: 673 additions & 66 deletions

File tree

.prep/prep.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ license = "Apache-2.0 OR MIT"
55
[tools]
66
rustup = "=1"
77
rust = "=1.93"
8-
ripgrep = "=14.1.1"
8+
ripgrep = "=15.1.0"

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
### Added
66

77
* `tools` command for tool management. ([#27] by [@xStrom])
8+
* Automatic installation of tools from source via `cargo`.
9+
Now implemented for `ripgrep`. ([#28] by [@xStrom])
810
* `--strict` option to `clippy`, `copyright`, and `format` commands to use locked tool versions. ([#27] by [@xStrom])
911

12+
### Changed
13+
14+
* `ci` command now also runs the `copyright` command. ([#28] by [@xStrom])
15+
1016
## [0.2.0] - 2026-02-07
1117

1218
### Added
@@ -39,6 +45,7 @@
3945
[#23]: https://github.com/Nevermore/prep/pull/23
4046
[#24]: https://github.com/Nevermore/prep/pull/24
4147
[#27]: https://github.com/Nevermore/prep/pull/27
48+
[#28]: https://github.com/Nevermore/prep/pull/28
4249

4350
[Unreleased]: https://github.com/Nevermore/prep/compare/v0.2.0...HEAD
4451
[0.2.0]: https://github.com/Nevermore/prep/compare/v0.1.0...v0.2.0

Cargo.lock

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rust.missing_docs = "warn"
1717
anyhow = "1.0.101"
1818
cargo_metadata = "0.23.1"
1919
clap = "4.5.57"
20+
directories = "6.0.0"
2021
regex = "1.12.3"
2122
semver = "1.0.27"
2223
serde = "1.0.228"

prep/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ workspace = true
2222
anyhow.workspace = true
2323
cargo_metadata.workspace = true
2424
clap = { workspace = true, features = ["derive"] }
25+
directories.workspace = true
2526
regex.workspace = true
2627
semver.workspace = true
2728
serde = { workspace = true, features = ["derive"] }
28-
time.workspace = true
29+
time = { workspace = true, features = ["serde", "serde-human-readable"] }
2930
toml.workspace = true

prep/build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2026 the Prep Authors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! Prep's build script.
5+
6+
use std::env;
7+
8+
fn main() {
9+
let target = env::var("TARGET").expect("failed to read TARGET environment variable");
10+
println!("cargo:rustc-env=PREP_HOST_TRIPLE={target}");
11+
}

prep/src/cmd/ci.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2026 the Prep Authors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
use crate::cmd::{CargoTargets, clippy, format};
4+
use crate::cmd::{CargoTargets, clippy, copyright, format};
55
use crate::session::Session;
66

77
/// Runs CI verification.
@@ -21,7 +21,7 @@ pub fn run(session: &mut Session, extended: bool, fail_fast: bool) -> anyhow::Re
2121
Ok(())
2222
};
2323

24-
//step(&|| copyright::run(session))?;
24+
step(&mut || copyright::run(session, true))?;
2525
step(&mut || format::run(session, true, true))?;
2626

2727
if extended {

prep/src/cmd/copyright.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright 2026 the Prep Authors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
use std::process::Command;
5-
64
use anyhow::{Context, bail, ensure};
75
use time::UtcDateTime;
86

97
use crate::session::Session;
8+
use crate::tools::cargo::CargoDeps;
9+
use crate::tools::ripgrep::{Ripgrep, RipgrepDeps};
1010
use crate::ui;
1111
use crate::ui::style::{ERROR, HEADER, LITERAL, NOTE};
1212

@@ -16,13 +16,26 @@ use crate::ui::style::{ERROR, HEADER, LITERAL, NOTE};
1616
/// Verify copyright headers.
1717
///
1818
/// In `strict` mode ripgrep version is locked.
19-
pub fn run(session: &mut Session, _strict: bool) -> anyhow::Result<()> {
20-
let config = session.config();
21-
let project = config.project();
19+
pub fn run(session: &mut Session, strict: bool) -> anyhow::Result<()> {
20+
let mut cmd = if strict {
21+
let tools_cfg = session.config().tools();
22+
let cargo_ver_req = tools_cfg.rust().clone();
23+
let rustup_ver_req = tools_cfg.rustup().clone();
24+
let ver_req = tools_cfg.ripgrep().clone();
25+
let toolset = session.toolset();
26+
let cargo_deps = CargoDeps::new(rustup_ver_req);
27+
let deps = RipgrepDeps::new(cargo_deps, cargo_ver_req);
28+
toolset.get::<Ripgrep>(&deps, &ver_req)?
29+
} else {
30+
let toolset = session.toolset();
31+
let cargo_deps = CargoDeps::new(None);
32+
let deps = RipgrepDeps::new(cargo_deps, None);
33+
toolset.get::<Ripgrep>(&deps, None)?
34+
};
35+
36+
let project = session.config().project();
2237
let header_regex = header_regex(project.name(), project.license());
2338

24-
// TODO: Strict mode for ripgrep.
25-
let mut cmd = Command::new("rg");
2639
let cmd = cmd
2740
.current_dir(session.root_dir())
2841
.arg(header_regex)

prep/src/cmd/tools/list.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use crate::session::Session;
55
use crate::tools::cargo::Cargo;
6+
use crate::tools::ripgrep::Ripgrep;
67
use crate::tools::rustup::Rustup;
78
use crate::ui::style::TABLE_HEADER;
89

@@ -26,7 +27,10 @@ pub fn run(session: &mut Session) -> anyhow::Result<()> {
2627
.default_version::<Cargo>()?
2728
.map(|v| format!("{v}"))
2829
.unwrap_or_else(|| MISSING.into());
29-
let rg_global = String::from("Who knows");
30+
let rg_global = toolset
31+
.default_version::<Ripgrep>()?
32+
.map(|v| format!("{v}"))
33+
.unwrap_or_else(|| MISSING.into());
3034

3135
fn cell(s: &str, len: usize) -> String {
3236
let mut s = String::from(s);

prep/src/host.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2026 the Prep Authors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
/// The triple that Prep was compiled for and thus is running on.
5+
#[expect(dead_code, reason = "for the future")]
6+
pub const TRIPLE: &str = env!("PREP_HOST_TRIPLE");
7+
8+
/// Returns the executable file name.
9+
///
10+
/// Appends `.exe` on Windows, does nothing on other platforms.
11+
pub fn executable_name(name: &str) -> String {
12+
//#[cfg(target_os = "windows")]
13+
if cfg!(target_os = "windows") {
14+
format!("{name}.exe")
15+
} else {
16+
name.to_string()
17+
}
18+
}

0 commit comments

Comments
 (0)