From 18aa04631bfea8ed40b382901190fd1121071d57 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 20 Jun 2023 11:17:35 +0200 Subject: [PATCH 1/3] Determine crates to publish automatically --- tools/release-operator/src/registry.rs | 62 ++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/tools/release-operator/src/registry.rs b/tools/release-operator/src/registry.rs index 71fe085d4..da458528e 100644 --- a/tools/release-operator/src/registry.rs +++ b/tools/release-operator/src/registry.rs @@ -1,7 +1,10 @@ use anyhow::{anyhow, bail, Context}; +use cargo_metadata::MetadataCommand; use secstr::SecUtf8; use serde::Deserialize; +use std::collections::{BTreeSet, VecDeque}; use std::fmt::{Display, Formatter}; +use std::fs; use std::path::PathBuf; use std::process::Command; use std::str::FromStr; @@ -16,7 +19,7 @@ enum Error { pub struct Registry { token: SecUtf8, - crates: Vec, + _crates: Vec, dry_run: bool, } @@ -40,13 +43,66 @@ impl Registry { pub fn new(token: &SecUtf8, crates: &[Crate], dry_run: bool) -> Self { Self { token: token.to_owned(), - crates: crates.to_vec(), + _crates: crates.to_vec(), dry_run, } } pub fn publish_crates(&self) -> anyhow::Result<()> { - for c in &self.crates { + let mut crates = VecDeque::new(); + + for dir_entry in fs::read_dir("crates")? { + let dir_entry = dir_entry?; + let name = dir_entry + .file_name() + .into_string() + .map_err(|err| anyhow!("Error converting string: {err:?}"))?; + + let mut command = MetadataCommand::new(); + command.manifest_path(dir_entry.path().join("Cargo.toml")); + + let metadata = command.exec()?; + + crates.push_back((name, metadata)); + } + + let mut crates_ordered = Vec::new(); + let mut processed_dependencies = BTreeSet::new(); + + while let Some((name, metadata)) = crates.pop_front() { + let mut package = None; + for p in &metadata.packages { + if p.name == name { + package = Some(p.clone()); + } + } + + let package = package.expect("Could not find package"); + + let mut unmet_dependencies = false; + + for dependency in &package.dependencies { + let unmet_dependency = dependency.path.is_some() + && !processed_dependencies.contains(&dependency.name); + + if unmet_dependency { + unmet_dependencies = true; + break; + } + } + + if unmet_dependencies { + crates.push_back((name, metadata)); + } else { + let mut path = package.manifest_path.into_std_path_buf(); + path.pop(); + + processed_dependencies.insert(name); + crates_ordered.push(Crate { path }); + } + } + + for c in crates_ordered { c.validate()?; match c.determine_state()? { From e048c02ceca6ea14c2c6f5e14a6a169cc3ffe04e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 20 Jun 2023 11:18:17 +0200 Subject: [PATCH 2/3] Remove unused code --- tools/release-operator/src/main.rs | 3 +-- tools/release-operator/src/registry.rs | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/release-operator/src/main.rs b/tools/release-operator/src/main.rs index 0480e63ce..0086dcdef 100644 --- a/tools/release-operator/src/main.rs +++ b/tools/release-operator/src/main.rs @@ -77,8 +77,7 @@ fn main() -> anyhow::Result<()> { .detect()?; } Commands::Publish(args) => { - Registry::new(&args.token, &args.crates, args.dry_run) - .publish_crates()?; + Registry::new(&args.token, args.dry_run).publish_crates()?; } } diff --git a/tools/release-operator/src/registry.rs b/tools/release-operator/src/registry.rs index da458528e..a4e3c6606 100644 --- a/tools/release-operator/src/registry.rs +++ b/tools/release-operator/src/registry.rs @@ -19,7 +19,6 @@ enum Error { pub struct Registry { token: SecUtf8, - _crates: Vec, dry_run: bool, } @@ -40,10 +39,9 @@ enum CrateState { } impl Registry { - pub fn new(token: &SecUtf8, crates: &[Crate], dry_run: bool) -> Self { + pub fn new(token: &SecUtf8, dry_run: bool) -> Self { Self { token: token.to_owned(), - _crates: crates.to_vec(), dry_run, } } From cd97c45f84a1892460350ab08e41ab0a030dd765 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 20 Jun 2023 11:18:56 +0200 Subject: [PATCH 3/3] Remove unused argument --- .github/workflows/cd.yml | 7 +------ tools/release-operator/src/main.rs | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 192cc09ad..92fbf3cd5 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -65,9 +65,4 @@ jobs: run: | # Publish to crates.io cargo run -p release-operator -- publish \ - --token ${{ secrets.CARGO_REGISTRY_TOKEN }} \ - --crate crates/fj-math \ - --crate crates/fj-interop \ - --crate crates/fj-kernel \ - --crate crates/fj-export \ - --crate crates/fj-viewer + --token ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/tools/release-operator/src/main.rs b/tools/release-operator/src/main.rs index 0086dcdef..49e37baf2 100644 --- a/tools/release-operator/src/main.rs +++ b/tools/release-operator/src/main.rs @@ -4,7 +4,7 @@ mod release; use crate::github::{Actions, GitHub}; -use crate::registry::{Crate, Registry}; +use crate::registry::Registry; use crate::release::Release; use clap::{Args, Parser, Subcommand}; use secstr::SecUtf8; @@ -42,10 +42,6 @@ struct PublishArgs { #[clap(short, long, env = "CARGO_REGISTRY_TOKEN")] token: SecUtf8, - /// Repeatable option to provide a list of paths to crates - #[clap(short, long = "crate")] - crates: Vec, - /// Perform all checks without uploading #[clap(long)] dry_run: bool,