Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl<T: ?Sized> Arc<T> {
/// allocation
#[inline]
pub(crate) fn ptr_eq(this: &Self, other: &Self) -> bool {
this.ptr() == other.ptr()
std::ptr::addr_eq(this.ptr(), other.ptr())
}

pub(crate) fn ptr(&self) -> *mut ArcInner<T> {
Expand Down
2 changes: 1 addition & 1 deletion src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ impl NodeData {
}
}
#[inline]
fn green_siblings(&self) -> slice::Iter<GreenChild> {
fn green_siblings(&self) -> slice::Iter<'_, GreenChild> {
match &self.parent().map(|it| &it.green) {
Some(Green::Node { ptr }) => unsafe { &*ptr.get().as_ptr() }.children().raw,
Some(Green::Token { .. }) => {
Expand Down
2 changes: 1 addition & 1 deletion src/green/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl GreenNode {

impl GreenChild {
#[inline]
pub(crate) fn as_ref(&self) -> GreenElementRef {
pub(crate) fn as_ref(&self) -> GreenElementRef<'_> {
match self {
GreenChild::Node { node, .. } => NodeOrToken::Node(node),
GreenChild::Token { token, .. } => NodeOrToken::Token(token),
Expand Down
3 changes: 2 additions & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
edition = "2021"

[dependencies]
xaction = "0.2"
anyhow = "1.0.103"
xshell = "0.2.7"
179 changes: 162 additions & 17 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use std::env;
use std::{
env,
path::PathBuf,
sync::atomic::{AtomicBool, Ordering},
time::{Duration, Instant},
};

use xaction::{cargo_toml, cmd, git, section, Result};
use anyhow::anyhow;
use xshell::{cmd, Shell};
pub type Result<T> = anyhow::Result<T>;

fn main() {
if let Err(err) = try_main() {
Expand All @@ -9,44 +16,167 @@ fn main() {
}
}

pub struct Section {
name: &'static str,
start: Instant,
}

pub struct CargoToml {
path: PathBuf,
contents: String,
}

impl CargoToml {
pub fn version(&self) -> Result<&str> {
self.get("version")
}

fn get(&self, field: &str) -> Result<&str> {
for line in self.contents.lines() {
let words = line.split_ascii_whitespace().collect::<Vec<_>>();
match words.as_slice() {
[n, "=", v, ..] if n.trim() == field => {
assert!(v.starts_with('"') && v.ends_with('"'));
return Ok(&v[1..v.len() - 1]);
}
_ => (),
}
}
Err(anyhow!("can't find `{}` in {}", field, self.path.display()))?
}

pub fn publish(&self, sh: &mut Shell) -> Result<()> {
let token = env::var("CRATES_IO_TOKEN").unwrap_or("no token".to_string());
let dry_run = dry_run();
cmd!(sh, "cargo publish --token {token} {dry_run...}").run()?;
Ok(())
}

pub fn publish_all(&self, dirs: &[&str], sh: &mut Shell) -> Result<()> {
let token = env::var("CRATES_IO_TOKEN").unwrap_or("no token".to_string());
if dry_run().is_none() {
for &dir in dirs {
for _ in 0..20 {
std::thread::sleep(Duration::from_secs(10));
if cmd!(
sh,
"cargo publish --manifest-path {dir}'/Cargo.toml' --token {token} --dry-run"
)
.run()
.is_ok()
{
break;
}
}
cmd!(sh, "cargo publish --manifest-path {dir}'/Cargo.toml' --token {token}")
.run()?;
}
}
Ok(())
}
}

fn dry_run() -> Option<&'static str> {
let dry_run = DRY_RUN.load(Ordering::Relaxed);
if dry_run {
Some("--dry-run")
} else {
None
}
}

pub fn section(name: &'static str) -> Section {
Section::new(name)
}

pub fn cargo_toml() -> Result<CargoToml> {
let manifest_dir = env::var("CARGO_MANIFEST_DIR")?;
let path = PathBuf::from(manifest_dir).join("Cargo.toml");
let contents = std::fs::read_to_string(&path)?;
Ok(CargoToml { path, contents })
}

static DRY_RUN: AtomicBool = AtomicBool::new(false);
pub fn set_dry_run(yes: bool) {
DRY_RUN.store(yes, Ordering::Relaxed)
}

fn try_main() -> Result<()> {
let mut sh = Shell::new()?;
let subcommand = std::env::args().nth(1);
match subcommand {
Some(it) if it == "ci" => (),
_ => {
print_usage();
Err("invalid arguments")?
Err(anyhow!("invalid arguments"))?
}
}

let cargo_toml = cargo_toml()?;

{
let _s = section("BUILD");
cmd!("cargo test --workspace --no-run").run()?;
}

{
let _s = section("TEST");
cmd!("cargo test --workspace -- --nocapture").run()?;
for &release in &[None, Some("--release")] {
cmd!(sh, "cargo test {release...} --workspace -- --nocapture").run()?;
}
}

let version = cargo_toml.version()?;
let tag = format!("v{}", version);

let dry_run =
env::var("CI").is_err() || git::has_tag(&tag)? || git::current_branch()? != "master";
xaction::set_dry_run(dry_run);
let dry_run = env::var("CI").is_err()
|| git::has_tag(&tag, &mut sh)?
|| git::current_branch(&mut sh)? != "master";
set_dry_run(dry_run);

{
let _s = section("PUBLISH");
cargo_toml.publish()?;
git::tag(&tag)?;
git::push_tags()?;
cargo_toml.publish(&mut sh)?;
git::tag(&tag, &mut sh)?;
git::push_tags(&mut sh)?;
}
Ok(())
}

pub mod git {
use xshell::{cmd, Shell};

use super::{dry_run, Result};

pub fn current_branch(sh: &mut Shell) -> Result<String> {
let res = cmd!(sh, "git branch --show-current").read()?;
Ok(res)
}

pub fn tag_list(sh: &mut Shell) -> Result<Vec<String>> {
let tags = cmd!(sh, "git tag --list").read()?;
let res = tags.lines().map(|it| it.trim().to_string()).collect();
Ok(res)
}

pub fn has_tag(tag: &str, sh: &mut Shell) -> Result<bool> {
let res = tag_list(sh)?.iter().any(|it| it == tag);
Ok(res)
}

pub fn tag(tag: &str, sh: &mut Shell) -> Result<()> {
if dry_run().is_some() {
return Ok(());
}
cmd!(sh, "git tag {tag}").run()?;
Ok(())
}

pub fn push_tags(sh: &mut Shell) -> Result<()> {
// `git push --tags --dry-run` exists, but it will fail with permissions
// error for forks.
if dry_run().is_some() {
return Ok(());
}

cmd!(sh, "git push --tags").run()?;
Ok(())
}
}

fn print_usage() {
eprintln!(
"\
Expand All @@ -57,3 +187,18 @@ SUBCOMMANDS:
"
)
}

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::");
}
}
5 changes: 3 additions & 2 deletions xtask/tests/tidy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use xaction::cmd;
use xshell::{cmd, Shell};

#[test]
fn test_formatting() {
cmd!("cargo fmt --all -- --check").run().unwrap()
let sh = Shell::new().unwrap();
cmd!(sh, "cargo fmt --all -- --check").run().unwrap()
}
Loading