Skip to content

Commit e57da8a

Browse files
authored
minor: utility to update version numbers for release (#986)
1 parent a11e2d6 commit e57da8a

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

etc/update_version/.gitignore

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

etc/update_version/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "update_version"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
argh = "0.1.12"
10+
regex = "1.10.2"

etc/update_version/src/main.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use std::{collections::HashMap, path::Path};
2+
3+
use regex::Regex;
4+
5+
#[derive(Debug)]
6+
struct Location {
7+
path: &'static Path,
8+
pattern: Regex, // must contain a (?<target>) match group
9+
}
10+
11+
impl Location {
12+
fn new(path: &'static str, pattern: &str) -> Self {
13+
Self {
14+
path: Path::new(path),
15+
pattern: Regex::new(pattern).unwrap(),
16+
}
17+
}
18+
}
19+
20+
struct PendingUpdates {
21+
files: HashMap<&'static Path, String>,
22+
}
23+
24+
impl PendingUpdates {
25+
fn new() -> Self {
26+
Self {
27+
files: HashMap::new(),
28+
}
29+
}
30+
31+
fn apply(&mut self, location: &Location, update: &str) {
32+
let text = self
33+
.files
34+
.entry(location.path)
35+
.or_insert_with(|| std::fs::read_to_string(location.path).unwrap());
36+
37+
if !location.pattern.is_match(text) {
38+
panic!("no match for {:?}", location);
39+
}
40+
let mut new_text = String::new();
41+
let mut last_match = 0;
42+
for caps in location.pattern.captures_iter(text) {
43+
let target = caps.name("target").expect("<target> capture group");
44+
let prefix = &text[last_match..target.start()];
45+
new_text.push_str(prefix);
46+
new_text.push_str(update);
47+
last_match = target.end();
48+
}
49+
new_text.push_str(&text[last_match..]);
50+
*text = new_text;
51+
}
52+
53+
fn write(self) {
54+
for (path, contents) in self.files {
55+
std::fs::write(path, contents).unwrap();
56+
}
57+
}
58+
}
59+
60+
#[derive(argh::FromArgs)]
61+
/// Update crate and git dependency versions in prep for release.
62+
struct Args {
63+
/// new version of the mongodb crate
64+
#[argh(option)]
65+
version: String,
66+
67+
/// version of the bson crate
68+
#[argh(option)]
69+
bson: Option<String>,
70+
71+
/// version of the mongocrypt crate
72+
#[argh(option)]
73+
mongocrypt: Option<String>,
74+
}
75+
76+
fn main() {
77+
let version_locs = vec![
78+
Location::new(
79+
"../../Cargo.toml",
80+
r#"name = "mongodb"\nversion = "(?<target>.*?)"\n"#,
81+
),
82+
Location::new("../../README.md", r#"mongodb = "(?<target>.*?)"\n"#),
83+
Location::new(
84+
"../../README.md",
85+
r#"\[dependencies.mongodb\]\nversion = "(?<target>.*?)"\n"#,
86+
),
87+
Location::new("../../src/lib.rs", r#"//! mongodb = "(?<target>.*?)"\n"#),
88+
Location::new("../../src/lib.rs", r#"//! version = "(?<target>.*?)"\n"#),
89+
Location::new(
90+
"../../src/lib.rs",
91+
r#"html_root_url = "https://docs.rs/mongodb/(?<target>.*?)""#,
92+
),
93+
Location::new(
94+
"../../manual/src/installation_features.md",
95+
r#"\[dependencies.mongodb\]\nversion = "(?<target>.*?)"\n"#,
96+
),
97+
];
98+
let bson_version_loc =
99+
Location::new("../../Cargo.toml", r#"bson = (?<target>\{ git = .*? \})\n"#);
100+
let mongocrypt_version_loc = Location::new(
101+
"../../Cargo.toml",
102+
r#"mongocrypt = (?<target>\{ git = .*? \})\n"#,
103+
);
104+
105+
let args: Args = argh::from_env();
106+
107+
let mut pending = PendingUpdates::new();
108+
for loc in &version_locs {
109+
pending.apply(loc, &args.version);
110+
}
111+
if let Some(bson) = args.bson {
112+
pending.apply(&bson_version_loc, &format!("{:?}", bson));
113+
}
114+
if let Some(mongocrypt) = args.mongocrypt {
115+
pending.apply(&mongocrypt_version_loc, &format!("{:?}", mongocrypt));
116+
}
117+
pending.write();
118+
}

0 commit comments

Comments
 (0)