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

Implement crates-admin binary #3011

Merged
merged 8 commits into from
Nov 13, 2020
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 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