LAUNCHER-14 feat: Disabling/enabling packages
This commit is contained in:
parent
04736cc6a4
commit
1912df7698
12 changed files with 200 additions and 128 deletions
|
|
@ -76,6 +76,7 @@ macro_rules! collect_commands {
|
|||
get_cluster_packages,
|
||||
add_cluster_package,
|
||||
remove_cluster_package,
|
||||
set_cluster_package_enabled,
|
||||
sync_cluster_packages,
|
||||
sync_cluster_packages_by_type,
|
||||
// Updater
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ pub async fn download_provider_package(
|
|||
&cluster.cluster_path(),
|
||||
pkg_path,
|
||||
pkg,
|
||||
Some(mgd_pkg.package_type),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
@ -182,11 +181,12 @@ pub async fn get_cluster_packages(
|
|||
#[tauri::command]
|
||||
pub async fn add_cluster_package(
|
||||
cluster_path: ClusterPath,
|
||||
package_path: PackagePath,
|
||||
file_name: String,
|
||||
package_type: PackageType,
|
||||
pkg: Package,
|
||||
package_type: Option<PackageType>,
|
||||
) -> Result<(), String> {
|
||||
package::add_package(&cluster_path, package_path, pkg, package_type).await?;
|
||||
let package_path = PackagePath::new(package_type, file_name)?;
|
||||
package::add_package(&cluster_path, package_path, pkg).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -194,10 +194,24 @@ pub async fn add_cluster_package(
|
|||
#[tauri::command]
|
||||
pub async fn remove_cluster_package(
|
||||
cluster_path: ClusterPath,
|
||||
package_path: PackagePath,
|
||||
file_name: String,
|
||||
package_type: PackageType,
|
||||
) -> Result<(), String> {
|
||||
package::remove_package(&cluster_path, &package_path, package_type).await?;
|
||||
let package_path = PackagePath::new(package_type, file_name)?;
|
||||
package::remove_package(&cluster_path, &package_path).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn set_cluster_package_enabled(
|
||||
cluster_path: ClusterPath,
|
||||
file_name: String,
|
||||
package_type: PackageType,
|
||||
enabled: bool,
|
||||
) -> Result<(), String> {
|
||||
let package_path = PackagePath::new(package_type, file_name)?;
|
||||
package::set_package_enabled(&cluster_path, &package_path, enabled).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { CheckIcon } from '@untitled-theme/icons-solid';
|
||||
import { createSignal, type JSX, splitProps } from 'solid-js';
|
||||
import { createSignal, type JSX, Show, splitProps, untrack } from 'solid-js';
|
||||
import styles from './Checkbox.module.scss';
|
||||
|
||||
type CheckboxProps = JSX.HTMLAttributes<HTMLDivElement> & {
|
||||
|
|
@ -11,8 +11,11 @@ function Checkbox(props: CheckboxProps) {
|
|||
const [checked, setChecked] = createSignal(props.defaultChecked || false);
|
||||
const [split, rest] = splitProps(props, ['class', 'defaultChecked', 'onChecked', 'text']);
|
||||
|
||||
function toggle() {
|
||||
const newValue = !checked();
|
||||
function toggle(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const newValue = !untrack(checked);
|
||||
setChecked(newValue);
|
||||
props.onChecked?.(newValue);
|
||||
}
|
||||
|
|
@ -20,11 +23,13 @@ function Checkbox(props: CheckboxProps) {
|
|||
return (
|
||||
<div
|
||||
class={`${styles.checkbox} ${split.class ?? ''}`}
|
||||
onClick={() => toggle()}
|
||||
onClick={toggle}
|
||||
{...rest}
|
||||
>
|
||||
<div class={`${styles.box} ${checked() ? styles.checked : ''}`}>
|
||||
<CheckIcon />
|
||||
<Show when={checked()}>
|
||||
<CheckIcon />
|
||||
</Show>
|
||||
</div>
|
||||
{props.children}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ import UFuzzy from '@leeoniya/ufuzzy';
|
|||
import { FilterFunnel01Icon, RefreshCw01Icon, SearchMdIcon, Trash03Icon } from '@untitled-theme/icons-solid';
|
||||
import { bridge } from '~imports';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Checkbox from '~ui/components/base/Checkbox';
|
||||
import TextField from '~ui/components/base/TextField';
|
||||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
import Sidebar from '~ui/components/Sidebar';
|
||||
import useBrowser from '~ui/hooks/useBrowser';
|
||||
import useClusterContext from '~ui/hooks/useCluster';
|
||||
import useCommand from '~ui/hooks/useCommand';
|
||||
import useCommand, { tryResult } from '~ui/hooks/useCommand';
|
||||
import useProcessor from '~ui/hooks/useProcessor';
|
||||
import { type Accessor, createEffect, createSignal, For, Match, on, Show, Switch, untrack } from 'solid-js';
|
||||
|
||||
|
|
@ -206,6 +207,25 @@ function ModEntry(props: ModEntryProps) {
|
|||
}
|
||||
}
|
||||
|
||||
async function togglePackage(checked: boolean) {
|
||||
try {
|
||||
const path = cluster()?.path;
|
||||
if (path) {
|
||||
// eslint-disable-next-line solid/reactivity -- bs lol
|
||||
await tryResult(() => bridge.commands.setClusterPackageEnabled(
|
||||
path,
|
||||
props.pkg.file_name,
|
||||
'mod',
|
||||
checked,
|
||||
));
|
||||
props.refetch();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
class="flex flex-row items-center gap-3 rounded-xl bg-component-bg p-3 active:bg-component-bg-pressed hover:bg-component-bg-hover"
|
||||
|
|
@ -251,9 +271,7 @@ function ModEntry(props: ModEntryProps) {
|
|||
</div>
|
||||
|
||||
<div class="flex flex-row items-end justify-center gap-2">
|
||||
{/* <Button buttonStyle="iconSecondary">
|
||||
<Edit02Icon />
|
||||
</Button> */}
|
||||
<Checkbox defaultChecked={!props.pkg.disabled} onChecked={togglePackage} />
|
||||
|
||||
<Button
|
||||
buttonStyle="iconDanger"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ async fn main() -> Result<()> {
|
|||
cluster::content::package::remove_package(
|
||||
&cluster.cluster_path(),
|
||||
&package_path,
|
||||
PackageType::Mod,
|
||||
)
|
||||
.await?;
|
||||
cluster::content::package::sync_packages_by_type(&cluster.cluster_path(), PackageType::Mod, None)
|
||||
|
|
@ -106,7 +105,6 @@ async fn download_mod(
|
|||
&cluster.cluster_path(),
|
||||
package_path.clone(),
|
||||
package,
|
||||
Some(PackageType::Mod),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"version": "1.0.0-alpha.1",
|
||||
"private": true,
|
||||
"engineStrict": true,
|
||||
"packageManager": "pnpm@9.15.1",
|
||||
"packageManager": "pnpm@9.15.4",
|
||||
"description": "Next-generation open source Minecraft launcher and tools for interacting with Polyfrost",
|
||||
"license": "GPL-3.0-only",
|
||||
"homepage": "https://polyfrost.org",
|
||||
|
|
|
|||
18
packages/client/src/bindings.ts
generated
18
packages/client/src/bindings.ts
generated
|
|
@ -464,9 +464,9 @@ export const commands = {
|
|||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
async addClusterPackage(clusterPath: ClusterPath, packagePath: PackagePath, pkg: Package, packageType: PackageType | null): Promise<Result<null, string>> {
|
||||
async addClusterPackage(clusterPath: ClusterPath, fileName: string, packageType: PackageType, pkg: Package): Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: 'ok', data: await TAURI_INVOKE('add_cluster_package', { clusterPath, packagePath, pkg, packageType }) };
|
||||
return { status: 'ok', data: await TAURI_INVOKE('add_cluster_package', { clusterPath, fileName, packageType, pkg }) };
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error)
|
||||
|
|
@ -474,9 +474,19 @@ export const commands = {
|
|||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
async removeClusterPackage(clusterPath: ClusterPath, packagePath: PackagePath, packageType: PackageType): Promise<Result<null, string>> {
|
||||
async removeClusterPackage(clusterPath: ClusterPath, fileName: string, packageType: PackageType): Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: 'ok', data: await TAURI_INVOKE('remove_cluster_package', { clusterPath, packagePath, packageType }) };
|
||||
return { status: 'ok', data: await TAURI_INVOKE('remove_cluster_package', { clusterPath, fileName, packageType }) };
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error)
|
||||
throw e;
|
||||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
async setClusterPackageEnabled(clusterPath: ClusterPath, fileName: string, packageType: PackageType, enabled: boolean): Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: 'ok', data: await TAURI_INVOKE('set_cluster_package_enabled', { clusterPath, fileName, packageType, enabled }) };
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error)
|
||||
|
|
|
|||
|
|
@ -112,11 +112,9 @@ async fn download_file(
|
|||
// TODO: Implement hash checking
|
||||
let cluster_path = &cluster.get_full_path().await?;
|
||||
|
||||
let path = PackagePath::new(
|
||||
&cluster_path
|
||||
let path = &cluster_path
|
||||
.join(package_type.get_folder())
|
||||
.join(&file.file_name),
|
||||
);
|
||||
.join(&file.file_name);
|
||||
|
||||
let ingress_id = init_ingress(
|
||||
crate::IngressType::DownloadPackage {
|
||||
|
|
@ -149,10 +147,10 @@ async fn download_file(
|
|||
tracing::error!("{err}");
|
||||
}
|
||||
|
||||
if let Err(err) = http::write(&path.0, &bytes, &state.io_semaphore).await {
|
||||
if let Err(err) = http::write(&path, &bytes, &state.io_semaphore).await {
|
||||
tracing::error!("failed to write file to cluster: {err}");
|
||||
if path.0.exists() {
|
||||
let _ = io::remove_file(&path.0).await;
|
||||
if path.exists() {
|
||||
let _ = io::remove_file(&path).await;
|
||||
}
|
||||
|
||||
return Err(err);
|
||||
|
|
@ -164,7 +162,7 @@ async fn download_file(
|
|||
|
||||
drop(state);
|
||||
|
||||
Ok(path)
|
||||
Ok(PackagePath::from_path(path).await?)
|
||||
}
|
||||
|
||||
/// Add a package to a cluster.
|
||||
|
|
@ -173,7 +171,6 @@ pub async fn add_package(
|
|||
cluster_path: &ClusterPath,
|
||||
package_path: PackagePath,
|
||||
package: Package,
|
||||
package_type: Option<PackageType>,
|
||||
) -> Result<()> {
|
||||
let state = State::get().await?;
|
||||
let mut manager = state.packages.write().await;
|
||||
|
|
@ -182,7 +179,7 @@ pub async fn add_package(
|
|||
.ok_or_else(|| anyhow::anyhow!("cluster not found in packages map"))?;
|
||||
|
||||
manager
|
||||
.add_package(package_path, package, package_type)
|
||||
.add_package(package_path, package)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -193,7 +190,6 @@ pub async fn add_package(
|
|||
pub async fn remove_package(
|
||||
cluster_path: &ClusterPath,
|
||||
package_path: &PackagePath,
|
||||
package_type: PackageType,
|
||||
) -> Result<()> {
|
||||
let state = State::get().await?;
|
||||
let mut manager = state.packages.write().await;
|
||||
|
|
@ -201,7 +197,24 @@ pub async fn remove_package(
|
|||
.get_mut(cluster_path)
|
||||
.ok_or_else(|| anyhow::anyhow!("cluster not found in packages map"))?;
|
||||
|
||||
manager.remove_package(package_path, package_type).await?;
|
||||
manager.remove_package(package_path).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn set_package_enabled(
|
||||
cluster_path: &ClusterPath,
|
||||
package_path: &PackagePath,
|
||||
enabled: bool,
|
||||
) -> Result<()> {
|
||||
let state = State::get().await?;
|
||||
let mut manager = state.packages.write().await;
|
||||
let manager = manager
|
||||
.get_mut(cluster_path)
|
||||
.ok_or_else(|| anyhow::anyhow!("cluster not found in packages map"))?;
|
||||
|
||||
manager.set_package_enabled(package_path, enabled).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::proxy::send::send_cluster;
|
|||
use crate::prelude::{ClusterPath, JavaVersion, PackagePath};
|
||||
use crate::proxy::ClusterPayloadType;
|
||||
pub use crate::store::{Cluster, JavaOptions, State};
|
||||
use crate::store::{ClusterStage, MinecraftCredentials, ProcessorChild};
|
||||
use crate::store::{MinecraftCredentials, ProcessorChild};
|
||||
|
||||
use onelauncher_utils::io::{self, IOError};
|
||||
|
||||
|
|
@ -256,12 +256,12 @@ pub async fn get_full_path(path: &ClusterPath) -> crate::Result<PathBuf> {
|
|||
|
||||
/// get a specific mod's full path in the filesystem by it's [`ClusterPath`] and [`PackagePath`].
|
||||
#[tracing::instrument]
|
||||
pub async fn get_mod_path(
|
||||
pub async fn get_package_full_path(
|
||||
cluster_path: &ClusterPath,
|
||||
package_path: &PackagePath,
|
||||
) -> crate::Result<PathBuf> {
|
||||
if get(cluster_path).await?.is_some() {
|
||||
let full_path = io::canonicalize(package_path.full_path(cluster_path.clone()).await?)?;
|
||||
let full_path = io::canonicalize(package_path.full_path(cluster_path).await?)?;
|
||||
|
||||
return Ok(full_path);
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@ pub async fn get_mod_path(
|
|||
Err(anyhow::anyhow!(
|
||||
"failed to get the full path of a cluster at path {}",
|
||||
package_path
|
||||
.full_path(cluster_path.clone())
|
||||
.full_path(cluster_path)
|
||||
.await?
|
||||
.display()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use notify_debouncer_mini::Debouncer;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::constants::CLUSTER_FILE;
|
||||
|
|
@ -51,7 +52,7 @@ impl ClusterStage {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for ClusterStage {
|
||||
impl FromStr for ClusterStage {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"installed" => Self::Installed,
|
||||
|
|
@ -188,7 +189,7 @@ impl From<InnerPathLinux> for RawPackagePath {
|
|||
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[serde(transparent)]
|
||||
pub struct PackagePath(pub PathBuf);
|
||||
pub struct PackagePath(PathBuf);
|
||||
|
||||
impl PackagePath {
|
||||
/// Transform a full [`PathBuf`] into a relative [`PackagePath`].
|
||||
|
|
@ -207,28 +208,32 @@ impl PackagePath {
|
|||
Ok(Self(path))
|
||||
}
|
||||
|
||||
pub fn new(package_type: PackageType, file_name: String) -> crate::Result<Self> {
|
||||
Ok(Self(
|
||||
PathBuf::from_str(format!("{}/{}", package_type.get_folder(), file_name).as_str())
|
||||
.map_err(|e| anyhow::anyhow!("couldn't create package path from '{package_type}' '{file_name}': {e:?}"))?
|
||||
))
|
||||
}
|
||||
|
||||
/// Get the full [`PathBuf`] of the current package path.
|
||||
pub async fn full_path(&self, cluster: ClusterPath) -> crate::Result<PathBuf> {
|
||||
pub async fn full_path(&self, cluster: &ClusterPath) -> crate::Result<PathBuf> {
|
||||
let cluster_dir = cluster.full_path().await?;
|
||||
Ok(cluster_dir.join(&self.0))
|
||||
}
|
||||
|
||||
/// Get the [`InnerPathLinux`] of a [`PackagePath`].
|
||||
#[must_use]
|
||||
pub fn inner_path(&self) -> InnerPathLinux {
|
||||
InnerPathLinux(
|
||||
self.0
|
||||
.components()
|
||||
.map(|c| c.as_os_str().to_string_lossy().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("/"),
|
||||
)
|
||||
pub fn package_type(&self) -> crate::Result<PackageType> {
|
||||
PackageType::from_parent(&self.0).ok_or_else(|| anyhow::anyhow!("couldn't get package type of package path: {:?}", self.0).into())
|
||||
}
|
||||
|
||||
/// Create a new `PackagePath` from a relative path.
|
||||
#[must_use]
|
||||
pub fn new(path: &Path) -> Self {
|
||||
Self(PathBuf::from(path))
|
||||
pub fn file_name(&self) -> crate::Result<String> {
|
||||
self.0
|
||||
.file_name()
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
.ok_or_else(|| anyhow::anyhow!("couldn't get file name of package path: {:?}", self.0).into())
|
||||
}
|
||||
|
||||
pub fn relative_path(&self) -> PathBuf {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,15 +183,12 @@ pub struct Package {
|
|||
}
|
||||
|
||||
impl Package {
|
||||
pub fn new(path: &PackagePath, meta: PackageMetadata) -> crate::Result<Self> {
|
||||
let file_name = path
|
||||
.0
|
||||
.file_name()
|
||||
.ok_or_else(|| crate::ErrorKind::AnyhowError(anyhow::anyhow!("no file name")))?
|
||||
pub fn new(path: &PathBuf, meta: PackageMetadata) -> crate::Result<Self> {
|
||||
let file_name = path.file_name()
|
||||
.ok_or_else(|| anyhow::anyhow!("couldn't get filename of path {path:?}"))?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
let sha1 = crypto::sha1_file(&path.0)?;
|
||||
let sha1 = crypto::sha1_file(path)?;
|
||||
|
||||
Ok(Self {
|
||||
sha1,
|
||||
|
|
@ -341,7 +338,7 @@ impl PackageManager {
|
|||
if let Ok(meta) = serde_json::from_slice(&io::read(packages_meta).await?) {
|
||||
meta
|
||||
} else {
|
||||
io::copy(packages_meta, packages_meta.with_extension("bak")).await?;
|
||||
io::copy(packages_meta, packages_meta.with_extension(".json.bak")).await?;
|
||||
io::write(packages_meta, "{}").await?;
|
||||
PackagesMeta::new(package_type)
|
||||
}
|
||||
|
|
@ -359,14 +356,10 @@ impl PackageManager {
|
|||
&mut self,
|
||||
package_path: PackagePath,
|
||||
package: Package,
|
||||
package_type: Option<PackageType>,
|
||||
) -> crate::Result<()> {
|
||||
let package_type = package
|
||||
.meta
|
||||
.get_package_type()
|
||||
.unwrap_or(package_type.ok_or_else(|| anyhow::anyhow!("no package type"))?);
|
||||
let package_type = package_path.package_type()?;
|
||||
let packages = &mut self.get_mut(package_type).packages;
|
||||
packages.insert(package_path, package);
|
||||
insert_package_by_path(packages, package_path, package);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -376,15 +369,10 @@ impl PackageManager {
|
|||
pub async fn remove_package(
|
||||
&mut self,
|
||||
package_path: &PackagePath,
|
||||
package_type: PackageType,
|
||||
) -> crate::Result<()> {
|
||||
let full_path = self
|
||||
.cluster_path
|
||||
.clone()
|
||||
.full_path()
|
||||
.await?
|
||||
.join(package_type.get_folder())
|
||||
.join(package_path.0.clone());
|
||||
let package_type = package_path.package_type()?;
|
||||
let full_path = package_path.full_path(&self.cluster_path).await?;
|
||||
|
||||
io::remove_file(full_path).await?;
|
||||
|
||||
let packages = &mut self.get_mut(package_type).packages;
|
||||
|
|
@ -393,6 +381,51 @@ impl PackageManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// disable a package in the manager
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub async fn set_package_enabled(
|
||||
&mut self,
|
||||
package_path: &PackagePath,
|
||||
enabled: bool,
|
||||
) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
|
||||
let package_type = package_path.package_type()?;
|
||||
let full_path = package_path.full_path(&self.cluster_path).await?;
|
||||
|
||||
let packages = &mut self.get_mut(package_type).packages;
|
||||
|
||||
let was_disabled = full_path.extension().map_or(false, |e| e == "disabled");
|
||||
let mut new_path = full_path.clone();
|
||||
|
||||
let changed = if enabled && was_disabled {
|
||||
new_path.set_extension("") // removes .disabled
|
||||
} else if !enabled && !was_disabled {
|
||||
new_path.set_extension("jar.disabled") // adds .disabled
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if changed {
|
||||
io::rename(full_path, new_path.clone()).await?;
|
||||
|
||||
|
||||
if let Some(mut package) = packages.remove(package_path) {
|
||||
let file_name = new_path.file_name().ok_or_else(|| anyhow::anyhow!("couldn't get file name"))?.to_string_lossy().to_string();
|
||||
let package_path = PackagePath::new(package_type.clone(), file_name.clone())?;
|
||||
|
||||
package.disabled = !enabled;
|
||||
package.file_name = file_name;
|
||||
|
||||
packages.insert(package_path, package);
|
||||
}
|
||||
|
||||
self.sync_to_file_by_type(&state.directories, package_type).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// sync all packages
|
||||
#[tracing::instrument(skip(self, dirs))]
|
||||
pub async fn sync_packages(&mut self, dirs: &Directories) {
|
||||
|
|
@ -458,19 +491,21 @@ impl PackageManager {
|
|||
let mut packages_to_keep = HashSet::<PackagePath>::new();
|
||||
let mut packages_to_infer = HashSet::<PathBuf>::new();
|
||||
|
||||
let full_cluster_path = self.cluster_path.full_path().await?;
|
||||
|
||||
while let Some(file) = files.next_entry().await? {
|
||||
// Skip .packages.json meta file
|
||||
if file.file_name().to_string_lossy().eq(&package_type.get_meta_file_name()) || file.file_type().await?.is_dir()
|
||||
if file.file_name().to_string_lossy().starts_with(&package_type.get_meta_file_name()) || file.file_type().await?.is_dir()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let package_path = PackagePath::new(&file.path());
|
||||
let package_path = PackagePath::from_path(&file.path()).await?;
|
||||
|
||||
// Check if the file is in the packages list already
|
||||
if packages.get(&package_path).is_none() {
|
||||
// Package path is not in the packages list but exists on file system, lets try to infer it later on
|
||||
packages_to_infer.insert(package_path.0.clone());
|
||||
packages_to_infer.insert(full_cluster_path.join(package_path.relative_path()));
|
||||
}
|
||||
|
||||
// Add the package to the set to not remove it from the manager
|
||||
|
|
@ -490,11 +525,11 @@ impl PackageManager {
|
|||
for path in not_found {
|
||||
tracing::warn!("failed to infer package: {:?}", path);
|
||||
|
||||
let package_path = PackagePath::new(&path);
|
||||
let meta = PackageMetadata::Unknown;
|
||||
let package = Package::new(&package_path, meta)?;
|
||||
let package = Package::new(&path, meta)?;
|
||||
let package_path = PackagePath::from_path(&path).await?;
|
||||
|
||||
packages.insert(package_path, package);
|
||||
insert_package_by_path(packages, package_path, package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -541,48 +576,17 @@ impl PackageManager {
|
|||
}
|
||||
}
|
||||
|
||||
// #[tracing::instrument(skip(packages))]
|
||||
// async fn infer_packages(
|
||||
// packages: &mut PackagesMap,
|
||||
// package_type: PackageType,
|
||||
// to_infer: HashSet<PathBuf>,
|
||||
// ) {
|
||||
// let infer_order = vec![
|
||||
// Providers::Modrinth,
|
||||
// Providers::SkyClient,
|
||||
// Providers::Curseforge,
|
||||
// ];
|
||||
fn insert_package_by_path(packages: &mut PackagesMap, path: PackagePath, mut package: Package) {
|
||||
if let Ok(file_name) = path.file_name() {
|
||||
let is_disabled = file_name.ends_with(".disabled");
|
||||
|
||||
if is_disabled {
|
||||
package.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// // if let Some(not_found) = infer_provider(Providers::Modrinth, package_type, packages, packages_to_infer, crypto::sha1_file).await {
|
||||
// // if let Some(not_found) = infer_provider(Providers::SkyClient, package_type, packages, not_found, crypto::md5_file).await {
|
||||
// // if let Some(not_found) = infer_provider(Providers::Curseforge, package_type, packages, not_found, |path| {
|
||||
// // let hash = crypto::murmur2_file(path)?;
|
||||
// // Ok(hash.to_string())
|
||||
// // }).await {
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// let mut to_infer = to_infer;
|
||||
// for provider in infer_order {
|
||||
// if let Some(not_found) = infer_provider(provider, package_type, packages, to_infer, move|path| {
|
||||
// Ok(provider.hash_file(path))
|
||||
// }).await {
|
||||
// to_infer = not_found;
|
||||
// }
|
||||
// }
|
||||
|
||||
// for path in to_infer {
|
||||
// tracing::warn!("failed to infer package: {:?}", path);
|
||||
|
||||
// let package_path = PackagePath::new(&path);
|
||||
// let meta = PackageMetadata::Unknown;
|
||||
// if let Ok(package) = Package::new(&package_path, meta) {
|
||||
// packages.insert(package_path, package);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
packages.insert(path, package);
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(packages, to_infer))]
|
||||
async fn infer_provider(
|
||||
|
|
@ -633,7 +637,7 @@ async fn infer_provider(
|
|||
|
||||
let Some(version) = versions.get(hash) else { continue; };
|
||||
|
||||
if let Some(package_path) = hash_map.get(hash) {
|
||||
if let Some(path) = hash_map.get(hash) {
|
||||
let meta = PackageMetadata::Managed {
|
||||
package_id: managed.id,
|
||||
provider: provider.clone(),
|
||||
|
|
@ -645,10 +649,14 @@ async fn infer_provider(
|
|||
icon_url: managed.icon_url
|
||||
};
|
||||
|
||||
let package_path = &PackagePath::new(package_path);
|
||||
match Package::new(package_path, meta) {
|
||||
let Ok(package_path) = PackagePath::from_path(path).await else {
|
||||
tracing::error!("failed to create package path for {:?}", path);
|
||||
continue;
|
||||
};
|
||||
|
||||
match Package::new(path, meta) {
|
||||
Ok(package) => {
|
||||
packages.insert(package_path.clone(), package);
|
||||
insert_package_by_path(packages, package_path, package);
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::error!("failed to create package from {}: {}", provider, err);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use uuid::Uuid;
|
|||
|
||||
use crate::api::cluster;
|
||||
use crate::constants::PROCESSOR_FILE;
|
||||
use crate::proxy::send::{send_ingress, send_message, send_process};
|
||||
use crate::proxy::send::{send_message, send_process};
|
||||
use crate::proxy::ProcessPayloadType;
|
||||
use crate::utils::http::read_json;
|
||||
use crate::State;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue