aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
authorBob McWhirter <[email protected]>2021-08-17 12:15:24 -0400
committerBob McWhirter <[email protected]>2021-08-17 15:23:08 -0400
commit61e6b52870072a95c2ec2b3701323fc493e0e8eb (patch)
treeb67dec216c3448ca9ae1036128b4ebf7e1eb8b0f /xtask
parentbc57d6839f817a4779525e6032de5ebe0ef1cba5 (diff)
xtask runner for CI types of things and other utilities.
Diffstat (limited to 'xtask')
-rw-r--r--xtask/.cargo/config6
-rw-r--r--xtask/Cargo.toml14
-rw-r--r--xtask/src/main.rs225
3 files changed, 245 insertions, 0 deletions
diff --git a/xtask/.cargo/config b/xtask/.cargo/config
new file mode 100644
index 000000000..919ec05a4
--- /dev/null
+++ b/xtask/.cargo/config
@@ -0,0 +1,6 @@
1[alias]
2xtask = "run --package xtask --"
3ci = "run --package xtask -- ci"
4core = "run --package xtask -- core"
5examples = "run --package xtask -- examples"
6fmt = "run --package xtask -- fmt"
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
new file mode 100644
index 000000000..ffa06ea9e
--- /dev/null
+++ b/xtask/Cargo.toml
@@ -0,0 +1,14 @@
1[package]
2authors = [
3 "Ulf Lilleengen <[email protected]>",
4 "Bob McWhirter <[email protected]>"
5]
6edition = "2018"
7name = "xtask"
8version = "0.1.0"
9
10[dependencies]
11anyhow = "1.0"
12xshell = "0.1"
13yaml-rust = "0.4"
14walkdir = "2.3.2" \ No newline at end of file
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
new file mode 100644
index 000000000..d8d5e07da
--- /dev/null
+++ b/xtask/src/main.rs
@@ -0,0 +1,225 @@
1#![allow(dead_code)]
2#![deny(unused_must_use)]
3
4use std::format;
5use std::{env, fs, path::PathBuf};
6
7use std::path::Path;
8use walkdir::WalkDir;
9use xshell::{cmd, Cmd};
10use yaml_rust::YamlLoader;
11
12extern crate yaml_rust;
13
14fn main() -> Result<(), anyhow::Error> {
15 let args = env::args().skip(1).collect::<Vec<_>>();
16 let args = args.iter().map(|s| &**s).collect::<Vec<_>>();
17
18 match &args[..] {
19 ["ci"] => task_ci()?,
20 ["core"] => task_check(Realm::Core)?,
21 ["metapac"] => task_metapac_gen()?,
22 ["examples"] => task_check(Realm::Examples)?,
23 ["fmt-check"] => task_cargo_fmt_check()?,
24 ["fmt"] => task_cargo_fmt()?,
25 _ => {
26 println!("");
27 println!("USAGE: cargo xtask [command]");
28 println!("");
29 println!("Commands:");
30 println!(" ci :: Runs entire CI");
31 println!(" core :: Builds the core");
32 println!(" metapac :: Builds the metapac");
33 println!(" examples :: Builds the examples");
34 println!(" fmt-check :: Checks rustfmt");
35 println!(" fmt :: Performs rustfmt");
36 println!("");
37 }
38 }
39 Ok(())
40}
41
42fn task_ci() -> Result<(), anyhow::Error> {
43 task_check(Realm::Core)?;
44 task_check(Realm::Examples)?;
45 task_metapac_gen()?;
46 task_cargo_fmt_check()?;
47 Ok(())
48}
49
50#[derive(Copy, Clone)]
51enum Realm {
52 All,
53 Core,
54 Examples,
55}
56
57impl Realm {
58 fn accepts(&self, package: &str) -> bool {
59 match self {
60 Realm::All => true,
61 Realm::Core => !package.contains("examples"),
62 Realm::Examples => package.contains("examples"),
63 }
64 }
65}
66
67fn task_check(realm: Realm) -> Result<(), anyhow::Error> {
68 let _e = xshell::pushenv("CI", "true");
69
70 let matrix_yaml = root_dir()
71 .join(".github")
72 .join("workflows")
73 .join("rust.yml");
74
75 let matrix = YamlLoader::load_from_str(&*fs::read_to_string(matrix_yaml).unwrap()).unwrap();
76
77 let matrix = &matrix.get(0).unwrap()["jobs"]["ci"]["strategy"]["matrix"]["include"];
78
79 let entries = matrix.as_vec().unwrap();
80
81 for entry in entries {
82 let package = entry["package"].as_str().unwrap();
83 if !realm.accepts(package) {
84 continue;
85 }
86 let target = entry["target"].as_str().unwrap();
87 let features = entry["features"].as_str();
88 let package_dir = root_dir().join(entry["package"].as_str().unwrap());
89 let _p = xshell::pushd(package_dir)?;
90 banner(&*format!(
91 "Building {} [target={}] [features={}]",
92 package,
93 target,
94 features.unwrap_or("default-features")
95 ));
96
97 let root_cargo_dir = root_dir().join(".cargo");
98 fs::create_dir_all(root_cargo_dir.clone()).unwrap();
99 fs::write(
100 root_cargo_dir.join("config"),
101 "[target.\"cfg(all())\"]\nrustflags = [\"-D\", \"warnings\"]",
102 )
103 .unwrap();
104
105 let mut args = Vec::new();
106 args.push("check");
107 args.push("--target");
108 args.push(target);
109
110 if let Some(features) = features {
111 args.push("--features");
112 args.push(features);
113 }
114
115 let command = Cmd::new(PathBuf::from("cargo"));
116 let command = command.args(args);
117 let result = command.run();
118
119 fs::remove_file(root_cargo_dir.join("config")).unwrap();
120
121 result?;
122 }
123
124 Ok(())
125}
126
127fn task_metapac_gen() -> Result<(), anyhow::Error> {
128 banner("Building metapac");
129 let _p = xshell::pushd(root_dir().join("stm32-metapac-gen"));
130 cmd!("cargo run").run()?;
131 Ok(())
132}
133
134fn task_cargo_fmt() -> Result<(), anyhow::Error> {
135 for entry in WalkDir::new(root_dir())
136 .follow_links(false)
137 .into_iter()
138 .filter_map(|e| e.ok())
139 {
140 let f_name = entry.file_name().to_string_lossy();
141
142 if f_name.ends_with(".rs") {
143 if !is_primary_source(entry.path()) {
144 continue;
145 }
146 let mut args = Vec::new();
147 args.push("--skip-children");
148 args.push("--unstable-features");
149 args.push("--edition=2018");
150 args.push(&*entry.path().to_str().unwrap());
151 let command = Cmd::new("rustfmt");
152 command.args(args).run()?;
153 }
154 }
155
156 Ok(())
157}
158
159fn task_cargo_fmt_check() -> Result<(), anyhow::Error> {
160 let mut actual_result = Ok(());
161 for entry in WalkDir::new(root_dir())
162 .follow_links(false)
163 .into_iter()
164 .filter_map(|e| e.ok())
165 {
166 let f_name = entry.file_name().to_string_lossy();
167
168 if f_name.ends_with(".rs") {
169 if !is_primary_source(entry.path()) {
170 continue;
171 }
172 let mut args = Vec::new();
173 args.push("--check");
174 args.push("--skip-children");
175 args.push("--unstable-features");
176 args.push("--edition=2018");
177 args.push(&*entry.path().to_str().unwrap());
178 let command = Cmd::new("rustfmt");
179 if let Err(result) = command.args(args).run() {
180 actual_result = Err(result.into());
181 }
182 }
183 }
184
185 actual_result
186}
187
188fn root_dir() -> PathBuf {
189 let mut xtask_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
190 xtask_dir.pop();
191 xtask_dir
192}
193
194fn examples_dir() -> PathBuf {
195 root_dir().join("examples")
196}
197
198fn is_primary_source(path: &Path) -> bool {
199 let mut current = path;
200
201 loop {
202 let current_file_name = current.file_name().unwrap().to_str().unwrap();
203 if current_file_name == "target"
204 || current_file_name == "stm32-metapac-gen"
205 || current_file_name == "stm32-data"
206 {
207 return false;
208 }
209
210 if let Some(path) = current.parent() {
211 current = path.into();
212 if current == root_dir() {
213 return true;
214 }
215 } else {
216 return false;
217 }
218 }
219}
220
221fn banner(text: &str) {
222 println!("------------------------------------------------------------------------------------------------------------------------------------------------");
223 println!("== {}", text);
224 println!("------------------------------------------------------------------------------------------------------------------------------------------------");
225}