Skip to content

Commit 2318a66

Browse files
committed
Copy xtask version bumper from nrf-hal
Minor changes to accomodate the slightly different CHANGELOG format.
1 parent 3049f8a commit 2318a66

File tree

10 files changed

+302
-169
lines changed

10 files changed

+302
-169
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2626
- Fix rustdoc warnings
2727
- Upgrade nrf51-hal to 0.12.1
2828

29-
[Unreleased]: https://github.com/therealprof/microbit/compare/v0.9.0...HEAD
30-
[0.9.0]: https://github.com/therealprof/microbit/compare/v0.8.0...v0.9.0
29+
[Unreleased]: https://github.com/nrf-rs/microbit/compare/v0.9.0...HEAD
30+
[0.9.0]: https://github.com/nrf-rs/microbit/compare/v0.8.0...v0.9.0

microbit-common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! microbit contains everything required to get started with the use of Rust
22
//! to create firmwares for the fabulous [BBC micro:bit](https://microbit.org)
33
//! microcontroller board.
4+
#![doc(html_root_url = "https://docs.rs/microbit-common/0.9.0")]
45
#![no_std]
56
#![deny(missing_docs)]
67
#![allow(non_camel_case_types)]

microbit-v2/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ path = "src/lib.rs"
3232
[dependencies.microbit-common]
3333
path = "../microbit-common"
3434
features = ["v2"]
35+
version = "=0.9.0"

microbit-v2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//!
99
//! [<img src="https://github.com/microbit-foundation/microbit-svg/raw/master/microbit-drawing-back-1-5.png" width="372px" height="300px">](https://github.com/microbit-foundation/microbit-svg/blob/master/microbit-drawing-back-1-5.png)
1010
//! [<img src="https://github.com/microbit-foundation/microbit-svg/raw/master/microbit-drawing-back-2.png" width="372px" height="300px">](https://github.com/microbit-foundation/microbit-svg/blob/master/microbit-drawing-back-2.png)
11+
#![doc(html_root_url = "https://docs.rs/microbit-v2/0.9.0")]
1112
#![no_std]
1213
#![deny(missing_docs)]
1314
#![allow(non_camel_case_types)]

microbit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ license = "0BSD"
2828
[dependencies.microbit-common]
2929
path = "../microbit-common"
3030
features = ["v1"]
31+
version = "=0.9.0"

microbit/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//!
99
//! [<img src="https://github.com/microbit-foundation/microbit-svg/raw/master/microbit-drawing-back-1-5.png" width="372px" height="300px">](https://github.com/microbit-foundation/microbit-svg/blob/master/microbit-drawing-back-1-5.png)
1010
//! [<img src="https://github.com/microbit-foundation/microbit-svg/raw/master/microbit-drawing-back-2.png" width="372px" height="300px">](https://github.com/microbit-foundation/microbit-svg/blob/master/microbit-drawing-back-2.png)
11+
#![doc(html_root_url = "https://docs.rs/microbit/0.9.0")]
1112
#![no_std]
1213
#![deny(missing_docs)]
1314
#![allow(non_camel_case_types)]

xtask/src/bump.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//! This has been copied pretty much wholesale from https://github.com/nrf-rs/nrf-hal/blob/master/xtask/src/lib.rs
2+
use super::CRATES;
3+
use std::fs;
4+
5+
fn file_replace(path: &str, from: &str, to: &str, dry_run: bool) {
6+
let old_contents = fs::read_to_string(path).unwrap();
7+
let new_contents = old_contents.replacen(from, to, 1);
8+
if old_contents == new_contents {
9+
panic!("failed to replace `{}` -> `{}` in `{}`", from, to, path);
10+
}
11+
12+
if !dry_run {
13+
fs::write(path, new_contents).unwrap();
14+
}
15+
}
16+
17+
/// Bumps the versions of all crates and the changelog to `new_version`.
18+
///
19+
/// Dependency declarations are updated automatically. `html_root_url` is updated automatically.
20+
pub fn bump_versions(new_version: &str, dry_run: bool) {
21+
let common_toml_path = "microbit-common/Cargo.toml";
22+
let toml = fs::read_to_string(common_toml_path).unwrap();
23+
24+
let needle = "version = \"";
25+
let version_pos = toml.find(needle).unwrap() + needle.len();
26+
let version_rest = &toml[version_pos..];
27+
let end_pos = version_rest.find('"').unwrap();
28+
let old_version = &version_rest[..end_pos];
29+
30+
{
31+
// Bump the changelog first, also check that it isn't empty.
32+
let changelog_path = "CHANGELOG.md";
33+
let changelog = fs::read_to_string(changelog_path).unwrap();
34+
// (ignore empty changelog when this is a dry_run, since that runs in normal CI)
35+
assert!(
36+
dry_run || !changelog.contains("(no entries)"),
37+
"changelog contains `(no entries)`; please fill it"
38+
);
39+
40+
// Prepend empty "[Unreleased]" section, promote the current one.
41+
let from = String::from("## [Unreleased]");
42+
let to = format!("## [Unreleased]\n\n(no changes)\n\n## [{}]", new_version);
43+
file_replace(changelog_path, &from, &to, dry_run);
44+
45+
// Replace the Unreleased link
46+
let from = format!(
47+
r#"[Unreleased]: https://github.com/nrf-rs/microbit/compare/v{old_version}...HEAD"#,
48+
old_version = old_version,
49+
);
50+
let to = format!(
51+
r#"[Unreleased]: https://github.com/nrf-rs/microbit/compare/v{new_version}...HEAD"#,
52+
new_version = new_version,
53+
);
54+
file_replace(changelog_path, &from, &to, dry_run);
55+
56+
// Append release link at the end.
57+
let mut changelog = fs::read_to_string(changelog_path).unwrap();
58+
changelog.push_str(&format!(
59+
"[{new_version}]: https://github.com/nrf-rs/microbit/releases/tag/v{new_version}...v{old_version}\n",
60+
new_version = new_version,
61+
old_version = old_version,
62+
));
63+
if !dry_run {
64+
fs::write(changelog_path, changelog).unwrap();
65+
}
66+
}
67+
68+
{
69+
println!("microbit-common: {} -> {}", old_version, new_version);
70+
71+
// Bump `microbit-common`'s version.
72+
let from = format!(r#"version = "{}""#, old_version);
73+
let to = format!(r#"version = "{}""#, new_version);
74+
file_replace("microbit-common/Cargo.toml", &from, &to, dry_run);
75+
76+
// Bump the `html_root_url`.
77+
let from = format!(
78+
r#"#![doc(html_root_url = "https://docs.rs/microbit-common/{old_version}")]"#,
79+
old_version = old_version
80+
);
81+
let to = format!(
82+
r#"#![doc(html_root_url = "https://docs.rs/microbit-common/{new_version}")]"#,
83+
new_version = new_version
84+
);
85+
let librs_path = "microbit-common/src/lib.rs";
86+
file_replace(librs_path, &from, &to, dry_run);
87+
}
88+
89+
for (crate_name, _, _) in CRATES {
90+
println!("{}: {} -> {}", crate_name, old_version, new_version);
91+
let toml_path = format!("{}/Cargo.toml", crate_name);
92+
93+
// Bump the crate's version.
94+
let from = format!(r#"version = "{}""#, old_version);
95+
let to = format!(r#"version = "{}""#, new_version);
96+
file_replace(&toml_path, &from, &to, dry_run);
97+
98+
// Bump the crate's dependency on `microbit-common`.
99+
let from = format!(r#"version = "={}""#, old_version);
100+
let to = format!(r#"version = "={}""#, new_version);
101+
file_replace(&toml_path, &from, &to, dry_run);
102+
103+
// Bump the crate's `html_root_url`.
104+
let from = format!(
105+
r#"#![doc(html_root_url = "https://docs.rs/{crate}/{old_version}")]"#,
106+
crate = crate_name,
107+
old_version = old_version
108+
);
109+
let to = format!(
110+
r#"#![doc(html_root_url = "https://docs.rs/{crate}/{new_version}")]"#,
111+
crate = crate_name,
112+
new_version = new_version
113+
);
114+
let librs_path = format!("{}/src/lib.rs", crate_name);
115+
file_replace(&librs_path, &from, &to, dry_run);
116+
}
117+
}

xtask/src/ci.rs

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
use super::CRATES;
2+
use std::{collections::HashMap, env, fs, path, process::Command};
3+
4+
pub static DEPENDENCIES: &[&str] = &["flip-link"];
5+
6+
fn install_targets() {
7+
let targets = CRATES
8+
.iter()
9+
.map(|(_, target, _)| *target)
10+
.collect::<Vec<_>>();
11+
12+
let mut rustup = Command::new("rustup");
13+
rustup.args(&["target", "add"]).args(&targets);
14+
let status = rustup
15+
.status()
16+
.map_err(|e| format!("couldn't execute {:?}: {}", rustup, e))
17+
.unwrap();
18+
assert!(
19+
status.success(),
20+
"failed to install targets with rustup: {:?}",
21+
rustup
22+
);
23+
}
24+
25+
/// Install global dependencies
26+
fn install_dependencies() {
27+
for dependency in DEPENDENCIES {
28+
let mut cargo = Command::new("cargo");
29+
cargo.args(&["install", dependency]);
30+
let status = cargo
31+
.status()
32+
.map_err(|e| format!("couldn't execute {:?}: {}", cargo, e))
33+
.unwrap();
34+
assert!(status.success(),);
35+
}
36+
}
37+
38+
/// Build-test each board support crate
39+
fn build_crates() {
40+
for (hal, target, _) in CRATES {
41+
let mut cargo = Command::new("cargo");
42+
let toml_path = format!("{}/Cargo.toml", hal);
43+
let status = cargo
44+
.args(&["build", "--manifest-path", &toml_path, "--target", target])
45+
.status()
46+
.map_err(|e| format!("could not execute {:?}: {}", cargo, e))
47+
.unwrap();
48+
assert!(
49+
status.success(),
50+
"command exited with error status: {:?}",
51+
cargo
52+
);
53+
}
54+
}
55+
56+
/// Build/Run doc-tests in `microbit-common` for each version.
57+
fn build_run_doc_tests() {
58+
for (_, _, feature) in CRATES {
59+
let mut cargo = Command::new("cargo");
60+
let status = cargo
61+
.current_dir("microbit-common")
62+
.args(&["test", "--features", feature])
63+
.status()
64+
.map_err(|e| format!("could not execute {:?}: {}", cargo, e))
65+
.unwrap();
66+
assert!(
67+
status.success(),
68+
"command exited with error status: {:?}",
69+
cargo
70+
);
71+
}
72+
}
73+
74+
/// Build all examples with the boards they support
75+
fn build_examples() {
76+
let feature_targets = CRATES
77+
.iter()
78+
.map(|(_, target, feature)| (feature.to_string(), target.to_string()))
79+
.collect::<HashMap<_, _>>();
80+
81+
let crate_targets = CRATES
82+
.iter()
83+
.map(|(name, target, _)| (name.to_string(), target.to_string()))
84+
.collect::<HashMap<_, _>>();
85+
86+
for example in fs::read_dir("examples").unwrap() {
87+
let dir = example.unwrap();
88+
let manifest_path = dir.path().join("Cargo.toml");
89+
90+
// Skip if there is no manifest
91+
if !manifest_path.exists() {
92+
continue;
93+
}
94+
95+
let manifest = cargo_toml::Manifest::from_path(&manifest_path).unwrap();
96+
97+
// find features and their targets supported by the example
98+
let mut features = manifest
99+
.features
100+
.keys()
101+
.filter_map(|feature| {
102+
feature_targets
103+
.get(feature)
104+
.map(|target| (Some(feature.to_owned()), target.to_owned()))
105+
})
106+
.collect::<Vec<_>>();
107+
108+
// if there are no features find the target from the dependencies
109+
if features.len() == 0 {
110+
features = manifest
111+
.dependencies
112+
.keys()
113+
.filter_map(|name| {
114+
crate_targets
115+
.get(name)
116+
.map(|target| (None, target.to_owned()))
117+
})
118+
.collect::<Vec<_>>();
119+
assert_eq!(
120+
features.len(),
121+
1,
122+
"examples must depend on either microbit or microbit-v2"
123+
);
124+
}
125+
126+
for (feature, target) in features {
127+
build_example(&manifest_path, feature, target);
128+
}
129+
}
130+
}
131+
132+
fn build_example(manifest_path: &path::PathBuf, feature: Option<String>, target: String) {
133+
let mut cargo = Command::new("cargo");
134+
cargo.args(&[
135+
"build",
136+
"--target",
137+
&target,
138+
"--manifest-path",
139+
manifest_path.to_str().unwrap(),
140+
]);
141+
if let Some(feature) = feature {
142+
cargo.args(&["--features", &feature]);
143+
}
144+
145+
let status = cargo
146+
.status()
147+
.map_err(|e| format!("could not execute {:?}: {}", cargo, e))
148+
.unwrap();
149+
150+
assert!(
151+
status.success(),
152+
"command exited with error status: {:?}",
153+
cargo
154+
);
155+
}
156+
157+
pub fn ci() {
158+
install_targets();
159+
install_dependencies();
160+
161+
// move up if we're running from inside xtask
162+
if env::current_dir().unwrap().ends_with("xtask") {
163+
env::set_current_dir("..").unwrap();
164+
}
165+
166+
build_crates();
167+
build_run_doc_tests();
168+
build_examples();
169+
}

0 commit comments

Comments
 (0)