Skip to content

Commit 6192366

Browse files
committed
add pr comment fixes
1 parent 8b0a926 commit 6192366

4 files changed

Lines changed: 110 additions & 17 deletions

File tree

Cargo.lock

Lines changed: 51 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: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,21 @@ sqlformat = "0.5.0"
3939
sysinfo = { version = "0.38.4", default-features = false, features = ["system"] }
4040
self_update = { version = "0.42", default-features = false, features = ["rustls"] }
4141
lzma-rs = "0.3"
42+
tempfile = "3"
4243

4344
[dev-dependencies]
4445
mockito = "1"
45-
tempfile = "3"
46+
47+
[build-dependencies]
48+
toml = "0.8"
49+
50+
# Project distribution config read by build.rs and exposed as compile-time
51+
# env vars (HOTDATA_HOMEBREW_FORMULA, ...) so source files don't hardcode
52+
# values that also live in the README / dist-workspace.toml.
53+
[package.metadata.hotdata]
54+
# Fully-qualified Homebrew install target. Matches the `brew install` line
55+
# in README.md; the trailing segment must match `formula` in dist-workspace.toml.
56+
homebrew_formula = "hotdata-dev/tap/cli"
4657

4758
[package.metadata.release]
4859
pre-release-hook = ["git-cliff", "-o", "CHANGELOG.md", "--tag", "v{{version}}" ]

build.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Reads `[package.metadata.hotdata]` from Cargo.toml and re-exports the
2+
// values as compile-time environment variables, so source files can read
3+
// distribution config (e.g. the Homebrew formula) via `env!()` without
4+
// duplicating strings that also live in README.md / dist-workspace.toml.
5+
6+
use std::path::PathBuf;
7+
8+
fn main() {
9+
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
10+
let manifest_path = manifest_dir.join("Cargo.toml");
11+
println!("cargo:rerun-if-changed={}", manifest_path.display());
12+
13+
let raw = std::fs::read_to_string(&manifest_path)
14+
.unwrap_or_else(|e| panic!("could not read {}: {e}", manifest_path.display()));
15+
let parsed: toml::Value = toml::from_str(&raw)
16+
.unwrap_or_else(|e| panic!("could not parse {}: {e}", manifest_path.display()));
17+
18+
let meta = parsed
19+
.get("package")
20+
.and_then(|p| p.get("metadata"))
21+
.and_then(|m| m.get("hotdata"))
22+
.unwrap_or_else(|| panic!("missing [package.metadata.hotdata] in Cargo.toml"));
23+
24+
let homebrew_formula = meta
25+
.get("homebrew_formula")
26+
.and_then(|v| v.as_str())
27+
.unwrap_or_else(|| panic!("missing package.metadata.hotdata.homebrew_formula"));
28+
29+
println!("cargo:rustc-env=HOTDATA_HOMEBREW_FORMULA={homebrew_formula}");
30+
}

src/update.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
99
const REPO_OWNER: &str = "hotdata-dev";
1010
const REPO_NAME: &str = "hotdata-cli";
1111
const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
12+
/// Fully-qualified Homebrew formula (e.g. `hotdata-dev/tap/cli`). Pulled from
13+
/// `[package.metadata.hotdata]` in Cargo.toml via build.rs so the README,
14+
/// dist-workspace.toml, and this binary all agree on the same target.
15+
const HOMEBREW_FORMULA: &str = env!("HOTDATA_HOMEBREW_FORMULA");
1216
const CHECK_INTERVAL_SECS: u64 = 86_400;
1317
const NETWORK_TIMEOUT_SECS: u64 = 5;
1418

@@ -134,8 +138,8 @@ pub fn maybe_print_update_notice() {
134138
return;
135139
};
136140
let how = match detect_install_method() {
137-
InstallMethod::Homebrew => "Run: brew upgrade hotdata",
138-
InstallMethod::Other => "Run: hotdata update",
141+
InstallMethod::Homebrew => format!("Run: brew upgrade {HOMEBREW_FORMULA}"),
142+
InstallMethod::Other => "Run: hotdata update".to_string(),
139143
};
140144
eprintln!(
141145
"{}",
@@ -151,7 +155,7 @@ pub fn run_update() {
151155

152156
if detect_install_method() == InstallMethod::Homebrew {
153157
println!("hotdata was installed via Homebrew. Update with:");
154-
println!(" {}", "brew upgrade hotdata".cyan());
158+
println!(" {}", format!("brew upgrade {HOMEBREW_FORMULA}").cyan());
155159
return;
156160
}
157161

@@ -222,23 +226,23 @@ fn perform_update(version: &Version) -> Result<(), String> {
222226
lzma_rs::xz_decompress(&mut std::io::Cursor::new(&xz_bytes[..]), &mut tar_bytes)
223227
.map_err(|e| format!("xz decompress: {e}"))?;
224228

225-
let tmp_dir = std::env::temp_dir().join(format!("hotdata-update-{}", std::process::id()));
226-
if tmp_dir.exists() {
227-
let _ = fs::remove_dir_all(&tmp_dir);
228-
}
229-
fs::create_dir_all(&tmp_dir).map_err(|e| format!("creating temp dir: {e}"))?;
229+
// `tempfile::TempDir` creates a randomly-named directory with 0700
230+
// permissions and removes it on drop. The random suffix prevents a
231+
// local attacker on a shared system from pre-planting a symlink at a
232+
// predictable path and redirecting the extraction to a directory
233+
// they control.
234+
let tmp_dir = tempfile::TempDir::new().map_err(|e| format!("creating temp dir: {e}"))?;
230235

231236
let mut archive = tar::Archive::new(std::io::Cursor::new(&tar_bytes[..]));
232237
archive
233-
.unpack(&tmp_dir)
238+
.unpack(tmp_dir.path())
234239
.map_err(|e| format!("extract tar: {e}"))?;
235240

236241
// cargo-dist lays out the tarball as `<asset-stem>/hotdata` (the binary
237242
// sits at the top of a single directory matching the asset name without
238243
// its extension).
239-
let new_binary = tmp_dir.join(&asset_stem).join("hotdata");
244+
let new_binary = tmp_dir.path().join(&asset_stem).join("hotdata");
240245
if !new_binary.exists() {
241-
let _ = fs::remove_dir_all(&tmp_dir);
242246
return Err(format!(
243247
"binary not found in archive at {}",
244248
new_binary.display()
@@ -253,13 +257,10 @@ fn perform_update(version: &Version) -> Result<(), String> {
253257
let backup = current_exe.with_extension("old");
254258
let _ = fs::remove_file(&backup);
255259

256-
let result = self_update::Move::from_source(&new_binary)
260+
self_update::Move::from_source(&new_binary)
257261
.replace_using_temp(&backup)
258262
.to_dest(&current_exe)
259-
.map_err(|e| format!("replacing binary: {e}"));
260-
261-
let _ = fs::remove_dir_all(&tmp_dir);
262-
result
263+
.map_err(|e| format!("replacing binary: {e}"))
263264
}
264265

265266
#[cfg(test)]

0 commit comments

Comments
 (0)