mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-01-09 12:19:09 +00:00
Reorganize & declutter source files
This commit is contained in:
parent
af3d022f5d
commit
86cd8ebe33
10 changed files with 167 additions and 171 deletions
|
@ -7,8 +7,8 @@ use clap::{CommandFactory, Parser};
|
||||||
use mlua::{Lua, Result};
|
use mlua::{Lua, Result};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lune::{console::Console, fs::Fs, net::Net, process::Process},
|
globals::{console::Console, fs::Fs, net::Net, process::Process},
|
||||||
utils::GithubClient,
|
utils::github::Client as GithubClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Lune CLI
|
/// Lune CLI
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use mlua::{Lua, MultiValue, Result, UserData, UserDataMethods};
|
use mlua::{Lua, MultiValue, Result, UserData, UserDataMethods};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::formatting::{
|
||||||
flush_stdout, pretty_format_multi_value, print_color, print_label, print_style,
|
flush_stdout, pretty_format_multi_value, print_color, print_label, print_style,
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ use reqwest::{
|
||||||
Method,
|
Method,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::get_github_user_agent_header;
|
use crate::utils::github::get_github_user_agent_header;
|
||||||
|
|
||||||
pub struct Net();
|
pub struct Net();
|
||||||
|
|
|
@ -5,11 +5,11 @@ use clap::Parser;
|
||||||
use mlua::Result;
|
use mlua::Result;
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod lune;
|
mod globals;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use cli::Cli;
|
use cli::Cli;
|
||||||
use utils::{pretty_print_luau_error, print_label};
|
use utils::formatting::{pretty_print_luau_error, print_label};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
|
|
@ -1,172 +1,42 @@
|
||||||
use std::{
|
use std::{
|
||||||
env::current_dir,
|
fmt::Write as _,
|
||||||
fmt::Write,
|
io::{self, Write as _},
|
||||||
io::{self, Write as IoWrite},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{bail, Context, Result};
|
|
||||||
use mlua::{MultiValue, Value};
|
use mlua::{MultiValue, Value};
|
||||||
use reqwest::{
|
|
||||||
header::{HeaderMap, HeaderValue},
|
|
||||||
Client,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
const MAX_FORMAT_DEPTH: usize = 4;
|
const MAX_FORMAT_DEPTH: usize = 4;
|
||||||
|
|
||||||
const INDENT: &str = " ";
|
const INDENT: &str = " ";
|
||||||
|
|
||||||
const COLOR_RESET: &str = "\x1B[0m";
|
pub const COLOR_RESET: &str = "\x1B[0m";
|
||||||
const COLOR_BLACK: &str = "\x1B[30m";
|
pub const COLOR_BLACK: &str = "\x1B[30m";
|
||||||
const COLOR_RED: &str = "\x1B[31m";
|
pub const COLOR_RED: &str = "\x1B[31m";
|
||||||
const COLOR_GREEN: &str = "\x1B[32m";
|
pub const COLOR_GREEN: &str = "\x1B[32m";
|
||||||
const COLOR_YELLOW: &str = "\x1B[33m";
|
pub const COLOR_YELLOW: &str = "\x1B[33m";
|
||||||
const COLOR_BLUE: &str = "\x1B[34m";
|
pub const COLOR_BLUE: &str = "\x1B[34m";
|
||||||
const COLOR_PURPLE: &str = "\x1B[35m";
|
pub const COLOR_PURPLE: &str = "\x1B[35m";
|
||||||
const COLOR_CYAN: &str = "\x1B[36m";
|
pub const COLOR_CYAN: &str = "\x1B[36m";
|
||||||
const COLOR_WHITE: &str = "\x1B[37m";
|
pub const COLOR_WHITE: &str = "\x1B[37m";
|
||||||
|
|
||||||
const STYLE_RESET: &str = "\x1B[22m";
|
pub const STYLE_RESET: &str = "\x1B[22m";
|
||||||
const STYLE_BOLD: &str = "\x1B[1m";
|
pub const STYLE_BOLD: &str = "\x1B[1m";
|
||||||
const STYLE_DIM: &str = "\x1B[2m";
|
pub const STYLE_DIM: &str = "\x1B[2m";
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
|
||||||
pub struct GithubReleaseAsset {
|
|
||||||
id: u64,
|
|
||||||
url: String,
|
|
||||||
name: Option<String>,
|
|
||||||
label: Option<String>,
|
|
||||||
content_type: String,
|
|
||||||
size: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
|
||||||
pub struct GithubRelease {
|
|
||||||
id: u64,
|
|
||||||
url: String,
|
|
||||||
tag_name: String,
|
|
||||||
name: Option<String>,
|
|
||||||
body: Option<String>,
|
|
||||||
draft: bool,
|
|
||||||
prerelease: bool,
|
|
||||||
assets: Vec<GithubReleaseAsset>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GithubClient {
|
|
||||||
client: Client,
|
|
||||||
github_owner: String,
|
|
||||||
github_repo: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GithubClient {
|
|
||||||
pub fn new() -> Result<Self> {
|
|
||||||
let (github_owner, github_repo) = get_github_owner_and_repo();
|
|
||||||
let mut headers = HeaderMap::new();
|
|
||||||
headers.insert(
|
|
||||||
"User-Agent",
|
|
||||||
HeaderValue::from_str(&get_github_user_agent_header())?,
|
|
||||||
);
|
|
||||||
headers.insert(
|
|
||||||
"Accept",
|
|
||||||
HeaderValue::from_static("application/vnd.github+json"),
|
|
||||||
);
|
|
||||||
headers.insert(
|
|
||||||
"X-GitHub-Api-Version",
|
|
||||||
HeaderValue::from_static("2022-11-28"),
|
|
||||||
);
|
|
||||||
let client = Client::builder().default_headers(headers).build()?;
|
|
||||||
Ok(Self {
|
|
||||||
client,
|
|
||||||
github_owner,
|
|
||||||
github_repo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn fetch_releases(&self) -> Result<Vec<GithubRelease>> {
|
|
||||||
let release_api_url = format!(
|
|
||||||
"https://api.github.com/repos/{}/{}/releases",
|
|
||||||
&self.github_owner, &self.github_repo
|
|
||||||
);
|
|
||||||
let response_bytes = self
|
|
||||||
.client
|
|
||||||
.get(release_api_url)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.context("Failed to send releases request")?
|
|
||||||
.bytes()
|
|
||||||
.await
|
|
||||||
.context("Failed to get releases response bytes")?;
|
|
||||||
let response_body: Vec<GithubRelease> = serde_json::from_slice(&response_bytes)?;
|
|
||||||
Ok(response_body)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn fetch_release_for_this_version(&self) -> Result<GithubRelease> {
|
|
||||||
let release_version_tag = format!("v{}", env!("CARGO_PKG_VERSION"));
|
|
||||||
let all_releases = self.fetch_releases().await?;
|
|
||||||
all_releases
|
|
||||||
.iter()
|
|
||||||
.find(|release| release.tag_name == release_version_tag)
|
|
||||||
.map(ToOwned::to_owned)
|
|
||||||
.with_context(|| format!("Failed to find release for version {release_version_tag}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn fetch_release_asset(
|
|
||||||
&self,
|
|
||||||
release: &GithubRelease,
|
|
||||||
asset_name: &str,
|
|
||||||
) -> Result<()> {
|
|
||||||
if let Some(asset) = release
|
|
||||||
.assets
|
|
||||||
.iter()
|
|
||||||
.find(|asset| matches!(&asset.name, Some(name) if name == asset_name))
|
|
||||||
{
|
|
||||||
let file_path = current_dir()?.join(asset_name);
|
|
||||||
let file_bytes = self
|
|
||||||
.client
|
|
||||||
.get(&asset.url)
|
|
||||||
.header("Accept", "application/octet-stream")
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.context("Failed to send asset download request")?
|
|
||||||
.bytes()
|
|
||||||
.await
|
|
||||||
.context("Failed to get asset download response bytes")?;
|
|
||||||
tokio::fs::write(&file_path, &file_bytes)
|
|
||||||
.await
|
|
||||||
.with_context(|| {
|
|
||||||
format!("Failed to write file at path '{}'", &file_path.display())
|
|
||||||
})?;
|
|
||||||
} else {
|
|
||||||
bail!(
|
|
||||||
"Failed to find release asset '{}' for release '{}'",
|
|
||||||
asset_name,
|
|
||||||
&release.tag_name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_github_owner_and_repo() -> (String, String) {
|
|
||||||
let (github_owner, github_repo) = env!("CARGO_PKG_REPOSITORY")
|
|
||||||
.strip_prefix("https://github.com/")
|
|
||||||
.unwrap()
|
|
||||||
.split_once('/')
|
|
||||||
.unwrap();
|
|
||||||
(github_owner.to_owned(), github_repo.to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_github_user_agent_header() -> String {
|
|
||||||
let (github_owner, github_repo) = get_github_owner_and_repo();
|
|
||||||
format!("{github_owner}-{github_repo}-cli")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Separate utils out into github & formatting
|
|
||||||
|
|
||||||
pub fn flush_stdout() -> mlua::Result<()> {
|
pub fn flush_stdout() -> mlua::Result<()> {
|
||||||
io::stdout().flush().map_err(mlua::Error::external)
|
io::stdout().flush().map_err(mlua::Error::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_be_plain_lua_table_key(s: &mlua::String) -> bool {
|
||||||
|
let str = s.to_string_lossy().to_string();
|
||||||
|
let first_char = str.chars().next().unwrap();
|
||||||
|
if first_char.is_alphabetic() {
|
||||||
|
str.chars().all(|c| c == '_' || c.is_alphanumeric())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
print!(
|
print!(
|
||||||
"{}[{}{}{}{}]{} ",
|
"{}[{}{}{}{}]{} ",
|
||||||
|
@ -230,17 +100,7 @@ pub fn print_color<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_be_plain_lua_table_key(s: &mlua::String) -> bool {
|
pub fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) -> anyhow::Result<()> {
|
||||||
let str = s.to_string_lossy().to_string();
|
|
||||||
let first_char = str.chars().next().unwrap();
|
|
||||||
if first_char.is_alphabetic() {
|
|
||||||
str.chars().all(|c| c == '_' || c.is_alphanumeric())
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) -> anyhow::Result<()> {
|
|
||||||
// TODO: Handle tables with cyclic references
|
// TODO: Handle tables with cyclic references
|
||||||
// TODO: Handle other types like function, userdata, ...
|
// TODO: Handle other types like function, userdata, ...
|
||||||
match &value {
|
match &value {
|
134
src/utils/github.rs
Normal file
134
src/utils/github.rs
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
use std::env::current_dir;
|
||||||
|
|
||||||
|
use anyhow::{bail, Context, Result};
|
||||||
|
use reqwest::header::{HeaderMap, HeaderValue};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub struct ReleaseAsset {
|
||||||
|
id: u64,
|
||||||
|
url: String,
|
||||||
|
name: Option<String>,
|
||||||
|
label: Option<String>,
|
||||||
|
content_type: String,
|
||||||
|
size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub struct Release {
|
||||||
|
id: u64,
|
||||||
|
url: String,
|
||||||
|
tag_name: String,
|
||||||
|
name: Option<String>,
|
||||||
|
body: Option<String>,
|
||||||
|
draft: bool,
|
||||||
|
prerelease: bool,
|
||||||
|
assets: Vec<ReleaseAsset>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
client: reqwest::Client,
|
||||||
|
github_owner: String,
|
||||||
|
github_repo: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let (github_owner, github_repo) = get_github_owner_and_repo();
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
headers.insert(
|
||||||
|
"User-Agent",
|
||||||
|
HeaderValue::from_str(&get_github_user_agent_header())?,
|
||||||
|
);
|
||||||
|
headers.insert(
|
||||||
|
"Accept",
|
||||||
|
HeaderValue::from_static("application/vnd.github+json"),
|
||||||
|
);
|
||||||
|
headers.insert(
|
||||||
|
"X-GitHub-Api-Version",
|
||||||
|
HeaderValue::from_static("2022-11-28"),
|
||||||
|
);
|
||||||
|
let client = reqwest::Client::builder()
|
||||||
|
.default_headers(headers)
|
||||||
|
.build()?;
|
||||||
|
Ok(Self {
|
||||||
|
client,
|
||||||
|
github_owner,
|
||||||
|
github_repo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_releases(&self) -> Result<Vec<Release>> {
|
||||||
|
let release_api_url = format!(
|
||||||
|
"https://api.github.com/repos/{}/{}/releases",
|
||||||
|
&self.github_owner, &self.github_repo
|
||||||
|
);
|
||||||
|
let response_bytes = self
|
||||||
|
.client
|
||||||
|
.get(release_api_url)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.context("Failed to send releases request")?
|
||||||
|
.bytes()
|
||||||
|
.await
|
||||||
|
.context("Failed to get releases response bytes")?;
|
||||||
|
let response_body: Vec<Release> = serde_json::from_slice(&response_bytes)?;
|
||||||
|
Ok(response_body)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_release_for_this_version(&self) -> Result<Release> {
|
||||||
|
let release_version_tag = format!("v{}", env!("CARGO_PKG_VERSION"));
|
||||||
|
let all_releases = self.fetch_releases().await?;
|
||||||
|
all_releases
|
||||||
|
.iter()
|
||||||
|
.find(|release| release.tag_name == release_version_tag)
|
||||||
|
.map(ToOwned::to_owned)
|
||||||
|
.with_context(|| format!("Failed to find release for version {release_version_tag}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_release_asset(&self, release: &Release, asset_name: &str) -> Result<()> {
|
||||||
|
if let Some(asset) = release
|
||||||
|
.assets
|
||||||
|
.iter()
|
||||||
|
.find(|asset| matches!(&asset.name, Some(name) if name == asset_name))
|
||||||
|
{
|
||||||
|
let file_path = current_dir()?.join(asset_name);
|
||||||
|
let file_bytes = self
|
||||||
|
.client
|
||||||
|
.get(&asset.url)
|
||||||
|
.header("Accept", "application/octet-stream")
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.context("Failed to send asset download request")?
|
||||||
|
.bytes()
|
||||||
|
.await
|
||||||
|
.context("Failed to get asset download response bytes")?;
|
||||||
|
tokio::fs::write(&file_path, &file_bytes)
|
||||||
|
.await
|
||||||
|
.with_context(|| {
|
||||||
|
format!("Failed to write file at path '{}'", &file_path.display())
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
bail!(
|
||||||
|
"Failed to find release asset '{}' for release '{}'",
|
||||||
|
asset_name,
|
||||||
|
&release.tag_name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_github_owner_and_repo() -> (String, String) {
|
||||||
|
let (github_owner, github_repo) = env!("CARGO_PKG_REPOSITORY")
|
||||||
|
.strip_prefix("https://github.com/")
|
||||||
|
.unwrap()
|
||||||
|
.split_once('/')
|
||||||
|
.unwrap();
|
||||||
|
(github_owner.to_owned(), github_repo.to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_github_user_agent_header() -> String {
|
||||||
|
let (github_owner, github_repo) = get_github_owner_and_repo();
|
||||||
|
format!("{github_owner}-{github_repo}-cli")
|
||||||
|
}
|
2
src/utils/mod.rs
Normal file
2
src/utils/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod formatting;
|
||||||
|
pub mod github;
|
Loading…
Reference in a new issue