Skip to content

Commit

Permalink
chore: Drop dependency on cargo-mono (#9569)
Browse files Browse the repository at this point in the history
**Description:**

We now have bump command inline.
  • Loading branch information
kdy1 committed Sep 19, 2024
1 parent f637f83 commit a5e6a06
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 20 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ jobs:
with:
tool: [email protected]

- name: Install cargo-mono
if: github.event_name == 'workflow_dispatch'
uses: taiki-e/install-action@v2
with:
tool: [email protected]

- run: cargo bump
if: github.event_name == 'workflow_dispatch'
continue-on-error: true
Expand Down
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions tools/swc-releaser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ anyhow = { workspace = true }
cargo_metadata = { workspace = true }
changesets = { workspace = true }
clap = { version = "4.5.9", features = ["derive"] }
indexmap = { workspace = true }
petgraph = { workspace = true }
212 changes: 200 additions & 12 deletions tools/swc-releaser/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use std::{
collections::{hash_map::Entry, HashMap},
env,
path::{Path, PathBuf},
process::Command,
};

use anyhow::{Context, Result};
use cargo_metadata::{semver::Version, DependencyKind};
use changesets::ChangeType;
use clap::{Parser, Subcommand};
use indexmap::IndexSet;
use petgraph::{prelude::DiGraphMap, Direction};

#[derive(Debug, Parser)]
struct CliArs {
Expand Down Expand Up @@ -49,11 +53,30 @@ fn run_bump(workspace_dir: &Path, dry_run: bool) -> Result<()> {
return Ok(());
}

let (versions, graph) = get_data()?;
let mut new_versions = VersionMap::new();

let mut worker = Bump {
versions: &versions,
graph: &graph,
new_versions: &mut new_versions,
};

for (pkg_name, release) in changeset.releases {
bump_crate(&pkg_name, release.change_type(), dry_run)
let is_breaking = worker
.is_breaking(pkg_name.as_str(), release.change_type())
.with_context(|| format!("failed to check if package {} is breaking", pkg_name))?;

worker
.bump_crate(pkg_name.as_str(), release.change_type(), is_breaking)
.with_context(|| format!("failed to bump package {}", pkg_name))?;
}

for (pkg_name, version) in new_versions {
run_cargo_set_version(&pkg_name, &version, dry_run)
.with_context(|| format!("failed to set version for {}", pkg_name))?;
}

{
eprintln!("Removing changeset files... ");
if !dry_run {
Expand All @@ -72,6 +95,24 @@ fn run_bump(workspace_dir: &Path, dry_run: bool) -> Result<()> {
Ok(())
}

fn run_cargo_set_version(pkg_name: &str, version: &Version, dry_run: bool) -> Result<()> {
let mut cmd = Command::new("cargo");
cmd.arg("set-version")
.arg("-p")
.arg(pkg_name)
.arg(version.to_string());

eprintln!("Running {:?}", cmd);

if dry_run {
return Ok(());
}

cmd.status().context("failed to run cargo set-version")?;

Ok(())
}

fn get_swc_core_version() -> Result<String> {
let md = cargo_metadata::MetadataCommand::new()
.no_deps()
Expand Down Expand Up @@ -105,23 +146,114 @@ fn commit(dry_run: bool) -> Result<()> {
Ok(())
}

fn bump_crate(pkg_name: &str, change_type: Option<&ChangeType>, dry_run: bool) -> Result<()> {
let mut cmd = Command::new("cargo");
cmd.arg("mono").arg("bump").arg(pkg_name);
struct Bump<'a> {
/// Original versions
versions: &'a VersionMap,
/// Dependency graph
graph: &'a InternedGraph,

new_versions: &'a mut VersionMap,
}

if let Some(ChangeType::Minor | ChangeType::Major) = change_type {
cmd.arg("--breaking");
impl<'a> Bump<'a> {
fn is_breaking(&self, pkg_name: &str, change_type: Option<&ChangeType>) -> Result<bool> {
let original_version = self
.versions
.get(pkg_name)
.context(format!("failed to find original version for {}", pkg_name))?;

Ok(match change_type {
Some(ChangeType::Major) => true,
Some(ChangeType::Minor) => original_version.major == 0,
Some(ChangeType::Patch) => false,
Some(ChangeType::Custom(label)) => {
if label == "breaking" {
true
} else {
panic!("unknown custom change type: {}", label)
}
}
None => false,
})
}

eprintln!("Running {:?}", cmd);
fn bump_crate(
&mut self,
pkg_name: &str,
change_type: Option<&ChangeType>,
is_breaking: bool,
) -> Result<()> {
let original_version = self
.versions
.get(pkg_name)
.context(format!("failed to find original version for {}", pkg_name))?;

let mut new_version = original_version.clone();

match change_type {
Some(ChangeType::Patch) => {
new_version.patch += 1;
}
Some(ChangeType::Minor) => {
new_version.minor += 1;
new_version.patch = 0;
}
Some(ChangeType::Major) => {
new_version.major += 1;
new_version.minor = 0;
new_version.patch = 0;
}
Some(ChangeType::Custom(label)) => {
if label == "breaking" {
if original_version.major == 0 {
new_version.minor += 1;
new_version.patch = 0;
} else {
new_version.major += 1;
new_version.minor = 0;
new_version.patch = 0;
}
} else {
panic!("unknown custom change type: {}", label)
}
}
None => {
if is_breaking {
if original_version.major == 0 {
new_version.minor += 1;
new_version.patch = 0;
} else {
new_version.major += 1;
new_version.minor = 0;
new_version.patch = 0;
}
} else {
new_version.patch += 1;
}
}
};

match self.new_versions.entry(pkg_name.to_string()) {
Entry::Vacant(v) => {
v.insert(new_version);
}
Entry::Occupied(mut o) => {
o.insert(new_version.max(o.get().clone()));
}
}

if dry_run {
return Ok(());
}
if is_breaking {
// Iterate over dependants

cmd.status().context("failed to bump version")?;
let a = self.graph.node(pkg_name);
for dep in self.graph.g.neighbors_directed(a, Direction::Incoming) {
let dep_name = &*self.graph.ix[dep];
self.bump_crate(dep_name, None, true)?;
}
}

Ok(())
Ok(())
}
}

fn update_changelog() -> Result<()> {
Expand All @@ -135,3 +267,59 @@ fn update_changelog() -> Result<()> {

Ok(())
}

type VersionMap = HashMap<String, Version>;

#[derive(Debug, Default)]
struct InternedGraph {
ix: IndexSet<String>,
g: DiGraphMap<usize, ()>,
}

impl InternedGraph {
fn add_node(&mut self, name: String) -> usize {
let id = self.ix.len();
self.ix.insert(name);
self.g.add_node(id);
id
}

fn node(&self, name: &str) -> usize {
self.ix.get_index_of(name).expect("unknown node")
}
}

fn get_data() -> Result<(VersionMap, InternedGraph)> {
let md = cargo_metadata::MetadataCommand::new()
.exec()
.expect("failed to run cargo metadata");

let workspace_packages = md
.workspace_packages()
.into_iter()
.map(|p| p.name.clone())
.collect::<Vec<_>>();
let mut graph = InternedGraph::default();
let mut versions = VersionMap::new();

for pkg in md.workspace_packages() {
versions.insert(pkg.name.clone(), pkg.version.clone());
}

for pkg in md.workspace_packages() {
for dep in &pkg.dependencies {
if dep.kind != DependencyKind::Normal {
continue;
}

if workspace_packages.contains(&dep.name) {
let from = graph.add_node(pkg.name.clone());
let to = graph.add_node(dep.name.clone());

graph.g.add_edge(from, to, ());
}
}
}

Ok((versions, graph))
}

0 comments on commit a5e6a06

Please sign in to comment.