mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[bugfix] Improve folder linking reliability
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { CopyOptions, copy, createReadStream, ensureDir, move, realpath, stat, symlink } from "fs-extra";
|
||||
import { CopyOptions, MoveOptions, copy, createReadStream, ensureDir, move, realpath, stat, symlink } from "fs-extra";
|
||||
import { access, mkdir, rm, readdir, unlink, lstat, readlink } from "fs/promises";
|
||||
import path from "path";
|
||||
import { Observable, concatMap, from } from "rxjs";
|
||||
@@ -7,6 +7,7 @@ import { BsmException } from "shared/models/bsm-exception.model";
|
||||
import crypto from "crypto";
|
||||
import { execSync } from "child_process";
|
||||
import { tryit } from "../../shared/helpers/error.helpers";
|
||||
import { CustomError } from "shared/models/exceptions/custom-error.class";
|
||||
|
||||
export async function pathExist(path: string): Promise<boolean> {
|
||||
try {
|
||||
@@ -78,7 +79,7 @@ export async function getFilesInFolder(folderPath: string): Promise<string[]> {
|
||||
return dirEntries.filter(entry => entry.isFile()).map(file => path.join(folderPath, file.name));
|
||||
}
|
||||
|
||||
export function moveFolderContent(src: string, dest: string): Observable<Progression> {
|
||||
export function moveFolderContent(src: string, dest: string, option?: MoveOptions): Observable<Progression> {
|
||||
const progress: Progression = { current: 0, total: 0 };
|
||||
return new Observable<Progression>(subscriber => {
|
||||
subscriber.next(progress);
|
||||
@@ -89,25 +90,19 @@ export function moveFolderContent(src: string, dest: string): Observable<Progres
|
||||
return subscriber.complete();
|
||||
}
|
||||
|
||||
ensureFolderExist(dest);
|
||||
await ensureFolderExist(dest);
|
||||
|
||||
const files = await readdir(src, { encoding: "utf-8" });
|
||||
progress.total = files.length;
|
||||
|
||||
const promises = files.map(async file => {
|
||||
for(const file of files){
|
||||
const srcFullPath = path.join(src, file);
|
||||
const destFullPath = path.join(dest, file);
|
||||
if (await pathExist(destFullPath)) {
|
||||
progress.current++;
|
||||
return subscriber.next(progress);
|
||||
}
|
||||
await move(srcFullPath, destFullPath);
|
||||
await move(srcFullPath, destFullPath, option);
|
||||
progress.current++;
|
||||
subscriber.next(progress);
|
||||
});
|
||||
|
||||
Promise.allSettled(promises).then(() => subscriber.complete());
|
||||
})();
|
||||
}
|
||||
})().catch(err => subscriber.error(CustomError.fromError(err, err?.code))).finally(() => subscriber.complete());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -175,7 +170,7 @@ export async function dirSize(dirPath: string): Promise<number>{
|
||||
const realPath = await realpath(fullPath);
|
||||
const stat = await lstat(realPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
if (stat.isDirectory()) {
|
||||
return dirSize(fullPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { deleteFolder, ensureFolderExist, moveFolderContent, pathExist, unlinkPa
|
||||
import { lstat, symlink } from "fs/promises";
|
||||
import path from "path";
|
||||
import { copy, readlink } from "fs-extra";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { noop } from "shared/helpers/function.helpers";
|
||||
|
||||
export class FolderLinkerService {
|
||||
private static instance: FolderLinkerService;
|
||||
@@ -72,7 +74,7 @@ export class FolderLinkerService {
|
||||
await ensureFolderExist(folderPath);
|
||||
|
||||
if (options?.keepContents !== false) {
|
||||
await moveFolderContent(folderPath, sharedPath).toPromise();
|
||||
await lastValueFrom(moveFolderContent(folderPath, sharedPath, { overwrite: true }));
|
||||
}
|
||||
|
||||
await deleteFolder(folderPath);
|
||||
@@ -95,9 +97,7 @@ export class FolderLinkerService {
|
||||
}
|
||||
|
||||
if (options.moveContents === true) {
|
||||
return moveFolderContent(sharedPath, folderPath)
|
||||
.toPromise()
|
||||
.then(() => {});
|
||||
return lastValueFrom(moveFolderContent(sharedPath, folderPath, { overwrite: true })).then(noop);
|
||||
}
|
||||
|
||||
if (options?.keepContents === false) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getFoldersInFolder } from "../helpers/fs.helpers";
|
||||
import path from "path";
|
||||
import { VersionLinkerAction, VersionLinkFolderAction, VersionUnlinkFolderAction } from "renderer/services/version-folder-linker.service";
|
||||
import { VersionLinkerAction, VersionUnlinkFolderAction } from "renderer/services/version-folder-linker.service";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
import { LocalMapsManagerService } from "./additional-content/local-maps-manager.service";
|
||||
import { BSLocalVersionService } from "./bs-local-version.service";
|
||||
@@ -58,17 +58,14 @@ export class VersionFolderLinkerService {
|
||||
return path.join(parentPath, relativePath);
|
||||
}
|
||||
|
||||
public async linkVersionFolder(action: VersionLinkerAction): Promise<boolean> {
|
||||
public async linkVersionFolder(action: VersionLinkerAction): Promise<void> {
|
||||
action.options = this.specialFolderOption(action.relativeFolder, action.options);
|
||||
const versionPath = await this.localVersion.getVersionPath(action.version);
|
||||
const folderPath = this.relativeToFullPath(versionPath, action.relativeFolder);
|
||||
return this.folderLinker
|
||||
.linkFolder(folderPath, action.options)
|
||||
.catch(() => false)
|
||||
.then(() => true);
|
||||
return this.folderLinker.linkFolder(folderPath, action.options)
|
||||
}
|
||||
|
||||
public async unlinkVersionFolder(action: VersionUnlinkFolderAction): Promise<boolean> {
|
||||
public async unlinkVersionFolder(action: VersionUnlinkFolderAction): Promise<void> {
|
||||
action.options = this.specialFolderOption(action.relativeFolder, action.options);
|
||||
|
||||
const versionPath = await this.localVersion.getVersionPath(action.version);
|
||||
@@ -76,13 +73,10 @@ export class VersionFolderLinkerService {
|
||||
|
||||
action.options.moveContents = !(await this.isOtherVersionHaveFolderLinked(action.relativeFolder, folderPath));
|
||||
|
||||
return this.folderLinker
|
||||
.unlinkFolder(folderPath, action.options)
|
||||
.catch(() => false)
|
||||
.then(() => true);
|
||||
return this.folderLinker.unlinkFolder(folderPath, action.options);
|
||||
}
|
||||
|
||||
public async doAction(action: VersionLinkerAction): Promise<boolean> {
|
||||
public doAction(action: VersionLinkerAction): Promise<void> {
|
||||
if (action.type === "link") {
|
||||
return this.linkVersionFolder(action);
|
||||
}
|
||||
@@ -123,7 +117,7 @@ export class VersionFolderLinkerService {
|
||||
|
||||
for (const version of versions) {
|
||||
const linkedFolders = await this.getLinkedFolders(version, { relative: true, ignoreSymlinkTargetError: true });
|
||||
const actions = linkedFolders.map(folder => ({ type: "link", version, relativeFolder: folder } as VersionLinkFolderAction));
|
||||
const actions = linkedFolders.map(folder => ({ type: "link", version, relativeFolder: folder } as VersionLinkerAction));
|
||||
await Promise.all(actions.map(action => this.doAction(action)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user