diff --git a/src/commands/modrinth.ts b/src/commands/modrinth.ts index 8938342..b503454 100644 --- a/src/commands/modrinth.ts +++ b/src/commands/modrinth.ts @@ -17,6 +17,7 @@ import semver from "semver" import { output } from "../output.js" import fs from "fs-extra" import { addModrinthMod, findModForModrinthMod, getModFileDataForModrinthVersion, isModrinthVersionCompatible, sortModrinthVersionsByPreference } from "../modrinth/utils.js" +import { walk } from "@root/walk" const modrinthCommand = new Command("modrinth") .alias("mr") @@ -311,10 +312,23 @@ modrinthCommand.command("export") "Copying client-server overrides" ) - if (await fs.pathExists(pack.paths.overrides["client"].toString())) await output.withLoading( - fs.copy(pack.paths.overrides["client"].toString(), outputDirectory.resolve("client-overrides").toString(), { recursive: true }), - "Copying client overrides" - ) + if (await fs.pathExists(pack.paths.overrides["client"].toString())) { + await output.withLoading( + fs.copy(pack.paths.overrides["client"].toString(), outputDirectory.resolve("client-overrides").toString(), { recursive: true }), + "Copying client overrides" + ) + + // Workaround for https://github.com/PolyMC/PolyMC/issues/1060 + await walk(pack.paths.overrides["client"].toString(), async (error, path, dirent) => { + if (error) return + if (dirent.isDirectory()) { + const relativePath = pack.paths.overrides["client"].relative(path) + await fs.mkdirp(outputDirectory.resolve("overrides", relativePath).toString()) + } + + return true + }) + } if (await fs.pathExists(pack.paths.overrides["server"].toString())) await output.withLoading( fs.copy(pack.paths.overrides["server"].toString(), outputDirectory.resolve("server-overrides").toString(), { recursive: true }), diff --git a/src/path.ts b/src/path.ts index caeb333..2417206 100644 --- a/src/path.ts +++ b/src/path.ts @@ -34,6 +34,12 @@ export class Path { return pathModule.isAbsolute(this.value) } + // Not tested + // isDescendantOf(other: Path) { + // if (!(this.isAbsolute() && other.isAbsolute())) throw new Error("Both paths must be absolute") + // return pathModule.relative(this.value, other.value).split("/").includes("..") + // } + toString() { return this.value } diff --git a/src/utils.ts b/src/utils.ts index 34918ed..6193ba6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -11,6 +11,8 @@ import addressWithCallback from "address" import { promisify } from "util" import { KeyvFile } from "keyv-file" import originalGot from "got" +import { dirname } from "path" +import { without } from "lodash-es" const keyvCache = new KeyvFile({ filename: paths.cache.resolve("http.json").toString(), @@ -80,14 +82,23 @@ export async function zipDirectory(directoryPath: Path, outputFilePath: Path) { const zipFile = new ZipFile() zipFile.outputStream.pipe(fs.createWriteStream(outputFilePath.toString())) + let emptyDirectories: string[] = [] await walk(directoryPath.toString(), async (error, path, dirent) => { if (error) return if (directoryPath.toString() === path) return true if (dirent.name.startsWith(".")) return false - if (dirent.isFile()) zipFile.addFile(path, directoryPath.relative(path).toString(), { compress: true }) + if (dirent.isDirectory()) { + emptyDirectories.push(path) + } else if (dirent.isFile()) { + zipFile.addFile(path, directoryPath.relative(path).toString(), { compress: true }) + } else return + + emptyDirectories = without(emptyDirectories, dirname(path)) }) + emptyDirectories.forEach(p => zipFile.addEmptyDirectory(directoryPath.relative(p).toString())) + zipFile.end() await pEvent(zipFile.outputStream, "close") }