Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ofl checksums #210

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ edition = "2018"
dyn-cache = { path = "dyn-cache", version = "0.12.0"}
futures = "0.3.5"
illicit = { path = "illicit", version = "1.1.1"}
moxie-macros = { path = "macros", version = "0.1.0" }
moxie-macros = { path = "macros", version = "0.1.0-pre" }
parking_lot = "0.11"
scopeguard = "1"
topo = { path = "topo", version = "0.13.0"}
Expand Down
2 changes: 1 addition & 1 deletion macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "moxie-macros"
version = "0.1.0"
version = "0.1.0-pre"
description = "Macros for the moxie crate."
readme = "../CHANGELOG.md"

Expand Down
275 changes: 187 additions & 88 deletions ofl/Cargo.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions ofl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ actix-files = "0.3.0-alpha.1"
actix-rt = "1.1.1"
actix-web = "3.0.0-alpha.3"
actix-web-actors = "3.0.0-alpha.1"
cargo_metadata = "0.10.0"
crates_io_api = "0.6"
anyhow = "1"
cargo_metadata = "0.12.0"
crates-index = "0.16.0"
crossbeam = "0.7.3"
crypto-hash = "0.3.4"
dialoguer = "0.6"
failure = "0.1"
futures = "0.3"
git2 = "0.13.6"
grcov = "0.5.15"
Expand All @@ -32,7 +33,7 @@ opener = "0.4"
pathfinding = "2.0.4"
pin-utils = "0.1.0"
rustc-hash = "1.1.0"
semver = "0.9"
semver = "0.11"
serde_json = "1.0.53"
spongedown = "0.4.1"
tempfile = "3.1.0"
Expand All @@ -44,4 +45,4 @@ which = "4.0.2"

[dependencies.reqwest] # force cargo to vendor native-tls (see issue #35)
version = "0.10.6"
features = ["native-tls-vendored"]
features = ["blocking", "native-tls-vendored"]
2 changes: 1 addition & 1 deletion ofl/src/coverage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use failure::{bail, Error, ResultExt};
use anyhow::{bail, Context, Error};
use gumdrop::Options;
use std::{
fs::{create_dir, File},
Expand Down
2 changes: 1 addition & 1 deletion ofl/src/format.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use failure::{bail, Error, ResultExt};
use anyhow::{bail, Context, Error};
use gumdrop::Options;
use std::{path::Path, process::Command};
use tracing::*;
Expand Down
2 changes: 1 addition & 1 deletion ofl/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use failure::Error;
use anyhow::Error;
use gumdrop::Options;
use std::path::{Path, PathBuf};
use tracing::*;
Expand Down
65 changes: 43 additions & 22 deletions ofl/src/published.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use anyhow::{bail, Context, Error};
use cargo_metadata::{Package, PackageId};
use crates_io_api as crates;
use failure::{bail, Error, ResultExt};
use crates_index::Index;
use gumdrop::Options;
use semver::Version;
use std::path::PathBuf;
use tracing::*;

Expand All @@ -19,6 +18,7 @@ pub struct EnsurePublished {
impl EnsurePublished {
pub fn run(self, root: PathBuf) -> Result<(), Error> {
let workspace = Workspace::get(&root)?;
info!(workspace = %root.display(), "identifying packages to publish");
let to_publish = packages_to_publish(&workspace)?;
for id in to_publish {
let package = &workspace.metadata[&id];
Expand All @@ -38,25 +38,58 @@ impl EnsurePublished {
}

fn packages_to_publish(workspace: &Workspace) -> Result<Vec<PackageId>, Error> {
let index = Index::new_cargo_default();
info!("updating cargo index");
index.retrieve_or_update()?;

let members = workspace.local_members();
let mut to_publish_ids = vec![];
let mut mismatched_checksums = vec![];

for member in members {
let package = &workspace.metadata[&member];
let version_str = package.version.to_string();

let manifest = std::fs::read_to_string(&package.manifest_path)?;
if manifest.contains("publish = false") {
info!({ %package.name }, "skipping `publish = false`");
debug!({ %package.name }, "skipping `publish = false`");
continue;
}

if package.version.is_prerelease()
|| crates_io_has(&package.name, &package.version).unwrap_or(false)
{
info!({ %package.name, %package.version }, "skipping");
} else {
to_publish_ids.push(member);
if package.version.is_prerelease() {
debug!({ %package.name, %package.version }, "skipping pre-release version");
continue;
}

if let Some(krate) = index.crate_(&package.name) {
if let Some(published) = krate.versions().iter().find(|v| v.version() == version_str) {
info!(
{ name = %published.name(), version = %published.version() },
"found already-published",
);

let current_checksum = workspace.member_checksum(&package.id)?;
if &current_checksum != published.checksum() {
error!({ name = %published.name() }, "checksums don't match crates.io");
error!("consider running `cargo ofl versions` to update its version");
mismatched_checksums.push(package.name.clone());
} else {
info!({ name = %published.name() }, "checksum matches crates.io");
}

continue;
}
}

to_publish_ids.push(member);
}

if !mismatched_checksums.is_empty() {
bail!(
"{} crates' checksums were a mismatch to what's published without updated version \
numbers.",
mismatched_checksums.len()
);
}

let to_publish =
Expand Down Expand Up @@ -95,15 +128,3 @@ stdout:

Ok(())
}

fn crates_io_has(name: &str, version: &Version) -> Result<bool, Error> {
info!({ %name, %version }, "checking crates.io for");

let client = crates::SyncClient::new("ofl", std::time::Duration::from_secs(1))?;
let krate = client.full_crate(name, true /* all_versions */)?;
let versions = &krate.versions;

let current_version_str = version.to_string();

Ok(versions.iter().map(|v| &v.num).any(|v| v == &current_version_str))
}
2 changes: 1 addition & 1 deletion ofl/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use actix_web::{
middleware, web, App, HttpServer,
};
use actix_web_actors::ws;
use anyhow::Error;
use crossbeam::channel::{select, unbounded as chan, Receiver, Sender};
use failure::Error;
use futures::{
future::{LocalBoxFuture, Ready},
FutureExt, TryFutureExt,
Expand Down
2 changes: 1 addition & 1 deletion ofl/src/server/run.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use failure::{bail, Error};
use anyhow::{bail, Error};
use gumdrop::Options;
use std::{
path::PathBuf,
Expand Down
48 changes: 32 additions & 16 deletions ofl/src/versions.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::Error;
use dialoguer::{Confirm, Select};
use failure::Error;
use gumdrop::Options;
use semver::Version;
use std::{
Expand All @@ -16,34 +16,47 @@ impl Versions {
pub fn run(self, project_root: PathBuf) -> Result<(), Error> {
let workspace = crate::workspace::Workspace::get(project_root)?;

let moxie_crates = workspace.local_members();
let mut moxie_crates = workspace
.local_members()
.into_iter()
.map(|id| workspace.get_member(&id).unwrap())
.collect::<Vec<_>>();
moxie_crates.sort_by_key(|c| &c.name);

// prompt the user for which crates' versions they want bumped
let mut choose_updates = Select::new();
for krate in &moxie_crates {
choose_updates.item(&krate.name);
}

// TODO prompt for a subset of crates to update
let to_update_idx = choose_updates.with_prompt("Select crates to update:").interact()?;
let to_update = moxie_crates[to_update_idx].clone();

let mut updates = Vec::new();
let mut updated_manifests = moxie_crates
.iter()
.map(|id| {
let moxie_crate = workspace.get_member(&id).unwrap();
.map(|moxie_crate| {
let manifest_contents = std::fs::read_to_string(&moxie_crate.manifest_path)?;
let manifest: Document = manifest_contents.parse()?;
Ok((moxie_crate.name.clone(), (moxie_crate, manifest)))
})
.collect::<Result<BTreeMap<_, _>, Error>>()?;
for id in moxie_crates {
let moxie_crate = workspace.get_member(&id).unwrap();

if let Some(registries) = &moxie_crate.publish {
if registries.is_empty() {
continue;
}
if let Some(registries) = &to_update.publish {
if registries.is_empty() {
info!("TODO figure out why this happens again?");
return Ok(());
}
}

let new_version = prompt_for_new_version(&moxie_crate.name, &moxie_crate.version)?;
let new_version = prompt_for_new_version(&to_update.name, &to_update.version)?;

if new_version != moxie_crate.version {
updates.push((moxie_crate, new_version, workspace.local_dependents(&id)));
}
if new_version != to_update.version {
updates.push((
to_update.clone(),
new_version,
workspace.local_dependents(&to_update.id),
));
}

let mut pending_updates = vec![String::from("crates to update:")];
Expand All @@ -62,7 +75,10 @@ impl Versions {

println!("{}", pending_updates.join("\n"));

failure::ensure!(Confirm::new().with_prompt("proceed?").interact()?);
anyhow::ensure!(
Confirm::new().with_prompt("proceed?").interact()?,
"user must agree to proceed"
);

let mut to_write = BTreeSet::new();
for (package, new_version, dependents) in updates {
Expand Down
47 changes: 41 additions & 6 deletions ofl/src/website.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use failure::{Error, SyncFailure};
use anyhow::{Context, Error};
use gumdrop::Options;
use mdbook::MDBook;
use std::path::{Path, PathBuf};
use std::{
path::{Path, PathBuf},
sync::Mutex,
};
use tracing::*;

#[derive(Debug, Options)]
Expand Down Expand Up @@ -56,8 +59,12 @@ impl DistOpts {
let rel_path = relative.display();
debug!({ %rel_path }, "copying path");
let destination = output_path.join(relative);
std::fs::create_dir_all(destination.parent().unwrap())?;
std::fs::copy(path, destination)?;
let parent = destination.parent().unwrap();
std::fs::create_dir_all(&parent)
.with_context(|| format!("creating {}", parent.display()))?;
std::fs::copy(&path, &destination).with_context(|| {
format!("copying {} to {}", path.display(), destination.display())
})?;
}

Ok(())
Expand All @@ -75,7 +82,7 @@ impl DistOpts {

info!("discovering files to copy");
let mut to_copy = vec![];
'entries: for entry in walkdir::WalkDir::new(root_path) {
for entry in walkdir::WalkDir::new(root_path) {
let path = entry?.path().to_owned();

match path.extension() {
Expand All @@ -85,11 +92,39 @@ impl DistOpts {

for prefix in &skip_prefixes {
if path.starts_with(prefix) {
continue 'entries;
continue;
}
}

if path.components().any(|c| c.as_os_str() == "node_modules") {
continue;
}

to_copy.push(path);
}
Ok(to_copy)
}
}

#[derive(Debug)]
struct SyncFailure<E>(Mutex<E>);

impl<E> SyncFailure<E>
where
E: std::error::Error,
{
fn new(e: E) -> Self {
Self(Mutex::new(e))
}
}

impl<E> std::fmt::Display for SyncFailure<E>
where
E: std::error::Error,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.lock().unwrap().fmt(f)
}
}

impl<E> std::error::Error for SyncFailure<E> where E: std::error::Error {}
Loading