wip papermc cli stuff
This commit is contained in:
parent
f2c4b97626
commit
63e1d170bc
5 changed files with 221 additions and 0 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -16,8 +16,10 @@ dependencies = [
|
|||
"chrono",
|
||||
"clap",
|
||||
"figment",
|
||||
"papermc-api",
|
||||
"serde",
|
||||
"signal-hook",
|
||||
"ureq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ edition.workspace = true
|
|||
|
||||
[dependencies]
|
||||
backup = { path = "../backup" }
|
||||
papermc-api = { path = "../papermc-api" }
|
||||
|
||||
chrono.workspace = true
|
||||
serde.workspace = true
|
||||
|
|
@ -13,3 +14,4 @@ serde.workspace = true
|
|||
clap = { version = "4.5.37", features = ["derive", "env"] }
|
||||
signal-hook = "0.3.15"
|
||||
figment = { version = "0.10.10", features = ["env", "toml"] }
|
||||
ureq = "3.3.0"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
mod backup;
|
||||
mod config;
|
||||
mod papermc;
|
||||
mod run;
|
||||
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
|
@ -72,6 +73,9 @@ pub enum Commands {
|
|||
Run(RunCli),
|
||||
/// Interact with the backup system without starting a server
|
||||
Backup(BackupArgs),
|
||||
/// Interact with the PaperMC API and download new JARs
|
||||
#[command(name = "papermc")]
|
||||
PaperMC(papermc::Cli),
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
|
|
@ -81,6 +85,7 @@ impl Cli {
|
|||
match &self.command {
|
||||
Commands::Run(args) => args.run(self, &config),
|
||||
Commands::Backup(args) => Ok(args.run(&config)?),
|
||||
Commands::PaperMC(cli) => cli.run(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
210
alex/src/cli/papermc.rs
Normal file
210
alex/src/cli/papermc.rs
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use chrono::Local;
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Show information or a specific version or build
|
||||
Show(ShowArgs),
|
||||
/// List all versions PaperMC jars are available for
|
||||
ListVersions,
|
||||
/// List all available builds for a given version
|
||||
ListBuilds(ListBuildsArgs),
|
||||
/// Download the jar for a specific build
|
||||
Download(DownloadBuildArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct ShowArgs {
|
||||
/// Version to show information for
|
||||
version: String,
|
||||
|
||||
/// Build within version to show information for
|
||||
build: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct ListBuildsArgs {
|
||||
/// Version to list builds for
|
||||
version: String,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct DownloadBuildArgs {
|
||||
/// Version of build to download
|
||||
version: String,
|
||||
/// Build number for build to download
|
||||
build: String,
|
||||
|
||||
/// Path to store the new JAR file in; stores JAR in the local directory if not specified
|
||||
#[arg(short, long, value_name = "OUT_PATH")]
|
||||
out: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
pub fn run(&self) -> crate::Result<()> {
|
||||
match &self.command {
|
||||
Commands::Show(ShowArgs {
|
||||
version,
|
||||
build: None,
|
||||
}) => show_version(&version),
|
||||
Commands::Show(ShowArgs {
|
||||
version,
|
||||
build: Some(build),
|
||||
}) => show_build(&version, &build),
|
||||
Commands::ListVersions => print_versions(),
|
||||
Commands::ListBuilds(args) => print_builds(&args.version),
|
||||
Commands::Download(args) => {
|
||||
download_build(&args.version, &args.build, args.out.as_deref())
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn show_version(version_str: &str) {
|
||||
let client = papermc_api::Client::new();
|
||||
|
||||
let version = match client.project("paper").version(version_str).info() {
|
||||
Ok(version) => version,
|
||||
Err(err) => {
|
||||
println!("failed to query API: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("id: {}", version.id);
|
||||
println!("status: {}", version.support_status);
|
||||
println!("Min. Java: {}", version.java.minimum_version);
|
||||
println!("builds: {}", version.builds.len());
|
||||
}
|
||||
|
||||
fn show_build(version_str: &str, build_str: &str) {
|
||||
let client = papermc_api::Client::new();
|
||||
|
||||
let build = match client
|
||||
.project("paper")
|
||||
.version(version_str)
|
||||
.build(build_str)
|
||||
{
|
||||
Ok(build) => build,
|
||||
Err(err) => {
|
||||
println!("failed to query API: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("id: {}", build.id);
|
||||
println!("time: {}", build.time.with_timezone(&Local));
|
||||
println!("channel: {}", build.channel);
|
||||
println!("commits:");
|
||||
|
||||
for commit in build.commits {
|
||||
println!("- SHA: {}", commit.sha);
|
||||
println!(" time: {}", commit.time.with_timezone(&Local));
|
||||
println!(" message: {}", commit.message);
|
||||
}
|
||||
|
||||
println!("downloads:");
|
||||
|
||||
for (name, download) in build.downloads.iter() {
|
||||
println!(" {name}:");
|
||||
println!(" name: {}", download.name);
|
||||
println!(" size: {}", download.size);
|
||||
println!(" URL: {}", download.url);
|
||||
println!(" checksums:");
|
||||
|
||||
for (name, value) in download.checksums.iter() {
|
||||
println!(" - {}: {}", name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_versions() {
|
||||
let client = papermc_api::Client::new();
|
||||
|
||||
match client.project("paper").versions() {
|
||||
Ok(versions) => {
|
||||
for version in versions {
|
||||
println!("{}", version.id);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
println!("failed to query API: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_builds(version: &str) {
|
||||
let client = papermc_api::Client::new();
|
||||
|
||||
match client.project("paper").version(version).builds() {
|
||||
Ok(builds) => {
|
||||
for build in builds {
|
||||
println!("{} ({})", build.id, build.channel);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
println!("failed to query API: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn download_build(version: &str, build: &str, out_path: Option<&Path>) {
|
||||
let client = papermc_api::Client::new();
|
||||
let build = match client.project("paper").version(version).build(build) {
|
||||
Ok(build) => build,
|
||||
Err(err) => {
|
||||
println!("failed to query API: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let filename = format!("paper-{}-{}.jar", version, build.id);
|
||||
let dest_path = match out_path {
|
||||
Some(path) if path.is_dir() => path.join(filename),
|
||||
Some(path) => path.to_path_buf(),
|
||||
None => PathBuf::from(filename),
|
||||
};
|
||||
|
||||
let download_url = match build
|
||||
.downloads
|
||||
.get("server:default")
|
||||
.or(build.downloads.values().next())
|
||||
{
|
||||
Some(download) => &download.url,
|
||||
None => {
|
||||
println!("no download URLs found for build.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut f = match std::fs::File::create(dest_path) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
println!("failed to create destination file: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut res = match ureq::get(download_url).call() {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
println!("failed to download file: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut reader = res.body_mut().as_reader();
|
||||
if let Err(err) = std::io::copy(&mut reader, &mut f) {
|
||||
println!("failed to download file: {err}");
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||
pub enum Error {
|
||||
IO(io::Error),
|
||||
Figment(figment::Error),
|
||||
Other(Box<dyn std::error::Error>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
|
@ -13,6 +14,7 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Error::IO(err) => write!(fmt, "{}", err),
|
||||
Error::Figment(err) => write!(fmt, "{}", err),
|
||||
Error::Other(err) => write!(fmt, "{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue