chore: add package.sh script and apply code formatting

This commit is contained in:
Yuhki 2025-05-30 23:18:05 +02:00
parent bece26c433
commit 29bd052ef4
11 changed files with 169 additions and 31 deletions

3
.gitignore vendored
View file

@ -4,6 +4,9 @@ debug/
target/ target/
.idea/ .idea/
# packaging
dist/
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk

113
package.sh Normal file
View file

@ -0,0 +1,113 @@
#!/bin/bash
set -e
BIN_NAME="wuwa-downloader"
DIST_DIR="dist"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
function info() {
echo -e "${CYAN}==> $1${NC}"
}
function success() {
echo -e "${GREEN}$1${NC}"
}
function warn() {
echo -e "${YELLOW}$1${NC}"
}
function error() {
echo -e "${RED}$1${NC}"
}
function build_linux() {
local OUT_DIR="target/release"
local PACKAGE_NAME="${BIN_NAME}-linux-x86_64"
local PACKAGE_DIR="${DIST_DIR}/${PACKAGE_NAME}"
local ARCHIVE_NAME="${PACKAGE_NAME}.tar.gz"
clear
info "Cleaning binaries to rebuild..."
cargo clean
info "Building release binary for Linux..."
cargo build --release
clear
success "Linux build finished"
info "Creating package directory..."
rm -rf "$PACKAGE_DIR"
mkdir -p "$PACKAGE_DIR"
success "Package directory ready: $PACKAGE_DIR"
info "Copying binary..."
cp "$OUT_DIR/$BIN_NAME" "$PACKAGE_DIR/"
success "Copied binary to package directory"
info "Creating archive..."
cd "$DIST_DIR"
tar -czf "$ARCHIVE_NAME" "$PACKAGE_NAME"
cd -
success "Archive created: ${DIST_DIR}/${ARCHIVE_NAME}"
}
function build_windows() {
local TARGET="x86_64-pc-windows-gnu"
local OUT_DIR="target/${TARGET}/release"
local PACKAGE_NAME="${BIN_NAME}-windows-x86_64"
local PACKAGE_DIR="${DIST_DIR}/${PACKAGE_NAME}"
local ARCHIVE_NAME="${PACKAGE_NAME}.zip"
clear
info "Cleaning binaries to rebuild..."
cargo clean
info "Building release binary for Windows..."
cargo build --release --target "$TARGET"
clear
success "Windows build finished"
info "Creating package directory..."
rm -rf "$PACKAGE_DIR"
mkdir -p "$PACKAGE_DIR"
success "Package directory ready: $PACKAGE_DIR"
info "Copying binary..."
cp "$OUT_DIR/${BIN_NAME}.exe" "$PACKAGE_DIR/"
success "Copied binary to package directory"
info "Creating archive..."
cd "$DIST_DIR"
zip -r "$ARCHIVE_NAME" "$PACKAGE_NAME"
cd -
success "Archive created: ${DIST_DIR}/${ARCHIVE_NAME}"
}
if [[ $# -ne 1 ]]; then
error "Usage: $0 [linux|windows]"
exit 1
fi
case "$1" in
linux)
build_linux
;;
windows)
build_windows
;;
*)
error "Unknown target: $1"
error "Usage: $0 [linux|windows]"
exit 1
;;
esac

View file

@ -2,4 +2,4 @@
pub struct Config { pub struct Config {
pub index_url: String, pub index_url: String,
pub zip_bases: Vec<String>, pub zip_bases: Vec<String>,
} }

View file

@ -4,11 +4,25 @@ use colored::*;
pub struct Status; pub struct Status;
impl Status { impl Status {
pub fn info() -> ColoredString { "[*]".cyan() } pub fn info() -> ColoredString {
pub fn success() -> ColoredString { "[+]".green() } "[*]".cyan()
pub fn warning() -> ColoredString { "[!]".yellow() } }
pub fn error() -> ColoredString { "[-]".red() } pub fn success() -> ColoredString {
pub fn question() -> ColoredString { "[?]".blue() } "[+]".green()
pub fn progress() -> ColoredString { "[→]".purple() } }
pub fn matched() -> ColoredString { "[↓]".bright_purple() } pub fn warning() -> ColoredString {
} "[!]".yellow()
}
pub fn error() -> ColoredString {
"[-]".red()
}
pub fn question() -> ColoredString {
"[?]".blue()
}
pub fn progress() -> ColoredString {
"[→]".purple()
}
pub fn matched() -> ColoredString {
"[↓]".bright_purple()
}
}

View file

@ -1,6 +1,6 @@
use std::{io, path::Path};
use colored::Colorize;
use crate::config::status::Status; use crate::config::status::Status;
use colored::Colorize;
use std::{io, path::Path};
pub fn print_results(success: usize, total: usize, folder: &Path) { pub fn print_results(success: usize, total: usize, folder: &Path) {
let title = if success == total { let title = if success == total {

View file

@ -1,5 +1,8 @@
use std::{fs::{self, OpenOptions}, io::Write, time::SystemTime}; use std::{
fs::{self, OpenOptions},
io::Write,
time::SystemTime,
};
pub fn setup_logging() -> fs::File { pub fn setup_logging() -> fs::File {
OpenOptions::new() OpenOptions::new()

View file

@ -1,4 +1,4 @@
pub mod console; pub mod console;
pub mod file; pub mod file;
pub mod logging; pub mod logging;
pub mod util; pub mod util;

View file

@ -2,7 +2,11 @@ use colored::Colorize;
use reqwest::blocking::Client; use reqwest::blocking::Client;
use serde_json::Value; use serde_json::Value;
use std::{ use std::{
fs::{self, File}, io::{self, Write}, sync::Arc, thread, time::{Duration, Instant} fs::{self, File},
io::{self, Write},
sync::Arc,
thread,
time::{Duration, Instant},
}; };
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
@ -124,7 +128,7 @@ pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Confi
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
Command::new("clear").status().unwrap(); Command::new("clear").status().unwrap();
total_size total_size
} }

View file

@ -13,10 +13,11 @@ use wuwa_downloader::{
io::{ io::{
console::print_results, console::print_results,
file::get_dir, file::get_dir,
util::{
calculate_total_size, download_resources, exit_with_error, setup_ctrlc, track_progress, start_title_thread
},
logging::setup_logging, logging::setup_logging,
util::{
calculate_total_size, download_resources, exit_with_error, setup_ctrlc,
start_title_thread, track_progress,
},
}, },
network::client::{fetch_index, get_config}, network::client::{fetch_index, get_config},
}; };
@ -90,7 +91,7 @@ fn main() {
#[cfg(windows)] #[cfg(windows)]
clear().unwrap(); clear().unwrap();
print_results( print_results(
success.load(std::sync::atomic::Ordering::SeqCst), success.load(std::sync::atomic::Ordering::SeqCst),
resources.len(), resources.len(),

View file

@ -2,7 +2,7 @@ use colored::Colorize;
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use reqwest::blocking::Client; use reqwest::blocking::Client;
use serde_json::{Value, from_reader, from_str}; use serde_json::{from_reader, from_str, Value};
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
use std::process::Command; use std::process::Command;
use std::{ use std::{
@ -322,7 +322,6 @@ pub fn download_file(
false false
} }
fn download_single_file( fn download_single_file(
client: &Client, client: &Client,
url: &str, url: &str,
@ -337,10 +336,8 @@ fn download_single_file(
.map_err(|e| format!("Metadata error: {}", e))? .map_err(|e| format!("Metadata error: {}", e))?
.len(); .len();
} }
let request = client let request = client.get(url).timeout(DOWNLOAD_TIMEOUT);
.get(url)
.timeout(DOWNLOAD_TIMEOUT);
let request = if downloaded > 0 { let request = if downloaded > 0 {
request.header("Range", format!("bytes={}-", downloaded)) request.header("Range", format!("bytes={}-", downloaded))
@ -356,18 +353,21 @@ fn download_single_file(
return Err("Range not satisfiable. File may already be fully downloaded.".into()); return Err("Range not satisfiable. File may already be fully downloaded.".into());
} }
if !response.status().is_success() && response.status() != reqwest::StatusCode::PARTIAL_CONTENT { if !response.status().is_success() && response.status() != reqwest::StatusCode::PARTIAL_CONTENT
{
return Err(format!("HTTP error: {}", response.status())); return Err(format!("HTTP error: {}", response.status()));
} }
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.create(true) .create(true)
.append(true) .append(true)
.open(path) .open(path)
.map_err(|e| format!("File error: {}", e))?; .map_err(|e| format!("File error: {}", e))?;
pb.set_position(downloaded); pb.set_position(downloaded);
progress.downloaded_bytes.store(downloaded, std::sync::atomic::Ordering::SeqCst); progress
.downloaded_bytes
.store(downloaded, std::sync::atomic::Ordering::SeqCst);
let mut buffer = [0; BUFFER_SIZE]; let mut buffer = [0; BUFFER_SIZE];
loop { loop {

View file

@ -1 +1 @@
pub mod client; pub mod client;