cli: make concurrent description-editing not use the same file

If you ran two concurrent `jj describe` (for example) before this
patch, they'd both try to open an editor on the same file. This patch
fixes that by randomizing the filename. It also deletes the file at
the end so the `.jj/` directory is not cluttered by these files.
This commit is contained in:
Martin von Zweigbergk 2021-05-15 14:05:56 -07:00
parent 6d61475f66
commit 798a6f7a74
3 changed files with 10 additions and 5 deletions

1
Cargo.lock generated
View file

@ -559,6 +559,7 @@ dependencies = [
"pest_derive", "pest_derive",
"protobuf", "protobuf",
"protobuf-codegen-pure", "protobuf-codegen-pure",
"rand 0.8.0",
"regex", "regex",
"serde_json", "serde_json",
"tempfile", "tempfile",

View file

@ -35,6 +35,7 @@ pest = "2.1.3"
pest_derive = "2.1.0" pest_derive = "2.1.0"
protobuf = { version = "2.22.1", features = ["with-bytes"] } protobuf = { version = "2.22.1", features = ["with-bytes"] }
protobuf-codegen-pure = "2.22.1" protobuf-codegen-pure = "2.22.1"
rand = "0.8.0"
serde_json = "1.0.60" serde_json = "1.0.60"
tempfile = "3.1.0" tempfile = "3.1.0"
thiserror = "1.0.22" thiserror = "1.0.22"

View file

@ -1310,13 +1310,12 @@ fn cmd_obslog(
} }
fn edit_description(repo: &ReadonlyRepo, description: &str) -> String { fn edit_description(repo: &ReadonlyRepo, description: &str) -> String {
// TODO: Where should this file live? The current location prevents two let random: u32 = rand::random();
// concurrent `jj describe` calls. let description_file_path = repo.repo_path().join(format!("description-{}", random));
let description_file_path = repo.repo_path().join("description");
{ {
let mut description_file = OpenOptions::new() let mut description_file = OpenOptions::new()
.write(true) .write(true)
.create(true) .create_new(true)
.truncate(true) .truncate(true)
.open(&description_file_path) .open(&description_file_path)
.unwrap_or_else(|_| panic!("failed to open {:?} for write", &description_file_path)); .unwrap_or_else(|_| panic!("failed to open {:?} for write", &description_file_path));
@ -1342,7 +1341,11 @@ fn edit_description(repo: &ReadonlyRepo, description: &str) -> String {
.unwrap_or_else(|_| panic!("failed to open {:?} for read", &description_file_path)); .unwrap_or_else(|_| panic!("failed to open {:?} for read", &description_file_path));
let mut buf = vec![]; let mut buf = vec![];
description_file.read_to_end(&mut buf).unwrap(); description_file.read_to_end(&mut buf).unwrap();
String::from_utf8(buf).unwrap() let description = String::from_utf8(buf).unwrap();
// Delete the file only if everything went well.
// TODO: Tell the user the name of the file we left behind.
std::fs::remove_file(description_file_path).ok();
description
} }
fn cmd_describe( fn cmd_describe(