Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'lib/smol_str/.github/ci.rs')
-rw-r--r--lib/smol_str/.github/ci.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/smol_str/.github/ci.rs b/lib/smol_str/.github/ci.rs
new file mode 100644
index 0000000000..c594e8973c
--- /dev/null
+++ b/lib/smol_str/.github/ci.rs
@@ -0,0 +1,127 @@
+use std::{
+ env, fs,
+ process::{self, Command, ExitStatus, Stdio},
+ time::Instant,
+};
+
+type Error = Box<dyn std::error::Error>;
+type Result<T> = std::result::Result<T, Error>;
+
+fn main() {
+ if let Err(err) = try_main() {
+ eprintln!("{}", err);
+ process::exit(1);
+ }
+}
+
+fn try_main() -> Result<()> {
+ let cwd = env::current_dir()?;
+ let cargo_toml = cwd.join("Cargo.toml");
+ assert!(
+ cargo_toml.exists(),
+ "Cargo.toml not found, cwd: {}",
+ cwd.display()
+ );
+
+ {
+ let _s = Section::new("BUILD_NO_DEFAULT_FEATURES");
+ shell("cargo test --all-features --workspace --no-run --no-default-features")?;
+ }
+
+ {
+ let _s = Section::new("BUILD");
+ shell("cargo test --all-features --workspace --no-run")?;
+ }
+
+ {
+ let _s = Section::new("TEST");
+ shell("cargo test --all-features --workspace")?;
+ shell("cargo test --no-default-features --workspace")?;
+ }
+
+ {
+ let _s = Section::new("TEST_BENCHES");
+ shell("cargo test --benches --all-features")?;
+ }
+
+ let current_branch = shell_output("git branch --show-current")?;
+ if &current_branch == "master" {
+ let _s = Section::new("PUBLISH");
+ let manifest = fs::read_to_string(&cargo_toml)?;
+ let version = get_field(&manifest, "version")?;
+ let tag = format!("v{}", version);
+ let tags = shell_output("git tag --list")?;
+
+ if !tags.contains(&tag) {
+ let token = env::var("CRATES_IO_TOKEN").unwrap();
+ shell(&format!("git tag v{}", version))?;
+ shell(&format!("cargo publish --token {}", token))?;
+ shell("git push --tags")?;
+ }
+ }
+ Ok(())
+}
+
+fn get_field<'a>(text: &'a str, name: &str) -> Result<&'a str> {
+ for line in text.lines() {
+ let words = line.split_ascii_whitespace().collect::<Vec<_>>();
+ match words.as_slice() {
+ [n, "=", v, ..] if n.trim() == name => {
+ assert!(v.starts_with('"') && v.ends_with('"'));
+ return Ok(&v[1..v.len() - 1]);
+ }
+ _ => (),
+ }
+ }
+ Err(format!("can't find `{}` in\n----\n{}\n----\n", name, text))?
+}
+
+fn shell(cmd: &str) -> Result<()> {
+ let status = command(cmd).status()?;
+ check_status(status)
+}
+
+fn shell_output(cmd: &str) -> Result<String> {
+ let output = command(cmd).stderr(Stdio::inherit()).output()?;
+ check_status(output.status)?;
+ let res = String::from_utf8(output.stdout)?;
+ let res = res.trim().to_string();
+ println!("{}", res);
+ Ok(res)
+}
+
+fn command(cmd: &str) -> Command {
+ eprintln!("> {}", cmd);
+ let words = cmd.split_ascii_whitespace().collect::<Vec<_>>();
+ let (cmd, args) = words.split_first().unwrap();
+ let mut res = Command::new(cmd);
+ res.args(args);
+ res
+}
+
+fn check_status(status: ExitStatus) -> Result<()> {
+ if !status.success() {
+ Err(format!("$status: {}", status))?;
+ }
+ Ok(())
+}
+
+struct Section {
+ name: &'static str,
+ start: Instant,
+}
+
+impl Section {
+ fn new(name: &'static str) -> Section {
+ println!("::group::{}", name);
+ let start = Instant::now();
+ Section { name, start }
+ }
+}
+
+impl Drop for Section {
+ fn drop(&mut self) {
+ eprintln!("{}: {:.2?}", self.name, self.start.elapsed());
+ println!("::endgroup::");
+ }
+}