Skip to content

Commit

Permalink
Auto merge of #3011 - Turbo87:crates-admin, r=jtgeibel
Browse files Browse the repository at this point in the history
Implement `crates-admin` binary

This PR resolves #1504 by adding a new `crates-admin` binary, that combines a lot of the previously separate binaries as subcommands.

I would recommend to review commit-by-commit :)

r? `@jtgeibel`
  • Loading branch information
bors committed Nov 13, 2020
2 parents a66f6e9 + 9aa026c commit 01cdee4
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 78 deletions.
2 changes: 1 addition & 1 deletion script/ci/prune-cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ du -hs target/debug

crate_name="cargo-registry"
test_name="all"
bin_names="background-worker delete-crate delete-version enqueue-job monitor populate render-readmes server test-pagerduty transfer-crates verify-token"
bin_names="background-worker crates-admin enqueue-job monitor server"

normalized_crate_name=${crate_name//-/_}
rm -vf target/debug/$normalized_crate_name-*
Expand Down
19 changes: 7 additions & 12 deletions src/bin/delete-crate.rs → src/admin/delete_crate.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{db, models::Crate, schema::crates};
use crate::{admin::dialoguer, db, models::Crate, schema::crates};

use clap::Clap;
use diesel::prelude::*;

mod dialoguer;

#[derive(Clap, Debug)]
#[clap(
name = "delete-crate",
about = "Purge all references to a crate from the database.\n\nPlease be super sure you want to do this before running this."
about = "Purge all references to a crate from the database.",
after_help = "Please be super sure you want to do this before running this!"
)]
struct Opts {
pub struct Opts {
/// Name of the crate
crate_name: String,
}

fn main() {
pub fn run(opts: Opts) {
let conn = db::connect_now().unwrap();
conn.transaction::<_, diesel::result::Error, _>(|| {
delete(&conn);
delete(opts, &conn);
Ok(())
})
.unwrap()
}

fn delete(conn: &PgConnection) {
let opts: Opts = Opts::parse();

fn delete(opts: Opts, conn: &PgConnection) {
let krate: Crate = Crate::by_name(&opts.crate_name).first(conn).unwrap();

let prompt = format!(
Expand Down
20 changes: 8 additions & 12 deletions src/bin/delete-version.rs → src/admin/delete_version.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{
use crate::{
admin::dialoguer,
db,
models::{Crate, Version},
schema::versions,
Expand All @@ -9,32 +8,29 @@ use cargo_registry::{
use clap::Clap;
use diesel::prelude::*;

mod dialoguer;

#[derive(Clap, Debug)]
#[clap(
name = "delete-version",
about = "Purge all references to a crate's version from the database.\n\nPlease be super sure you want to do this before running this."
about = "Purge all references to a crate's version from the database.",
after_help = "Please be super sure you want to do this before running this!"
)]
struct Opts {
pub struct Opts {
/// Name of the crate
crate_name: String,
/// Version number that should be deleted
version: String,
}

fn main() {
pub fn run(opts: Opts) {
let conn = db::connect_now().unwrap();
conn.transaction::<_, diesel::result::Error, _>(|| {
delete(&conn);
delete(opts, &conn);
Ok(())
})
.unwrap()
}

fn delete(conn: &PgConnection) {
let opts: Opts = Opts::parse();

fn delete(opts: Opts, conn: &PgConnection) {
let krate: Crate = Crate::by_name(&opts.crate_name).first(conn).unwrap();
let v: Version = Version::belonging_to(&krate)
.filter(versions::num.eq(&opts.version))
Expand Down
2 changes: 1 addition & 1 deletion src/bin/dialoguer/mod.rs → src/admin/dialoguer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn confirm(msg: &str) -> bool {
}

#[derive(Debug, Copy, Clone)]
pub struct CustomTheme;
struct CustomTheme;

impl Theme for CustomTheme {
fn format_confirm_prompt(
Expand Down
9 changes: 9 additions & 0 deletions src/admin/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub mod delete_crate;
pub mod delete_version;
pub mod dialoguer;
pub mod on_call;
pub mod populate;
pub mod render_readmes;
pub mod test_pagerduty;
pub mod transfer_crates;
pub mod verify_token;
File renamed without changes.
14 changes: 5 additions & 9 deletions src/bin/populate.rs → src/admin/populate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{db, schema::version_downloads};
use crate::{db, schema::version_downloads};

use clap::Clap;
use diesel::prelude::*;
Expand All @@ -11,21 +9,19 @@ use rand::{thread_rng, Rng};
name = "populate",
about = "Populate a set of dummy download statistics for a specific version in the database."
)]
struct Opts {
pub struct Opts {
#[clap(required = true)]
version_ids: Vec<i32>,
}

fn main() {
pub fn run(opts: Opts) {
let conn = db::connect_now().unwrap();
conn.transaction(|| update(&conn)).unwrap();
conn.transaction(|| update(opts, &conn)).unwrap();
}

fn update(conn: &PgConnection) -> QueryResult<()> {
fn update(opts: Opts, conn: &PgConnection) -> QueryResult<()> {
use diesel::dsl::*;

let opts: Opts = Opts::parse();

for id in opts.version_ids {
let mut rng = thread_rng();
let mut dls = rng.gen_range(5_000i32, 10_000);
Expand Down
18 changes: 5 additions & 13 deletions src/bin/render-readmes.rs → src/admin/render_readmes.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#![warn(clippy::all, rust_2018_idioms)]

#[macro_use]
extern crate serde;

use cargo_registry::{
use crate::{
db,
models::Version,
render::readme_to_html,
Expand All @@ -25,11 +20,10 @@ const CACHE_CONTROL_README: &str = "public,max-age=604800";
#[clap(
name = "render-readmes",
about = "Iterates over every crate versions ever uploaded and (re-)renders their \
readme using the readme renderer from the cargo_registry crate.\n\
\n\
Warning: this can take a lot of time."
readme using the readme renderer from the cargo_registry crate.",
after_help = "Warning: this can take a lot of time."
)]
struct Opts {
pub struct Opts {
/// How many versions should be queried and processed at a time.
#[clap(long, default_value = "25")]
page_size: usize,
Expand All @@ -43,9 +37,7 @@ struct Opts {
crate_name: Option<String>,
}

fn main() {
let opts: Opts = Opts::parse();

pub fn run(opts: Opts) {
let config = Config::default();
let conn = db::connect_now().unwrap();

Expand Down
16 changes: 6 additions & 10 deletions src/bin/test-pagerduty.rs → src/admin/test_pagerduty.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#![warn(clippy::all, rust_2018_idioms)]

mod on_call;

use anyhow::Result;
use clap::Clap;
use failure::_core::str::FromStr;

#[derive(Debug)]
enum EventType {
use crate::admin::on_call;

#[derive(Debug, Copy, Clone)]
pub enum EventType {
Trigger,
Acknowledge,
Resolve,
Expand All @@ -28,15 +26,13 @@ impl FromStr for EventType {

#[derive(Clap, Debug)]
#[clap(name = "test-pagerduty", about = "Send a test event to pagerduty")]
struct Opts {
pub struct Opts {
#[clap(possible_values = &["trigger", "acknowledge", "resolve"])]
event_type: EventType,
description: Option<String>,
}

fn main() -> Result<()> {
let opts: Opts = Opts::parse();

pub fn run(opts: Opts) -> Result<()> {
let event = match opts.event_type {
EventType::Trigger => on_call::Event::Trigger {
incident_key: Some("test".into()),
Expand Down
17 changes: 6 additions & 11 deletions src/bin/transfer-crates.rs → src/admin/transfer_crates.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{
use crate::{
admin::dialoguer,
db,
models::{Crate, OwnerKind, User},
schema::{crate_owners, crates, users},
Expand All @@ -10,32 +9,28 @@ use std::process::exit;
use clap::Clap;
use diesel::prelude::*;

mod dialoguer;

#[derive(Clap, Debug)]
#[clap(
name = "transfer-crates",
about = "Transfer all crates from one user to another."
)]
struct Opts {
pub struct Opts {
/// GitHub login of the "from" user
from_user: String,
/// GitHub login of the "to" user
to_user: String,
}

fn main() {
pub fn run(opts: Opts) {
let conn = db::connect_now().unwrap();
conn.transaction::<_, diesel::result::Error, _>(|| {
transfer(&conn);
transfer(opts, &conn);
Ok(())
})
.unwrap()
}

fn transfer(conn: &PgConnection) {
let opts: Opts = Opts::parse();

fn transfer(opts: Opts, conn: &PgConnection) {
let from: User = users::table
.filter(users::gh_login.eq(opts.from_user))
.first(conn)
Expand Down
11 changes: 5 additions & 6 deletions src/bin/verify-token.rs → src/admin/verify_token.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use cargo_registry::{db, models::User, util::errors::AppResult};
use crate::{db, models::User, util::errors::AppResult};

use clap::Clap;

#[derive(Clap, Debug)]
#[clap(
name = "verify-token",
about = "Look up a username by API token. Used by staff to verify someone's identity \
about = "Look up a username by API token.",
long_about = "Look up a username by API token. Used by staff to verify someone's identity \
by having an API token given. If an error occurs, including being unable to \
find a user with that API token, the error will be displayed."
)]
struct Opts {
pub struct Opts {
api_token: String,
}

fn main() -> AppResult<()> {
let opts: Opts = Opts::parse();

pub fn run(opts: Opts) -> AppResult<()> {
let conn = db::connect_now()?;
let user = User::find_by_api_token(&conn, &opts.api_token)?;
println!("The token belongs to user {}", user.gh_login);
Expand Down
40 changes: 40 additions & 0 deletions src/bin/crates-admin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::admin::{
delete_crate, delete_version, populate, render_readmes, test_pagerduty, transfer_crates,
verify_token,
};

use clap::Clap;

#[derive(Clap, Debug)]
#[clap(name = "crates-admin")]
struct Opts {
#[clap(subcommand)]
command: SubCommand,
}

#[derive(Clap, Debug)]
enum SubCommand {
DeleteCrate(delete_crate::Opts),
DeleteVersion(delete_version::Opts),
Populate(populate::Opts),
RenderReadmes(render_readmes::Opts),
TestPagerduty(test_pagerduty::Opts),
TransferCrates(transfer_crates::Opts),
VerifyToken(verify_token::Opts),
}

fn main() {
let opts: Opts = Opts::parse();

match opts.command {
SubCommand::DeleteCrate(opts) => delete_crate::run(opts),
SubCommand::DeleteVersion(opts) => delete_version::run(opts),
SubCommand::Populate(opts) => populate::run(opts),
SubCommand::RenderReadmes(opts) => render_readmes::run(opts),
SubCommand::TestPagerduty(opts) => test_pagerduty::run(opts).unwrap(),
SubCommand::TransferCrates(opts) => transfer_crates::run(opts),
SubCommand::VerifyToken(opts) => verify_token::run(opts).unwrap(),
}
}
4 changes: 1 addition & 3 deletions src/bin/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
#![warn(clippy::all, rust_2018_idioms)]

mod on_call;

use anyhow::Result;
use cargo_registry::{db, schema::*};
use cargo_registry::{admin::on_call, db, schema::*};
use diesel::prelude::*;

fn main() -> Result<()> {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use jemallocator::Jemalloc;
#[global_allocator]
static ALLOC: Jemalloc = Jemalloc;

pub mod admin;
mod app;
pub mod background_jobs;
pub mod boot;
Expand Down

0 comments on commit 01cdee4

Please sign in to comment.